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