summaryrefslogtreecommitdiff
path: root/src/lib/libssl
diff options
context:
space:
mode:
authorbeck <>2025-12-04 21:16:17 +0000
committerbeck <>2025-12-04 21:16:17 +0000
commitdccd1f43a0c2de3852d9515f57353d756629c97a (patch)
tree7ffb1e1927c856374b227b21ca57105f14121045 /src/lib/libssl
parentf8fcf556caab3fb1fb9d9b496d2724345c90a3eb (diff)
downloadopenbsd-dccd1f43a0c2de3852d9515f57353d756629c97a.tar.gz
openbsd-dccd1f43a0c2de3852d9515f57353d756629c97a.tar.bz2
openbsd-dccd1f43a0c2de3852d9515f57353d756629c97a.zip
Hook up X25519MKLEM768 to the TLS 1.3 handshake
This does the following: 1) Adds a second key share prediction to the TLS 1.3 handshake. We only add one as we are unlikely to want to send more than one PQ one, and one classical one and are unlikely to waste bytes on a second PQ algorithm (anything that wants something else that we support can HRR to get it) 2) Adds X25519MLKEM768 (4588) to our list of supported groups. We add this to our preferred client and server key shares for TLS 1.3 and we now have a separate list for TLS 1.2 which does not do this, cleaning up the old "full list" from the comments. 3) Updates the golden magic numbers in the regression tests to allow for the above two things changing the handshake, so the regress tests pass. With this you can successfully hybrid PQ with servers and clients that support it. ok tb@ kenjiro@
Diffstat (limited to 'src/lib/libssl')
-rw-r--r--src/lib/libssl/s3_lib.c5
-rw-r--r--src/lib/libssl/ssl_local.h5
-rw-r--r--src/lib/libssl/ssl_tlsext.c51
-rw-r--r--src/lib/libssl/t1_lib.c64
-rw-r--r--src/lib/libssl/tls13_client.c14
5 files changed, 100 insertions, 39 deletions
diff --git a/src/lib/libssl/s3_lib.c b/src/lib/libssl/s3_lib.c
index 86b32aec15..bcf26bec40 100644
--- a/src/lib/libssl/s3_lib.c
+++ b/src/lib/libssl/s3_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: s3_lib.c,v 1.257 2024/07/23 14:40:53 jsing Exp $ */ 1/* $OpenBSD: s3_lib.c,v 1.258 2025/12/04 21:16:17 beck 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 *
@@ -1286,6 +1286,7 @@ ssl3_free(SSL *s)
1286 sk_X509_pop_free(s->s3->hs.peer_certs_no_leaf, X509_free); 1286 sk_X509_pop_free(s->s3->hs.peer_certs_no_leaf, X509_free);
1287 sk_X509_pop_free(s->s3->hs.verified_chain, X509_free); 1287 sk_X509_pop_free(s->s3->hs.verified_chain, X509_free);
1288 tls_key_share_free(s->s3->hs.key_share); 1288 tls_key_share_free(s->s3->hs.key_share);
1289 tls_key_share_free(s->s3->hs.tls13.key_share);
1289 1290
1290 tls13_secrets_destroy(s->s3->hs.tls13.secrets); 1291 tls13_secrets_destroy(s->s3->hs.tls13.secrets);
1291 freezero(s->s3->hs.tls13.cookie, s->s3->hs.tls13.cookie_len); 1292 freezero(s->s3->hs.tls13.cookie, s->s3->hs.tls13.cookie_len);
@@ -1337,6 +1338,8 @@ ssl3_clear(SSL *s)
1337 1338
1338 tls_key_share_free(s->s3->hs.key_share); 1339 tls_key_share_free(s->s3->hs.key_share);
1339 s->s3->hs.key_share = NULL; 1340 s->s3->hs.key_share = NULL;
1341 tls_key_share_free(s->s3->hs.tls13.key_share);
1342 s->s3->hs.tls13.key_share = NULL;
1340 1343
1341 tls13_secrets_destroy(s->s3->hs.tls13.secrets); 1344 tls13_secrets_destroy(s->s3->hs.tls13.secrets);
1342 s->s3->hs.tls13.secrets = NULL; 1345 s->s3->hs.tls13.secrets = NULL;
diff --git a/src/lib/libssl/ssl_local.h b/src/lib/libssl/ssl_local.h
index 9921c3a730..7942c36dbd 100644
--- a/src/lib/libssl/ssl_local.h
+++ b/src/lib/libssl/ssl_local.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_local.h,v 1.34 2025/10/24 09:23:06 tb Exp $ */ 1/* $OpenBSD: ssl_local.h,v 1.35 2025/12/04 21:16:17 beck 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 *
@@ -490,6 +490,9 @@ typedef struct ssl_handshake_tls13_st {
490 /* Certificate selected for use (static pointer). */ 490 /* Certificate selected for use (static pointer). */
491 const SSL_CERT_PKEY *cpk; 491 const SSL_CERT_PKEY *cpk;
492 492
493 /* Client's extra predicted key share */
494 struct tls_key_share *key_share;
495
493 /* Version proposed by peer server. */ 496 /* Version proposed by peer server. */
494 uint16_t server_version; 497 uint16_t server_version;
495 498
diff --git a/src/lib/libssl/ssl_tlsext.c b/src/lib/libssl/ssl_tlsext.c
index dcd9a31205..d879b3304e 100644
--- a/src/lib/libssl/ssl_tlsext.c
+++ b/src/lib/libssl/ssl_tlsext.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_tlsext.c,v 1.158 2025/12/04 21:03:42 beck Exp $ */ 1/* $OpenBSD: ssl_tlsext.c,v 1.159 2025/12/04 21:16:17 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org>
4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org> 4 * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@@ -1445,7 +1445,7 @@ tlsext_keyshare_client_needs(SSL *s, uint16_t msg_type)
1445static int 1445static int
1446tlsext_keyshare_client_build(SSL *s, uint16_t msg_type, CBB *cbb) 1446tlsext_keyshare_client_build(SSL *s, uint16_t msg_type, CBB *cbb)
1447{ 1447{
1448 CBB client_shares, key_exchange; 1448 CBB client_shares, key_exchange, key_exchange2;
1449 1449
1450 if (!CBB_add_u16_length_prefixed(cbb, &client_shares)) 1450 if (!CBB_add_u16_length_prefixed(cbb, &client_shares))
1451 return 0; 1451 return 0;
@@ -1458,6 +1458,31 @@ tlsext_keyshare_client_build(SSL *s, uint16_t msg_type, CBB *cbb)
1458 if (!tls_key_share_public(s->s3->hs.key_share, &key_exchange)) 1458 if (!tls_key_share_public(s->s3->hs.key_share, &key_exchange))
1459 return 0; 1459 return 0;
1460 1460
1461 /*
1462 * We wish to include a second key share prediction in a TLS 1.3 client
1463 * hello if we have more than one preferred group. We never wish to do
1464 * this in response to a server selected group (Either from a TLS 1.2
1465 * server, or from a hello retry request after having negotiated TLS
1466 * 1.3).
1467 *
1468 * Therefore we only do this if we have not yet negotiated
1469 * a version, and our max version could negotiate TLS 1.3.
1470 */
1471 if (s->s3->hs.negotiated_tls_version == 0 &&
1472 s->s3->hs.our_max_tls_version >= TLS1_3_VERSION) {
1473 if (s->s3->hs.tls13.key_share != NULL) {
1474 if (!CBB_add_u16(&client_shares,
1475 tls_key_share_group(s->s3->hs.tls13.key_share)))
1476 return 0;
1477 if (!CBB_add_u16_length_prefixed(&client_shares,
1478 &key_exchange2))
1479 return 0;
1480 if (!tls_key_share_public(s->s3->hs.tls13.key_share,
1481 &key_exchange2))
1482 return 0;
1483 }
1484 }
1485
1461 if (!CBB_flush(cbb)) 1486 if (!CBB_flush(cbb))
1462 return 0; 1487 return 0;
1463 1488
@@ -1687,10 +1712,32 @@ tlsext_keyshare_client_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
1687 *alert = SSL_AD_INTERNAL_ERROR; 1712 *alert = SSL_AD_INTERNAL_ERROR;
1688 return 0; 1713 return 0;
1689 } 1714 }
1715
1716 if (s->s3->hs.tls13.server_version >= TLS1_3_VERSION &&
1717 tls_key_share_group(s->s3->hs.key_share) != group &&
1718 s->s3->hs.tls13.key_share != NULL &&
1719 tls_key_share_group(s->s3->hs.tls13.key_share) == group) {
1720 /*
1721 * Server chose our second key share prediction, switch to it,
1722 * and discard the first one.
1723 */
1724 tls_key_share_free(s->s3->hs.key_share);
1725 s->s3->hs.key_share = s->s3->hs.tls13.key_share;
1726 s->s3->hs.tls13.key_share = NULL;
1727 }
1728
1690 if (tls_key_share_group(s->s3->hs.key_share) != group) { 1729 if (tls_key_share_group(s->s3->hs.key_share) != group) {
1691 *alert = SSL_AD_INTERNAL_ERROR; 1730 *alert = SSL_AD_INTERNAL_ERROR;
1692 return 0; 1731 return 0;
1693 } 1732 }
1733
1734 /*
1735 * Discard our now unused second key share prediction if we had made one
1736 * with our initial 1.3 client hello
1737 */
1738 tls_key_share_free(s->s3->hs.tls13.key_share);
1739 s->s3->hs.tls13.key_share = NULL;
1740
1694 if (!tls_key_share_client_peer_public(s->s3->hs.key_share, 1741 if (!tls_key_share_client_peer_public(s->s3->hs.key_share,
1695 &key_exchange, &decode_error, NULL)) { 1742 &key_exchange, &decode_error, NULL)) {
1696 if (!decode_error) 1743 if (!decode_error)
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index 57cd180d09..912bea592a 100644
--- a/src/lib/libssl/t1_lib.c
+++ b/src/lib/libssl/t1_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: t1_lib.c,v 1.206 2025/05/31 15:17:11 tb Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.207 2025/12/04 21:16:17 beck 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 *
@@ -306,6 +306,11 @@ static const struct supported_group nid_list[] = {
306 .nid = NID_X25519, 306 .nid = NID_X25519,
307 .bits = 128, 307 .bits = 128,
308 }, 308 },
309 {
310 .group_id = 4588,
311 .nid = NID_X25519MLKEM768,
312 .bits = 128,
313 },
309}; 314};
310 315
311#define NID_LIST_LEN (sizeof(nid_list) / sizeof(nid_list[0])) 316#define NID_LIST_LEN (sizeof(nid_list) / sizeof(nid_list[0]))
@@ -322,41 +327,21 @@ static const uint8_t ecformats_default[] = {
322 TLSEXT_ECPOINTFORMAT_uncompressed, 327 TLSEXT_ECPOINTFORMAT_uncompressed,
323}; 328};
324 329
325#if 0 330static const uint16_t ecgroups_tls12_client_default[] = {
326static const uint16_t ecgroups_list[] = {
327 29, /* X25519 (29) */ 331 29, /* X25519 (29) */
328 14, /* sect571r1 (14) */ 332 23, /* secp256r1 (23) */
329 13, /* sect571k1 (13) */
330 25, /* secp521r1 (25) */
331 28, /* brainpoolP512r1 (28) */
332 11, /* sect409k1 (11) */
333 12, /* sect409r1 (12) */
334 27, /* brainpoolP384r1 (27) */
335 24, /* secp384r1 (24) */ 333 24, /* secp384r1 (24) */
336 9, /* sect283k1 (9) */ 334 25, /* secp521r1 (25) */
337 10, /* sect283r1 (10) */ 335};
338 26, /* brainpoolP256r1 (26) */ 336
339 22, /* secp256k1 (22) */ 337static const uint16_t ecgroups_tls12_server_default[] = {
338 29, /* X25519 (29) */
340 23, /* secp256r1 (23) */ 339 23, /* secp256r1 (23) */
341 8, /* sect239k1 (8) */ 340 24, /* secp384r1 (24) */
342 6, /* sect233k1 (6) */
343 7, /* sect233r1 (7) */
344 20, /* secp224k1 (20) */
345 21, /* secp224r1 (21) */
346 4, /* sect193r1 (4) */
347 5, /* sect193r2 (5) */
348 18, /* secp192k1 (18) */
349 19, /* secp192r1 (19) */
350 1, /* sect163k1 (1) */
351 2, /* sect163r1 (2) */
352 3, /* sect163r2 (3) */
353 15, /* secp160k1 (15) */
354 16, /* secp160r1 (16) */
355 17, /* secp160r2 (17) */
356}; 341};
357#endif
358 342
359static const uint16_t ecgroups_client_default[] = { 343static const uint16_t ecgroups_client_default[] = {
344 4588, /* X25519MLKEM768 (4588) */
360 29, /* X25519 (29) */ 345 29, /* X25519 (29) */
361 23, /* secp256r1 (23) */ 346 23, /* secp256r1 (23) */
362 24, /* secp384r1 (24) */ 347 24, /* secp384r1 (24) */
@@ -364,6 +349,7 @@ static const uint16_t ecgroups_client_default[] = {
364}; 349};
365 350
366static const uint16_t ecgroups_server_default[] = { 351static const uint16_t ecgroups_server_default[] = {
352 4588, /* X25519MLKEM768 (4588) */
367 29, /* X25519 (29) */ 353 29, /* X25519 (29) */
368 23, /* secp256r1 (23) */ 354 23, /* secp256r1 (23) */
369 24, /* secp384r1 (24) */ 355 24, /* secp384r1 (24) */
@@ -478,11 +464,21 @@ tls1_get_group_list(const SSL *s, int client_groups, const uint16_t **pgroups,
478 return; 464 return;
479 465
480 if (!s->server) { 466 if (!s->server) {
481 *pgroups = ecgroups_client_default; 467 if (s->s3->hs.our_max_tls_version >= TLS1_3_VERSION) {
482 *pgroupslen = sizeof(ecgroups_client_default) / 2; 468 *pgroups = ecgroups_client_default;
469 *pgroupslen = sizeof(ecgroups_client_default) / 2;
470 } else {
471 *pgroups = ecgroups_tls12_client_default;
472 *pgroupslen = sizeof(ecgroups_tls12_client_default) / 2;
473 }
483 } else { 474 } else {
484 *pgroups = ecgroups_server_default; 475 if (s->s3->hs.our_max_tls_version >= TLS1_3_VERSION) {
485 *pgroupslen = sizeof(ecgroups_server_default) / 2; 476 *pgroups = ecgroups_server_default;
477 *pgroupslen = sizeof(ecgroups_server_default) / 2;
478 } else {
479 *pgroups = ecgroups_tls12_server_default;
480 *pgroupslen = sizeof(ecgroups_tls12_server_default) / 2;
481 }
486 } 482 }
487} 483}
488 484
diff --git a/src/lib/libssl/tls13_client.c b/src/lib/libssl/tls13_client.c
index b0a285694d..21d3960796 100644
--- a/src/lib/libssl/tls13_client.c
+++ b/src/lib/libssl/tls13_client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls13_client.c,v 1.105 2025/12/04 21:03:42 beck Exp $ */ 1/* $OpenBSD: tls13_client.c,v 1.106 2025/12/04 21:16:17 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2018, 2019 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -56,6 +56,18 @@ tls13_client_init(struct tls13_ctx *ctx)
56 if (!tls_key_share_client_generate(ctx->hs->key_share)) 56 if (!tls_key_share_client_generate(ctx->hs->key_share))
57 return 0; 57 return 0;
58 58
59 /*
60 * Generate a second key share prediction if we have another
61 * supported group
62 */
63 if (groups_len > 1) {
64 if ((ctx->hs->tls13.key_share = tls_key_share_new(groups[1])) ==
65 NULL)
66 return 0;
67 if (!tls_key_share_client_generate(ctx->hs->tls13.key_share))
68 return 0;
69 }
70
59 arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE); 71 arc4random_buf(s->s3->client_random, SSL3_RANDOM_SIZE);
60 72
61 /* 73 /*