1/* $OpenBSD: tls12_key_schedule.c,v 1.4 2024/02/03 15:58:34 beck 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_local.h" 24#include "tls12_internal.h" 25 26struct tls12_key_block { 27 CBS client_write_mac_key; 28 CBS server_write_mac_key; 29 CBS client_write_key; 30 CBS server_write_key; 31 CBS client_write_iv; 32 CBS server_write_iv; 33 34 uint8_t *key_block; 35 size_t key_block_len; 36}; 37 38struct tls12_key_block * 39tls12_key_block_new(void) 40{ 41 return calloc(1, sizeof(struct tls12_key_block)); 42} 43 44static void 45tls12_key_block_clear(struct tls12_key_block *kb) 46{ 47 CBS_init(&kb->client_write_mac_key, NULL, 0); 48 CBS_init(&kb->server_write_mac_key, NULL, 0); 49 CBS_init(&kb->client_write_key, NULL, 0); 50 CBS_init(&kb->server_write_key, NULL, 0); 51 CBS_init(&kb->client_write_iv, NULL, 0); 52 CBS_init(&kb->server_write_iv, NULL, 0); 53 54 freezero(kb->key_block, kb->key_block_len); 55 kb->key_block = NULL; 56 kb->key_block_len = 0; 57} 58 59void 60tls12_key_block_free(struct tls12_key_block *kb) 61{ 62 if (kb == NULL) 63 return; 64 65 tls12_key_block_clear(kb); 66 67 freezero(kb, sizeof(struct tls12_key_block)); 68} 69 70void 71tls12_key_block_client_write(struct tls12_key_block *kb, CBS *mac_key, 72 CBS *key, CBS *iv) 73{ 74 CBS_dup(&kb->client_write_mac_key, mac_key); 75 CBS_dup(&kb->client_write_key, key); 76 CBS_dup(&kb->client_write_iv, iv); 77} 78 79void 80tls12_key_block_server_write(struct tls12_key_block *kb, CBS *mac_key, 81 CBS *key, CBS *iv) 82{ 83 CBS_dup(&kb->server_write_mac_key, mac_key); 84 CBS_dup(&kb->server_write_key, key); 85 CBS_dup(&kb->server_write_iv, iv); 86} 87 88int 89tls12_key_block_generate(struct tls12_key_block *kb, SSL *s, 90 const EVP_AEAD *aead, const EVP_CIPHER *cipher, const EVP_MD *mac_hash) 91{ 92 size_t mac_key_len = 0, key_len = 0, iv_len = 0; 93 uint8_t *key_block = NULL; 94 size_t key_block_len = 0; 95 CBS cbs; 96 97 /* 98 * Generate a TLSv1.2 key block and partition into individual secrets, 99 * as per RFC 5246 section 6.3. 100 */ 101 102 tls12_key_block_clear(kb); 103 104 /* Must have AEAD or cipher/MAC pair. */ 105 if (aead == NULL && (cipher == NULL || mac_hash == NULL)) 106 goto err; 107 108 if (aead != NULL) { 109 key_len = EVP_AEAD_key_length(aead); 110 111 /* AEAD fixed nonce length. */ 112 if (aead == EVP_aead_aes_128_gcm() || 113 aead == EVP_aead_aes_256_gcm()) 114 iv_len = 4; 115 else if (aead == EVP_aead_chacha20_poly1305()) 116 iv_len = 12; 117 else 118 goto err; 119 } else if (cipher != NULL && mac_hash != NULL) { 120 /* 121 * A negative integer return value will be detected via the 122 * EVP_MAX_* checks against the size_t variables below. 123 */ 124 mac_key_len = EVP_MD_size(mac_hash); 125 key_len = EVP_CIPHER_key_length(cipher); 126 iv_len = EVP_CIPHER_iv_length(cipher); 127 } 128 129 if (mac_key_len > EVP_MAX_MD_SIZE) 130 goto err; 131 if (key_len > EVP_MAX_KEY_LENGTH) 132 goto err; 133 if (iv_len > EVP_MAX_IV_LENGTH) 134 goto err; 135 136 key_block_len = 2 * mac_key_len + 2 * key_len + 2 * iv_len; 137 if ((key_block = calloc(1, key_block_len)) == NULL) 138 goto err; 139 140 if (!tls1_generate_key_block(s, key_block, key_block_len)) 141 goto err; 142 143 kb->key_block = key_block; 144 kb->key_block_len = key_block_len; 145 key_block = NULL; 146 key_block_len = 0; 147 148 /* Partition key block into individual secrets. */ 149 CBS_init(&cbs, kb->key_block, kb->key_block_len); 150 if (!CBS_get_bytes(&cbs, &kb->client_write_mac_key, mac_key_len)) 151 goto err; 152 if (!CBS_get_bytes(&cbs, &kb->server_write_mac_key, mac_key_len)) 153 goto err; 154 if (!CBS_get_bytes(&cbs, &kb->client_write_key, key_len)) 155 goto err; 156 if (!CBS_get_bytes(&cbs, &kb->server_write_key, key_len)) 157 goto err; 158 if (!CBS_get_bytes(&cbs, &kb->client_write_iv, iv_len)) 159 goto err; 160 if (!CBS_get_bytes(&cbs, &kb->server_write_iv, iv_len)) 161 goto err; 162 if (CBS_len(&cbs) != 0) 163 goto err; 164 165 return 1; 166 167 err: 168 tls12_key_block_clear(kb); 169 freezero(key_block, key_block_len); 170 171 return 0; 172} 173 174struct tls12_reserved_label { 175 const char *label; 176 size_t label_len; 177}; 178 179/* 180 * RFC 5705 section 6. 181 */ 182static const struct tls12_reserved_label tls12_reserved_labels[] = { 183 { 184 .label = TLS_MD_CLIENT_FINISH_CONST, 185 .label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE, 186 }, 187 { 188 .label = TLS_MD_SERVER_FINISH_CONST, 189 .label_len = TLS_MD_SERVER_FINISH_CONST_SIZE, 190 }, 191 { 192 .label = TLS_MD_MASTER_SECRET_CONST, 193 .label_len = TLS_MD_MASTER_SECRET_CONST_SIZE, 194 }, 195 { 196 .label = TLS_MD_KEY_EXPANSION_CONST, 197 .label_len = TLS_MD_KEY_EXPANSION_CONST_SIZE, 198 }, 199 { 200 .label = NULL, 201 .label_len = 0, 202 }, 203}; 204 205int 206tls12_exporter(SSL *s, const uint8_t *label, size_t label_len, 207 const uint8_t *context_value, size_t context_value_len, int use_context, 208 uint8_t *out, size_t out_len) 209{ 210 uint8_t *data = NULL; 211 size_t data_len = 0; 212 CBB cbb, context; 213 CBS seed; 214 size_t i; 215 int ret = 0; 216 217 /* 218 * RFC 5705 - Key Material Exporters for TLS. 219 */ 220 221 memset(&cbb, 0, sizeof(cbb)); 222 223 if (!SSL_is_init_finished(s)) { 224 SSLerror(s, SSL_R_BAD_STATE); 225 goto err; 226 } 227 228 if (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION) 229 goto err; 230 231 /* 232 * Due to exceptional design choices, we need to build a concatenation 233 * of the label and the seed value, before checking for reserved 234 * labels. This prevents a reserved label from being split across the 235 * label and the seed (that includes the client random), which are 236 * concatenated by the PRF. 237 */ 238 if (!CBB_init(&cbb, 0)) 239 goto err; 240 if (!CBB_add_bytes(&cbb, label, label_len)) 241 goto err; 242 if (!CBB_add_bytes(&cbb, s->s3->client_random, SSL3_RANDOM_SIZE)) 243 goto err; 244 if (!CBB_add_bytes(&cbb, s->s3->server_random, SSL3_RANDOM_SIZE)) 245 goto err; 246 if (use_context) { 247 if (!CBB_add_u16_length_prefixed(&cbb, &context)) 248 goto err; 249 if (context_value_len > 0) { 250 if (!CBB_add_bytes(&context, context_value, 251 context_value_len)) 252 goto err; 253 } 254 } 255 if (!CBB_finish(&cbb, &data, &data_len)) 256 goto err; 257 258 /* 259 * Ensure that the block (label + seed) does not start with a reserved 260 * label - in an ideal world we would ensure that the label has an 261 * explicitly permitted prefix instead, but of course this also got 262 * messed up by the standards. 263 */ 264 for (i = 0; tls12_reserved_labels[i].label != NULL; i++) { 265 /* XXX - consider adding/using CBS_has_prefix(). */ 266 if (tls12_reserved_labels[i].label_len > data_len) 267 goto err; 268 if (memcmp(data, tls12_reserved_labels[i].label, 269 tls12_reserved_labels[i].label_len) == 0) { 270 SSLerror(s, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); 271 goto err; 272 } 273 } 274 275 CBS_init(&seed, data, data_len); 276 if (!CBS_skip(&seed, label_len)) 277 goto err; 278 279 if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length, 280 label, label_len, CBS_data(&seed), CBS_len(&seed), NULL, 0, NULL, 0, 281 NULL, 0, out, out_len)) 282 goto err; 283 284 ret = 1; 285 286 err: 287 freezero(data, data_len); 288 CBB_cleanup(&cbb); 289 290 return ret; 291} 292