diff --git a/examples/server/server.c b/examples/server/server.c index 7a8a57df5..47bce5fa0 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -670,6 +670,7 @@ static void Usage(void) #ifdef WOLFSSL_EARLY_DATA printf("%s", msg[++msgId]); /* -0 */ #endif + printf("-X Disable DH Prime check\n"); #ifdef WOLFSSL_MULTICAST printf("%s", msg[++msgId]); /* -3 */ #endif @@ -732,6 +733,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) short minEccKeyBits = DEFAULT_MIN_ECCKEY_BITS; int doListen = 1; int crlFlags = 0; + int doDhKeyCheck = 1; int ret; int err = 0; char* serverReadyFile = NULL; @@ -830,6 +832,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) (void)alpnList; (void)alpn_opt; (void)crlFlags; + (void)doDhKeyCheck; (void)readySignal; (void)updateKeysIVs; (void)postHandAuth; @@ -843,10 +846,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #ifdef WOLFSSL_VXWORKS useAnyAddr = 1; #else - /* Not Used: h, m, z, F, M, T, V, W, X */ + /* Not Used: h, m, z, F, M, T, V, W */ while ((ch = mygetopt(argc, argv, "?:" "abc:defgijk:l:nop:q:rstuv:wxy" - "A:B:C:D:E:GH:IJKL:NO:PQR:S:TUVYZ:" + "A:B:C:D:E:GH:IJKL:NO:PQR:S:TUVXYZ:" "01:3:")) != -1) { switch (ch) { case '?' : @@ -1153,6 +1156,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif break; + case 'X' : + doDhKeyCheck = 0; + break; + case '0' : #ifdef WOLFSSL_EARLY_DATA earlyData = 1; @@ -1765,6 +1772,11 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #elif !defined(NO_DH) SetDH(ssl); /* repick suites with DHE, higher priority than PSK */ #endif +#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) + if (!doDhKeyCheck) + wolfSSL_SetEnableDhKeyTest(ssl, 0); +#endif } #ifndef WOLFSSL_CALLBACKS diff --git a/src/internal.c b/src/internal.c index c19cd0fa8..f10e6fef0 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4392,6 +4392,10 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->options.groupMessages = ctx->groupMessages; #ifndef NO_DH + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) + ssl->options.dhKeyTested = ctx->dhKeyTested; + #endif ssl->buffers.serverDH_P = ctx->serverDH_P; ssl->buffers.serverDH_G = ctx->serverDH_G; #endif @@ -4689,6 +4693,12 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->options.buildMsgState = BUILD_MSG_BEGIN; ssl->encrypt.state = CIPHER_STATE_BEGIN; ssl->decrypt.state = CIPHER_STATE_BEGIN; +#ifndef NO_DH + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) + ssl->options.dhDoKeyTest = 1; + #endif +#endif #ifdef WOLFSSL_DTLS #ifdef WOLFSSL_SCTP @@ -19588,21 +19598,21 @@ int SendClientKeyExchange(WOLFSSL* ssl) goto exit_scke; } -#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \ - !defined(WOLFSSL_OLD_PRIME_CHECK) + #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \ + !defined(WOLFSSL_OLD_PRIME_CHECK) ret = wc_DhSetCheckKey(ssl->buffers.serverDH_Key, ssl->buffers.serverDH_P.buffer, ssl->buffers.serverDH_P.length, ssl->buffers.serverDH_G.buffer, ssl->buffers.serverDH_G.length, NULL, 0, 0, ssl->rng); -#else + #else ret = wc_DhSetKey(ssl->buffers.serverDH_Key, ssl->buffers.serverDH_P.buffer, ssl->buffers.serverDH_P.length, ssl->buffers.serverDH_G.buffer, ssl->buffers.serverDH_G.length); -#endif + #endif if (ret != 0) { goto exit_scke; } @@ -21431,13 +21441,35 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, goto exit_sske; } - ret = wc_DhSetKey(ssl->buffers.serverDH_Key, - ssl->buffers.serverDH_P.buffer, - ssl->buffers.serverDH_P.length, - ssl->buffers.serverDH_G.buffer, - ssl->buffers.serverDH_G.length); - if (ret != 0) { - goto exit_sske; + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \ + !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) + if (ssl->options.dhDoKeyTest && + !ssl->options.dhKeyTested) + { + ret = wc_DhSetCheckKey( + ssl->buffers.serverDH_Key, + ssl->buffers.serverDH_P.buffer, + ssl->buffers.serverDH_P.length, + ssl->buffers.serverDH_G.buffer, + ssl->buffers.serverDH_G.length, + NULL, 0, 0, ssl->rng); + if (ret != 0) { + goto exit_sske; + } + ssl->options.dhKeyTested = 1; + } + else + #endif + { + ret = wc_DhSetKey(ssl->buffers.serverDH_Key, + ssl->buffers.serverDH_P.buffer, + ssl->buffers.serverDH_P.length, + ssl->buffers.serverDH_G.buffer, + ssl->buffers.serverDH_G.length); + if (ret != 0) { + goto exit_sske; + } } ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key, diff --git a/src/ssl.c b/src/ssl.c index 99bd48497..ce5add06d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1482,21 +1482,8 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz, #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \ !defined(HAVE_SELFTEST) - { - DhKey checkKey; - int error, freeKey = 0; - - error = wc_InitDhKey(&checkKey); - if (!error) { - freeKey = 1; - error = wc_DhSetCheckKey(&checkKey, - p, pSz, g, gSz, NULL, 0, 0, ssl->rng); - } - if (freeKey) - wc_FreeDhKey(&checkKey); - if (error) - return error; - } + ssl->options.dhKeyTested = 0; + ssl->options.dhDoKeyTest = 1; #endif if (ssl->buffers.serverDH_P.buffer && ssl->buffers.weOwnDH) { @@ -1555,6 +1542,28 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz, return WOLFSSL_SUCCESS; } + +#if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) +/* Enables or disables the session's DH key prime test. */ +int wolfSSL_SetEnableDhKeyTest(WOLFSSL* ssl, int enable) +{ + WOLFSSL_ENTER("wolfSSL_SetEnableDhKeyTest"); + + if (ssl == NULL) + return BAD_FUNC_ARG; + + if (!enable) + ssl->options.dhDoKeyTest = 0; + else + ssl->options.dhDoKeyTest = 1; + + WOLFSSL_LEAVE("wolfSSL_SetEnableDhKeyTest", WOLFSSL_SUCCESS); + return WOLFSSL_SUCCESS; +} +#endif + + /* server ctx Diffie-Hellman parameters, WOLFSSL_SUCCESS on ok */ int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz, const unsigned char* g, int gSz) @@ -1587,6 +1596,8 @@ int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz, wc_FreeRng(&rng); if (error) return error; + + ctx->dhKeyTested = 1; } #endif diff --git a/wolfssl/internal.h b/wolfssl/internal.h index d6a855384..2cb9cce87 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2531,6 +2531,12 @@ struct WOLFSSL_CTX { #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) byte postHandshakeAuth:1; /* Post-handshake auth supported. */ #endif +#ifndef NO_DH + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && !defined(HAVE_FIPS) && \ + !defined(HAVE_SELFTEST) + byte dhKeyTested:1; /* Set when key has been tested. */ + #endif +#endif #ifdef WOLFSSL_MULTICAST byte haveMcast; /* multicast requested */ byte mcastID; /* multicast group ID */ @@ -3240,7 +3246,13 @@ typedef struct Options { !defined(NO_ED25519_CLIENT_AUTH) word16 cacheMessages:1; /* Cache messages for sign/verify */ #endif - +#ifndef NO_DH + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \ + !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + word16 dhDoKeyTest:1; /* Need to do the DH Key prime test */ + word16 dhKeyTested:1; /* Set when key has been tested. */ + #endif +#endif /* need full byte values for this section */ byte processReply; /* nonblocking resume */ byte cipherSuite0; /* first byte, normally 0 */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 1f6a22649..5b6efab44 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1649,6 +1649,7 @@ WOLFSSL_API int wolfSSL_SetTmpDH(WOLFSSL*, const unsigned char* p, int pSz, const unsigned char* g, int gSz); WOLFSSL_API int wolfSSL_SetTmpDH_buffer(WOLFSSL*, const unsigned char* b, long sz, int format); +WOLFSSL_API int wolfSSL_SetEnableDhKeyTest(WOLFSSL*, int); #ifndef NO_FILESYSTEM WOLFSSL_API int wolfSSL_SetTmpDH_file(WOLFSSL*, const char* f, int format); #endif