CryptGenRandom

CryptGenRandom is a deprecated cryptographically secure pseudorandom number generator function that is included in Microsoft CryptoAPI. In Win32 programs, Microsoft recommends its use anywhere random number generation is needed. A 2007 paper from Hebrew University suggested security problems in the Windows 2000 implementation of CryptGenRandom (assuming the attacker has control of the machine). Microsoft later acknowledged that the same problems exist in Windows XP, but not in Vista. Microsoft released a fix for the bug with Windows XP Service Pack 3 in mid-2008.
Background.
The Win32 API includes comprehensive support for cryptographic security, including native TLS support (via the "SCHANNEL" API) and code signing. These capabilities are built on native Windows libraries for cryptographic operations, such as RSA and AES key generation. These libraries in turn rely on a cryptographically secure pseudorandom number generator (CSPRNG). CryptGenRandom is the standard CSPRNG for the Win32 programming environment.
Method of operation.
Microsoft-provided cryptography providers share the same implementation of CryptGenRandom, currently based on an internal function called RtlGenRandom. Only a general outline of the algorithm had been published :
["RtlGenRandom"] generates as specified in FIPS 186-2 appendix 3.1 with SHA-1 as the G function. And with entropy from:
["omitted: long lists of low-level system information fields and performance counters"]
Security.
The security of a cryptosystem's CSPRNG is significant because it is the origin for dynamic key material. Keys needed "on the fly", such as the AES TLS session keys that protect HTTPS sessions with bank websites, originate from CSPRNGs. If these pseudorandom numbers are predictable, session keys are predictable as well. Because CryptGenRandom is the de facto standard CSPRNG in Win32 environments, its security is critical for Windows users.
The specifics of CryptGenRandom's algorithm have not been officially published. As with any unpublished random number generation algorithm, it may be susceptible to theoretical weaknesses including the use of outdated algorithms, and a reliance for entropy gathering on several monotonically-increasing counters that might be estimated or controlled to an extent by an attacker with local access to the system.
Cryptanalysis.
A cryptanalysis of CryptGenRandom, published in November 2007 by Leo Dorrendorf and others from the Hebrew University of Jerusalem and University of Haifa, found significant weaknesses in the Windows 2000 implementation of the algorithm.
To take advantage of the vulnerability, an attacker would first need to compromise the program running the random number generator. The weaknesses in the paper all depend on an attacker siphoning the state bits out of the generator. An attacker in a position to carry out this attack would typically already be in a position to defeat any random number generator (for instance, they can simply sniff the outputs of the generator, or fix them in memory to known values). However, the Hebrew University team notes that an attacker only need steal the state bits once in order to persistently violate the security of a CryptGenRandom instance. They can also use the information they glean to determine past random numbers that were generated, potentially compromising information, such as credit card numbers, already sent.
The paper's attacks are based on the fact that CryptGenRandom uses the stream cipher RC4, which can be run backwards once its state is known. They also take advantage of the fact that CryptGenRandom runs in user mode, allowing anyone who gains access to the operating system at user level, for example by exploiting a buffer overflow, to get CryptGenRandom's state information for that process. Finally, CryptGenRandom refreshes its seed from entropy infrequently. This problem is aggravated by the fact that each Win32 process has its own instance of CryptGenRandom state; while this means that a compromise of one process does not transitively compromise every other process, it may also increase the longevity of any successful break.
Because the details of the CryptGenRandom algorithm are not public, Dorrendorf's team used reverse engineering tools to discern how the algorithm works. Their paper is the first published record of how the Windows cryptographic random number generator operates.
Common Criteria.
Windows 2000, XP and 2003 have all successfully undergone EAL4+ evaluations, including the CryptGenRandom() and FIPSGenRandom() implementations. The Security Target documentation is available at the Common Criteria Portal, and indicates compliance with the EAL4 requirements. Few conclusions can be drawn about the security of the algorithm as a result; EAL4 measures products against best practices and stated security objectives, but rarely involves in-depth cryptanalysis.
FIPS validation.
Microsoft has obtained validation of its RNG implementations in the following environments:
These tests are "designed to test conformance to the various approved RNG specifications rather
than provide a measure of a product’s security. [...] Thus, validation should not be interpreted as an evaluation or
endorsement of overall product security." Few conclusions can be drawn about the security of the algorithm as a result; FIPS evaluations do not necessarily inspect source code or evaluate the way RNG seeds are generated.
Alternatives.
API level.
Windows developers have several alternative means of accessing the CryptGenRandom functionality; these alternatives invoke the same algorithm and share the same security characteristics, but may have other advantages.
Using RtlGenRandom.
"Historically, we always told developers not to use functions such as rand to generate keys, nonces and passwords, rather they should use functions like CryptGenRandom, which creates cryptographically secure random numbers. The problem with CryptGenRandom is you need to pull in CryptoAPI (CryptAcquireContext and such) which is fine if you're using other crypto functions.
On a default Windows XP and later install, CryptGenRandom calls into a function named ADVAPI32!RtlGenRandom, which does not require you load all the CryptAPI stuff. In fact, the new Whidbey CRT function, rand_s calls RtlGenRandom".
Using RNGCryptoServiceProvider.
Programmers using .NET should use the RNGCryptoServiceProvider Class.
Using Cryptography API: Next Generation (CNG).
The CNG is a long term replacement for the deprecated Crypto API. It provides an equivalent function BCryptGenRandom as well as dedicated functions for key generation.