public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 0/3] MdePkg,SecurityPkg: Update BaseRngLib and RngDxe to support ARMv8.5 FEAT_RNG
@ 2021-04-28 20:44 Rebecca Cran
  2021-04-28 20:44 ` [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions Rebecca Cran
                   ` (2 more replies)
  0 siblings, 3 replies; 16+ messages in thread
From: Rebecca Cran @ 2021-04-28 20:44 UTC (permalink / raw)
  To: devel
  Cc: Rebecca Cran, Jiewen Yao, Jian J Wang, Michael D Kinney,
	Liming Gao, Zhiguang Liu, Ard Biesheuvel, Sami Mujawar

This is the RngLib|RNDR implementation from page 11 of the "Proposed
update to RNG implementation" presentation from Ard and Sami.

The presentation can be found at:
https://edk2.groups.io/g/devel/files/Designs/2021/0116/EDKII%20-%20Proposed%20update%20to%20RNG%20implementation.pdf

Rebecca Cran (3):
  MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions
  MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86
  SecurityPkg: Add support for RngDxe on AARCH64

 MdePkg/MdePkg.dec                                             |   9 +-
 MdePkg/MdePkg.dsc                                             |   4 +-
 SecurityPkg/SecurityPkg.dsc                                   |  11 +-
 MdePkg/Library/BaseLib/BaseLib.inf                            |   4 +
 MdePkg/Library/BaseRngLib/BaseRngLib.inf                      |  16 ++-
 SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf           |  19 ++-
 MdePkg/Include/Library/BaseLib.h                              |  47 ++++++++
 MdePkg/Library/BaseLib/BaseLibInternals.h                     |   6 +
 MdePkg/Library/BaseRngLib/BaseRngLibInternals.h               |  31 +++++
 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h       |  37 ++++++
 SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h |   0
 SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h  |   0
 SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h    |  88 ++++++++++++++
 MdePkg/Library/BaseRngLib/AArch64/Rndr.c                      | 121 ++++++++++++++++++++
 MdePkg/Library/BaseRngLib/BaseRng.c                           |  55 +++------
 MdePkg/Library/BaseRngLib/Rand/RdRand.c                       | 103 +++++++++++++++++
 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c       |  54 +++++++++
 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c     | 108 +++++++++++++++++
 SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c |   0
 SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c  |   0
 SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c        | 120 +++++++++++++++++++
 SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c             | 117 ++++---------------
 MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S               |  29 +++++
 MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm             |  28 +++++
 MdePkg/Library/BaseLib/AArch64/ArmRng.S                       |  51 +++++++++
 MdePkg/Library/BaseLib/AArch64/ArmRng.asm                     |  55 +++++++++
 MdePkg/Library/BaseRngLib/BaseRngLib.uni                      |   6 +-
 27 files changed, 961 insertions(+), 158 deletions(-)
 create mode 100644 MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
 rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h (100%)
 rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h (100%)
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
 create mode 100644 MdePkg/Library/BaseRngLib/AArch64/Rndr.c
 create mode 100644 MdePkg/Library/BaseRngLib/Rand/RdRand.c
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
 rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c (100%)
 rename SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c (100%)
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
 create mode 100644 MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S
 create mode 100644 MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm
 create mode 100644 MdePkg/Library/BaseLib/AArch64/ArmRng.S
 create mode 100644 MdePkg/Library/BaseLib/AArch64/ArmRng.asm

-- 
2.26.2


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions
  2021-04-28 20:44 [PATCH 0/3] MdePkg,SecurityPkg: Update BaseRngLib and RngDxe to support ARMv8.5 FEAT_RNG Rebecca Cran
@ 2021-04-28 20:44 ` Rebecca Cran
  2021-04-29  1:08   ` 回复: " gaoliming
  2021-05-04 21:06   ` Sami Mujawar
  2021-04-28 20:44 ` [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86 Rebecca Cran
  2021-04-28 20:44 ` [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64 Rebecca Cran
  2 siblings, 2 replies; 16+ messages in thread
From: Rebecca Cran @ 2021-04-28 20:44 UTC (permalink / raw)
  To: devel
  Cc: Rebecca Cran, Jiewen Yao, Jian J Wang, Michael D Kinney,
	Liming Gao, Zhiguang Liu, Ard Biesheuvel, Sami Mujawar

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 <rebecca@nuviainc.com>
---
 MdePkg/Library/BaseLib/BaseLib.inf                |  4 ++
 MdePkg/Include/Library/BaseLib.h                  | 47 +++++++++++++++++
 MdePkg/Library/BaseLib/BaseLibInternals.h         |  6 +++
 MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S   | 29 +++++++++++
 MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm | 28 ++++++++++
 MdePkg/Library/BaseLib/AArch64/ArmRng.S           | 51 ++++++++++++++++++
 MdePkg/Library/BaseLib/AArch64/ArmRng.asm         | 55 ++++++++++++++++++++
 7 files changed, 220 insertions(+)

diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index b76f3af380ea..7f582079d786 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -380,6 +380,8 @@ [Sources.AARCH64]
   AArch64/SetJumpLongJump.S         | GCC
   AArch64/CpuBreakpoint.S           | GCC
   AArch64/SpeculationBarrier.S      | GCC
+  AArch64/ArmRng.S                  | GCC
+  AArch64/ArmReadIdIsar0.S          | GCC
 
   AArch64/MemoryFence.asm           | MSFT
   AArch64/SwitchStack.asm           | MSFT
@@ -389,6 +391,8 @@ [Sources.AARCH64]
   AArch64/SetJumpLongJump.asm       | MSFT
   AArch64/CpuBreakpoint.asm         | MSFT
   AArch64/SpeculationBarrier.asm    | MSFT
+  AArch64/ArmRng.asm                | MSFT
+  AArch64/ArmReadIdIsar0.asm        | MSFT
 
 [Sources.RISCV64]
   Math64.c
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 7253997a6f8c..60cf559b0849 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7519,4 +7519,51 @@ PatchInstructionX86 (
   );
 
 #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
+
+#if defined (MDE_CPU_AARCH64)
+
+/**
+  Reads the ID_AA64ISAR0 Register.
+
+  @return The contents of the ID_AA64ISAR0 Register
+
+**/
+UINT64
+EFIAPI
+ArmReadIdIsar0 (
+  VOID
+  );
+
+/**
+  Generates a random number using the RNDR instruction.
+
+  @param[out]  The generated random number
+
+  @retval TRUE  Success: a random number was successfully generated
+  @retval FALSE Failure: a random number was unable to be generated
+
+**/
+BOOLEAN
+EFIAPI
+ArmRndr (
+  OUT UINT64 *Rand
+  );
+
+/**
+  Generates a random number using the RNDRRS instruction.
+
+  @param[out]  The generated random number
+
+  @retval TRUE  Success: a random number was successfully generated
+  @retval FALSE Failure: a random number was unable to be generated
+
+**/
+BOOLEAN
+EFIAPI
+ArmRndrrs (
+  OUT UINT64 *Rand
+  );
+
+#endif // defined (MDE_CPU_AARCH64)
+
 #endif // !defined (__BASE_LIB__)
diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h b/MdePkg/Library/BaseLib/BaseLibInternals.h
index 6837d67d90cf..4ae79a4e7ab4 100644
--- a/MdePkg/Library/BaseLib/BaseLibInternals.h
+++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
@@ -862,6 +862,12 @@ InternalX86RdRand64  (
   OUT     UINT64                    *Rand
   );
 
+#elif defined (MDE_CPU_AARCH64)
+
+// RNDR, Random Number
+#define RNDR      S3_3_C2_C4_0
+#define RNDRRS    S3_3_C2_C4_1
+
 #else
 
 #endif
diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S
new file mode 100644
index 000000000000..b31e565c7955
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S
@@ -0,0 +1,29 @@
+#------------------------------------------------------------------------------
+#
+# ArmReadIdIsar0() for AArch64
+#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#------------------------------------------------------------------------------
+
+.text
+.p2align 2
+GCC_ASM_EXPORT(ArmReadIdIsar0)
+
+#/**
+#  Reads 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/BaseLib/AArch64/ArmReadIdIsar0.asm b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm
new file mode 100644
index 000000000000..1f1d15626cc2
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm
@@ -0,0 +1,28 @@
+;------------------------------------------------------------------------------
+;
+; ArmReadIdIsar0() for AArch64
+;
+; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+  EXPORT ArmReadIdIsar0
+  AREA BaseLib_LowLevel, CODE, READONLY
+
+;/**
+;  Reads 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/BaseLib/AArch64/ArmRng.S b/MdePkg/Library/BaseLib/AArch64/ArmRng.S
new file mode 100644
index 000000000000..fc2adb660d21
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/ArmRng.S
@@ -0,0 +1,51 @@
+#------------------------------------------------------------------------------
+#
+# ArmRndr() and ArmRndrrs() for AArch64
+#
+# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#------------------------------------------------------------------------------
+
+#include "BaseLibInternals.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.
+#
+#**/
+#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.
+#
+#**/
+#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/BaseLib/AArch64/ArmRng.asm b/MdePkg/Library/BaseLib/AArch64/ArmRng.asm
new file mode 100644
index 000000000000..ed8d1a81bdfe
--- /dev/null
+++ b/MdePkg/Library/BaseLib/AArch64/ArmRng.asm
@@ -0,0 +1,55 @@
+;------------------------------------------------------------------------------
+;
+; ArmRndr() and ArmRndrrs() for AArch64
+;
+; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+;
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+#include "BaseLibInternals.h"
+
+  EXPORT ArmRndr
+  EXPORT ArmRndrrs
+  AREA BaseLib_LowLevel, CODE, READONLY
+
+
+;/**
+;  Generates a random number using RNDR.
+;  Returns TRUE on success; FALSE on failure.
+;
+;**/
+;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.
+;
+;**/
+;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
+
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86
  2021-04-28 20:44 [PATCH 0/3] MdePkg,SecurityPkg: Update BaseRngLib and RngDxe to support ARMv8.5 FEAT_RNG Rebecca Cran
  2021-04-28 20:44 ` [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions Rebecca Cran
@ 2021-04-28 20:44 ` Rebecca Cran
  2021-04-29  1:10   ` 回复: " gaoliming
  2021-05-04 21:09   ` Sami Mujawar
  2021-04-28 20:44 ` [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64 Rebecca Cran
  2 siblings, 2 replies; 16+ messages in thread
From: Rebecca Cran @ 2021-04-28 20:44 UTC (permalink / raw)
  To: devel
  Cc: Rebecca Cran, Jiewen Yao, Jian J Wang, Michael D Kinney,
	Liming Gao, Zhiguang Liu, Ard Biesheuvel, Sami Mujawar

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.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
 MdePkg/MdePkg.dec                               |   9 +-
 MdePkg/MdePkg.dsc                               |   4 +-
 MdePkg/Library/BaseRngLib/BaseRngLib.inf        |  16 ++-
 MdePkg/Library/BaseRngLib/BaseRngLibInternals.h |  31 +++++
 MdePkg/Library/BaseRngLib/AArch64/Rndr.c        | 121 ++++++++++++++++++++
 MdePkg/Library/BaseRngLib/BaseRng.c             |  55 +++------
 MdePkg/Library/BaseRngLib/Rand/RdRand.c         | 103 +++++++++++++++++
 MdePkg/Library/BaseRngLib/BaseRngLib.uni        |   6 +-
 8 files changed, 291 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..1dc3249a8c20 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 high-quality random numbers.
 #
+#  Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
 #  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -22,11 +23,18 @@ [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
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
new file mode 100644
index 000000000000..44fda69c9eec
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
@@ -0,0 +1,31 @@
+/** @file
+
+  Architecture specific interface to RNG functionality.
+
+Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef BASE_RNGLIB_INTERNALS_H_
+
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber16 (
+  OUT UINT16 *Rand
+  );
+
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber32 (
+  OUT UINT32 *Rand
+  );
+
+BOOLEAN
+EFIAPI
+ArchGetRandomNumber64 (
+  OUT UINT64 *Rand
+  );
+
+#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..19643237923a
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
@@ -0,0 +1,121 @@
+/** @file
+  Random number generator service that uses the RNDR instruction
+  to provide high-quality random numbers.
+
+  Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
+  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/RngLib.h>
+
+#include "BaseRngLibInternals.h"
+
+//
+// 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 RETURN_SUCCESS.
+
+  @retval RETURN_SUCCESS   The constructor always returns EFI_SUCCESS.
+
+**/
+RETURN_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);
+  (void)Isar0;
+
+  return RETURN_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);
+}
+
diff --git a/MdePkg/Library/BaseRngLib/BaseRng.c b/MdePkg/Library/BaseRngLib/BaseRng.c
index 7ad7aec9d38f..072fa37d3394 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 high-quality random numbers.
 
+Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
 Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -10,46 +12,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/BaseLib.h>
 #include <Library/DebugLib.h>
 
-//
-// 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.
@@ -75,8 +46,8 @@ GetRandomNumber16 (
   //
   // 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;
     }
   }
@@ -108,8 +79,8 @@ GetRandomNumber32 (
   //
   // 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;
     }
   }
@@ -141,8 +112,8 @@ GetRandomNumber64 (
   //
   // 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;
     }
   }
diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
new file mode 100644
index 000000000000..3f1378064b4c
--- /dev/null
+++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
@@ -0,0 +1,103 @@
+/** @file
+  Random number generator services that uses RdRand instruction access
+  to provide high-quality random numbers.
+
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+#include "BaseRngLibInternals.h"
+
+//
+// Bit mask used to determine if RdRand instruction is supported.
+//
+#define RDRAND_MASK                  BIT30
+
+/**
+  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.
+
+  @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);
+}
+
diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.uni b/MdePkg/Library/BaseRngLib/BaseRngLib.uni
index f3ed954c5209..8c7fe1219450 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 high-quality
+// random numbers.
 //
 // Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
 //
@@ -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 high-quality random numbers"
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64
  2021-04-28 20:44 [PATCH 0/3] MdePkg,SecurityPkg: Update BaseRngLib and RngDxe to support ARMv8.5 FEAT_RNG Rebecca Cran
  2021-04-28 20:44 ` [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions Rebecca Cran
  2021-04-28 20:44 ` [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86 Rebecca Cran
@ 2021-04-28 20:44 ` Rebecca Cran
  2021-04-29  1:13   ` 回复: " gaoliming
  2021-04-29 10:35   ` Ard Biesheuvel
  2 siblings, 2 replies; 16+ messages in thread
From: Rebecca Cran @ 2021-04-28 20:44 UTC (permalink / raw)
  To: devel
  Cc: Rebecca Cran, Jiewen Yao, Jian J Wang, Michael D Kinney,
	Liming Gao, Zhiguang Liu, Ard Biesheuvel, Sami Mujawar

AARCH64 support has been added to BaseRngLib via the optional
ARMv8.5 FEAT_RNG.

Refactor RngDxe to support AARCH64, note support for it in the
VALID_ARCHITECTURES line of RngDxe.inf and enable it in SecurityPkg.dsc.

Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
---
 SecurityPkg/SecurityPkg.dsc                                   |  11 +-
 SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf           |  19 +++-
 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h       |  37 ++++++
 SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h |   0
 SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h  |   0
 SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h    |  88 ++++++++++++++
 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c       |  54 +++++++++
 SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c     | 108 ++++++++++++++++++
 SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c |   0
 SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c  |   0
 SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c        | 120 ++++++++++++++++++++
 SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c             | 117 ++++---------------
 12 files changed, 450 insertions(+), 104 deletions(-)

diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index 12ccd1634941..bd4b810bce61 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -259,6 +259,12 @@ [Components]
 [Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
   SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
 
+[Components.IA32, Components.X64, Components.AARCH64]
+  #
+  # Random Number Generator
+  #
+  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+
 [Components.IA32, Components.X64]
   SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
 
@@ -334,11 +340,6 @@ [Components.IA32, Components.X64]
   SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.inf
   SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.inf
 
-  #
-  # Random Number Generator
-  #
-  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
-
   #
   # Opal Password solution
   #
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
index 99d6f6b35fc2..c188b6076c00 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
@@ -26,15 +26,24 @@ [Defines]
 #
 # The following information is for reference only and not required by the build tools.
 #
-#  VALID_ARCHITECTURES           = IA32 X64
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
 #
 
 [Sources.common]
   RngDxe.c
-  RdRand.c
-  RdRand.h
-  AesCore.c
-  AesCore.h
+  RngDxeInternals.h
+
+[Sources.IA32, Sources.X64]
+  Rand/RngDxe.c
+  Rand/RdRand.c
+  Rand/RdRand.h
+  Rand/AesCore.c
+  Rand/AesCore.h
+
+[Sources.AARCH64]
+  AArch64/RngDxe.c
+  AArch64/Rndr.c
+  AArch64/Rndr.h
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
new file mode 100644
index 000000000000..458faa834a3d
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
@@ -0,0 +1,37 @@
+/** @file
+  Header for the RNDR APIs used by RNG DXE driver.
+
+  Support API definitions for RNDR instruction access.
+
+
+  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RNDR_H_
+#define RNDR_H_
+
+#include <Library/BaseLib.h>
+#include <Protocol/Rng.h>
+
+/**
+  Calls RNDR to fill a buffer of arbitrary size with random bytes.
+
+  @param[in]   Length        Size of the buffer, in bytes, to fill with.
+  @param[out]  RandBuffer    Pointer to the buffer to store the random result.
+
+  @retval EFI_SUCCESS        Random bytes generation succeeded.
+  @retval EFI_NOT_READY      Failed to request random bytes.
+
+**/
+EFI_STATUS
+EFIAPI
+RndrGetBytes (
+  IN UINTN         Length,
+  OUT UINT8        *RandBuffer
+  );
+
+#endif  // RNDR_H_
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
similarity index 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
similarity index 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
new file mode 100644
index 000000000000..7e38fc2564f6
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
@@ -0,0 +1,88 @@
+/** @file
+  Function prototypes for UEFI Random Number Generator protocol support.
+
+  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RNGDXE_INTERNALS_H_
+#define RNGDXE_INTERNALS_H_
+
+extern EFI_RNG_ALGORITHM *mSUpportedRngAlgorithms;
+
+/**
+  Returns information about the random number generation implementation.
+
+  @param[in]     This                 A pointer to the EFI_RNG_PROTOCOL instance.
+  @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
+                                      On output with a return code of EFI_SUCCESS, the size
+                                      in bytes of the data returned in RNGAlgorithmList. On output
+                                      with a return code of EFI_BUFFER_TOO_SMALL,
+                                      the size of RNGAlgorithmList required to obtain the list.
+  @param[out] RNGAlgorithmList        A caller-allocated memory buffer filled by the driver
+                                      with one EFI_RNG_ALGORITHM element for each supported
+                                      RNG algorithm. The list must not change across multiple
+                                      calls to the same driver. The first algorithm in the list
+                                      is the default algorithm for the driver.
+
+  @retval EFI_SUCCESS                 The RNG algorithm list was returned successfully.
+  @retval EFI_UNSUPPORTED             The services is not supported by this driver.
+  @retval EFI_DEVICE_ERROR            The list of algorithms could not be retrieved due to a
+                                      hardware or firmware error.
+  @retval EFI_INVALID_PARAMETER       One or more of the parameters are incorrect.
+  @retval EFI_BUFFER_TOO_SMALL        The buffer RNGAlgorithmList is too small to hold the result.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetInfo (
+  IN EFI_RNG_PROTOCOL             *This,
+  IN OUT UINTN                    *RNGAlgorithmListSize,
+  OUT EFI_RNG_ALGORITHM           *RNGAlgorithmList
+  );
+
+/**
+  Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+  @param[in]  This                    A pointer to the EFI_RNG_PROTOCOL instance.
+  @param[in]  RNGAlgorithm            A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+                                      algorithm to use. May be NULL in which case the function will
+                                      use its default RNG algorithm.
+  @param[in]  RNGValueLength          The length in bytes of the memory buffer pointed to by
+                                      RNGValue. The driver shall return exactly this numbers of bytes.
+  @param[out] RNGValue                A caller-allocated memory buffer filled by the driver with the
+                                      resulting RNG value.
+
+  @retval EFI_SUCCESS                 The RNG value was returned successfully.
+  @retval EFI_UNSUPPORTED             The algorithm specified by RNGAlgorithm is not supported by
+                                      this driver.
+  @retval EFI_DEVICE_ERROR            An RNG value could not be retrieved due to a hardware or
+                                      firmware error.
+  @retval EFI_NOT_READY               There is not enough random data available to satisfy the length
+                                      requested by RNGValueLength.
+  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+  IN EFI_RNG_PROTOCOL            *This,
+  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
+  IN UINTN                       RNGValueLength,
+  OUT UINT8                      *RNGValue
+  );
+
+/**
+  Returns the size of the RNG algorithms structure.
+
+  @return Size of the EFI_RNG_ALGORITHM list.
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithmsSize (
+  VOID
+  );
+
+#endif  // RNGDXE_INTERNALS_H_
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
new file mode 100644
index 000000000000..36166a9cbc13
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
@@ -0,0 +1,54 @@
+/** @file
+  Support routines for RNDR instruction access.
+
+  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/RngLib.h>
+
+#include "Rndr.h"
+
+/**
+  Calls RNDR to fill a buffer of arbitrary size with random bytes.
+
+  @param[in]   Length        Size of the buffer, in bytes, to fill with.
+  @param[out]  RandBuffer    Pointer to the buffer to store the random result.
+
+  @retval EFI_SUCCESS        Random bytes generation succeeded.
+  @retval EFI_NOT_READY      Failed to request random bytes.
+
+**/
+EFI_STATUS
+EFIAPI
+RndrGetBytes (
+  IN UINTN         Length,
+  OUT UINT8        *RandBuffer
+  )
+{
+  BOOLEAN     IsRandom;
+  UINT64      TempRand;
+
+  while (Length > 0) {
+    IsRandom = GetRandomNumber64 (&TempRand);
+    if (!IsRandom) {
+      return EFI_NOT_READY;
+    }
+    if (Length >= sizeof (TempRand)) {
+      WriteUnaligned64 ((UINT64*)RandBuffer, TempRand);
+      RandBuffer += sizeof (UINT64);
+      Length -= sizeof (TempRand);
+    } else {
+      CopyMem (RandBuffer, &TempRand, Length);
+      Length = 0;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
new file mode 100644
index 000000000000..18cca825e72d
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
@@ -0,0 +1,108 @@
+/** @file
+  RNG Driver to produce the UEFI Random Number Generator protocol.
+
+  The driver will use the new RNDR instruction to produce high-quality, high-performance
+  entropy and random number.
+
+  RNG Algorithms defined in UEFI 2.4:
+   - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID  - Unsupported
+   - EFI_RNG_ALGORITHM_RAW                    - Supported
+   - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
+   - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
+   - EFI_RNG_ALGORITHM_X9_31_3DES_GUID        - Unsupported
+   - EFI_RNG_ALGORITHM_X9_31_AES_GUID         - Unsupported
+
+  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
+  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/TimerLib.h>
+#include <Protocol/Rng.h>
+
+#include "Rndr.h"
+
+//
+// Supported RNG Algorithms list by this driver.
+//
+EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
+  EFI_RNG_ALGORITHM_RAW
+};
+
+/**
+  Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+  @param[in]  This                    A pointer to the EFI_RNG_PROTOCOL instance.
+  @param[in]  RNGAlgorithm            A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+                                      algorithm to use. May be NULL in which case the function will
+                                      use its default RNG algorithm.
+  @param[in]  RNGValueLength          The length in bytes of the memory buffer pointed to by
+                                      RNGValue. The driver shall return exactly this numbers of bytes.
+  @param[out] RNGValue                A caller-allocated memory buffer filled by the driver with the
+                                      resulting RNG value.
+
+  @retval EFI_SUCCESS                 The RNG value was returned successfully.
+  @retval EFI_UNSUPPORTED             The algorithm specified by RNGAlgorithm is not supported by
+                                      this driver.
+  @retval EFI_DEVICE_ERROR            An RNG value could not be retrieved due to a hardware or
+                                      firmware error.
+  @retval EFI_NOT_READY               There is not enough random data available to satisfy the length
+                                      requested by RNGValueLength.
+  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+  IN EFI_RNG_PROTOCOL            *This,
+  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
+  IN UINTN                       RNGValueLength,
+  OUT UINT8                      *RNGValue
+  )
+{
+  EFI_STATUS    Status;
+
+  if ((RNGValueLength == 0) || (RNGValue == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (RNGAlgorithm == NULL) {
+    //
+    // Use the default RNG algorithm if RNGAlgorithm is NULL.
+    //
+    RNGAlgorithm = &gEfiRngAlgorithmRaw;
+  }
+
+  //
+  // The "raw" algorithm is intended to provide entropy directly
+  //
+  if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
+    Status = RndrGetBytes (RNGValueLength, RNGValue);
+    return Status;
+  }
+
+  //
+  // Other algorithms are unsupported by this driver.
+  //
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Returns the size of the RNG algorithms structure.
+
+  @return Size of the EFI_RNG_ALGORITHM list.
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithmsSize (
+  VOID
+  )
+{
+  return sizeof (mSupportedRngAlgorithms);
+}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c
similarity index 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
similarity index 100%
rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
new file mode 100644
index 000000000000..cf0bebd6a386
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
@@ -0,0 +1,120 @@
+/** @file
+  RNG Driver to produce the UEFI Random Number Generator protocol.
+
+  The driver will use the new RDRAND instruction to produce high-quality, high-performance
+  entropy and random number.
+
+  RNG Algorithms defined in UEFI 2.4:
+   - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID  - Supported
+     (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based DRBG)
+   - EFI_RNG_ALGORITHM_RAW                    - Supported
+     (Structuring RDRAND invocation can be guaranteed as high-quality entropy source)
+   - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
+   - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
+   - EFI_RNG_ALGORITHM_X9_31_3DES_GUID        - Unsupported
+   - EFI_RNG_ALGORITHM_X9_31_AES_GUID         - Unsupported
+
+  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RdRand.h"
+
+//
+// Supported RNG Algorithms list by this driver.
+//
+EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
+  EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID,
+  EFI_RNG_ALGORITHM_RAW
+};
+
+/**
+  Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+  @param[in]  This                    A pointer to the EFI_RNG_PROTOCOL instance.
+  @param[in]  RNGAlgorithm            A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+                                      algorithm to use. May be NULL in which case the function will
+                                      use its default RNG algorithm.
+  @param[in]  RNGValueLength          The length in bytes of the memory buffer pointed to by
+                                      RNGValue. The driver shall return exactly this numbers of bytes.
+  @param[out] RNGValue                A caller-allocated memory buffer filled by the driver with the
+                                      resulting RNG value.
+
+  @retval EFI_SUCCESS                 The RNG value was returned successfully.
+  @retval EFI_UNSUPPORTED             The algorithm specified by RNGAlgorithm is not supported by
+                                      this driver.
+  @retval EFI_DEVICE_ERROR            An RNG value could not be retrieved due to a hardware or
+                                      firmware error.
+  @retval EFI_NOT_READY               There is not enough random data available to satisfy the length
+                                      requested by RNGValueLength.
+  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+  IN EFI_RNG_PROTOCOL            *This,
+  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
+  IN UINTN                       RNGValueLength,
+  OUT UINT8                      *RNGValue
+  )
+{
+  EFI_STATUS    Status;
+
+  if ((RNGValueLength == 0) || (RNGValue == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = EFI_UNSUPPORTED;
+  if (RNGAlgorithm == NULL) {
+    //
+    // Use the default RNG algorithm if RNGAlgorithm is NULL.
+    //
+    RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
+  }
+
+  //
+  // NIST SP800-90-AES-CTR-256 supported by RDRAND
+  //
+  if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) {
+    Status = RdRandGetBytes (RNGValueLength, RNGValue);
+    return Status;
+  }
+
+  //
+  // The "raw" algorithm is intended to provide entropy directly
+  //
+  if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
+    //
+    // When a DRBG is used on the output of a entropy source,
+    // its security level must be at least 256 bits according to UEFI Spec.
+    //
+    if (RNGValueLength < 32) {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
+    return Status;
+  }
+
+  //
+  // Other algorithms were unsupported by this driver.
+  //
+  return Status;
+}
+
+/**
+  Returns the size of the RNG algorithms list.
+
+  @return Size of the EFI_RNG_ALGORIGM list.
+**/
+UINTN
+EFIAPI
+ArchGetSupportedRngAlgorithmsSize (
+  VOID
+  )
+{
+  return sizeof (mSupportedRngAlgorithms);
+}
diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
index 13d3dbd0bfbe..0072e6b433e6 100644
--- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
+++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
@@ -1,34 +1,38 @@
 /** @file
   RNG Driver to produce the UEFI Random Number Generator protocol.
 
-  The driver will use the new RDRAND instruction to produce high-quality, high-performance
-  entropy and random number.
+  The driver uses CPU RNG instructions to produce high-quality,
+  high-performance entropy and random number.
 
   RNG Algorithms defined in UEFI 2.4:
-   - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID  - Supported
-     (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based DRBG)
-   - EFI_RNG_ALGORITHM_RAW                    - Supported
-     (Structuring RDRAND invocation can be guaranteed as high-quality entropy source)
-   - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
-   - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
-   - EFI_RNG_ALGORITHM_X9_31_3DES_GUID        - Unsupported
-   - EFI_RNG_ALGORITHM_X9_31_AES_GUID         - Unsupported
+   - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID
+   - EFI_RNG_ALGORITHM_RAW
+   - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID
+   - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID
+   - EFI_RNG_ALGORITHM_X9_31_3DES_GUID
+   - EFI_RNG_ALGORITHM_X9_31_AES_GUID
 
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
-(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
+  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
 
-#include "RdRand.h"
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/TimerLib.h>
+#include <Protocol/Rng.h>
+
+#include "RngDxeInternals.h"
+
 
 //
 // Supported RNG Algorithms list by this driver.
 //
-EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
-  EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID,
-  EFI_RNG_ALGORITHM_RAW
-};
+
+extern EFI_RNG_ALGORITHM mSupportedRngAlgorithms[];
 
 /**
   Returns information about the random number generation implementation.
@@ -68,7 +72,7 @@ RngGetInfo (
     return EFI_INVALID_PARAMETER;
   }
 
-  RequiredSize = sizeof (mSupportedRngAlgorithms);
+  RequiredSize = ArchGetSupportedRngAlgorithmsSize ();
   if (*RNGAlgorithmListSize < RequiredSize) {
     Status = EFI_BUFFER_TOO_SMALL;
   } else {
@@ -87,81 +91,6 @@ RngGetInfo (
   return Status;
 }
 
-/**
-  Produces and returns an RNG value using either the default or specified RNG algorithm.
-
-  @param[in]  This                    A pointer to the EFI_RNG_PROTOCOL instance.
-  @param[in]  RNGAlgorithm            A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
-                                      algorithm to use. May be NULL in which case the function will
-                                      use its default RNG algorithm.
-  @param[in]  RNGValueLength          The length in bytes of the memory buffer pointed to by
-                                      RNGValue. The driver shall return exactly this numbers of bytes.
-  @param[out] RNGValue                A caller-allocated memory buffer filled by the driver with the
-                                      resulting RNG value.
-
-  @retval EFI_SUCCESS                 The RNG value was returned successfully.
-  @retval EFI_UNSUPPORTED             The algorithm specified by RNGAlgorithm is not supported by
-                                      this driver.
-  @retval EFI_DEVICE_ERROR            An RNG value could not be retrieved due to a hardware or
-                                      firmware error.
-  @retval EFI_NOT_READY               There is not enough random data available to satisfy the length
-                                      requested by RNGValueLength.
-  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or RNGValueLength is zero.
-
-**/
-EFI_STATUS
-EFIAPI
-RngGetRNG (
-  IN EFI_RNG_PROTOCOL            *This,
-  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
-  IN UINTN                       RNGValueLength,
-  OUT UINT8                      *RNGValue
-  )
-{
-  EFI_STATUS    Status;
-
-  if ((RNGValueLength == 0) || (RNGValue == NULL)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  Status = EFI_UNSUPPORTED;
-  if (RNGAlgorithm == NULL) {
-    //
-    // Use the default RNG algorithm if RNGAlgorithm is NULL.
-    //
-    RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
-  }
-
-  //
-  // NIST SP800-90-AES-CTR-256 supported by RDRAND
-  //
-  if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) {
-    Status = RdRandGetBytes (RNGValueLength, RNGValue);
-    return Status;
-  }
-
-  //
-  // The "raw" algorithm is intended to provide entropy directly
-  //
-  if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
-    //
-    // When a DRBG is used on the output of a entropy source,
-    // its security level must be at least 256 bits according to UEFI Spec.
-    //
-    if (RNGValueLength < 32) {
-      return EFI_INVALID_PARAMETER;
-    }
-
-    Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
-    return Status;
-  }
-
-  //
-  // Other algorithms were unsupported by this driver.
-  //
-  return Status;
-}
-
 //
 // The Random Number Generator (RNG) protocol
 //
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* 回复: [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions
  2021-04-28 20:44 ` [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions Rebecca Cran
@ 2021-04-29  1:08   ` gaoliming
  2021-05-05 21:02     ` [edk2-devel] " Rebecca Cran
  2021-05-04 21:06   ` Sami Mujawar
  1 sibling, 1 reply; 16+ messages in thread
From: gaoliming @ 2021-04-29  1:08 UTC (permalink / raw)
  To: 'Rebecca Cran', devel
  Cc: 'Jiewen Yao', 'Jian J Wang',
	'Michael D Kinney', 'Zhiguang Liu',
	'Ard Biesheuvel', 'Sami Mujawar'

Rebecca:
  Can you submit one BZ for this new feature? 

Thanks
Liming
> -----邮件原件-----
> 发件人: Rebecca Cran <rebecca@nuviainc.com>
> 发送时间: 2021年4月29日 4:44
> 收件人: devel@edk2.groups.io
> 抄送: Rebecca Cran <rebecca@nuviainc.com>; Jiewen Yao
> <jiewen.yao@intel.com>; Jian J Wang <jian.j.wang@intel.com>; Michael D
> Kinney <michael.d.kinney@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>; Ard
> Biesheuvel <ardb+tianocore@kernel.org>; Sami Mujawar
> <Sami.Mujawar@arm.com>
> 主题: [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG
> instructions
> 
> 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 <rebecca@nuviainc.com>
> ---
>  MdePkg/Library/BaseLib/BaseLib.inf                |  4 ++
>  MdePkg/Include/Library/BaseLib.h                  | 47
> +++++++++++++++++
>  MdePkg/Library/BaseLib/BaseLibInternals.h         |  6 +++
>  MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S   | 29 +++++++++++
>  MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm | 28 ++++++++++
>  MdePkg/Library/BaseLib/AArch64/ArmRng.S           | 51
> ++++++++++++++++++
>  MdePkg/Library/BaseLib/AArch64/ArmRng.asm         | 55
> ++++++++++++++++++++
>  7 files changed, 220 insertions(+)
> 
> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> b/MdePkg/Library/BaseLib/BaseLib.inf
> index b76f3af380ea..7f582079d786 100644
> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> @@ -380,6 +380,8 @@ [Sources.AARCH64]
>    AArch64/SetJumpLongJump.S         | GCC
>    AArch64/CpuBreakpoint.S           | GCC
>    AArch64/SpeculationBarrier.S      | GCC
> +  AArch64/ArmRng.S                  | GCC
> +  AArch64/ArmReadIdIsar0.S          | GCC
> 
>    AArch64/MemoryFence.asm           | MSFT
>    AArch64/SwitchStack.asm           | MSFT
> @@ -389,6 +391,8 @@ [Sources.AARCH64]
>    AArch64/SetJumpLongJump.asm       | MSFT
>    AArch64/CpuBreakpoint.asm         | MSFT
>    AArch64/SpeculationBarrier.asm    | MSFT
> +  AArch64/ArmRng.asm                | MSFT
> +  AArch64/ArmReadIdIsar0.asm        | MSFT
> 
>  [Sources.RISCV64]
>    Math64.c
> diff --git a/MdePkg/Include/Library/BaseLib.h
> b/MdePkg/Include/Library/BaseLib.h
> index 7253997a6f8c..60cf559b0849 100644
> --- a/MdePkg/Include/Library/BaseLib.h
> +++ b/MdePkg/Include/Library/BaseLib.h
> @@ -7519,4 +7519,51 @@ PatchInstructionX86 (
>    );
> 
>  #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> +
> +#if defined (MDE_CPU_AARCH64)
> +
> +/**
> +  Reads the ID_AA64ISAR0 Register.
> +
> +  @return The contents of the ID_AA64ISAR0 Register
> +
> +**/
> +UINT64
> +EFIAPI
> +ArmReadIdIsar0 (
> +  VOID
> +  );
> +
> +/**
> +  Generates a random number using the RNDR instruction.
> +
> +  @param[out]  The generated random number
> +
> +  @retval TRUE  Success: a random number was successfully generated
> +  @retval FALSE Failure: a random number was unable to be generated
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +ArmRndr (
> +  OUT UINT64 *Rand
> +  );
> +
> +/**
> +  Generates a random number using the RNDRRS instruction.
> +
> +  @param[out]  The generated random number
> +
> +  @retval TRUE  Success: a random number was successfully generated
> +  @retval FALSE Failure: a random number was unable to be generated
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +ArmRndrrs (
> +  OUT UINT64 *Rand
> +  );
> +

What usage is for this API ArmRndrrs()? I don't see it is used in RngLib. 

Thanks
Liming
> +#endif // defined (MDE_CPU_AARCH64)
> +
>  #endif // !defined (__BASE_LIB__)
> diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h
> b/MdePkg/Library/BaseLib/BaseLibInternals.h
> index 6837d67d90cf..4ae79a4e7ab4 100644
> --- a/MdePkg/Library/BaseLib/BaseLibInternals.h
> +++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
> @@ -862,6 +862,12 @@ InternalX86RdRand64  (
>    OUT     UINT64                    *Rand
>    );
> 
> +#elif defined (MDE_CPU_AARCH64)
> +
> +// RNDR, Random Number
> +#define RNDR      S3_3_C2_C4_0
> +#define RNDRRS    S3_3_C2_C4_1
> +
>  #else
> 
>  #endif
> diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S
> b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S
> new file mode 100644
> index 000000000000..b31e565c7955
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S
> @@ -0,0 +1,29 @@
>
+#--------------------------------------------------------------------------
----
> +#
> +# ArmReadIdIsar0() for AArch64
> +#
> +# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
>
+#--------------------------------------------------------------------------
----
> +
> +.text
> +.p2align 2
> +GCC_ASM_EXPORT(ArmReadIdIsar0)
> +
> +#/**
> +#  Reads 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/BaseLib/AArch64/ArmReadIdIsar0.asm
> b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm
> new file mode 100644
> index 000000000000..1f1d15626cc2
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm
> @@ -0,0 +1,28 @@
>
+;--------------------------------------------------------------------------
----
> +;
> +; ArmReadIdIsar0() for AArch64
> +;
> +; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
>
+;--------------------------------------------------------------------------
----
> +
> +  EXPORT ArmReadIdIsar0
> +  AREA BaseLib_LowLevel, CODE, READONLY
> +
> +;/**
> +;  Reads 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/BaseLib/AArch64/ArmRng.S
> b/MdePkg/Library/BaseLib/AArch64/ArmRng.S
> new file mode 100644
> index 000000000000..fc2adb660d21
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/AArch64/ArmRng.S
> @@ -0,0 +1,51 @@
>
+#--------------------------------------------------------------------------
----
> +#
> +# ArmRndr() and ArmRndrrs() for AArch64
> +#
> +# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
>
+#--------------------------------------------------------------------------
----
> +
> +#include "BaseLibInternals.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.
> +#
> +#**/
> +#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.
> +#
> +#**/
> +#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/BaseLib/AArch64/ArmRng.asm
> b/MdePkg/Library/BaseLib/AArch64/ArmRng.asm
> new file mode 100644
> index 000000000000..ed8d1a81bdfe
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/AArch64/ArmRng.asm
> @@ -0,0 +1,55 @@
>
+;--------------------------------------------------------------------------
----
> +;
> +; ArmRndr() and ArmRndrrs() for AArch64
> +;
> +; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
>
+;--------------------------------------------------------------------------
----
> +
> +#include "BaseLibInternals.h"
> +
> +  EXPORT ArmRndr
> +  EXPORT ArmRndrrs
> +  AREA BaseLib_LowLevel, CODE, READONLY
> +
> +
> +;/**
> +;  Generates a random number using RNDR.
> +;  Returns TRUE on success; FALSE on failure.
> +;
> +;**/
> +;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.
> +;
> +;**/
> +;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
> +
> --
> 2.26.2




^ permalink raw reply	[flat|nested] 16+ messages in thread

* 回复: [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86
  2021-04-28 20:44 ` [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86 Rebecca Cran
@ 2021-04-29  1:10   ` gaoliming
  2021-04-29  3:01     ` [edk2-devel] " Rebecca Cran
  2021-05-04 21:09   ` Sami Mujawar
  1 sibling, 1 reply; 16+ messages in thread
From: gaoliming @ 2021-04-29  1:10 UTC (permalink / raw)
  To: 'Rebecca Cran', devel
  Cc: 'Jiewen Yao', 'Jian J Wang',
	'Michael D Kinney', 'Zhiguang Liu',
	'Ard Biesheuvel', 'Sami Mujawar'

Rebecca:

> -----邮件原件-----
> 发件人: Rebecca Cran <rebecca@nuviainc.com>
> 发送时间: 2021年4月29日 4:44
> 收件人: devel@edk2.groups.io
> 抄送: Rebecca Cran <rebecca@nuviainc.com>; Jiewen Yao
> <jiewen.yao@intel.com>; Jian J Wang <jian.j.wang@intel.com>; Michael D
> Kinney <michael.d.kinney@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>; Ard
> Biesheuvel <ardb+tianocore@kernel.org>; Sami Mujawar
> <Sami.Mujawar@arm.com>
> 主题: [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in
> addition to X86
> 
> 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.
> 
> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
> ---
>  MdePkg/MdePkg.dec                               |   9 +-
>  MdePkg/MdePkg.dsc                               |   4 +-
>  MdePkg/Library/BaseRngLib/BaseRngLib.inf        |  16 ++-
>  MdePkg/Library/BaseRngLib/BaseRngLibInternals.h |  31 +++++
>  MdePkg/Library/BaseRngLib/AArch64/Rndr.c        | 121
> ++++++++++++++++++++
>  MdePkg/Library/BaseRngLib/BaseRng.c             |  55 +++------
>  MdePkg/Library/BaseRngLib/Rand/RdRand.c         | 103
> +++++++++++++++++
>  MdePkg/Library/BaseRngLib/BaseRngLib.uni        |   6 +-
>  8 files changed, 291 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.in
> f
> 
> +[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..1dc3249a8c20 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 high-quality random numbers.
>  #
> +#  Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
>  #  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent
> @@ -22,11 +23,18 @@ [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
> 
>  [Packages]
>    MdePkg/MdePkg.dec
> diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
> b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
> new file mode 100644
> index 000000000000..44fda69c9eec
> --- /dev/null
> +++ b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
> @@ -0,0 +1,31 @@
> +/** @file
> +
> +  Architecture specific interface to RNG functionality.
> +
> +Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef BASE_RNGLIB_INTERNALS_H_
> +
> +BOOLEAN
> +EFIAPI
> +ArchGetRandomNumber16 (
> +  OUT UINT16 *Rand
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +ArchGetRandomNumber32 (
> +  OUT UINT32 *Rand
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +ArchGetRandomNumber64 (
> +  OUT UINT64 *Rand
> +  );
> +
> +#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..19643237923a
> --- /dev/null
> +++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
> @@ -0,0 +1,121 @@
> +/** @file
> +  Random number generator service that uses the RNDR instruction
> +  to provide high-quality random numbers.
> +
> +  Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
> +  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <Library/RngLib.h>
> +
> +#include "BaseRngLibInternals.h"
> +
> +//
> +// 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 RETURN_SUCCESS.
> +
> +  @retval RETURN_SUCCESS   The constructor always returns
> EFI_SUCCESS.
> +
> +**/
> +RETURN_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);
> +  (void)Isar0;
> +

What behavior for this statement "(void)Isar0;"?

Thanks
Liming
> +  return RETURN_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);
> +}
> +
> diff --git a/MdePkg/Library/BaseRngLib/BaseRng.c
> b/MdePkg/Library/BaseRngLib/BaseRng.c
> index 7ad7aec9d38f..072fa37d3394 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 high-quality random numbers.
> 
> +Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
>  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
>  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> @@ -10,46 +12,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>  #include <Library/BaseLib.h>
>  #include <Library/DebugLib.h>
> 
> -//
> -// 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.
> @@ -75,8 +46,8 @@ GetRandomNumber16 (
>    //
>    // 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;
>      }
>    }
> @@ -108,8 +79,8 @@ GetRandomNumber32 (
>    //
>    // 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;
>      }
>    }
> @@ -141,8 +112,8 @@ GetRandomNumber64 (
>    //
>    // 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;
>      }
>    }
> diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c
> b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
> new file mode 100644
> index 000000000000..3f1378064b4c
> --- /dev/null
> +++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
> @@ -0,0 +1,103 @@
> +/** @file
> +  Random number generator services that uses RdRand instruction access
> +  to provide high-quality random numbers.
> +
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include "BaseRngLibInternals.h"
> +
> +//
> +// Bit mask used to determine if RdRand instruction is supported.
> +//
> +#define RDRAND_MASK                  BIT30
> +
> +/**
> +  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.
> +
> +  @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);
> +}
> +
> diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.uni
> b/MdePkg/Library/BaseRngLib/BaseRngLib.uni
> index f3ed954c5209..8c7fe1219450 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 high-quality
> +// random numbers.
>  //
>  // Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
>  //
> @@ -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 high-quality random
> numbers"
> 
> --
> 2.26.2




^ permalink raw reply	[flat|nested] 16+ messages in thread

* 回复: [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64
  2021-04-28 20:44 ` [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64 Rebecca Cran
@ 2021-04-29  1:13   ` gaoliming
  2021-04-29 15:50     ` [edk2-devel] " Rebecca Cran
  2021-04-29 10:35   ` Ard Biesheuvel
  1 sibling, 1 reply; 16+ messages in thread
From: gaoliming @ 2021-04-29  1:13 UTC (permalink / raw)
  To: 'Rebecca Cran', devel
  Cc: 'Jiewen Yao', 'Jian J Wang',
	'Michael D Kinney', 'Zhiguang Liu',
	'Ard Biesheuvel', 'Sami Mujawar'

Rebecca:

> -----邮件原件-----
> 发件人: Rebecca Cran <rebecca@nuviainc.com>
> 发送时间: 2021年4月29日 4:44
> 收件人: devel@edk2.groups.io
> 抄送: Rebecca Cran <rebecca@nuviainc.com>; Jiewen Yao
> <jiewen.yao@intel.com>; Jian J Wang <jian.j.wang@intel.com>; Michael D
> Kinney <michael.d.kinney@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>; Ard
> Biesheuvel <ardb+tianocore@kernel.org>; Sami Mujawar
> <Sami.Mujawar@arm.com>
> 主题: [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64
> 
> AARCH64 support has been added to BaseRngLib via the optional
> ARMv8.5 FEAT_RNG.
> 
> Refactor RngDxe to support AARCH64, note support for it in the
> VALID_ARCHITECTURES line of RngDxe.inf and enable it in SecurityPkg.dsc.
> 
> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
> ---
>  SecurityPkg/SecurityPkg.dsc                                   |
> 11 +-
>  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf           |
> 19 +++-
>  SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h       |
> 37 ++++++
>  SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h |
> 0
>  SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h  |
> 0
>  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h    |
> 88 ++++++++++++++
>  SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c       |
> 54 +++++++++
>  SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c     |
> 108 ++++++++++++++++++
>  SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c |
> 0
>  SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c  |
> 0
>  SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c        |
> 120 ++++++++++++++++++++
>  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c             |
> 117 ++++---------------
>  12 files changed, 450 insertions(+), 104 deletions(-)
> 
> diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
> index 12ccd1634941..bd4b810bce61 100644
> --- a/SecurityPkg/SecurityPkg.dsc
> +++ b/SecurityPkg/SecurityPkg.dsc
> @@ -259,6 +259,12 @@ [Components]
>  [Components.IA32, Components.X64, Components.ARM,
> Components.AARCH64]
>    SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> 
> +[Components.IA32, Components.X64, Components.AARCH64]
> +  #
> +  # Random Number Generator
> +  #
> +  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> +
>  [Components.IA32, Components.X64]
> 
> SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigD
> xe.inf
> 
> @@ -334,11 +340,6 @@ [Components.IA32, Components.X64]
> 
> SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresence
> Lib.inf
> 
> SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2Physic
> alPresenceLib.inf
> 
> -  #
> -  # Random Number Generator
> -  #
> -  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> -
>    #
>    # Opal Password solution
>    #
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> index 99d6f6b35fc2..c188b6076c00 100644
> --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> @@ -26,15 +26,24 @@ [Defines]
>  #
>  # The following information is for reference only and not required by the
> build tools.
>  #
> -#  VALID_ARCHITECTURES           = IA32 X64
> +#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
>  #
> 
>  [Sources.common]
>    RngDxe.c
> -  RdRand.c
> -  RdRand.h
> -  AesCore.c
> -  AesCore.h
> +  RngDxeInternals.h
> +
> +[Sources.IA32, Sources.X64]
> +  Rand/RngDxe.c
> +  Rand/RdRand.c
> +  Rand/RdRand.h
> +  Rand/AesCore.c
> +  Rand/AesCore.h
> +
> +[Sources.AARCH64]
> +  AArch64/RngDxe.c
> +  AArch64/Rndr.c
> +  AArch64/Rndr.h
> 
>  [Packages]
>    MdePkg/MdePkg.dec
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
> b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
> new file mode 100644
> index 000000000000..458faa834a3d
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
> @@ -0,0 +1,37 @@
> +/** @file
> +  Header for the RNDR APIs used by RNG DXE driver.
> +
> +  Support API definitions for RNDR instruction access.
> +
> +
> +  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RNDR_H_
> +#define RNDR_H_
> +
> +#include <Library/BaseLib.h>
> +#include <Protocol/Rng.h>
> +
> +/**
> +  Calls RNDR to fill a buffer of arbitrary size with random bytes.
> +
> +  @param[in]   Length        Size of the buffer, in bytes, to fill with.
> +  @param[out]  RandBuffer    Pointer to the buffer to store the random
> result.
> +
> +  @retval EFI_SUCCESS        Random bytes generation succeeded.
> +  @retval EFI_NOT_READY      Failed to request random bytes.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RndrGetBytes (
> +  IN UINTN         Length,
> +  OUT UINT8        *RandBuffer
> +  );
> +
> +#endif  // RNDR_H_
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
> similarity index 100%
> rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
> similarity index 100%
> rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
> b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
> new file mode 100644
> index 000000000000..7e38fc2564f6
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
> @@ -0,0 +1,88 @@
> +/** @file
> +  Function prototypes for UEFI Random Number Generator protocol
> support.
> +
> +  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RNGDXE_INTERNALS_H_
> +#define RNGDXE_INTERNALS_H_
> +
> +extern EFI_RNG_ALGORITHM *mSUpportedRngAlgorithms;
> +
> +/**
> +  Returns information about the random number generation
> implementation.
> +
> +  @param[in]     This                 A pointer to the
> EFI_RNG_PROTOCOL instance.
> +  @param[in,out] RNGAlgorithmListSize On input, the size in bytes of
> RNGAlgorithmList.
> +                                      On output with a return code
> of EFI_SUCCESS, the size
> +                                      in bytes of the data returned
> in RNGAlgorithmList. On output
> +                                      with a return code of
> EFI_BUFFER_TOO_SMALL,
> +                                      the size of RNGAlgorithmList
> required to obtain the list.
> +  @param[out] RNGAlgorithmList        A caller-allocated memory
> buffer filled by the driver
> +                                      with one
> EFI_RNG_ALGORITHM element for each supported
> +                                      RNG algorithm. The list must
> not change across multiple
> +                                      calls to the same driver. The
> first algorithm in the list
> +                                      is the default algorithm for
> the driver.
> +
> +  @retval EFI_SUCCESS                 The RNG algorithm list was
> returned successfully.
> +  @retval EFI_UNSUPPORTED             The services is not supported
> by this driver.
> +  @retval EFI_DEVICE_ERROR            The list of algorithms could
> not be retrieved due to a
> +                                      hardware or firmware error.
> +  @retval EFI_INVALID_PARAMETER       One or more of the
> parameters are incorrect.
> +  @retval EFI_BUFFER_TOO_SMALL        The buffer RNGAlgorithmList
> is too small to hold the result.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetInfo (
> +  IN EFI_RNG_PROTOCOL             *This,
> +  IN OUT UINTN                    *RNGAlgorithmListSize,
> +  OUT EFI_RNG_ALGORITHM           *RNGAlgorithmList
> +  );
> +
> +/**
> +  Produces and returns an RNG value using either the default or specified
> RNG algorithm.
> +
> +  @param[in]  This                    A pointer to the
> EFI_RNG_PROTOCOL instance.
> +  @param[in]  RNGAlgorithm            A pointer to the
> EFI_RNG_ALGORITHM that identifies the RNG
> +                                      algorithm to use. May be
> NULL in which case the function will
> +                                      use its default RNG
> algorithm.
> +  @param[in]  RNGValueLength          The length in bytes of the
> memory buffer pointed to by
> +                                      RNGValue. The driver shall
> return exactly this numbers of bytes.
> +  @param[out] RNGValue                A caller-allocated memory
> buffer filled by the driver with the
> +                                      resulting RNG value.
> +
> +  @retval EFI_SUCCESS                 The RNG value was returned
> successfully.
> +  @retval EFI_UNSUPPORTED             The algorithm specified by
> RNGAlgorithm is not supported by
> +                                      this driver.
> +  @retval EFI_DEVICE_ERROR            An RNG value could not be
> retrieved due to a hardware or
> +                                      firmware error.
> +  @retval EFI_NOT_READY               There is not enough random
> data available to satisfy the length
> +                                      requested by
> RNGValueLength.
> +  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or
> RNGValueLength is zero.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetRNG (
> +  IN EFI_RNG_PROTOCOL            *This,
> +  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
> +  IN UINTN                       RNGValueLength,
> +  OUT UINT8                      *RNGValue
> +  );
> +
> +/**
> +  Returns the size of the RNG algorithms structure.
> +
> +  @return Size of the EFI_RNG_ALGORITHM list.
> +**/
> +UINTN
> +EFIAPI
> +ArchGetSupportedRngAlgorithmsSize (
> +  VOID
> +  );
> +
> +#endif  // RNGDXE_INTERNALS_H_
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
> new file mode 100644
> index 000000000000..36166a9cbc13
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
> @@ -0,0 +1,54 @@
> +/** @file
> +  Support routines for RNDR instruction access.
> +
> +  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/RngLib.h>
> +
> +#include "Rndr.h"
> +
> +/**
> +  Calls RNDR to fill a buffer of arbitrary size with random bytes.
> +
> +  @param[in]   Length        Size of the buffer, in bytes, to fill with.
> +  @param[out]  RandBuffer    Pointer to the buffer to store the random
> result.
> +
> +  @retval EFI_SUCCESS        Random bytes generation succeeded.
> +  @retval EFI_NOT_READY      Failed to request random bytes.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RndrGetBytes (
> +  IN UINTN         Length,
> +  OUT UINT8        *RandBuffer
> +  )
> +{
> +  BOOLEAN     IsRandom;
> +  UINT64      TempRand;
> +
> +  while (Length > 0) {
> +    IsRandom = GetRandomNumber64 (&TempRand);
> +    if (!IsRandom) {
> +      return EFI_NOT_READY;
> +    }
> +    if (Length >= sizeof (TempRand)) {
> +      WriteUnaligned64 ((UINT64*)RandBuffer, TempRand);
> +      RandBuffer += sizeof (UINT64);
> +      Length -= sizeof (TempRand);
> +    } else {
> +      CopyMem (RandBuffer, &TempRand, Length);
> +      Length = 0;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +

Can this function be shared between X86 and AARCH64?

Thanks
Liming
> diff --git
> a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
> new file mode 100644
> index 000000000000..18cca825e72d
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
> @@ -0,0 +1,108 @@
> +/** @file
> +  RNG Driver to produce the UEFI Random Number Generator protocol.
> +
> +  The driver will use the new RNDR instruction to produce high-quality,
> high-performance
> +  entropy and random number.
> +
> +  RNG Algorithms defined in UEFI 2.4:
> +   - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID  - Unsupported
> +   - EFI_RNG_ALGORITHM_RAW                    - Supported
> +   - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
> +   - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
> +   - EFI_RNG_ALGORITHM_X9_31_3DES_GUID        - Unsupported
> +   - EFI_RNG_ALGORITHM_X9_31_AES_GUID         - Unsupported
> +
> +  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/TimerLib.h>
> +#include <Protocol/Rng.h>
> +
> +#include "Rndr.h"
> +
> +//
> +// Supported RNG Algorithms list by this driver.
> +//
> +EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
> +  EFI_RNG_ALGORITHM_RAW
> +};
> +
> +/**
> +  Produces and returns an RNG value using either the default or specified
> RNG algorithm.
> +
> +  @param[in]  This                    A pointer to the
> EFI_RNG_PROTOCOL instance.
> +  @param[in]  RNGAlgorithm            A pointer to the
> EFI_RNG_ALGORITHM that identifies the RNG
> +                                      algorithm to use. May be
> NULL in which case the function will
> +                                      use its default RNG
> algorithm.
> +  @param[in]  RNGValueLength          The length in bytes of the
> memory buffer pointed to by
> +                                      RNGValue. The driver shall
> return exactly this numbers of bytes.
> +  @param[out] RNGValue                A caller-allocated memory
> buffer filled by the driver with the
> +                                      resulting RNG value.
> +
> +  @retval EFI_SUCCESS                 The RNG value was returned
> successfully.
> +  @retval EFI_UNSUPPORTED             The algorithm specified by
> RNGAlgorithm is not supported by
> +                                      this driver.
> +  @retval EFI_DEVICE_ERROR            An RNG value could not be
> retrieved due to a hardware or
> +                                      firmware error.
> +  @retval EFI_NOT_READY               There is not enough random
> data available to satisfy the length
> +                                      requested by
> RNGValueLength.
> +  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or
> RNGValueLength is zero.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetRNG (
> +  IN EFI_RNG_PROTOCOL            *This,
> +  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
> +  IN UINTN                       RNGValueLength,
> +  OUT UINT8                      *RNGValue
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  if ((RNGValueLength == 0) || (RNGValue == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (RNGAlgorithm == NULL) {
> +    //
> +    // Use the default RNG algorithm if RNGAlgorithm is NULL.
> +    //
> +    RNGAlgorithm = &gEfiRngAlgorithmRaw;
> +  }
> +
> +  //
> +  // The "raw" algorithm is intended to provide entropy directly
> +  //
> +  if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
> +    Status = RndrGetBytes (RNGValueLength, RNGValue);
> +    return Status;
> +  }
> +
> +  //
> +  // Other algorithms are unsupported by this driver.
> +  //
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Returns the size of the RNG algorithms structure.
> +
> +  @return Size of the EFI_RNG_ALGORITHM list.
> +**/
> +UINTN
> +EFIAPI
> +ArchGetSupportedRngAlgorithmsSize (
> +  VOID
> +  )
> +{
> +  return sizeof (mSupportedRngAlgorithms);
> +}
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c
> similarity index 100%
> rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.c
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
> similarity index 100%
> rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.c
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
> new file mode 100644
> index 000000000000..cf0bebd6a386
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c
> @@ -0,0 +1,120 @@
> +/** @file
> +  RNG Driver to produce the UEFI Random Number Generator protocol.
> +
> +  The driver will use the new RDRAND instruction to produce high-quality,
> high-performance
> +  entropy and random number.
> +
> +  RNG Algorithms defined in UEFI 2.4:
> +   - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID  - Supported
> +     (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based
> DRBG)
> +   - EFI_RNG_ALGORITHM_RAW                    - Supported
> +     (Structuring RDRAND invocation can be guaranteed as high-quality
> entropy source)
> +   - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
> +   - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
> +   - EFI_RNG_ALGORITHM_X9_31_3DES_GUID        - Unsupported
> +   - EFI_RNG_ALGORITHM_X9_31_AES_GUID         - Unsupported
> +
> +  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "RdRand.h"
> +
> +//
> +// Supported RNG Algorithms list by this driver.
> +//
> +EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
> +  EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID,
> +  EFI_RNG_ALGORITHM_RAW
> +};
> +
> +/**
> +  Produces and returns an RNG value using either the default or specified
> RNG algorithm.
> +
> +  @param[in]  This                    A pointer to the
> EFI_RNG_PROTOCOL instance.
> +  @param[in]  RNGAlgorithm            A pointer to the
> EFI_RNG_ALGORITHM that identifies the RNG
> +                                      algorithm to use. May be
> NULL in which case the function will
> +                                      use its default RNG
> algorithm.
> +  @param[in]  RNGValueLength          The length in bytes of the
> memory buffer pointed to by
> +                                      RNGValue. The driver shall
> return exactly this numbers of bytes.
> +  @param[out] RNGValue                A caller-allocated memory
> buffer filled by the driver with the
> +                                      resulting RNG value.
> +
> +  @retval EFI_SUCCESS                 The RNG value was returned
> successfully.
> +  @retval EFI_UNSUPPORTED             The algorithm specified by
> RNGAlgorithm is not supported by
> +                                      this driver.
> +  @retval EFI_DEVICE_ERROR            An RNG value could not be
> retrieved due to a hardware or
> +                                      firmware error.
> +  @retval EFI_NOT_READY               There is not enough random
> data available to satisfy the length
> +                                      requested by
> RNGValueLength.
> +  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or
> RNGValueLength is zero.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetRNG (
> +  IN EFI_RNG_PROTOCOL            *This,
> +  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
> +  IN UINTN                       RNGValueLength,
> +  OUT UINT8                      *RNGValue
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  if ((RNGValueLength == 0) || (RNGValue == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = EFI_UNSUPPORTED;
> +  if (RNGAlgorithm == NULL) {
> +    //
> +    // Use the default RNG algorithm if RNGAlgorithm is NULL.
> +    //
> +    RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
> +  }
> +
> +  //
> +  // NIST SP800-90-AES-CTR-256 supported by RDRAND
> +  //
> +  if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid))
> {
> +    Status = RdRandGetBytes (RNGValueLength, RNGValue);
> +    return Status;
> +  }
> +
> +  //
> +  // The "raw" algorithm is intended to provide entropy directly
> +  //
> +  if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
> +    //
> +    // When a DRBG is used on the output of a entropy source,
> +    // its security level must be at least 256 bits according to UEFI
Spec.
> +    //
> +    if (RNGValueLength < 32) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
> +    return Status;
> +  }
> +
> +  //
> +  // Other algorithms were unsupported by this driver.
> +  //
> +  return Status;
> +}
> +
> +/**
> +  Returns the size of the RNG algorithms list.
> +
> +  @return Size of the EFI_RNG_ALGORIGM list.
> +**/
> +UINTN
> +EFIAPI
> +ArchGetSupportedRngAlgorithmsSize (
> +  VOID
> +  )
> +{
> +  return sizeof (mSupportedRngAlgorithms);
> +}
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
> b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
> index 13d3dbd0bfbe..0072e6b433e6 100644
> --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c
> @@ -1,34 +1,38 @@
>  /** @file
>    RNG Driver to produce the UEFI Random Number Generator protocol.
> 
> -  The driver will use the new RDRAND instruction to produce high-quality,
> high-performance
> -  entropy and random number.
> +  The driver uses CPU RNG instructions to produce high-quality,
> +  high-performance entropy and random number.
> 
>    RNG Algorithms defined in UEFI 2.4:
> -   - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID  - Supported
> -     (RDRAND implements a hardware NIST SP800-90 AES-CTR-256 based
> DRBG)
> -   - EFI_RNG_ALGORITHM_RAW                    - Supported
> -     (Structuring RDRAND invocation can be guaranteed as high-quality
> entropy source)
> -   - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
> -   - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
> -   - EFI_RNG_ALGORITHM_X9_31_3DES_GUID        - Unsupported
> -   - EFI_RNG_ALGORITHM_X9_31_AES_GUID         - Unsupported
> +   - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID
> +   - EFI_RNG_ALGORITHM_RAW
> +   - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID
> +   - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID
> +   - EFI_RNG_ALGORITHM_X9_31_3DES_GUID
> +   - EFI_RNG_ALGORITHM_X9_31_AES_GUID
> 
> -Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> -(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> +  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
>  **/
> 
> -#include "RdRand.h"
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/TimerLib.h>
> +#include <Protocol/Rng.h>
> +
> +#include "RngDxeInternals.h"
> +
> 
>  //
>  // Supported RNG Algorithms list by this driver.
>  //
> -EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
> -  EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID,
> -  EFI_RNG_ALGORITHM_RAW
> -};
> +
> +extern EFI_RNG_ALGORITHM mSupportedRngAlgorithms[];
> 
>  /**
>    Returns information about the random number generation
> implementation.
> @@ -68,7 +72,7 @@ RngGetInfo (
>      return EFI_INVALID_PARAMETER;
>    }
> 
> -  RequiredSize = sizeof (mSupportedRngAlgorithms);
> +  RequiredSize = ArchGetSupportedRngAlgorithmsSize ();
>    if (*RNGAlgorithmListSize < RequiredSize) {
>      Status = EFI_BUFFER_TOO_SMALL;
>    } else {
> @@ -87,81 +91,6 @@ RngGetInfo (
>    return Status;
>  }
> 
> -/**
> -  Produces and returns an RNG value using either the default or specified
> RNG algorithm.
> -
> -  @param[in]  This                    A pointer to the
> EFI_RNG_PROTOCOL instance.
> -  @param[in]  RNGAlgorithm            A pointer to the
> EFI_RNG_ALGORITHM that identifies the RNG
> -                                      algorithm to use. May be
> NULL in which case the function will
> -                                      use its default RNG
> algorithm.
> -  @param[in]  RNGValueLength          The length in bytes of the
> memory buffer pointed to by
> -                                      RNGValue. The driver shall
> return exactly this numbers of bytes.
> -  @param[out] RNGValue                A caller-allocated memory
> buffer filled by the driver with the
> -                                      resulting RNG value.
> -
> -  @retval EFI_SUCCESS                 The RNG value was returned
> successfully.
> -  @retval EFI_UNSUPPORTED             The algorithm specified by
> RNGAlgorithm is not supported by
> -                                      this driver.
> -  @retval EFI_DEVICE_ERROR            An RNG value could not be
> retrieved due to a hardware or
> -                                      firmware error.
> -  @retval EFI_NOT_READY               There is not enough random
> data available to satisfy the length
> -                                      requested by
> RNGValueLength.
> -  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or
> RNGValueLength is zero.
> -
> -**/
> -EFI_STATUS
> -EFIAPI
> -RngGetRNG (
> -  IN EFI_RNG_PROTOCOL            *This,
> -  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
> -  IN UINTN                       RNGValueLength,
> -  OUT UINT8                      *RNGValue
> -  )
> -{
> -  EFI_STATUS    Status;
> -
> -  if ((RNGValueLength == 0) || (RNGValue == NULL)) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> -
> -  Status = EFI_UNSUPPORTED;
> -  if (RNGAlgorithm == NULL) {
> -    //
> -    // Use the default RNG algorithm if RNGAlgorithm is NULL.
> -    //
> -    RNGAlgorithm = &gEfiRngAlgorithmSp80090Ctr256Guid;
> -  }
> -
> -  //
> -  // NIST SP800-90-AES-CTR-256 supported by RDRAND
> -  //
> -  if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmSp80090Ctr256Guid)) {
> -    Status = RdRandGetBytes (RNGValueLength, RNGValue);
> -    return Status;
> -  }
> -
> -  //
> -  // The "raw" algorithm is intended to provide entropy directly
> -  //
> -  if (CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
> -    //
> -    // When a DRBG is used on the output of a entropy source,
> -    // its security level must be at least 256 bits according to UEFI
Spec.
> -    //
> -    if (RNGValueLength < 32) {
> -      return EFI_INVALID_PARAMETER;
> -    }
> -
> -    Status = RdRandGenerateEntropy (RNGValueLength, RNGValue);
> -    return Status;
> -  }
> -
> -  //
> -  // Other algorithms were unsupported by this driver.
> -  //
> -  return Status;
> -}
> -
>  //
>  // The Random Number Generator (RNG) protocol
>  //
> --
> 2.26.2




^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] 回复: [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86
  2021-04-29  1:10   ` 回复: " gaoliming
@ 2021-04-29  3:01     ` Rebecca Cran
  0 siblings, 0 replies; 16+ messages in thread
From: Rebecca Cran @ 2021-04-29  3:01 UTC (permalink / raw)
  To: devel, gaoliming
  Cc: 'Jiewen Yao', 'Jian J Wang',
	'Michael D Kinney', 'Zhiguang Liu',
	'Ard Biesheuvel', 'Sami Mujawar'

On 4/28/21 7:10 PM, gaoliming wrote:
> Rebecca:
> 
>> -----邮件原件-----
>> 发件人: Rebecca Cran <rebecca@nuviainc.com>
>> 发送时间: 2021年4月29日 4:44
>> 收件人: devel@edk2.groups.io
>> 抄送: Rebecca Cran <rebecca@nuviainc.com>; Jiewen Yao
>> <jiewen.yao@intel.com>; Jian J Wang <jian.j.wang@intel.com>; Michael D
>> Kinney <michael.d.kinney@intel.com>; Liming Gao
>> <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>; Ard
>> Biesheuvel <ardb+tianocore@kernel.org>; Sami Mujawar
>> <Sami.Mujawar@arm.com>
>> 主题: [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in
>> addition to X86
>>
>> 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.
>>
>> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
>> ---
>>   MdePkg/MdePkg.dec                               |   9 +-
>>   MdePkg/MdePkg.dsc                               |   4 +-
>>   MdePkg/Library/BaseRngLib/BaseRngLib.inf        |  16 ++-
>>   MdePkg/Library/BaseRngLib/BaseRngLibInternals.h |  31 +++++
>>   MdePkg/Library/BaseRngLib/AArch64/Rndr.c        | 121
>> ++++++++++++++++++++
>>   MdePkg/Library/BaseRngLib/BaseRng.c             |  55 +++------
>>   MdePkg/Library/BaseRngLib/Rand/RdRand.c         | 103
>> +++++++++++++++++
>>   MdePkg/Library/BaseRngLib/BaseRngLib.uni        |   6 +-
>>   8 files changed, 291 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.in
>> f
>>
>> +[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..1dc3249a8c20 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 high-quality random numbers.
>>   #
>> +#  Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
>>   #  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
>>   #
>>   #  SPDX-License-Identifier: BSD-2-Clause-Patent
>> @@ -22,11 +23,18 @@ [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
>>
>>   [Packages]
>>     MdePkg/MdePkg.dec
>> diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
>> b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
>> new file mode 100644
>> index 000000000000..44fda69c9eec
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
>> @@ -0,0 +1,31 @@
>> +/** @file
>> +
>> +  Architecture specific interface to RNG functionality.
>> +
>> +Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
>> +
>> +SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef BASE_RNGLIB_INTERNALS_H_
>> +
>> +BOOLEAN
>> +EFIAPI
>> +ArchGetRandomNumber16 (
>> +  OUT UINT16 *Rand
>> +  );
>> +
>> +BOOLEAN
>> +EFIAPI
>> +ArchGetRandomNumber32 (
>> +  OUT UINT32 *Rand
>> +  );
>> +
>> +BOOLEAN
>> +EFIAPI
>> +ArchGetRandomNumber64 (
>> +  OUT UINT64 *Rand
>> +  );
>> +
>> +#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..19643237923a
>> --- /dev/null
>> +++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
>> @@ -0,0 +1,121 @@
>> +/** @file
>> +  Random number generator service that uses the RNDR instruction
>> +  to provide high-quality random numbers.
>> +
>> +  Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
>> +  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/BaseLib.h>
>> +#include <Library/DebugLib.h>
>> +
>> +#include <Library/RngLib.h>
>> +
>> +#include "BaseRngLibInternals.h"
>> +
>> +//
>> +// 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 RETURN_SUCCESS.
>> +
>> +  @retval RETURN_SUCCESS   The constructor always returns
>> EFI_SUCCESS.
>> +
>> +**/
>> +RETURN_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);
>> +  (void)Isar0;
>> +
> 
> What behavior for this statement "(void)Isar0;"?

It causes Isar0 to be 'used' in builds where ASSERT is compiled out, 
avoiding a warning/error.

-- 
Rebecca Cran

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64
  2021-04-28 20:44 ` [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64 Rebecca Cran
  2021-04-29  1:13   ` 回复: " gaoliming
@ 2021-04-29 10:35   ` Ard Biesheuvel
  1 sibling, 0 replies; 16+ messages in thread
From: Ard Biesheuvel @ 2021-04-29 10:35 UTC (permalink / raw)
  To: Rebecca Cran
  Cc: edk2-devel-groups-io, Jiewen Yao, Jian J Wang, Michael D Kinney,
	Liming Gao, Zhiguang Liu, Ard Biesheuvel, Sami Mujawar

On Wed, 28 Apr 2021 at 22:44, Rebecca Cran <rebecca@nuviainc.com> wrote:
>
> AARCH64 support has been added to BaseRngLib via the optional
> ARMv8.5 FEAT_RNG.
>
> Refactor RngDxe to support AARCH64, note support for it in the
> VALID_ARCHITECTURES line of RngDxe.inf and enable it in SecurityPkg.dsc.
>
> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
> ---
>  SecurityPkg/SecurityPkg.dsc                                   |  11 +-
>  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf           |  19 +++-
>  SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h       |  37 ++++++
>  SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h |   0
>  SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h  |   0
>  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h    |  88 ++++++++++++++
>  SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c       |  54 +++++++++
>  SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c     | 108 ++++++++++++++++++
>  SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c |   0
>  SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c  |   0
>  SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c        | 120 ++++++++++++++++++++
>  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c             | 117 ++++---------------
>  12 files changed, 450 insertions(+), 104 deletions(-)
>
> diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
> index 12ccd1634941..bd4b810bce61 100644
> --- a/SecurityPkg/SecurityPkg.dsc
> +++ b/SecurityPkg/SecurityPkg.dsc
> @@ -259,6 +259,12 @@ [Components]
>  [Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
>    SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
>
> +[Components.IA32, Components.X64, Components.AARCH64]
> +  #
> +  # Random Number Generator
> +  #
> +  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> +
>  [Components.IA32, Components.X64]
>    SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
>
> @@ -334,11 +340,6 @@ [Components.IA32, Components.X64]
>    SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresenceLib.inf
>    SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2PhysicalPresenceLib.inf
>
> -  #
> -  # Random Number Generator
> -  #
> -  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> -
>    #
>    # Opal Password solution
>    #
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> index 99d6f6b35fc2..c188b6076c00 100644
> --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
> @@ -26,15 +26,24 @@ [Defines]
>  #
>  # The following information is for reference only and not required by the build tools.
>  #
> -#  VALID_ARCHITECTURES           = IA32 X64
> +#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
>  #
>
>  [Sources.common]
>    RngDxe.c
> -  RdRand.c
> -  RdRand.h
> -  AesCore.c
> -  AesCore.h
> +  RngDxeInternals.h
> +
> +[Sources.IA32, Sources.X64]
> +  Rand/RngDxe.c
> +  Rand/RdRand.c
> +  Rand/RdRand.h
> +  Rand/AesCore.c
> +  Rand/AesCore.h
> +
> +[Sources.AARCH64]
> +  AArch64/RngDxe.c
> +  AArch64/Rndr.c
> +  AArch64/Rndr.h
>
>  [Packages]
>    MdePkg/MdePkg.dec
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
> new file mode 100644
> index 000000000000..458faa834a3d
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
> @@ -0,0 +1,37 @@
> +/** @file
> +  Header for the RNDR APIs used by RNG DXE driver.
> +
> +  Support API definitions for RNDR instruction access.
> +
> +
> +  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RNDR_H_
> +#define RNDR_H_
> +
> +#include <Library/BaseLib.h>
> +#include <Protocol/Rng.h>
> +
> +/**
> +  Calls RNDR to fill a buffer of arbitrary size with random bytes.
> +
> +  @param[in]   Length        Size of the buffer, in bytes, to fill with.
> +  @param[out]  RandBuffer    Pointer to the buffer to store the random result.
> +
> +  @retval EFI_SUCCESS        Random bytes generation succeeded.
> +  @retval EFI_NOT_READY      Failed to request random bytes.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RndrGetBytes (
> +  IN UINTN         Length,
> +  OUT UINT8        *RandBuffer
> +  );
> +
> +#endif  // RNDR_H_
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
> similarity index 100%
> rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
> similarity index 100%
> rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
> new file mode 100644
> index 000000000000..7e38fc2564f6
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
> @@ -0,0 +1,88 @@
> +/** @file
> +  Function prototypes for UEFI Random Number Generator protocol support.
> +
> +  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RNGDXE_INTERNALS_H_
> +#define RNGDXE_INTERNALS_H_
> +
> +extern EFI_RNG_ALGORITHM *mSUpportedRngAlgorithms;
> +
> +/**
> +  Returns information about the random number generation implementation.
> +
> +  @param[in]     This                 A pointer to the EFI_RNG_PROTOCOL instance.
> +  @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
> +                                      On output with a return code of EFI_SUCCESS, the size
> +                                      in bytes of the data returned in RNGAlgorithmList. On output
> +                                      with a return code of EFI_BUFFER_TOO_SMALL,
> +                                      the size of RNGAlgorithmList required to obtain the list.
> +  @param[out] RNGAlgorithmList        A caller-allocated memory buffer filled by the driver
> +                                      with one EFI_RNG_ALGORITHM element for each supported
> +                                      RNG algorithm. The list must not change across multiple
> +                                      calls to the same driver. The first algorithm in the list
> +                                      is the default algorithm for the driver.
> +
> +  @retval EFI_SUCCESS                 The RNG algorithm list was returned successfully.
> +  @retval EFI_UNSUPPORTED             The services is not supported by this driver.
> +  @retval EFI_DEVICE_ERROR            The list of algorithms could not be retrieved due to a
> +                                      hardware or firmware error.
> +  @retval EFI_INVALID_PARAMETER       One or more of the parameters are incorrect.
> +  @retval EFI_BUFFER_TOO_SMALL        The buffer RNGAlgorithmList is too small to hold the result.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetInfo (
> +  IN EFI_RNG_PROTOCOL             *This,
> +  IN OUT UINTN                    *RNGAlgorithmListSize,
> +  OUT EFI_RNG_ALGORITHM           *RNGAlgorithmList
> +  );
> +
> +/**
> +  Produces and returns an RNG value using either the default or specified RNG algorithm.
> +
> +  @param[in]  This                    A pointer to the EFI_RNG_PROTOCOL instance.
> +  @param[in]  RNGAlgorithm            A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
> +                                      algorithm to use. May be NULL in which case the function will
> +                                      use its default RNG algorithm.
> +  @param[in]  RNGValueLength          The length in bytes of the memory buffer pointed to by
> +                                      RNGValue. The driver shall return exactly this numbers of bytes.
> +  @param[out] RNGValue                A caller-allocated memory buffer filled by the driver with the
> +                                      resulting RNG value.
> +
> +  @retval EFI_SUCCESS                 The RNG value was returned successfully.
> +  @retval EFI_UNSUPPORTED             The algorithm specified by RNGAlgorithm is not supported by
> +                                      this driver.
> +  @retval EFI_DEVICE_ERROR            An RNG value could not be retrieved due to a hardware or
> +                                      firmware error.
> +  @retval EFI_NOT_READY               There is not enough random data available to satisfy the length
> +                                      requested by RNGValueLength.
> +  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or RNGValueLength is zero.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetRNG (
> +  IN EFI_RNG_PROTOCOL            *This,
> +  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
> +  IN UINTN                       RNGValueLength,
> +  OUT UINT8                      *RNGValue
> +  );
> +
> +/**
> +  Returns the size of the RNG algorithms structure.
> +
> +  @return Size of the EFI_RNG_ALGORITHM list.
> +**/
> +UINTN
> +EFIAPI
> +ArchGetSupportedRngAlgorithmsSize (
> +  VOID
> +  );
> +
> +#endif  // RNGDXE_INTERNALS_H_
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
> new file mode 100644
> index 000000000000..36166a9cbc13
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
> @@ -0,0 +1,54 @@
> +/** @file
> +  Support routines for RNDR instruction access.
> +
> +  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/RngLib.h>
> +
> +#include "Rndr.h"
> +
> +/**
> +  Calls RNDR to fill a buffer of arbitrary size with random bytes.
> +
> +  @param[in]   Length        Size of the buffer, in bytes, to fill with.
> +  @param[out]  RandBuffer    Pointer to the buffer to store the random result.
> +
> +  @retval EFI_SUCCESS        Random bytes generation succeeded.
> +  @retval EFI_NOT_READY      Failed to request random bytes.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RndrGetBytes (
> +  IN UINTN         Length,
> +  OUT UINT8        *RandBuffer
> +  )
> +{
> +  BOOLEAN     IsRandom;
> +  UINT64      TempRand;
> +
> +  while (Length > 0) {
> +    IsRandom = GetRandomNumber64 (&TempRand);
> +    if (!IsRandom) {
> +      return EFI_NOT_READY;
> +    }
> +    if (Length >= sizeof (TempRand)) {
> +      WriteUnaligned64 ((UINT64*)RandBuffer, TempRand);
> +      RandBuffer += sizeof (UINT64);
> +      Length -= sizeof (TempRand);
> +    } else {
> +      CopyMem (RandBuffer, &TempRand, Length);
> +      Length = 0;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
> new file mode 100644
> index 000000000000..18cca825e72d
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c
> @@ -0,0 +1,108 @@
> +/** @file
> +  RNG Driver to produce the UEFI Random Number Generator protocol.
> +
> +  The driver will use the new RNDR instruction to produce high-quality, high-performance
> +  entropy and random number.
> +
> +  RNG Algorithms defined in UEFI 2.4:
> +   - EFI_RNG_ALGORITHM_SP800_90_CTR_256_GUID  - Unsupported
> +   - EFI_RNG_ALGORITHM_RAW                    - Supported
> +   - EFI_RNG_ALGORITHM_SP800_90_HMAC_256_GUID - Unsupported
> +   - EFI_RNG_ALGORITHM_SP800_90_HASH_256_GUID - Unsupported
> +   - EFI_RNG_ALGORITHM_X9_31_3DES_GUID        - Unsupported
> +   - EFI_RNG_ALGORITHM_X9_31_AES_GUID         - Unsupported
> +
> +  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/TimerLib.h>
> +#include <Protocol/Rng.h>
> +
> +#include "Rndr.h"
> +
> +//
> +// Supported RNG Algorithms list by this driver.
> +//
> +EFI_RNG_ALGORITHM mSupportedRngAlgorithms[] = {
> +  EFI_RNG_ALGORITHM_RAW


This is incorrect. Both flavors of RNDR return the output of a DRBG,
the only difference is how often they are reseeded.

We might need a PCD here to define which exact DRBG implementation is
used in the hardware, and set this accordingly. We could use a VOID*
PTR PCD type to carry the GUID itself, in which case we could reuse
the same code for x86 as well, if I am not mistaken.

-- 
Ard.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] 回复: [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64
  2021-04-29  1:13   ` 回复: " gaoliming
@ 2021-04-29 15:50     ` Rebecca Cran
  0 siblings, 0 replies; 16+ messages in thread
From: Rebecca Cran @ 2021-04-29 15:50 UTC (permalink / raw)
  To: devel, gaoliming
  Cc: 'Jiewen Yao', 'Jian J Wang',
	'Michael D Kinney', 'Zhiguang Liu',
	'Ard Biesheuvel', 'Sami Mujawar'

On 4/28/21 7:13 PM, gaoliming wrote:
> Rebecca:
> 
>> -----邮件原件-----
>> 发件人: Rebecca Cran <rebecca@nuviainc.com>
>> 发送时间: 2021年4月29日 4:44
>> 收件人: devel@edk2.groups.io
>> 抄送: Rebecca Cran <rebecca@nuviainc.com>; Jiewen Yao
>> <jiewen.yao@intel.com>; Jian J Wang <jian.j.wang@intel.com>; Michael D
>> Kinney <michael.d.kinney@intel.com>; Liming Gao
>> <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>; Ard
>> Biesheuvel <ardb+tianocore@kernel.org>; Sami Mujawar
>> <Sami.Mujawar@arm.com>
>> 主题: [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64
>>
>> AARCH64 support has been added to BaseRngLib via the optional
>> ARMv8.5 FEAT_RNG.
>>
>> Refactor RngDxe to support AARCH64, note support for it in the
>> VALID_ARCHITECTURES line of RngDxe.inf and enable it in SecurityPkg.dsc.
>>
>> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
>> ---
>>   SecurityPkg/SecurityPkg.dsc                                   |
>> 11 +-
>>   SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf           |
>> 19 +++-
>>   SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h       |
>> 37 ++++++
>>   SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.h |
>> 0
>>   SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.h  |
>> 0
>>   SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h    |
>> 88 ++++++++++++++
>>   SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c       |
>> 54 +++++++++
>>   SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/RngDxe.c     |
>> 108 ++++++++++++++++++
>>   SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/AesCore.c |
>> 0
>>   SecurityPkg/RandomNumberGenerator/RngDxe/{ => Rand}/RdRand.c  |
>> 0
>>   SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RngDxe.c        |
>> 120 ++++++++++++++++++++
>>   SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.c             |
>> 117 ++++---------------
>>   12 files changed, 450 insertions(+), 104 deletions(-)
>>
>> diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
>> index 12ccd1634941..bd4b810bce61 100644
>> --- a/SecurityPkg/SecurityPkg.dsc
>> +++ b/SecurityPkg/SecurityPkg.dsc
>> @@ -259,6 +259,12 @@ [Components]
>>   [Components.IA32, Components.X64, Components.ARM,
>> Components.AARCH64]
>>     SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
>>
>> +[Components.IA32, Components.X64, Components.AARCH64]
>> +  #
>> +  # Random Number Generator
>> +  #
>> +  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
>> +
>>   [Components.IA32, Components.X64]
>>
>> SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigD
>> xe.inf
>>
>> @@ -334,11 +340,6 @@ [Components.IA32, Components.X64]
>>
>> SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/SmmTcg2PhysicalPresence
>> Lib.inf
>>
>> SecurityPkg/Library/SmmTcg2PhysicalPresenceLib/StandaloneMmTcg2Physic
>> alPresenceLib.inf
>>
>> -  #
>> -  # Random Number Generator
>> -  #
>> -  SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
>> -
>>     #
>>     # Opal Password solution
>>     #
>> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
>> b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
>> index 99d6f6b35fc2..c188b6076c00 100644
>> --- a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
>> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
>> @@ -26,15 +26,24 @@ [Defines]
>>   #
>>   # The following information is for reference only and not required by the
>> build tools.
>>   #
>> -#  VALID_ARCHITECTURES           = IA32 X64
>> +#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
>>   #
>>
>>   [Sources.common]
>>     RngDxe.c
>> -  RdRand.c
>> -  RdRand.h
>> -  AesCore.c
>> -  AesCore.h
>> +  RngDxeInternals.h
>> +
>> +[Sources.IA32, Sources.X64]
>> +  Rand/RngDxe.c
>> +  Rand/RdRand.c
>> +  Rand/RdRand.h
>> +  Rand/AesCore.c
>> +  Rand/AesCore.h
>> +
>> +[Sources.AARCH64]
>> +  AArch64/RngDxe.c
>> +  AArch64/Rndr.c
>> +  AArch64/Rndr.h
>>
>>   [Packages]
>>     MdePkg/MdePkg.dec
>> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
>> b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
>> new file mode 100644
>> index 000000000000..458faa834a3d
>> --- /dev/null
>> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.h
>> @@ -0,0 +1,37 @@
>> +/** @file
>> +  Header for the RNDR APIs used by RNG DXE driver.
>> +
>> +  Support API definitions for RNDR instruction access.
>> +
>> +
>> +  Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
>> +  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef RNDR_H_
>> +#define RNDR_H_
>> +
>> +#include <Library/BaseLib.h>
>> +#include <Protocol/Rng.h>
>> +
>> +/**
>> +  Calls RNDR to fill a buffer of arbitrary size with random bytes.
>> +
>> +  @param[in]   Length        Size of the buffer, in bytes, to fill with.
>> +  @param[out]  RandBuffer    Pointer to the buffer to store the random
>> result.
>> +
>> +  @retval EFI_SUCCESS        Random bytes generation succeeded.
>> +  @retval EFI_NOT_READY      Failed to request random bytes.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +RndrGetBytes (
>> +  IN UINTN         Length,
>> +  OUT UINT8        *RandBuffer
>> +  );
>> +
>> +#endif  // RNDR_H_
>> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
>> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
>> similarity index 100%
>> rename from SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.h
>> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/AesCore.h
>> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
>> b/SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
>> similarity index 100%
>> rename from SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.h
>> rename to SecurityPkg/RandomNumberGenerator/RngDxe/Rand/RdRand.h
>> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
>> b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
>> new file mode 100644
>> index 000000000000..7e38fc2564f6
>> --- /dev/null
>> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/RngDxeInternals.h
>> @@ -0,0 +1,88 @@
>> +/** @file
>> +  Function prototypes for UEFI Random Number Generator protocol
>> support.
>> +
>> +  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef RNGDXE_INTERNALS_H_
>> +#define RNGDXE_INTERNALS_H_
>> +
>> +extern EFI_RNG_ALGORITHM *mSUpportedRngAlgorithms;
>> +
>> +/**
>> +  Returns information about the random number generation
>> implementation.
>> +
>> +  @param[in]     This                 A pointer to the
>> EFI_RNG_PROTOCOL instance.
>> +  @param[in,out] RNGAlgorithmListSize On input, the size in bytes of
>> RNGAlgorithmList.
>> +                                      On output with a return code
>> of EFI_SUCCESS, the size
>> +                                      in bytes of the data returned
>> in RNGAlgorithmList. On output
>> +                                      with a return code of
>> EFI_BUFFER_TOO_SMALL,
>> +                                      the size of RNGAlgorithmList
>> required to obtain the list.
>> +  @param[out] RNGAlgorithmList        A caller-allocated memory
>> buffer filled by the driver
>> +                                      with one
>> EFI_RNG_ALGORITHM element for each supported
>> +                                      RNG algorithm. The list must
>> not change across multiple
>> +                                      calls to the same driver. The
>> first algorithm in the list
>> +                                      is the default algorithm for
>> the driver.
>> +
>> +  @retval EFI_SUCCESS                 The RNG algorithm list was
>> returned successfully.
>> +  @retval EFI_UNSUPPORTED             The services is not supported
>> by this driver.
>> +  @retval EFI_DEVICE_ERROR            The list of algorithms could
>> not be retrieved due to a
>> +                                      hardware or firmware error.
>> +  @retval EFI_INVALID_PARAMETER       One or more of the
>> parameters are incorrect.
>> +  @retval EFI_BUFFER_TOO_SMALL        The buffer RNGAlgorithmList
>> is too small to hold the result.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +RngGetInfo (
>> +  IN EFI_RNG_PROTOCOL             *This,
>> +  IN OUT UINTN                    *RNGAlgorithmListSize,
>> +  OUT EFI_RNG_ALGORITHM           *RNGAlgorithmList
>> +  );
>> +
>> +/**
>> +  Produces and returns an RNG value using either the default or specified
>> RNG algorithm.
>> +
>> +  @param[in]  This                    A pointer to the
>> EFI_RNG_PROTOCOL instance.
>> +  @param[in]  RNGAlgorithm            A pointer to the
>> EFI_RNG_ALGORITHM that identifies the RNG
>> +                                      algorithm to use. May be
>> NULL in which case the function will
>> +                                      use its default RNG
>> algorithm.
>> +  @param[in]  RNGValueLength          The length in bytes of the
>> memory buffer pointed to by
>> +                                      RNGValue. The driver shall
>> return exactly this numbers of bytes.
>> +  @param[out] RNGValue                A caller-allocated memory
>> buffer filled by the driver with the
>> +                                      resulting RNG value.
>> +
>> +  @retval EFI_SUCCESS                 The RNG value was returned
>> successfully.
>> +  @retval EFI_UNSUPPORTED             The algorithm specified by
>> RNGAlgorithm is not supported by
>> +                                      this driver.
>> +  @retval EFI_DEVICE_ERROR            An RNG value could not be
>> retrieved due to a hardware or
>> +                                      firmware error.
>> +  @retval EFI_NOT_READY               There is not enough random
>> data available to satisfy the length
>> +                                      requested by
>> RNGValueLength.
>> +  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or
>> RNGValueLength is zero.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +RngGetRNG (
>> +  IN EFI_RNG_PROTOCOL            *This,
>> +  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
>> +  IN UINTN                       RNGValueLength,
>> +  OUT UINT8                      *RNGValue
>> +  );
>> +
>> +/**
>> +  Returns the size of the RNG algorithms structure.
>> +
>> +  @return Size of the EFI_RNG_ALGORITHM list.
>> +**/
>> +UINTN
>> +EFIAPI
>> +ArchGetSupportedRngAlgorithmsSize (
>> +  VOID
>> +  );
>> +
>> +#endif  // RNGDXE_INTERNALS_H_
>> diff --git a/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
>> b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
>> new file mode 100644
>> index 000000000000..36166a9cbc13
>> --- /dev/null
>> +++ b/SecurityPkg/RandomNumberGenerator/RngDxe/AArch64/Rndr.c
>> @@ -0,0 +1,54 @@
>> +/** @file
>> +  Support routines for RNDR instruction access.
>> +
>> +  Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
>> +  Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
>> +  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/RngLib.h>
>> +
>> +#include "Rndr.h"
>> +
>> +/**
>> +  Calls RNDR to fill a buffer of arbitrary size with random bytes.
>> +
>> +  @param[in]   Length        Size of the buffer, in bytes, to fill with.
>> +  @param[out]  RandBuffer    Pointer to the buffer to store the random
>> result.
>> +
>> +  @retval EFI_SUCCESS        Random bytes generation succeeded.
>> +  @retval EFI_NOT_READY      Failed to request random bytes.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +RndrGetBytes (
>> +  IN UINTN         Length,
>> +  OUT UINT8        *RandBuffer
>> +  )
>> +{
>> +  BOOLEAN     IsRandom;
>> +  UINT64      TempRand;
>> +
>> +  while (Length > 0) {
>> +    IsRandom = GetRandomNumber64 (&TempRand);
>> +    if (!IsRandom) {
>> +      return EFI_NOT_READY;
>> +    }
>> +    if (Length >= sizeof (TempRand)) {
>> +      WriteUnaligned64 ((UINT64*)RandBuffer, TempRand);
>> +      RandBuffer += sizeof (UINT64);
>> +      Length -= sizeof (TempRand);
>> +    } else {
>> +      CopyMem (RandBuffer, &TempRand, Length);
>> +      Length = 0;
>> +    }
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
> 
> Can this function be shared between X86 and AARCH64?

Yes. I've removed it, and will send out a v2 series.

-- 
Rebecca Cran

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions
  2021-04-28 20:44 ` [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions Rebecca Cran
  2021-04-29  1:08   ` 回复: " gaoliming
@ 2021-05-04 21:06   ` Sami Mujawar
  2021-05-04 21:42     ` Rebecca Cran
  1 sibling, 1 reply; 16+ messages in thread
From: Sami Mujawar @ 2021-05-04 21:06 UTC (permalink / raw)
  To: Rebecca Cran, devel
  Cc: Jiewen Yao, Jian J Wang, Michael D Kinney, Liming Gao,
	Zhiguang Liu, Ard Biesheuvel, nd

Hi Rebecca,

Please find my response inline marked [SAMI].

Regards,

Sami Mujawar


On 28/04/2021 09:44 PM, Rebecca Cran wrote:
> 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 <rebecca@nuviainc.com>
> ---
>   MdePkg/Library/BaseLib/BaseLib.inf                |  4 ++
>   MdePkg/Include/Library/BaseLib.h                  | 47 +++++++++++++++++
>   MdePkg/Library/BaseLib/BaseLibInternals.h         |  6 +++
>   MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S   | 29 +++++++++++
>   MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm | 28 ++++++++++
>   MdePkg/Library/BaseLib/AArch64/ArmRng.S           | 51 ++++++++++++++++++
>   MdePkg/Library/BaseLib/AArch64/ArmRng.asm         | 55 ++++++++++++++++++++
>   7 files changed, 220 insertions(+)
>
> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
> index b76f3af380ea..7f582079d786 100644
> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> @@ -380,6 +380,8 @@ [Sources.AARCH64]
>     AArch64/SetJumpLongJump.S         | GCC
>     AArch64/CpuBreakpoint.S           | GCC
>     AArch64/SpeculationBarrier.S      | GCC
> +  AArch64/ArmRng.S                  | GCC
> +  AArch64/ArmReadIdIsar0.S          | GCC
>   
>     AArch64/MemoryFence.asm           | MSFT
>     AArch64/SwitchStack.asm           | MSFT
> @@ -389,6 +391,8 @@ [Sources.AARCH64]
>     AArch64/SetJumpLongJump.asm       | MSFT
>     AArch64/CpuBreakpoint.asm         | MSFT
>     AArch64/SpeculationBarrier.asm    | MSFT
> +  AArch64/ArmRng.asm                | MSFT
> +  AArch64/ArmReadIdIsar0.asm        | MSFT
>   
>   [Sources.RISCV64]
>     Math64.c
> diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
> index 7253997a6f8c..60cf559b0849 100644
> --- a/MdePkg/Include/Library/BaseLib.h
> +++ b/MdePkg/Include/Library/BaseLib.h
> @@ -7519,4 +7519,51 @@ PatchInstructionX86 (
>     );
>   
>   #endif // defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)
> +
> +#if defined (MDE_CPU_AARCH64)
> +
> +/**
> +  Reads the ID_AA64ISAR0 Register.
> +
> +  @return The contents of the ID_AA64ISAR0 Register
> +
> +**/
> +UINT64
> +EFIAPI
> +ArmReadIdIsar0 (
> +  VOID
> +  );
> +
[SAMI] Should this function be part of ArmLib?
[/SAMI]
> +/**
> +  Generates a random number using the RNDR instruction.
> +
> +  @param[out]  The generated random number
> +
> +  @retval TRUE  Success: a random number was successfully generated
> +  @retval FALSE Failure: a random number was unable to be generated
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +ArmRndr (
> +  OUT UINT64 *Rand
> +  );
> +
> +/**
> +  Generates a random number using the RNDRRS instruction.
> +
> +  @param[out]  The generated random number
> +
> +  @retval TRUE  Success: a random number was successfully generated
> +  @retval FALSE Failure: a random number was unable to be generated
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +ArmRndrrs (
> +  OUT UINT64 *Rand
> +  );
> +
> +#endif // defined (MDE_CPU_AARCH64)
> +
>   #endif // !defined (__BASE_LIB__)
> diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h b/MdePkg/Library/BaseLib/BaseLibInternals.h
> index 6837d67d90cf..4ae79a4e7ab4 100644
> --- a/MdePkg/Library/BaseLib/BaseLibInternals.h
> +++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
> @@ -862,6 +862,12 @@ InternalX86RdRand64  (
>     OUT     UINT64                    *Rand
>     );
[SAMI] I can see that the X86RdRand64 functions are implemented in this 
library. However, I am not sure we want ArmRndr() and ArmRndrrs() in 
BaseLib.
I think these functions should be in BaseRngLib and should not be 
available publicly. The RngLib interface should be used by edk2 modules. 
What do you think?
[/SAMI]
>   
> +#elif defined (MDE_CPU_AARCH64)
> +
> +// RNDR, Random Number
> +#define RNDR      S3_3_C2_C4_0
> +#define RNDRRS    S3_3_C2_C4_1
> +
>   #else
>   
>   #endif
> diff --git a/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S
> new file mode 100644
> index 000000000000..b31e565c7955
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.S
> @@ -0,0 +1,29 @@
> +#------------------------------------------------------------------------------
> +#
> +# ArmReadIdIsar0() for AArch64
> +#
> +# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#------------------------------------------------------------------------------
> +
> +.text
> +.p2align 2
> +GCC_ASM_EXPORT(ArmReadIdIsar0)
> +
> +#/**
> +#  Reads 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/BaseLib/AArch64/ArmReadIdIsar0.asm b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm
> new file mode 100644
> index 000000000000..1f1d15626cc2
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/AArch64/ArmReadIdIsar0.asm
> @@ -0,0 +1,28 @@
> +;------------------------------------------------------------------------------
> +;
> +; ArmReadIdIsar0() for AArch64
> +;
> +; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;------------------------------------------------------------------------------
> +
> +  EXPORT ArmReadIdIsar0
> +  AREA BaseLib_LowLevel, CODE, READONLY
> +
> +;/**
> +;  Reads 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/BaseLib/AArch64/ArmRng.S b/MdePkg/Library/BaseLib/AArch64/ArmRng.S
> new file mode 100644
> index 000000000000..fc2adb660d21
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/AArch64/ArmRng.S
> @@ -0,0 +1,51 @@
> +#------------------------------------------------------------------------------
> +#
> +# ArmRndr() and ArmRndrrs() for AArch64
> +#
> +# Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#------------------------------------------------------------------------------
> +
> +#include "BaseLibInternals.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.
> +#
> +#**/
> +#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.
> +#
> +#**/
> +#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/BaseLib/AArch64/ArmRng.asm b/MdePkg/Library/BaseLib/AArch64/ArmRng.asm
> new file mode 100644
> index 000000000000..ed8d1a81bdfe
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/AArch64/ArmRng.asm
> @@ -0,0 +1,55 @@
> +;------------------------------------------------------------------------------
> +;
> +; ArmRndr() and ArmRndrrs() for AArch64
> +;
> +; Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
> +;
> +; SPDX-License-Identifier: BSD-2-Clause-Patent
> +;
> +;------------------------------------------------------------------------------
> +
> +#include "BaseLibInternals.h"
> +
> +  EXPORT ArmRndr
> +  EXPORT ArmRndrrs
> +  AREA BaseLib_LowLevel, CODE, READONLY
> +
> +
> +;/**
> +;  Generates a random number using RNDR.
> +;  Returns TRUE on success; FALSE on failure.
> +;
> +;**/
> +;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.
> +;
> +;**/
> +;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
> +


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86
  2021-04-28 20:44 ` [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86 Rebecca Cran
  2021-04-29  1:10   ` 回复: " gaoliming
@ 2021-05-04 21:09   ` Sami Mujawar
  2021-05-05 19:27     ` [edk2-devel] " Rebecca Cran
  2021-05-06 21:47     ` Rebecca Cran
  1 sibling, 2 replies; 16+ messages in thread
From: Sami Mujawar @ 2021-05-04 21:09 UTC (permalink / raw)
  To: Rebecca Cran, devel
  Cc: Jiewen Yao, Jian J Wang, Michael D Kinney, Liming Gao,
	Zhiguang Liu, Ard Biesheuvel, nd

[-- Attachment #1: Type: text/plain, Size: 16739 bytes --]

Hi Rebecca,

Please see my response inline marked [SAMI].

Regards,

Sami Mujawar

On 28/04/2021 09:44 PM, Rebecca Cran wrote:
> 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.
>
> Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
> ---
>   MdePkg/MdePkg.dec                               |   9 +-
>   MdePkg/MdePkg.dsc                               |   4 +-
>   MdePkg/Library/BaseRngLib/BaseRngLib.inf        |  16 ++-
>   MdePkg/Library/BaseRngLib/BaseRngLibInternals.h |  31 +++++
>   MdePkg/Library/BaseRngLib/AArch64/Rndr.c        | 121 ++++++++++++++++++++
>   MdePkg/Library/BaseRngLib/BaseRng.c             |  55 +++------
>   MdePkg/Library/BaseRngLib/Rand/RdRand.c         | 103 +++++++++++++++++
>   MdePkg/Library/BaseRngLib/BaseRngLib.uni        |   6 +-
>   8 files changed, 291 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..1dc3249a8c20 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 high-quality random numbers.
>   #
> +#  Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
>   #  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
>   #
>   #  SPDX-License-Identifier: BSD-2-Clause-Patent
> @@ -22,11 +23,18 @@ [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
>   
>   [Packages]
>     MdePkg/MdePkg.dec
> diff --git a/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
> new file mode 100644
> index 000000000000..44fda69c9eec
> --- /dev/null
> +++ b/MdePkg/Library/BaseRngLib/BaseRngLibInternals.h
> @@ -0,0 +1,31 @@
> +/** @file
> +
> +  Architecture specific interface to RNG functionality.
> +
> +Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef BASE_RNGLIB_INTERNALS_H_
> +
> +BOOLEAN
> +EFIAPI
> +ArchGetRandomNumber16 (
> +  OUT UINT16 *Rand
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +ArchGetRandomNumber32 (
> +  OUT UINT32 *Rand
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +ArchGetRandomNumber64 (
> +  OUT UINT64 *Rand
> +  );
[SAMI] Please add doxygen headers for the above functions.
[/SAMI]
> +
> +#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..19643237923a
> --- /dev/null
> +++ b/MdePkg/Library/BaseRngLib/AArch64/Rndr.c
> @@ -0,0 +1,121 @@
> +/** @file
> +  Random number generator service that uses the RNDR instruction
> +  to provide high-quality random numbers.
> +
> +  Copyright (c) 2020, NUVIA Inc. All rights reserved.<BR>
> +  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include <Library/RngLib.h>
> +
> +#include "BaseRngLibInternals.h"
> +
> +//
> +// 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 RETURN_SUCCESS.
> +
> +  @retval RETURN_SUCCESS   The constructor always returns EFI_SUCCESS.
> +
> +**/
> +RETURN_STATUS
[SAMI] Should the return type be EFI_STATUS? See 
https://edk2-docs.gitbook.io/edk-ii-module-writer-s-guide/3_module_development/33_additional_steps_for_library_instances#3-3-2-1-types-of-library-constructor-functions
> +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);
> +  (void)Isar0;
[SAMI] ASSERTs will vanish in the release builds. So, I think this needs 
to be an if condition. If RNDR is not supported RETURN_UNSUPPORTED 
should be returned.
However, it appears thatthe auto generated function 
ProcessLibraryConstructorList() disregards the error code returned by 
the constructor (see Build\...\AutoGen.c files). So it looks like the 
loading operation would continue in release builds despite of an error.
I am not aware if this is the desired behavior or why the status code 
returned by the constructor is disregarded.

However, this would be a probem in the current case as subsequent calls 
to generate random numbers will result in an undefined instruction 
exception.
To prevent this, I think the above check should be done in either
    - ArmRndr()/ArmRndrrs()
   or
    - preferably in ArchGetRandomNumberXX(), which should return an 
error code EFI_UNSUPPORTED, EFI_NOT_READY or EFI_SUCCESS. However, the 
impact on IA32/x64 code needs to be evaluated.

[/SAMI]
> +
> +  return RETURN_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);
> +}
> +
> diff --git a/MdePkg/Library/BaseRngLib/BaseRng.c b/MdePkg/Library/BaseRngLib/BaseRng.c
> index 7ad7aec9d38f..072fa37d3394 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 high-quality random numbers.
>   
> +Copyright (c) 2021, NUVIA Inc. All rights reserved.<BR>
>   Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
>   SPDX-License-Identifier: BSD-2-Clause-Patent
>   
>   **/
> @@ -10,46 +12,15 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>   #include <Library/BaseLib.h>
>   #include <Library/DebugLib.h>
>   
> -//
> -// 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.
> @@ -75,8 +46,8 @@ GetRandomNumber16 (
>     //
>     // 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;
>       }
>     }
> @@ -108,8 +79,8 @@ GetRandomNumber32 (
>     //
>     // 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;
>       }
>     }
> @@ -141,8 +112,8 @@ GetRandomNumber64 (
>     //
>     // 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;
>       }
>     }
> diff --git a/MdePkg/Library/BaseRngLib/Rand/RdRand.c b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
> new file mode 100644
> index 000000000000..3f1378064b4c
> --- /dev/null
> +++ b/MdePkg/Library/BaseRngLib/Rand/RdRand.c
> @@ -0,0 +1,103 @@
> +/** @file
> +  Random number generator services that uses RdRand instruction access
> +  to provide high-quality random numbers.
> +
> +Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +
> +#include "BaseRngLibInternals.h"
> +
> +//
> +// Bit mask used to determine if RdRand instruction is supported.
> +//
> +#define RDRAND_MASK                  BIT30
> +
> +/**
> +  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.
> +
> +  @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);
> +}
> +
> diff --git a/MdePkg/Library/BaseRngLib/BaseRngLib.uni b/MdePkg/Library/BaseRngLib/BaseRngLib.uni
> index f3ed954c5209..8c7fe1219450 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 high-quality
> +// random numbers.
>   //
>   // Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
>   //
> @@ -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 high-quality random numbers"
>   


[-- Attachment #2: Type: text/html, Size: 17158 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions
  2021-05-04 21:06   ` Sami Mujawar
@ 2021-05-04 21:42     ` Rebecca Cran
  0 siblings, 0 replies; 16+ messages in thread
From: Rebecca Cran @ 2021-05-04 21:42 UTC (permalink / raw)
  To: Sami Mujawar, devel
  Cc: Jiewen Yao, Jian J Wang, Michael D Kinney, Liming Gao,
	Zhiguang Liu, Ard Biesheuvel, nd

On 5/4/21 3:06 PM, Sami Mujawar wrote:

>> +#if defined (MDE_CPU_AARCH64)
>> +
>> +/**
>> +  Reads the ID_AA64ISAR0 Register.
>> +
>> +  @return The contents of the ID_AA64ISAR0 Register
>> +
>> +**/
>> +UINT64
>> +EFIAPI
>> +ArmReadIdIsar0 (
>> +  VOID
>> +  );
>> +
> [SAMI] Should this function be part of ArmLib?
> [/SAMI]

It's currently used in BaseRngLib, and since there are other Aarch64 
functions in BaseLib I thought it should belong here - especially since 
I don't think MdePkg can depend on ArmPkg?

>> diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h 
>> b/MdePkg/Library/BaseLib/BaseLibInternals.h
>> index 6837d67d90cf..4ae79a4e7ab4 100644
>> --- a/MdePkg/Library/BaseLib/BaseLibInternals.h
>> +++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
>> @@ -862,6 +862,12 @@ InternalX86RdRand64  (
>>     OUT     UINT64                    *Rand
>>     );
> [SAMI] I can see that the X86RdRand64 functions are implemented in this 
> library. However, I am not sure we want ArmRndr() and ArmRndrrs() in 
> BaseLib.
> I think these functions should be in BaseRngLib and should not be 
> available publicly. The RngLib interface should be used by edk2 modules. 
> What do you think?
> [/SAMI]
That makes sense - I'll move them.

-- 
Rebecca Cran

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86
  2021-05-04 21:09   ` Sami Mujawar
@ 2021-05-05 19:27     ` Rebecca Cran
  2021-05-06 21:47     ` Rebecca Cran
  1 sibling, 0 replies; 16+ messages in thread
From: Rebecca Cran @ 2021-05-05 19:27 UTC (permalink / raw)
  To: devel, sami.mujawar
  Cc: Jiewen Yao, Jian J Wang, Michael D Kinney, Liming Gao,
	Zhiguang Liu, Ard Biesheuvel, nd

On 5/4/21 3:09 PM, Sami Mujawar wrote:
>> +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);
>> +  (void)Isar0;
> [SAMI] ASSERTs will vanish in the release builds. So, I think this needs 
> to be an if condition. If RNDR is not supported RETURN_UNSUPPORTED 
> should be returned.
> However, it appears thatthe auto generated function 
> ProcessLibraryConstructorList() disregards the error code returned by 
> the constructor (see Build\...\AutoGen.c files). So it looks like the 
> loading operation would continue in release builds despite of an error.
> I am not aware if this is the desired behavior or why the status code 
> returned by the constructor is disregarded.
> 
> However, this would be a probem in the current case as subsequent calls 
> to generate random numbers will result in an undefined instruction 
> exception.
> To prevent this, I think the above check should be done in either
>     - ArmRndr()/ArmRndrrs()
>    or
>     - preferably in ArchGetRandomNumberXX(), which should return an 
> error code EFI_UNSUPPORTED, EFI_NOT_READY or EFI_SUCCESS. However, the 
> impact on IA32/x64 code needs to be evaluated.
> 
> [/SAMI]

Yes, I noticed that but the same problem exists for the IA32/x64 code, 
since it might not support RDRAND/RDSEED. Should I change the BaseRngLib 
interface to return an EFI_STATUS instead of BOOLEAN? Or would that be 
too disruptive?

-- 
Rebecca Cran

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] 回复: [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions
  2021-04-29  1:08   ` 回复: " gaoliming
@ 2021-05-05 21:02     ` Rebecca Cran
  0 siblings, 0 replies; 16+ messages in thread
From: Rebecca Cran @ 2021-05-05 21:02 UTC (permalink / raw)
  To: devel, gaoliming
  Cc: 'Jiewen Yao', 'Jian J Wang',
	'Michael D Kinney', 'Zhiguang Liu',
	'Ard Biesheuvel', 'Sami Mujawar'

On 4/28/21 7:08 PM, gaoliming wrote:
> Rebecca:
>    Can you submit one BZ for this new feature?

Create https://bugzilla.tianocore.org/show_bug.cgi?id=3368

>> +/**
>> +  Generates a random number using the RNDRRS instruction.
>> +
>> +  @param[out]  The generated random number
>> +
>> +  @retval TRUE  Success: a random number was successfully generated
>> +  @retval FALSE Failure: a random number was unable to be generated
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +ArmRndrrs (
>> +  OUT UINT64 *Rand
>> +  );
>> +
> 
> What usage is for this API ArmRndrrs()? I don't see it is used in RngLib.

It's not used at the moment, but it uses the RNDRRS instruction, which 
re-seeds the PRNG immediately before generating a random number.

-- 
Rebecca Cran

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [edk2-devel] [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86
  2021-05-04 21:09   ` Sami Mujawar
  2021-05-05 19:27     ` [edk2-devel] " Rebecca Cran
@ 2021-05-06 21:47     ` Rebecca Cran
  1 sibling, 0 replies; 16+ messages in thread
From: Rebecca Cran @ 2021-05-06 21:47 UTC (permalink / raw)
  To: devel, sami.mujawar
  Cc: Jiewen Yao, Jian J Wang, Michael D Kinney, Liming Gao,
	Zhiguang Liu, Ard Biesheuvel, nd

On 5/4/21 3:09 PM, Sami Mujawar wrote:

>> +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);
>> +  (void)Isar0;
> [SAMI] ASSERTs will vanish in the release builds. So, I think this needs 
> to be an if condition. If RNDR is not supported RETURN_UNSUPPORTED 
> should be returned.
> However, it appears thatthe auto generated function 
> ProcessLibraryConstructorList() disregards the error code returned by 
> the constructor (see Build\...\AutoGen.c files). So it looks like the 
> loading operation would continue in release builds despite of an error.
> I am not aware if this is the desired behavior or why the status code 
> returned by the constructor is disregarded.
> 
> However, this would be a probem in the current case as subsequent calls 
> to generate random numbers will result in an undefined instruction 
> exception.
> To prevent this, I think the above check should be done in either
>     - ArmRndr()/ArmRndrrs()
>    or
>     - preferably in ArchGetRandomNumberXX(), which should return an 
> error code EFI_UNSUPPORTED, EFI_NOT_READY or EFI_SUCCESS. However, the 
> impact on IA32/x64 code needs to be evaluated.

