1 /* $OpenBSD: tls12_key_schedule.c,v 1.1 2021/05/05 10:05:27 jsing Exp $ */ 2 /* 3 * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <stdlib.h> 19 20 #include <openssl/evp.h> 21 22 #include "bytestring.h" 23 #include "ssl_locl.h" 24 25 struct tls12_key_block { 26 CBS client_write_mac_key; 27 CBS server_write_mac_key; 28 CBS client_write_key; 29 CBS server_write_key; 30 CBS client_write_iv; 31 CBS server_write_iv; 32 33 uint8_t *key_block; 34 size_t key_block_len; 35 }; 36 37 struct tls12_key_block * 38 tls12_key_block_new(void) 39 { 40 return calloc(1, sizeof(struct tls12_key_block)); 41 } 42 43 static void 44 tls12_key_block_clear(struct tls12_key_block *kb) 45 { 46 CBS_init(&kb->client_write_mac_key, NULL, 0); 47 CBS_init(&kb->server_write_mac_key, NULL, 0); 48 CBS_init(&kb->client_write_key, NULL, 0); 49 CBS_init(&kb->server_write_key, NULL, 0); 50 CBS_init(&kb->client_write_iv, NULL, 0); 51 CBS_init(&kb->server_write_iv, NULL, 0); 52 53 freezero(kb->key_block, kb->key_block_len); 54 kb->key_block = NULL; 55 kb->key_block_len = 0; 56 } 57 58 void 59 tls12_key_block_free(struct tls12_key_block *kb) 60 { 61 if (kb == NULL) 62 return; 63 64 tls12_key_block_clear(kb); 65 66 freezero(kb, sizeof(struct tls12_key_block)); 67 } 68 69 void 70 tls12_key_block_client_write(struct tls12_key_block *kb, CBS *mac_key, 71 CBS *key, CBS *iv) 72 { 73 CBS_dup(&kb->client_write_mac_key, mac_key); 74 CBS_dup(&kb->client_write_key, key); 75 CBS_dup(&kb->client_write_iv, iv); 76 } 77 78 void 79 tls12_key_block_server_write(struct tls12_key_block *kb, CBS *mac_key, 80 CBS *key, CBS *iv) 81 { 82 CBS_dup(&kb->server_write_mac_key, mac_key); 83 CBS_dup(&kb->server_write_key, key); 84 CBS_dup(&kb->server_write_iv, iv); 85 } 86 87 int 88 tls12_key_block_generate(struct tls12_key_block *kb, SSL *s, 89 const EVP_AEAD *aead, const EVP_CIPHER *cipher, const EVP_MD *mac_hash) 90 { 91 size_t mac_key_len = 0, key_len = 0, iv_len = 0; 92 uint8_t *key_block = NULL; 93 size_t key_block_len = 0; 94 CBS cbs; 95 96 /* 97 * Generate a TLSv1.2 key block and partition into individual secrets, 98 * as per RFC 5246 section 6.3. 99 */ 100 101 tls12_key_block_clear(kb); 102 103 /* Must have AEAD or cipher/MAC pair. */ 104 if (aead == NULL && (cipher == NULL || mac_hash == NULL)) 105 goto err; 106 107 if (aead != NULL) { 108 key_len = EVP_AEAD_key_length(aead); 109 110 /* AEAD fixed nonce length. */ 111 if (aead == EVP_aead_aes_128_gcm() || 112 aead == EVP_aead_aes_256_gcm()) 113 iv_len = 4; 114 else if (aead == EVP_aead_chacha20_poly1305()) 115 iv_len = 12; 116 else 117 goto err; 118 } else if (cipher != NULL && mac_hash != NULL) { 119 /* 120 * A negative integer return value will be detected via the 121 * EVP_MAX_* checks against the size_t variables below. 122 */ 123 mac_key_len = EVP_MD_size(mac_hash); 124 key_len = EVP_CIPHER_key_length(cipher); 125 iv_len = EVP_CIPHER_iv_length(cipher); 126 127 /* Special handling for GOST... */ 128 if (EVP_MD_type(mac_hash) == NID_id_Gost28147_89_MAC) 129 mac_key_len = 32; 130 } 131 132 if (mac_key_len > EVP_MAX_MD_SIZE) 133 goto err; 134 if (key_len > EVP_MAX_KEY_LENGTH) 135 goto err; 136 if (iv_len > EVP_MAX_IV_LENGTH) 137 goto err; 138 139 key_block_len = 2 * mac_key_len + 2 * key_len + 2 * iv_len; 140 if ((key_block = calloc(1, key_block_len)) == NULL) 141 goto err; 142 143 if (!tls1_generate_key_block(s, key_block, key_block_len)) 144 goto err; 145 146 kb->key_block = key_block; 147 kb->key_block_len = key_block_len; 148 key_block = NULL; 149 key_block_len = 0; 150 151 /* Partition key block into individual secrets. */ 152 CBS_init(&cbs, kb->key_block, kb->key_block_len); 153 if (!CBS_get_bytes(&cbs, &kb->client_write_mac_key, mac_key_len)) 154 goto err; 155 if (!CBS_get_bytes(&cbs, &kb->server_write_mac_key, mac_key_len)) 156 goto err; 157 if (!CBS_get_bytes(&cbs, &kb->client_write_key, key_len)) 158 goto err; 159 if (!CBS_get_bytes(&cbs, &kb->server_write_key, key_len)) 160 goto err; 161 if (!CBS_get_bytes(&cbs, &kb->client_write_iv, iv_len)) 162 goto err; 163 if (!CBS_get_bytes(&cbs, &kb->server_write_iv, iv_len)) 164 goto err; 165 if (CBS_len(&cbs) != 0) 166 goto err; 167 168 return 1; 169 170 err: 171 tls12_key_block_clear(kb); 172 freezero(key_block, key_block_len); 173 174 return 0; 175 } 176