From: "Leif Lindholm" <leif@nuviainc.com>
To: devel@edk2.groups.io, sami.mujawar@arm.com
Cc: ardb+tianocore@kernel.org, rebecca@bsdio.com, kraxel@redhat.com,
michael.d.kinney@intel.com, gaoliming@byosoft.com.cn,
zhiguang.liu@intel.com, jiewen.yao@intel.com,
jian.j.wang@intel.com, Matteo.Carlini@arm.com,
Akanksha.Jain2@arm.com, Ben.Adderson@arm.com, nd@arm.com
Subject: Re: [edk2-devel] [PATCH v2 3/8] ArmPkg: Add Arm Firmware TRNG library
Date: Wed, 24 Nov 2021 13:01:55 +0000 [thread overview]
Message-ID: <YZ43w/aKaDH99wjc@leviathan> (raw)
In-Reply-To: <20211116113301.31088-4-sami.mujawar@arm.com>
Hi Sami,
On Tue, Nov 16, 2021 at 11:32:55 +0000, Sami Mujawar wrote:
> Bugzilla: 3668 (https://bugzilla.tianocore.org/show_bug.cgi?id=3668)
>
> The Arm True Random Number Generator Firmware, Interface 1.0,
> Platform Design Document
> (https://developer.arm.com/documentation/den0098/latest/)
> defines an interface between an Operating System (OS) executing
> at EL1 and Firmware (FW) exposing a conditioned entropy source
> that is provided by a TRNG back end.
>
> The conditioned entropy, that is provided by the TRNG FW interface,
> is commonly used to seed deterministic random number generators.
>
> This patch adds a TrngLib library that implements the Arm TRNG
> firmware interface.
>
> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
> ---
>
> Notes:
> v2:
> - MdePkg\Include\Library\TrngLib.h is base type [LIMING]
> library. It can use RETURN_STATUS instead of
> EFI_STATUS.
> - Replaced EFI_STATUS with RETURN_STATUS. [SAMI]
> - MdePkg\Include\Library\TrngLib.h API parameter [LIMING]
> doesn't require CONST. CONST means the value
> specified by the input pointer will not be
> changed in API implementation.
> - Removed the use of constant pointers in the [SAMI]
> TRNG API.
>
> ArmPkg/ArmPkg.dsc | 1 +
> ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h | 64 +++
> ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c | 483 ++++++++++++++++++++
> ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf | 34 ++
> 4 files changed, 582 insertions(+)
>
> diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc
> index 59fd8f295d4f614cc68ee1021e691f94e279ab81..23df68c5eb53df11de5d96bde4949f3c833c9b2c 100644
> --- a/ArmPkg/ArmPkg.dsc
> +++ b/ArmPkg/ArmPkg.dsc
> @@ -156,6 +156,7 @@ [Components.common]
> ArmPkg/Drivers/ArmCrashDumpDxe/ArmCrashDumpDxe.inf
> ArmPkg/Drivers/ArmScmiDxe/ArmScmiDxe.inf
>
> + ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf
> ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf
> ArmPkg/Universal/Smbios/SmbiosMiscDxe/SmbiosMiscDxe.inf
> ArmPkg/Universal/Smbios/OemMiscLibNull/OemMiscLibNull.inf
> diff --git a/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..42236e743d972df0df205b1565496afeff5785f3
> --- /dev/null
> +++ b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngDefs.h
> @@ -0,0 +1,64 @@
> +/** @file
> + Arm Firmware TRNG definitions.
> +
> + Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Reference(s):
> + - [1] Arm True Random Number Generator Firmware, Interface 1.0,
> + Platform Design Document.
> + (https://developer.arm.com/documentation/den0098/latest/)
> +
> + @par Glossary:
> + - TRNG - True Random Number Generator
> + - FID - Function ID
> +**/
> +
> +#ifndef ARM_FW_TRNG_DEFS_H_
> +#define ARM_FW_TRNG_DEFS_H_
> +
> +// Firmware TRNG interface Function IDs
> +#define FID_TRNG_VERSION 0x84000050
> +#define FID_TRNG_FEATURES 0x84000051
> +#define FID_TRNG_GET_UUID 0x84000052
> +#define FID_TRNG_RND_AARCH32 0x84000053
> +#define FID_TRNG_RND_AARCH64 0xC4000053
Do these belong in ArmStdSmc.h?
> +
> +// Firmware TRNG revision mask and shift
> +#define TRNG_REV_MAJOR_MASK 0x7FFF
> +#define TRNG_REV_MINOR_MASK 0xFFFF
> +#define TRNG_REV_MAJOR_SHIFT 16
> +#define TRNG_REV_MINOR_SHIFT 0
> +
> +// Firmware TRNG status codes
> +#define TRNG_STATUS_SUCCESS (INT32)(0)
> +#define TRNG_NOT_SUPPORTED (INT32)(-1)
> +#define TRNG_INVALID_PARAMETER (INT32)(-2)
> +#define TRNG_NO_ENTROPY (INT32)(-3)
And the rest of the stuff to here, really?
> +#if defined (MDE_CPU_ARM)
> +/** FID to use on AArch32 platform to request entropy.
> +*/
> +#define FID_TRNG_RND FID_TRNG_RND_AARCH32
> +
> +/** Maximum bits of entropy supported on AArch32.
> +*/
> +#define MAX_ENTROPY_BITS 96
> +#elif defined (MDE_CPU_AARCH64)
> +/** FID to use on AArch64 platform to request entropy.
> +*/
> +#define FID_TRNG_RND FID_TRNG_RND_AARCH64
> +
> +/** Maximum bits of entropy supported on AArch64.
> +*/
> +#define MAX_ENTROPY_BITS 192
> +#else
> +#error "Firmware TRNG not supported. Unknown chipset."
> +#endif
> +
> +/** Typedef for SMC or HVC arguments.
> +*/
> +typedef ARM_SMC_ARGS ARM_MONITOR_ARGS;
> +
> +#endif // ARM_FW_TRNG_DEFS_H_
> diff --git a/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..314e7ffbc232ae90bbb77306f9c7113ce63012c8
> --- /dev/null
> +++ b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.c
> @@ -0,0 +1,483 @@
> +/** @file
> + Arm Firmware TRNG interface library.
> +
> + Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> + @par Reference(s):
> + - [1] Arm True Random Number Generator Firmware, Interface 1.0,
> + Platform Design Document.
> + (https://developer.arm.com/documentation/den0098/latest/)
> + - [2] NIST Special Publication 800-90A Revision 1, June 2015, Recommendation
> + for Random Number Generation Using Deterministic Random Bit Generators.
> + (https://csrc.nist.gov/publications/detail/sp/800-90a/rev-1/final)
> + - [3] NIST Special Publication 800-90B, Recommendation for the Entropy
> + Sources Used for Random Bit Generation.
> + (https://csrc.nist.gov/publications/detail/sp/800-90b/final)
> + - [4] (Second Draft) NIST Special Publication 800-90C, Recommendation for
> + Random Bit Generator (RBG) Constructions.
> + (https://csrc.nist.gov/publications/detail/sp/800-90c/draft)
> +
> + @par Glossary:
> + - TRNG - True Random Number Generator
> + - FID - Function ID
> +**/
> +
> +#include <Base.h>
> +#include <Library/ArmHvcLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/ArmSmcLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include "ArmFwTrngDefs.h"
> +
> +/** Convert TRNG status codes to EFI status codes.
> +
> + @param [in] TrngStatus TRNG status code.
> +
> + @retval RETURN_SUCCESS Success.
> + @retval RETURN_UNSUPPORTED Function not implemented.
> + @retval RETURN_INVALID_PARAMETER A parameter is invalid.
> + @retval RETURN_NOT_READY No Entropy available.
> +**/
> +STATIC
> +RETURN_STATUS
> +TrngStatusToEfiStatus (
> + IN INT32 TrngStatus
> + )
> +{
> + switch (TrngStatus) {
> + case TRNG_NOT_SUPPORTED:
> + return RETURN_UNSUPPORTED;
> +
> + case TRNG_INVALID_PARAMETER:
> + return RETURN_INVALID_PARAMETER;
> +
> + case TRNG_NO_ENTROPY:
> + return RETURN_NOT_READY;
> +
> + case TRNG_STATUS_SUCCESS:
> + default:
> + return RETURN_SUCCESS;
> + }
> +}
> +
> +/** Invoke the monitor call using the appropriate conduit.
> + If PcdMonitorConduitHvc is TRUE use the HVC conduit else use SMC conduit.
> +
> + @param [in, out] Args Arguments passed to and returned from the monitor.
> +
> + @return VOID
> +**/
> +STATIC
> +VOID
> +ArmCallMonitor (
> + IN OUT ARM_MONITOR_ARGS *Args
> + )
> +{
> + if (FeaturePcdGet (PcdMonitorConduitHvc)) {
> + ArmCallHvc ((ARM_HVC_ARGS*)Args);
> + } else {
> + ArmCallSmc ((ARM_SMC_ARGS*)Args);
> + }
> +}
Should this be in (a potentially renamed) ArmSmcLib?
> +
> +/** Get the version of the TRNG backend.
> +
> + A TRNG may be implemented by the system firmware, in which case this
> + function shall return the version of the TRNG backend.
> + The implementation must return NOT_SUPPORTED if a Back end is not present.
> +
> + @param [out] MajorRevision Major revision.
> + @param [out] MinorRevision Minor revision.
> +
> + @retval RETURN_SUCCESS The function completed successfully.
> + @retval RETURN_INVALID_PARAMETER Invalid parameter.
> + @retval RETURN_UNSUPPORTED Backend not present.
> +**/
> +RETURN_STATUS
> +EFIAPI
> +GetTrngVersion (
> + OUT UINT16 *MajorRevision,
> + OUT UINT16 *MinorRevision
> + )
> +{
> + RETURN_STATUS Status;
> + ARM_MONITOR_ARGS Parameters;
> + INT32 Revision;
> +
> + if ((MajorRevision == NULL) || (MinorRevision == NULL)) {
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + ZeroMem (&Parameters, sizeof (Parameters));
> +
> + /*
> + Cf. [1], 2.1 TRNG_VERSION
> + Function ID (W0) 0x8400_0050
> + Parameters
> + W1-W7 Reserved (MBZ)
> + Returns
> + Success (W0 > 0) W0[31] MBZ
> + W0[30:16] Major revision
> + W0[15:0] Minor revision
> + W1 - W3 Reserved (MBZ)
> + Error (W0 < 0)
> + NOT_SUPPORTED Function not implemented
> + */
I have a comment on the placement of API descriptions further down.
> + Parameters.Arg0 = FID_TRNG_VERSION;
> + ArmCallMonitor (&Parameters);
> +
> + Revision = (INT32)Parameters.Arg0;
> + // Convert status codes to EFI status codes.
> + Status = TrngStatusToEfiStatus (Revision);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + *MinorRevision = (Revision & TRNG_REV_MINOR_MASK);
> + *MajorRevision = ((Revision >> TRNG_REV_MAJOR_SHIFT) & TRNG_REV_MAJOR_MASK);
> + return RETURN_SUCCESS;
> +}
> +
> +#ifndef MDEPKG_NDEBUG
> +/** Get the features supported by the TRNG backend.
> +
> + The caller can determine if functions defined in the TRNG ABI are
> + present in the ABI implementation.
> +
> + @param [in] FunctionId Function Id.
> + @param [out] Capability Function specific capability if present
> + otherwise Zero is returned.
> +
> + @retval RETURN_SUCCESS The function completed successfully.
> + @retval RETURN_INVALID_PARAMETER Invalid parameter.
> + @retval RETURN_UNSUPPORTED Function not implemented.
> +**/
> +STATIC
> +RETURN_STATUS
> +EFIAPI
> +GetTrngFeatures (
> + IN CONST UINT32 FunctionId,
> + OUT UINT32 *Capability OPTIONAL
> + )
> +{
> + ARM_MONITOR_ARGS Parameters;
> +
> + ZeroMem (&Parameters, sizeof (Parameters));
> +
> + /*
> + Cf. [1], Section 2.2 TRNG_FEATURES
> + Function ID (W0) 0x8400_0051
> + Parameters
> + W1 trng_func_id
> + W2-W7 Reserved (MBZ)
> + Returns
> + Success (W0 >= 0)
> + SUCCESS Function is implemented.
> + > 0 Function is implemented and
> + has specific capabilities,
> + see function definition.
> + Error (W0 < 0)
> + NOT_SUPPORTED Function with FID=trng_func_id
> + is not implemented
> + */
I have a comment on the placement of API descriptions further down.
> + Parameters.Arg0 = FID_TRNG_FEATURES;
> + Parameters.Arg1 = FunctionId;
> + ArmCallMonitor (&Parameters);
> + if (Parameters.Arg0 < TRNG_STATUS_SUCCESS) {
> + return RETURN_UNSUPPORTED;
> + }
> +
> + if (Capability != NULL) {
> + *Capability = Parameters.Arg0;
> + }
> +
> + return RETURN_SUCCESS;
> +}
> +#endif //MDEPKG_NDEBUG
> +
> +/** Get the UUID of the TRNG backend.
> +
> + A TRNG may be implemented by the system firmware, in which case this
> + function shall return the UUID of the TRNG backend.
> + Returning the TRNG UUID is optional and if not implemented, RETURN_UNSUPPORTED
> + shall be returned.
> +
> + Note: The caller must not rely on the returned UUID as a trustworthy TRNG
> + Back end identity
> +
> + @param [out] Guid UUID of the TRNG backend.
> +
> + @retval RETURN_SUCCESS The function completed successfully.
> + @retval RETURN_INVALID_PARAMETER Invalid parameter.
> + @retval RETURN_UNSUPPORTED Function not implemented.
> +**/
> +RETURN_STATUS
> +EFIAPI
> +GetTrngUuid (
> + OUT GUID *Guid
> + )
> +{
> + RETURN_STATUS Status;
> + ARM_MONITOR_ARGS Parameters;
> +
> + ZeroMem (&Parameters, sizeof (Parameters));
> +
> + /*
> + Cf. [1], Section 2.3 TRNG_GET_UUID
> + Function ID (W0) 0x8400_0052
> + Parameters
> + W1-W7 Reserved (MBZ)
> + Returns
> + Success (W0 != -1)
> + W0 UUID[31:0]
> + W1 UUID[63:32]
> + W2 UUID[95:64]
> + W3 UUID[127:96]
> + Error (W0 = -1)
> + W0 NOT_SUPPORTED
> + */
> + Parameters.Arg0 = FID_TRNG_GET_UUID;
> + ArmCallMonitor (&Parameters);
> +
> + // Convert status codes to EFI status codes.
> + Status = TrngStatusToEfiStatus ((INT32)Parameters.Arg0);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Guid->Data1 = (Parameters.Arg0 & MAX_UINT32);
> + Guid->Data2 = (Parameters.Arg1 & MAX_UINT16);
> + Guid->Data3 = ((Parameters.Arg1 >> 16) & MAX_UINT16);
> +
> + Guid->Data4[0] = (Parameters.Arg2 & MAX_UINT8);
> + Guid->Data4[1] = ((Parameters.Arg2 >> 8) & MAX_UINT8);
> + Guid->Data4[2] = ((Parameters.Arg2 >> 16) & MAX_UINT8);
> + Guid->Data4[3] = ((Parameters.Arg2 >> 24) & MAX_UINT8);
> +
> + Guid->Data4[4] = (Parameters.Arg3 & MAX_UINT8);
> + Guid->Data4[5] = ((Parameters.Arg3 >> 8) & MAX_UINT8);
> + Guid->Data4[6] = ((Parameters.Arg3 >> 16) & MAX_UINT8);
> + Guid->Data4[7] = ((Parameters.Arg3 >> 24) & MAX_UINT8);
> +
> + DEBUG ((DEBUG_INFO, "FW-TRNG: UUID %g\n", Guid));
> +
> + return RETURN_SUCCESS;
> +}
> +
> +/** Returns maximum number of entropy bits that can be returned in a single
> + call.
> +
> + @return Returns the maximum number of Entropy bits that can be returned
> + in a single call to GetEntropy().
> +**/
> +UINTN
> +EFIAPI
> +GetTrngMaxSupportedEntropyBits (
> + VOID
> + )
> +{
> + return MAX_ENTROPY_BITS;
> +}
> +
> +/** Returns N bits of conditioned entropy.
> +
> + See [3] Section 2.3.1 GetEntropy: An Interface to the Entropy Source
> + GetEntropy
> + Input:
> + bits_of_entropy: the requested amount of entropy
> + Output:
> + entropy_bitstring: The string that provides the requested entropy.
> + status: A Boolean value that is TRUE if the request has been satisfied,
> + and is FALSE otherwise.
> +
> + Note: In this implementation this function returns a status code instead
> + of a boolean value.
> + This is also compatible with the definition of Get_Entropy, see [2]
> + Section 7.4 Entropy Source Calls.
> + (status, entropy_bitstring) = Get_Entropy (
> + requested_entropy,
> + max_length
> + )
> +
> + @param [in] EntropyBits Number of entropy bits requested.
> + @param [out] Buffer Buffer to return the entropy bits.
> + @param [in] BufferSize Size of the Buffer in bytes.
> +
> + @retval RETURN_SUCCESS The function completed successfully.
> + @retval RETURN_INVALID_PARAMETER Invalid parameter.
> + @retval RETURN_UNSUPPORTED Function not implemented.
> + @retval RETURN_BAD_BUFFER_SIZE Buffer size is too small.
> + @retval RETURN_NOT_READY No Entropy available.
> +**/
> +RETURN_STATUS
> +EFIAPI
> +GetEntropy (
> + IN CONST UINTN EntropyBits,
> + OUT UINT8 *Buffer,
> + IN CONST UINTN BufferSize
> + )
> +{
> + RETURN_STATUS Status;
> + ARM_MONITOR_ARGS Parameters;
> + UINTN EntropyBytes;
> + UINTN LastValidBits;
> + UINTN ArgSelector;
> + UINTN BytesToClear;
> +
> + // [1] Section 2.4.3 Caller responsibilities.
> + // The caller cannot request more than MAX_BITS bits of conditioned
> + // entropy per call.
Comment is redundant, code is clearer without it.
> + if ((EntropyBits == 0) || (EntropyBits > MAX_ENTROPY_BITS)) {
> + return RETURN_INVALID_PARAMETER;
> + }
> +
> + EntropyBytes = (EntropyBits + 7) >> 3;
> + if (EntropyBytes > BufferSize) {
Not for later: we're verifying the value of EntropyBytes here - if
there are more aspects of it that need verifying, that should also be
done here.
> + return RETURN_BAD_BUFFER_SIZE;
> + }
> +
> + ZeroMem (Buffer, BufferSize);
> + ZeroMem (&Parameters, sizeof (Parameters));
> +
> + /*
> + Cf. [1], Section 2.4 TRNG_RND
> + Function ID (W0) 0x8400_0053
> + 0xC400_0053
> + SMC32 Parameters
> + W1 N bits of entropy (1 6 N 6 96)
> + W2-W7 Reserved (MBZ)
> + SMC64 Parameters
> + X1 N bits of entropy (1 6 N 6 192)
> + X2-X7 Reserved (MBZ)
> + SMC32 Returns
> + Success (W0 = 0):
> + W0 MBZ
> + W1 Entropy[95:64]
> + W2 Entropy[63:32]
> + W3 Entropy[31:0]
> + Error (W0 < 0)
> + W0 NOT_SUPPORTED
> + NO_ENTROPY
> + INVALID_PARAMETERS
> + W1 - W3 Reserved (MBZ)
> + SMC64 Returns
> + Success (X0 = 0):
> + X0 MBZ
> + X1 Entropy[191:128]
> + X2 Entropy[127:64]
> + X3 Entropy[63:0]
> + Error (X0 < 0)
> + X0 NOT_SUPPORTED
> + NO_ENTROPY
> + INVALID_PARAMETERS
> + X1 - X3 Reserved (MBZ)
> + */
The above comment block completely wrecks the readability of the
function.
Would suggest putting it in the header file describing the monitor
call. For our SIP SVC calls, we've done this in the following form:
/*
* SMC call to retrieve number of CPUs present in the system.
* Input values:
* x0: NUVIA_SIP_GET_NUM_CPUS
* Return values:
* x0: SMC_OK
* x1: Number of CPUs present
*/
#define NUVIA_SIP_GET_NUM_CPUS SIP_FUNCTION_ID(0x20)
(Where SIP_FUNCTION_ID is one of a set of macros I should submit for
addition to ArmStdSmc.h)
> + Parameters.Arg0 = FID_TRNG_RND;
> + Parameters.Arg1 = EntropyBits;
> + ArmCallMonitor (&Parameters);
> +
> + // Convert status codes to EFI status codes.
Function name already says this, comment redundant.
> + Status = TrngStatusToEfiStatus ((INT32)Parameters.Arg0);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
>From here
> + // Extract Data
> + // ArgSelector = ((EntropyBytes + 3) >> 2); for AArch32
> + // ArgSelector = ((EntropyBytes + 7) >> 3); for AArch64
> + // ((sizeof (UINTN) >> 2) + 1) is 3 or 2 depending on size of UINTN
> + ArgSelector = ((EntropyBytes + (sizeof (UINTN) - 1)) >>
> + ((sizeof (UINTN) >> 2) + 1));
> +
> + switch (ArgSelector) {
> + case 3:
> + CopyMem (&Buffer[(sizeof (UINTN) * 2)], &Parameters.Arg1, sizeof (UINTN));
> +
> + case 2:
> + CopyMem (&Buffer[sizeof (UINTN)], &Parameters.Arg2, sizeof (UINTN));
> +
> + case 1:
> + CopyMem (&Buffer[0], &Parameters.Arg3, sizeof (UINTN));
> + break;
> +
> + default:
> + ASSERT (0);
> + return RETURN_INVALID_PARAMETER;
> + } // switch
to here ... I'm not convinced you yourself would be able to read or
explain this code a few months down the line.
Is there a strong reason for why Buffer cannot be a UINTN *?
I think what this code is doing can equally be written as:
Buffer[0] = Parameters.Arg3;
if ((EntropyBytes / sizeof (UINTN)) > 1) {
Buffer[1] = Parameters.Arg2;
}
if ((EntropyBytes / sizeof (UINTN)) > 2) {
Buffer[2] = Parameters.Arg1;
}
> +
> +
> + // [1] Section 2.4.3 Caller responsibilities.
> + // The caller must ensure that only the value in Entropy[N-1:0] is consumed
> + // and that the remaining bits in Entropy[MAX_BITS-1:N] are ignored.
> + // Therefore, Clear the unused upper bytes.
This is source code, not the specification.
// Mask off any unused top bytes, in accordance with specification
is sufficient as a comment.
/
Leif
> + BytesToClear = (sizeof (UINTN) * ArgSelector) - EntropyBytes;
> + if (BytesToClear != 0) {
> + ZeroMem (&Buffer[EntropyBytes], BytesToClear);
> + }
> +
> + // Clear the unused MSB bits of the last byte.
> + LastValidBits = EntropyBits & 0x7;
> + if (LastValidBits != 0) {
> + Buffer[EntropyBytes - 1] &= (0xFF >> (8 - LastValidBits));
> + }
> +
> + return Status;
> +}
> +
> +/** The constructor checks that the FW-TRNG interface is supported
> + by the host firmware.
> +
> + It will ASSERT() if FW-TRNG is not supported.
> + It will always return RETURN_SUCCESS.
> +
> + @retval RETURN_SUCCESS The constructor always returns RETURN_SUCCESS.
> +**/
> +RETURN_STATUS
> +EFIAPI
> +ArmFwTrngLibConstructor (
> + VOID
> + )
> +{
> + RETURN_STATUS Status;
> + UINT16 MajorRev;
> + UINT16 MinorRev;
> + GUID Guid;
> +
> + Status = GetTrngVersion (&MajorRev, &MinorRev);
> + if (EFI_ERROR (Status)) {
> + return RETURN_SUCCESS;
> + }
> +
> +#ifndef MDEPKG_NDEBUG
> + // Check that the required features are present.
> + Status = GetTrngFeatures (FID_TRNG_RND, NULL);
> + if (EFI_ERROR (Status)) {
> + return RETURN_SUCCESS;
> + }
> +
> + // Check if TRNG UUID is supported and if so trace the GUID.
> + Status = GetTrngFeatures (FID_TRNG_GET_UUID, NULL);
> + if (EFI_ERROR (Status)) {
> + return RETURN_SUCCESS;
> + }
> +#endif
> +
> + Status = GetTrngUuid (&Guid);
> + if (EFI_ERROR (Status)) {
> + return RETURN_SUCCESS;
> + }
> +
> + DEBUG ((
> + DEBUG_INFO,
> + "FW-TRNG: Version %d.%d, GUID {%g}\n",
> + MajorRev,
> + MinorRev,
> + Guid
> + ));
> +
> + return RETURN_SUCCESS;
> +}
> diff --git a/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf
> new file mode 100644
> index 0000000000000000000000000000000000000000..4b2c58251fbe8fbcb5af308736db014e8d954720
> --- /dev/null
> +++ b/ArmPkg/Library/ArmFwTrngLib/ArmFwTrngLib.inf
> @@ -0,0 +1,34 @@
> +## @file
> +# Arm Firmware TRNG interface library.
> +#
> +# Copyright (c) 2021, Arm Limited. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +##
> +
> +[Defines]
> + INF_VERSION = 0x0001001B
> + BASE_NAME = ArmFwTrngLib
> + FILE_GUID = 10DE97C9-28E4-4C9B-A53E-8D7D1B0DD4E0
> + VERSION_STRING = 1.0
> + MODULE_TYPE = BASE
> + LIBRARY_CLASS = TrngLib
> + CONSTRUCTOR = ArmFwTrngLibConstructor
> +
> +[Sources]
> + ArmFwTrngDefs.h
> + ArmFwTrngLib.c
> +
> +[Packages]
> + ArmPkg/ArmPkg.dec
> + MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> + ArmSmcLib
> + ArmHvcLib
> + BaseLib
> + BaseMemoryLib
> +
> +[Pcd]
> + gArmTokenSpaceGuid.PcdMonitorConduitHvc
> +
> --
> 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
>
>
>
>
>
>
next prev parent reply other threads:[~2021-11-24 13:02 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-16 11:32 [PATCH v2 0/8] Add Raw algorithm support using Arm FW-TRNG interface Sami Mujawar
2021-11-16 11:32 ` [PATCH v2 1/8] MdePkg: Definition for TRNG library class interface Sami Mujawar
2021-11-16 11:32 ` [PATCH v2 2/8] ArmPkg: PCD to select conduit for monitor calls Sami Mujawar
2021-11-24 12:07 ` Leif Lindholm
2021-11-24 13:03 ` Ard Biesheuvel
2021-11-24 13:05 ` Leif Lindholm
2021-11-24 13:07 ` Ard Biesheuvel
2021-11-24 13:25 ` Leif Lindholm
2021-11-16 11:32 ` [PATCH v2 3/8] ArmPkg: Add Arm Firmware TRNG library Sami Mujawar
2021-11-24 13:01 ` Leif Lindholm [this message]
2021-11-25 15:23 ` [edk2-devel] " Sami Mujawar
2022-03-24 9:46 ` PierreGondois
[not found] ` <80941d66-5d31-053f-388a-95efe5dbbfdf@arm.com>
2022-03-24 14:56 ` PierreGondois
2022-03-24 18:12 ` Leif Lindholm
2021-11-16 11:32 ` [PATCH v2 4/8] MdePkg: Add NULL instance of TRNG Library Sami Mujawar
2021-11-16 11:32 ` [PATCH v2 5/8] SecurityPkg: Rename RdRandGenerateEntropy to common name Sami Mujawar
2021-11-16 11:32 ` [PATCH v2 6/8] SecurityPkg: Restructure checks in RngGetInfo Sami Mujawar
2021-11-16 11:32 ` [PATCH v2 7/8] SecurityPkg: Add RawAlgorithm support using TRNG library Sami Mujawar
2021-11-16 11:33 ` [PATCH v2 8/8] ArmVirtPkg: Kvmtool: Add RNG support using FW-TRNG interface Sami Mujawar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YZ43w/aKaDH99wjc@leviathan \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox