summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libssl/ssl_lib.c21
-rw-r--r--src/lib/libssl/ssl_locl.h5
-rw-r--r--src/lib/libssl/t1_enc.c82
-rw-r--r--src/lib/libssl/tls12_internal.h29
-rw-r--r--src/lib/libssl/tls12_key_schedule.c122
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
167const char *SSL_version_str = OPENSSL_VERSION_TEXT; 168const 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
1869int 1870int
1870SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, 1871SSL_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
1887static unsigned long 1888static 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);
1463int tls1_change_write_cipher_state(SSL *s); 1463int tls1_change_write_cipher_state(SSL *s);
1464int tls1_setup_key_block(SSL *s); 1464int tls1_setup_key_block(SSL *s);
1465int tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len); 1465int tls1_generate_key_block(SSL *s, uint8_t *key_block, size_t key_block_len);
1466int 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);
1469int ssl_ok(SSL *s); 1466int ssl_ok(SSL *s);
1470 1467
1471int tls12_derive_finished(SSL *s); 1468int 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
417int
418tls1_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
23int 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
25struct tls12_key_block { 26struct 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
178struct tls12_reserved_label {
179 const char *label;
180 size_t label_len;
181};
182
183/*
184 * RFC 5705 section 6.
185 */
186static 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
209int
210tls12_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}