summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c87
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c26
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c40
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf1
-rw-r--r--SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h27
5 files changed, 172 insertions, 9 deletions
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
index f9c740d761..09a5924a69 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
@@ -22,11 +22,63 @@
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
+#include <Library/RngLib.h>
#include <Protocol/Rng.h>
#include "RngDxeInternals.h"
+// Maximum number of Rng algorithms.
+#define RNG_AVAILABLE_ALGO_MAX 1
+
+/** Allocate and initialize mAvailableAlgoArray with the available
+ Rng algorithms. Also update mAvailableAlgoArrayCount.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+GetAvailableAlgorithms (
+ VOID
+ )
+{
+ UINT64 DummyRand;
+
+ // Allocate RNG_AVAILABLE_ALGO_MAX entries to avoid evaluating
+ // Rng algorithms 2 times, one for the allocation, one to populate.
+ mAvailableAlgoArray = AllocateZeroPool (RNG_AVAILABLE_ALGO_MAX);
+ if (mAvailableAlgoArray == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Check RngGetBytes() before advertising PcdCpuRngSupportedAlgorithm.
+ if (!EFI_ERROR (RngGetBytes (sizeof (DummyRand), (UINT8 *)&DummyRand))) {
+ CopyMem (
+ &mAvailableAlgoArray[mAvailableAlgoArrayCount],
+ PcdGetPtr (PcdCpuRngSupportedAlgorithm),
+ sizeof (EFI_RNG_ALGORITHM)
+ );
+ mAvailableAlgoArrayCount++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/** Free mAvailableAlgoArray.
+**/
+VOID
+EFIAPI
+FreeAvailableAlgorithms (
+ VOID
+ )
+{
+ FreePool (mAvailableAlgoArray);
+ return;
+}
+
/**
Produces and returns an RNG value using either the default or specified RNG algorithm.
@@ -59,6 +111,7 @@ RngGetRNG (
)
{
EFI_STATUS Status;
+ UINTN Index;
if ((This == NULL) || (RNGValueLength == 0) || (RNGValue == NULL)) {
return EFI_INVALID_PARAMETER;
@@ -68,9 +121,21 @@ RngGetRNG (
//
// Use the default RNG algorithm if RNGAlgorithm is NULL.
//
- RNGAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
+ for (Index = 0; Index < mAvailableAlgoArrayCount; Index++) {
+ if (!IsZeroGuid (&mAvailableAlgoArray[Index])) {
+ RNGAlgorithm = &mAvailableAlgoArray[Index];
+ goto FoundAlgo;
+ }
+ }
+
+ if (Index == mAvailableAlgoArrayCount) {
+ // No algorithm available.
+ ASSERT (Index != mAvailableAlgoArrayCount);
+ return EFI_DEVICE_ERROR;
+ }
}
+FoundAlgo:
if (CompareGuid (RNGAlgorithm, PcdGetPtr (PcdCpuRngSupportedAlgorithm))) {
Status = RngGetBytes (RNGValueLength, RNGValue);
return Status;
@@ -113,24 +178,30 @@ RngGetInfo (
OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
)
{
- UINTN RequiredSize;
- EFI_RNG_ALGORITHM *CpuRngSupportedAlgorithm;
-
- RequiredSize = sizeof (EFI_RNG_ALGORITHM);
+ UINTN RequiredSize;
if ((This == NULL) || (RNGAlgorithmListSize == NULL)) {
return EFI_INVALID_PARAMETER;
}
+ RequiredSize = mAvailableAlgoArrayCount * sizeof (EFI_RNG_ALGORITHM);
+
+ if (RequiredSize == 0) {
+ // No supported algorithms found.
+ return EFI_UNSUPPORTED;
+ }
+
if (*RNGAlgorithmListSize < RequiredSize) {
*RNGAlgorithmListSize = RequiredSize;
return EFI_BUFFER_TOO_SMALL;
}
- CpuRngSupportedAlgorithm = PcdGetPtr (PcdCpuRngSupportedAlgorithm);
-
- CopyMem (&RNGAlgorithmList[0], CpuRngSupportedAlgorithm, sizeof (EFI_RNG_ALGORITHM));
+ if (RNGAlgorithmList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ // There is no gap in the array, so copy the block.
+ CopyMem (RNGAlgorithmList, mAvailableAlgoArray, RequiredSize);
*RNGAlgorithmListSize = RequiredSize;
return EFI_SUCCESS;
}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
index 8f5d8e740f..677600bed7 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
@@ -26,6 +26,32 @@
#include "RngDxeInternals.h"
+/** Allocate and initialize mAvailableAlgoArray with the available
+ Rng algorithms. Also update mAvailableAlgoArrayCount.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+GetAvailableAlgorithms (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/** Free mAvailableAlgoArray.
+**/
+VOID
+EFIAPI
+FreeAvailableAlgorithms (
+ VOID
+ )
+{
+ return;
+}
+
/**
Produces and returns an RNG value using either the default or specified RNG algorithm.
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
index d7905a7f4d..421abb52b8 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
@@ -28,6 +28,13 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "RngDxeInternals.h"
//
+// Array containing the validated Rng algorithm.
+// The entry with the lowest index will be the default algorithm.
+//
+UINTN mAvailableAlgoArrayCount;
+EFI_RNG_ALGORITHM *mAvailableAlgoArray;
+
+//
// The Random Number Generator (RNG) protocol
//
EFI_RNG_PROTOCOL mRngRdRand = {
@@ -66,8 +73,39 @@ RngDriverEntry (
&mRngRdRand,
NULL
);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the list of available algorithm.
+ //
+ return GetAvailableAlgorithms ();
+}
+
+/**
+ This is the unload handle for RndgDxe module.
+
+ Disconnect the driver specified by ImageHandle from all the devices in the handle database.
+ Uninstall all the protocols installed in the driver entry point.
- return Status;
+ @param[in] ImageHandle The drivers' driver image.
+
+ @retval EFI_SUCCESS The image is unloaded.
+ @retval Others Failed to unload the image.
+
+**/
+EFI_STATUS
+EFIAPI
+RngDriverUnLoad (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ //
+ // Free the list of available algorithm.
+ //
+ FreeAvailableAlgorithms ();
+ return EFI_SUCCESS;
}
/**
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
index 60efb5562e..1985dfbb46 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
@@ -22,6 +22,7 @@
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = RngDriverEntry
+ UNLOAD_IMAGE = RngDriverUnLoad
MODULE_UNI_FILE = RngDxe.uni
#
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
index 7ecab14048..f751402608 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
@@ -12,6 +12,33 @@
#include <Protocol/Rng.h>
+//
+// Array containing the validated Rng algorithm.
+// The entry with the lowest index will be the default algorithm.
+//
+extern UINTN mAvailableAlgoArrayCount;
+extern EFI_RNG_ALGORITHM *mAvailableAlgoArray;
+
+/** Allocate and initialize mAvailableAlgoArray with the available
+ Rng algorithms. Also update mAvailableAlgoArrayCount.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate memory.
+**/
+EFI_STATUS
+EFIAPI
+GetAvailableAlgorithms (
+ VOID
+ );
+
+/** Free mAvailableAlgoArray.
+**/
+VOID
+EFIAPI
+FreeAvailableAlgorithms (
+ VOID
+ );
+
/**
Returns information about the random number generation implementation.