TianoCore EDK2 master
Loading...
Searching...
No Matches
ArmTrngLib.c
Go to the documentation of this file.
1
21#include <Base.h>
22#include <Library/ArmLib.h>
25#include <Library/DebugLib.h>
26
27#include "ArmTrngDefs.h"
28
40RETURN_STATUS
42 IN INT32 TrngStatus
43 )
44{
45 switch (TrngStatus) {
46 case TRNG_STATUS_NOT_SUPPORTED:
47 return RETURN_UNSUPPORTED;
48
49 case TRNG_STATUS_INVALID_PARAMETER:
51
52 case TRNG_STATUS_NO_ENTROPY:
53 return RETURN_NOT_READY;
54
55 case TRNG_STATUS_SUCCESS:
56 return RETURN_SUCCESS;
57
58 default:
59 if (TrngStatus < 0) {
60 return RETURN_UNSUPPORTED;
61 }
62
63 return RETURN_SUCCESS;
64 }
65}
66
80RETURN_STATUS
81EFIAPI
83 OUT UINT16 *MajorRevision,
84 OUT UINT16 *MinorRevision
85 )
86{
87 RETURN_STATUS Status;
88 ARM_MONITOR_ARGS Parameters;
89 INT32 Revision;
90
91 if ((MajorRevision == NULL) || (MinorRevision == NULL)) {
93 }
94
95 ZeroMem (&Parameters, sizeof (Parameters));
96
97 Parameters.Arg0 = ARM_SMC_ID_TRNG_VERSION;
98 ArmMonitorCall (&Parameters);
99
100 Revision = (INT32)Parameters.Arg0;
101 Status = TrngStatusToReturnStatus (Revision);
102 if (RETURN_ERROR (Status)) {
103 return Status;
104 }
105
106 *MinorRevision = (Revision & TRNG_REV_MINOR_MASK);
107 *MajorRevision = ((Revision >> TRNG_REV_MAJOR_SHIFT) & TRNG_REV_MAJOR_MASK);
108 return RETURN_SUCCESS;
109}
110
123STATIC
124RETURN_STATUS
125EFIAPI
127 IN CONST UINT32 FunctionId,
128 OUT UINT32 *Capability OPTIONAL
129 )
130{
131 ARM_MONITOR_ARGS Parameters;
132 RETURN_STATUS Status;
133
134 ZeroMem (&Parameters, sizeof (Parameters));
135
136 Parameters.Arg0 = ARM_SMC_ID_TRNG_FEATURES;
137 Parameters.Arg1 = FunctionId;
138 ArmMonitorCall (&Parameters);
139
140 Status = TrngStatusToReturnStatus (Parameters.Arg0);
141 if (RETURN_ERROR (Status)) {
142 return Status;
143 }
144
145 if (Capability != NULL) {
146 *Capability = (UINT32)Parameters.Arg0;
147 }
148
149 return RETURN_SUCCESS;
150}
151
168RETURN_STATUS
169EFIAPI
171 OUT GUID *Guid
172 )
173{
174 ARM_MONITOR_ARGS Parameters;
175
176 if (Guid == NULL) {
178 }
179
180 ZeroMem (&Parameters, sizeof (Parameters));
181
182 Parameters.Arg0 = ARM_SMC_ID_TRNG_GET_UUID;
183 ArmMonitorCall (&Parameters);
184
185 // Only invalid value is TRNG_STATUS_NOT_SUPPORTED (-1).
186 if ((INT32)Parameters.Arg0 == TRNG_STATUS_NOT_SUPPORTED) {
187 return TrngStatusToReturnStatus ((INT32)Parameters.Arg0);
188 }
189
190 Guid->Data1 = (Parameters.Arg0 & MAX_UINT32);
191 Guid->Data2 = (Parameters.Arg1 & MAX_UINT16);
192 Guid->Data3 = ((Parameters.Arg1 >> 16) & MAX_UINT16);
193
194 Guid->Data4[0] = (Parameters.Arg2 & MAX_UINT8);
195 Guid->Data4[1] = ((Parameters.Arg2 >> 8) & MAX_UINT8);
196 Guid->Data4[2] = ((Parameters.Arg2 >> 16) & MAX_UINT8);
197 Guid->Data4[3] = ((Parameters.Arg2 >> 24) & MAX_UINT8);
198
199 Guid->Data4[4] = (Parameters.Arg3 & MAX_UINT8);
200 Guid->Data4[5] = ((Parameters.Arg3 >> 8) & MAX_UINT8);
201 Guid->Data4[6] = ((Parameters.Arg3 >> 16) & MAX_UINT8);
202 Guid->Data4[7] = ((Parameters.Arg3 >> 24) & MAX_UINT8);
203
204 DEBUG ((DEBUG_INFO, "FW-TRNG: UUID %g\n", Guid));
205
206 return RETURN_SUCCESS;
207}
208
215UINTN
216EFIAPI
218 VOID
219 )
220{
221 return MAX_ENTROPY_BITS;
222}
223
245RETURN_STATUS
246EFIAPI
248 IN UINTN EntropyBits,
249 IN UINTN BufferSize,
250 OUT UINT8 *Buffer
251 )
252{
253 RETURN_STATUS Status;
254 ARM_MONITOR_ARGS Parameters;
255 UINTN EntropyBytes;
256 UINTN LastValidBits;
257 UINTN BytesToClear;
258 UINTN EntropyData[3];
259
260 if ((EntropyBits == 0) ||
261 (EntropyBits > MAX_ENTROPY_BITS) ||
262 (Buffer == NULL))
263 {
265 }
266
267 EntropyBytes = (EntropyBits + 7) >> 3;
268 if (EntropyBytes > BufferSize) {
270 }
271
272 ZeroMem (Buffer, BufferSize);
273 ZeroMem (&Parameters, sizeof (Parameters));
274
275 Parameters.Arg0 = ARM_SMC_ID_TRNG_RND;
276 Parameters.Arg1 = EntropyBits;
277 ArmMonitorCall (&Parameters);
278
279 Status = TrngStatusToReturnStatus ((INT32)Parameters.Arg0);
280 if (RETURN_ERROR (Status)) {
281 return Status;
282 }
283
284 // The entropy data is returned in the Parameters.Arg<3..1>
285 // With the lower order bytes in Parameters.Arg3 and the higher
286 // order bytes being stored in Parameters.Arg1.
287 EntropyData[0] = Parameters.Arg3;
288 EntropyData[1] = Parameters.Arg2;
289 EntropyData[2] = Parameters.Arg1;
290
291 CopyMem (Buffer, EntropyData, EntropyBytes);
292
293 // Mask off any unused top bytes, in accordance with specification.
294 BytesToClear = BufferSize - EntropyBytes;
295 if (BytesToClear != 0) {
296 ZeroMem (&Buffer[EntropyBytes], BytesToClear);
297 }
298
299 // Clear the unused MSB bits of the last byte.
300 LastValidBits = EntropyBits & 0x7;
301 if (LastValidBits != 0) {
302 Buffer[EntropyBytes - 1] &= (0xFF >> (8 - LastValidBits));
303 }
304
305 return Status;
306}
307
316RETURN_STATUS
317EFIAPI
319 VOID
320 )
321{
322 ARM_MONITOR_ARGS Parameters;
323 RETURN_STATUS Status;
324 UINT16 MajorRev;
325 UINT16 MinorRev;
326 GUID Guid;
327
328 ZeroMem (&Parameters, sizeof (Parameters));
329
330 Parameters.Arg0 = SMCCC_VERSION;
331 ArmMonitorCall (&Parameters);
332 Status = TrngStatusToReturnStatus ((INT32)Parameters.Arg0);
333 if (RETURN_ERROR (Status)) {
334 goto ErrorHandler;
335 }
336
337 // Cf [1] s2.1.3 'Caller responsibilities',
338 // SMCCC version must be greater or equal than 1.1
339 if ((INT32)Parameters.Arg0 < 0x10001) {
340 goto ErrorHandler;
341 }
342
343 Status = GetArmTrngVersion (&MajorRev, &MinorRev);
344 if (RETURN_ERROR (Status)) {
345 goto ErrorHandler;
346 }
347
348 // Check that the required features are present.
349 Status = GetArmTrngFeatures (ARM_SMC_ID_TRNG_RND, NULL);
350 if (RETURN_ERROR (Status)) {
351 goto ErrorHandler;
352 }
353
354 // Check if TRNG UUID is supported and if so trace the GUID.
355 Status = GetArmTrngFeatures (ARM_SMC_ID_TRNG_GET_UUID, NULL);
356 if (RETURN_ERROR (Status)) {
357 goto ErrorHandler;
358 }
359
361
362 Status = GetArmTrngUuid (&Guid);
363 if (RETURN_ERROR (Status)) {
364 goto ErrorHandler;
365 }
366
367 DEBUG ((
368 DEBUG_INFO,
369 "FW-TRNG: Version %d.%d, GUID {%g}\n",
370 MajorRev,
371 MinorRev,
372 &Guid
373 ));
374
376
377 return RETURN_SUCCESS;
378
379ErrorHandler:
380 DEBUG ((DEBUG_ERROR, "ArmTrngLib could not be correctly initialized.\n"));
381 return RETURN_SUCCESS;
382}
UINT64 UINTN
VOID EFIAPI ArmMonitorCall(IN OUT ARM_MONITOR_ARGS *Args)
STATIC RETURN_STATUS TrngStatusToReturnStatus(IN INT32 TrngStatus)
Definition: ArmTrngLib.c:41
RETURN_STATUS EFIAPI GetArmTrngVersion(OUT UINT16 *MajorRevision, OUT UINT16 *MinorRevision)
Definition: ArmTrngLib.c:82
RETURN_STATUS EFIAPI GetArmTrngUuid(OUT GUID *Guid)
Definition: ArmTrngLib.c:170
RETURN_STATUS EFIAPI ArmTrngLibConstructor(VOID)
Definition: ArmTrngLib.c:318
RETURN_STATUS EFIAPI GetArmTrngEntropy(IN UINTN EntropyBits, IN UINTN BufferSize, OUT UINT8 *Buffer)
Definition: ArmTrngLib.c:247
STATIC RETURN_STATUS EFIAPI GetArmTrngFeatures(IN CONST UINT32 FunctionId, OUT UINT32 *Capability OPTIONAL)
Definition: ArmTrngLib.c:126
UINTN EFIAPI GetArmTrngMaxSupportedEntropyBits(VOID)
Definition: ArmTrngLib.c:217
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define RETURN_NOT_READY
Definition: Base.h:1098
#define RETURN_UNSUPPORTED
Definition: Base.h:1081
#define RETURN_SUCCESS
Definition: Base.h:1066
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define RETURN_INVALID_PARAMETER
Definition: Base.h:1076
#define RETURN_BAD_BUFFER_SIZE
Definition: Base.h:1086
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:564
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE_END()
Definition: DebugLib.h:578
Definition: Base.h:213