Entropy Sources
This implementation of Fortuna uses a number of different entropy sources.
High Performance Timer
As part of my work developing this implementation of Fortuna, I investigated using the high performance timer as a source of entropy. I found that for my particular system, there were 3 bits of entropy available for each timing done using the high performance timer on the Sleep() API function. Go here for a detailed description of what I found using the high performance timer for gathering entropy.
My implementation of Fortuna uses 32 threads that simply collect this timing data. Is this overkill? I'm not sure, but it certainly does not put much of a load on the system because the 32 threads are mainly sleeping. For the systems I've tested this appears to be a good source of random data to feed to the pools. With this much data, reseeds happen fairly often so that if the prng state is compromised, a new state is being used typically within a few seconds.
Windows Registry
The Windows Registry is a large data repository. There are 4 different threads which walk each section of the registry, adding the data in the registry to the 32 entropy pools. Each time a registry value is retrieved, the bytes are spread out among the entropy pools. After each registry entry is retrieved, the registry source thread Sleeps() an additional 10-50 ms. The length of the sleep is a function of the data retrieved from the registry. See SourceRegistryWalker::GetChaoticData() in SourceRegistryWalker.cpp for more details.
I realize that the Registry is not that random, but using the registry increases the workload of the attacker. Now the attacker desiring to manipulate inputs to the prng must also duplicate the registry. With each thread being walked on it's own thread, it is very difficult to determine which pool a given registry entry will end up in.
Process Information
The Windows API provides a lot of information about running processes. The following Win32 API functions are used to extract this process information. This information is gathered on a separate thread. This information is being gathered continually, with a Sleep of around 100-200 ms between each quantity for each process.
|
GetProcessIOCounters | |
|
GetProcessTimes | |
|
GetProcessMemoryInfo | |
|
GetPerformanceInfo | |
|
QueryWorkingSet |
Machine Signature
Each time the Fortuna PRNG begins executing, a machine signature is determined which contains static data. This data is mixed into the existing entropy pools if the pools exist, or is used as an initial seed to the pools. The machine signature consists of the following:
|
Computer Name | |
|
Windows Version | |
|
System Info | |
|
Current Hardware Profile | |
|
Environment Strings | |
|
MAC Addresses | |
|
Startup Info | |
|
Global Memory Status | |
|
Windowing Info |
Windows Crypto API
Windows provides an api for cryptographic functions. However, none of the internals of these methods are published, and given Microsoft's history of security practices it would seem unwise to rely entirely on this api. However, including it as an entropy source certainly cannot hurt. Including this provides another source that an attacker must compromise.
Ping
Pinging another computer over the internet provides an excellent source of data which is difficult for an attacker to guess. I use the high performance timer to gather timing information from Ping. Note that even if the ping times out, this still provides useful timing data which does not compress well (my tests showed only around 2% compression). The ping timing data returns so few bytes that performing a detailed statistical test with Diehard is not practical due to the amount of data required.