]>
Commit | Line | Data |
---|---|---|
ed0dce7d MC |
1 | /** @file\r |
2 | Provides an implementation of the library class RngLib that uses the Rng protocol.\r | |
3 | \r | |
4 | Copyright (c) Microsoft Corporation. All rights reserved.\r | |
5 | SPDX-License-Identifier: BSD-2-Clause-Patent\r | |
6 | \r | |
7 | **/\r | |
8 | #include <Uefi.h>\r | |
9 | #include <Library/UefiBootServicesTableLib.h>\r | |
10 | #include <Library/DebugLib.h>\r | |
11 | #include <Library/RngLib.h>\r | |
12 | #include <Protocol/Rng.h>\r | |
13 | \r | |
14 | /**\r | |
15 | Routine Description:\r | |
16 | \r | |
17 | Generates a random number via the NIST\r | |
18 | 800-9A algorithm. Refer to\r | |
19 | http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf\r | |
20 | for more information.\r | |
21 | \r | |
22 | @param[out] Buffer Buffer to receive the random number.\r | |
23 | @param[in] BufferSize Number of bytes in Buffer.\r | |
24 | \r | |
25 | @retval EFI_SUCCESS or underlying failure code.\r | |
26 | **/\r | |
27 | STATIC\r | |
28 | EFI_STATUS\r | |
29 | GenerateRandomNumberViaNist800Algorithm (\r | |
30 | OUT UINT8 *Buffer,\r | |
31 | IN UINTN BufferSize\r | |
32 | )\r | |
33 | {\r | |
34 | EFI_STATUS Status;\r | |
35 | EFI_RNG_PROTOCOL *RngProtocol;\r | |
36 | \r | |
37 | RngProtocol = NULL;\r | |
38 | \r | |
39 | if (Buffer == NULL) {\r | |
2f88bd3a MK |
40 | DEBUG ((DEBUG_ERROR, "%a: Buffer == NULL.\n", __FUNCTION__));\r |
41 | return EFI_INVALID_PARAMETER;\r | |
ed0dce7d MC |
42 | }\r |
43 | \r | |
44 | Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&RngProtocol);\r | |
2f88bd3a MK |
45 | if (EFI_ERROR (Status) || (RngProtocol == NULL)) {\r |
46 | DEBUG ((DEBUG_ERROR, "%a: Could not locate RNG prototocol, Status = %r\n", __FUNCTION__, Status));\r | |
47 | return Status;\r | |
ed0dce7d MC |
48 | }\r |
49 | \r | |
50 | Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Ctr256Guid, BufferSize, Buffer);\r | |
2f88bd3a | 51 | DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm CTR-256 - Status = %r\n", __FUNCTION__, Status));\r |
ed0dce7d MC |
52 | if (!EFI_ERROR (Status)) {\r |
53 | return Status;\r | |
54 | }\r | |
55 | \r | |
56 | Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hmac256Guid, BufferSize, Buffer);\r | |
2f88bd3a | 57 | DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm HMAC-256 - Status = %r\n", __FUNCTION__, Status));\r |
ed0dce7d MC |
58 | if (!EFI_ERROR (Status)) {\r |
59 | return Status;\r | |
60 | }\r | |
61 | \r | |
62 | Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hash256Guid, BufferSize, Buffer);\r | |
2f88bd3a | 63 | DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm Hash-256 - Status = %r\n", __FUNCTION__, Status));\r |
ed0dce7d MC |
64 | if (!EFI_ERROR (Status)) {\r |
65 | return Status;\r | |
66 | }\r | |
2f88bd3a | 67 | \r |
ed0dce7d MC |
68 | // If all the other methods have failed, use the default method from the RngProtocol\r |
69 | Status = RngProtocol->GetRNG (RngProtocol, NULL, BufferSize, Buffer);\r | |
2f88bd3a | 70 | DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm Hash-256 - Status = %r\n", __FUNCTION__, Status));\r |
ed0dce7d MC |
71 | if (!EFI_ERROR (Status)) {\r |
72 | return Status;\r | |
73 | }\r | |
2f88bd3a | 74 | \r |
ed0dce7d | 75 | // If we get to this point, we have failed\r |
2f88bd3a | 76 | DEBUG ((DEBUG_ERROR, "%a: GetRNG() failed, staus = %r\n", __FUNCTION__, Status));\r |
ed0dce7d MC |
77 | \r |
78 | return Status;\r | |
79 | }// GenerateRandomNumberViaNist800Algorithm()\r | |
80 | \r | |
ed0dce7d MC |
81 | /**\r |
82 | Generates a 16-bit random number.\r | |
83 | \r | |
84 | if Rand is NULL, return FALSE.\r | |
85 | \r | |
86 | @param[out] Rand Buffer pointer to store the 16-bit random value.\r | |
87 | \r | |
88 | @retval TRUE Random number generated successfully.\r | |
89 | @retval FALSE Failed to generate the random number.\r | |
90 | \r | |
91 | **/\r | |
92 | BOOLEAN\r | |
93 | EFIAPI\r | |
94 | GetRandomNumber16 (\r | |
95 | OUT UINT16 *Rand\r | |
96 | )\r | |
97 | {\r | |
2f88bd3a | 98 | EFI_STATUS Status;\r |
ed0dce7d | 99 | \r |
2f88bd3a | 100 | if (Rand == NULL) {\r |
ed0dce7d MC |
101 | return FALSE;\r |
102 | }\r | |
103 | \r | |
2f88bd3a | 104 | Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, sizeof (UINT16));\r |
ed0dce7d MC |
105 | if (EFI_ERROR (Status)) {\r |
106 | return FALSE;\r | |
107 | }\r | |
2f88bd3a | 108 | \r |
ed0dce7d MC |
109 | return TRUE;\r |
110 | }\r | |
111 | \r | |
112 | /**\r | |
113 | Generates a 32-bit random number.\r | |
114 | \r | |
115 | if Rand is NULL, return FALSE.\r | |
116 | \r | |
117 | @param[out] Rand Buffer pointer to store the 32-bit random value.\r | |
118 | \r | |
119 | @retval TRUE Random number generated successfully.\r | |
120 | @retval FALSE Failed to generate the random number.\r | |
121 | \r | |
122 | **/\r | |
123 | BOOLEAN\r | |
124 | EFIAPI\r | |
125 | GetRandomNumber32 (\r | |
2f88bd3a | 126 | OUT UINT32 *Rand\r |
ed0dce7d MC |
127 | )\r |
128 | {\r | |
2f88bd3a | 129 | EFI_STATUS Status;\r |
ed0dce7d MC |
130 | \r |
131 | if (Rand == NULL) {\r | |
132 | return FALSE;\r | |
133 | }\r | |
134 | \r | |
2f88bd3a | 135 | Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, sizeof (UINT32));\r |
ed0dce7d MC |
136 | if (EFI_ERROR (Status)) {\r |
137 | return FALSE;\r | |
138 | }\r | |
2f88bd3a | 139 | \r |
ed0dce7d MC |
140 | return TRUE;\r |
141 | }\r | |
142 | \r | |
143 | /**\r | |
144 | Generates a 64-bit random number.\r | |
145 | \r | |
146 | if Rand is NULL, return FALSE.\r | |
147 | \r | |
148 | @param[out] Rand Buffer pointer to store the 64-bit random value.\r | |
149 | \r | |
150 | @retval TRUE Random number generated successfully.\r | |
151 | @retval FALSE Failed to generate the random number.\r | |
152 | \r | |
153 | **/\r | |
154 | BOOLEAN\r | |
155 | EFIAPI\r | |
156 | GetRandomNumber64 (\r | |
2f88bd3a | 157 | OUT UINT64 *Rand\r |
ed0dce7d MC |
158 | )\r |
159 | {\r | |
2f88bd3a | 160 | EFI_STATUS Status;\r |
ed0dce7d MC |
161 | \r |
162 | if (Rand == NULL) {\r | |
163 | return FALSE;\r | |
164 | }\r | |
165 | \r | |
2f88bd3a | 166 | Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, sizeof (UINT64));\r |
ed0dce7d MC |
167 | if (EFI_ERROR (Status)) {\r |
168 | return FALSE;\r | |
169 | }\r | |
2f88bd3a | 170 | \r |
ed0dce7d MC |
171 | return TRUE;\r |
172 | }\r | |
173 | \r | |
174 | /**\r | |
175 | Generates a 128-bit random number.\r | |
176 | \r | |
177 | if Rand is NULL, return FALSE.\r | |
178 | \r | |
179 | @param[out] Rand Buffer pointer to store the 128-bit random value.\r | |
180 | \r | |
181 | @retval TRUE Random number generated successfully.\r | |
182 | @retval FALSE Failed to generate the random number.\r | |
183 | \r | |
184 | **/\r | |
185 | BOOLEAN\r | |
186 | EFIAPI\r | |
187 | GetRandomNumber128 (\r | |
2f88bd3a | 188 | OUT UINT64 *Rand\r |
ed0dce7d MC |
189 | )\r |
190 | {\r | |
2f88bd3a | 191 | EFI_STATUS Status;\r |
ed0dce7d MC |
192 | \r |
193 | if (Rand == NULL) {\r | |
194 | return FALSE;\r | |
195 | }\r | |
196 | \r | |
2f88bd3a | 197 | Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 2 * sizeof (UINT64));\r |
ed0dce7d MC |
198 | if (EFI_ERROR (Status)) {\r |
199 | return FALSE;\r | |
200 | }\r | |
2f88bd3a | 201 | \r |
ed0dce7d MC |
202 | return TRUE;\r |
203 | }\r |