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