Jump to content

CryptGenRandom: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
No edit summary
m Changing short description from "Cryptographic algorithm" to "Cryptographic algorithm for random number generation"
 
(37 intermediate revisions by 19 users not shown)
Line 1: Line 1:
{{Short description|Cryptographic algorithm for random number generation}}
{{external links|date=March 2015}}
'''CryptGenRandom''' is a [[CSPRNG|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 [[Windows Vista|Vista]]. Microsoft released a fix for the bug with Windows XP Service Pack 3 in mid-2008.<ref>[http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=9048438 Microsoft confirms that XP contains random number generator bug<!-- Bot generated title -->]</ref>
'''CryptGenRandom''' is a deprecated<ref>[https://docs.microsoft.com/en-us/windows/desktop/api/wincrypt/nf-wincrypt-cryptgenrandom CryptGenRandom Function (Windows)] "Important: This API is deprecated. New and existing software should start using Cryptography Next Generation APIs. Microsoft may remove this API in future releases." (This notice applies to all of CryptoAPI.)</ref> [[CSPRNG|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 [[Windows Vista|Vista]]. Microsoft released a fix for the bug with Windows XP Service Pack 3 in mid-2008.<ref>{{cite web|url=http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=9048438|title=Microsoft confirms that XP contains random number generator bug|archive-url=https://web.archive.org/web/20080622122347/http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=9048438|archive-date=2008-06-22}}</ref>


==Background==
==Background==
The [[Win32]] [[API]] includes comprehensive support for cryptographic security, including native [[Transport Layer Security|TLS]] support (via the ''SCHANNEL'' API) and [[Code signing]]. These capabilities are built on native Windows libraries for cryptographic operations, such as [[RSA (algorithm)|RSA]] and [[Advanced Encryption Standard|AES]] key generation. These libraries in turn rely on a [[CSPRNG|cryptographically secure pseudorandom number generator]] (CSPRNG). '''CryptGenRandom''' is the standard CSPRNG for the Win32 programming environment.
The [[Win32]] [[API]] includes comprehensive support for cryptography through the [[Microsoft CryptoAPI]], a set of cryptographic primitives provided by Microsoft for use in Windows applications. Windows technologies such as [[Transport Layer Security|TLS]] support (via the [[Security Support Provider Interface#Providers|Schannel]] API) and [[code signing]] rely on these primitives, which in turn rely on a [[CSPRNG|cryptographically secure pseudorandom number generator]] (CSPRNG). {{code|CryptGenRandom}} is the standard CSPRNG supplied with the Microsoft CryptoAPI.


==Method of operation==
==Method of operation==

Microsoft-provided [[cryptography]] providers share the same implementation of CryptGenRandom, currently based on an internal [[function (computer science)|function]] called '''RtlGenRandom'''.<ref>[http://msdn2.microsoft.com/en-us/library/aa387694.aspx RtlGenRandom Function (Windows)<!-- Bot generated title -->]</ref> Only a general outline of the [[algorithm]] had been published {{As of|2007|lc=on}}:
=== Before Windows Vista ===
Microsoft-provided [[cryptography]] providers share the same implementation of {{code|CryptGenRandom}}, currently based on an internal [[function (computer science)|function]] called {{code|RtlGenRandom}}.<ref name="rtlgenrandom">{{cite web |title=RtlGenRandom function (ntsecapi.h) |url=https://learn.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom |website=Microsoft Learn |date=22 February 2024 |publisher=Microsoft |access-date=7 November 2024}}</ref> Only a general outline of the [[algorithm]] had been published {{As of|2007|lc=on}}:


<blockquote>
<blockquote>
Line 18: Line 20:
*High-precision internal CPU counters, such as RDTSC, RDMSR, RDPMC
*High-precision internal CPU counters, such as RDTSC, RDMSR, RDPMC
<nowiki>[</nowiki>''omitted: long lists of low-level system information fields and performance counters''<nowiki>]</nowiki>
<nowiki>[</nowiki>''omitted: long lists of low-level system information fields and performance counters''<nowiki>]</nowiki>
<ref>{{cite book | title=Writing Secure Code, Second Edition | isbn=0-7356-1722-8}}</ref>
<ref>{{cite book | title=Writing Secure Code, Second Edition | year=2003 | isbn=0-7356-1722-8 | url-access=registration | url=https://archive.org/details/writingsecucod00howa | last1=Howard | first1=Michael | last2=Leblanc | first2=David | publisher=Pearson Education }}</ref>
</blockquote>
</blockquote>

=== Windows Vista and above ===
Microsoft has documented the implementation of the Windows 10 random number generator in some detail, in a whitepaper published in 2019.<ref name="10white">{{cite web |last1=Ferguson |first1=Niels |title=The Windows 10 random number generation infrastructure |url=https://download.microsoft.com/download/1/c/9/1c9813b8-089c-4fef-b2ad-ad80e79403ba/Whitepaper%20-%20The%20Windows%2010%20random%20number%20generation%20infrastructure.pdf |website=download.microsoft.com |date=October 2019}}</ref> In Windows 10:
* There exists a hierarchy of random number generators. The kernel has a "Root" PRNG, from which all randomness is ultimately derived. The kernel then uses the Root PRNG to seed one PRNG per logical processor (so the PRNG state is [[thread-local]] and requires no locking). When a process launches, it requests random bytes from the kernel per-processor PRNG to seed its own Process PRNG. It then uses the Process PRNG to also seed one buffered PRNG per logical processor.<ref name="10white"/>
* All userspace calls to fetch randomness, be it {{code|CryptGenRandom}} or {{code|RtlGenRandom}}, ultimately fall to {{code|ProcessPrng}}, which returns bytes from the process's per-processor PRNG. The PRNG always uses the AES-CTR-DRBG algorithm as specified by FIPS SP800-90. Although {{code|BCryptGenRandom}} accepts requests for older algorithms for backward compatibility, it only ever return random numbers from the per-processor PRNG.<ref name="10white"/>{{rp|8}}
** AES-CTR-DRBG, instead of FIPS 186, has been the default since Windows Vista and Windows Server 2008.<ref name=CNGid/>
** The removal of other algorithms happened in Windows 10.<ref name=CNGid>{{cite web |title=CNG Algorithm Identifiers (Bcrypt.h) - Win32 apps |url=https://learn.microsoft.com/en-us/windows/win32/seccng/cng-algorithm-identifiers |website=learn.microsoft.com |language=en-us |date=13 April 2023 |quote=Note: Beginning with Windows Vista with SP1 and Windows Server 2008, the random number generator is based on the AES counter mode specified in the NIST SP 800-90 standard. [...] Windows 10: Beginning with Windows 10, the dual elliptic curve random number generator algorithm has been removed. Existing uses of this algorithm will continue to work; however, the random number generator is based on the AES counter mode specified in the NIST SP 800-90 standard.}}</ref>
* The root RNG is periodically reseeded from the entropy pools.<ref name="10white"/>{{rp|9}} At bootup when very little entropy is available, a special "initial seeding" procedure provides the seed from seed files, external entropy, [[Trusted Platform Module|TPM]] randomness, [[RDRAND]]/RDSEED instructions, ACPI-OEM0 table, UEFI entropy, and the current time.<ref name="10white"/>{{rp|11}}
* The kernel maintains multiple entropy pools. Multiple entropy sources append into pools, the main one being interrupt timing.<ref name="10white"/>{{rp|12}} When a pool is used, the SHA-512 hash of its contents is taken as the output.<ref name="10white"/>{{rp|10}} Windows does not estimate entropy.<ref name="10white"/>{{rp|16}}


==Security==
==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 security of a cryptosystem's CSPRNG is crucial because it is the origin for dynamic key material. Keys needed "on the fly", such as the TLS [[Session key|session keys]] that protect [[HTTPS]] connections, originate from CSPRNGs. If these pseudorandom numbers are predictable, session keys are predictable as well. Because {{code|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 [[information entropy|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===
===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.<ref>{{cite web|url=http://eprint.iacr.org/2007/419.pdf|format=pdf|title=Cryptanalysis of the Random Number Generator of the Windows Operating System|first=Leo|last=Dorrendorf|author2=Zvi Gutterman |author3=Benny Pinkas }}</ref>
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.<ref>{{cite web|url=http://eprint.iacr.org/2007/419.pdf|title=Cryptanalysis of the Random Number Generator of the Windows Operating System|first=Leo|last=Dorrendorf|author2=Zvi Gutterman|author3=Benny Pinkas|access-date=2007-11-12|archive-url=https://web.archive.org/web/20120518140455/http://eprint.iacr.org/2007/419.pdf|archive-date=2012-05-18|url-status=dead}}</ref>


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.
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.
Line 34: Line 43:
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 [[information entropy|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.
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 [[information entropy|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{{Citation needed|date=March 2015}}.
Because the details of the CryptGenRandom algorithm were not public at the time, 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{{Citation needed|date=March 2015}}.


===Common Criteria===
===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 [http://www.commoncriteriaportal.org 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.
Windows 2000, XP and 2003 have all successfully undergone EAL4+ evaluations, including the CryptGenRandom() and FIPSGenRandom() implementations. The Security Target documentation is available at [https://web.archive.org/web/20060718074701/http://www.commoncriteriaportal.org/ 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===
===FIPS validation===
{{cleanup section|reason=Incomplete list; just going to the [https://csrc.nist.rip/groups/STM/cavp/documents/rng/rngval.html rngval page] and Ctrl-F for "Microsoft Corp" is easier. Do we really want to complete the list? It's boring and repetitive, and all it does is show FIPS 186-2 conformance.|date=March 2024}}
Microsoft has [http://csrc.nist.gov/cryptval/rng/rngval.html obtained validation] of its RNG implementations in the following environments:
Microsoft has obtained validation of its RNG implementations in the following environments:
* Windows Vista RNG implementations (certificate 321)<ref name=nistrng>{{cite web|title=RNG Validation List|url=http://csrc.nist.gov/groups/STM/cavp/documents/rng/rngval.html|publisher=NIST Computer Security Division|accessdate=18 June 2013}}</ref>
* Windows Vista and Server 2008 RNG Implementation (certificate 435)<ref name=nistrng/>
* Windows Vista RNG implementations (certificate 321)<ref name=nistrng>{{cite web|title=RNG Validation List|url=https://csrc.nist.rip/groups/STM/cavp/documents/rng/rngval.html|publisher=NIST Computer Security Division|accessdate=20 March 2024}}</ref>
* Windows 2003 Enhanced Cryptographic Provider (rsaenh.dll) (certificate 316)<ref name=nistrng />
* Windows 2003 Enhanced Cryptographic Provider (rsaenh.dll) (certificate 316)<ref name=nistrng />
* Windows 2003 Enhanced DSS and Diffie-Hellman Cryptographic Provider (dssenh.dll) (certificate 314)<ref name=nistrng />
* Windows 2003 Enhanced DSS and Diffie-Hellman Cryptographic Provider (dssenh.dll) (certificate 314)<ref name=nistrng />
Line 51: Line 62:
These tests are "designed to test conformance to the various approved RNG specifications rather
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
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.<ref name=rngvs>{{cite web|title=The Random Number Generator Validation System (RNGVS)|url=http://csrc.nist.gov/groups/STM/cavp/documents/rng/RNGVS.pdf|publisher=National Institute of Standards and Technology Computer Security Division|accessdate=18 June 2013|date=31 January 2005}}</ref>
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.<ref name=rngvs>{{cite web|title=The Random Number Generator Validation System (RNGVS)|url=http://csrc.nist.gov/groups/STM/cavp/documents/rng/RNGVS.pdf|publisher=National Institute of Standards and Technology Computer Security Division|accessdate=18 June 2013|date=31 January 2005|archive-url=https://web.archive.org/web/20130224022101/http://csrc.nist.gov/groups/STM/cavp/documents/rng/RNGVS.pdf|archive-date=24 February 2013|url-status=dead}}</ref>


The RNG validation list carries the following notice: "As of January 1, 2016, in accordance with the SP800-131A Revision 1 Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths, the use of RNGs specified in FIPS 186-2, [X9.31], and the 1998 version of [X9.62] is no longer approved. This list is provided for historical purposes only."<ref>{{cite web |title=Cryptographic Algorithm Validation Program: rng Validation List |url=https://csrc.nist.rip/Projects/Cryptographic-Algorithm-Validation-Program/Validation/Validation-List/RNG}}</ref>
===Source Code Access programs===
There are a number of [http://www.microsoft.com/en-us/sharedsource/default.aspx source code access programs] offered by Microsoft (usually protected by very explicit EULAs) that provide access to source code not otherwise shared with the general public.


==Alternatives==
==Alternatives==
Line 62: Line 72:


====Using RtlGenRandom====
====Using RtlGenRandom====
If backwards compatibility up to Windows XP is required for your program, the Windows API function {{code|RtlGenRandom}} (which resides in {{code|advapi32.dll}}<ref name="rtlgenrandom" />) can be called to generate secure random data, as shown below. If this is not an issue, the program should use the newer {{code|BCryptGenRandom}} call instead.
<blockquote>
<blockquote>
"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.
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 [[Visual Studio 2005|Whidbey]] CRT function, rand_s calls RtlGenRandom".<ref name=Howard>[http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx Michael Howard's Web Log : Cryptographically Secure Random number on Windows without using CryptoAPI<!-- Bot generated title -->]</ref>
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 [[Visual Studio 2005|Whidbey]] CRT function, rand_s calls RtlGenRandom.<ref name="rand_s" />
</blockquote>
</blockquote>


====Using RNGCryptoServiceProvider====
====Using RNGCryptoServiceProvider====
Programmers using [[.NET Framework|.NET]] should use the [http://msdn2.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.aspx RNGCryptoServiceProvider Class].<ref>http://jis.mit.edu/pipermail/saag/2004q3.txt</ref>
Programmers using [[.NET Framework|.NET]] should use the RNGCryptoServiceProvider Class.<ref>{{Cite web |url=http://jis.mit.edu/pipermail/saag/2004q3.txt |title=Archived copy |access-date=2007-08-27 |archive-url=https://web.archive.org/web/20060908135924/http://jis.mit.edu/pipermail/saag/2004q3.txt |archive-date=2006-09-08 |url-status=dead }}</ref>

====Using Cryptography API: Next Generation (CNG)====
The CNG <ref>[https://docs.microsoft.com/en-us/windows/desktop/SecCNG/cng-portal Crypto API Next Generation (Windows)]</ref> is a long term replacement for the deprecated Crypto API. It provides an equivalent function '''BCryptGenRandom'''<ref>[https://docs.microsoft.com/en-us/windows/desktop/api/Bcrypt/nf-bcrypt-bcryptgenrandom BCryptGenRandom (Windows)]</ref> as well as dedicated functions for key generation.


===Programming languages===
===Programming languages===
*the Microsoft C++ library function ''rand_s'' uses RtlGenRandom and is recommended by Microsoft for secure applications.<ref>http://msdn.microsoft.com/en-us/library/sxtz2fa8(VS.80).aspx Visual C++ Developer Center
*the Microsoft C library function {{code|rand_s}} uses {{code|RtlGenRandom}} to generate cryptographically secure random numbers.<ref name="rand_s">{{cite web |title=rand_s |url=https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/rand-s?view=msvc-170 |website=Microsoft Learn | date=2 December 2022 |publisher=Microsoft |access-date=7 November 2024}}</ref>
, rand_s</ref>
*the [[Python (programming language)|Python]] function ''urandom'' in the ''os'' module, which uses [[/dev/urandom]] on [[Unix-like]] systems, calls CryptGenRandom on Windows systems.<ref>https://docs.python.org/2/library/os.html#os.urandom Python Library Reference, OS module</ref>
*the [[Python (programming language)|Python]] function ''urandom'' in the ''os'' module, which uses [[/dev/urandom]] on [[Unix-like]] systems, calls CryptGenRandom on Windows systems.<ref>https://docs.python.org/2/library/os.html#os.urandom Python Library Reference, OS module</ref>
*the {{code|SunMSCAPI}} [[Java Cryptography Architecture|JCA]] provider available with [[OpenJDK]] and Oracle distributions of the [[Java Runtime Environment|JRE]] on Windows provides a SecureRandom implementation with the algorithm name Windows-PRNG. This class forwards all queries for random or seed bytes as well as setting additional seed bytes to CryptGenRandom.<ref>http://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunMSCAPI Oracle Java SE 8 technical documentation, Sun Providers</ref>


==See also==
==See also==

{{Portal|Cryptography}}
* [[Entropy-supplying system calls]] – the approximate equivalent of CryptGenRandom in [[OpenBSD]] and the [[Linux kernel]]
* [[Entropy-supplying system calls]] – the approximate equivalent of CryptGenRandom in [[OpenBSD]] and the [[Linux kernel]]
* [[/dev/random]] – a randomness source in most [[Unix-like]] kernels
* [[/dev/random]] – a randomness source in most [[Unix-like]] kernels
Line 86: Line 100:


==External links==
==External links==
* [http://msdn2.microsoft.com/en-us/library/aa379942.aspx Microsoft documentation for ''CryptGenRandom'']
* [https://www.microsoft.com/en-us/sharedsource/ Microsoft Shared Source licensing programs]
* [http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx Cryptographically Secure Random number on Windows without using CryptoAPI]
* [http://www.microsoft.com/technet/security/prodtech/Windows2000/w2kccwp.mspx Overview of Windows 2000 Common Criterion evaluation]
* [http://www.microsoft.com/resources/sharedsource/Licensing/default.mspx Microsoft Shared Source licensing programs]
* [http://go.microsoft.com/fwlink?/LinkID=36329 Microsoft FIPS 140 evaluations]


[[Category:Cryptographic algorithms]]
[[Category:Cryptographic algorithms]]

Latest revision as of 03:26, 24 December 2024

CryptGenRandom is a deprecated[1] 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.[2]

Background

[edit]

The Win32 API includes comprehensive support for cryptography through the Microsoft CryptoAPI, a set of cryptographic primitives provided by Microsoft for use in Windows applications. Windows technologies such as TLS support (via the Schannel API) and code signing rely on these primitives, which in turn rely on a cryptographically secure pseudorandom number generator (CSPRNG). CryptGenRandom is the standard CSPRNG supplied with the Microsoft CryptoAPI.

Method of operation

[edit]

Before Windows Vista

[edit]

Microsoft-provided cryptography providers share the same implementation of CryptGenRandom, currently based on an internal function called RtlGenRandom.[3] Only a general outline of the algorithm had been published as of 2007:

[RtlGenRandom] generates as specified in FIPS 186-2 appendix 3.1 with SHA-1 as the G function. And with entropy from:

  • The current process ID (GetCurrentProcessID).
  • The current thread ID (GetCurrentThreadID).
  • The tick count since boot time (GetTickCount).
  • The current time (GetLocalTime).
  • Various high-precision performance counters (QueryPerformanceCounter).
  • An MD4 hash of the user's environment block, which includes username, computer name, and search path. [...]
  • High-precision internal CPU counters, such as RDTSC, RDMSR, RDPMC

[omitted: long lists of low-level system information fields and performance counters] [4]

Windows Vista and above

[edit]

Microsoft has documented the implementation of the Windows 10 random number generator in some detail, in a whitepaper published in 2019.[5] In Windows 10:

  • There exists a hierarchy of random number generators. The kernel has a "Root" PRNG, from which all randomness is ultimately derived. The kernel then uses the Root PRNG to seed one PRNG per logical processor (so the PRNG state is thread-local and requires no locking). When a process launches, it requests random bytes from the kernel per-processor PRNG to seed its own Process PRNG. It then uses the Process PRNG to also seed one buffered PRNG per logical processor.[5]
  • All userspace calls to fetch randomness, be it CryptGenRandom or RtlGenRandom, ultimately fall to ProcessPrng, which returns bytes from the process's per-processor PRNG. The PRNG always uses the AES-CTR-DRBG algorithm as specified by FIPS SP800-90. Although BCryptGenRandom accepts requests for older algorithms for backward compatibility, it only ever return random numbers from the per-processor PRNG.[5]: 8 
    • AES-CTR-DRBG, instead of FIPS 186, has been the default since Windows Vista and Windows Server 2008.[6]
    • The removal of other algorithms happened in Windows 10.[6]
  • The root RNG is periodically reseeded from the entropy pools.[5]: 9  At bootup when very little entropy is available, a special "initial seeding" procedure provides the seed from seed files, external entropy, TPM randomness, RDRAND/RDSEED instructions, ACPI-OEM0 table, UEFI entropy, and the current time.[5]: 11 
  • The kernel maintains multiple entropy pools. Multiple entropy sources append into pools, the main one being interrupt timing.[5]: 12  When a pool is used, the SHA-512 hash of its contents is taken as the output.[5]: 10  Windows does not estimate entropy.[5]: 16 

Security

[edit]

The security of a cryptosystem's CSPRNG is crucial because it is the origin for dynamic key material. Keys needed "on the fly", such as the TLS session keys that protect HTTPS connections, 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.

Cryptanalysis

[edit]

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.[7]

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 were not public at the time, 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[citation needed].

Common Criteria

[edit]

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

[edit]

Microsoft has obtained validation of its RNG implementations in the following environments:

  • Windows Vista and Server 2008 RNG Implementation (certificate 435)[8]
  • Windows Vista RNG implementations (certificate 321)[8]
  • Windows 2003 Enhanced Cryptographic Provider (rsaenh.dll) (certificate 316)[8]
  • Windows 2003 Enhanced DSS and Diffie-Hellman Cryptographic Provider (dssenh.dll) (certificate 314)[8]
  • Windows 2003 Kernel Mode Cryptographic Module (fips.sys) (certificate 313)[8]
  • Windows CE and Windows Mobile Enhanced Cryptographic Provider (rsaenh.dll) (certificate 292)[8]
  • Windows CE and Windows Mobile Enhanced Cryptographic Provider (rsaenh.dll) (certificate 286)[8]
  • Windows CE Enhanced Cryptographic Provider (rsaenh.dll) (certificate 66)[8]

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.[9]

The RNG validation list carries the following notice: "As of January 1, 2016, in accordance with the SP800-131A Revision 1 Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths, the use of RNGs specified in FIPS 186-2, [X9.31], and the 1998 version of [X9.62] is no longer approved. This list is provided for historical purposes only."[10]

Alternatives

[edit]

API level

[edit]

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

[edit]

If backwards compatibility up to Windows XP is required for your program, the Windows API function RtlGenRandom (which resides in advapi32.dll[3]) can be called to generate secure random data, as shown below. If this is not an issue, the program should use the newer BCryptGenRandom call instead.

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.[11]

Using RNGCryptoServiceProvider

[edit]

Programmers using .NET should use the RNGCryptoServiceProvider Class.[12]

Using Cryptography API: Next Generation (CNG)

[edit]

The CNG [13] is a long term replacement for the deprecated Crypto API. It provides an equivalent function BCryptGenRandom[14] as well as dedicated functions for key generation.

Programming languages

[edit]
  • the Microsoft C library function rand_s uses RtlGenRandom to generate cryptographically secure random numbers.[11]
  • the Python function urandom in the os module, which uses /dev/urandom on Unix-like systems, calls CryptGenRandom on Windows systems.[15]
  • the SunMSCAPI JCA provider available with OpenJDK and Oracle distributions of the JRE on Windows provides a SecureRandom implementation with the algorithm name Windows-PRNG. This class forwards all queries for random or seed bytes as well as setting additional seed bytes to CryptGenRandom.[16]

See also

[edit]

References

[edit]
  1. ^ CryptGenRandom Function (Windows) "Important: This API is deprecated. New and existing software should start using Cryptography Next Generation APIs. Microsoft may remove this API in future releases." (This notice applies to all of CryptoAPI.)
  2. ^ "Microsoft confirms that XP contains random number generator bug". Archived from the original on 2008-06-22.
  3. ^ a b "RtlGenRandom function (ntsecapi.h)". Microsoft Learn. Microsoft. 22 February 2024. Retrieved 7 November 2024.
  4. ^ Howard, Michael; Leblanc, David (2003). Writing Secure Code, Second Edition. Pearson Education. ISBN 0-7356-1722-8.
  5. ^ a b c d e f g h Ferguson, Niels (October 2019). "The Windows 10 random number generation infrastructure" (PDF). download.microsoft.com.
  6. ^ a b "CNG Algorithm Identifiers (Bcrypt.h) - Win32 apps". learn.microsoft.com. 13 April 2023. Note: Beginning with Windows Vista with SP1 and Windows Server 2008, the random number generator is based on the AES counter mode specified in the NIST SP 800-90 standard. [...] Windows 10: Beginning with Windows 10, the dual elliptic curve random number generator algorithm has been removed. Existing uses of this algorithm will continue to work; however, the random number generator is based on the AES counter mode specified in the NIST SP 800-90 standard.
  7. ^ Dorrendorf, Leo; Zvi Gutterman; Benny Pinkas. "Cryptanalysis of the Random Number Generator of the Windows Operating System" (PDF). Archived from the original (PDF) on 2012-05-18. Retrieved 2007-11-12.
  8. ^ a b c d e f g h "RNG Validation List". NIST Computer Security Division. Retrieved 20 March 2024.
  9. ^ "The Random Number Generator Validation System (RNGVS)" (PDF). National Institute of Standards and Technology Computer Security Division. 31 January 2005. Archived from the original (PDF) on 24 February 2013. Retrieved 18 June 2013.
  10. ^ "Cryptographic Algorithm Validation Program: rng Validation List".
  11. ^ a b "rand_s". Microsoft Learn. Microsoft. 2 December 2022. Retrieved 7 November 2024.
  12. ^ "Archived copy". Archived from the original on 2006-09-08. Retrieved 2007-08-27.{{cite web}}: CS1 maint: archived copy as title (link)
  13. ^ Crypto API Next Generation (Windows)
  14. ^ BCryptGenRandom (Windows)
  15. ^ https://docs.python.org/2/library/os.html#os.urandom Python Library Reference, OS module
  16. ^ http://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunMSCAPI Oracle Java SE 8 technical documentation, Sun Providers
[edit]