]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/OpensslLib/rand_pool.c
CryptoPkg: OpensslLib: Use RngLib to generate entropy in rand_pool
[mirror_edk2.git] / CryptoPkg / Library / OpensslLib / rand_pool.c
1 /** @file
2 OpenSSL_1_1_1b doesn't implement rand_pool_* functions for UEFI.
3 The file implement these functions.
4
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "crypto/rand.h"
11 #include <openssl/aes.h>
12
13 #include <Uefi.h>
14 #include <Library/RngLib.h>
15
16 /**
17 Calls RandomNumber64 to fill
18 a buffer of arbitrary size with random bytes.
19 This is a shim layer to RngLib.
20
21 @param[in] Length Size of the buffer, in bytes, to fill with.
22 @param[out] RandBuffer Pointer to the buffer to store the random result.
23
24 @retval TRUE Random bytes generation succeeded.
25 @retval FALSE Failed to request random bytes.
26
27 **/
28 STATIC
29 BOOLEAN
30 EFIAPI
31 RandGetBytes (
32 IN UINTN Length,
33 OUT UINT8 *RandBuffer
34 )
35 {
36 BOOLEAN Ret;
37 UINT64 TempRand;
38
39 Ret = FALSE;
40
41 if (RandBuffer == NULL) {
42 DEBUG((DEBUG_ERROR, "[OPENSSL_RAND_POOL] NULL RandBuffer. No random numbers are generated and your system is not secure\n"));
43 ASSERT (RandBuffer != NULL); // Since we can't generate random numbers, we should assert. Otherwise we will just blow up later.
44 return Ret;
45 }
46
47
48 while (Length > 0) {
49 // Use RngLib to get random number
50 Ret = GetRandomNumber64 (&TempRand);
51
52 if (!Ret) {
53 return Ret;
54 }
55 if (Length >= sizeof (TempRand)) {
56 *((UINT64*) RandBuffer) = TempRand;
57 RandBuffer += sizeof (UINT64);
58 Length -= sizeof (TempRand);
59 }
60 else {
61 CopyMem (RandBuffer, &TempRand, Length);
62 Length = 0;
63 }
64 }
65
66 return Ret;
67 }
68
69 /*
70 * Add random bytes to the pool to acquire requested amount of entropy
71 *
72 * This function is platform specific and tries to acquire the requested
73 * amount of entropy by polling platform specific entropy sources.
74 *
75 * This is OpenSSL required interface.
76 */
77 size_t
78 rand_pool_acquire_entropy (
79 RAND_POOL *pool
80 )
81 {
82 BOOLEAN Ret;
83 size_t Bytes_needed;
84 unsigned char *Buffer;
85
86 Bytes_needed = rand_pool_bytes_needed (pool, 1 /*entropy_factor*/);
87 if (Bytes_needed > 0) {
88 Buffer = rand_pool_add_begin (pool, Bytes_needed);
89
90 if (Buffer != NULL) {
91 Ret = RandGetBytes (Bytes_needed, Buffer);
92 if (FALSE == Ret) {
93 rand_pool_add_end (pool, 0, 0);
94 }
95 else {
96 rand_pool_add_end (pool, Bytes_needed, 8 * Bytes_needed);
97 }
98 }
99 }
100
101 return rand_pool_entropy_available (pool);
102 }
103
104 /*
105 * Implementation for UEFI
106 *
107 * This is OpenSSL required interface.
108 */
109 int
110 rand_pool_add_nonce_data (
111 RAND_POOL *pool
112 )
113 {
114 UINT8 data[16];
115 RandGetBytes (sizeof(data), data);
116
117 return rand_pool_add (pool, (unsigned char*)&data, sizeof(data), 0);
118 }
119
120 /*
121 * Implementation for UEFI
122 *
123 * This is OpenSSL required interface.
124 */
125 int
126 rand_pool_add_additional_data (
127 RAND_POOL *pool
128 )
129 {
130 UINT8 data[16];
131 RandGetBytes (sizeof(data), data);
132
133 return rand_pool_add (pool, (unsigned char*)&data, sizeof(data), 0);
134 }
135
136 /*
137 * Dummy Implementation for UEFI
138 *
139 * This is OpenSSL required interface.
140 */
141 int
142 rand_pool_init (
143 VOID
144 )
145 {
146 return 1;
147 }
148
149 /*
150 * Dummy Implementation for UEFI
151 *
152 * This is OpenSSL required interface.
153 */
154 VOID
155 rand_pool_cleanup(
156 VOID
157 )
158 {
159 }
160
161 /*
162 * Dummy Implementation for UEFI
163 *
164 * This is OpenSSL required interface.
165 */
166 VOID
167 rand_pool_keep_random_devices_open (
168 int keep
169 )
170 {
171 }