]>
git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/OpensslLib/rand_pool.c
2 OpenSSL_1_1_1b doesn't implement rand_pool_* functions for UEFI.
3 The file implement these functions.
5 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "internal/rand_int.h"
11 #include <openssl/aes.h>
14 #include <Library/TimerLib.h>
16 #include "rand_pool_noise.h"
19 Get some randomness from low-order bits of GetPerformanceCounter results.
20 And combine them to the 64-bit value
22 @param[out] Rand Buffer pointer to store the 64-bit random value.
24 @retval TRUE Random number generated successfully.
25 @retval FALSE Failed to generate.
30 GetRandNoise64FromPerformanceCounter(
41 RandPtr
= (UINT32
*) Rand
;
43 for (Index
= 0; Index
< 2; Index
++) {
44 *RandPtr
= (UINT32
) (GetPerformanceCounter () & 0xFF);
45 MicroSecondDelay (10);
53 Calls RandomNumber64 to fill
54 a buffer of arbitrary size with random bytes.
56 @param[in] Length Size of the buffer, in bytes, to fill with.
57 @param[out] RandBuffer Pointer to the buffer to store the random result.
59 @retval EFI_SUCCESS Random bytes generation succeeded.
60 @retval EFI_NOT_READY Failed to request random bytes.
78 // Get random noise from platform.
79 // If it failed, fallback to PerformanceCounter
80 // If you really care about security, you must override
81 // GetRandomNoise64FromPlatform.
83 Ret
= GetRandomNoise64 (&TempRand
);
85 Ret
= GetRandNoise64FromPerformanceCounter (&TempRand
);
90 if (Length
>= sizeof (TempRand
)) {
91 *((UINT64
*) RandBuffer
) = TempRand
;
92 RandBuffer
+= sizeof (UINT64
);
93 Length
-= sizeof (TempRand
);
95 CopyMem (RandBuffer
, &TempRand
, Length
);
104 Creates a 128bit random value that is fully forward and backward prediction resistant,
105 suitable for seeding a NIST SP800-90 Compliant.
106 This function takes multiple random numbers from PerformanceCounter to ensure reseeding
107 and performs AES-CBC-MAC over the data to compute the seed value.
109 @param[out] SeedBuffer Pointer to a 128bit buffer to store the random seed.
111 @retval TRUE Random seed generation succeeded.
112 @retval FALSE Failed to request random bytes.
119 OUT UINT8
*SeedBuffer
132 // Chose an arbitrary key and zero the feed_forward_value (FFV)
134 for (Index
= 0; Index
< 16; Index
++) {
135 Key
[Index
] = (UINT8
) Index
;
139 AES_set_encrypt_key (Key
, 16 * 8, &AESKey
);
142 // Perform CBC_MAC over 32 * 128 bit values, with 10us gaps between 128 bit value
143 // The 10us gaps will ensure multiple reseeds within the system time with a large
146 for (Index
= 0; Index
< 32; Index
++) {
147 MicroSecondDelay (10);
148 Ret
= RandGetBytes (16, RandByte
);
154 // Perform XOR operations on two 128-bit value.
156 for (Index2
= 0; Index2
< 16; Index2
++) {
157 Xored
[Index2
] = RandByte
[Index2
] ^ Ffv
[Index2
];
160 AES_encrypt (Xored
, Ffv
, &AESKey
);
163 for (Index
= 0; Index
< 16; Index
++) {
164 SeedBuffer
[Index
] = Ffv
[Index
];
171 Generate high-quality entropy source.
173 @param[in] Length Size of the buffer, in bytes, to fill with.
174 @param[out] Entropy Pointer to the buffer to store the entropy data.
176 @retval EFI_SUCCESS Entropy generation succeeded.
177 @retval EFI_NOT_READY Failed to request random data.
183 RandGenerateEntropy (
193 BlockCount
= Length
/ 16;
194 Ptr
= (UINT8
*) Entropy
;
197 // Generate high-quality seed for DRBG Entropy
199 while (BlockCount
> 0) {
200 Ret
= RandGetSeed128 (Seed
);
204 CopyMem (Ptr
, Seed
, 16);
211 // Populate the remained data as request.
213 Ret
= RandGetSeed128 (Seed
);
217 CopyMem (Ptr
, Seed
, (Length
% 16));
223 * Add random bytes to the pool to acquire requested amount of entropy
225 * This function is platform specific and tries to acquire the requested
226 * amount of entropy by polling platform specific entropy sources.
228 * This is OpenSSL required interface.
230 size_t rand_pool_acquire_entropy(RAND_POOL
*pool
)
234 unsigned char * buffer
;
236 bytes_needed
= rand_pool_bytes_needed(pool
, 1 /*entropy_factor*/);
237 if (bytes_needed
> 0) {
238 buffer
= rand_pool_add_begin(pool
, bytes_needed
);
240 if (buffer
!= NULL
) {
241 Ret
= RandGenerateEntropy(bytes_needed
, buffer
);
243 rand_pool_add_end(pool
, 0, 0);
245 rand_pool_add_end(pool
, bytes_needed
, 8 * bytes_needed
);
250 return rand_pool_entropy_available(pool
);
254 * Implementation for UEFI
256 * This is OpenSSL required interface.
258 int rand_pool_add_nonce_data(RAND_POOL
*pool
)
265 RandGetBytes(8, (UINT8
*)&(data
.Rand
));
266 data
.TimerValue
= GetPerformanceCounter();
268 return rand_pool_add(pool
, (unsigned char*)&data
, sizeof(data
), 0);
272 * Implementation for UEFI
274 * This is OpenSSL required interface.
276 int rand_pool_add_additional_data(RAND_POOL
*pool
)
283 RandGetBytes(8, (UINT8
*)&(data
.Rand
));
284 data
.TimerValue
= GetPerformanceCounter();
286 return rand_pool_add(pool
, (unsigned char*)&data
, sizeof(data
), 0);
290 * Dummy Implementation for UEFI
292 * This is OpenSSL required interface.
294 int rand_pool_init(void)
300 * Dummy Implementation for UEFI
302 * This is OpenSSL required interface.
304 void rand_pool_cleanup(void)
309 * Dummy Implementation for UEFI
311 * This is OpenSSL required interface.
313 void rand_pool_keep_random_devices_open(int keep
)