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