Skip to content

Commit ad05cb5

Browse files
committed
Check params to GeneratePrivateDh186
1 parent 7867e60 commit ad05cb5

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

wolfcrypt/src/dh.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1122,13 +1122,24 @@ static int GeneratePrivateDh186(DhKey* key, WC_RNG* rng, byte* priv,
11221122
byte cBuf[DH_MAX_SIZE + 64 / WOLFSSL_BIT_SIZE];
11231123
#endif
11241124

1125-
/* Parameters validated in calling functions. */
1125+
/* Pointer parameters validated by the public entry wc_DhGenerateKeyPair. */
11261126

11271127
if (mp_iszero(&key->q) == MP_YES) {
11281128
WOLFSSL_MSG("DH q parameter needed for FIPS 186-4 key generation");
11291129
return BAD_FUNC_ARG;
11301130
}
11311131

1132+
/* Bound *privSz so cSz (= *privSz + 8) cannot exceed the cBuf capacity.
1133+
* Note: DH_MAX_SIZE is documented as a bit count, but the cBuf declaration
1134+
* above uses it directly as a byte count (cBuf is DH_MAX_SIZE + 8 bytes).
1135+
* This check matches that convention so *privSz (in bytes) is bounded by
1136+
* the actual byte capacity of cBuf. The same bound is applied to the
1137+
* WOLFSSL_SMALL_STACK path to avoid unbounded heap allocation. */
1138+
if (*privSz > DH_MAX_SIZE) {
1139+
WOLFSSL_MSG("DH private key size exceeds DH_MAX_SIZE");
1140+
return BAD_FUNC_ARG;
1141+
}
1142+
11321143
qSz = (word32)mp_unsigned_bin_size(&key->q);
11331144
pSz = (word32)mp_unsigned_bin_size(&key->p);
11341145

wolfcrypt/test/test.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27612,6 +27612,24 @@ static wc_test_ret_t dh_fips_generate_test(WC_RNG *rng)
2761227612
if (ret != 0)
2761327613
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test);
2761427614

27615+
#ifndef WOLFSSL_NO_DH186
27616+
/* Regression: an oversized *privSz must be rejected before
27617+
* GeneratePrivateDh186 writes (*privSz + 8) bytes of RNG output into the
27618+
* stack-allocated cBuf (sized DH_MAX_SIZE + 8 in non-WOLFSSL_SMALL_STACK
27619+
* builds). The key still has q set here, so the call dispatches through
27620+
* GeneratePrivateDh186. */
27621+
{
27622+
word32 hugePrivSz = (word32)DH_MAX_SIZE + 1;
27623+
word32 outPubSz = sizeof(pub);
27624+
ret = wc_DhGenerateKeyPair(key, rng, priv, &hugePrivSz, pub, &outPubSz);
27625+
#if defined(WOLFSSL_ASYNC_CRYPT)
27626+
ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE);
27627+
#endif
27628+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
27629+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test);
27630+
}
27631+
#endif /* !WOLFSSL_NO_DH186 */
27632+
2761527633
wc_FreeDhKey(key);
2761627634
ret = wc_InitDhKey_ex(key, HEAP_HINT, devId);
2761727635
if (ret != 0)

0 commit comments

Comments
 (0)