diff options
-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 | } | ||