For unit tests of a cryptographic utility, I would like to be able to force OpenSSL’s cryptographic random number generator (both RAND_bytes and RAND_pseudo_bytes) to return predictable, repeatable byte sequences, so that various ciphertexts are in turn predictable and can be baked into test vectors. (All other key material is under my control.)
I know this totally defeats security. This will only be used for unit tests.
I cannot simply call RAND_seed with a fixed seed before each test, because (it appears) the RNG automatically seeds itself from /dev/urandom whether I want it to or not, and anyway RAND_seed doesn’t reset the RNG, it only adds the seed to the entropy pool.
Is there any way to do this? (In extremis, it looks like I could write my own PRNG engine, but I’d like to think there’s a simpler option.)
You can force the FIPS ANSI X9.31 RNG into a test mode at runtime, but not the SSLeay RNG (the default). If you recompile OpenSSL with
-DPREDICT, the default RNG will output a predictable sequence of numbers, but that’s not very convenient.The
RAND_pseudo_bytesfunction generates a predictable series of numbers, meaning it does not add entropy to itself automatically likeRAND_bytes. But like you noticed it’s only possible to add entropy to the seed, not provide the seed explicitly, so between runs of the program you’ll get different numbers. Also not helpful.But writing your own predictable RNG engine is not difficult. In fact, I’ll take you through it by making a rand engine with stdlib’s
rand()at its core:Every time you run this program, it seeds
srand()with the same number and therefore gives you the same sequence of random numbers every time.