]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseRngLib/BaseRng.c
5b63d8f7146b2ba8d42b692688b6d567fc256d00
[mirror_edk2.git] / MdePkg / Library / BaseRngLib / BaseRng.c
1 /** @file
2 Random number generator services that uses CPU RNG instructions to
3 provide random numbers.
4
5 Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
6 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
7
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10 **/
11
12 #include <Library/BaseLib.h>
13 #include <Library/DebugLib.h>
14
15 #include "BaseRngLibInternals.h"
16
17 //
18 // Limited retry number when valid random data is returned.
19 // Uses the recommended value defined in Section 7.3.17 of "Intel 64 and IA-32
20 // Architectures Software Developer's Manual".
21 //
22 #define GETRANDOM_RETRY_LIMIT 10
23
24
25 /**
26 Generates a 16-bit random number.
27
28 if Rand is NULL, then ASSERT().
29
30 @param[out] Rand Buffer pointer to store the 16-bit random value.
31
32 @retval TRUE Random number generated successfully.
33 @retval FALSE Failed to generate the random number.
34
35 **/
36 BOOLEAN
37 EFIAPI
38 GetRandomNumber16 (
39 OUT UINT16 *Rand
40 )
41 {
42 UINT32 Index;
43
44 ASSERT (Rand != NULL);
45
46 if (Rand == NULL) {
47 return FALSE;
48 }
49
50 if (!ArchIsRngSupported ()) {
51 return FALSE;
52 }
53
54 //
55 // A loop to fetch a 16 bit random value with a retry count limit.
56 //
57 for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
58 if (ArchGetRandomNumber16 (Rand)) {
59 return TRUE;
60 }
61 }
62
63 return FALSE;
64 }
65
66 /**
67 Generates a 32-bit random number.
68
69 if Rand is NULL, then ASSERT().
70
71 @param[out] Rand Buffer pointer to store the 32-bit random value.
72
73 @retval TRUE Random number generated successfully.
74 @retval FALSE Failed to generate the random number.
75
76 **/
77 BOOLEAN
78 EFIAPI
79 GetRandomNumber32 (
80 OUT UINT32 *Rand
81 )
82 {
83 UINT32 Index;
84
85 ASSERT (Rand != NULL);
86
87 if (Rand == NULL) {
88 return FALSE;
89 }
90
91 if (!ArchIsRngSupported ()) {
92 return FALSE;
93 }
94
95 //
96 // A loop to fetch a 32 bit random value with a retry count limit.
97 //
98 for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
99 if (ArchGetRandomNumber32 (Rand)) {
100 return TRUE;
101 }
102 }
103
104 return FALSE;
105 }
106
107 /**
108 Generates a 64-bit random number.
109
110 if Rand is NULL, then ASSERT().
111
112 @param[out] Rand Buffer pointer to store the 64-bit random value.
113
114 @retval TRUE Random number generated successfully.
115 @retval FALSE Failed to generate the random number.
116
117 **/
118 BOOLEAN
119 EFIAPI
120 GetRandomNumber64 (
121 OUT UINT64 *Rand
122 )
123 {
124 UINT32 Index;
125
126 ASSERT (Rand != NULL);
127
128 if (Rand == NULL) {
129 return FALSE;
130 }
131
132 if (!ArchIsRngSupported ()) {
133 return FALSE;
134 }
135
136 //
137 // A loop to fetch a 64 bit random value with a retry count limit.
138 //
139 for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
140 if (ArchGetRandomNumber64 (Rand)) {
141 return TRUE;
142 }
143 }
144
145 return FALSE;
146 }
147
148 /**
149 Generates a 128-bit random number.
150
151 if Rand is NULL, then ASSERT().
152
153 @param[out] Rand Buffer pointer to store the 128-bit random value.
154
155 @retval TRUE Random number generated successfully.
156 @retval FALSE Failed to generate the random number.
157
158 **/
159 BOOLEAN
160 EFIAPI
161 GetRandomNumber128 (
162 OUT UINT64 *Rand
163 )
164 {
165 ASSERT (Rand != NULL);
166
167 if (Rand == NULL) {
168 return FALSE;
169 }
170
171 if (!ArchIsRngSupported ()) {
172 return FALSE;
173 }
174
175 //
176 // Read first 64 bits
177 //
178 if (!GetRandomNumber64 (Rand)) {
179 return FALSE;
180 }
181
182 //
183 // Read second 64 bits
184 //
185 return GetRandomNumber64 (++Rand);
186 }