From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-oi1-f173.google.com (mail-oi1-f173.google.com [209.85.167.173]) by mx.groups.io with SMTP id smtpd.web08.11014.1620397412450893905 for ; Fri, 07 May 2021 07:23:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nuviainc-com.20150623.gappssmtp.com header.s=20150623 header.b=PYQ6dytj; spf=pass (domain: nuviainc.com, ip: 209.85.167.173, mailfrom: rebecca@nuviainc.com) Received: by mail-oi1-f173.google.com with SMTP id v22so3975178oic.2 for ; Fri, 07 May 2021 07:23:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuviainc-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xjzmsnjhQO+vAvOgVDzgHiqThsiOz+jlvFN1E+6vvO8=; b=PYQ6dytj7dDvUh5LfbKy8yCnV8/IESIYGZkMy4SrC0yQcxTeH04zy0rSHwLOUPck5M NxONmpXKqih0NRYKifKEpguDBGkIIEc5/dCusSsHKSPCECHtVWdk7oCiMKFtBUIPXVxn nHT2mRwIAma50cuLFa+4NFPvuAAP8rMJwWfzvVbbx3YQ1Ae+FU7mlmSx/GUlY0uLqUUZ LHwQWFI7hbPoDu7ef/eQUC6CnKERay+ZzK1n8Aq3YDN9gck4hww18FAPy461qMQ8buLm SeEWR8v1nRKABfwzhBN0Vem/pps2PnXGkJioLa1iJDitig4cYyLwE3naf229lXThcYWU mL8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xjzmsnjhQO+vAvOgVDzgHiqThsiOz+jlvFN1E+6vvO8=; b=MNLBiKEpfVZoR0vdjzmUdSETKBVi7J1c0UvAwibwzTqzUxoi5bNiasQdp5L52KjO5F hPSj1BxRWjW2Dv9oeHGQ0sAgauekLZcjArXwg3uOq2ksfEI9wrmwTmdwWI9xZsOGhT1C LxJ5ZzqrpgO5UKRSQmCsbq/iZuMFwd/QqP/CJq9w6eyMkUBLk+0k1d4K2lZbANzME/iE mt90kEYOIzEG9Jc+cX2dwHpKgSj43ZemHUTAIiX6PNIvTfIcdIDttqHseeAEfOas+OFP mrh8euQW3sh4FSDqhrIEbhiNgNxkV6Kkmwzj838fT6n9JhxzzrntitSjo/wdZIwNJSL3 wVCw== X-Gm-Message-State: AOAM53088V53ta3ly3GPY8dN+PqWKG4V4wgT7vY9/o8/8Wyg6eOtFuuW EXAkO7jAI1oM/Ntlh0TCcdhle9QhyZLb+p5+P4Da8vkJnIkAQlTT+5pL27064o0q82ZMF/OUj7u Qyoo2Z4rN4kkr4qyUb5syaQEtDENdbcyFoIsyLBYhJkCDvmHfW1IdwfvnCCtKNKbO39m69A== X-Google-Smtp-Source: ABdhPJxhPfaCPVBwJfw9xcYwwh7U/o0m29Fg9sSO/zi4OwdkCFqnbklNS8DpxcPi9ZhY4iBR3lJR0g== X-Received: by 2002:aca:b5c4:: with SMTP id e187mr7417520oif.149.1620397411000; Fri, 07 May 2021 07:23:31 -0700 (PDT) Return-Path: Received: from cube.nuviainc.com (c-174-52-16-57.hsd1.ut.comcast.net. [174.52.16.57]) by smtp.gmail.com with ESMTPSA id 88sm1215641otx.2.2021.05.07.07.23.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 May 2021 07:23:30 -0700 (PDT) From: "Rebecca Cran" To: devel@edk2.groups.io, Jiewen Yao , Jian J Wang , Michael D Kinney , Liming Gao , Zhiguang Liu , Ard Biesheuvel , Sami Mujawar Cc: Rebecca Cran Subject: [PATCH v2 1/2] MdePkg/BaseRngLib: Add support for ARMv8.5 RNG instructions Date: Fri, 7 May 2021 08:23:14 -0600 Message-Id: <20210507142315.679-2-rebecca@nuviainc.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20210507142315.679-1-rebecca@nuviainc.com> References: <20210507142315.679-1-rebecca@nuviainc.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Make BaseRngLib more generic by moving x86 specific functionality from BaseRng.c into Rand/RdRand.c, and adding AArch64/Rndr.c, which supports the optional ARMv8.5 RNG instructions RNDR and RNDRRS that are a part of FEAT_RNG. Add support for the optional ARMv8.5 RNDR and RNDRRS instructions that are a part of FEAT_RNG to BaseLib, and add a function to read the ISAR0 register which indicates whether the CPU supports FEAT_RNG. Signed-off-by: Rebecca Cran --- MdePkg/MdePkg.dec | 9 +- MdePkg/MdePkg.dsc | 4 +- MdePkg/Library/BaseRngLib/BaseRngLib.inf | 23 +++- MdePkg/Library/BaseRngLib/AArch64/ArmRng.h | 59 +++++++++ MdePkg/Library/BaseRngLib/BaseRngLibInternals.h | 79 +++++++++++ MdePkg/Library/BaseRngLib/AArch64/Rndr.c | 139 ++++++++++++++++++++ MdePkg/Library/BaseRngLib/BaseRng.c | 87 ++++++------ MdePkg/Library/BaseRngLib/Rand/RdRand.c | 131 ++++++++++++++++++ MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S | 31 +++++ MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm | 30 +++++ MdePkg/Library/BaseRngLib/AArch64/ArmRng.S | 61 +++++++++ MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm | 64 +++++++++ MdePkg/Library/BaseRngLib/BaseRngLib.uni | 6 +- 13 files changed, 669 insertions(+), 54 deletions(-) diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 8965e903e093..b49f88d8e18f 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -267,6 +267,11 @@ [LibraryClasses] # RegisterFilterLib|Include/Library/RegisterFilterLib.h +[LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64] + ## @libraryclass Provides services to generate random number. + # + RngLib|Include/Library/RngLib.h + [LibraryClasses.IA32, LibraryClasses.X64] ## @libraryclass Abstracts both S/W SMI generation and detection. ## @@ -288,10 +293,6 @@ [LibraryClasses.IA32, LibraryClasses.X64] # SmmPeriodicSmiLib|Include/Library/SmmPeriodicSmiLib.h - ## @libraryclass Provides services to generate random number. - # - RngLib|Include/Library/RngLib.h - ## @libraryclass Provides services to log the SMI handler registration. SmiHandlerProfileLib|Include/Library/SmiHandlerProfileLib.h diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index d363419006ea..a94959169b2f 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -145,6 +145,9 @@ [Components.IA32, Components.X64, Components.ARM, Components.AARCH64] MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibSmm.inf MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLibUefiShell.inf +[Components.IA32, Components.X64, Components.AARCH64] + MdePkg/Library/BaseRngLib/BaseRngLib.inf + [Components.IA32, Components.X64] MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsicSev.inf @@ -168,7 +171,6 @@ [Components.IA32, Components.X64] MdePkg/Library/BaseS3StallLib/BaseS3StallLib.inf MdePkg/Library/SmmMemLib/SmmMemLib.inf MdePkg/Library/SmmIoLib/SmmIoLib.inf - MdePkg/Library/BaseRngLib/BaseRngLib.inf MdePkg/Library/SmmPciExpressLib/SmmPciExpressLib.inf MdePkg/Library/SmiHandlerProfileLibNull/SmiHandlerProfileLibNull.inf MdePkg/Library/MmServicesTableLib/MmServicesTableLib.inf diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.inf b/MdePkg/Library/BaseRngLib/BaseRngLib.inf index 31740751c69c..1fcceb941495 100644 --- a/MdePkg/Library/BaseRngLib/BaseRngLib.inf +++ b/MdePkg/Library/BaseRngLib/BaseRngLib.inf @@ -1,9 +1,10 @@ ## @file # Instance of RNG (Random Number Generator) Library. # -# BaseRng Library that uses CPU RdRand instruction access to provide -# high-quality random numbers. +# BaseRng Library that uses CPU RNG instructions (e.g. RdRand) to +# provide random numbers. # +# Copyright (c) 2021, NUVIA Inc. All rights reserved.
# Copyright (c) 2015, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent @@ -22,11 +23,25 @@ [Defines] CONSTRUCTOR = BaseRngLibConstructor # -# VALID_ARCHITECTURES = IA32 X64 +# VALID_ARCHITECTURES = IA32 X64 AARCH64 # -[Sources.Ia32, Sources.X64] +[Sources] BaseRng.c + BaseRngLibInternals.h + +[Sources.Ia32, Sources.X64] + Rand/RdRand.c + +[Sources.AARCH64] + AArch64/Rndr.c + AArch64/ArmRng.h + + AArch64/ArmReadIdIsar0.S | GCC + AArch64/ArmRng.S | GCC + + AArch64/ArmReadIdIsar0.asm | MSFT + AArch64/ArmRng.asm | MSFT [Packages] MdePkg/MdePkg.dec diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h new file mode 100644 index 000000000000..595bd87ba60c --- /dev/null +++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.h @@ -0,0 +1,59 @@ +/** @file + Random number generator service that uses the RNDR instruction + to provide pseudorandom numbers. + + Copyright (c) 2021, NUVIA Inc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef ARM_RNG_H_ +#define ARM_RNG_H_ + +/** + Generates a random number using RNDR. + Returns TRUE on success; FALSE on failure. + + @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 +ArmRndr ( + OUT UINT64 *Rand + ); + +/** + Generates a random number using RNDRRS. + Returns TRUE on success; FALSE on failure. + + @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 +ArmRndrrs ( + OUT UINT64 *Rand + ); + +/** + Reads the ID_AA64ISAR0 Register. + + @return The contents of the ID_AA64ISAR0 register. + +**/ +UINT64 +EFIAPI +ArmReadIdIsar0 ( + VOID + ); + +#endif /* ARM_RNG_H_ */ + diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h new file mode 100644 index 000000000000..338ba6ea5313 --- /dev/null +++ b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h @@ -0,0 +1,79 @@ +/** @file + + Architecture specific interface to RNG functionality. + +Copyright (c) 2021, NUVIA Inc. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef BASE_RNGLIB_INTERNALS_H_ + +/** + Generates a 16-bit random number. + + @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 +ArchGetRandomNumber16 ( + OUT UINT16 *Rand + ); + +/** + Generates a 32-bit random number. + + @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 +ArchGetRandomNumber32 ( + OUT UINT32 *Rand + ); + +/** + Generates a 64-bit random number. + + @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 +ArchGetRandomNumber64 ( + OUT UINT64 *Rand + ); + +/** + Checks whether the RNG instruction is supported. + + @retval TRUE RNG instruction is supported. + @retval FALSE RNG instruction is not supported. + +**/ +BOOLEAN +EFIAPI +ArchIsRngSupported ( + VOID + ); + +#if defined (MDE_CPU_AARCH64) + +// RNDR, Random Number +#define RNDR S3_3_C2_C4_0 +#define RNDRRS S3_3_C2_C4_1 + +#endif + +#endif // BASE_RNGLIB_INTERNALS_H_ diff --git a/MdePkg/Library/BaseRngLib/AArch64/Rndr.c b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c new file mode 100644 index 000000000000..d658ad2bea89 --- /dev/null +++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c @@ -0,0 +1,139 @@ +/** @file + Random number generator service that uses the RNDR instruction + to provide pseudorandom numbers. + + Copyright (c) 2021, NUVIA Inc. All rights reserved.
+ Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +#include "ArmRng.h" +#include "BaseRngLibInternals.h" + +STATIC BOOLEAN mRndrSupported; + +// +// Bit mask used to determine if RNDR instruction is supported. +// +#define RNDR_MASK ((UINT64)MAX_UINT16 << 60U) + +/** + The constructor function checks whether or not RNDR instruction is supported + by the host hardware. + + The constructor function checks whether or not RNDR instruction is supported. + It will ASSERT() if RNDR instruction is not supported. + It will always return EFI_SUCCESS. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +BaseRngLibConstructor ( + VOID + ) +{ + UINT64 Isar0; + // + // Determine RNDR support by examining bits 63:60 of the ISAR0 register returned by + // MSR. A non-zero value indicates that the processor supports the RNDR instruction. + // + Isar0 = ArmReadIdIsar0 (); + ASSERT ((Isar0 & RNDR_MASK) != 0); + + mRndrSupported = ((Isar0 & RNDR_MASK) != 0); + + return EFI_SUCCESS; +} + +/** + Generates a 16-bit random number. + + @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 +ArchGetRandomNumber16 ( + OUT UINT16 *Rand + ) +{ + UINT64 Rand64; + + if (ArchGetRandomNumber64 (&Rand64)) { + *Rand = Rand64 & MAX_UINT16; + return TRUE; + } + + return FALSE; +} + +/** + Generates a 32-bit random number. + + @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 +ArchGetRandomNumber32 ( + OUT UINT32 *Rand + ) +{ + UINT64 Rand64; + + if (ArchGetRandomNumber64 (&Rand64)) { + *Rand = Rand64 & MAX_UINT32; + return TRUE; + } + + return FALSE; +} + +/** + Generates a 64-bit random number. + + @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 +ArchGetRandomNumber64 ( + OUT UINT64 *Rand + ) +{ + return ArmRndr (Rand); +} + +/** + Checks whether RNDR and RNDRRS (FEAT_RNG) are supported. + + @retval TRUE RNDR and RNDRRS are supported. + @retval FALSE RNDR and RNDRRS are not supported. + +**/ +BOOLEAN +EFIAPI +ArchIsRngSupported ( + VOID + ) +{ + return mRndrSupported; +} diff --git a/MdePkg/Library/BaseRngLib/BaseRng.c b/MdePkg/Library/BaseRngLib/BaseRng.c index 7ad7aec9d38f..5b63d8f7146b 100644 --- a/MdePkg/Library/BaseRngLib/BaseRng.c +++ b/MdePkg/Library/BaseRngLib/BaseRng.c @@ -1,8 +1,10 @@ /** @file - Random number generator services that uses RdRand instruction access - to provide high-quality random numbers. + Random number generator services that uses CPU RNG instructions to + provide random numbers. +Copyright (c) 2021, NUVIA Inc. All rights reserved.
Copyright (c) 2015, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -10,46 +12,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include -// -// Bit mask used to determine if RdRand instruction is supported. -// -#define RDRAND_MASK BIT30 +#include "BaseRngLibInternals.h" // // Limited retry number when valid random data is returned. // Uses the recommended value defined in Section 7.3.17 of "Intel 64 and IA-32 -// Architectures Software Developer's Mannual". +// Architectures Software Developer's Manual". // -#define RDRAND_RETRY_LIMIT 10 +#define GETRANDOM_RETRY_LIMIT 10 -/** - The constructor function checks whether or not RDRAND instruction is supported - by the host hardware. - - The constructor function checks whether or not RDRAND instruction is supported. - It will ASSERT() if RDRAND instruction is not supported. - It will always return RETURN_SUCCESS. - - @retval RETURN_SUCCESS The constructor always returns EFI_SUCCESS. - -**/ -RETURN_STATUS -EFIAPI -BaseRngLibConstructor ( - VOID - ) -{ - UINT32 RegEcx; - - // - // Determine RDRAND support by examining bit 30 of the ECX register returned by - // CPUID. A value of 1 indicates that processor support RDRAND instruction. - // - AsmCpuid (1, 0, 0, &RegEcx, 0); - ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK); - - return RETURN_SUCCESS; -} /** Generates a 16-bit random number. @@ -72,11 +43,19 @@ GetRandomNumber16 ( ASSERT (Rand != NULL); + if (Rand == NULL) { + return FALSE; + } + + if (!ArchIsRngSupported ()) { + return FALSE; + } + // // A loop to fetch a 16 bit random value with a retry count limit. // - for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) { - if (AsmRdRand16 (Rand)) { + for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) { + if (ArchGetRandomNumber16 (Rand)) { return TRUE; } } @@ -105,11 +84,19 @@ GetRandomNumber32 ( ASSERT (Rand != NULL); + if (Rand == NULL) { + return FALSE; + } + + if (!ArchIsRngSupported ()) { + return FALSE; + } + // // A loop to fetch a 32 bit random value with a retry count limit. // - for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) { - if (AsmRdRand32 (Rand)) { + for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) { + if (ArchGetRandomNumber32 (Rand)) { return TRUE; } } @@ -138,11 +125,19 @@ GetRandomNumber64 ( ASSERT (Rand != NULL); + if (Rand == NULL) { + return FALSE; + } + + if (!ArchIsRngSupported ()) { + return FALSE; + } + // // A loop to fetch a 64 bit random value with a retry count limit. // - for (Index = 0; Index < RDRAND_RETRY_LIMIT; Index++) { - if (AsmRdRand64 (Rand)) { + for (Index = 0; Index < GETRANDOM_RETRY_LIMIT; Index++) { + if (ArchGetRandomNumber64 (Rand)) { return TRUE; } } @@ -169,6 +164,14 @@ GetRandomNumber128 ( { ASSERT (Rand != NULL); + if (Rand == NULL) { + return FALSE; + } + + if (!ArchIsRngSupported ()) { + return FALSE; + } + // // Read first 64 bits // diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c b/MdePkg/Library/BaseRngLib/Rand/RdRand.c new file mode 100644 index 000000000000..09fb875ac3f9 --- /dev/null +++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c @@ -0,0 +1,131 @@ +/** @file + Random number generator services that uses RdRand instruction access + to provide high-quality random numbers. + +Copyright (c) 2021, NUVIA Inc. All rights reserved.
+Copyright (c) 2015, Intel Corporation. All rights reserved.
+ +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +#include "BaseRngLibInternals.h" + +// +// Bit mask used to determine if RdRand instruction is supported. +// +#define RDRAND_MASK BIT30 + + +STATIC BOOLEAN mRdRandSupported; + +/** + The constructor function checks whether or not RDRAND instruction is supported + by the host hardware. + + The constructor function checks whether or not RDRAND instruction is supported. + It will ASSERT() if RDRAND instruction is not supported. + It will always return EFI_SUCCESS. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +BaseRngLibConstructor ( + VOID + ) +{ + UINT32 RegEcx; + + // + // Determine RDRAND support by examining bit 30 of the ECX register returned by + // CPUID. A value of 1 indicates that processor support RDRAND instruction. + // + AsmCpuid (1, 0, 0, &RegEcx, 0); + ASSERT ((RegEcx & RDRAND_MASK) == RDRAND_MASK); + + mRdRandSupported = ((RegEcx & RDRAND_MASK) == RDRAND_MASK); + + return EFI_SUCCESS; +} + +/** + Generates a 16-bit random number. + + @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 +ArchGetRandomNumber16 ( + OUT UINT16 *Rand + ) +{ + return AsmRdRand16 (Rand); +} + +/** + Generates a 32-bit random number. + + @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 +ArchGetRandomNumber32 ( + OUT UINT32 *Rand + ) +{ + return AsmRdRand32 (Rand); +} + +/** + Generates a 64-bit random number. + + @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 +ArchGetRandomNumber64 ( + OUT UINT64 *Rand + ) +{ + return AsmRdRand64 (Rand); +} + +/** + Checks whether RDRAND is supported. + + @retval TRUE RDRAND is supported. + @retval FALSE RDRAND is not supported. + +**/ +BOOLEAN +EFIAPI +ArchIsRngSupported ( + VOID + ) +{ + /* + Existing software depends on this always returning TRUE, so for + now hard-code it. + + return mRdRandSupported; + */ + return TRUE; +} diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S new file mode 100644 index 000000000000..82a00d362212 --- /dev/null +++ b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.S @@ -0,0 +1,31 @@ +#------------------------------------------------------------------------------ +# +# ArmReadIdIsar0() for AArch64 +# +# Copyright (c) 2021, NUVIA Inc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + +.text +.p2align 2 +GCC_ASM_EXPORT(ArmReadIdIsar0) + +#/** +# Reads the ID_AA64ISAR0 Register. +# +# @return The contents of the ID_AA64ISAR0 register. +# +#**/ +#UINT64 +#EFIAPI +#ArmReadIdIsar0 ( +# VOID +# ); +# +ASM_PFX(ArmReadIdIsar0): + mrs x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register + ret + + diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm new file mode 100644 index 000000000000..1d9f9a808c0c --- /dev/null +++ b/MdePkg/Library/BaseRngLib/AArch64/ArmReadIdIsar0.asm @@ -0,0 +1,30 @@ +;------------------------------------------------------------------------------ +; +; ArmReadIdIsar0() for AArch64 +; +; Copyright (c) 2021, NUVIA Inc. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + + EXPORT ArmReadIdIsar0 + AREA BaseLib_LowLevel, CODE, READONLY + +;/** +; Reads the ID_AA64ISAR0 Register. +; +; @return The contents of the ID_AA64ISAR0 register. +; +;**/ +;UINT64 +;EFIAPI +;ArmReadIdIsar0 ( +; VOID +; ); +; +ArmReadIdIsar0 + mrs x0, id_aa64isar0_el1 // Read ID_AA64ISAR0 Register + ret + + END diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S new file mode 100644 index 000000000000..4b9898dadc52 --- /dev/null +++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.S @@ -0,0 +1,61 @@ +#------------------------------------------------------------------------------ +# +# ArmRndr() and ArmRndrrs() for AArch64 +# +# Copyright (c) 2021, NUVIA Inc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + +#include "BaseRngLibInternals.h" + +.text +.p2align 2 +GCC_ASM_EXPORT(ArmRndr) +GCC_ASM_EXPORT(ArmRndrrs) + +#/** +# Generates a random number using RNDR. +# Returns TRUE on success; FALSE on failure. +# +# @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 +#ArmRndr ( +# OUT UINT64 *Rand +# ); +# +ASM_PFX(ArmRndr): + mrs x1, RNDR + str x1, [x0] + cset x0, ne // RNDR sets NZCV to 0b0100 on failure + ret + + +#/** +# Generates a random number using RNDRRS +# Returns TRUE on success; FALSE on failure. +# +# @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 +#ArmRndrrs ( +# OUT UINT64 *Rand +# ); +# +ASM_PFX(ArmRndrrs): + mrs x1, RNDRRS + str x1, [x0] + cset x0, ne // RNDRRS sets NZCV to 0b0100 on failure + ret diff --git a/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm new file mode 100644 index 000000000000..e3feb56adbcf --- /dev/null +++ b/MdePkg/Library/BaseRngLib/AArch64/ArmRng.asm @@ -0,0 +1,64 @@ +;------------------------------------------------------------------------------ +; +; ArmRndr() and ArmRndrrs() for AArch64 +; +; Copyright (c) 2021, NUVIA Inc. All rights reserved.
+; +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +;------------------------------------------------------------------------------ + +#include "BaseRngLibInternals.h" + + EXPORT ArmRndr + EXPORT ArmRndrrs + AREA BaseLib_LowLevel, CODE, READONLY + + +;/** +; Generates a random number using RNDR. +; Returns TRUE on success; FALSE on failure. +; +; @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 +;ArmRndr ( +; OUT UINT64 *Rand +; ); +; +ArmRndr + mrs x1, RNDR + str x1, [x0] + cset x0, ne // RNDR sets NZCV to 0b0100 on failure + ret + + END + +;/** +; Generates a random number using RNDRRS. +; Returns TRUE on success; FALSE on failure. +; +; @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 +;ArmRndrrs ( +; OUT UINT64 *Rand +; ); +; +ArmRndrrs + mrs x1, RNDRRS + str x1, [x0] + cset x0, ne // RNDRRS sets NZCV to 0b0100 on failure + ret + + END diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.uni b/MdePkg/Library/BaseRngLib/BaseRngLib.uni index f3ed954c5209..de5d4f9dd869 100644 --- a/MdePkg/Library/BaseRngLib/BaseRngLib.uni +++ b/MdePkg/Library/BaseRngLib/BaseRngLib.uni @@ -1,8 +1,8 @@ // /** @file // Instance of RNG (Random Number Generator) Library. // -// BaseRng Library that uses CPU RdRand instruction access to provide -// high-quality random numbers. +// BaseRng Library that uses CPU RNG instructions to provide +// random numbers. // // Copyright (c) 2015, Intel Corporation. All rights reserved.
// @@ -13,5 +13,5 @@ #string STR_MODULE_ABSTRACT #language en-US "Instance of RNG Library" -#string STR_MODULE_DESCRIPTION #language en-US "BaseRng Library that uses CPU RdRand instruction access to provide high-quality random numbers" +#string STR_MODULE_DESCRIPTION #language en-US "BaseRng Library that uses CPU RNG instructions to provide random numbers" -- 2.26.2