Random: add DRBG reseed support

pull/130/head
Martijn de Milliano 2026-06-26 00:02:59 +00:00
parent 3c911eeb29
commit e6f4632030
3 changed files with 34 additions and 0 deletions

View File

@ -378,6 +378,7 @@ def get_features(local_wolfssl, features):
features["ML_DSA"] = 1 if '#define HAVE_DILITHIUM' in defines else 0
features["ML_KEM"] = 1 if '#define WOLFSSL_HAVE_MLKEM' in defines else 0
features["HKDF"] = 1 if "#define HAVE_HKDF" in defines else 0
features["HASHDRBG"] = 1 if "#define HAVE_HASHDRBG" in defines else 0
if '#define HAVE_FIPS' in defines:
if not fips:
@ -497,6 +498,7 @@ def build_ffi(local_wolfssl, features):
int ML_KEM_ENABLED = {features["ML_KEM"]};
int ML_DSA_ENABLED = {features["ML_DSA"]};
int HKDF_ENABLED = {features["HKDF"]};
int HASHDRBG_ENABLED = {features["HASHDRBG"]};
"""
ffibuilder.set_source( "wolfcrypt._ffi", init_source_string,
@ -537,6 +539,7 @@ def build_ffi(local_wolfssl, features):
extern int ML_KEM_ENABLED;
extern int ML_DSA_ENABLED;
extern int HKDF_ENABLED;
extern int HASHDRBG_ENABLED;
typedef unsigned char byte;
typedef unsigned int word32;
@ -551,6 +554,10 @@ def build_ffi(local_wolfssl, features):
int wc_RNG_GenerateByte(WC_RNG*, byte*);
int wc_FreeRng(WC_RNG*);
"""
if features["HASHDRBG"]:
cdef += """
int wc_RNG_DRBG_Reseed(WC_RNG*, const byte*, word32);
"""
if features["ERROR_STRINGS"]:
cdef += """
@ -1369,6 +1376,7 @@ def main(ffibuilder):
"ML_KEM": 1,
"ML_DSA": 1,
"HKDF": 1,
"HASHDRBG": 1,
}
# Ed448 requires SHAKE256, which isn't part of the Windows build, yet.

View File

@ -21,7 +21,9 @@
# pylint: disable=redefined-outer-name
import pytest
from wolfcrypt._ffi import lib as _lib
from wolfcrypt.random import Random
from wolfcrypt.exceptions import WolfCryptApiError
@pytest.fixture
@ -48,3 +50,17 @@ def test_nonce_byte(rng_nonce):
@pytest.mark.parametrize("length", (1, 8, 128))
def test_nonce_bytes(rng_nonce, length):
assert len(rng_nonce.bytes(length)) == length
@pytest.mark.skipif(not _lib.HASHDRBG_ENABLED, reason="Reseeding only available with hash-DRBG")
def test_reseed(rng):
rng.reseed(b"some seed material for testing")
assert len(rng.bytes(32)) == 32
@pytest.mark.skipif(not _lib.HASHDRBG_ENABLED, reason="Reseeding only available with hash-DRBG")
def test_reseed_empty(rng):
try:
rng.reseed(b"")
except WolfCryptApiError:
pass # acceptable — C rejects zero-length seed

View File

@ -77,3 +77,13 @@ class Random:
raise WolfCryptApiError("RNG generate block error", ret)
return _ffi.buffer(result, length)[:]
if _lib.HASHDRBG_ENABLED:
def reseed(self, seed: __builtins__.bytes) -> None:
"""
Reseed the DRBG with the provided seed material.
"""
assert self.native_object is not None
ret = _lib.wc_RNG_DRBG_Reseed(self.native_object, seed, len(seed))
if ret < 0:
raise WolfCryptApiError("RNG reseed error", ret)