Skip to content

Commit dc6db15

Browse files
committed
Check params to GeneratePrivateDh186
1 parent 8c85618 commit dc6db15

2 files changed

Lines changed: 33 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: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29605,6 +29605,27 @@ static wc_test_ret_t dh_fips_generate_test(WC_RNG *rng)
2960529605
if (ret != 0)
2960629606
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test);
2960729607

29608+
#if !defined(WOLFSSL_NO_DH186) && !defined(HAVE_SELFTEST) && \
29609+
!defined(HAVE_FIPS)
29610+
/* Regression: an oversized *privSz must be rejected before
29611+
* GeneratePrivateDh186 writes (*privSz + 8) bytes of RNG output into the
29612+
* stack-allocated cBuf (sized DH_MAX_SIZE + 8 in non-WOLFSSL_SMALL_STACK
29613+
* builds). The key still has q set here, so the call dispatches through
29614+
* GeneratePrivateDh186. Only exercised when the local src/dh.c bound
29615+
* check is in play (not HAVE_SELFTEST / HAVE_FIPS builds, which use
29616+
* separate validated modules). */
29617+
{
29618+
word32 hugePrivSz = (word32)DH_MAX_SIZE + 1;
29619+
word32 outPubSz = sizeof(pub);
29620+
ret = wc_DhGenerateKeyPair(key, rng, priv, &hugePrivSz, pub, &outPubSz);
29621+
#if defined(WOLFSSL_ASYNC_CRYPT)
29622+
ret = wc_AsyncWait(ret, &key->asyncDev, WC_ASYNC_FLAG_NONE);
29623+
#endif
29624+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
29625+
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_gen_test);
29626+
}
29627+
#endif /* !WOLFSSL_NO_DH186 && !HAVE_SELFTEST && !HAVE_FIPS */
29628+
2960829629
wc_FreeDhKey(key);
2960929630
ret = wc_InitDhKey_ex(key, HEAP_HINT, devId);
2961029631
if (ret != 0)

0 commit comments

Comments
 (0)