From bb2f962d982531a916ca9429cf9751b6d43ee306 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Fri, 31 May 2024 12:02:45 -0400 Subject: [PATCH] MdePkg: Add PeiRngLib Adds a new PEI library instance for RngLib that uses the RNG services provided by the RNG PPI. This library instance will add a DEPEX on gEfiRngPpiGuid on modules it links against. It can be used to allow PEIMs to get RNG support over a dynamic interface. Signed-off-by: Michael Kubacki --- MdePkg/Library/PeiRngLib/PeiRngLib.c | 230 +++++++++++++++++++++++++ MdePkg/Library/PeiRngLib/PeiRngLib.inf | 43 +++++ MdePkg/Library/PeiRngLib/PeiRngLib.uni | 13 ++ MdePkg/MdePkg.dsc | 1 + 4 files changed, 287 insertions(+) create mode 100644 MdePkg/Library/PeiRngLib/PeiRngLib.c create mode 100644 MdePkg/Library/PeiRngLib/PeiRngLib.inf create mode 100644 MdePkg/Library/PeiRngLib/PeiRngLib.uni diff --git a/MdePkg/Library/PeiRngLib/PeiRngLib.c b/MdePkg/Library/PeiRngLib/PeiRngLib.c new file mode 100644 index 0000000000..d30195834a --- /dev/null +++ b/MdePkg/Library/PeiRngLib/PeiRngLib.c @@ -0,0 +1,230 @@ +/** @file + RNG library instance that uses the Random Number Generator (RNG) PPI to provide + random numbers. + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent + + MU_CHANGE: WHOLE FILE +**/ +#include +#include +#include +#include +#include + +/** + Generates a random number via the NIST 800-9A algorithm. Refer to + http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf for more information. + + @param[out] Buffer Buffer to receive the random number. + @param[in] BufferSize Number of bytes in Buffer. + + @retval EFI_SUCCESS or underlying failure code. + +**/ +STATIC +EFI_STATUS +GenerateRandomNumberViaNist800Algorithm ( + OUT UINT8 *Buffer, + IN UINTN BufferSize + ) +{ + EFI_STATUS Status; + EFI_RNG_PPI *RngPpi; + + RngPpi = NULL; + + if (Buffer == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Buffer == NULL.\n", __func__)); + return EFI_INVALID_PARAMETER; + } + + Status = PeiServicesLocatePpi (&gEfiRngPpiGuid, 0, NULL, (VOID **)&RngPpi); + if (EFI_ERROR (Status) || (RngPpi == NULL)) { + DEBUG ((DEBUG_ERROR, "%a: Could not locate RNG PPI, Status = %r\n", __func__, Status)); + return Status; + } + + Status = RngPpi->GetRNG (RngPpi, &gEfiRngAlgorithmSp80090Ctr256Guid, BufferSize, Buffer); + DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm CTR-256 - Status = %r\n", __func__, Status)); + if (!EFI_ERROR (Status)) { + return Status; + } + + Status = RngPpi->GetRNG (RngPpi, &gEfiRngAlgorithmSp80090Hmac256Guid, BufferSize, Buffer); + DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm HMAC-256 - Status = %r\n", __func__, Status)); + if (!EFI_ERROR (Status)) { + return Status; + } + + Status = RngPpi->GetRNG (RngPpi, &gEfiRngAlgorithmSp80090Hash256Guid, BufferSize, Buffer); + DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm Hash-256 - Status = %r\n", __func__, Status)); + if (!EFI_ERROR (Status)) { + return Status; + } + + Status = RngPpi->GetRNG (RngPpi, &gEfiRngAlgorithmRaw, BufferSize, Buffer); + DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm Raw - Status = %r\n", __func__, Status)); + if (!EFI_ERROR (Status)) { + return Status; + } + + // If all the other methods have failed, use the default method from the RngPpi + Status = RngPpi->GetRNG (RngPpi, NULL, BufferSize, Buffer); + DEBUG ((DEBUG_INFO, "%a: GetRNG algorithm default - Status = %r\n", __func__, Status)); + if (!EFI_ERROR (Status)) { + return Status; + } + + // If we get to this point, we have failed + DEBUG ((DEBUG_ERROR, "%a: GetRNG() failed, staus = %r\n", __func__, Status)); + + return Status; +}// GenerateRandomNumberViaNist800Algorithm() + +/** + Generates a 16-bit random number. + + if Rand is NULL, return FALSE. + + @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 + ) +{ + EFI_STATUS Status; + + if (Rand == NULL) { + return FALSE; + } + + Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, sizeof (UINT16)); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; +} + +/** + Generates a 32-bit random number. + + if Rand is NULL, return FALSE. + + @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 + ) +{ + EFI_STATUS Status; + + if (Rand == NULL) { + return FALSE; + } + + Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, sizeof (UINT32)); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; +} + +/** + Generates a 64-bit random number. + + if Rand is NULL, return FALSE. + + @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 + ) +{ + EFI_STATUS Status; + + if (Rand == NULL) { + return FALSE; + } + + Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, sizeof (UINT64)); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; +} + +/** + Generates a 128-bit random number. + + if Rand is NULL, return FALSE. + + @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 + ) +{ + EFI_STATUS Status; + + if (Rand == NULL) { + return FALSE; + } + + Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 2 * sizeof (UINT64)); + if (EFI_ERROR (Status)) { + return FALSE; + } + + return TRUE; +} + +/** + Get a GUID identifying the RNG algorithm implementation. + + @param [out] RngGuid If success, contains the GUID identifying + the RNG algorithm implementation. + + @retval EFI_SUCCESS Success. + @retval EFI_UNSUPPORTED Not supported. + @retval EFI_INVALID_PARAMETER Invalid parameter. +**/ +EFI_STATUS +EFIAPI +GetRngGuid ( + GUID *RngGuid + ) +{ + // Similar to DxeRngLib, EFI_UNSUPPORTED is returned for this library instance since it is unknown + // which exact algorithm may be used for a given request. + + return EFI_UNSUPPORTED; +} diff --git a/MdePkg/Library/PeiRngLib/PeiRngLib.inf b/MdePkg/Library/PeiRngLib/PeiRngLib.inf new file mode 100644 index 0000000000..b130b067d5 --- /dev/null +++ b/MdePkg/Library/PeiRngLib/PeiRngLib.inf @@ -0,0 +1,43 @@ +## @file +# PPI-based Instance of RNG (Random Number Generator) Library. +# +# This library instance requires a RNG PPI to be produced so that the module may use +# it for RNG operations. A RNG PPI DEPEX will be placed on the module. +# +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# MU_CHANGE: WHOLE FILE +## + +[Defines] + INF_VERSION = 0x0001001B + BASE_NAME = PeiRngLib + MODULE_UNI_FILE = PeiRngLib.uni + FILE_GUID = FF240232-C25D-4277-AB81-D6B0C51F2D25 + VERSION_STRING = 1.0 + MODULE_TYPE = PEIM + LIBRARY_CLASS = RngLib | PEIM + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + PeiServicesLib + +[Guids] + gEfiRngAlgorithmSp80090Ctr256Guid + gEfiRngAlgorithmSp80090Hash256Guid + gEfiRngAlgorithmSp80090Hmac256Guid + gEfiRngAlgorithmRaw + +[Sources] + PeiRngLib.c + +[Ppis] + gEfiRngPpiGuid ## CONSUMES + +[Depex] + gEfiRngPpiGuid diff --git a/MdePkg/Library/PeiRngLib/PeiRngLib.uni b/MdePkg/Library/PeiRngLib/PeiRngLib.uni new file mode 100644 index 0000000000..1a6fdeb986 --- /dev/null +++ b/MdePkg/Library/PeiRngLib/PeiRngLib.uni @@ -0,0 +1,13 @@ +// @file +// PEI Instance of the RNG (Random Number Generator) Library. +// +// A RngLib instance that uses the RNG PPI to provide random numbers. +// +// Copyright (c) Microsoft Corporation. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// + +#string STR_MODULE_ABSTRACT #language en-US "Instance of the RNG Library for PEI" + +#string STR_MODULE_DESCRIPTION #language en-US "A library that uses the RNG PPI to provide random numbers" diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 4536a14c5b..491b240980 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -144,6 +144,7 @@ MdePkg/Library/StackCheckLib/StackCheckLibDynamicInit.inf ## MU_CHANGE MdePkg/Library/StackCheckFailureHookLibNull/StackCheckFailureHookLibNull.inf ## MU_CHANGE MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf ## MU_CHANGE + MdePkg/Library/PeiRngLib/PeiRngLib.inf # MU_CHANGE: Add PeiRngLib [Components.IA32, Components.X64, Components.ARM, Components.AARCH64] #