]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
SecurityPkg: Apply uncrustify changes
[mirror_edk2.git] / SecurityPkg / RandomNumberGenerator / RngDxe / RngDxe.c
1 /** @file
2 RNG Driver to produce the UEFI Random Number Generator protocol.
3
4 The driver uses CPU RNG instructions to produce high-quality,
5 high-performance entropy and random number.
6
7 RNG Algorithms defined in UEFI 2.4:
8 - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID
9 - EFI_RNG_ALGORITHM_RAW
10 - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID
11 - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID
12 - EFI_RNG_ALGORITHM_X9_31_3DES_GUID
13 - EFI_RNG_ALGORITHM_X9_31_AES_GUID
14
15 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
16 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
17
18 SPDX-License-Identifier: BSD-2-Clause-Patent
19
20 **/
21
22 #include <Library/BaseLib.h>
23 #include <Library/BaseMemoryLib.h>
24 #include <Library/UefiBootServicesTableLib.h>
25 #include <Library/RngLib.h>
26 #include <Library/TimerLib.h>
27 #include <Protocol/Rng.h>
28
29 #include "RngDxeInternals.h"
30
31 /**
32 Returns information about the random number generation implementation.
33
34 @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.
35 @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
36 On output with a return code of EFI_SUCCESS, the size
37 in bytes of the data returned in RNGAlgorithmList. On output
38 with a return code of EFI_BUFFER_TOO_SMALL,
39 the size of RNGAlgorithmList required to obtain the list.
40 @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver
41 with one EFI_RNG_ALGORITHM element for each supported
42 RNG algorithm. The list must not change across multiple
43 calls to the same driver. The first algorithm in the list
44 is the default algorithm for the driver.
45
46 @retval EFI_SUCCESS The RNG algorithm list was returned successfully.
47 @retval EFI_UNSUPPORTED The services is not supported by this driver.
48 @retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a
49 hardware or firmware error.
50 @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.
51 @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.
52
53 **/
54 EFI_STATUS
55 EFIAPI
56 RngGetInfo (
57 IN EFI_RNG_PROTOCOL *This,
58 IN OUT UINTN *RNGAlgorithmListSize,
59 OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
60 )
61 {
62 EFI_STATUS Status;
63
64 if ((This == NULL) || (RNGAlgorithmListSize == NULL)) {
65 return EFI_INVALID_PARAMETER;
66 }
67
68 //
69 // Return algorithm list supported by driver.
70 //
71 if (RNGAlgorithmList != NULL) {
72 Status = ArchGetSupportedRngAlgorithms (RNGAlgorithmListSize, RNGAlgorithmList);
73 } else {
74 Status = EFI_INVALID_PARAMETER;
75 }
76
77 return Status;
78 }
79
80 //
81 // The Random Number Generator (RNG) protocol
82 //
83 EFI_RNG_PROTOCOL mRngRdRand = {
84 RngGetInfo,
85 RngGetRNG
86 };
87
88 /**
89 The user Entry Point for the Random Number Generator (RNG) driver.
90
91 @param[in] ImageHandle The firmware allocated handle for the EFI image.
92 @param[in] SystemTable A pointer to the EFI System Table.
93
94 @retval EFI_SUCCESS The entry point is executed successfully.
95 @retval EFI_NOT_SUPPORTED Platform does not support RNG.
96 @retval Other Some error occurs when executing this entry point.
97
98 **/
99 EFI_STATUS
100 EFIAPI
101 RngDriverEntry (
102 IN EFI_HANDLE ImageHandle,
103 IN EFI_SYSTEM_TABLE *SystemTable
104 )
105 {
106 EFI_STATUS Status;
107 EFI_HANDLE Handle;
108
109 //
110 // Install UEFI RNG (Random Number Generator) Protocol
111 //
112 Handle = NULL;
113 Status = gBS->InstallMultipleProtocolInterfaces (
114 &Handle,
115 &gEfiRngProtocolGuid,
116 &mRngRdRand,
117 NULL
118 );
119
120 return Status;
121 }
122
123 /**
124 Calls RDRAND to fill a buffer of arbitrary size with random bytes.
125
126 @param[in] Length Size of the buffer, in bytes, to fill with.
127 @param[out] RandBuffer Pointer to the buffer to store the random result.
128
129 @retval EFI_SUCCESS Random bytes generation succeeded.
130 @retval EFI_NOT_READY Failed to request random bytes.
131
132 **/
133 EFI_STATUS
134 EFIAPI
135 RngGetBytes (
136 IN UINTN Length,
137 OUT UINT8 *RandBuffer
138 )
139 {
140 BOOLEAN IsRandom;
141 UINT64 TempRand[2];
142
143 while (Length > 0) {
144 IsRandom = GetRandomNumber128 (TempRand);
145 if (!IsRandom) {
146 return EFI_NOT_READY;
147 }
148
149 if (Length >= sizeof (TempRand)) {
150 WriteUnaligned64 ((UINT64 *)RandBuffer, TempRand[0]);
151 RandBuffer += sizeof (UINT64);
152 WriteUnaligned64 ((UINT64 *)RandBuffer, TempRand[1]);
153 RandBuffer += sizeof (UINT64);
154 Length -= sizeof (TempRand);
155 } else {
156 CopyMem (RandBuffer, TempRand, Length);
157 Length = 0;
158 }
159 }
160
161 return EFI_SUCCESS;
162 }