From 2aee73ed90b3b47d0dd86875989003f0982ccf22 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Mon, 3 Aug 2026 06:43:16 +0000 Subject: [PATCH] upstream: fix ML-KEM/ECDH interop problem (does not affect mlkem768x25519-sha256) from markus@ OpenBSD-Commit-ID: 9c72e9c0407906bb7d5fb16648b38282676391e9 --- kex.h | 4 ++-- kexecdh.c | 31 +++++++++++++++++++++---------- kexmlkem768ecdh.c | 7 ++++--- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/kex.h b/kex.h index 373325686..3ce1c3328 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.132 2026/07/27 12:31:09 markus Exp $ */ +/* $OpenBSD: kex.h,v 1.133 2026/08/03 06:43:16 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -236,7 +236,7 @@ int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, int kex_dh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); int kex_ecdh_dec_key_group(struct kex *, const struct sshbuf *, EC_KEY *key, - const EC_GROUP *, struct sshbuf **); + const EC_GROUP *, int, struct sshbuf **); int kex_ecdh_keypair(struct kex *); int kex_ecdh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, diff --git a/kexecdh.c b/kexecdh.c index f1a0b4765..a9dbf5c4b 100644 --- a/kexecdh.c +++ b/kexecdh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexecdh.c,v 1.13 2026/07/27 12:28:52 markus Exp $ */ +/* $OpenBSD: kexecdh.c,v 1.14 2026/08/03 06:43:16 djm Exp $ */ /* * Copyright (c) 2010 Damien Miller. All rights reserved. * Copyright (c) 2019 Markus Friedl. All rights reserved. @@ -119,7 +119,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob, (r = sshbuf_get_u32(server_blob, NULL)) != 0) goto out; if ((r = kex_ecdh_dec_key_group(kex, client_blob, server_key, group, - shared_secretp)) != 0) + 0, shared_secretp)) != 0) goto out; *server_blobp = server_blob; server_blob = NULL; @@ -131,7 +131,7 @@ kex_ecdh_enc(struct kex *kex, const struct sshbuf *client_blob, int kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, - EC_KEY *key, const EC_GROUP *group, struct sshbuf **shared_secretp) + EC_KEY *key, const EC_GROUP *group, int raw, struct sshbuf **shared_secretp) { struct sshbuf *buf = NULL; BIGNUM *shared_secret = NULL; @@ -166,21 +166,32 @@ kex_ecdh_dec_key_group(struct kex *kex, const struct sshbuf *ec_blob, goto out; } klen = (EC_GROUP_get_degree(group) + 7) / 8; - if ((kbuf = malloc(klen)) == NULL || - (shared_secret = BN_new()) == NULL) { + if ((kbuf = malloc(klen)) == NULL) { r = SSH_ERR_ALLOC_FAIL; goto out; } - if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen || - BN_bin2bn(kbuf, klen, shared_secret) == NULL) { + if (ECDH_compute_key(kbuf, klen, dh_pub, key, NULL) != (int)klen) { r = SSH_ERR_LIBCRYPTO_ERROR; goto out; } #ifdef DEBUG_KEXECDH dump_digest("shared secret", kbuf, klen); #endif - if ((r = sshbuf_put_bignum2(buf, shared_secret)) != 0) - goto out; + if (raw) { + if ((r = sshbuf_put(buf, kbuf, klen)) != 0) + goto out; + } else { + if ((shared_secret = BN_new()) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if ((r = sshbuf_put_bignum2(buf, shared_secret)) != 0) + goto out; + } *shared_secretp = buf; buf = NULL; out: @@ -198,7 +209,7 @@ kex_ecdh_dec(struct kex *kex, const struct sshbuf *server_blob, int r; r = kex_ecdh_dec_key_group(kex, server_blob, kex->ec_client_key, - kex->ec_group, shared_secretp); + kex->ec_group, 0, shared_secretp); EC_KEY_free(kex->ec_client_key); kex->ec_client_key = NULL; return r; diff --git a/kexmlkem768ecdh.c b/kexmlkem768ecdh.c index 04c7a8fd2..b43b1b3cb 100644 --- a/kexmlkem768ecdh.c +++ b/kexmlkem768ecdh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexmlkem768ecdh.c,v 1.3 2026/07/30 07:30:41 dtucker Exp $ */ +/* $OpenBSD: kexmlkem768ecdh.c,v 1.4 2026/08/03 06:43:16 djm Exp $ */ /* * Copyright (c) 2025 Markus Friedl. All rights reserved. * @@ -191,7 +191,7 @@ kex_kem_mlkem768ecdh_enc(struct kex *kex, /* append ECDH shared key */ if ((r = kex_ecdh_dec_key_group(kex, ec_pub, server_key, group, - &ec_shared)) != 0 || + 1, &ec_shared)) != 0 || (r = sshbuf_putb(buf, ec_shared)) != 0) goto out; @@ -272,7 +272,8 @@ kex_kem_mlkem768ecdh_dec(struct kex *kex, r = SSH_ERR_ALLOC_FAIL; goto out; } - if ((r = kex_ecdh_dec(kex, ec_pub, &ec_shared)) != 0 || + if ((r = kex_ecdh_dec_key_group(kex, ec_pub, kex->ec_client_key, + kex->ec_group, 1, &ec_shared)) != 0 || (r = sshbuf_putb(buf, ec_shared)) != 0) goto out; if ((r = ssh_digest_buffer(kex->hash_alg, buf,