Skip to content

Commit 886d4f6

Browse files
committed
add DRBG reseed boundary test
1 parent b0e115e commit 886d4f6

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

tests/api/test_random.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,61 @@ 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) && !defined(HAVE_SELFTEST)
108+
/* FIPS and CAVP-selftest builds substitute an older random.h that does
109+
* not expose struct DRBG_internal or WC_DRBG_OK, so we can't poke
110+
* reseedCtr directly. Skip under either. */
111+
WC_RNG rng;
112+
struct DRBG_internal* drbg;
113+
byte out[32];
114+
#ifdef WORD64_AVAILABLE
115+
word64 startCtr;
116+
#else
117+
word32 startCtr;
118+
#endif
119+
120+
XMEMSET(&rng, 0, sizeof(WC_RNG));
121+
ExpectIntEQ(wc_InitRng(&rng), 0);
122+
123+
/* The test requires a regular in-process DRBG. Skip when wc_InitRng
124+
* routes to a bank (status != DRBG_OK), when the backend bypasses the
125+
* DRBG (RDRAND, cryptocb, etc.) and leaves the counter untouched, or
126+
* when drbg is otherwise not a DRBG_internal. */
127+
drbg = (struct DRBG_internal*)rng.drbg;
128+
if (drbg != NULL && rng.status == WC_DRBG_OK) {
129+
startCtr = drbg->reseedCtr;
130+
ExpectIntEQ(wc_RNG_GenerateBlock(&rng, out, sizeof(out)), 0);
131+
if (drbg->reseedCtr == startCtr + 1) {
132+
/* Counter advanced, so this backend really is the DRBG. Set to
133+
* WC_RESEED_INTERVAL - 1 and verify the reseed boundary:
134+
* - First generate: counter -> WC_RESEED_INTERVAL.
135+
* - Second generate: counter >= WC_RESEED_INTERVAL triggers
136+
* reseed (counter = 1), then post-increments to 2.
137+
* A `>` mutation of the check would leave the counter at
138+
* WC_RESEED_INTERVAL + 1 instead. */
139+
drbg->reseedCtr = WC_RESEED_INTERVAL - 1;
140+
ExpectIntEQ(wc_RNG_GenerateBlock(&rng, out, sizeof(out)), 0);
141+
ExpectTrue(drbg->reseedCtr == WC_RESEED_INTERVAL);
142+
ExpectIntEQ(wc_RNG_GenerateBlock(&rng, out, sizeof(out)), 0);
143+
ExpectTrue(drbg->reseedCtr == 2);
144+
}
145+
}
146+
147+
DoExpectIntEQ(wc_FreeRng(&rng), 0);
148+
#endif
149+
return EXPECT_RESULT();
150+
}
151+
97152
int test_wc_RNG_GenerateBlock(void)
98153
{
99154
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)