MdeModulePkg: Duplicate BaseRngLibTimerLib to MdeModulePkg
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4504 The BaseRngLibTimerLib allows to generate number based on a timer. This mechanism allows to have a basic non-secure implementation for non-production platforms. To bind and identify Random Number Generators implementations with a GUID, an unsafe GUID should be added. This GUID cannot be added to the MdePkg unless it is also added to a specification. To keep the MdePkg self-contained, copy the BaseRngLibTimerLib to the MdeModulePkg. This will allow to define an unsafe Rng GUID in a later patch in the MdeModulePkg. The MdePkg implementation will be removed later. This allows to give some time to platform owners to switch to the MdeModulePkg implementation. Signed-off-by: Pierre Gondois <pierre.gondois@arm.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com> Acked-by: Ard Biesheuvel <ardb@kernel.org> Tested-by: Kun Qin <kun.qin@microsoft.com>
This commit is contained in:
committed by
mergify[bot]
parent
2ce5ae43c2
commit
2f981bddcb
192
MdeModulePkg/Library/BaseRngLibTimerLib/RngLibTimer.c
Normal file
192
MdeModulePkg/Library/BaseRngLibTimerLib/RngLibTimer.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/** @file
|
||||
BaseRng Library that uses the TimerLib to provide reasonably random numbers.
|
||||
Do not use this on a production system.
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
|
||||
#define DEFAULT_DELAY_TIME_IN_MICROSECONDS 10
|
||||
|
||||
/**
|
||||
Using the TimerLib GetPerformanceCounterProperties() we delay
|
||||
for enough time for the PerformanceCounter to increment.
|
||||
|
||||
If the return value from GetPerformanceCounterProperties (TimerLib)
|
||||
is zero, this function will return 10 and attempt to assert.
|
||||
**/
|
||||
STATIC
|
||||
UINT32
|
||||
CalculateMinimumDecentDelayInMicroseconds (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
UINT64 CounterHz;
|
||||
|
||||
// Get the counter properties
|
||||
CounterHz = GetPerformanceCounterProperties (NULL, NULL);
|
||||
// Make sure we won't divide by zero
|
||||
if (CounterHz == 0) {
|
||||
ASSERT (CounterHz != 0); // Assert so the developer knows something is wrong
|
||||
return DEFAULT_DELAY_TIME_IN_MICROSECONDS;
|
||||
}
|
||||
|
||||
// Calculate the minimum delay based on 1.5 microseconds divided by the hertz.
|
||||
// We calculate the length of a cycle (1/CounterHz) and multiply it by 1.5 microseconds
|
||||
// This ensures that the performance counter has increased by at least one
|
||||
return (UINT32)(MAX (DivU64x64Remainder (1500000, CounterHz, NULL), 1));
|
||||
}
|
||||
|
||||
/**
|
||||
Generates a 16-bit random number.
|
||||
|
||||
if Rand is NULL, then ASSERT().
|
||||
|
||||
@param[out] Rand Buffer pointer to store the 16-bit random value.
|
||||
|
||||
@retval TRUE Random number generated successfully.
|
||||
@retval FALSE Failed to generate the random number.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
GetRandomNumber16 (
|
||||
OUT UINT16 *Rand
|
||||
)
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT8 *RandPtr;
|
||||
UINT32 DelayInMicroSeconds;
|
||||
|
||||
ASSERT (Rand != NULL);
|
||||
|
||||
if (Rand == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DelayInMicroSeconds = CalculateMinimumDecentDelayInMicroseconds ();
|
||||
RandPtr = (UINT8 *)Rand;
|
||||
// Get 2 bytes of random ish data
|
||||
for (Index = 0; Index < sizeof (UINT16); Index++) {
|
||||
*RandPtr = (UINT8)(GetPerformanceCounter () & 0xFF);
|
||||
// Delay to give the performance counter a chance to change
|
||||
MicroSecondDelay (DelayInMicroSeconds);
|
||||
RandPtr++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Generates a 32-bit random number.
|
||||
|
||||
if Rand is NULL, then ASSERT().
|
||||
|
||||
@param[out] Rand Buffer pointer to store the 32-bit random value.
|
||||
|
||||
@retval TRUE Random number generated successfully.
|
||||
@retval FALSE Failed to generate the random number.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
GetRandomNumber32 (
|
||||
OUT UINT32 *Rand
|
||||
)
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT8 *RandPtr;
|
||||
UINT32 DelayInMicroSeconds;
|
||||
|
||||
ASSERT (Rand != NULL);
|
||||
|
||||
if (NULL == Rand) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RandPtr = (UINT8 *)Rand;
|
||||
DelayInMicroSeconds = CalculateMinimumDecentDelayInMicroseconds ();
|
||||
// Get 4 bytes of random ish data
|
||||
for (Index = 0; Index < sizeof (UINT32); Index++) {
|
||||
*RandPtr = (UINT8)(GetPerformanceCounter () & 0xFF);
|
||||
// Delay to give the performance counter a chance to change
|
||||
MicroSecondDelay (DelayInMicroSeconds);
|
||||
RandPtr++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Generates a 64-bit random number.
|
||||
|
||||
if Rand is NULL, then ASSERT().
|
||||
|
||||
@param[out] Rand Buffer pointer to store the 64-bit random value.
|
||||
|
||||
@retval TRUE Random number generated successfully.
|
||||
@retval FALSE Failed to generate the random number.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
GetRandomNumber64 (
|
||||
OUT UINT64 *Rand
|
||||
)
|
||||
{
|
||||
UINT32 Index;
|
||||
UINT8 *RandPtr;
|
||||
UINT32 DelayInMicroSeconds;
|
||||
|
||||
ASSERT (Rand != NULL);
|
||||
|
||||
if (NULL == Rand) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RandPtr = (UINT8 *)Rand;
|
||||
DelayInMicroSeconds = CalculateMinimumDecentDelayInMicroseconds ();
|
||||
// Get 8 bytes of random ish data
|
||||
for (Index = 0; Index < sizeof (UINT64); Index++) {
|
||||
*RandPtr = (UINT8)(GetPerformanceCounter () & 0xFF);
|
||||
// Delay to give the performance counter a chance to change
|
||||
MicroSecondDelay (DelayInMicroSeconds);
|
||||
RandPtr++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
Generates a 128-bit random number.
|
||||
|
||||
if Rand is NULL, then ASSERT().
|
||||
|
||||
@param[out] Rand Buffer pointer to store the 128-bit random value.
|
||||
|
||||
@retval TRUE Random number generated successfully.
|
||||
@retval FALSE Failed to generate the random number.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
GetRandomNumber128 (
|
||||
OUT UINT64 *Rand
|
||||
)
|
||||
{
|
||||
ASSERT (Rand != NULL);
|
||||
// This should take around 80ms
|
||||
|
||||
// Read first 64 bits
|
||||
if (!GetRandomNumber64 (Rand)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Read second 64 bits
|
||||
return GetRandomNumber64 (++Rand);
|
||||
}
|
Reference in New Issue
Block a user