VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdePkg/Library/BaseRngLib/AArch64/Rndr.c

Last change on this file was 108794, checked in by vboxsync, 4 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 4.3 KB
Line 
1/** @file
2 Random number generator service that uses the RNDR instruction
3 to provide pseudorandom numbers.
4
5 Copyright (c) 2023, Arm Limited. All rights reserved.<BR>
6 Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
7 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
8
9 SPDX-License-Identifier: BSD-2-Clause-Patent
10
11**/
12
13#include <Uefi.h>
14#include <Library/BaseLib.h>
15#include <Library/BaseMemoryLib.h>
16#include <Library/DebugLib.h>
17#include <Library/RngLib.h>
18
19#include "ArmRng.h"
20#include "BaseRngLibInternals.h"
21
22/*
23 * This is non XIP (eXecute In Place) safe.
24 * This is used very early on in the TPM code when tings are still directly running from the ROM region which is RX only,
25 * causing a write access fault, so avoid caching the flag and query it always.
26 */
27#ifndef VBOX
28STATIC BOOLEAN mRndrSupported;
29#else
30inline BOOLEAN VBoxIsRndrSupported()
31{
32 UINT64 Isar0;
33
34 Isar0 = ArmReadIdAA64Isar0Reg ();
35 return !!((Isar0 >> ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT) & ARM_ID_AA64ISAR0_EL1_RNDR_MASK);
36}
37#endif
38
39/**
40 The constructor function checks whether or not RNDR instruction is supported
41 by the host hardware.
42
43 The constructor function checks whether or not RNDR instruction is supported.
44 It will ASSERT() if RNDR instruction is not supported.
45 It will always return EFI_SUCCESS.
46
47 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
48
49**/
50EFI_STATUS
51EFIAPI
52BaseRngLibConstructor (
53 VOID
54 )
55{
56#ifndef VBOX
57 UINT64 Isar0;
58
59 //
60 // Determine RNDR support by examining bits 63:60 of the ISAR0 register returned by
61 // MSR. A non-zero value indicates that the processor supports the RNDR instruction.
62 //
63 Isar0 = ArmReadIdAA64Isar0Reg ();
64 mRndrSupported = !!((Isar0 >> ARM_ID_AA64ISAR0_EL1_RNDR_SHIFT) & ARM_ID_AA64ISAR0_EL1_RNDR_MASK);
65#endif
66
67 return EFI_SUCCESS;
68}
69
70/**
71 Generates a 16-bit random number.
72
73 @param[out] Rand Buffer pointer to store the 16-bit random value.
74
75 @retval TRUE Random number generated successfully.
76 @retval FALSE Failed to generate the random number.
77
78**/
79BOOLEAN
80EFIAPI
81ArchGetRandomNumber16 (
82 OUT UINT16 *Rand
83 )
84{
85 UINT64 Rand64;
86
87 if (ArchGetRandomNumber64 (&Rand64)) {
88 *Rand = Rand64 & MAX_UINT16;
89 return TRUE;
90 }
91
92 return FALSE;
93}
94
95/**
96 Generates a 32-bit random number.
97
98 @param[out] Rand Buffer pointer to store the 32-bit random value.
99
100 @retval TRUE Random number generated successfully.
101 @retval FALSE Failed to generate the random number.
102
103**/
104BOOLEAN
105EFIAPI
106ArchGetRandomNumber32 (
107 OUT UINT32 *Rand
108 )
109{
110 UINT64 Rand64;
111
112 if (ArchGetRandomNumber64 (&Rand64)) {
113 *Rand = Rand64 & MAX_UINT32;
114 return TRUE;
115 }
116
117 return FALSE;
118}
119
120/**
121 Generates a 64-bit random number.
122
123 @param[out] Rand Buffer pointer to store the 64-bit random value.
124
125 @retval TRUE Random number generated successfully.
126 @retval FALSE Failed to generate the random number.
127
128**/
129BOOLEAN
130EFIAPI
131ArchGetRandomNumber64 (
132 OUT UINT64 *Rand
133 )
134{
135 return ArmRndr (Rand);
136}
137
138/**
139 Checks whether RNDR is supported.
140
141 @retval TRUE RNDR is supported.
142 @retval FALSE RNDR is not supported.
143
144**/
145BOOLEAN
146EFIAPI
147ArchIsRngSupported (
148 VOID
149 )
150{
151#ifndef VBOX
152 return mRndrSupported;
153#else
154 return VBoxIsRndrSupported();
155#endif
156}
157
158/**
159 Get a GUID identifying the RNG algorithm implementation.
160
161 @param [out] RngGuid If success, contains the GUID identifying
162 the RNG algorithm implementation.
163
164 @retval EFI_SUCCESS Success.
165 @retval EFI_UNSUPPORTED Not supported.
166 @retval EFI_INVALID_PARAMETER Invalid parameter.
167**/
168EFI_STATUS
169EFIAPI
170GetRngGuid (
171 GUID *RngGuid
172 )
173{
174 GUID *RngLibGuid;
175
176 if (RngGuid == NULL) {
177 return EFI_INVALID_PARAMETER;
178 }
179
180#ifndef VBOX
181 if (!mRndrSupported) {
182 return EFI_UNSUPPORTED;
183 }
184#else
185 if (!VBoxIsRndrSupported()) {
186 return EFI_UNSUPPORTED;
187 }
188#endif
189
190 //
191 // If the platform advertises the algorithm behind RNDR instruction,
192 // use it. Otherwise use gEfiRngAlgorithmArmRndr.
193 //
194 RngLibGuid = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
195 if (!IsZeroGuid (RngLibGuid)) {
196 CopyMem (RngGuid, RngLibGuid, sizeof (*RngGuid));
197 } else {
198 CopyMem (RngGuid, &gEfiRngAlgorithmArmRndr, sizeof (*RngGuid));
199 }
200
201 return EFI_SUCCESS;
202}
Note: See TracBrowser for help on using the repository browser.

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