/** @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 | |
) | |
{ | |
} |