]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseRngLib/BaseRng.c
cbf405db8129585867610d9009a09815d17c5500
[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 Generates a 16-bit random number.
26
27 if Rand is NULL, then ASSERT().
28
29 @param[out] Rand Buffer pointer to store the 16-bit random value.
30
31 @retval TRUE Random number generated successfully.
32 @retval FALSE Failed to generate the random number.
33
34 **/
35 BOOLEAN
36 EFIAPI
37 GetRandomNumber16 (
38 OUT UINT16 *Rand
39 )
40 {
41 UINT32 Index;
42
43 ASSERT (Rand != NULL);
44
45 if (Rand == NULL) {
46 return FALSE;
47 }
48
49 if (!ArchIsRngSupported ()) {
50 return FALSE;
51 }
52
53 //
54 // A loop to fetch a 16 bit random value with a retry count limit.
55 //
56 for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
57 if (ArchGetRandomNumber16 (Rand)) {
58 return TRUE;
59 }
60 }
61
62 return FALSE;
63 }
64
65 /**
66 Generates a 32-bit random number.
67
68 if Rand is NULL, then ASSERT().
69
70 @param[out] Rand Buffer pointer to store the 32-bit random value.
71
72 @retval TRUE Random number generated successfully.
73 @retval FALSE Failed to generate the random number.
74
75 **/
76 BOOLEAN
77 EFIAPI
78 GetRandomNumber32 (
79 OUT UINT32 *Rand
80 )
81 {
82 UINT32 Index;
83
84 ASSERT (Rand != NULL);
85
86 if (Rand == NULL) {
87 return FALSE;
88 }
89
90 if (!ArchIsRngSupported ()) {
91 return FALSE;
92 }
93
94 //
95 // A loop to fetch a 32 bit random value with a retry count limit.
96 //
97 for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
98 if (ArchGetRandomNumber32 (Rand)) {
99 return TRUE;
100 }
101 }
102
103 return FALSE;
104 }
105
106 /**
107 Generates a 64-bit random number.
108
109 if Rand is NULL, then ASSERT().
110
111 @param[out] Rand Buffer pointer to store the 64-bit random value.
112
113 @retval TRUE Random number generated successfully.
114 @retval FALSE Failed to generate the random number.
115
116 **/
117 BOOLEAN
118 EFIAPI
119 GetRandomNumber64 (
120 OUT UINT64 *Rand
121 )
122 {
123 UINT32 Index;
124
125 ASSERT (Rand != NULL);
126
127 if (Rand == NULL) {
128 return FALSE;
129 }
130
131 if (!ArchIsRngSupported ()) {
132 return FALSE;
133 }
134
135 //
136 // A loop to fetch a 64 bit random value with a retry count limit.
137 //
138 for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) {
139 if (ArchGetRandomNumber64 (Rand)) {
140 return TRUE;
141 }
142 }
143
144 return FALSE;
145 }
146
147 /**
148 Generates a 128-bit random number.
149
150 if Rand is NULL, then ASSERT().
151
152 @param[out] Rand Buffer pointer to store the 128-bit random value.
153
154 @retval TRUE Random number generated successfully.
155 @retval FALSE Failed to generate the random number.
156
157 **/
158 BOOLEAN
159 EFIAPI
160 GetRandomNumber128 (
161 OUT UINT64 *Rand
162 )
163 {
164 ASSERT (Rand != NULL);
165
166 if (Rand == NULL) {
167 return FALSE;
168 }
169
170 if (!ArchIsRngSupported ()) {
171 return FALSE;
172 }
173
174 //
175 // Read first 64 bits
176 //
177 if (!GetRandomNumber64 (Rand)) {
178 return FALSE;
179 }
180
181 //
182 // Read second 64 bits
183 //
184 return GetRandomNumber64 (++Rand);
185 }