Skip to content

Commit 4047aa2

Browse files
authored
Merge pull request #233 from wolfSSL/update-random-seed-section
Update section 2.7 Random Seed with comprehensive documentation
2 parents 3479bd4 + d6f4d24 commit 4047aa2

File tree

1 file changed

+217
-3
lines changed

1 file changed

+217
-3
lines changed

wolfSSL-Porting/src/section02.md

Lines changed: 217 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,225 @@ If wolfSSL needs to be used in a multithreaded environment, the wolfSSL mutex la
127127
## Random Seed
128128

129129
Q: When do I need to read this section?
130-
A: Either /dev/random or /dev/urandom is not available or you want to integrate into a hardware RNG.
130+
A: Either /dev/random or /dev/urandom is not available, you want to integrate into a hardware RNG, or you need to understand wolfSSL's random number generation architecture.
131131

132-
By default, wolfSSL uses /dev/urandom or /dev/random to generate a RNG seed. The NO_DEV_RANDOM define can be used when building wolfSSL to disable the default GenerateSeed() function. If this is defined, you need to write a custom GenerateSeed() function in ./wolfcrypt/src/random.c, specific to your target platform. This allows you to seed wolfSSL’s PRNG with a hardware-based random entropy source if available.
132+
### Overview
133133

134-
For examples of how GenerateSeed() needs to be written, reference wolfSSL’s existing GenerateSeed() implementations in ./wolfcrypt/src/random.c.
134+
wolfSSL uses a FIPS-certified Hash_DRBG (Deterministic Random Bit Generator) based on SHA-256 by default. This DRBG is compliant with NIST SP 800-90A and provides cryptographically secure random number generation for all SSL/TLS operations. The DRBG requires an entropy source (seed) to initialize and periodically reseed itself.
135+
136+
### Default Behavior
137+
138+
By default, wolfSSL's DRBG obtains entropy from the following sources in order of preference:
139+
140+
1. **Hardware entropy sources** (if available and enabled):
141+
- Intel RDSEED instruction (`HAVE_INTEL_RDSEED`)
142+
- AMD RDSEED instruction (`HAVE_AMD_RDSEED`)
143+
- Platform-specific hardware RNG (various embedded platforms)
144+
145+
2. **Operating system entropy sources**:
146+
- `/dev/urandom` (preferred on Unix-like systems)
147+
- `/dev/random` (fallback if /dev/urandom is unavailable)
148+
- `getrandom()` system call on Linux (when `WOLFSSL_GETRANDOM` is defined)
149+
150+
The DRBG is enabled by default and can be found in `./wolfcrypt/src/random.c`. The Hash_DRBG implementation uses SHA-256 and maintains internal state that is periodically reseeded to ensure continued entropy.
151+
152+
### Disabling /dev/urandom or /dev/random
153+
154+
If your platform does not have `/dev/urandom` or `/dev/random`, or you want to disable their use, you can define:
155+
156+
- **`NO_DEV_URANDOM`**: Disables use of `/dev/urandom` (will fall back to `/dev/random`)
157+
- **`NO_DEV_RANDOM`**: Disables use of both `/dev/urandom` and `/dev/random`
158+
159+
When `NO_DEV_RANDOM` is defined, you must provide an alternative entropy source using one of the methods described below.
160+
161+
### Disabling the DRBG
162+
163+
The entire Hash_DRBG can be disabled by defining `WC_NO_HASHDRBG`. However, when the DRBG is disabled, you **must** provide a custom random number generator using `CUSTOM_RAND_GENERATE_BLOCK`.
164+
165+
Example in `user_settings.h`:
166+
```c
167+
#define WC_NO_HASHDRBG
168+
#define CUSTOM_RAND_GENERATE_BLOCK myHardwareRNG
169+
```
170+
171+
Where `myHardwareRNG` is a function with the signature:
172+
```c
173+
int myHardwareRNG(unsigned char* output, unsigned int sz);
174+
```
175+
176+
This function should fill the `output` buffer with `sz` bytes of random data from your hardware RNG and return 0 on success.
177+
178+
### Custom Seed Generation Methods
179+
180+
wolfSSL provides several methods to customize how the DRBG obtains its seed:
181+
182+
#### 1. CUSTOM_RAND_GENERATE_SEED
183+
184+
Define a custom function that generates seed data. This is the most direct way to provide entropy.
185+
186+
```c
187+
#define CUSTOM_RAND_GENERATE_SEED myGenerateSeed
188+
189+
int myGenerateSeed(unsigned char* output, unsigned int sz)
190+
{
191+
/* Fill output buffer with sz bytes of entropy from your source */
192+
/* Return 0 on success, non-zero on error */
193+
}
194+
```
195+
196+
#### 2. CUSTOM_RAND_GENERATE
197+
198+
Define a function that returns random values one at a time. wolfSSL will call this function repeatedly to fill the seed buffer.
199+
200+
```c
201+
#define CUSTOM_RAND_GENERATE myRandFunc
202+
#define CUSTOM_RAND_TYPE unsigned int
203+
204+
unsigned int myRandFunc(void)
205+
{
206+
/* Return a random value from your entropy source */
207+
}
208+
```
209+
210+
The `CUSTOM_RAND_TYPE` should match the return type of your function (e.g., `unsigned int`, `unsigned long`, etc.).
211+
212+
Example from `./wolfcrypt/src/random.c`:
213+
```c
214+
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
215+
{
216+
word32 i = 0;
217+
while (i < sz) {
218+
if ((i + sizeof(CUSTOM_RAND_TYPE)) > sz ||
219+
((wc_ptr_t)&output[i] % sizeof(CUSTOM_RAND_TYPE)) != 0) {
220+
output[i++] = (byte)CUSTOM_RAND_GENERATE();
221+
}
222+
else {
223+
*((CUSTOM_RAND_TYPE*)&output[i]) = CUSTOM_RAND_GENERATE();
224+
i += sizeof(CUSTOM_RAND_TYPE);
225+
}
226+
}
227+
return 0;
228+
}
229+
```
230+
231+
#### 3. wc_SetSeed_Cb (Runtime Callback)
232+
233+
Set a seed generation callback at runtime using `wc_SetSeed_Cb()`. This requires defining `WC_RNG_SEED_CB` at build time.
234+
235+
Build configuration:
236+
```c
237+
#define WC_RNG_SEED_CB
238+
```
239+
240+
Runtime usage:
241+
```c
242+
#include <wolfssl/wolfcrypt/random.h>
243+
244+
int myCustomSeedFunc(OS_Seed* os, byte* seed, word32 sz)
245+
{
246+
/* Generate sz bytes of entropy into seed buffer */
247+
/* Return 0 on success */
248+
}
249+
250+
/* Set the callback before initializing RNG */
251+
wc_SetSeed_Cb(myCustomSeedFunc);
252+
253+
/* Now initialize and use RNG as normal */
254+
WC_RNG rng;
255+
wc_InitRng(&rng);
256+
```
257+
258+
The `wc_SetSeed_Cb` function is defined in `./wolfcrypt/src/random.c`.
259+
260+
#### 4. Crypto Callbacks (WC_ALGO_TYPE_SEED)
261+
262+
Use wolfSSL's crypto callback mechanism to provide seed generation through a hardware security module or custom crypto device. This requires `WOLF_CRYPTO_CB` to be defined.
263+
264+
Build configuration:
265+
```c
266+
#define WOLF_CRYPTO_CB
267+
```
268+
269+
Implementation example (from `wolfssl-examples/tls/cryptocb-common.c`):
270+
```c
271+
int myCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
272+
{
273+
if (info->algo_type == WC_ALGO_TYPE_SEED) {
274+
/* Generate random seed data */
275+
/* info->seed.seed = output buffer */
276+
/* info->seed.sz = requested size */
277+
278+
/* Example: Fill with entropy from hardware */
279+
while (info->seed.sz > 0) {
280+
word32 len = (info->seed.sz < BLOCK_SIZE) ? info->seed.sz : BLOCK_SIZE;
281+
/* Get entropy from your hardware */
282+
getHardwareEntropy(info->seed.seed, len);
283+
info->seed.seed += len;
284+
info->seed.sz -= len;
285+
}
286+
return 0;
287+
}
288+
return CRYPTOCB_UNAVAILABLE;
289+
}
290+
291+
/* Register the callback */
292+
int devId = 1;
293+
wc_CryptoCb_RegisterDevice(devId, myCryptoCb, NULL);
294+
295+
/* Use the device ID when initializing RNG */
296+
WC_RNG rng;
297+
wc_InitRng_ex(&rng, NULL, devId);
298+
```
299+
300+
This method is particularly useful for integrating with HSMs, TPMs, or other hardware security devices.
301+
302+
### Testing and Development
303+
304+
#### WOLFSSL_GENSEED_FORTEST
305+
306+
For development and testing purposes only, you can define `WOLFSSL_GENSEED_FORTEST` to use a fake, predictable seed. **This should never be used in production** as it provides no security.
307+
308+
```c
309+
#define WOLFSSL_GENSEED_FORTEST
310+
```
311+
312+
This will generate a deterministic seed pattern (0x00, 0x01, 0x02, ...) suitable only for testing and debugging. The implementation can be found in `./wolfcrypt/src/random.c`.
313+
314+
### Platform-Specific Examples
315+
316+
For examples of platform-specific `wc_GenerateSeed()` implementations, reference the existing implementations in `./wolfcrypt/src/random.c`:
317+
318+
- **Windows**: Uses `CryptGenRandom()` or `BCryptGenRandom()`
319+
- **SGX**: Uses `sgx_read_rand()`
320+
- **Embedded platforms**: Various implementations for FreeRTOS, Zephyr, Micrium, etc.
321+
- **Hardware RNG**: Examples for STM32, NXP, Renesas, Infineon, and other platforms
322+
323+
### Summary of Configuration Options
324+
325+
| Define | Purpose | Requires |
326+
|--------|---------|----------|
327+
| `NO_DEV_URANDOM` | Disable /dev/urandom | Falls back to /dev/random |
328+
| `NO_DEV_RANDOM` | Disable /dev/urandom and /dev/random | Alternative seed source |
329+
| `WC_NO_HASHDRBG` | Disable Hash_DRBG entirely | `CUSTOM_RAND_GENERATE_BLOCK` |
330+
| `CUSTOM_RAND_GENERATE_BLOCK` | Provide complete RNG replacement | Function implementation |
331+
| `CUSTOM_RAND_GENERATE_SEED` | Custom seed generation function | Function implementation |
332+
| `CUSTOM_RAND_GENERATE` | Custom random value function | Function + `CUSTOM_RAND_TYPE` |
333+
| `WC_RNG_SEED_CB` | Enable runtime seed callback | `wc_SetSeed_Cb()` usage |
334+
| `WOLF_CRYPTO_CB` | Enable crypto callbacks | Callback registration |
335+
| `WOLFSSL_GENSEED_FORTEST` | Fake seed for testing | **Testing only!** |
336+
337+
### Recommendations
338+
339+
1. **Use the default DRBG** when possible - it's FIPS-certified and well-tested
340+
2. **For embedded systems without /dev/random**: Use `CUSTOM_RAND_GENERATE_SEED` with your hardware RNG
341+
3. **For HSM/TPM integration**: Use crypto callbacks with `WC_ALGO_TYPE_SEED`
342+
4. **For maximum flexibility**: Use `wc_SetSeed_Cb()` to set callbacks at runtime
343+
5. **Never use** `WOLFSSL_GENSEED_FORTEST` in production
344+
345+
For additional examples and reference implementations, see:
346+
- `./wolfcrypt/src/random.c` - All seed generation implementations
347+
- `wolfssl-examples/tls/cryptocb-common.c` - Crypto callback example with WC_ALGO_TYPE_SEED
348+
- Platform-specific examples in `./wolfcrypt/src/port/` directories
135349

136350
## Memory
137351

0 commit comments

Comments
 (0)