1 /* $OpenBSD: tls13_key_schedule.c,v 1.15 2022/07/07 17:09:45 tb Exp $ */ 2 /* 3 * Copyright (c) 2018, Bob Beck <beck@openbsd.org> 4 * 5 * Permission to use, copy, modify, and/or 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 ANY 12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <string.h> 19 #include <stdlib.h> 20 21 #include <openssl/hkdf.h> 22 23 #include "bytestring.h" 24 #include "tls13_internal.h" 25 26 int 27 tls13_secret_init(struct tls13_secret *secret, size_t len) 28 { 29 if (secret->data != NULL) 30 return 0; 31 32 if ((secret->data = calloc(1, len)) == NULL) 33 return 0; 34 secret->len = len; 35 36 return 1; 37 } 38 39 void 40 tls13_secret_cleanup(struct tls13_secret *secret) 41 { 42 freezero(secret->data, secret->len); 43 secret->data = NULL; 44 secret->len = 0; 45 } 46 47 /* 48 * Allocate a set of secrets for a key schedule using 49 * a size of hash_length from RFC 8446 section 7.1. 50 */ 51 struct tls13_secrets * 52 tls13_secrets_create(const EVP_MD *digest, int resumption) 53 { 54 struct tls13_secrets *secrets = NULL; 55 EVP_MD_CTX *mdctx = NULL; 56 unsigned int mdlen; 57 size_t hash_length; 58 59 hash_length = EVP_MD_size(digest); 60 61 if ((secrets = calloc(1, sizeof(struct tls13_secrets))) == NULL) 62 goto err; 63 64 if (!tls13_secret_init(&secrets->zeros, hash_length)) 65 goto err; 66 if (!tls13_secret_init(&secrets->empty_hash, hash_length)) 67 goto err; 68 69 if (!tls13_secret_init(&secrets->extracted_early, hash_length)) 70 goto err; 71 if (!tls13_secret_init(&secrets->binder_key, hash_length)) 72 goto err; 73 if (!tls13_secret_init(&secrets->client_early_traffic, hash_length)) 74 goto err; 75 if (!tls13_secret_init(&secrets->early_exporter_master, hash_length)) 76 goto err; 77 if (!tls13_secret_init(&secrets->derived_early, hash_length)) 78 goto err; 79 if (!tls13_secret_init(&secrets->extracted_handshake, hash_length)) 80 goto err; 81 if (!tls13_secret_init(&secrets->client_handshake_traffic, hash_length)) 82 goto err; 83 if (!tls13_secret_init(&secrets->server_handshake_traffic, hash_length)) 84 goto err; 85 if (!tls13_secret_init(&secrets->derived_handshake, hash_length)) 86 goto err; 87 if (!tls13_secret_init(&secrets->extracted_master, hash_length)) 88 goto err; 89 if (!tls13_secret_init(&secrets->client_application_traffic, hash_length)) 90 goto err; 91 if (!tls13_secret_init(&secrets->server_application_traffic, hash_length)) 92 goto err; 93 if (!tls13_secret_init(&secrets->exporter_master, hash_length)) 94 goto err; 95 if (!tls13_secret_init(&secrets->resumption_master, hash_length)) 96 goto err; 97 98 /* 99 * Calculate the hash of a zero-length string - this is needed during 100 * the "derived" step for key extraction. 101 */ 102 if ((mdctx = EVP_MD_CTX_new()) == NULL) 103 goto err; 104 if (!EVP_DigestInit_ex(mdctx, digest, NULL)) 105 goto err; 106 if (!EVP_DigestUpdate(mdctx, secrets->zeros.data, 0)) 107 goto err; 108 if (!EVP_DigestFinal_ex(mdctx, secrets->empty_hash.data, &mdlen)) 109 goto err; 110 EVP_MD_CTX_free(mdctx); 111 mdctx = NULL; 112 113 if (secrets->empty_hash.len != mdlen) 114 goto err; 115 116 secrets->digest = digest; 117 secrets->resumption = resumption; 118 secrets->init_done = 1; 119 120 return secrets; 121 122 err: 123 tls13_secrets_destroy(secrets); 124 EVP_MD_CTX_free(mdctx); 125 126 return NULL; 127 } 128 129 void 130 tls13_secrets_destroy(struct tls13_secrets *secrets) 131 { 132 if (secrets == NULL) 133 return; 134 135 /* you can never be too sure :) */ 136 tls13_secret_cleanup(&secrets->zeros); 137 tls13_secret_cleanup(&secrets->empty_hash); 138 139 tls13_secret_cleanup(&secrets->extracted_early); 140 tls13_secret_cleanup(&secrets->binder_key); 141 tls13_secret_cleanup(&secrets->client_early_traffic); 142 tls13_secret_cleanup(&secrets->early_exporter_master); 143 tls13_secret_cleanup(&secrets->derived_early); 144 tls13_secret_cleanup(&secrets->extracted_handshake); 145 tls13_secret_cleanup(&secrets->client_handshake_traffic); 146 tls13_secret_cleanup(&secrets->server_handshake_traffic); 147 tls13_secret_cleanup(&secrets->derived_handshake); 148 tls13_secret_cleanup(&secrets->extracted_master); 149 tls13_secret_cleanup(&secrets->client_application_traffic); 150 tls13_secret_cleanup(&secrets->server_application_traffic); 151 tls13_secret_cleanup(&secrets->exporter_master); 152 tls13_secret_cleanup(&secrets->resumption_master); 153 154 freezero(secrets, sizeof(struct tls13_secrets)); 155 } 156 157 int 158 tls13_hkdf_expand_label(struct tls13_secret *out, const EVP_MD *digest, 159 const struct tls13_secret *secret, const char *label, 160 const struct tls13_secret *context) 161 { 162 return tls13_hkdf_expand_label_with_length(out, digest, secret, label, 163 strlen(label), context); 164 } 165 166 int 167 tls13_hkdf_expand_label_with_length(struct tls13_secret *out, 168 const EVP_MD *digest, const struct tls13_secret *secret, 169 const uint8_t *label, size_t label_len, const struct tls13_secret *context) 170 { 171 const char tls13_plabel[] = "tls13 "; 172 uint8_t *hkdf_label = NULL; 173 size_t hkdf_label_len; 174 CBB cbb, child; 175 int ret; 176 177 if (!CBB_init(&cbb, 256)) 178 return 0; 179 if (!CBB_add_u16(&cbb, out->len)) 180 goto err; 181 if (!CBB_add_u8_length_prefixed(&cbb, &child)) 182 goto err; 183 if (!CBB_add_bytes(&child, tls13_plabel, strlen(tls13_plabel))) 184 goto err; 185 if (!CBB_add_bytes(&child, label, label_len)) 186 goto err; 187 if (!CBB_add_u8_length_prefixed(&cbb, &child)) 188 goto err; 189 if (!CBB_add_bytes(&child, context->data, context->len)) 190 goto err; 191 if (!CBB_finish(&cbb, &hkdf_label, &hkdf_label_len)) 192 goto err; 193 194 ret = HKDF_expand(out->data, out->len, digest, secret->data, 195 secret->len, hkdf_label, hkdf_label_len); 196 197 free(hkdf_label); 198 return(ret); 199 err: 200 CBB_cleanup(&cbb); 201 return(0); 202 } 203 204 int 205 tls13_derive_secret(struct tls13_secret *out, const EVP_MD *digest, 206 const struct tls13_secret *secret, const char *label, 207 const struct tls13_secret *context) 208 { 209 return tls13_hkdf_expand_label(out, digest, secret, label, context); 210 } 211 212 int 213 tls13_derive_secret_with_label_length(struct tls13_secret *out, 214 const EVP_MD *digest, const struct tls13_secret *secret, const uint8_t *label, 215 size_t label_len, const struct tls13_secret *context) 216 { 217 return tls13_hkdf_expand_label_with_length(out, digest, secret, label, 218 label_len, context); 219 } 220 221 int 222 tls13_derive_early_secrets(struct tls13_secrets *secrets, 223 uint8_t *psk, size_t psk_len, const struct tls13_secret *context) 224 { 225 if (!secrets->init_done || secrets->early_done) 226 return 0; 227 228 if (!HKDF_extract(secrets->extracted_early.data, 229 &secrets->extracted_early.len, secrets->digest, psk, psk_len, 230 secrets->zeros.data, secrets->zeros.len)) 231 return 0; 232 233 if (secrets->extracted_early.len != secrets->zeros.len) 234 return 0; 235 236 if (!tls13_derive_secret(&secrets->binder_key, secrets->digest, 237 &secrets->extracted_early, 238 secrets->resumption ? "res binder" : "ext binder", 239 &secrets->empty_hash)) 240 return 0; 241 if (!tls13_derive_secret(&secrets->client_early_traffic, 242 secrets->digest, &secrets->extracted_early, "c e traffic", 243 context)) 244 return 0; 245 if (!tls13_derive_secret(&secrets->early_exporter_master, 246 secrets->digest, &secrets->extracted_early, "e exp master", 247 context)) 248 return 0; 249 if (!tls13_derive_secret(&secrets->derived_early, 250 secrets->digest, &secrets->extracted_early, "derived", 251 &secrets->empty_hash)) 252 return 0; 253 254 /* RFC 8446 recommends */ 255 if (!secrets->insecure) 256 explicit_bzero(secrets->extracted_early.data, 257 secrets->extracted_early.len); 258 secrets->early_done = 1; 259 return 1; 260 } 261 262 int 263 tls13_derive_handshake_secrets(struct tls13_secrets *secrets, 264 const uint8_t *ecdhe, size_t ecdhe_len, 265 const struct tls13_secret *context) 266 { 267 if (!secrets->init_done || !secrets->early_done || 268 secrets->handshake_done) 269 return 0; 270 271 if (!HKDF_extract(secrets->extracted_handshake.data, 272 &secrets->extracted_handshake.len, secrets->digest, 273 ecdhe, ecdhe_len, secrets->derived_early.data, 274 secrets->derived_early.len)) 275 return 0; 276 277 if (secrets->extracted_handshake.len != secrets->zeros.len) 278 return 0; 279 280 /* XXX */ 281 if (!secrets->insecure) 282 explicit_bzero(secrets->derived_early.data, 283 secrets->derived_early.len); 284 285 if (!tls13_derive_secret(&secrets->client_handshake_traffic, 286 secrets->digest, &secrets->extracted_handshake, "c hs traffic", 287 context)) 288 return 0; 289 if (!tls13_derive_secret(&secrets->server_handshake_traffic, 290 secrets->digest, &secrets->extracted_handshake, "s hs traffic", 291 context)) 292 return 0; 293 if (!tls13_derive_secret(&secrets->derived_handshake, 294 secrets->digest, &secrets->extracted_handshake, "derived", 295 &secrets->empty_hash)) 296 return 0; 297 298 /* RFC 8446 recommends */ 299 if (!secrets->insecure) 300 explicit_bzero(secrets->extracted_handshake.data, 301 secrets->extracted_handshake.len); 302 303 secrets->handshake_done = 1; 304 305 return 1; 306 } 307 308 int 309 tls13_derive_application_secrets(struct tls13_secrets *secrets, 310 const struct tls13_secret *context) 311 { 312 if (!secrets->init_done || !secrets->early_done || 313 !secrets->handshake_done || secrets->schedule_done) 314 return 0; 315 316 if (!HKDF_extract(secrets->extracted_master.data, 317 &secrets->extracted_master.len, secrets->digest, 318 secrets->zeros.data, secrets->zeros.len, 319 secrets->derived_handshake.data, secrets->derived_handshake.len)) 320 return 0; 321 322 if (secrets->extracted_master.len != secrets->zeros.len) 323 return 0; 324 325 /* XXX */ 326 if (!secrets->insecure) 327 explicit_bzero(secrets->derived_handshake.data, 328 secrets->derived_handshake.len); 329 330 if (!tls13_derive_secret(&secrets->client_application_traffic, 331 secrets->digest, &secrets->extracted_master, "c ap traffic", 332 context)) 333 return 0; 334 if (!tls13_derive_secret(&secrets->server_application_traffic, 335 secrets->digest, &secrets->extracted_master, "s ap traffic", 336 context)) 337 return 0; 338 if (!tls13_derive_secret(&secrets->exporter_master, 339 secrets->digest, &secrets->extracted_master, "exp master", 340 context)) 341 return 0; 342 if (!tls13_derive_secret(&secrets->resumption_master, 343 secrets->digest, &secrets->extracted_master, "res master", 344 context)) 345 return 0; 346 347 /* RFC 8446 recommends */ 348 if (!secrets->insecure) 349 explicit_bzero(secrets->extracted_master.data, 350 secrets->extracted_master.len); 351 352 secrets->schedule_done = 1; 353 354 return 1; 355 } 356 357 int 358 tls13_update_client_traffic_secret(struct tls13_secrets *secrets) 359 { 360 struct tls13_secret context = { .data = "", .len = 0 }; 361 362 if (!secrets->init_done || !secrets->early_done || 363 !secrets->handshake_done || !secrets->schedule_done) 364 return 0; 365 366 return tls13_hkdf_expand_label(&secrets->client_application_traffic, 367 secrets->digest, &secrets->client_application_traffic, 368 "traffic upd", &context); 369 } 370 371 int 372 tls13_update_server_traffic_secret(struct tls13_secrets *secrets) 373 { 374 struct tls13_secret context = { .data = "", .len = 0 }; 375 376 if (!secrets->init_done || !secrets->early_done || 377 !secrets->handshake_done || !secrets->schedule_done) 378 return 0; 379 380 return tls13_hkdf_expand_label(&secrets->server_application_traffic, 381 secrets->digest, &secrets->server_application_traffic, 382 "traffic upd", &context); 383 } 384