diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libssl/ssl_lib.c | 21 | ||||
| -rw-r--r-- | src/lib/libssl/ssl_locl.h | 5 | ||||
| -rw-r--r-- | src/lib/libssl/t1_enc.c | 82 | ||||
| -rw-r--r-- | src/lib/libssl/tls12_internal.h | 29 | ||||
| -rw-r--r-- | src/lib/libssl/tls12_key_schedule.c | 122 |
5 files changed, 163 insertions, 96 deletions
diff --git a/src/lib/libssl/ssl_lib.c b/src/lib/libssl/ssl_lib.c index 4b5f119a88..c9c63e9d3f 100644 --- a/src/lib/libssl/ssl_lib.c +++ b/src/lib/libssl/ssl_lib.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_lib.c,v 1.306 2022/10/02 16:36:41 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_lib.c,v 1.307 2022/11/07 11:58:45 jsing Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -163,6 +163,7 @@ | |||
| 163 | #include "ssl_locl.h" | 163 | #include "ssl_locl.h" |
| 164 | #include "ssl_sigalgs.h" | 164 | #include "ssl_sigalgs.h" |
| 165 | #include "ssl_tlsext.h" | 165 | #include "ssl_tlsext.h" |
| 166 | #include "tls12_internal.h" | ||
| 166 | 167 | ||
| 167 | const char *SSL_version_str = OPENSSL_VERSION_TEXT; | 168 | const char *SSL_version_str = OPENSSL_VERSION_TEXT; |
| 168 | 169 | ||
| @@ -1867,21 +1868,21 @@ SSL_set_psk_use_session_callback(SSL *s, SSL_psk_use_session_cb_func cb) | |||
| 1867 | } | 1868 | } |
| 1868 | 1869 | ||
| 1869 | int | 1870 | int |
| 1870 | SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, | 1871 | SSL_export_keying_material(SSL *s, unsigned char *out, size_t out_len, |
| 1871 | const char *label, size_t llen, const unsigned char *p, size_t plen, | 1872 | const char *label, size_t label_len, const unsigned char *context, |
| 1872 | int use_context) | 1873 | size_t context_len, int use_context) |
| 1873 | { | 1874 | { |
| 1874 | if (s->tls13 != NULL && s->version == TLS1_3_VERSION) { | 1875 | if (s->tls13 != NULL && s->version == TLS1_3_VERSION) { |
| 1875 | if (!use_context) { | 1876 | if (!use_context) { |
| 1876 | p = NULL; | 1877 | context = NULL; |
| 1877 | plen = 0; | 1878 | context_len = 0; |
| 1878 | } | 1879 | } |
| 1879 | return tls13_exporter(s->tls13, label, llen, p, plen, | 1880 | return tls13_exporter(s->tls13, label, label_len, context, |
| 1880 | out, olen); | 1881 | context_len, out, out_len); |
| 1881 | } | 1882 | } |
| 1882 | 1883 | ||
| 1883 | return (tls1_export_keying_material(s, out, olen, label, llen, p, plen, | 1884 | return tls12_exporter(s, label, label_len, context, context_len, |
| 1884 | use_context)); | 1885 | use_context, out, out_len); |
| 1885 | } | 1886 | } |
| 1886 | 1887 | ||
| 1887 | static unsigned long | 1888 | static unsigned long |
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h index 42ae429074..64cf6a60f9 100644 --- a/src/lib/libssl/ssl_locl.h +++ b/src/lib/libssl/ssl_locl.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: ssl_locl.h,v 1.429 2022/10/20 15:22:51 tb Exp $ */ | 1 | /* $OpenBSD: ssl_locl.h,v 1.430 2022/11/07 11:58:45 jsing Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -1463,9 +1463,6 @@ int tls1_change_read_cipher_state(SSL *s); | |||
| 1463 | int tls1_change_write_cipher_state(SSL *s); | 1463 | int tls1_change_write_cipher_state(SSL *s); |
| 1464 | int tls1_setup_key_block(SSL *s); | 1464 | int tls1_setup_key_block(SSL *s); |
| 1465 | int tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len); | 1465 | int tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len); |
| 1466 | int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, | ||
| 1467 | const char *label, size_t llen, const unsigned char *p, size_t plen, | ||
| 1468 | int use_context); | ||
| 1469 | int ssl_ok(SSL *s); | 1466 | int ssl_ok(SSL *s); |
| 1470 | 1467 | ||
| 1471 | int tls12_derive_finished(SSL *s); | 1468 | int tls12_derive_finished(SSL *s); |
diff --git a/src/lib/libssl/t1_enc.c b/src/lib/libssl/t1_enc.c index 66a7aea2f5..dc627c5a8b 100644 --- a/src/lib/libssl/t1_enc.c +++ b/src/lib/libssl/t1_enc.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: t1_enc.c,v 1.155 2022/10/02 16:36:41 jsing Exp $ */ | 1 | /* $OpenBSD: t1_enc.c,v 1.156 2022/11/07 11:58:45 jsing Exp $ */ |
| 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 | * All rights reserved. | 3 | * All rights reserved. |
| 4 | * | 4 | * |
| @@ -413,83 +413,3 @@ tls1_setup_key_block(SSL *s) | |||
| 413 | 413 | ||
| 414 | return (ret); | 414 | return (ret); |
| 415 | } | 415 | } |
| 416 | |||
| 417 | int | ||
| 418 | tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, | ||
| 419 | const char *label, size_t llen, const unsigned char *context, | ||
| 420 | size_t contextlen, int use_context) | ||
| 421 | { | ||
| 422 | unsigned char *val = NULL; | ||
| 423 | size_t vallen, currentvalpos; | ||
| 424 | int rv; | ||
| 425 | |||
| 426 | if (!SSL_is_init_finished(s)) { | ||
| 427 | SSLerror(s, SSL_R_BAD_STATE); | ||
| 428 | return 0; | ||
| 429 | } | ||
| 430 | |||
| 431 | /* construct PRF arguments | ||
| 432 | * we construct the PRF argument ourself rather than passing separate | ||
| 433 | * values into the TLS PRF to ensure that the concatenation of values | ||
| 434 | * does not create a prohibited label. | ||
| 435 | */ | ||
| 436 | vallen = llen + SSL3_RANDOM_SIZE * 2; | ||
| 437 | if (use_context) { | ||
| 438 | vallen += 2 + contextlen; | ||
| 439 | } | ||
| 440 | |||
| 441 | val = malloc(vallen); | ||
| 442 | if (val == NULL) | ||
| 443 | goto err2; | ||
| 444 | currentvalpos = 0; | ||
| 445 | memcpy(val + currentvalpos, (unsigned char *) label, llen); | ||
| 446 | currentvalpos += llen; | ||
| 447 | memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE); | ||
| 448 | currentvalpos += SSL3_RANDOM_SIZE; | ||
| 449 | memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE); | ||
| 450 | currentvalpos += SSL3_RANDOM_SIZE; | ||
| 451 | |||
| 452 | if (use_context) { | ||
| 453 | val[currentvalpos] = (contextlen >> 8) & 0xff; | ||
| 454 | currentvalpos++; | ||
| 455 | val[currentvalpos] = contextlen & 0xff; | ||
| 456 | currentvalpos++; | ||
| 457 | if ((contextlen > 0) || (context != NULL)) { | ||
| 458 | memcpy(val + currentvalpos, context, contextlen); | ||
| 459 | } | ||
| 460 | } | ||
| 461 | |||
| 462 | /* disallow prohibited labels | ||
| 463 | * note that SSL3_RANDOM_SIZE > max(prohibited label len) = | ||
| 464 | * 15, so size of val > max(prohibited label len) = 15 and the | ||
| 465 | * comparisons won't have buffer overflow | ||
| 466 | */ | ||
| 467 | if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST, | ||
| 468 | TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) | ||
| 469 | goto err1; | ||
| 470 | if (memcmp(val, TLS_MD_SERVER_FINISH_CONST, | ||
| 471 | TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) | ||
| 472 | goto err1; | ||
| 473 | if (memcmp(val, TLS_MD_MASTER_SECRET_CONST, | ||
| 474 | TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) | ||
| 475 | goto err1; | ||
| 476 | if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST, | ||
| 477 | TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) | ||
| 478 | goto err1; | ||
| 479 | |||
| 480 | rv = tls1_PRF(s, s->session->master_key, s->session->master_key_length, | ||
| 481 | val, vallen, NULL, 0, NULL, 0, NULL, 0, NULL, 0, out, olen); | ||
| 482 | |||
| 483 | goto ret; | ||
| 484 | err1: | ||
| 485 | SSLerror(s, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); | ||
| 486 | rv = 0; | ||
| 487 | goto ret; | ||
| 488 | err2: | ||
| 489 | SSLerror(s, ERR_R_MALLOC_FAILURE); | ||
| 490 | rv = 0; | ||
| 491 | ret: | ||
| 492 | free(val); | ||
| 493 | |||
| 494 | return (rv); | ||
| 495 | } | ||
diff --git a/src/lib/libssl/tls12_internal.h b/src/lib/libssl/tls12_internal.h new file mode 100644 index 0000000000..d416b2e3f1 --- /dev/null +++ b/src/lib/libssl/tls12_internal.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* $OpenBSD: tls12_internal.h,v 1.1 2022/11/07 11:58:45 jsing Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022 Joel Sing <jsing@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 | #ifndef HEADER_TLS12_INTERNAL_H | ||
| 19 | #define HEADER_TLS12_INTERNAL_H | ||
| 20 | |||
| 21 | __BEGIN_HIDDEN_DECLS | ||
| 22 | |||
| 23 | int tls12_exporter(SSL *s, const uint8_t *label, size_t label_len, | ||
| 24 | const uint8_t *context_value, size_t context_value_len, int use_context, | ||
| 25 | uint8_t *out, size_t out_len); | ||
| 26 | |||
| 27 | __END_HIDDEN_DECLS | ||
| 28 | |||
| 29 | #endif | ||
diff --git a/src/lib/libssl/tls12_key_schedule.c b/src/lib/libssl/tls12_key_schedule.c index c206460d95..e603e2c222 100644 --- a/src/lib/libssl/tls12_key_schedule.c +++ b/src/lib/libssl/tls12_key_schedule.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: tls12_key_schedule.c,v 1.1 2021/05/05 10:05:27 jsing Exp $ */ | 1 | /* $OpenBSD: tls12_key_schedule.c,v 1.2 2022/11/07 11:58:45 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2021 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -21,6 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #include "bytestring.h" | 22 | #include "bytestring.h" |
| 23 | #include "ssl_locl.h" | 23 | #include "ssl_locl.h" |
| 24 | #include "tls12_internal.h" | ||
| 24 | 25 | ||
| 25 | struct tls12_key_block { | 26 | struct tls12_key_block { |
| 26 | CBS client_write_mac_key; | 27 | CBS client_write_mac_key; |
| @@ -173,3 +174,122 @@ tls12_key_block_generate(struct tls12_key_block *kb, SSL *s, | |||
| 173 | 174 | ||
| 174 | return 0; | 175 | return 0; |
| 175 | } | 176 | } |
| 177 | |||
| 178 | struct tls12_reserved_label { | ||
| 179 | const char *label; | ||
| 180 | size_t label_len; | ||
| 181 | }; | ||
| 182 | |||
| 183 | /* | ||
| 184 | * RFC 5705 section 6. | ||
| 185 | */ | ||
| 186 | static const struct tls12_reserved_label tls12_reserved_labels[] = { | ||
| 187 | { | ||
| 188 | .label = TLS_MD_CLIENT_FINISH_CONST, | ||
| 189 | .label_len = TLS_MD_CLIENT_FINISH_CONST_SIZE, | ||
| 190 | }, | ||
| 191 | { | ||
| 192 | .label = TLS_MD_SERVER_FINISH_CONST, | ||
| 193 | .label_len = TLS_MD_SERVER_FINISH_CONST_SIZE, | ||
| 194 | }, | ||
| 195 | { | ||
| 196 | .label = TLS_MD_MASTER_SECRET_CONST, | ||
| 197 | .label_len = TLS_MD_MASTER_SECRET_CONST_SIZE, | ||
| 198 | }, | ||
| 199 | { | ||
| 200 | .label = TLS_MD_KEY_EXPANSION_CONST, | ||
| 201 | .label_len = TLS_MD_KEY_EXPANSION_CONST_SIZE, | ||
| 202 | }, | ||
| 203 | { | ||
| 204 | .label = NULL, | ||
| 205 | .label_len = 0, | ||
| 206 | }, | ||
| 207 | }; | ||
| 208 | |||
| 209 | int | ||
| 210 | tls12_exporter(SSL *s, const uint8_t *label, size_t label_len, | ||
| 211 | const uint8_t *context_value, size_t context_value_len, int use_context, | ||
| 212 | uint8_t *out, size_t out_len) | ||
| 213 | { | ||
| 214 | uint8_t *data = NULL; | ||
| 215 | size_t data_len = 0; | ||
| 216 | CBB cbb, context; | ||
| 217 | CBS seed; | ||
| 218 | size_t i; | ||
| 219 | int ret = 0; | ||
| 220 | |||
| 221 | /* | ||
| 222 | * RFC 5705 - Key Material Exporters for TLS. | ||
| 223 | */ | ||
| 224 | |||
| 225 | memset(&cbb, 0, sizeof(cbb)); | ||
| 226 | |||
| 227 | if (!SSL_is_init_finished(s)) { | ||
| 228 | SSLerror(s, SSL_R_BAD_STATE); | ||
| 229 | goto err; | ||
| 230 | } | ||
| 231 | |||
| 232 | if (s->s3->hs.negotiated_tls_version >= TLS1_3_VERSION) | ||
| 233 | goto err; | ||
| 234 | |||
| 235 | /* | ||
| 236 | * Due to exceptional design choices, we need to build a concatenation | ||
| 237 | * of the label and the seed value, before checking for reserved | ||
| 238 | * labels. This prevents a reserved label from being split across the | ||
| 239 | * label and the seed (that includes the client random), which are | ||
| 240 | * concatenated by the PRF. | ||
| 241 | */ | ||
| 242 | if (!CBB_init(&cbb, 0)) | ||
| 243 | goto err; | ||
| 244 | if (!CBB_add_bytes(&cbb, label, label_len)) | ||
| 245 | goto err; | ||
| 246 | if (!CBB_add_bytes(&cbb, s->s3->client_random, SSL3_RANDOM_SIZE)) | ||
| 247 | goto err; | ||
| 248 | if (!CBB_add_bytes(&cbb, s->s3->server_random, SSL3_RANDOM_SIZE)) | ||
| 249 | goto err; | ||
| 250 | if (use_context) { | ||
| 251 | if (!CBB_add_u16_length_prefixed(&cbb, &context)) | ||
| 252 | goto err; | ||
| 253 | if (context_value_len > 0) { | ||
| 254 | if (!CBB_add_bytes(&context, context_value, | ||
| 255 | context_value_len)) | ||
| 256 | goto err; | ||
| 257 | } | ||
| 258 | } | ||
| 259 | if (!CBB_finish(&cbb, &data, &data_len)) | ||
| 260 | goto err; | ||
| 261 | |||
| 262 | /* | ||
| 263 | * Ensure that the block (label + seed) does not start with a reserved | ||
| 264 | * label - in an ideal world we would ensure that the label has an | ||
| 265 | * explicitly permitted prefix instead, but of course this also got | ||
| 266 | * messed up by the standards. | ||
| 267 | */ | ||
| 268 | for (i = 0; tls12_reserved_labels[i].label != NULL; i++) { | ||
| 269 | /* XXX - consider adding/using CBS_has_prefix(). */ | ||
| 270 | if (tls12_reserved_labels[i].label_len > data_len) | ||
| 271 | goto err; | ||
| 272 | if (memcmp(data, tls12_reserved_labels[i].label, | ||
| 273 | tls12_reserved_labels[i].label_len) == 0) { | ||
| 274 | SSLerror(s, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); | ||
| 275 | goto err; | ||
| 276 | } | ||
| 277 | } | ||
| 278 | |||
| 279 | CBS_init(&seed, data, data_len); | ||
| 280 | if (!CBS_skip(&seed, label_len)) | ||
| 281 | goto err; | ||
| 282 | |||
| 283 | if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length, | ||
| 284 | label, label_len, CBS_data(&seed), CBS_len(&seed), NULL, 0, NULL, 0, | ||
| 285 | NULL, 0, out, out_len)) | ||
| 286 | goto err; | ||
| 287 | |||
| 288 | ret = 1; | ||
| 289 | |||
| 290 | err: | ||
| 291 | freezero(data, data_len); | ||
| 292 | CBB_cleanup(&cbb); | ||
| 293 | |||
| 294 | return ret; | ||
| 295 | } | ||
