@@ -58,3 +58,185 @@ For building wolfCrypt test project in Visual Studio open the `test.sln`. For ne
5858If you see an error about ` rc.exe ` then you'll need to update the "Target Platform Version". You can do this by right-clicking on the test project -> General -> "Target Platform Version" and changing to 8.1 (needs to match the wolfssl library project).
5959
6060This solution includes the wolfSSL library project at ` <wolfssl-root>wolfssl.vcxproj ` and will compile the library, then the test project.
61+
62+ --------
63+
64+ Jan 2026 - Reviewing the older FIPS compliant CRNGT test specified in FIPS 140-2
65+ ss 4.9.2 vs the newer replacement tests RCT/ADP that are allowed to replace the
66+ CRNGT under the new FIPS 140-3 / ISO 19790 standard.
67+
68+ ================================================================================
69+ DRBG Continuous Health Test Statistical Analysis & Diagnostic Report
70+ ================================================================================
71+
72+ OVERVIEW
73+ --------
74+ This document describes the statistical false positive behavior of the DRBG
75+ continuous health test in wc_RNG_TestSeed() and provides diagnostic tools to
76+ distinguish between:
77+ 1 . Statistical false positives (expected behavior)
78+ 2 . Entropy source depletion (under heavy concurrent load)
79+ 3 . Actual stuck entropy source (hardware failure)
80+
81+
82+ BACKGROUND: THE ISSUE
83+ ---------------------
84+ The DRBG was experiencing high volumes of (DRBG_CONT_FIPS_E) on wc_InitRng()
85+ calls.
86+
87+ Example error:
88+ ERROR: wc_InitRng failed at iteration 330788 with code -209
89+
90+ This raises the question: Is this a bug in wc_RNG_TestSeed() or expected
91+ statistical behavior?
92+
93+
94+ STATISTICAL ANALYSIS
95+ --------------------
96+
97+ The wc_RNG_TestSeed() Function Behavior:
98+ - Compares ALL consecutive SEED_BLOCK_SZ chunks in the seed buffer
99+ - With FIPS mode (typical configuration):
100+ SEED_SZ = 256 * 4 / 8 = 128 bytes (1024-bits)
101+ SEED_BLOCK_SZ = 4 bytes (default) (32-bits)
102+ seedSz passed to test = 132 bytes (SEED_SZ + SEED_BLOCK_SZ)
103+ Number of comparisons = ~ 32 consecutive block pairs
104+
105+ False Positive Probability Calculation:
106+ - Probability one 4-byte block equals another random 4-byte block: 1/2^32
107+ - With 32 comparisons per seed: 32/2^32 ≈ 1 in 134 million per wc_InitRng()
108+
109+ Test Configuration (Default):
110+ - 40 threads × 100M iterations = 4 BILLION total wc_InitRng() calls
111+ - Expected false positives: 4,000,000,000 × (32/2^32) ≈ 30 failures
112+
113+ Conclusion:
114+ Seeing failures around 1 in 30-140 million is EXPECTED STATISTICAL BEHAVIOR.
115+ Under heavy concurrent load (40 threads), entropy source
116+ depletion can also cause legitimate failures.
117+
118+
119+ TESTING IT
120+ --------------------
121+
122+ Non-FIPS:
123+
124+ ./configure CFLAGS="-DWC_RNG_SEED_DEBUG -DREALLY_LONG_DRBG_CONTINUOUS_TEST"
125+ make
126+ ./wolfcrypt/test/testwolfcrypt
127+
128+ FIPS:
129+
130+ ./configure --enable-fips=<flavor> CFLAGS="-DWC_RNG_SEED_DEBUG -DREALLY_LONG_DRBG_CONTINUOUS_TEST"
131+ make
132+ ./fips-hash.sh
133+ make
134+ ./wolfcrypt/test/testwolfcrypt
135+
136+
137+ OUTPUTS EXPECTED
138+ --------------------
139+
140+ Non-FIPS:
141+
142+ Math: Multi-Precision: Wolf(SP) word-size=64 bits=4096 sp_int.c
143+ ------------------------------------------------------------------------------
144+ wolfSSL version 5.8.4
145+ ------------------------------------------------------------------------------
146+ macro test passed!
147+ error test passed!
148+ MEMORY test passed!
149+ base64 test passed!
150+ asn test passed!
151+ MD5 test passed!
152+ SHA test passed!
153+ SHA-224 test passed!
154+ SHA-256 test passed!
155+ SHA-384 test passed!
156+ SHA-512 test passed!
157+ SHA-512/224 test passed!
158+ SHA-512/256 test passed!
159+ SHA-3 test passed!
160+ RNG Entropy Source: getrandom() syscall
161+ ===============================================
162+ DRBG Continuous Test Validation Suite
163+ ===============================================
164+ FIPS Build: NO
165+
166+ --- Test 1: Basic RNG Functionality ---
167+ Generated 32 random bytes successfully
168+ [PASS] Basic RNG Functionality
169+
170+ --- Test 2: Multiple RNG Instances ---
171+ Successfully operated 100 RNG instances concurrently
172+ [PASS] Multiple RNG Instances
173+
174+ --- Test 3: FIPS Status Check ---
175+ SKIPPED: FIPS not enabled
176+ [PASS] FIPS Status Check
177+
178+ --- Test 4: RNG ReInit Test (multi-threaded) ---
179+ Configuration: 40 threads × 100000000 iterations = 4000000000 total
180+ Test Profile: Default (Aggressive multi-threaded)
181+ Expected statistical false positive rate: ~29.80 failures
182+ Duplicate block at offset 4:
183+ Block 1: E6 E9 D1 7B
184+ Block 2: E6 E9 D1 7B
185+ Full seed buffer (52 bytes):
186+ DA 93 B7 88 E6 E9 D1 7B E6 E9 D1 7B A5 4C C9 E9
187+ 13 EE D8 4C B3 C1 71 DE 32 37 17 F2 E7 A4 29 7D
188+ 9B 02 B0 0C EC 8D AC F5 DA B1 71 05 84 C0 61 75
189+ 59 6D 87 B5
190+ ERROR: wc_InitRng failed at iteration 778551 with code -209
191+ ERROR: wc_RNG_GenerateBlock failed at iteration 778551 with code -199
192+ ...
193+ (18 other failures truncated here for brevity)
194+ ...
195+ Duplicate block at offset 16:
196+ Block 1: C1 19 37 B1
197+ Block 2: C1 19 37 B1
198+ Full seed buffer (52 bytes):
199+ 62 66 5B D2 F5 54 47 9B 59 DD 0A 55 4B 52 8C 39
200+ C1 19 37 B1 C1 19 37 B1 3F 62 CB 2E FE 56 65 4D
201+ 4F 0C A7 7D 1C 09 48 51 30 1B CA 00 56 9F 29 A7
202+ E3 93 EF 8E
203+ ERROR: wc_InitRng failed at iteration 90467867 with code -209
204+ ERROR: wc_RNG_GenerateBlock failed at iteration 90467867 with code -199
205+ Thread 0 Succeeded
206+ ...
207+ 38 other thread results truncated here for brevity (all threads succeeded
208+ even though they experienced 1 or 2 failures in several of the threads)
209+ ...
210+ Thread 39 Succeeded
211+ Reinitialized RNG 4000000000 times across 40 threads
212+ Experienced 0 thread failures and 40 thread successes
213+ 20/4000000000 API calls failed <--- This is the bread and the butter of the
214+ test, we unfortunately expect to see
215+ ~ 29.80 failures, prior to the newer FIPS
216+ 140-3 RCT and ADP tests the CRNGT was
217+ required. Now the CRNGT is replaceable
218+ by the more mathematically robust
219+ RCT/ADP.
220+ [ PASS] RNG Reinitialization
221+
222+
223+
224+ TESTING RESULTS with the CRNGT test:
225+ --------------------
226+
227+ Old implementation non-FIPS:
228+ Run 1 - 6 failures in 4 billion runs (100M per thread, 40 threads)
229+ Run 2 - 11 failures in 4 billion (100M per thread, 40 threads)
230+ Run 3 - 13 failures in 4 billion (100M per thread, 40 threads)
231+
232+ Old implementation with FIPS:
233+ (keeping in mind just a single failure means catastrophic
234+ failure for the entire module until power cycled):
235+ Run 1 - 3990118689 failures in 4 billion API calls (yikes)
236+
237+ TESTING RESULTS with the RCT/ADP tests in place of the CRNGT test:
238+
239+ New implementation non-FIPS: 4 billion successes
240+ New implementation FIPS: 4 billion successes
241+
242+
0 commit comments