From 303cafc9be92afee8a50da2ef2d7e7007f913fd6 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 13 Jan 2026 17:03:27 -0800 Subject: [PATCH] Add ML-KEM with Curve25519 and NISTp384 1. Reorganize the KEX test to allow for testing any KEX algorithm. Add test cases for the new algorithms to the KEX test. 2. Reorder the cannedKexAlgoNames with the ML-KEM algos first. 3. Add the new algos to wolfSSH_GetText(). 4. Add comments and whitespace cleanup. --- src/internal.c | 18 ++++++++----- src/ssh.c | 17 +++++++++++- tests/kex.c | 71 +++++++++++++++++++++++++++----------------------- 3 files changed, 66 insertions(+), 40 deletions(-) diff --git a/src/internal.c b/src/internal.c index 719a8eb9..f30fc518 100644 --- a/src/internal.c +++ b/src/internal.c @@ -146,8 +146,14 @@ Flags: Set when ECC or SHA2-512 are disabled. Set to disable use of ECDSA server authentication with prime NISTP521. WOLFSSH_NO_NISTP256_MLKEM768_SHA256 - Set when ML-KEM is disabled in wolfssl. Set to disable use of ECDHE with - prime NISTP256 hybridized with post-quantum ML-KEM 768. + Set when ML-KEM, ECC, or SHA2-256 are disabled in wolfssl. Set to disable + use of ECDHE with prime NISTP256 hybridized with post-quantum ML-KEM 768. + WOLFSSH_NO_NISTP384_MLKEM1024_SHA384 + Set when ML-KEM, ECC, or SHA2-384 are disabled in wolfssl. Set to disable + use of ECDHE with prime NISTP384 hybridized with post-quantum ML-KEM 1024. + WOLFSSH_NO_CURVE25519_MLKEM768_SHA256 + Set when ML-KEM, Curve25519, or SHA2-256 are disabled in wolfssl. Set to + disable use of Curve25519 hybridized with post-quantum ML-KEM 768. WOLFSSH_NO_AES_CBC_SOFT_DISABLE AES-CBC is normally soft-disabled. The default configuration will not advertise the availability of AES-CBC algorithms during KEX. AES-CBC @@ -847,14 +853,14 @@ int wolfSSH_TestIsMessageAllowed(WOLFSSH* ssh, byte msg, byte state) static const char cannedKexAlgoNames[] = -#if !defined(WOLFSSH_NO_NISTP256_MLKEM768_SHA256) - "mlkem768nistp256-sha256," +#if !defined(WOLFSSH_NO_CURVE25519_MLKEM768_SHA256) + "mlkem768x25519-sha256," #endif #if !defined(WOLFSSH_NO_NISTP384_MLKEM1024_SHA384) "mlkem1024nistp384-sha384," #endif -#if !defined(WOLFSSH_NO_CURVE25519_MLKEM768_SHA256) - "mlkem768x25519-sha256," +#if !defined(WOLFSSH_NO_NISTP256_MLKEM768_SHA256) + "mlkem768nistp256-sha256," #endif #ifndef WOLFSSH_NO_CURVE25519_SHA256 "curve25519-sha256," diff --git a/src/ssh.c b/src/ssh.c index d52d6105..4e16e111 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -3199,7 +3199,22 @@ size_t wolfSSH_GetText(WOLFSSH *ssh, WS_Text id, char *str, size_t strSz) #ifndef WOLFSSH_NO_NISTP256_MLKEM768_SHA256 case ID_NISTP256_MLKEM768_SHA256: - ret = WSNPRINTF(str, strSz, "%s", "ECDH-MLKEM768"); + ret = WSNPRINTF(str, strSz, "%s", + "ECDH-NISTP256-MLKEM768"); + break; + #endif + + #ifndef WOLFSSH_NO_NISTP384_MLKEM1024_SHA384 + case ID_NISTP384_MLKEM1024_SHA384: + ret = WSNPRINTF(str, strSz, "%s", + "ECDH-NISTP384-MLKEM1024"); + break; + #endif + + #ifndef WOLFSSH_NO_CURVE25519_MLKEM768_SHA256 + case ID_CURVE25519_MLKEM768_SHA256: + ret = WSNPRINTF(str, strSz, "%s", + "ECDH-CURVE25519-MLKEM768"); break; #endif diff --git a/tests/kex.c b/tests/kex.c index 24597706..1ce92487 100644 --- a/tests/kex.c +++ b/tests/kex.c @@ -138,9 +138,17 @@ #if !defined(NO_WOLFSSH_SERVER) && !defined(NO_WOLFSSH_CLIENT) && \ - !defined(SINGLE_THREADED) && !defined(WOLFSSH_TEST_BLOCK) && \ - !defined(WOLFSSH_NO_DH_GROUP16_SHA512) && !defined(WOLFSSH_NO_HMAC_SHA2_512) + !defined(SINGLE_THREADED) && !defined(WOLFSSH_TEST_BLOCK) + #if !defined(WOLFSSH_NO_DH_GROUP16_SHA512) \ + || !defined(WOLFSSH_NO_CURVE25519_MLKEM768_SHA256) \ + || !defined(WOLFSSH_NO_NISTP384_MLKEM1024_SHA384) + + #define KEXTEST_AVAILABLE + #endif +#endif + +#ifdef KEXTEST_AVAILABLE static int tsClientUserAuth(byte authType, WS_UserAuthData* authData, void* ctx) { static char password[] = "upthehill"; @@ -163,7 +171,7 @@ static int tsClientUserAuth(byte authType, WS_UserAuthData* authData, void* ctx) #define NUMARGS 12 #define ARGLEN 32 -/* +/* * Macro: ADD_ARG * Purpose: Adds a string argument to the argument list. * Parameters: @@ -185,7 +193,7 @@ static int tsClientUserAuth(byte authType, WS_UserAuthData* authData, void* ctx) WSTRNCPY((argList)[(argListCount)++], (arg), ARGLEN); \ } while (0) -/* +/* * Macro: ADD_ARG_INT * Purpose: Adds an integer argument to the argument list as a string. * Parameters: @@ -209,7 +217,7 @@ static int tsClientUserAuth(byte authType, WS_UserAuthData* authData, void* ctx) } while (0) -static int wolfSSH_wolfSSH_Group16_512(void) +static int wolfSSH_KexTest_Connect(const char* kex) { tcp_ready ready; THREAD_TYPE serverThread; @@ -226,27 +234,6 @@ static int wolfSSH_wolfSSH_Group16_512(void) int serverArgc = 0; int clientArgc = 0; - WSTARTTCP(); - - #if defined(DEBUG_WOLFSSH) - wolfSSH_Debugging_ON(); - #endif - - wolfSSH_Init(); - - #if defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,2) - { - int i; - for (i = 0; i < FIPS_CAST_COUNT; i++) { - wc_RunCast_fips(i); - } - } - #endif /* HAVE_FIPS */ - - #if !defined(WOLFSSL_TIRTOS) - ChangeToWolfSshRoot(); - #endif - InitTcpReady(&ready); ADD_ARG(serverArgv, serverArgc, "echoserver"); @@ -257,7 +244,7 @@ static int wolfSSH_wolfSSH_Group16_512(void) ADD_ARG(serverArgv, serverArgc, "-0"); #endif ADD_ARG(serverArgv, serverArgc, "-x"); - ADD_ARG(serverArgv, serverArgc, "diffie-hellman-group16-sha512"); + ADD_ARG(serverArgv, serverArgc, kex); ADD_ARG(serverArgv, serverArgc, "-m"); ADD_ARG(serverArgv, serverArgc, "hmac-sha2-512"); ADD_ARG(serverArgv, serverArgc, "-c"); @@ -318,7 +305,7 @@ static int wolfSSH_wolfSSH_Group16_512(void) return EXIT_SUCCESS; } -#endif +#endif /* KEXTEST_AVAILABLE */ int wolfSSH_KexTest(int argc, char** argv) { @@ -326,10 +313,19 @@ int wolfSSH_KexTest(int argc, char** argv) (void)argv; -#if defined(NO_WOLFSSH_SERVER) || defined(NO_WOLFSSH_CLIENT) || \ - defined(SINGLE_THREADED) || defined(WOLFSSH_TEST_BLOCK) +#if !defined(KEXTEST_AVAILABLE) return 77; #else + WSTARTTCP(); + + #if defined(DEBUG_WOLFSSH) + wolfSSH_Debugging_ON(); + #endif + + #if !defined(WOLFSSL_TIRTOS) + ChangeToWolfSshRoot(); + #endif + AssertIntEQ(wolfSSH_Init(), WS_SUCCESS); #if defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,2) @@ -341,14 +337,23 @@ int wolfSSH_KexTest(int argc, char** argv) } #endif /* HAVE_FIPS */ -#if !defined(WOLFSSH_NO_DH_GROUP16_SHA512) && !defined(WOLFSSH_NO_HMAC_SHA2_512) - wolfSSH_wolfSSH_Group16_512(); +#if !defined(WOLFSSH_NO_DH_GROUP16_SHA512) + AssertIntEQ(wolfSSH_KexTest_Connect("diffie-hellman-group16-sha512"), + EXIT_SUCCESS); +#endif +#if !defined(WOLFSSH_NO_CURVE25519_MLKEM768_SHA256) + AssertIntEQ(wolfSSH_KexTest_Connect("mlkem768x25519-sha256"), + EXIT_SUCCESS); +#endif +#if !defined(WOLFSSH_NO_NISTP384_MLKEM1024_SHA384) + AssertIntEQ(wolfSSH_KexTest_Connect("mlkem1024nistp384-sha384"), + EXIT_SUCCESS); #endif AssertIntEQ(wolfSSH_Cleanup(), WS_SUCCESS); return 0; -#endif +#endif /* KEXTEST_AVAILABLE */ }