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:
committed by
Daniel Pouzzner
parent
3eaeaf3a57
commit
04ffd2ab45
@@ -3348,7 +3348,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"],
|
||||
@@ -6865,6 +6865,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
|
||||
|
@@ -23595,8 +23595,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);
|
||||
@@ -24970,6 +24970,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 &&
|
||||
@@ -25115,7 +25127,8 @@ 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,
|
||||
ssl->buffers.sig.buffer,
|
||||
(word32*)&ssl->buffers.sig.length,
|
||||
args->output + OPAQUE16_LEN, &args->length);
|
||||
break;
|
||||
}
|
||||
@@ -26874,29 +26887,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) {
|
||||
@@ -26932,25 +26943,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 =
|
||||
|
@@ -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)
|
||||
@@ -1060,8 +1061,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
|
||||
@@ -1100,7 +1101,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;
|
||||
@@ -1152,18 +1153,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);
|
||||
|
||||
@@ -1201,7 +1202,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);
|
||||
|
||||
@@ -1910,10 +1911,6 @@ int wc_DhGenerateKeyPair(DhKey* key, WC_RNG* rng,
|
||||
}
|
||||
#endif /* WOLFSSL_KCAPI_DH */
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_DhCheckKeyPair(key, pub, *pubSz, priv, *privSz);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2392,7 +2389,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -2400,6 +2397,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);
|
||||
}
|
||||
|
||||
@@ -2478,9 +2476,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)
|
||||
{
|
||||
@@ -2489,47 +2484,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:
|
||||
@@ -2539,10 +2514,6 @@ word32 wc_DhGetNamedKeyMinSize(int name)
|
||||
return size;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FIPS_V5
|
||||
#undef HAVE_FIPS_V5
|
||||
#endif
|
||||
|
||||
|
||||
/* Returns 1: params match
|
||||
* 0: params differ */
|
||||
|
@@ -16026,8 +16026,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);
|
||||
|
||||
@@ -16364,10 +16364,10 @@ static int dh_ffdhe_test(WC_RNG *rng, int name)
|
||||
ERROR_OUT(-8050, done);
|
||||
#endif
|
||||
|
||||
pubSz = MAX_DH_KEY_SZ;
|
||||
pubSz2 = MAX_DH_KEY_SZ;
|
||||
privSz = MAX_DH_PRIV_SZ;
|
||||
privSz2 = MAX_DH_PRIV_SZ;
|
||||
pubSz = FFDHE_KEY_SIZE;
|
||||
pubSz2 = 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