DHE Speed Up

When loading DH domain parameters into a CTX, test the prime
immediately. When loading them into a session, test the prime right
before using it during the handshake. Sessions that get their prime from
their context do not need to test their prime. Added a function to
disable testing the prime in a session. The goal is to speed up testing
as every single test case loads DH parameters whether they are used or
not.
This commit is contained in:
John Safranek
2018-11-29 17:01:37 -08:00
parent 2c48553a29
commit ff1a1dc5d5
5 changed files with 97 additions and 29 deletions

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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 */

View File

@ -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