Skip to content

Commit 48c6f34

Browse files
committed
add DRBG reseed boundary test
1 parent b0e115e commit 48c6f34

2 files changed

Lines changed: 56 additions & 0 deletions

File tree

tests/api/test_random.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,60 @@ int test_wc_RNG_GenerateBlock_Reseed(void)
9494
return EXPECT_RESULT();
9595
}
9696

97+
/*
98+
* Exercise the exact Hash_DRBG reseed-counter boundary: a mutation of
99+
* `>=` to `>` in the reseed check would survive all existing tests because
100+
* nothing generates WC_RESEED_INTERVAL blocks. Set the counter to the
101+
* boundary, generate, and confirm the next call reseeds (counter resets).
102+
*/
103+
int test_wc_RNG_ReseedBoundary(void)
104+
{
105+
EXPECT_DECLS;
106+
#if defined(HAVE_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) && \
107+
!defined(HAVE_FIPS)
108+
/* FIPS builds keep DRBG_internal opaque (defined only inside the FIPS
109+
* module), so we can't poke reseedCtr directly. Skip under FIPS. */
110+
WC_RNG rng;
111+
struct DRBG_internal* drbg;
112+
byte out[32];
113+
#ifdef WORD64_AVAILABLE
114+
word64 startCtr;
115+
#else
116+
word32 startCtr;
117+
#endif
118+
119+
XMEMSET(&rng, 0, sizeof(WC_RNG));
120+
ExpectIntEQ(wc_InitRng(&rng), 0);
121+
122+
/* The test requires a regular in-process DRBG. Skip when wc_InitRng
123+
* routes to a bank (status != DRBG_OK), when the backend bypasses the
124+
* DRBG (RDRAND, cryptocb, etc.) and leaves the counter untouched, or
125+
* when drbg is otherwise not a DRBG_internal. */
126+
drbg = (struct DRBG_internal*)rng.drbg;
127+
if (drbg != NULL && rng.status == WC_DRBG_OK) {
128+
startCtr = drbg->reseedCtr;
129+
ExpectIntEQ(wc_RNG_GenerateBlock(&rng, out, sizeof(out)), 0);
130+
if (drbg->reseedCtr == startCtr + 1) {
131+
/* Counter advanced, so this backend really is the DRBG. Set to
132+
* WC_RESEED_INTERVAL - 1 and verify the reseed boundary:
133+
* - First generate: counter -> WC_RESEED_INTERVAL.
134+
* - Second generate: counter >= WC_RESEED_INTERVAL triggers
135+
* reseed (counter = 1), then post-increments to 2.
136+
* A `>` mutation of the check would leave the counter at
137+
* WC_RESEED_INTERVAL + 1 instead. */
138+
drbg->reseedCtr = WC_RESEED_INTERVAL - 1;
139+
ExpectIntEQ(wc_RNG_GenerateBlock(&rng, out, sizeof(out)), 0);
140+
ExpectTrue(drbg->reseedCtr == WC_RESEED_INTERVAL);
141+
ExpectIntEQ(wc_RNG_GenerateBlock(&rng, out, sizeof(out)), 0);
142+
ExpectTrue(drbg->reseedCtr == 2);
143+
}
144+
}
145+
146+
DoExpectIntEQ(wc_FreeRng(&rng), 0);
147+
#endif
148+
return EXPECT_RESULT();
149+
}
150+
97151
int test_wc_RNG_GenerateBlock(void)
98152
{
99153
EXPECT_DECLS;

tests/api/test_random.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
int test_wc_InitRng(void);
2828
int test_wc_RNG_GenerateBlock_Reseed(void);
29+
int test_wc_RNG_ReseedBoundary(void);
2930
int test_wc_RNG_GenerateBlock(void);
3031
int test_wc_RNG_GenerateByte(void);
3132
int test_wc_InitRngNonce(void);
@@ -39,6 +40,7 @@ int test_wc_RNG_HealthTest(void);
3940
#define TEST_RANDOM_DECLS \
4041
TEST_DECL_GROUP("random", test_wc_InitRng), \
4142
TEST_DECL_GROUP("random", test_wc_RNG_GenerateBlock_Reseed), \
43+
TEST_DECL_GROUP("random", test_wc_RNG_ReseedBoundary), \
4244
TEST_DECL_GROUP("random", test_wc_RNG_GenerateBlock), \
4345
TEST_DECL_GROUP("random", test_wc_RNG_GenerateByte), \
4446
TEST_DECL_GROUP("random", test_wc_InitRngNonce), \

0 commit comments

Comments
 (0)