forked from wolfSSL/wolfssl
Fixes:
1. When enabling FIPSv5 in configure, enable WOLFSSL_WOLFSSH. 2. Appropriate size selection of DH private keys.
This commit is contained in:
@ -3046,7 +3046,7 @@ fi
|
||||
AS_CASE([$FIPS_VERSION],
|
||||
["v5"], [ # FIPS 140-3
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_FIPS -DHAVE_FIPS_VERSION=5 -DWOLFSSL_KEY_GEN -DWOLFSSL_SHA224 -DWOLFSSL_AES_DIRECT -DHAVE_AES_ECB -DHAVE_ECC_CDH -DWC_RSA_NO_PADDING"
|
||||
ENABLED_KEYGEN="yes"; ENABLED_SHA224="yes"; ENABLED_DES3="no"; ENABLED=WOLFSSH="yes"
|
||||
ENABLED_KEYGEN="yes"; ENABLED_SHA224="yes"; ENABLED_DES3="no"
|
||||
# Shake256 is a SHA-3 algorithm not in our FIPS algorithm list
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_SHAKE256"
|
||||
AS_IF([test "x$ENABLED_AESCCM" != "xyes"],
|
||||
@ -6114,6 +6114,9 @@ AS_IF([test "x$ENABLED_NULL_CIPHER" = "xno" && \
|
||||
[AM_CFLAGS="-DHAVE_NULL_CIPHER $AM_CFLAGS"
|
||||
ENABLED_NULL_CIPHER=yes])
|
||||
|
||||
# FIPSv5 requires the wolfSSH option.
|
||||
AS_IF([test "x$FIPS_VERSION" = "xv5"],[ENABLED_WOLFSSH="yes"])
|
||||
|
||||
# wolfSSH and WPA Supplicant both need Public MP, only enable once.
|
||||
# This will let you know if you enabled wolfSSH but have any of the prereqs
|
||||
# disabled. Some of these options, disabling them adds things to the FLAGS and
|
||||
|
@ -22281,8 +22281,8 @@ static int GetDhPublicKey(WOLFSSL* ssl, const byte* input, word32 size,
|
||||
|
||||
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)) {
|
||||
ssl->buffers.serverDH_G.buffer, ssl->buffers.serverDH_G.length,
|
||||
NULL, 0)) {
|
||||
WOLFSSL_MSG("Server not using FFDHE parameters");
|
||||
#ifdef WOLFSSL_REQUIRE_FFDHE
|
||||
SendAlert(ssl, alert_fatal, handshake_failure);
|
||||
@ -24069,6 +24069,18 @@ int SendClientKeyExchange(WOLFSSL* ssl)
|
||||
goto exit_scke;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FFDHE
|
||||
if (ssl->namedGroup) {
|
||||
ret = wc_DhSetNamedKey(ssl->buffers.serverDH_Key,
|
||||
ssl->namedGroup);
|
||||
if (ret != 0) {
|
||||
goto exit_scke;
|
||||
}
|
||||
ssl->buffers.sig.length =
|
||||
wc_DhGetNamedKeyMinSize(ssl->namedGroup);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \
|
||||
!defined(WOLFSSL_OLD_PRIME_CHECK)
|
||||
if (ssl->options.dhDoKeyTest &&
|
||||
@ -24214,8 +24226,9 @@ int SendClientKeyExchange(WOLFSSL* ssl)
|
||||
|
||||
/* for DH, encSecret is Yc, agree is pre-master */
|
||||
ret = DhGenKeyPair(ssl, ssl->buffers.serverDH_Key,
|
||||
ssl->buffers.sig.buffer, (word32*)&ssl->buffers.sig.length,
|
||||
args->output + OPAQUE16_LEN, &args->length);
|
||||
ssl->buffers.sig.buffer,
|
||||
(word32*)&ssl->buffers.sig.length,
|
||||
args->output + OPAQUE16_LEN, &args->length);
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_DH && !NO_PSK */
|
||||
@ -26115,29 +26128,27 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
/* Free'd in SSL_ResourceFree and
|
||||
* FreeHandshakeResources */
|
||||
ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
|
||||
pSz + OPAQUE16_LEN,
|
||||
ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
pSz, 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;
|
||||
ssl->buffers.serverDH_Pub.length = pSz;
|
||||
}
|
||||
ssl->options.dhKeySz =(word16)pSz;
|
||||
|
||||
pSz = wc_DhGetNamedKeyMinSize(ssl->namedGroup);
|
||||
|
||||
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);
|
||||
pSz, 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->buffers.serverDH_Priv.length = pSz;
|
||||
}
|
||||
|
||||
ssl->options.dhKeySz =(word16)pSz;
|
||||
|
||||
ret = AllocKey(ssl, DYNAMIC_TYPE_DH,
|
||||
(void**)&ssl->buffers.serverDH_Key);
|
||||
if (ret != 0) {
|
||||
@ -26173,25 +26184,25 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
|
||||
if (ssl->buffers.serverDH_Pub.buffer == NULL) {
|
||||
/* Free'd in SSL_ResourceFree and FreeHandshakeResources */
|
||||
ssl->buffers.serverDH_Pub.buffer = (byte*)XMALLOC(
|
||||
ssl->buffers.serverDH_P.length + OPAQUE16_LEN,
|
||||
ssl->buffers.serverDH_P.length,
|
||||
ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||
if (ssl->buffers.serverDH_Pub.buffer == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_sske);
|
||||
}
|
||||
ssl->buffers.serverDH_Pub.length =
|
||||
ssl->buffers.serverDH_P.length + OPAQUE16_LEN;
|
||||
ssl->buffers.serverDH_P.length;
|
||||
}
|
||||
|
||||
if (ssl->buffers.serverDH_Priv.buffer == NULL) {
|
||||
/* Free'd in SSL_ResourceFree and FreeHandshakeResources */
|
||||
ssl->buffers.serverDH_Priv.buffer = (byte*)XMALLOC(
|
||||
ssl->buffers.serverDH_P.length + OPAQUE16_LEN,
|
||||
ssl->buffers.serverDH_P.length,
|
||||
ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
|
||||
if (ssl->buffers.serverDH_Priv.buffer == NULL) {
|
||||
ERROR_OUT(MEMORY_E, exit_sske);
|
||||
}
|
||||
ssl->buffers.serverDH_Priv.length =
|
||||
ssl->buffers.serverDH_P.length + OPAQUE16_LEN;
|
||||
ssl->buffers.serverDH_P.length;
|
||||
}
|
||||
|
||||
ssl->options.dhKeySz =
|
||||
|
@ -6695,6 +6695,11 @@ static int TLSX_KeyShare_GenDhKey(WOLFSSL *ssl, KeyShareEntry* kse)
|
||||
goto end;
|
||||
}
|
||||
/* Allocate space for the private key */
|
||||
keySz = wc_DhGetNamedKeyMinSize(kse->group);
|
||||
if (keySz == 0) {
|
||||
ret = WC_KEY_SIZE_E;
|
||||
goto end;
|
||||
}
|
||||
key = (byte*)XMALLOC(keySz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
|
||||
if (key == NULL) {
|
||||
ret = MEMORY_E;
|
||||
|
@ -939,6 +939,7 @@ int wc_InitDhKey_ex(DhKey* key, void* heap, int devId)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
key->heap = heap; /* for XMALLOC/XFREE in future */
|
||||
key->trustedGroup = 0;
|
||||
|
||||
#ifdef WOLFSSL_DH_EXTRA
|
||||
if (mp_init_multi(&key->p, &key->g, &key->q, &key->pub, &key->priv, NULL) != MP_OKAY)
|
||||
@ -1051,8 +1052,8 @@ static int CheckDhLN(int modLen, int divLen)
|
||||
|
||||
/* Create DH private key
|
||||
*
|
||||
* Based on NIST FIPS 186-4,
|
||||
* "B.1.1 Key Pair Generation Using Extra Random Bits"
|
||||
* Based on NIST SP 800-56Ar3
|
||||
* "5.6.1.1.3 Key Pair Generation Using Extra Random Bits"
|
||||
*
|
||||
* dh - pointer to initialized DhKey structure, needs to have dh->q
|
||||
* rng - pointer to initialized WC_RNG structure
|
||||
@ -1091,7 +1092,7 @@ static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv,
|
||||
}
|
||||
|
||||
/* generate extra 64 bits so that bias from mod function is negligible */
|
||||
cSz = qSz + (64 / WOLFSSL_BIT_SIZE);
|
||||
cSz = *privSz + (64 / WOLFSSL_BIT_SIZE);
|
||||
cBuf = (byte*)XMALLOC(cSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (cBuf == NULL) {
|
||||
return MEMORY_E;
|
||||
@ -1143,18 +1144,18 @@ static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv,
|
||||
ForceZero(cBuf, cSz);
|
||||
XFREE(cBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
/* tmpQ = q - 1 */
|
||||
/* tmpQ: M = 2^N - 1 */
|
||||
if (err == MP_OKAY)
|
||||
err = mp_copy(&key->q, tmpQ);
|
||||
err = mp_2expt(tmpQ, *privSz * 8);
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_sub_d(tmpQ, 1, tmpQ);
|
||||
|
||||
/* x = c mod (q-1), tmpX holds c */
|
||||
/* x = c mod (M), tmpX holds c */
|
||||
if (err == MP_OKAY)
|
||||
err = mp_mod(tmpX, tmpQ, tmpX);
|
||||
|
||||
/* x = c mod (q-1) + 1 */
|
||||
/* x = c mod (M) + 1 */
|
||||
if (err == MP_OKAY)
|
||||
err = mp_add_d(tmpX, 1, tmpX);
|
||||
|
||||
@ -1192,7 +1193,7 @@ static int GeneratePrivateDh(DhKey* key, WC_RNG* rng, byte* priv,
|
||||
#ifndef WOLFSSL_NO_DH186
|
||||
if (mp_iszero(&key->q) == MP_NO) {
|
||||
|
||||
/* q param available, use NIST FIPS 186-4, "B.1.1 Key Pair
|
||||
/* q param available, use NIST SP 800-56Ar3, "5.6.1.1.3 Key Pair
|
||||
* Generation Using Extra Random Bits" */
|
||||
ret = GeneratePrivateDh186(key, rng, priv, privSz);
|
||||
|
||||
@ -1894,10 +1895,6 @@ int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,
|
||||
ret = wc_DhGenerateKeyPair_Sync(key, rng, priv, privSz, pub, pubSz);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_DhCheckKeyPair(key, pub, *pubSz, priv, *privSz);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2368,7 +2365,7 @@ int wc_DhSetCheckKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
|
||||
int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,
|
||||
word32 gSz, const byte* q, word32 qSz)
|
||||
{
|
||||
return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 1, NULL);
|
||||
return _DhSetKey(key, p, pSz, g, gSz, q, qSz, 0, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -2376,6 +2373,7 @@ int wc_DhSetKey_ex(DhKey* key, const byte* p, word32 pSz, const byte* g,
|
||||
int wc_DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g,
|
||||
word32 gSz)
|
||||
{
|
||||
/* This should not have trusted set. */
|
||||
return _DhSetKey(key, p, pSz, g, gSz, NULL, 0, 1, NULL);
|
||||
}
|
||||
|
||||
@ -2454,9 +2452,6 @@ int wc_DhSetNamedKey(DhKey* key, int name)
|
||||
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)
|
||||
{
|
||||
@ -2465,47 +2460,27 @@ word32 wc_DhGetNamedKeyMinSize(int name)
|
||||
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
|
||||
size = 46;
|
||||
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:
|
||||
@ -2515,10 +2490,6 @@ word32 wc_DhGetNamedKeyMinSize(int name)
|
||||
return size;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FIPS_V5
|
||||
#undef HAVE_FIPS_V5
|
||||
#endif
|
||||
|
||||
|
||||
/* Returns 1: params match
|
||||
* 0: params differ */
|
||||
|
@ -16048,8 +16048,8 @@ static int dh_fips_generate_test(WC_RNG *rng)
|
||||
0xec, 0x24, 0x5d, 0x78, 0x59, 0xe7, 0x8d, 0xb5,
|
||||
0x40, 0x52, 0xed, 0x41
|
||||
};
|
||||
byte priv[256];
|
||||
byte pub[256];
|
||||
byte priv[sizeof q];
|
||||
byte pub[sizeof p];
|
||||
word32 privSz = sizeof(priv);
|
||||
word32 pubSz = sizeof(pub);
|
||||
|
||||
@ -16368,8 +16368,8 @@ static int dh_ffdhe_test(WC_RNG *rng, int name)
|
||||
|
||||
pubSz = FFDHE_KEY_SIZE;
|
||||
pubSz2 = FFDHE_KEY_SIZE;
|
||||
privSz = FFDHE_KEY_SIZE;
|
||||
privSz2 = FFDHE_KEY_SIZE;
|
||||
privSz = wc_DhGetNamedKeyMinSize(name);
|
||||
privSz2 = privSz;
|
||||
|
||||
XMEMSET(key, 0, sizeof *key);
|
||||
XMEMSET(key2, 0, sizeof *key2);
|
||||
|
Reference in New Issue
Block a user