+++ /dev/null
-/** @file\r
- RNG Driver to produce the UEFI Random Number Generator protocol.\r
-\r
- The driver can use RNDR instruction (through the RngLib and if FEAT_RNG is\r
- present) to produce random numbers. It also uses the Arm FW-TRNG interface\r
- to implement EFI_RNG_ALGORITHM_RAW.\r
-\r
- RNG Algorithms defined in UEFI 2.4:\r
- - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID\r
- - EFI_RNG_ALGORITHM_RAW\r
- - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID\r
- - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID\r
- - EFI_RNG_ALGORITHM_X9_31_3DES_GUID - Unsupported\r
- - EFI_RNG_ALGORITHM_X9_31_AES_GUID - Unsupported\r
-\r
- Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>\r
- Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>\r
- (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
- Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>\r
-\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/RngLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/ArmTrngLib.h>\r
-#include <Protocol/Rng.h>\r
-\r
-#include "RngDxeInternals.h"\r
-\r
-// Maximum number of Rng algorithms.\r
-#define RNG_AVAILABLE_ALGO_MAX 2\r
-\r
-/** Allocate and initialize mAvailableAlgoArray with the available\r
- Rng algorithms. Also update mAvailableAlgoArrayCount.\r
-\r
- @retval EFI_SUCCESS The function completed successfully.\r
- @retval EFI_OUT_OF_RESOURCES Could not allocate memory.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetAvailableAlgorithms (\r
- VOID\r
- )\r
-{\r
- UINT64 DummyRand;\r
- UINT16 MajorRevision;\r
- UINT16 MinorRevision;\r
-\r
- // Rng algorithms 2 times, one for the allocation, one to populate.\r
- mAvailableAlgoArray = AllocateZeroPool (RNG_AVAILABLE_ALGO_MAX);\r
- if (mAvailableAlgoArray == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- // Check RngGetBytes() before advertising PcdCpuRngSupportedAlgorithm.\r
- if (!EFI_ERROR (RngGetBytes (sizeof (DummyRand), (UINT8 *)&DummyRand))) {\r
- CopyMem (\r
- &mAvailableAlgoArray[mAvailableAlgoArrayCount],\r
- PcdGetPtr (PcdCpuRngSupportedAlgorithm),\r
- sizeof (EFI_RNG_ALGORITHM)\r
- );\r
- mAvailableAlgoArrayCount++;\r
-\r
- DEBUG_CODE_BEGIN ();\r
- if (IsZeroGuid (PcdGetPtr (PcdCpuRngSupportedAlgorithm))) {\r
- DEBUG ((\r
- DEBUG_WARN,\r
- "PcdCpuRngSupportedAlgorithm should be a non-zero GUID\n"\r
- ));\r
- }\r
-\r
- DEBUG_CODE_END ();\r
- }\r
-\r
- // Raw algorithm (Trng)\r
- if (!EFI_ERROR (GetArmTrngVersion (&MajorRevision, &MinorRevision))) {\r
- CopyMem (\r
- &mAvailableAlgoArray[mAvailableAlgoArrayCount],\r
- &gEfiRngAlgorithmRaw,\r
- sizeof (EFI_RNG_ALGORITHM)\r
- );\r
- mAvailableAlgoArrayCount++;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/** Free mAvailableAlgoArray.\r
-**/\r
-VOID\r
-EFIAPI\r
-FreeAvailableAlgorithms (\r
- VOID\r
- )\r
-{\r
- FreePool (mAvailableAlgoArray);\r
- return;\r
-}\r
-\r
-/**\r
- Produces and returns an RNG value using either the default or specified RNG algorithm.\r
-\r
- @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.\r
- @param[in] RNGAlgorithm A pointer to the EFI_RNG_ALGORITHM that identifies the RNG\r
- algorithm to use. May be NULL in which case the function will\r
- use its default RNG algorithm.\r
- @param[in] RNGValueLength The length in bytes of the memory buffer pointed to by\r
- RNGValue. The driver shall return exactly this numbers of bytes.\r
- @param[out] RNGValue A caller-allocated memory buffer filled by the driver with the\r
- resulting RNG value.\r
-\r
- @retval EFI_SUCCESS The RNG value was returned successfully.\r
- @retval EFI_UNSUPPORTED The algorithm specified by RNGAlgorithm is not supported by\r
- this driver.\r
- @retval EFI_DEVICE_ERROR An RNG value could not be retrieved due to a hardware or\r
- firmware error.\r
- @retval EFI_NOT_READY There is not enough random data available to satisfy the length\r
- requested by RNGValueLength.\r
- @retval EFI_INVALID_PARAMETER RNGValue is NULL or RNGValueLength is zero.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-RngGetRNG (\r
- IN EFI_RNG_PROTOCOL *This,\r
- IN EFI_RNG_ALGORITHM *RNGAlgorithm OPTIONAL,\r
- IN UINTN RNGValueLength,\r
- OUT UINT8 *RNGValue\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
-\r
- if ((This == NULL) || (RNGValueLength == 0) || (RNGValue == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (RNGAlgorithm == NULL) {\r
- //\r
- // Use the default RNG algorithm if RNGAlgorithm is NULL.\r
- //\r
- for (Index = 0; Index < mAvailableAlgoArrayCount; Index++) {\r
- if (!IsZeroGuid (&mAvailableAlgoArray[Index])) {\r
- RNGAlgorithm = &mAvailableAlgoArray[Index];\r
- goto FoundAlgo;\r
- }\r
- }\r
-\r
- if (Index == mAvailableAlgoArrayCount) {\r
- // No algorithm available.\r
- ASSERT (Index != mAvailableAlgoArrayCount);\r
- return EFI_DEVICE_ERROR;\r
- }\r
- }\r
-\r
-FoundAlgo:\r
- if (CompareGuid (RNGAlgorithm, PcdGetPtr (PcdCpuRngSupportedAlgorithm))) {\r
- Status = RngGetBytes (RNGValueLength, RNGValue);\r
- return Status;\r
- }\r
-\r
- // Raw algorithm (Trng)\r
- if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {\r
- return GenerateEntropy (RNGValueLength, RNGValue);\r
- }\r
-\r
- //\r
- // Other algorithms are unsupported by this driver.\r
- //\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- Returns information about the random number generation implementation.\r
-\r
- @param[in] This A pointer to the EFI_RNG_PROTOCOL instance.\r
- @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.\r
- On output with a return code of EFI_SUCCESS, the size\r
- in bytes of the data returned in RNGAlgorithmList. On output\r
- with a return code of EFI_BUFFER_TOO_SMALL,\r
- the size of RNGAlgorithmList required to obtain the list.\r
- @param[out] RNGAlgorithmList A caller-allocated memory buffer filled by the driver\r
- with one EFI_RNG_ALGORITHM element for each supported\r
- RNG algorithm. The list must not change across multiple\r
- calls to the same driver. The first algorithm in the list\r
- is the default algorithm for the driver.\r
-\r
- @retval EFI_SUCCESS The RNG algorithm list was returned successfully.\r
- @retval EFI_UNSUPPORTED The services is not supported by this driver.\r
- @retval EFI_DEVICE_ERROR The list of algorithms could not be retrieved due to a\r
- hardware or firmware error.\r
- @retval EFI_INVALID_PARAMETER One or more of the parameters are incorrect.\r
- @retval EFI_BUFFER_TOO_SMALL The buffer RNGAlgorithmList is too small to hold the result.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-RngGetInfo (\r
- IN EFI_RNG_PROTOCOL *This,\r
- IN OUT UINTN *RNGAlgorithmListSize,\r
- OUT EFI_RNG_ALGORITHM *RNGAlgorithmList\r
- )\r
-{\r
- UINTN RequiredSize;\r
-\r
- if ((This == NULL) || (RNGAlgorithmListSize == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- RequiredSize = mAvailableAlgoArrayCount * sizeof (EFI_RNG_ALGORITHM);\r
-\r
- if (RequiredSize == 0) {\r
- // No supported algorithms found.\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- if (*RNGAlgorithmListSize < RequiredSize) {\r
- *RNGAlgorithmListSize = RequiredSize;\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- if (RNGAlgorithmList == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // There is no gap in the array, so copy the block.\r
- CopyMem (RNGAlgorithmList, mAvailableAlgoArray, RequiredSize);\r
- *RNGAlgorithmListSize = RequiredSize;\r
- return EFI_SUCCESS;\r
-}\r