]>
git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseRngLib/BaseRng.c
2 Random number generator services that uses RdRand instruction access
3 to provide high-quality random numbers.
5 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/BaseLib.h>
17 #include <Library/DebugLib.h>
20 // Bit mask used to determine if RdRand instruction is supported.
22 #define RDRAND_MASK BIT30
25 // Limited retry number when valid random data is returned.
26 // Uses the recommended value defined in Section 7.3.17 of "Intel 64 and IA-32
27 // Architectures Software Developer's Mannual".
29 #define RDRAND_RETRY_LIMIT 10
32 The constructor function checks whether or not RDRAND instruction is supported
35 The constructor function checks whether or not RDRAND instruction is supported.
36 It will ASSERT() if RDRAND instruction is not supported.
37 It will always return RETURN_SUCCESS.
39 @retval RETURN_SUCCESS The constructor always returns EFI_SUCCESS.
44 BaseRngLibConstructor (
51 // Determine RDRAND support by examining bit 30 of the ECX register returned by
52 // CPUID. A value of 1 indicates that processor support RDRAND instruction.
54 AsmCpuid (1, 0, 0, &RegEcx
, 0);
55 ASSERT ((RegEcx
& RDRAND_MASK
) == RDRAND_MASK
);
57 return RETURN_SUCCESS
;
61 Generates a 16-bit random number.
63 if Rand is NULL, then ASSERT().
65 @param[out] Rand Buffer pointer to store the 16-bit random value.
67 @retval TRUE Random number generated successfully.
68 @retval FALSE Failed to generate the random number.
79 ASSERT (Rand
!= NULL
);
82 // A loop to fetch a 16 bit random value with a retry count limit.
84 for (Index
= 0; Index
< RDRAND_RETRY_LIMIT
; Index
++) {
85 if (AsmRdRand16 (Rand
)) {
94 Generates a 32-bit random number.
96 if Rand is NULL, then ASSERT().
98 @param[out] Rand Buffer pointer to store the 32-bit random value.
100 @retval TRUE Random number generated successfully.
101 @retval FALSE Failed to generate the random number.
112 ASSERT (Rand
!= NULL
);
115 // A loop to fetch a 32 bit random value with a retry count limit.
117 for (Index
= 0; Index
< RDRAND_RETRY_LIMIT
; Index
++) {
118 if (AsmRdRand32 (Rand
)) {
127 Generates a 64-bit random number.
129 if Rand is NULL, then ASSERT().
131 @param[out] Rand Buffer pointer to store the 64-bit random value.
133 @retval TRUE Random number generated successfully.
134 @retval FALSE Failed to generate the random number.
145 ASSERT (Rand
!= NULL
);
148 // A loop to fetch a 64 bit random value with a retry count limit.
150 for (Index
= 0; Index
< RDRAND_RETRY_LIMIT
; Index
++) {
151 if (AsmRdRand64 (Rand
)) {
160 Generates a 128-bit random number.
162 if Rand is NULL, then ASSERT().
164 @param[out] Rand Buffer pointer to store the 128-bit random value.
166 @retval TRUE Random number generated successfully.
167 @retval FALSE Failed to generate the random number.
176 ASSERT (Rand
!= NULL
);
179 // Read first 64 bits
181 if (!GetRandomNumber64 (Rand
)) {
186 // Read second 64 bits
188 return GetRandomNumber64 (++Rand
);