I've updated both the x86 and aarch64 code to add checks that the RDRAND 
and RNDR instructions are supported before trying to use them in 
GetRandomNumber[16,32,64,128].
However, it causes the X64 CryptoPkg host-based unit tests to fail 
because UnitTestHostBaseLibAsmCpuid just sets all the OUT parameters to 
0, which causes RngDxe to think RDRAND isn't supported.

Should the unit tests be using BaseRngLibTimerLib instead of BaseRngLib? 
Or should I leave the x86 code as it was, with the ASSERT in the 
constructor and no further checks at the time of use?

-- 
Rebecca Cran

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2021-05-06 21:47 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-04-28 20:44 [PATCH 0/3] MdePkg,SecurityPkg: Update BaseRngLib and RngDxe to support ARMv8.5 FEAT_RNG Rebecca Cran
2021-04-28 20:44 ` [PATCH 1/3] MdePkg/BaseLib: Add support for ARMv8.5 RNG instructions Rebecca Cran
2021-04-29  1:08   ` 回复: " gaoliming
2021-05-05 21:02     ` [edk2-devel] " Rebecca Cran
2021-05-04 21:06   ` Sami Mujawar
2021-05-04 21:42     ` Rebecca Cran
2021-04-28 20:44 ` [PATCH 2/3] MdePkg: Refactor BaseRngLib to support AARCH64 in addition to X86 Rebecca Cran
2021-04-29  1:10   ` 回复: " gaoliming
2021-04-29  3:01     ` [edk2-devel] " Rebecca Cran
2021-05-04 21:09   ` Sami Mujawar
2021-05-05 19:27     ` [edk2-devel] " Rebecca Cran
2021-05-06 21:47     ` Rebecca Cran
2021-04-28 20:44 ` [PATCH 3/3] SecurityPkg: Add support for RngDxe on AARCH64 Rebecca Cran
2021-04-29  1:13   ` 回复: " gaoliming
2021-04-29 15:50     ` [edk2-devel] " Rebecca Cran
2021-04-29 10:35   ` Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox