diff --git a/IDE/WIN10/user_settings.h b/IDE/WIN10/user_settings.h index cdfae92b5..a44606c47 100644 --- a/IDE/WIN10/user_settings.h +++ b/IDE/WIN10/user_settings.h @@ -85,7 +85,7 @@ #define HAVE_FFDHE_4096 #define HAVE_FFDHE_6144 #define HAVE_FFDHE_8192 - #define FP_MAX_BITS=16384 + #define FP_MAX_BITS 16384 #endif /* FIPS v5 */ #else /* Enables blinding mode, to prevent timing attacks */ diff --git a/src/internal.c b/src/internal.c index 2daec0f6c..fcfdc5d0e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -23401,7 +23401,6 @@ static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size, int ret = 0; word16 length; #ifdef HAVE_FFDHE - const DhParams* params = NULL; word16 group = 0; #endif @@ -23567,31 +23566,26 @@ static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size, switch (ssl->options.dhKeySz) { #ifdef HAVE_FFDHE_2048 case 2048/8: - params = wc_Dh_ffdhe2048_Get(); group = WOLFSSL_FFDHE_2048; break; #endif #ifdef HAVE_FFDHE_3072 case 3072/8: - params = wc_Dh_ffdhe3072_Get(); group = WOLFSSL_FFDHE_3072; break; #endif #ifdef HAVE_FFDHE_4096 case 4096/8: - params = wc_Dh_ffdhe4096_Get(); group = WOLFSSL_FFDHE_4096; break; #endif #ifdef HAVE_FFDHE_6144 case 6144/8: - params = wc_Dh_ffdhe6144_Get(); group = WOLFSSL_FFDHE_6144; break; #endif #ifdef HAVE_FFDHE_8192 case 8192/8: - params = wc_Dh_ffdhe8192_Get(); group = WOLFSSL_FFDHE_8192; break; #endif @@ -23599,11 +23593,10 @@ static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size, break; } - if (params == NULL || params->g_len != ssl->buffers.serverDH_G.length || - (XMEMCMP(ssl->buffers.serverDH_G.buffer, params->g, - params->g_len) != 0) || - (XMEMCMP(ssl->buffers.serverDH_P.buffer, params->p, - params->p_len) != 0)) { + if (!wc_DhCmpNamedKey(group, 1, + ssl->buffers.serverDH_P.buffer, ssl->buffers.serverDH_P.length, + NULL, 0, + ssl->buffers.serverDH_G.buffer, ssl->buffers.serverDH_G.length)) { WOLFSSL_MSG("Server not using FFDHE parameters"); #ifdef WOLFSSL_REQUIRE_FFDHE SendAlert(ssl, alert_fatal, handshake_failure); @@ -26870,6 +26863,65 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, !defined(WOLFSSL_NO_TLS12)) case diffie_hellman_kea: #endif +#if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) + if (ssl->namedGroup) { + word32 pSz = 0; + + wc_DhGetNamedKeyParamSize(ssl->namedGroup, &pSz, + NULL, NULL); + + if (ssl->buffers.serverDH_Pub.buffer == NULL) { + /* Free'd in SSL_ResourceFree and + * FreeHandshakeResources */ + ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC( + pSz + OPAQUE16_LEN, + ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (ssl->buffers.serverDH_Pub.buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_sske); + } + ssl->buffers.serverDH_Pub.length = + pSz + OPAQUE16_LEN; + } + if (ssl->buffers.serverDH_Priv.buffer == NULL) { + /* Free'd in SSL_ResourceFree and + * FreeHandshakeResources */ + ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC( + pSz + OPAQUE16_LEN, + ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + if (ssl->buffers.serverDH_Priv.buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_sske); + } + ssl->buffers.serverDH_Priv.length = + pSz + OPAQUE16_LEN; + } + + ssl->options.dhKeySz =(word16)pSz; + + ret = AllocKey(ssl, DYNAMIC_TYPE_DH, + (void**)&ssl->buffers.serverDH_Key); + if (ret != 0) { + goto exit_sske; + } + + ret = wc_DhSetNamedKey(ssl->buffers.serverDH_Key, + ssl->namedGroup); + if (ret != 0) { + goto exit_sske; + } + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \ + !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + ssl->options.dhKeyTested = 1; + #endif + + ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key, + ssl->buffers.serverDH_Priv.buffer, + (word32*)&ssl->buffers.serverDH_Priv.length, + ssl->buffers.serverDH_Pub.buffer, + (word32*)&ssl->buffers.serverDH_Pub.length); + break; + } + else +#endif { /* Allocate DH key buffers and generate key */ if (ssl->buffers.serverDH_P.buffer == NULL || diff --git a/src/sniffer.c b/src/sniffer.c index 6cfb52548..08241f3d6 100644 --- a/src/sniffer.c +++ b/src/sniffer.c @@ -2282,25 +2282,17 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, /* Static DH Key */ if (ksInfo && ksInfo->dh_key_bits != 0 && keys->dhKey) { DhKey dhKey; +#ifdef HAVE_PUBLIC_FFDHE const DhParams* params; word32 privKeySz; +#else + word32 privKeySz = 0, p_len = 0; +#endif byte privKey[52]; /* max for TLS */ keyBuf = keys->dhKey; -#ifdef WOLFSSL_SNIFFER_KEY_CALLBACK - if (KeyCb != NULL) { - ret = KeyCb(session, ksInfo->named_group, - session->srvKs.key, session->srvKs.key_len, - session->cliKs.key, session->cliKs.key_len, - keyBuf, KeyCbCtx, error); - if (ret != 0) { - SetError(-1, error, session, FATAL_ERROR_STATE); - return ret; - } - } -#endif - +#ifdef HAVE_PUBLIC_FFDHE /* get DH params */ switch (ksInfo->named_group) { #ifdef HAVE_FFDHE_2048 @@ -2336,16 +2328,28 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, default: return BAD_FUNC_ARG; } +#endif - ret = wc_InitDhKey_ex(&dhKey, NULL, devId); + ret = wc_InitDhKey(&dhKey); if (ret == 0) { +#ifdef HAVE_PUBLIC_FFDHE ret = wc_DhSetKey(&dhKey, (byte*)params->p, params->p_len, (byte*)params->g, params->g_len); +#else + ret = wc_DhSetNamedKey(&dhKey, ksInfo->named_group); +#endif if (ret == 0) { ret = wc_DhKeyDecode(keyBuf->buffer, &idx, &dhKey, keyBuf->length); } +#ifndef HAVE_PUBLIC_FFDHE + if (ret == 0) { + privKeySz = wc_DhGetNamedKeyMinSize(ksInfo->named_group); + ret = wc_DhGetNamedKeyParamSize(ksInfo->named_group, + &p_len, NULL, NULL); + } +#endif if (ret == 0) { ret = wc_DhExportKeyPair(&dhKey, privKey, &privKeySz, NULL, NULL); @@ -2354,7 +2358,7 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, /* Derive secret from private key and peer's public key */ do { #ifdef WOLFSSL_ASYNC_CRYPT - ret = wc_AsyncWait(ret, &dhKey.asyncDev, + ret = wc_AsyncWait(ret, &dhPriv.asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); #endif if (ret >= 0) { @@ -2367,21 +2371,27 @@ static int SetupKeys(const byte* input, int* sslBytes, SnifferSession* session, } while (ret == WC_PENDING_E); wc_FreeDhKey(&dhKey); - - #ifdef WOLFSSL_SNIFFER_STATS - if (ret != 0) - INC_STAT(SnifferStats.sslKeyFails); - #endif - + /* left-padded with zeros up to the size of the prime */ - if (ret == 0 && params->p_len > session->sslServer->arrays->preMasterSz) { +#ifdef HAVE_PUBLIC_FFDHE + if (params->p_len > session->sslServer->arrays->preMasterSz) { word32 diff = params->p_len - session->sslServer->arrays->preMasterSz; XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff, - session->sslServer->arrays->preMasterSecret, + session->sslServer->arrays->preMasterSecret, session->sslServer->arrays->preMasterSz); XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff); session->sslServer->arrays->preMasterSz = params->p_len; } +#else /* HAVE_PUBLIC_FFDHE */ + if (p_len > session->sslServer->arrays->preMasterSz) { + word32 diff = p_len - session->sslServer->arrays->preMasterSz; + XMEMMOVE(session->sslServer->arrays->preMasterSecret + diff, + session->sslServer->arrays->preMasterSecret, + session->sslServer->arrays->preMasterSz); + XMEMSET(session->sslServer->arrays->preMasterSecret, 0, diff); + session->sslServer->arrays->preMasterSz = p_len; + } +#endif /* HAVE_PUBLIC_FFDHE */ } } #endif /* !NO_DH && WOLFSSL_DH_EXTRA */ diff --git a/src/tls.c b/src/tls.c index 63ef41d0c..9246f4fb9 100644 --- a/src/tls.c +++ b/src/tls.c @@ -4171,7 +4171,7 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl) SupportedCurve* serverGroup; SupportedCurve* clientGroup; SupportedCurve* group; - const DhParams* params = NULL; + word32 p_len; int found = 0; extension = TLSX_Find(ssl->extensions, TLSX_SUPPORTED_GROUPS); @@ -4220,39 +4220,11 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl) if (serverGroup->name != group->name) continue; - switch (serverGroup->name) { - #ifdef HAVE_FFDHE_2048 - case WOLFSSL_FFDHE_2048: - params = wc_Dh_ffdhe2048_Get(); - break; - #endif - #ifdef HAVE_FFDHE_3072 - case WOLFSSL_FFDHE_3072: - params = wc_Dh_ffdhe3072_Get(); - break; - #endif - #ifdef HAVE_FFDHE_4096 - case WOLFSSL_FFDHE_4096: - params = wc_Dh_ffdhe4096_Get(); - break; - #endif - #ifdef HAVE_FFDHE_6144 - case WOLFSSL_FFDHE_6144: - params = wc_Dh_ffdhe6144_Get(); - break; - #endif - #ifdef HAVE_FFDHE_8192 - case WOLFSSL_FFDHE_8192: - params = wc_Dh_ffdhe8192_Get(); - break; - #endif - default: - break; - } - if (params == NULL) + wc_DhGetNamedKeyParamSize(serverGroup->name, &p_len, NULL, NULL); + if (p_len == 0) return BAD_FUNC_ARG; - if (params->p_len >= ssl->options.minDhKeySz && - params->p_len <= ssl->options.maxDhKeySz) { + if (p_len >= ssl->options.minDhKeySz && + p_len <= ssl->options.maxDhKeySz) { break; } } @@ -4262,15 +4234,26 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl) } if (serverGroup) { - ssl->buffers.serverDH_P.buffer = (unsigned char *)params->p; - ssl->buffers.serverDH_P.length = params->p_len; - ssl->buffers.serverDH_G.buffer = (unsigned char *)params->g; - ssl->buffers.serverDH_G.length = params->g_len; + word32 pSz, gSz; + + ret = wc_DhGetNamedKeyParamSize(serverGroup->name, &pSz, &gSz, NULL); + ssl->buffers.serverDH_P.buffer = (byte*)XMALLOC(pSz, + ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + ssl->buffers.serverDH_P.length = pSz; + ssl->buffers.serverDH_G.buffer = (byte*)XMALLOC(gSz, + ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + ssl->buffers.serverDH_G.length = gSz; + wc_DhCopyNamedKey(serverGroup->name, + ssl->buffers.serverDH_P.buffer, &pSz, + ssl->buffers.serverDH_G.buffer, &gSz, + NULL, NULL); ssl->namedGroup = serverGroup->name; + #if !defined(WOLFSSL_OLD_PRIME_CHECK) && \ !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) ssl->options.dhDoKeyTest = 0; #endif + ssl->buffers.weOwnDH = 1; ssl->options.haveDH = 1; } @@ -6047,14 +6030,26 @@ static int TLSX_SetSignatureAlgorithmsCert(TLSX** extensions, const void* data, */ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse) { - int ret = 0; -#if !defined(NO_DH) && (!defined(NO_CERTS) || !defined(NO_PSK)) - word32 keySz = 0; - const DhParams* params = NULL; - DhKey* dhKey = (DhKey*)kse->key; + int ret; +#ifndef NO_DH + byte* keyData = NULL; + void* key = NULL; + word32 keySz; + word32 dataSz; +#ifdef WOLFSSL_SMALL_STACK + DhKey* dhKey = NULL; +#else + DhKey dhKey[1]; +#endif +#ifdef HAVE_PUBLIC_FFDHE + const DhParams* params; +#else + word32 p_len; +#endif /* TODO: [TLS13] The key size should come from wolfcrypt. */ /* Pick the parameters from the named group. */ +#ifdef HAVE_PUBLIC_FFDHE switch (kse->group) { #ifdef HAVE_FFDHE_2048 case WOLFSSL_FFDHE_2048: @@ -6087,116 +6082,132 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse) break; #endif default: - break; + return BAD_FUNC_ARG; } - - if (params == NULL) +#else + keySz = wc_DhGetNamedKeyMinSize(kse->group); + if (keySz == 0) { return BAD_FUNC_ARG; + } +#endif - kse->pubKeyLen = params->p_len; - kse->keyLen = keySz; +#ifdef WOLFSSL_SMALL_STACK + dhKey = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap, DYNAMIC_TYPE_DH); + if (dhKey == NULL) + return MEMORY_E; +#endif - /* Trigger Key Generation */ - if (kse->pubKey == NULL || kse->privKey == NULL) { - if (kse->key == NULL) { - kse->key = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap, - DYNAMIC_TYPE_DH); - if (kse->key == NULL) - return MEMORY_E; - - /* Setup Key */ - ret = wc_InitDhKey_ex((DhKey*)kse->key, ssl->heap, ssl->devId); - if (ret == 0) { - dhKey = (DhKey*)kse->key; - ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g, - params->g_len); - } - } - - /* Allocate space for the private and public key */ - if (ret == 0 && kse->pubKey == NULL) { - kse->pubKey = (byte*)XMALLOC(kse->pubKeyLen, ssl->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - if (kse->pubKey == NULL) - ret = MEMORY_E; - } - - if (ret == 0 && kse->privKey == NULL) { - kse->privKey = (byte*)XMALLOC(kse->keyLen, ssl->heap, - DYNAMIC_TYPE_PRIVATE_KEY); - if (kse->privKey == NULL) - ret = MEMORY_E; - } - - if (ret == 0) { - #if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(WOLFSSL_DH_EXTRA) - if (ssl->staticKE.dhKey) { - DerBuffer* keyDer = ssl->staticKE.dhKey; - word32 idx = 0; - WOLFSSL_MSG("Using static DH key"); - ret = wc_DhKeyDecode(keyDer->buffer, &idx, dhKey, keyDer->length); - if (ret == 0) { - ret = wc_DhExportKeyPair(dhKey, - (byte*)kse->privKey, &kse->keyLen, /* private */ - kse->pubKey, &kse->pubKeyLen /* public */ - ); - } - } - else - #endif - { - /* Generate a new key pair */ - /* For async this is called once and when event is done, the - * provided buffers will be populated. - * Final processing is zero pad below. */ - ret = DhGenKeyPair(ssl, dhKey, - (byte*)kse->privKey, &kse->keyLen, /* private */ - kse->pubKey, &kse->pubKeyLen /* public */ - ); - #ifdef WOLFSSL_ASYNC_CRYPT - if (ret == WC_PENDING_E) { - return ret; - } - #endif - } - } + ret = wc_InitDhKey_ex(dhKey, ssl->heap, ssl->devId); + if (ret != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH); + #endif + return ret; } - if (ret == 0) { - if (params->p_len != kse->pubKeyLen) { - /* Zero pad the front of the public key to match prime "p" size */ - XMEMMOVE(kse->pubKey + params->p_len - kse->pubKeyLen, kse->pubKey, - kse->pubKeyLen); - XMEMSET(kse->pubKey, 0, params->p_len - kse->pubKeyLen); + /* Allocate space for the public key */ +#ifdef HAVE_PUBLIC_FFDHE + dataSz = params->p_len; +#else + ret = wc_DhGetNamedKeyParamSize(kse->group, &p_len, NULL, NULL); + if (ret != 0) { + goto end; + } + dataSz = p_len; +#endif + keyData = (byte*)XMALLOC(dataSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (keyData == NULL) { + ret = MEMORY_E; + goto end; + } + /* Allocate space for the private key */ +#ifndef HAVE_PUBLIC_FFDHE + keySz = wc_DhGetNamedKeyMinSize(kse->group); + if (keySz == 0) { + ret = WC_KEY_SIZE_E; + goto end; + } +#endif + key = (byte*)XMALLOC(keySz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + if (key == NULL) { + ret = MEMORY_E; + goto end; + } + + /* Set key */ +#ifdef HAVE_PUBLIC_FFDHE + ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g, + params->g_len); +#else + ret = wc_DhSetNamedKey(dhKey, kse->group); +#endif + if (ret != 0) + goto end; + +#if defined(WOLFSSL_STATIC_EPHEMERAL) && defined(WOLFSSL_DH_EXTRA) + if (ssl->staticKE.dhKey) { + DerBuffer* keyDer = ssl->staticKE.dhKey; + word32 idx = 0; + WOLFSSL_MSG("Using static DH key"); + ret = wc_DhKeyDecode(keyDer->buffer, &idx, dhKey, keyDer->length); + if (ret == 0) { + ret = wc_DhExportKeyPair(dhKey, (byte*)key, &keySz, keyData, &dataSz); + } + } + else +#endif + { + /* Generate a new key pair */ + ret = wc_DhGenerateKeyPair(dhKey, ssl->rng, (byte*)key, &keySz, keyData, + &dataSz); + #ifdef WOLFSSL_ASYNC_CRYPT + /* TODO: Make this function non-blocking */ + if (ret == WC_PENDING_E) { + ret = wc_AsyncWait(ret, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE); } - - kse->pubKeyLen = params->p_len; - - #ifdef WOLFSSL_DEBUG_TLS - WOLFSSL_MSG("Public DH Key"); - WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen); #endif } + if (ret != 0) + goto end; - /* Always release the DH key to free up memory. - * The DhKey will be setup again in TLSX_KeyShare_ProcessDh */ - if (dhKey != NULL) - wc_FreeDhKey(dhKey); - if (kse->key != NULL) { - XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_DH); - kse->key = NULL; +#ifdef HAVE_PUBLIC_FFDHE + if (params->p_len != dataSz) { + /* Zero pad the front of the public key to match prime "p" size */ + XMEMMOVE(keyData + params->p_len - dataSz, keyData, dataSz); + XMEMSET(keyData, 0, params->p_len - dataSz); + } + kse->pubKeyLen = params->p_len; +#else + if (p_len != dataSz) { + /* Zero pad the front of the public key to match prime "p" size */ + XMEMMOVE(keyData + p_len - dataSz, keyData, dataSz); + XMEMSET(keyData, 0, p_len - dataSz); } + kse->pubKeyLen = p_len; +#endif + + kse->pubKey = keyData; + kse->key = key; + kse->keyLen = keySz; + +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Public DH Key"); + WOLFSSL_BUFFER(keyData, params->p_len); +#endif + +end: + + wc_FreeDhKey(dhKey); +#ifdef WOLFSSL_SMALL_STACK + XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH); +#endif if (ret != 0) { - /* Cleanup on error, otherwise data owned by key share entry */ - if (kse->privKey != NULL) { - XFREE(kse->privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); - kse->privKey = NULL; - } - if (kse->pubKey != NULL) { - XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - kse->pubKey = NULL; - } + /* Data owned by key share entry otherwise. */ + if (keyData != NULL) + XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (key != NULL) + XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); } #else (void)ssl; @@ -6880,11 +6891,20 @@ static word16 TLSX_KeyShare_Write(KeyShareEntry* list, byte* output, */ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) { - int ret = 0; -#if !defined(NO_DH) && (!defined(NO_CERTS) || !defined(NO_PSK)) - const DhParams* params = NULL; - DhKey* dhKey = (DhKey*)keyShareEntry->key; +#ifndef NO_DH + int ret; +#ifdef HAVE_PUBLIC_FFDHE + const DhParams* params; +#else + word32 pSz; +#endif +#ifdef WOLFSSL_SMALL_STACK + DhKey* dhKey = NULL; +#else + DhKey dhKey[1]; +#endif +#ifdef HAVE_PUBLIC_FFDHE switch (keyShareEntry->group) { #ifdef HAVE_FFDHE_2048 case WOLFSSL_FFDHE_2048: @@ -6912,88 +6932,109 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) break; #endif default: - break; + return PEER_KEY_ERROR; + } +#endif + +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Peer DH Key"); + WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); +#endif + +#ifdef WOLFSSL_SMALL_STACK + dhKey = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap, DYNAMIC_TYPE_DH); + if (dhKey == NULL) + return MEMORY_E; +#endif + + ret = wc_InitDhKey_ex(dhKey, ssl->heap, ssl->devId); + if (ret != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH); + #endif + return ret; } - if (params == NULL) + /* Set key */ +#ifdef HAVE_PUBLIC_FFDHE + ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g, + params->g_len); +#else + ret = wc_DhSetNamedKey(dhKey, keyShareEntry->group); +#endif + if (ret != 0) { + wc_FreeDhKey(dhKey); + #ifdef WOLFSSL_SMALL_STACK + XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH); + #endif + return ret; + } +#ifndef HAVE_PUBLIC_FFDHE + pSz = wc_DhGetNamedKeyMinSize(keyShareEntry->group); +#endif + + ret = wc_DhCheckPubKey(dhKey, keyShareEntry->ke, keyShareEntry->keLen); + if (ret != 0) { + wc_FreeDhKey(dhKey); + #ifdef WOLFSSL_SMALL_STACK + XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH); + #endif return PEER_KEY_ERROR; - - /* if DhKey is not setup, do it now */ - if (keyShareEntry->key == NULL) { - keyShareEntry->key = (DhKey*)XMALLOC(sizeof(DhKey), ssl->heap, - DYNAMIC_TYPE_DH); - if (keyShareEntry->key == NULL) - return MEMORY_E; - - /* Setup Key */ - ret = wc_InitDhKey_ex((DhKey*)keyShareEntry->key, ssl->heap, ssl->devId); - if (ret == 0) { - dhKey = (DhKey*)keyShareEntry->key; - ret = wc_DhSetKey(dhKey, params->p, params->p_len, params->g, - params->g_len); - } } - if (ret == 0 - #ifdef WOLFSSL_ASYNC_CRYPT - && keyShareEntry->lastRet == 0 /* don't enter here if WC_PENDING_E */ - #endif - ) { - #ifdef WOLFSSL_DEBUG_TLS - WOLFSSL_MSG("Peer DH Key"); - WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); - #endif - - ssl->options.dhKeySz = (word16)params->p_len; - - /* Derive secret from private key and peer's public key. */ - ret = DhAgree(ssl, dhKey, - (const byte*)keyShareEntry->privKey, keyShareEntry->keyLen, /* our private */ - keyShareEntry->ke, keyShareEntry->keLen, /* peer's public key */ - ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, /* secret */ - NULL, 0 - ); - #ifdef WOLFSSL_ASYNC_CRYPT - if (ret == WC_PENDING_E) { - return ret; - } - #endif + /* Derive secret from private key and peer's public key. */ + ret = wc_DhAgree(dhKey, + ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, + (const byte*)keyShareEntry->key, keyShareEntry->keyLen, + keyShareEntry->ke, keyShareEntry->keLen); +#ifdef WOLFSSL_ASYNC_CRYPT + /* TODO: Make this function non-blocking */ + if (ret == WC_PENDING_E) { + ret = wc_AsyncWait(ret, &dhKey->asyncDev, WC_ASYNC_FLAG_NONE); } - +#endif /* RFC 8446 Section 7.4.1: * ... left-padded with zeros up to the size of the prime. ... */ - if (ret == 0 && (word32)ssl->options.dhKeySz > ssl->arrays->preMasterSz) { - word32 diff = (word32)ssl->options.dhKeySz - ssl->arrays->preMasterSz; +#ifdef HAVE_PUBLIC_FFDHE + if (params->p_len > ssl->arrays->preMasterSz) { + word32 diff = params->p_len - ssl->arrays->preMasterSz; + XMEMMOVE(ssl->arrays->preMasterSecret + diff, + ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz); + XMEMSET(ssl->arrays->preMasterSecret, 0, diff); + ssl->arrays->preMasterSz = params->p_len; + } + ssl->options.dhKeySz = (word16)params->p_len; +#else + if (pSz > ssl->arrays->preMasterSz) { + word32 diff = pSz - ssl->arrays->preMasterSz; XMEMMOVE(ssl->arrays->preMasterSecret + diff, ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz); XMEMSET(ssl->arrays->preMasterSecret, 0, diff); - ssl->arrays->preMasterSz = ssl->options.dhKeySz; + ssl->arrays->preMasterSz = pSz; } + ssl->options.dhKeySz = pSz; +#endif - /* done with key share, release resources */ - if (dhKey) - wc_FreeDhKey(dhKey); - if (keyShareEntry->key) { - XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_DH); + wc_FreeDhKey(dhKey); +#ifdef WOLFSSL_SMALL_STACK + XFREE(dhKey, ssl->heap, DYNAMIC_TYPE_DH); +#endif + if (keyShareEntry->key != NULL) { + XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); keyShareEntry->key = NULL; } - if (keyShareEntry->privKey != NULL) { - XFREE(keyShareEntry->privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); - keyShareEntry->privKey = NULL; - } - if (keyShareEntry->pubKey != NULL) { - XFREE(keyShareEntry->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - keyShareEntry->pubKey = NULL; - } + XFREE(keyShareEntry->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + keyShareEntry->pubKey = NULL; XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); keyShareEntry->ke = NULL; + + return ret; #else (void)ssl; (void)keyShareEntry; - ret = PEER_KEY_ERROR; + return PEER_KEY_ERROR; #endif - return ret; } /* Process the X25519 key share extension on the client side. diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 3bec7e24a..0efe6706d 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -5072,8 +5072,8 @@ void bench_dh(int doAsync) word32 pubSz2 = BENCH_DH_KEY_SIZE; word32 privSz2 = BENCH_DH_PRIV_SIZE; word32 agreeSz[BENCH_MAX_PENDING]; -#ifdef HAVE_FFDHE_2048 - const DhParams *params = NULL; +#if defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072) + int paramName = 0; #endif DECLARE_ARRAY(pub, byte, BENCH_MAX_PENDING, BENCH_DH_KEY_SIZE, HEAP_HINT); @@ -5112,13 +5112,13 @@ void bench_dh(int doAsync) } #ifdef HAVE_FFDHE_2048 else if (use_ffdhe == 2048) { - params = wc_Dh_ffdhe2048_Get(); + paramName = WC_FFDHE_2048; dhKeySz = 2048; } #endif #ifdef HAVE_FFDHE_3072 else if (use_ffdhe == 3072) { - params = wc_Dh_ffdhe3072_Get(); + paramName = WC_FFDHE_3072; dhKeySz = 3072; } #endif @@ -5151,9 +5151,8 @@ void bench_dh(int doAsync) #endif } #if defined(HAVE_FFDHE_2048) || defined(HAVE_FFDHE_3072) - else if (params != NULL) { - ret = wc_DhSetKey(&dhKey[i], params->p, params->p_len, params->g, - params->g_len); + else if (paramName != 0) { + ret = wc_DhSetNamedKey(&dhKey[i], paramName); } #endif if (ret != 0) { diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index 02a2de7cc..3fa95fa11 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -148,6 +148,7 @@ static const byte dh_ffdhe2048_q[] = { }; #endif /* HAVE_FFDHE_Q */ +#ifdef HAVE_PUBLIC_FFDHE const DhParams* wc_Dh_ffdhe2048_Get(void) { static const DhParams ffdhe2048 = { @@ -160,6 +161,7 @@ const DhParams* wc_Dh_ffdhe2048_Get(void) return &ffdhe2048; } #endif +#endif #ifdef HAVE_FFDHE_3072 static const byte dh_ffdhe3072_p[] = { @@ -266,6 +268,7 @@ static const byte dh_ffdhe3072_q[] = { }; #endif /* HAVE_FFDHE_Q */ +#ifdef HAVE_PUBLIC_FFDHE const DhParams* wc_Dh_ffdhe3072_Get(void) { static const DhParams ffdhe3072 = { @@ -278,6 +281,7 @@ const DhParams* wc_Dh_ffdhe3072_Get(void) return &ffdhe3072; } #endif +#endif #ifdef HAVE_FFDHE_4096 static const byte dh_ffdhe4096_p[] = { @@ -416,6 +420,7 @@ static const byte dh_ffdhe4096_q[] = { }; #endif /* HAVE_FFDHE_Q */ +#ifdef HAVE_PUBLIC_FFDHE const DhParams* wc_Dh_ffdhe4096_Get(void) { static const DhParams ffdhe4096 = { @@ -428,6 +433,7 @@ const DhParams* wc_Dh_ffdhe4096_Get(void) return &ffdhe4096; } #endif +#endif #ifdef HAVE_FFDHE_6144 static const byte dh_ffdhe6144_p[] = { @@ -630,6 +636,7 @@ static const byte dh_ffdhe6144_q[] = { }; #endif /* HAVE_FFDHE_Q */ +#ifdef HAVE_PUBLIC_FFDHE const DhParams* wc_Dh_ffdhe6144_Get(void) { static const DhParams ffdhe6144 = { @@ -642,6 +649,7 @@ const DhParams* wc_Dh_ffdhe6144_Get(void) return &ffdhe6144; } #endif +#endif #ifdef HAVE_FFDHE_8192 static const byte dh_ffdhe8192_p[] = { @@ -908,6 +916,7 @@ static const byte dh_ffdhe8192_q[] = { }; #endif /* HAVE_FFDHE_Q */ +#ifdef HAVE_PUBLIC_FFDHE const DhParams* wc_Dh_ffdhe8192_Get(void) { static const DhParams ffdhe8192 = { @@ -920,6 +929,7 @@ const DhParams* wc_Dh_ffdhe8192_Get(void) return &ffdhe8192; } #endif +#endif int wc_InitDhKey_ex(DhKey* key, void* heap, int devId) { @@ -2391,6 +2401,386 @@ int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL); } + +int wc_DhSetNamedKey(DhKey* key, int name) +{ + const byte* p = NULL; + const byte* g = NULL; + const byte* q = NULL; + word32 pSz = 0, gSz = 0, qSz = 0; + + switch (name) { + #ifdef HAVE_FFDHE_2048 + case WC_FFDHE_2048: + p = dh_ffdhe2048_p; + pSz = sizeof(dh_ffdhe2048_p); + g = dh_ffdhe2048_g; + gSz = sizeof(dh_ffdhe2048_g); + #ifdef HAVE_FFDHE_Q + q = dh_ffdhe2048_q; + qSz = sizeof(dh_ffdhe2048_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_2048 */ + #ifdef HAVE_FFDHE_3072 + case WC_FFDHE_3072: + p = dh_ffdhe3072_p; + pSz = sizeof(dh_ffdhe3072_p); + g = dh_ffdhe3072_g; + gSz = sizeof(dh_ffdhe3072_g); + #ifdef HAVE_FFDHE_Q + q = dh_ffdhe3072_q; + qSz = sizeof(dh_ffdhe3072_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_3072 */ + #ifdef HAVE_FFDHE_4096 + case WC_FFDHE_4096: + p = dh_ffdhe4096_p; + pSz = sizeof(dh_ffdhe4096_p); + g = dh_ffdhe4096_g; + gSz = sizeof(dh_ffdhe4096_g); + #ifdef HAVE_FFDHE_Q + q = dh_ffdhe4096_q; + qSz = sizeof(dh_ffdhe4096_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_4096 */ + #ifdef HAVE_FFDHE_6144 + case WC_FFDHE_6144: + p = dh_ffdhe6144_p; + pSz = sizeof(dh_ffdhe6144_p); + g = dh_ffdhe6144_g; + gSz = sizeof(dh_ffdhe6144_g); + #ifdef HAVE_FFDHE_Q + q = dh_ffdhe6144_q; + qSz = sizeof(dh_ffdhe6144_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_6144 */ + #ifdef HAVE_FFDHE_8192 + case WC_FFDHE_8192: + p = dh_ffdhe8192_p; + pSz = sizeof(dh_ffdhe8192_p); + g = dh_ffdhe8192_g; + gSz = sizeof(dh_ffdhe8192_g); + #ifdef HAVE_FFDHE_Q + q = dh_ffdhe8192_q; + qSz = sizeof(dh_ffdhe8192_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_8192 */ + default: + return BAD_FUNC_ARG; + } + return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL); +} + +#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 5) + #define HAVE_FIPS_V5 +#endif + +word32 wc_DhGetNamedKeyMinSize(int name) +{ + int size; + + switch (name) { + #ifdef HAVE_FFDHE_2048 + case WC_FFDHE_2048: + #ifndef HAVE_FIPS_V5 + size = 29; + #else + size = 256; + #endif + break; + #endif /* HAVE_FFDHE_2048 */ + #ifdef HAVE_FFDHE_3072 + case WC_FFDHE_3072: + #ifndef HAVE_FIPS_V5 + size = 34; + #else + size = 384; + #endif + break; + #endif /* HAVE_FFDHE_3072 */ + #ifdef HAVE_FFDHE_4096 + case WC_FFDHE_4096: + #ifndef HAVE_FIPS_V5 + size = 39; + #else + size = 512; + #endif + break; + #endif /* HAVE_FFDHE_4096 */ + #ifdef HAVE_FFDHE_6144 + case WC_FFDHE_6144: + #ifndef HAVE_FIPS_V5 + size = 768; + #else + size = 256; + #endif + break; + #endif /* HAVE_FFDHE_6144 */ + #ifdef HAVE_FFDHE_8192 + case WC_FFDHE_8192: + #ifndef HAVE_FIPS_V5 + size = 52; + #else + size = 1024; + #endif + break; + #endif /* HAVE_FFDHE_8192 */ + default: + size = 0; + } + + return size; +} + +#ifdef HAVE_FIPS_V5 + #undef HAVE_FIPS_V5 +#endif + + +/* Returns 1: params match + * 0: params differ */ +int wc_DhCmpNamedKey(int name, int noQ, + const byte* p, word32 pSz, + const byte* g, word32 gSz, + const byte* q, word32 qSz) +{ + const byte* pCmp = NULL; + const byte* qCmp = NULL; + const byte* gCmp = NULL; + word32 pCmpSz = 0, qCmpSz = 0, gCmpSz = 0; + int cmp = 0; + + switch (name) { + #ifdef HAVE_FFDHE_2048 + case WC_FFDHE_2048: + pCmp = dh_ffdhe2048_p; + pCmpSz = sizeof(dh_ffdhe2048_p); + gCmp = dh_ffdhe2048_g; + gCmpSz = sizeof(dh_ffdhe2048_g); + #ifdef HAVE_FFDHE_Q + qCmp = dh_ffdhe2048_q; + qCmpSz = sizeof(dh_ffdhe2048_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_2048 */ + #ifdef HAVE_FFDHE_3072 + case WC_FFDHE_3072: + pCmp = dh_ffdhe3072_p; + pCmpSz = sizeof(dh_ffdhe3072_p); + gCmp = dh_ffdhe3072_g; + gCmpSz = sizeof(dh_ffdhe3072_g); + #ifdef HAVE_FFDHE_Q + qCmp = dh_ffdhe3072_q; + qCmpSz = sizeof(dh_ffdhe3072_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_3072 */ + #ifdef HAVE_FFDHE_4096 + case WC_FFDHE_4096: + pCmp = dh_ffdhe4096_p; + pCmpSz = sizeof(dh_ffdhe4096_p); + gCmp = dh_ffdhe4096_g; + gCmpSz = sizeof(dh_ffdhe4096_g); + #ifdef HAVE_FFDHE_Q + qCmp = dh_ffdhe4096_q; + qCmpSz = sizeof(dh_ffdhe4096_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_4096 */ + #ifdef HAVE_FFDHE_6144 + case WC_FFDHE_6144: + pCmp = dh_ffdhe6144_p; + pCmpSz = sizeof(dh_ffdhe6144_p); + gCmp = dh_ffdhe6144_g; + gCmpSz = sizeof(dh_ffdhe6144_g); + #ifdef HAVE_FFDHE_Q + qCmp = dh_ffdhe6144_q; + qCmpSz = sizeof(dh_ffdhe6144_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_6144 */ + #ifdef HAVE_FFDHE_8192 + case WC_FFDHE_8192: + pCmp = dh_ffdhe8192_p; + pCmpSz = sizeof(dh_ffdhe8192_p); + gCmp = dh_ffdhe8192_g; + gCmpSz = sizeof(dh_ffdhe8192_g); + #ifdef HAVE_FFDHE_Q + qCmp = dh_ffdhe8192_q; + qCmpSz = sizeof(dh_ffdhe8192_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_8192 */ + default: + return 0; + } + + cmp = (pSz == pCmpSz) && (gSz == gCmpSz) && + (noQ || ((qSz == qCmpSz) && XMEMCMP(q, qCmp, qCmpSz))) && + (XMEMCMP(p, pCmp, pCmpSz) == 0) && + (XMEMCMP(g, gCmp, gCmpSz) == 0); + + return cmp; +} + + +int wc_DhGetNamedKeyParamSize(int name, word32* p, word32* g, word32* q) +{ + word32 pSz = 0, gSz = 0, qSz = 0; + + switch (name) { + #ifdef HAVE_FFDHE_2048 + case WC_FFDHE_2048: + pSz = sizeof(dh_ffdhe2048_p); + gSz = sizeof(dh_ffdhe2048_g); + #ifdef HAVE_FFDHE_Q + qSz = sizeof(dh_ffdhe2048_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_2048 */ + #ifdef HAVE_FFDHE_3072 + case WC_FFDHE_3072: + pSz = sizeof(dh_ffdhe3072_p); + gSz = sizeof(dh_ffdhe3072_g); + #ifdef HAVE_FFDHE_Q + qSz = sizeof(dh_ffdhe3072_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_3072 */ + #ifdef HAVE_FFDHE_4096 + case WC_FFDHE_4096: + pSz = sizeof(dh_ffdhe4096_p); + gSz = sizeof(dh_ffdhe4096_g); + #ifdef HAVE_FFDHE_Q + qSz = sizeof(dh_ffdhe4096_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_4096 */ + #ifdef HAVE_FFDHE_6144 + case WC_FFDHE_6144: + pSz = sizeof(dh_ffdhe6144_p); + gSz = sizeof(dh_ffdhe6144_g); + #ifdef HAVE_FFDHE_Q + qSz = sizeof(dh_ffdhe6144_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_6144 */ + #ifdef HAVE_FFDHE_8192 + case WC_FFDHE_8192: + pSz = sizeof(dh_ffdhe8192_p); + gSz = sizeof(dh_ffdhe8192_g); + #ifdef HAVE_FFDHE_Q + qSz = sizeof(dh_ffdhe8192_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_8192 */ + default: + break; + } + + if (p != NULL) *p = pSz; + if (g != NULL) *g = gSz; + if (q != NULL) *q = qSz; + + return 0; +} + + +int wc_DhCopyNamedKey(int name, + byte* p, word32* pSz, byte* g, word32* gSz, byte* q, word32* qSz) +{ + const byte* pC = NULL; + const byte* gC = NULL; + const byte* qC = NULL; + word32 pCSz = 0, gCSz = 0, qCSz = 0; + + switch (name) { + #ifdef HAVE_FFDHE_2048 + case WC_FFDHE_2048: + pC = dh_ffdhe2048_p; + pCSz = sizeof(dh_ffdhe2048_p); + gC = dh_ffdhe2048_g; + gCSz = sizeof(dh_ffdhe2048_g); + #ifdef HAVE_FFDHE_Q + qC = dh_ffdhe2048_q; + qCSz = sizeof(dh_ffdhe2048_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_2048 */ + #ifdef HAVE_FFDHE_3072 + case WC_FFDHE_3072: + pC = dh_ffdhe3072_p; + pCSz = sizeof(dh_ffdhe3072_p); + gC = dh_ffdhe3072_g; + gCSz = sizeof(dh_ffdhe3072_g); + #ifdef HAVE_FFDHE_Q + qC = dh_ffdhe3072_q; + qCSz = sizeof(dh_ffdhe3072_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_3072 */ + #ifdef HAVE_FFDHE_4096 + case WC_FFDHE_4096: + pC = dh_ffdhe4096_p; + pCSz = sizeof(dh_ffdhe4096_p); + gC = dh_ffdhe4096_g; + gCSz = sizeof(dh_ffdhe4096_g); + #ifdef HAVE_FFDHE_Q + qC = dh_ffdhe4096_q; + qCSz = sizeof(dh_ffdhe4096_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_4096 */ + #ifdef HAVE_FFDHE_6144 + case WC_FFDHE_6144: + pC = dh_ffdhe6144_p; + pCSz = sizeof(dh_ffdhe6144_p); + gC = dh_ffdhe6144_g; + gCSz = sizeof(dh_ffdhe6144_g); + #ifdef HAVE_FFDHE_Q + qC = dh_ffdhe6144_q; + qCSz = sizeof(dh_ffdhe6144_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_6144 */ + #ifdef HAVE_FFDHE_8192 + case WC_FFDHE_8192: + pC = dh_ffdhe8192_p; + pCSz = sizeof(dh_ffdhe8192_p); + gC = dh_ffdhe8192_g; + gCSz = sizeof(dh_ffdhe8192_g); + #ifdef HAVE_FFDHE_Q + qC = dh_ffdhe8192_q; + qCSz = sizeof(dh_ffdhe8192_q); + #endif /* HAVE_FFDHE_Q */ + break; + #endif /* HAVE_FFDHE_8192 */ + default: + break; + } + + if (p != NULL && pC != NULL) + XMEMCPY(p, pC, pCSz); + if (pSz != NULL) + *pSz = pCSz; + if (g != NULL && gC != NULL) + XMEMCPY(g, gC, gCSz); + if (gSz != NULL) + *gSz = gCSz; + if (q != NULL && qC != NULL) + XMEMCPY(q, qC, qCSz); + if (qSz != NULL) + *qSz = qCSz; + + return 0; +} + + #ifdef WOLFSSL_KEY_GEN /* modulus_size in bits */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 5865d0189..c537645b2 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -16326,7 +16326,7 @@ static int dh_test_check_pubvalue(void) #endif #ifndef WC_NO_RNG -static int dh_ffdhe_test(WC_RNG *rng, const DhParams* params) +static int dh_ffdhe_test(WC_RNG *rng, int name) { int ret; word32 privSz, pubSz, privSz2, pubSz2; @@ -16381,13 +16381,12 @@ static int dh_ffdhe_test(WC_RNG *rng, const DhParams* params) ERROR_OUT(-8052, done); } - ret = wc_DhSetKey(key, params->p, params->p_len, params->g, params->g_len); + ret = wc_DhSetNamedKey(key, name); if (ret != 0) { ERROR_OUT(-8053, done); } - ret = wc_DhSetKey(key2, params->p, params->p_len, params->g, - params->g_len); + ret = wc_DhSetNamedKey(key2, name); if (ret != 0) { ERROR_OUT(-8054, done); } @@ -16809,12 +16808,12 @@ WOLFSSL_TEST_SUBROUTINE int dh_test(void) #ifndef WC_NO_RNG /* Specialized code for key gen when using FFDHE-2048, FFDHE-3072 and FFDHE-4096 */ #ifdef HAVE_FFDHE_2048 - ret = dh_ffdhe_test(&rng, wc_Dh_ffdhe2048_Get()); + ret = dh_ffdhe_test(&rng, WC_FFDHE_2048); if (ret != 0) ERROR_OUT(-8126, done); #endif #ifdef HAVE_FFDHE_3072 - ret = dh_ffdhe_test(&rng, wc_Dh_ffdhe3072_Get()); + ret = dh_ffdhe_test(&rng, WC_FFDHE_3072); if (ret != 0) ERROR_OUT(-8127, done); #endif diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index 9b25286ee..4777b2b7c 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -83,6 +83,15 @@ struct DhKey { #define WC_DH_TYPE_DEFINED #endif +enum { + WC_FFDHE_2048 = 256, + WC_FFDHE_3072 = 257, + WC_FFDHE_4096 = 258, + WC_FFDHE_6144 = 259, + WC_FFDHE_8192 = 260, +}; + +#ifdef HAVE_PUBLIC_FFDHE #ifdef HAVE_FFDHE_2048 WOLFSSL_API const DhParams* wc_Dh_ffdhe2048_Get(void); #endif @@ -98,6 +107,7 @@ WOLFSSL_API const DhParams* wc_Dh_ffdhe6144_Get(void); #ifdef HAVE_FFDHE_8192 WOLFSSL_API const DhParams* wc_Dh_ffdhe8192_Get(void); #endif +#endif WOLFSSL_API int wc_InitDhKey(DhKey* key); WOLFSSL_API int wc_InitDhKey_ex(DhKey* key, void* heap, int devId); @@ -116,6 +126,16 @@ WOLFSSL_API int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g word32 gSz); WOLFSSL_API int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz, const byte* q, word32 qSz); +WOLFSSL_API int wc_DhSetNamedKey(DhKey* key, int name); +WOLFSSL_API int wc_DhGetNamedKeyParamSize(int name, + word32* p, word32* g, word32* q); +WOLFSSL_API word32 wc_DhGetNamedKeyMinSize(int name); +WOLFSSL_API int wc_DhCmpNamedKey(int name, int noQ, + const byte* p, word32 pSz, + const byte* g, word32 gSz, + const byte* q, word32 qSz); +WOLFSSL_API int wc_DhCopyNamedKey(int name, + byte* p, word32* pSz, byte* g, word32* gSz, byte* q, word32* qSz); #ifdef WOLFSSL_DH_EXTRA WOLFSSL_API int wc_DhPublicKeyDecode(const byte* input, word32* inOutIdx,