VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/MdePkg/Library/BaseRngLibTimerLib/RngLibTimer.c@ 107675

最後變更 在這個檔案從107675是 105670,由 vboxsync 提交於 7 月 前

Devices/EFI/FirmwareNew: Merge edk2-stable-202405 and make it build on aarch64, bugref:4643

  • 屬性 svn:eol-style 設為 native
檔案大小: 5.5 KB
 
1/** @file
2 BaseRng Library that uses the TimerLib to provide reasonably random numbers.
3 Do not use this on a production system.
4
5 Copyright (c) Microsoft Corporation.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7**/
8
9#include <Base.h>
10#include <Library/BaseLib.h>
11#include <Library/DebugLib.h>
12#include <Library/TimerLib.h>
13
14#define DEFAULT_DELAY_TIME_IN_MICROSECONDS 10
15
16/**
17 This implementation is to be replaced by its MdeModulePkg copy.
18 The cause being that some GUIDs (gEdkiiRngAlgorithmUnSafe) cannot
19 be defined in the MdePkg.
20
21 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
22**/
23RETURN_STATUS
24EFIAPI
25BaseRngLibTimerConstructor (
26 VOID
27 )
28{
29 DEBUG ((
30 DEBUG_WARN,
31 "Warning: This BaseRngTimerLib implementation will be deprecated. "
32 "Please use the MdeModulePkg implementation equivalent.\n"
33 ));
34
35 return RETURN_SUCCESS;
36}
37
38/**
39 Using the TimerLib GetPerformanceCounterProperties() we delay
40 for enough time for the PerformanceCounter to increment.
41
42 If the return value from GetPerformanceCounterProperties (TimerLib)
43 is zero, this function will return 10 and attempt to assert.
44 **/
45STATIC
46UINT32
47CalculateMinimumDecentDelayInMicroseconds (
48 VOID
49 )
50{
51 UINT64 CounterHz;
52
53 // Get the counter properties
54 CounterHz = GetPerformanceCounterProperties (NULL, NULL);
55 // Make sure we won't divide by zero
56 if (CounterHz == 0) {
57 ASSERT (CounterHz != 0); // Assert so the developer knows something is wrong
58 return DEFAULT_DELAY_TIME_IN_MICROSECONDS;
59 }
60
61 // Calculate the minimum delay based on 1.5 microseconds divided by the hertz.
62 // We calculate the length of a cycle (1/CounterHz) and multiply it by 1.5 microseconds
63 // This ensures that the performance counter has increased by at least one
64 return (UINT32)(MAX (DivU64x64Remainder (1500000, CounterHz, NULL), 1));
65}
66
67/**
68 Generates a 16-bit random number.
69
70 if Rand is NULL, then ASSERT().
71
72 @param[out] Rand Buffer pointer to store the 16-bit random value.
73
74 @retval TRUE Random number generated successfully.
75 @retval FALSE Failed to generate the random number.
76
77**/
78BOOLEAN
79EFIAPI
80GetRandomNumber16 (
81 OUT UINT16 *Rand
82 )
83{
84 UINT32 Index;
85 UINT8 *RandPtr;
86 UINT32 DelayInMicroSeconds;
87
88 ASSERT (Rand != NULL);
89
90 if (Rand == NULL) {
91 return FALSE;
92 }
93
94 DelayInMicroSeconds = CalculateMinimumDecentDelayInMicroseconds ();
95 RandPtr = (UINT8 *)Rand;
96 // Get 2 bytes of random ish data
97 for (Index = 0; Index < sizeof (UINT16); Index++) {
98 *RandPtr = (UINT8)(GetPerformanceCounter () & 0xFF);
99 // Delay to give the performance counter a chance to change
100 MicroSecondDelay (DelayInMicroSeconds);
101 RandPtr++;
102 }
103
104 return TRUE;
105}
106
107/**
108 Generates a 32-bit random number.
109
110 if Rand is NULL, then ASSERT().
111
112 @param[out] Rand Buffer pointer to store the 32-bit random value.
113
114 @retval TRUE Random number generated successfully.
115 @retval FALSE Failed to generate the random number.
116
117**/
118BOOLEAN
119EFIAPI
120GetRandomNumber32 (
121 OUT UINT32 *Rand
122 )
123{
124 UINT32 Index;
125 UINT8 *RandPtr;
126 UINT32 DelayInMicroSeconds;
127
128 ASSERT (Rand != NULL);
129
130 if (NULL == Rand) {
131 return FALSE;
132 }
133
134 RandPtr = (UINT8 *)Rand;
135 DelayInMicroSeconds = CalculateMinimumDecentDelayInMicroseconds ();
136 // Get 4 bytes of random ish data
137 for (Index = 0; Index < sizeof (UINT32); Index++) {
138 *RandPtr = (UINT8)(GetPerformanceCounter () & 0xFF);
139 // Delay to give the performance counter a chance to change
140 MicroSecondDelay (DelayInMicroSeconds);
141 RandPtr++;
142 }
143
144 return TRUE;
145}
146
147/**
148 Generates a 64-bit random number.
149
150 if Rand is NULL, then ASSERT().
151
152 @param[out] Rand Buffer pointer to store the 64-bit random value.
153
154 @retval TRUE Random number generated successfully.
155 @retval FALSE Failed to generate the random number.
156
157**/
158BOOLEAN
159EFIAPI
160GetRandomNumber64 (
161 OUT UINT64 *Rand
162 )
163{
164 UINT32 Index;
165 UINT8 *RandPtr;
166 UINT32 DelayInMicroSeconds;
167
168 ASSERT (Rand != NULL);
169
170 if (NULL == Rand) {
171 return FALSE;
172 }
173
174 RandPtr = (UINT8 *)Rand;
175 DelayInMicroSeconds = CalculateMinimumDecentDelayInMicroseconds ();
176 // Get 8 bytes of random ish data
177 for (Index = 0; Index < sizeof (UINT64); Index++) {
178 *RandPtr = (UINT8)(GetPerformanceCounter () & 0xFF);
179 // Delay to give the performance counter a chance to change
180 MicroSecondDelay (DelayInMicroSeconds);
181 RandPtr++;
182 }
183
184 return TRUE;
185}
186
187/**
188 Generates a 128-bit random number.
189
190 if Rand is NULL, then ASSERT().
191
192 @param[out] Rand Buffer pointer to store the 128-bit random value.
193
194 @retval TRUE Random number generated successfully.
195 @retval FALSE Failed to generate the random number.
196
197**/
198BOOLEAN
199EFIAPI
200GetRandomNumber128 (
201 OUT UINT64 *Rand
202 )
203{
204 ASSERT (Rand != NULL);
205 // This should take around 80ms
206
207 // Read first 64 bits
208 if (!GetRandomNumber64 (Rand)) {
209 return FALSE;
210 }
211
212 // Read second 64 bits
213 return GetRandomNumber64 (++Rand);
214}
215
216/**
217 Get a GUID identifying the RNG algorithm implementation.
218
219 @param [out] RngGuid If success, contains the GUID identifying
220 the RNG algorithm implementation.
221
222 @retval EFI_SUCCESS Success.
223 @retval EFI_UNSUPPORTED Not supported.
224 @retval EFI_INVALID_PARAMETER Invalid parameter.
225**/
226RETURN_STATUS
227EFIAPI
228GetRngGuid (
229 GUID *RngGuid
230 )
231{
232 /* This implementation is to be replaced by its MdeModulePkg copy.
233 * The cause being that some GUIDs (gEdkiiRngAlgorithmUnSafe) cannot
234 * be defined in the MdePkg.
235 */
236 return RETURN_UNSUPPORTED;
237}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette