public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 00/11] Use proper entropy sources
@ 2019-11-14  2:17 Wang, Jian J
  2019-11-14  2:17 ` [PATCH 01/11] NetworkPkg/NetworkPkg.dsc: specify RngLib instance for build Wang, Jian J
                   ` (11 more replies)
  0 siblings, 12 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel
  Cc: Ard Biesheuvel, Bret Barkelew, Chao Zhang, Jiaxin Wu, Jiewen Yao,
	Jordan Justen, Laszlo Ersek, Leif Lindholm, Liming Gao,
	Maciej Rabeda, Matthew Carlson, Michael D Kinney, Ray Ni,
	Sean Brogan, Siyuan Fu, Xiaoyu Lu

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1871

Patch series summary:
 - Add BaseRngLibNull to package dsc
 - Add DxeRngLibRngProtocol to make use EFI_RNG_PROTOCOL
 - Add RdSeed interface and RngLibRdSeed for IA32/X64 arch
 - Remove following files
    rand_pool_noise.h
    rand_pool_noise_tsc.c
    rand_pool_noise.c
 - Update rand_pool.c to use RngLib interface directly
   and the drop the TimerLib depenency from OpensslLib
 - Update OVMF platform dsc to use DxeRngLibRngProtocol
   when necessary

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Bret Barkelew <bret.barkelew@microsoft.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@intel.com>
Cc: Matthew Carlson <macarl@microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>

Jian J Wang (11):
  NetworkPkg/NetworkPkg.dsc: specify RngLib instance for build
  SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib instances
  FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib instances in dsc files
  MdePkg/BaseLib: add interface to wrap rdseed IA instruction
  SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
  SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib
  SecurityPkg/SecurityPkg.dsc: add new RngLib instances for build
  OvmfPkg: specify RngLib instances in dsc files
  ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances in dsc files
  CryptoPkg/OpensslLib: use RngLib to get high quality random entropy
  FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib instance

 ArmVirtPkg/ArmVirt.dsc.inc                    |   2 +
 CryptoPkg/CryptoPkg.dsc                       |   1 +
 CryptoPkg/Library/OpensslLib/OpensslLib.inf   |  15 +-
 .../Library/OpensslLib/OpensslLibCrypto.inf   |  15 +-
 CryptoPkg/Library/OpensslLib/rand_pool.c      | 253 ++----------------
 .../Library/OpensslLib/rand_pool_noise.c      |  29 --
 .../Library/OpensslLib/rand_pool_noise.h      |  29 --
 .../Library/OpensslLib/rand_pool_noise_tsc.c  |  43 ---
 FmpDevicePkg/FmpDevicePkg.dsc                 |   2 +-
 MdePkg/Include/Library/BaseLib.h              |  51 ++++
 MdePkg/Library/BaseLib/BaseLib.inf            |   4 +
 MdePkg/Library/BaseLib/BaseLibInternals.h     |  46 ++++
 MdePkg/Library/BaseLib/Ia32/RdSeed.nasm       |  87 ++++++
 MdePkg/Library/BaseLib/X64/RdSeed.nasm        |  80 ++++++
 MdePkg/Library/BaseLib/X86RdSeed.c            |  73 +++++
 NetworkPkg/NetworkPkg.dsc                     |   1 +
 OvmfPkg/OvmfPkgIa32.dsc                       |   5 +
 OvmfPkg/OvmfPkgIa32X64.dsc                    |   5 +
 OvmfPkg/OvmfPkgX64.dsc                        |   5 +
 OvmfPkg/OvmfXen.dsc                           |   5 +
 .../DxeRngLibRngProtocol.c                    | 200 ++++++++++++++
 .../DxeRngLibRngProtocol.inf                  |  42 +++
 .../DxeRngLibRngProtocol.uni                  |  14 +
 .../RngLibRdSeed/RngLibRdSeed.inf             |  37 +++
 .../RngLibRdSeed/RngLibRdSeed.uni             |  18 ++
 .../RngLibRdSeed/RngRdSeed.c                  | 189 +++++++++++++
 SecurityPkg/SecurityPkg.dsc                   |   6 +
 SignedCapsulePkg/SignedCapsulePkg.dsc         |   6 +
 28 files changed, 909 insertions(+), 354 deletions(-)
 delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.c
 delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.h
 delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
 create mode 100644 MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
 create mode 100644 MdePkg/Library/BaseLib/X64/RdSeed.nasm
 create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c
 create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c
 create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
 create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.uni
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSeed.c

-- 
2.17.1.windows.2


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

* [PATCH 01/11] NetworkPkg/NetworkPkg.dsc: specify RngLib instance for build
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14  2:17 ` [PATCH 02/11] SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib instances Wang, Jian J
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel; +Cc: Jiaxin Wu, Siyuan Fu, Maciej Rabeda, Liming Gao, Ray Ni

Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib.
RngLibNull is used by default.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Maciej Rabeda <maciej.rabeda@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 NetworkPkg/NetworkPkg.dsc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc
index b149453d26..bc324a06a1 100644
--- a/NetworkPkg/NetworkPkg.dsc
+++ b/NetworkPkg/NetworkPkg.dsc
@@ -47,6 +47,7 @@
 !else
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
   IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
   TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
 !endif
-- 
2.17.1.windows.2


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

* [PATCH 02/11] SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib instances
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
  2019-11-14  2:17 ` [PATCH 01/11] NetworkPkg/NetworkPkg.dsc: specify RngLib instance for build Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14  2:17 ` [PATCH 03/11] FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib instances in dsc files Wang, Jian J
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel; +Cc: Liming Gao, Michael D Kinney, Ray Ni

Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib.
RngLibNull is used by default just for build.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 SignedCapsulePkg/SignedCapsulePkg.dsc | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/SignedCapsulePkg/SignedCapsulePkg.dsc b/SignedCapsulePkg/SignedCapsulePkg.dsc
index c5080ec1dd..e8af37be8c 100644
--- a/SignedCapsulePkg/SignedCapsulePkg.dsc
+++ b/SignedCapsulePkg/SignedCapsulePkg.dsc
@@ -119,6 +119,7 @@
 !else
   IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
 !endif
 
@@ -134,6 +135,7 @@
 !else
   IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
 !endif
 
@@ -148,6 +150,7 @@
 !else
   IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
 !endif
 
@@ -171,6 +174,7 @@
 !else
   IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf
 !endif
 
@@ -183,6 +187,7 @@
 !else
   IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
 !endif
 
@@ -195,6 +200,7 @@
 !else
   IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
 !endif
 
-- 
2.17.1.windows.2


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

* [PATCH 03/11] FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib instances in dsc files
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
  2019-11-14  2:17 ` [PATCH 01/11] NetworkPkg/NetworkPkg.dsc: specify RngLib instance for build Wang, Jian J
  2019-11-14  2:17 ` [PATCH 02/11] SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib instances Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14  2:17 ` [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction Wang, Jian J
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel; +Cc: Liming Gao, Michael D Kinney, Ray Ni

Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib.
RngLibNull is used by default. TimerLib will be removed once its
dependency is removed.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 FmpDevicePkg/FmpDevicePkg.dsc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index f4093d3837..201ea00f63 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -53,6 +53,7 @@
 !else
   IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
 !endif
   FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
-- 
2.17.1.windows.2


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

* [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
                   ` (2 preceding siblings ...)
  2019-11-14  2:17 ` [PATCH 03/11] FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib instances in dsc files Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14  4:17   ` [edk2-devel] " Michael D Kinney
  2019-11-14  2:17 ` [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed Wang, Jian J
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel; +Cc: Michael D Kinney, Liming Gao, Ray Ni

BaseRngLib uses rdrand instruction to get random number from DRNG in the
processor, which is not a good candidate for seeding openssl rand
interface.

rdseed in x86 cpu provides non-deterministic random number (NRBG) which
meets NIST SP 800-90B and NIST SP800-90C standards and can be used as
seed for other software DRNG. This patch adds a C interface AsmRdSeed()
to wrap it in BaseLib so that we can add a new RngLib for users to choose
in their platform, if their processor support rdseed instruction.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 MdePkg/Include/Library/BaseLib.h          | 51 +++++++++++++
 MdePkg/Library/BaseLib/BaseLib.inf        |  4 ++
 MdePkg/Library/BaseLib/BaseLibInternals.h | 46 ++++++++++++
 MdePkg/Library/BaseLib/Ia32/RdSeed.nasm   | 87 +++++++++++++++++++++++
 MdePkg/Library/BaseLib/X64/RdSeed.nasm    | 80 +++++++++++++++++++++
 MdePkg/Library/BaseLib/X86RdSeed.c        | 73 +++++++++++++++++++
 6 files changed, 341 insertions(+)
 create mode 100644 MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
 create mode 100644 MdePkg/Library/BaseLib/X64/RdSeed.nasm
 create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c

diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 2a75bc023f..e2f9bf121e 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7856,6 +7856,57 @@ AsmRdRand64  (
   OUT     UINT64                    *Rand
   );
 
+/**
+  Generates a 16-bit random seed through RDSEED instruction.
+
+  if Seed is NULL, then ASSERT().
+
+  @param[out]  Seed     Buffer pointer to store the seed data.
+
+  @retval TRUE          RDSEED call was successful.
+  @retval FALSE         Failed attempts to call RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdSeed16 (
+  OUT     UINT16                    *Seed
+  );
+
+/**
+  Generates a 32-bit random seed through RDSEED instruction.
+
+  if Seed is NULL, then ASSERT().
+
+  @param[out]  Seed     Buffer pointer to store the seed data.
+
+  @retval TRUE          RDSEED call was successful.
+  @retval FALSE         Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed32 (
+  OUT     UINT32                    *Seed
+  );
+
+/**
+  Generates a 64-bit random seed through RDSEED instruction.
+
+  if Seed is NULL, then ASSERT().
+
+  @param[out]  Seed     Buffer pointer to store the seed data.
+
+  @retval TRUE          RDSEED call was successful.
+  @retval FALSE         Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed64  (
+  OUT     UINT64                    *Seed
+  );
+
 /**
   Load given selector into TR register.
 
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 3586beb0ab..5e12093ba3 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -181,6 +181,7 @@
   Ia32/EnableCache.nasm| GCC
   Ia32/DisableCache.nasm| GCC
   Ia32/RdRand.nasm
+  Ia32/RdSeed.nasm
 
   Ia32/DivS64x64Remainder.c
   Ia32/InternalSwitchStack.c | MSFT
@@ -202,6 +203,7 @@
   X86DisablePaging64.c
   X86DisablePaging32.c
   X86RdRand.c
+  X86RdSeed.c
   X86PatchInstruction.c
   X86SpeculationBarrier.c
 
@@ -306,12 +308,14 @@
   X86DisablePaging64.c
   X86DisablePaging32.c
   X86RdRand.c
+  X86RdSeed.c
   X86PatchInstruction.c
   X86SpeculationBarrier.c
   X64/GccInline.c | GCC
   X64/EnableDisableInterrupts.nasm
   X64/DisablePaging64.nasm
   X64/RdRand.nasm
+  X64/RdSeed.nasm
   ChkStkGcc.c  | GCC
 
 [Sources.EBC]
diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h b/MdePkg/Library/BaseLib/BaseLibInternals.h
index 6837d67d90..7b18b192c9 100644
--- a/MdePkg/Library/BaseLib/BaseLibInternals.h
+++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
@@ -862,6 +862,52 @@ InternalX86RdRand64  (
   OUT     UINT64                    *Rand
   );
 
+/**
+  Generates a 16-bit random seed through RDSEED instruction.
+
+  @param[out]  Seed     Buffer pointer to store the seed data.
+
+  @retval TRUE          RDSEED call was successful.
+  @retval FALSE         Failed attempts to call RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed16 (
+  OUT     UINT16                    *Seed
+  );
+
+/**
+  Generates a 32-bit random seed through RDSEED instruction.
+
+  @param[out]  Seed     Buffer pointer to store the seed data.
+
+  @retval TRUE          RDSEED call was successful.
+  @retval FALSE         Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed32 (
+  OUT     UINT32                    *Seed
+  );
+
+/**
+  Generates a 64-bit random seed through RDSEED instruction.
+
+
+  @param[out]  Seed     Buffer pointer to store the seed data.
+
+  @retval TRUE          RDSEED call was successful.
+  @retval FALSE         Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+InternalX86RdSeed64  (
+  OUT     UINT64                    *Seed
+  );
+
 #else
 
 #endif
diff --git a/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
new file mode 100644
index 0000000000..0a4de30db6
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
@@ -0,0 +1,87 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;   RdSeed.nasm
+;
+; Abstract:
+;
+;   Generates random seed through CPU RdSeed instruction under 32-bit platform.
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+;------------------------------------------------------------------------------
+;  Generates a 16 bit random seed through RDSEED instruction.
+;  Return TRUE if Seed generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed16)
+ASM_PFX(InternalX86RdSeed16):
+    ; rdseed   ax                  ; generate a 16 bit RN into ax
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0xf, 0xc7, 0xf8         ; rdseed r16: "0f c7 /7  ModRM:r/m(w)"
+    jc     rn16_ok                 ; jmp if CF=1
+    xor    eax, eax                ; reg=0 if CF=0
+    pause
+    ret                            ; return with failure status
+rn16_ok:
+    mov    edx, dword [esp + 4]
+    mov    [edx], ax
+    mov    eax,  1
+    ret
+
+;------------------------------------------------------------------------------
+;  Generates a 32 bit random seed through RDSEED instruction.
+;  Return TRUE if Seed generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed32)
+ASM_PFX(InternalX86RdSeed32):
+    ; rdseed   eax                 ; generate a 32 bit RN into eax
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0xf, 0xc7, 0xf8         ; rdseed r32: "0f c7 /7  ModRM:r/m(w)"
+    jc     rn32_ok                 ; jmp if CF=1
+    xor    eax, eax                ; reg=0 if CF=0
+    pause
+    ret                            ; return with failure status
+rn32_ok:
+    mov    edx, dword [esp + 4]
+    mov    [edx], eax
+    mov    eax,  1
+    ret
+
+;------------------------------------------------------------------------------
+;  Generates a 64 bit random seed through RDSEED instruction.
+;  Return TRUE if Seed generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed64)
+ASM_PFX(InternalX86RdSeed64):
+    ; rdseed   eax                 ; generate a 32 bit RN into eax
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0xf, 0xc7, 0xf8         ; rdseed r32: "0f c7 /7  ModRM:r/m(w)"
+    jnc    rn64_ret                ; jmp if CF=0
+    mov    edx, dword [esp + 4]
+    mov    [edx], eax
+
+    db     0xf, 0xc7, 0xf0         ; generate another 32 bit RN
+    jnc    rn64_ret                ; jmp if CF=0
+    mov    [edx + 4], eax
+
+    mov    eax,  1
+    ret
+rn64_ret:
+    xor    eax, eax
+    pause
+    ret                            ; return with failure status
+
diff --git a/MdePkg/Library/BaseLib/X64/RdSeed.nasm b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
new file mode 100644
index 0000000000..a60acfeace
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
@@ -0,0 +1,80 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+;   RdSeed.nasm
+;
+; Abstract:
+;
+;   Generates random seed through CPU RdSeed instruction under 64-bit platform.
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+    DEFAULT REL
+    SECTION .text
+
+;------------------------------------------------------------------------------
+;  Generates a 16 bit random seed through RDSEED instruction.
+;  Return TRUE if Seed generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed16)
+ASM_PFX(InternalX86RdSeed16):
+    ; rdseed   ax                  ; generate a 16 bit RN into eax,
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0xf, 0xc7, 0xf8         ; rdseed r16: "0f c7 /7  ModRM:r/m(w)"
+    jc     rn16_ok                 ; jmp if CF=1
+    xor    rax, rax                ; reg=0 if CF=0
+    pause
+    ret                            ; return with failure status
+rn16_ok:
+    mov    [rcx], ax
+    mov    rax,  1
+    ret
+
+;------------------------------------------------------------------------------
+;  Generates a 32 bit random seed through RDSEED instruction.
+;  Return TRUE if Seed generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed32)
+ASM_PFX(InternalX86RdSeed32):
+    ; rdseed   eax                 ; generate a 32 bit RN into eax,
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0xf, 0xc7, 0xf8         ; rdseed r32: "0f c7 /7  ModRM:r/m(w)"
+    jc     rn32_ok                 ; jmp if CF=1
+    xor    rax, rax                ; reg=0 if CF=0
+    pause
+    ret                            ; return with failure status
+rn32_ok:
+    mov    [rcx], eax
+    mov    rax,  1
+    ret
+
+;------------------------------------------------------------------------------
+;  Generates a 64 bit random seed through one RDSEED instruction.
+;  Return TRUE if Seed generated successfully, or FALSE if not.
+;
+;  BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
+;------------------------------------------------------------------------------
+global ASM_PFX(InternalX86RdSeed64)
+ASM_PFX(InternalX86RdSeed64):
+    ; rdseed   rax                 ; generate a 64 bit RN into rax,
+                                   ; CF=1 if RN generated ok, otherwise CF=0
+    db     0x48, 0xf, 0xc7, 0xf8   ; rdseed r64: "REX.W + 0f c7 /7 ModRM:r/m(w)"
+    jc     rn64_ok                 ; jmp if CF=1
+    xor    rax, rax                ; reg=0 if CF=0
+    pause
+    ret                            ; return with failure status
+rn64_ok:
+    mov    [rcx], rax
+    mov    rax, 1
+    ret
+
diff --git a/MdePkg/Library/BaseLib/X86RdSeed.c b/MdePkg/Library/BaseLib/X86RdSeed.c
new file mode 100644
index 0000000000..9fa7948ff1
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X86RdSeed.c
@@ -0,0 +1,73 @@
+/** @file
+  IA-32/x64 AsmRdSeedxx()
+  Generates random seed through CPU RdSeed instruction.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BaseLibInternals.h"
+
+/**
+  Generates a 16-bit random seed through RDSEED instruction.
+
+  if Seed is NULL, then ASSERT().
+
+  @param[out]  Seed     Buffer pointer to store the seed data.
+
+  @retval TRUE          RDSEED call was successful.
+  @retval FALSE         Failed attempts to call RDSEED.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdSeed16 (
+  OUT     UINT16                    *Seed
+  )
+{
+  ASSERT (Seed != NULL);
+  return InternalX86RdSeed16 (Seed);
+}
+
+/**
+  Generates a 32-bit random seed through RDSEED instruction.
+
+  if Seed is NULL, then ASSERT().
+
+  @param[out]  Seed     Buffer pointer to store the seed data.
+
+  @retval TRUE          RDSEED call was successful.
+  @retval FALSE         Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed32 (
+  OUT     UINT32                    *Seed
+  )
+{
+  ASSERT (Seed != NULL);
+  return InternalX86RdSeed32 (Seed);
+}
+
+/**
+  Generates a 64-bit random seed through RDSEED instruction.
+
+  if Seed is NULL, then ASSERT().
+
+  @param[out]  Seed     Buffer pointer to store the seed data.
+
+  @retval TRUE          RDSEED call was successful.
+  @retval FALSE         Failed attempts to call RDSEED.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdSeed64  (
+  OUT     UINT64                    *Seed
+  )
+{
+  ASSERT (Seed != NULL);
+  return InternalX86RdSeed64 (Seed);
+}
-- 
2.17.1.windows.2


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

* [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
                   ` (3 preceding siblings ...)
  2019-11-14  2:17 ` [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14  4:24   ` [edk2-devel] " Michael D Kinney
  2019-11-14  2:17 ` [PATCH 06/11] SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib Wang, Jian J
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Chao Zhang, Michael D Kinney, Liming Gao, Ray Ni

This version of RngLib makes use of AsmRdSeed to get non-deterministic
random number, which can be used for seeding other software DRNG like
rand interface in openssl. It can be used only on IA32/X64 processors
which supports rdseed instruction.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 .../RngLibRdSeed/RngLibRdSeed.inf             |  37 ++++
 .../RngLibRdSeed/RngLibRdSeed.uni             |  18 ++
 .../RngLibRdSeed/RngRdSeed.c                  | 189 ++++++++++++++++++
 3 files changed, 244 insertions(+)
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.uni
 create mode 100644 SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSeed.c

diff --git a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf
new file mode 100644
index 0000000000..8162408775
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf
@@ -0,0 +1,37 @@
+## @file
+#  Instance of RNG (Random Number Generator) Library.
+#
+#  Rng RdSeed Library that uses CPU RdSeed instruction access to provide
+#  non-deterministic random number which can be used as seed for other
+#  software deterministic RNGs.
+#
+#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010029
+  BASE_NAME                      = RngLibRdSeed
+  MODULE_UNI_FILE                = RngLibRdSeed.uni
+  FILE_GUID                      = 8B613B2E-B944-40F9-B979-1B60D7CAA73C
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RngLib
+  CONSTRUCTOR                    = RngLibRdSeedConstructor
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources.Ia32, Sources.X64]
+  RngRdSeed.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
diff --git a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.uni b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.uni
new file mode 100644
index 0000000000..051a3019bc
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.uni
@@ -0,0 +1,18 @@
+// /** @file
+// Instance of RNG (Random Number Generator) Library.
+//
+// Rng RdSeed Library that uses CPU RdSeed instruction access to provide
+// non-deterministic random number which can be used as seed for other
+// software deterministic RNGs.
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Instance of RNG Library"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "RngRdSeed Library that uses CPU RdSeed instruction access to provide non-deterministic random numbers."
+
diff --git a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSeed.c b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSeed.c
new file mode 100644
index 0000000000..0036faa050
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSeed.c
@@ -0,0 +1,189 @@
+/** @file
+  Random number generator services that uses RdSeed instruction access
+  to provide non-deterministic random numbers, which are usually used
+  for seeding other pseudo-random number generators.
+
+Copyright (c) 2019, 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>
+
+//
+// Bit mask used to determine if RdSeed instruction is supported.
+//
+#define RDSEED_MASK                  BIT18
+
+//
+// Limited retry number when valid random data is returned.
+// It varies between 1 and 100 according to "Intel(R) DRGN Software Implementation
+// Guide". Let's use the same value as RDRAND in BaseRngLib.
+//
+#define RDSEED_RETRY_LIMIT           10
+
+/**
+  The constructor function checks whether or not RDSEED instruction is supported
+  by the host hardware.
+
+  The constructor function checks whether or not RDSEED instruction is supported.
+  It will ASSERT() if RDSEED instruction is not supported.
+
+  @retval RETURN_SUCCESS      The processor supports RDSEED instruction.
+  @retval RETURN_UNSUPPORTED  RDSEED instruction is not supported.
+
+**/
+RETURN_STATUS
+EFIAPI
+RngLibRdSeedConstructor (
+  VOID
+  )
+{
+  UINT32  RegEbx;
+
+  //
+  // Determine RDSEED support by examining bit 18 of the EBX register returned by
+  // CPUID(EAX=7, ECX=0). BIT18 of EBX indicates that processor support RDSEED
+  // instruction.
+  //
+  AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL);
+  if ((RegEbx & RDSEED_MASK) != RDSEED_MASK) {
+    ASSERT ((RegEbx & RDSEED_MASK) == RDSEED_MASK);
+    return RETURN_UNSUPPORTED;
+  }
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Generates a 16-bit random number.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out] Rand     Buffer pointer to store the 16-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber16 (
+  OUT     UINT16                    *Rand
+  )
+{
+  UINT32  Index;
+
+  ASSERT (Rand != NULL);
+
+  //
+  // A loop to fetch a 16 bit random value with a retry count limit.
+  //
+  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++) {
+    if (AsmRdSeed16 (Rand)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Generates a 32-bit random number.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out] Rand     Buffer pointer to store the 32-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber32 (
+  OUT     UINT32                    *Rand
+  )
+{
+  UINT32  Index;
+
+  ASSERT (Rand != NULL);
+
+  //
+  // A loop to fetch a 32 bit random value with a retry count limit.
+  //
+  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++) {
+    if (AsmRdSeed32 (Rand)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Generates a 64-bit random number.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out] Rand     Buffer pointer to store the 64-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber64 (
+  OUT     UINT64                    *Rand
+  )
+{
+  UINT32  Index;
+
+  ASSERT (Rand != NULL);
+
+  //
+  // A loop to fetch a 64 bit random value with a retry count limit.
+  //
+  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++) {
+    if (AsmRdSeed64 (Rand)) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+  Generates a 128-bit random number.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out] Rand     Buffer pointer to store the 128-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber128 (
+  OUT     UINT64                    *Rand
+  )
+{
+  ASSERT (Rand != NULL);
+
+  //
+  // Read first 64 bits
+  //
+  if (!GetRandomNumber64 (Rand)) {
+    return FALSE;
+  }
+
+  //
+  // Read second 64 bits
+  //
+  return GetRandomNumber64 (++Rand);
+}
-- 
2.17.1.windows.2


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

* [PATCH 06/11] SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
                   ` (4 preceding siblings ...)
  2019-11-14  2:17 ` [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14 11:15   ` [edk2-devel] " Laszlo Ersek
  2019-11-14  2:17 ` [PATCH 07/11] SecurityPkg/SecurityPkg.dsc: add new RngLib instances for build Wang, Jian J
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel
  Cc: Jiewen Yao, Chao Zhang, Laszlo Ersek, Ard Biesheuvel,
	Matthew Carlson, Sean Brogan, Bret Barkelew, Liming Gao, Ray Ni

From: Matthew Carlson <macarl@microsoft.com>

This version of RngLib makes use of EFI_RNG_PROTOCOL to provide random
number. According to UEFI spec, EFI_RNG_PROTOCOL should meet NIST SP
800-90 and/or ANSI X9.31 standards.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Matthew Carlson <macarl@microsoft.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <bret.barkelew@microsoft.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 .../DxeRngLibRngProtocol.c                    | 200 ++++++++++++++++++
 .../DxeRngLibRngProtocol.inf                  |  42 ++++
 .../DxeRngLibRngProtocol.uni                  |  14 ++
 3 files changed, 256 insertions(+)
 create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c
 create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
 create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni

diff --git a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c
new file mode 100644
index 0000000000..8ce4a7050d
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c
@@ -0,0 +1,200 @@
+/** @file
+ Provides an implementation of the library class RngLib that uses the Rng protocol.
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+Copyright (c) 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Uefi.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>
+#include <Protocol/Rng.h>
+
+/**
+  Generates a random number via the NIST 800-9A algorithm.  Refer to
+  http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf
+  for more information.
+
+  @param[out] Buffer      Buffer to receive the random number.
+  @param[in]  BufferSize  Number of bytes in Buffer.
+
+  @retval EFI_SUCCESS  Random data generated successfully.
+  @retval Others       Failed to generate the random number.
+
+**/
+STATIC
+EFI_STATUS
+GenerateRandomNumberViaNist800Algorithm(
+  OUT UINT8* Buffer,
+  IN  UINTN  BufferSize
+  )
+{
+  EFI_STATUS        Status;
+  EFI_RNG_PROTOCOL* RngProtocol;
+
+  Status = EFI_UNSUPPORTED;
+  RngProtocol = NULL;
+
+  if (Buffer == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a] Buffer == NULL.\n", __FUNCTION__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (gBS == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a] GenerateRandomNumber, gBS == NULL.  Called too soon.\n", __FUNCTION__));
+    return EFI_LOAD_ERROR;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&RngProtocol);
+  if (EFI_ERROR (Status) || RngProtocol == NULL) {
+    DEBUG ((DEBUG_ERROR, "[%a] Could not locate RNG prototocol, Status = %r\n", __FUNCTION__, Status));
+    return Status;
+  }
+
+  Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Ctr256Guid, BufferSize, Buffer);
+  DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm CTR-256 - Status = %r\n", __FUNCTION__, Status));
+  if (!EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hmac256Guid, BufferSize, Buffer);
+  DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm HMAC-256 - Status = %r\n", __FUNCTION__, Status));
+  if (!EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hash256Guid, BufferSize, Buffer);
+  DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm Hash-256 - Status = %r\n", __FUNCTION__, Status));
+  if (!EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // If we get to this point, we have failed
+  //
+  DEBUG((DEBUG_ERROR, "[%a] GetRNG() failed, staus = %r\n", __FUNCTION__, Status));
+
+  return Status;
+}
+
+
+/**
+  Generates a 16-bit random number.
+
+  if Rand is NULL, return FALSE.
+
+  @param[out] Rand     Buffer pointer to store the 16-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber16 (
+  OUT     UINT16                    *Rand
+  )
+{
+  EFI_STATUS Status;
+
+  if (Rand == NULL) {
+    return FALSE;
+  }
+
+  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 2);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Generates a 32-bit random number.
+
+  if Rand is NULL, return FALSE.
+
+  @param[out] Rand     Buffer pointer to store the 32-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber32 (
+  OUT     UINT32                    *Rand
+  )
+{
+  EFI_STATUS Status;
+
+  if (Rand == NULL) {
+    return FALSE;
+  }
+
+  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 4);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Generates a 64-bit random number.
+
+  if Rand is NULL, return FALSE.
+
+  @param[out] Rand     Buffer pointer to store the 64-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber64 (
+  OUT     UINT64                    *Rand
+  )
+{
+  EFI_STATUS Status;
+
+  if (Rand == NULL) {
+    return FALSE;
+  }
+
+  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 8);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/**
+  Generates a 128-bit random number.
+
+  if Rand is NULL, return FALSE.
+
+  @param[out] Rand     Buffer pointer to store the 128-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber128 (
+  OUT     UINT64                    *Rand
+  )
+{
+  EFI_STATUS Status;
+
+  if (Rand == NULL) {
+    return FALSE;
+  }
+
+  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 16);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+  return TRUE;
+}
diff --git a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
new file mode 100644
index 0000000000..d47fe3be53
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
@@ -0,0 +1,42 @@
+# @file
+# Provides implementation of the library class RngLib that uses the RngProtocol
+#
+# @copyright
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION     = 0x00010029
+  BASE_NAME       = DxeRngLibRngProtocol
+  MODULE_UNI_FILE = DxeRngLibRngProtocol.uni
+  FILE_GUID       = FF9F84C5-A33E-44E3-9BB5-0D654B2D4149
+  MODULE_TYPE     = DXE_DRIVER
+  VERSION_STRING  = 1.0
+  LIBRARY_CLASS   = RngLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 EBC ARM AARCH64
+#
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[Sources]
+  DxeRngLibRngProtocol.c
+
+[LibraryClasses]
+  DebugLib
+  UefiBootServicesTableLib
+
+[Protocols]
+  gEfiRngProtocolGuid                 ## CONSUMES
+
+[Depex]
+  gEfiRngProtocolGuid
+
+[Guids]
+  gEfiRngAlgorithmSp80090Ctr256Guid            ## CONSUMES
+  gEfiRngAlgorithmSp80090Hash256Guid           ## CONSUMES
+  gEfiRngAlgorithmSp80090Hmac256Guid           ## CONSUMES
diff --git a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni
new file mode 100644
index 0000000000..09af056bd3
--- /dev/null
+++ b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Instance of RNG (Random Number Generator) Library Based on EFI_RNG_PROTOCOL.
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Instance of RNG Library Based on EFI_RNG_PROTOCOL."
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This version of RNG library makes use of EFI_RNG_PROTOCOL to generate random number compliant with NIST 800-9A."
+
-- 
2.17.1.windows.2


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

* [PATCH 07/11] SecurityPkg/SecurityPkg.dsc: add new RngLib instances for build
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
                   ` (5 preceding siblings ...)
  2019-11-14  2:17 ` [PATCH 06/11] SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14  2:17 ` [PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files Wang, Jian J
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Chao Zhang, Liming Gao, Ray Ni

Add new libraries DxeRngLibRngProtocol and RngLibRdSeed into
SecurityPkg.dsc.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 SecurityPkg/SecurityPkg.dsc | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index a2eeadda7a..21b454f80d 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -231,6 +231,11 @@
   SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf
   SecurityPkg/Library/TcgPpVendorLibNull/TcgPpVendorLibNull.inf
 
+  #
+  # General Random Number Generator
+  #
+  SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
+
 [Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
   SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
 
@@ -309,6 +314,7 @@
   # Random Number Generator
   #
   SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
+  SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRdSeed.inf
 
   #
   # Opal Password solution
-- 
2.17.1.windows.2


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

* [PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
                   ` (6 preceding siblings ...)
  2019-11-14  2:17 ` [PATCH 07/11] SecurityPkg/SecurityPkg.dsc: add new RngLib instances for build Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14 11:07   ` [edk2-devel] " Laszlo Ersek
  2019-11-14  2:17 ` [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: " Wang, Jian J
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel; +Cc: Jordan Justen, Laszlo Ersek, Ard Biesheuvel, Liming Gao, Ray Ni

Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib.
Update OVMF dsc files to accommodate the coming changes. It's supposed
that only TlsDxe needs random number. The DxeRngLibRngProtocol is added
for it. For all other drivers, BaseRngLibNull is used by default.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 OvmfPkg/OvmfPkgIa32.dsc    | 5 +++++
 OvmfPkg/OvmfPkgIa32X64.dsc | 5 +++++
 OvmfPkg/OvmfPkgX64.dsc     | 5 +++++
 OvmfPkg/OvmfXen.dsc        | 5 +++++
 4 files changed, 20 insertions(+)

diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index d350b75630..5a709a95b2 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -217,6 +217,7 @@
 
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
 
 [LibraryClasses.common.SEC]
   TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
@@ -786,6 +787,10 @@
     <LibraryClasses>
       NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
   }
+  NetworkPkg/TlsDxe/TlsDxe.inf {
+    <LibraryClasses>
+      RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
+  }
 !endif
   OvmfPkg/VirtioNetDxe/VirtioNet.inf
 
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index 1ef82cafe4..16ff25fd2c 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -222,6 +222,7 @@
 
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
 
 [LibraryClasses.common.SEC]
   TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
@@ -799,6 +800,10 @@
     <LibraryClasses>
       NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
   }
+  NetworkPkg/TlsDxe/TlsDxe.inf {
+    <LibraryClasses>
+      RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
+  }
 !endif
   OvmfPkg/VirtioNetDxe/VirtioNet.inf
 
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 232815c08e..c9c2af740f 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -222,6 +222,7 @@
 
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
 
 [LibraryClasses.common.SEC]
   TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
@@ -797,6 +798,10 @@
     <LibraryClasses>
       NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
   }
+  NetworkPkg/TlsDxe/TlsDxe.inf {
+    <LibraryClasses>
+      RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
+  }
 !endif
   OvmfPkg/VirtioNetDxe/VirtioNet.inf
 
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 8c11efe9b7..557dff7744 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -204,6 +204,7 @@
 
 [LibraryClasses.common]
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
 
 [LibraryClasses.common.SEC]
   QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgSecLib.inf
@@ -666,6 +667,10 @@
     <LibraryClasses>
       NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
   }
+  NetworkPkg/TlsDxe/TlsDxe.inf {
+    <LibraryClasses>
+      RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
+  }
 !endif
 
   #
-- 
2.17.1.windows.2


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

* [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances in dsc files
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
                   ` (7 preceding siblings ...)
  2019-11-14  2:17 ` [PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14  7:41   ` [edk2-devel] " Ard Biesheuvel
  2019-11-14 10:36   ` Laszlo Ersek
  2019-11-14  2:17 ` [PATCH 10/11] CryptoPkg/OpensslLib: use RngLib to get high quality random entropy Wang, Jian J
                   ` (2 subsequent siblings)
  11 siblings, 2 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel; +Cc: Leif Lindholm, Laszlo Ersek, Ard Biesheuvel

Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib. Update
ArmVirt.dsc.inc file to accommodate the coming changes. It's supposed
that only TlsDxe needs random number. The RngDxeLib is added for it. For
all other drivers, RngLibNull is used by default.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 ArmVirtPkg/ArmVirt.dsc.inc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index 10037c938e..10e0890699 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -156,8 +156,10 @@
   IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
 !if $(NETWORK_TLS_ENABLE) == TRUE
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
 !else
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
 !endif
   BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
 
-- 
2.17.1.windows.2


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

* [PATCH 10/11] CryptoPkg/OpensslLib: use RngLib to get high quality random entropy
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
                   ` (8 preceding siblings ...)
  2019-11-14  2:17 ` [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: " Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14  7:42   ` Ard Biesheuvel
  2019-11-14  2:17 ` [PATCH 11/11] FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib instance Wang, Jian J
  2019-11-14  4:21 ` [edk2-devel] [PATCH 00/11] Use proper entropy sources Michael D Kinney
  11 siblings, 1 reply; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel
  Cc: Xiaoyu Lu, Laszlo Ersek, Ard Biesheuvel, Jiewen Yao, Chao Zhang,
	Liming Gao, Ray Ni

Per BZ1871, OpensslLib should use RngLib to get high quality of random
entropy. This patch remove all code depending on TimerLib for this job,
and add RngLib interface to implement the rand interface required by
openssl.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 CryptoPkg/CryptoPkg.dsc                       |   1 +
 CryptoPkg/Library/OpensslLib/OpensslLib.inf   |  15 +-
 .../Library/OpensslLib/OpensslLibCrypto.inf   |  15 +-
 CryptoPkg/Library/OpensslLib/rand_pool.c      | 253 ++----------------
 .../Library/OpensslLib/rand_pool_noise.c      |  29 --
 .../Library/OpensslLib/rand_pool_noise.h      |  29 --
 .../Library/OpensslLib/rand_pool_noise_tsc.c  |  43 ---
 7 files changed, 32 insertions(+), 353 deletions(-)
 delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.c
 delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.h
 delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c

diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index ec43c1f0a4..54f892996a 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -44,6 +44,7 @@
 
   IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
   OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
 
 [LibraryClasses.ARM, LibraryClasses.AARCH64]
   #
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
index b28dd9e480..4c535dc1e6 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
@@ -23,7 +23,6 @@
 
 [Sources]
   buildinf.h
-  rand_pool_noise.h
   $(OPENSSL_PATH)/e_os.h
 # Autogenerated files list starts here
   $(OPENSSL_PATH)/crypto/aes/aes_cbc.c
@@ -602,18 +601,6 @@
   ossl_store.c
   rand_pool.c
 
-[Sources.Ia32]
-  rand_pool_noise_tsc.c
-
-[Sources.X64]
-  rand_pool_noise_tsc.c
-
-[Sources.ARM]
-  rand_pool_noise.c
-
-[Sources.AARCH64]
-  rand_pool_noise.c
-
 [Packages]
   MdePkg/MdePkg.dec
   CryptoPkg/CryptoPkg.dec
@@ -621,7 +608,7 @@
 [LibraryClasses]
   BaseLib
   DebugLib
-  TimerLib
+  RngLib
   PrintLib
 
 [LibraryClasses.ARM]
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
index 1b6ff5ed54..51159a6f2d 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
@@ -547,22 +547,9 @@
   $(OPENSSL_PATH)/crypto/objects/obj_xref.h
 # Autogenerated files list ends here
   buildinf.h
-  rand_pool_noise.h
   ossl_store.c
   rand_pool.c
 
-[Sources.Ia32]
-  rand_pool_noise_tsc.c
-
-[Sources.X64]
-  rand_pool_noise_tsc.c
-
-[Sources.ARM]
-  rand_pool_noise.c
-
-[Sources.AARCH64]
-  rand_pool_noise.c
-
 [Packages]
   MdePkg/MdePkg.dec
   CryptoPkg/CryptoPkg.dec
@@ -570,7 +557,7 @@
 [LibraryClasses]
   BaseLib
   DebugLib
-  TimerLib
+  RngLib
   PrintLib
 
 [LibraryClasses.ARM]
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool.c b/CryptoPkg/Library/OpensslLib/rand_pool.c
index 9d2a4ad138..f57c238fc4 100644
--- a/CryptoPkg/Library/OpensslLib/rand_pool.c
+++ b/CryptoPkg/Library/OpensslLib/rand_pool.c
@@ -11,213 +11,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <openssl/aes.h>
 
 #include <Uefi.h>
-#include <Library/TimerLib.h>
-
-#include "rand_pool_noise.h"
-
-/**
-  Get some randomness from low-order bits of GetPerformanceCounter results.
-  And combine them to the 64-bit value
-
-  @param[out] Rand    Buffer pointer to store the 64-bit random value.
-
-  @retval TRUE        Random number generated successfully.
-  @retval FALSE       Failed to generate.
-**/
-STATIC
-BOOLEAN
-EFIAPI
-GetRandNoise64FromPerformanceCounter(
-  OUT UINT64      *Rand
-  )
-{
-  UINT32 Index;
-  UINT32 *RandPtr;
-
-  if (NULL == Rand) {
-    return FALSE;
-  }
-
-  RandPtr = (UINT32 *) Rand;
-
-  for (Index = 0; Index < 2; Index ++) {
-    *RandPtr = (UINT32) (GetPerformanceCounter () & 0xFF);
-    MicroSecondDelay (10);
-    RandPtr++;
-  }
-
-  return TRUE;
-}
-
-/**
-  Calls RandomNumber64 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.
-
-**/
-STATIC
-BOOLEAN
-EFIAPI
-RandGetBytes (
-  IN UINTN         Length,
-  OUT UINT8        *RandBuffer
-  )
-{
-  BOOLEAN     Ret;
-  UINT64      TempRand;
-
-  Ret = FALSE;
-
-  while (Length > 0) {
-    //
-    // Get random noise from platform.
-    // If it failed, fallback to PerformanceCounter
-    // If you really care about security, you must override
-    // GetRandomNoise64FromPlatform.
-    //
-    Ret = GetRandomNoise64 (&TempRand);
-    if (Ret == FALSE) {
-      Ret = GetRandNoise64FromPerformanceCounter (&TempRand);
-    }
-    if (!Ret) {
-      return Ret;
-    }
-    if (Length >= sizeof (TempRand)) {
-      *((UINT64*) RandBuffer) = TempRand;
-      RandBuffer += sizeof (UINT64);
-      Length -= sizeof (TempRand);
-    } else {
-      CopyMem (RandBuffer, &TempRand, Length);
-      Length = 0;
-    }
-  }
-
-  return Ret;
-}
-
-/**
-  Creates a 128bit random value that is fully forward and backward prediction resistant,
-  suitable for seeding a NIST SP800-90 Compliant.
-  This function takes multiple random numbers from PerformanceCounter to ensure reseeding
-  and performs AES-CBC-MAC over the data to compute the seed value.
-
-  @param[out]  SeedBuffer    Pointer to a 128bit buffer to store the random seed.
-
-  @retval TRUE        Random seed generation succeeded.
-  @retval FALSE      Failed to request random bytes.
-
-**/
-STATIC
-BOOLEAN
-EFIAPI
-RandGetSeed128 (
-  OUT UINT8        *SeedBuffer
-  )
-{
-  BOOLEAN     Ret;
-  UINT8       RandByte[16];
-  UINT8       Key[16];
-  UINT8       Ffv[16];
-  UINT8       Xored[16];
-  UINT32      Index;
-  UINT32      Index2;
-  AES_KEY     AESKey;
-
-  //
-  // Chose an arbitary key and zero the feed_forward_value (FFV)
-  //
-  for (Index = 0; Index < 16; Index++) {
-    Key[Index] = (UINT8) Index;
-    Ffv[Index] = 0;
-  }
-
-  AES_set_encrypt_key (Key, 16 * 8, &AESKey);
-
-  //
-  // Perform CBC_MAC over 32 * 128 bit values, with 10us gaps between 128 bit value
-  // The 10us gaps will ensure multiple reseeds within the system time with a large
-  // design margin.
-  //
-  for (Index = 0; Index < 32; Index++) {
-    MicroSecondDelay (10);
-    Ret = RandGetBytes (16, RandByte);
-    if (!Ret) {
-      return Ret;
-    }
-
-    //
-    // Perform XOR operations on two 128-bit value.
-    //
-    for (Index2 = 0; Index2 < 16; Index2++) {
-      Xored[Index2] = RandByte[Index2] ^ Ffv[Index2];
-    }
-
-    AES_encrypt (Xored, Ffv, &AESKey);
-  }
-
-  for (Index = 0; Index < 16; Index++) {
-    SeedBuffer[Index] = Ffv[Index];
-  }
-
-  return Ret;
-}
-
-/**
-  Generate high-quality entropy source.
-
-  @param[in]   Length        Size of the buffer, in bytes, to fill with.
-  @param[out]  Entropy       Pointer to the buffer to store the entropy data.
-
-  @retval EFI_SUCCESS        Entropy generation succeeded.
-  @retval EFI_NOT_READY      Failed to request random data.
-
-**/
-STATIC
-BOOLEAN
-EFIAPI
-RandGenerateEntropy (
-  IN UINTN         Length,
-  OUT UINT8        *Entropy
-  )
-{
-  BOOLEAN     Ret;
-  UINTN       BlockCount;
-  UINT8       Seed[16];
-  UINT8       *Ptr;
-
-  BlockCount = Length / 16;
-  Ptr        = (UINT8 *) Entropy;
-
-  //
-  // Generate high-quality seed for DRBG Entropy
-  //
-  while (BlockCount > 0) {
-    Ret = RandGetSeed128 (Seed);
-    if (!Ret) {
-      return Ret;
-    }
-    CopyMem (Ptr, Seed, 16);
-
-    BlockCount--;
-    Ptr = Ptr + 16;
-  }
-
-  //
-  // Populate the remained data as request.
-  //
-  Ret = RandGetSeed128 (Seed);
-  if (!Ret) {
-    return Ret;
-  }
-  CopyMem (Ptr, Seed, (Length % 16));
-
-  return Ret;
-}
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>
 
 /*
  * Add random bytes to the pool to acquire requested amount of entropy
@@ -229,17 +25,30 @@ RandGenerateEntropy (
  */
 size_t rand_pool_acquire_entropy(RAND_POOL *pool)
 {
-  BOOLEAN  Ret;
-  size_t bytes_needed;
-  unsigned char * buffer;
+  BOOLEAN         ret;
+  size_t          bytes_needed;
+  size_t          len;
+  unsigned char   *buffer;
+  UINT64          data[2];
 
   bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
   if (bytes_needed > 0) {
     buffer = rand_pool_add_begin(pool, bytes_needed);
 
     if (buffer != NULL) {
-      Ret = RandGenerateEntropy(bytes_needed, buffer);
-      if (FALSE == Ret) {
+      ret = TRUE;
+      while (bytes_needed > 0 && ret) {
+        ret = GetRandomNumber128 (data);
+        if (ret) {
+          len = MIN (bytes_needed, sizeof(data));
+          CopyMem (buffer, data, len);
+
+          bytes_needed  -= len;
+          buffer        += len;
+        }
+      }
+
+      if (FALSE == ret) {
         rand_pool_add_end(pool, 0, 0);
       } else {
         rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
@@ -257,13 +66,11 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
  */
 int rand_pool_add_nonce_data(RAND_POOL *pool)
 {
-  struct {
-    UINT64  Rand;
-    UINT64  TimerValue;
-  } data = { 0 };
+  UINT64    data[2];
 
-  RandGetBytes(8, (UINT8 *)&(data.Rand));
-  data.TimerValue = GetPerformanceCounter();
+  if (!GetRandomNumber128 (data)) {
+    return 0;
+  }
 
   return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0);
 }
@@ -275,13 +82,11 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
  */
 int rand_pool_add_additional_data(RAND_POOL *pool)
 {
-  struct {
-    UINT64  Rand;
-    UINT64  TimerValue;
-  } data = { 0 };
+  UINT64    data[2];
 
-  RandGetBytes(8, (UINT8 *)&(data.Rand));
-  data.TimerValue = GetPerformanceCounter();
+  if (!GetRandomNumber128 (data)) {
+    return 0;
+  }
 
   return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0);
 }
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise.c b/CryptoPkg/Library/OpensslLib/rand_pool_noise.c
deleted file mode 100644
index c16ed8b454..0000000000
--- a/CryptoPkg/Library/OpensslLib/rand_pool_noise.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/** @file
-  Provide rand noise source.
-
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/BaseLib.h>
-
-/**
-  Get 64-bit noise source
-
-  @param[out] Rand         Buffer pointer to store 64-bit noise source
-
-  @retval FALSE            Failed to generate
-**/
-BOOLEAN
-EFIAPI
-GetRandomNoise64 (
-  OUT UINT64         *Rand
-  )
-{
-  //
-  // Return FALSE will fallback to use PerformaceCounter to
-  // generate noise.
-  //
-  return FALSE;
-}
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise.h b/CryptoPkg/Library/OpensslLib/rand_pool_noise.h
deleted file mode 100644
index 75acc686a9..0000000000
--- a/CryptoPkg/Library/OpensslLib/rand_pool_noise.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/** @file
-  Provide rand noise source.
-
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __RAND_POOL_NOISE_H__
-#define __RAND_POOL_NOISE_H__
-
-#include <Uefi/UefiBaseType.h>
-
-/**
-   Get 64-bit noise source.
-
-   @param[out] Rand         Buffer pointer to store 64-bit noise source
-
-   @retval TRUE             Get randomness successfully.
-   @retval FALSE            Failed to generate
-**/
-BOOLEAN
-EFIAPI
-GetRandomNoise64 (
-  OUT UINT64         *Rand
-  );
-
-
-#endif // __RAND_POOL_NOISE_H__
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c b/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
deleted file mode 100644
index 4158106231..0000000000
--- a/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/** @file
-  Provide rand noise source.
-
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/TimerLib.h>
-
-/**
-  Get 64-bit noise source
-
-  @param[out] Rand         Buffer pointer to store 64-bit noise source
-
-  @retval TRUE             Get randomness successfully.
-  @retval FALSE            Failed to generate
-**/
-BOOLEAN
-EFIAPI
-GetRandomNoise64 (
-  OUT UINT64         *Rand
-  )
-{
-  UINT32 Index;
-  UINT32 *RandPtr;
-
-  if (NULL == Rand) {
-    return FALSE;
-  }
-
-  RandPtr = (UINT32 *)Rand;
-
-  for (Index = 0; Index < 2; Index ++) {
-    *RandPtr = (UINT32) ((AsmReadTsc ()) & 0xFF);
-    RandPtr++;
-    MicroSecondDelay (10);
-  }
-
-  return TRUE;
-}
-- 
2.17.1.windows.2


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

* [PATCH 11/11] FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib instance
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
                   ` (9 preceding siblings ...)
  2019-11-14  2:17 ` [PATCH 10/11] CryptoPkg/OpensslLib: use RngLib to get high quality random entropy Wang, Jian J
@ 2019-11-14  2:17 ` Wang, Jian J
  2019-11-14  4:21 ` [edk2-devel] [PATCH 00/11] Use proper entropy sources Michael D Kinney
  11 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  2:17 UTC (permalink / raw)
  To: devel; +Cc: Liming Gao, Michael D Kinney, Ray Ni

TimerLib instance was added for openssl1.1.1b upgrade due to rand
interface implementation based on TimerLib. Since RngLib is now
used instead, TimerLib is not needed any more.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
---
 FmpDevicePkg/FmpDevicePkg.dsc | 1 -
 1 file changed, 1 deletion(-)

diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index 201ea00f63..2fd7cf4d88 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -60,7 +60,6 @@
   CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
   FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
   FmpDeviceLib|FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf
-  TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
 
 [LibraryClasses.ARM, LibraryClasses.AARCH64]
   #
-- 
2.17.1.windows.2


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

* Re: [edk2-devel] [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction
  2019-11-14  2:17 ` [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction Wang, Jian J
@ 2019-11-14  4:17   ` Michael D Kinney
  2019-11-14  4:40     ` Wang, Jian J
  0 siblings, 1 reply; 36+ messages in thread
From: Michael D Kinney @ 2019-11-14  4:17 UTC (permalink / raw)
  To: devel@edk2.groups.io, Wang, Jian J, Kinney, Michael D
  Cc: Gao, Liming, Ni, Ray

Jian,

According to the NASM docuimentation, the rdseed instruction
has been supported since 2.10.02.

https://www.nasm.us/xdoc/2.10.09/html/nasmdocc.html

Please use rdseed instead of db bytes.

Thanks,

Mike

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On
> Behalf Of Wang, Jian J
> Sent: Wednesday, November 13, 2019 6:18 PM
> To: devel@edk2.groups.io
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>;
> Gao, Liming <liming.gao@intel.com>; Ni, Ray
> <ray.ni@intel.com>
> Subject: [edk2-devel] [PATCH 04/11] MdePkg/BaseLib: add
> interface to wrap rdseed IA instruction
> 
> BaseRngLib uses rdrand instruction to get random number
> from DRNG in the processor, which is not a good
> candidate for seeding openssl rand interface.
> 
> rdseed in x86 cpu provides non-deterministic random
> number (NRBG) which meets NIST SP 800-90B and NIST
> SP800-90C standards and can be used as seed for other
> software DRNG. This patch adds a C interface
> AsmRdSeed() to wrap it in BaseLib so that we can add a
> new RngLib for users to choose in their platform, if
> their processor support rdseed instruction.
> 
> Ref:
> https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> ---
>  MdePkg/Include/Library/BaseLib.h          | 51
> +++++++++++++
>  MdePkg/Library/BaseLib/BaseLib.inf        |  4 ++
>  MdePkg/Library/BaseLib/BaseLibInternals.h | 46
> ++++++++++++
>  MdePkg/Library/BaseLib/Ia32/RdSeed.nasm   | 87
> +++++++++++++++++++++++
>  MdePkg/Library/BaseLib/X64/RdSeed.nasm    | 80
> +++++++++++++++++++++
>  MdePkg/Library/BaseLib/X86RdSeed.c        | 73
> +++++++++++++++++++
>  6 files changed, 341 insertions(+)
>  create mode 100644
> MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
>  create mode 100644
> MdePkg/Library/BaseLib/X64/RdSeed.nasm
>  create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c
> 
> diff --git a/MdePkg/Include/Library/BaseLib.h
> b/MdePkg/Include/Library/BaseLib.h
> index 2a75bc023f..e2f9bf121e 100644
> --- a/MdePkg/Include/Library/BaseLib.h
> +++ b/MdePkg/Include/Library/BaseLib.h
> @@ -7856,6 +7856,57 @@ AsmRdRand64  (
>    OUT     UINT64                    *Rand
>    );
> 
> +/**
> +  Generates a 16-bit random seed through RDSEED
> instruction.
> +
> +  if Seed is NULL, then ASSERT().
> +
> +  @param[out]  Seed     Buffer pointer to store the
> seed data.
> +
> +  @retval TRUE          RDSEED call was successful.
> +  @retval FALSE         Failed attempts to call
> RDSEED.
> +
> + **/
> +BOOLEAN
> +EFIAPI
> +AsmRdSeed16 (
> +  OUT     UINT16                    *Seed
> +  );
> +
> +/**
> +  Generates a 32-bit random seed through RDSEED
> instruction.
> +
> +  if Seed is NULL, then ASSERT().
> +
> +  @param[out]  Seed     Buffer pointer to store the
> seed data.
> +
> +  @retval TRUE          RDSEED call was successful.
> +  @retval FALSE         Failed attempts to call
> RDSEED.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +AsmRdSeed32 (
> +  OUT     UINT32                    *Seed
> +  );
> +
> +/**
> +  Generates a 64-bit random seed through RDSEED
> instruction.
> +
> +  if Seed is NULL, then ASSERT().
> +
> +  @param[out]  Seed     Buffer pointer to store the
> seed data.
> +
> +  @retval TRUE          RDSEED call was successful.
> +  @retval FALSE         Failed attempts to call
> RDSEED.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +AsmRdSeed64  (
> +  OUT     UINT64                    *Seed
> +  );
> +
>  /**
>    Load given selector into TR register.
> 
> diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> b/MdePkg/Library/BaseLib/BaseLib.inf
> index 3586beb0ab..5e12093ba3 100644
> --- a/MdePkg/Library/BaseLib/BaseLib.inf
> +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> @@ -181,6 +181,7 @@
>    Ia32/EnableCache.nasm| GCC
>    Ia32/DisableCache.nasm| GCC
>    Ia32/RdRand.nasm
> +  Ia32/RdSeed.nasm
> 
>    Ia32/DivS64x64Remainder.c
>    Ia32/InternalSwitchStack.c | MSFT
> @@ -202,6 +203,7 @@
>    X86DisablePaging64.c
>    X86DisablePaging32.c
>    X86RdRand.c
> +  X86RdSeed.c
>    X86PatchInstruction.c
>    X86SpeculationBarrier.c
> 
> @@ -306,12 +308,14 @@
>    X86DisablePaging64.c
>    X86DisablePaging32.c
>    X86RdRand.c
> +  X86RdSeed.c
>    X86PatchInstruction.c
>    X86SpeculationBarrier.c
>    X64/GccInline.c | GCC
>    X64/EnableDisableInterrupts.nasm
>    X64/DisablePaging64.nasm
>    X64/RdRand.nasm
> +  X64/RdSeed.nasm
>    ChkStkGcc.c  | GCC
> 
>  [Sources.EBC]
> diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h
> b/MdePkg/Library/BaseLib/BaseLibInternals.h
> index 6837d67d90..7b18b192c9 100644
> --- a/MdePkg/Library/BaseLib/BaseLibInternals.h
> +++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
> @@ -862,6 +862,52 @@ InternalX86RdRand64  (
>    OUT     UINT64                    *Rand
>    );
> 
> +/**
> +  Generates a 16-bit random seed through RDSEED
> instruction.
> +
> +  @param[out]  Seed     Buffer pointer to store the
> seed data.
> +
> +  @retval TRUE          RDSEED call was successful.
> +  @retval FALSE         Failed attempts to call
> RDSEED.
> +
> + **/
> +BOOLEAN
> +EFIAPI
> +InternalX86RdSeed16 (
> +  OUT     UINT16                    *Seed
> +  );
> +
> +/**
> +  Generates a 32-bit random seed through RDSEED
> instruction.
> +
> +  @param[out]  Seed     Buffer pointer to store the
> seed data.
> +
> +  @retval TRUE          RDSEED call was successful.
> +  @retval FALSE         Failed attempts to call
> RDSEED.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +InternalX86RdSeed32 (
> +  OUT     UINT32                    *Seed
> +  );
> +
> +/**
> +  Generates a 64-bit random seed through RDSEED
> instruction.
> +
> +
> +  @param[out]  Seed     Buffer pointer to store the
> seed data.
> +
> +  @retval TRUE          RDSEED call was successful.
> +  @retval FALSE         Failed attempts to call
> RDSEED.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +InternalX86RdSeed64  (
> +  OUT     UINT64                    *Seed
> +  );
> +
>  #else
> 
>  #endif
> diff --git a/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
> b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
> new file mode 100644
> index 0000000000..0a4de30db6
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
> @@ -0,0 +1,87 @@
> +;-----------------------------------------------------
> -----------------
> +--------
> +;
> +; Copyright (c) 2019, Intel Corporation. All rights
> reserved.<BR> ;
> +SPDX-License-Identifier: BSD-2-Clause-Patent ; ;
> Module Name:
> +;
> +;   RdSeed.nasm
> +;
> +; Abstract:
> +;
> +;   Generates random seed through CPU RdSeed
> instruction under 32-bit platform.
> +;
> +; Notes:
> +;
> +;-----------------------------------------------------
> -----------------
> +--------
> +
> +SECTION .text
> +
> +;-----------------------------------------------------
> -----------------
> +-------- ;  Generates a 16 bit random seed through
> RDSEED instruction.
> +;  Return TRUE if Seed generated successfully, or
> FALSE if not.
> +;
> +;  BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
> +;-----------------------------------------------------
> -----------------
> +--------
> +global ASM_PFX(InternalX86RdSeed16)
> +ASM_PFX(InternalX86RdSeed16):
> +    ; rdseed   ax                  ; generate a 16 bit
> RN into ax
> +                                   ; CF=1 if RN
> generated ok, otherwise CF=0
> +    db     0xf, 0xc7, 0xf8         ; rdseed r16: "0f
> c7 /7  ModRM:r/m(w)"
> +    jc     rn16_ok                 ; jmp if CF=1
> +    xor    eax, eax                ; reg=0 if CF=0
> +    pause
> +    ret                            ; return with
> failure status
> +rn16_ok:
> +    mov    edx, dword [esp + 4]
> +    mov    [edx], ax
> +    mov    eax,  1
> +    ret
> +
> +;-----------------------------------------------------
> -----------------
> +-------- ;  Generates a 32 bit random seed through
> RDSEED instruction.
> +;  Return TRUE if Seed generated successfully, or
> FALSE if not.
> +;
> +;  BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
> +;-----------------------------------------------------
> -----------------
> +--------
> +global ASM_PFX(InternalX86RdSeed32)
> +ASM_PFX(InternalX86RdSeed32):
> +    ; rdseed   eax                 ; generate a 32 bit
> RN into eax
> +                                   ; CF=1 if RN
> generated ok, otherwise CF=0
> +    db     0xf, 0xc7, 0xf8         ; rdseed r32: "0f
> c7 /7  ModRM:r/m(w)"
> +    jc     rn32_ok                 ; jmp if CF=1
> +    xor    eax, eax                ; reg=0 if CF=0
> +    pause
> +    ret                            ; return with
> failure status
> +rn32_ok:
> +    mov    edx, dword [esp + 4]
> +    mov    [edx], eax
> +    mov    eax,  1
> +    ret
> +
> +;-----------------------------------------------------
> -----------------
> +-------- ;  Generates a 64 bit random seed through
> RDSEED instruction.
> +;  Return TRUE if Seed generated successfully, or
> FALSE if not.
> +;
> +;  BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
> +;-----------------------------------------------------
> -----------------
> +--------
> +global ASM_PFX(InternalX86RdSeed64)
> +ASM_PFX(InternalX86RdSeed64):
> +    ; rdseed   eax                 ; generate a 32 bit
> RN into eax
> +                                   ; CF=1 if RN
> generated ok, otherwise CF=0
> +    db     0xf, 0xc7, 0xf8         ; rdseed r32: "0f
> c7 /7  ModRM:r/m(w)"
> +    jnc    rn64_ret                ; jmp if CF=0
> +    mov    edx, dword [esp + 4]
> +    mov    [edx], eax
> +
> +    db     0xf, 0xc7, 0xf0         ; generate another
> 32 bit RN
> +    jnc    rn64_ret                ; jmp if CF=0
> +    mov    [edx + 4], eax
> +
> +    mov    eax,  1
> +    ret
> +rn64_ret:
> +    xor    eax, eax
> +    pause
> +    ret                            ; return with
> failure status
> +
> diff --git a/MdePkg/Library/BaseLib/X64/RdSeed.nasm
> b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
> new file mode 100644
> index 0000000000..a60acfeace
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
> @@ -0,0 +1,80 @@
> +;-----------------------------------------------------
> -----------------
> +--------
> +;
> +; Copyright (c) 2019, Intel Corporation. All rights
> reserved.<BR> ;
> +SPDX-License-Identifier: BSD-2-Clause-Patent ; ;
> Module Name:
> +;
> +;   RdSeed.nasm
> +;
> +; Abstract:
> +;
> +;   Generates random seed through CPU RdSeed
> instruction under 64-bit platform.
> +;
> +; Notes:
> +;
> +;-----------------------------------------------------
> -----------------
> +--------
> +
> +    DEFAULT REL
> +    SECTION .text
> +
> +;-----------------------------------------------------
> -----------------
> +-------- ;  Generates a 16 bit random seed through
> RDSEED instruction.
> +;  Return TRUE if Seed generated successfully, or
> FALSE if not.
> +;
> +;  BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
> +;-----------------------------------------------------
> -----------------
> +--------
> +global ASM_PFX(InternalX86RdSeed16)
> +ASM_PFX(InternalX86RdSeed16):
> +    ; rdseed   ax                  ; generate a 16 bit
> RN into eax,
> +                                   ; CF=1 if RN
> generated ok, otherwise CF=0
> +    db     0xf, 0xc7, 0xf8         ; rdseed r16: "0f
> c7 /7  ModRM:r/m(w)"
> +    jc     rn16_ok                 ; jmp if CF=1
> +    xor    rax, rax                ; reg=0 if CF=0
> +    pause
> +    ret                            ; return with
> failure status
> +rn16_ok:
> +    mov    [rcx], ax
> +    mov    rax,  1
> +    ret
> +
> +;-----------------------------------------------------
> -----------------
> +-------- ;  Generates a 32 bit random seed through
> RDSEED instruction.
> +;  Return TRUE if Seed generated successfully, or
> FALSE if not.
> +;
> +;  BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
> +;-----------------------------------------------------
> -----------------
> +--------
> +global ASM_PFX(InternalX86RdSeed32)
> +ASM_PFX(InternalX86RdSeed32):
> +    ; rdseed   eax                 ; generate a 32 bit
> RN into eax,
> +                                   ; CF=1 if RN
> generated ok, otherwise CF=0
> +    db     0xf, 0xc7, 0xf8         ; rdseed r32: "0f
> c7 /7  ModRM:r/m(w)"
> +    jc     rn32_ok                 ; jmp if CF=1
> +    xor    rax, rax                ; reg=0 if CF=0
> +    pause
> +    ret                            ; return with
> failure status
> +rn32_ok:
> +    mov    [rcx], eax
> +    mov    rax,  1
> +    ret
> +
> +;-----------------------------------------------------
> -----------------
> +-------- ;  Generates a 64 bit random seed through one
> RDSEED
> +instruction.
> +;  Return TRUE if Seed generated successfully, or
> FALSE if not.
> +;
> +;  BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
> +;-----------------------------------------------------
> -----------------
> +--------
> +global ASM_PFX(InternalX86RdSeed64)
> +ASM_PFX(InternalX86RdSeed64):
> +    ; rdseed   rax                 ; generate a 64 bit
> RN into rax,
> +                                   ; CF=1 if RN
> generated ok, otherwise CF=0
> +    db     0x48, 0xf, 0xc7, 0xf8   ; rdseed r64:
> "REX.W + 0f c7 /7 ModRM:r/m(w)"
> +    jc     rn64_ok                 ; jmp if CF=1
> +    xor    rax, rax                ; reg=0 if CF=0
> +    pause
> +    ret                            ; return with
> failure status
> +rn64_ok:
> +    mov    [rcx], rax
> +    mov    rax, 1
> +    ret
> +
> diff --git a/MdePkg/Library/BaseLib/X86RdSeed.c
> b/MdePkg/Library/BaseLib/X86RdSeed.c
> new file mode 100644
> index 0000000000..9fa7948ff1
> --- /dev/null
> +++ b/MdePkg/Library/BaseLib/X86RdSeed.c
> @@ -0,0 +1,73 @@
> +/** @file
> +  IA-32/x64 AsmRdSeedxx()
> +  Generates random seed through CPU RdSeed
> instruction.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights
> reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "BaseLibInternals.h"
> +
> +/**
> +  Generates a 16-bit random seed through RDSEED
> instruction.
> +
> +  if Seed is NULL, then ASSERT().
> +
> +  @param[out]  Seed     Buffer pointer to store the
> seed data.
> +
> +  @retval TRUE          RDSEED call was successful.
> +  @retval FALSE         Failed attempts to call
> RDSEED.
> +
> + **/
> +BOOLEAN
> +EFIAPI
> +AsmRdSeed16 (
> +  OUT     UINT16                    *Seed
> +  )
> +{
> +  ASSERT (Seed != NULL);
> +  return InternalX86RdSeed16 (Seed);
> +}
> +
> +/**
> +  Generates a 32-bit random seed through RDSEED
> instruction.
> +
> +  if Seed is NULL, then ASSERT().
> +
> +  @param[out]  Seed     Buffer pointer to store the
> seed data.
> +
> +  @retval TRUE          RDSEED call was successful.
> +  @retval FALSE         Failed attempts to call
> RDSEED.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +AsmRdSeed32 (
> +  OUT     UINT32                    *Seed
> +  )
> +{
> +  ASSERT (Seed != NULL);
> +  return InternalX86RdSeed32 (Seed);
> +}
> +
> +/**
> +  Generates a 64-bit random seed through RDSEED
> instruction.
> +
> +  if Seed is NULL, then ASSERT().
> +
> +  @param[out]  Seed     Buffer pointer to store the
> seed data.
> +
> +  @retval TRUE          RDSEED call was successful.
> +  @retval FALSE         Failed attempts to call
> RDSEED.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +AsmRdSeed64  (
> +  OUT     UINT64                    *Seed
> +  )
> +{
> +  ASSERT (Seed != NULL);
> +  return InternalX86RdSeed64 (Seed);
> +}
> --
> 2.17.1.windows.2
> 
> 
> 


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

* Re: [edk2-devel] [PATCH 00/11] Use proper entropy sources
  2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
                   ` (10 preceding siblings ...)
  2019-11-14  2:17 ` [PATCH 11/11] FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib instance Wang, Jian J
@ 2019-11-14  4:21 ` Michael D Kinney
  2019-11-14  5:15   ` Wang, Jian J
  11 siblings, 1 reply; 36+ messages in thread
From: Michael D Kinney @ 2019-11-14  4:21 UTC (permalink / raw)
  To: devel@edk2.groups.io, Wang, Jian J, Kinney, Michael D
  Cc: Ard Biesheuvel, Bret Barkelew, Zhang, Chao B, Wu, Jiaxin,
	Yao, Jiewen, Justen, Jordan L, Laszlo Ersek, Leif Lindholm,
	Gao, Liming, Rabeda, Maciej, Matthew Carlson, Ni, Ray,
	Sean Brogan, Fu, Siyuan, Lu, XiaoyuX

Jian,

In this patch series I see mixed use of different RngLib instances.

How does a platform developer working on their DSC file know if the
BaseCryptLib services they are using require a Null or a complete
implementation of the RngLib?  How does a platform developer know
if they made the wrong choice.

Thanks,

Mike

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On
> Behalf Of Wang, Jian J
> Sent: Wednesday, November 13, 2019 6:18 PM
> To: devel@edk2.groups.io
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Bret
> Barkelew <bret.barkelew@microsoft.com>; Zhang, Chao B
> <chao.b.zhang@intel.com>; Wu, Jiaxin
> <jiaxin.wu@intel.com>; Yao, Jiewen
> <jiewen.yao@intel.com>; Justen, Jordan L
> <jordan.l.justen@intel.com>; Laszlo Ersek
> <lersek@redhat.com>; Leif Lindholm
> <leif.lindholm@linaro.org>; Gao, Liming
> <liming.gao@intel.com>; Rabeda, Maciej
> <maciej.rabeda@intel.com>; Matthew Carlson
> <macarl@microsoft.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Ni, Ray
> <ray.ni@intel.com>; Sean Brogan
> <sean.brogan@microsoft.com>; Fu, Siyuan
> <siyuan.fu@intel.com>; Lu, XiaoyuX
> <xiaoyux.lu@intel.com>
> Subject: [edk2-devel] [PATCH 00/11] Use proper entropy
> sources
> 
> REF:
> https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> 
> Patch series summary:
>  - Add BaseRngLibNull to package dsc
>  - Add DxeRngLibRngProtocol to make use
> EFI_RNG_PROTOCOL
>  - Add RdSeed interface and RngLibRdSeed for IA32/X64
> arch
>  - Remove following files
>     rand_pool_noise.h
>     rand_pool_noise_tsc.c
>     rand_pool_noise.c
>  - Update rand_pool.c to use RngLib interface directly
>    and the drop the TimerLib depenency from OpensslLib
>  - Update OVMF platform dsc to use DxeRngLibRngProtocol
>    when necessary
> 
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Bret Barkelew <bret.barkelew@microsoft.com>
> Cc: Chao Zhang <chao.b.zhang@intel.com>
> Cc: Jiaxin Wu <jiaxin.wu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Maciej Rabeda <maciej.rabeda@intel.com>
> Cc: Matthew Carlson <macarl@microsoft.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>
> Cc: Siyuan Fu <siyuan.fu@intel.com>
> Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
> 
> Jian J Wang (11):
>   NetworkPkg/NetworkPkg.dsc: specify RngLib instance
> for build
>   SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib
> instances
>   FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib
> instances in dsc files
>   MdePkg/BaseLib: add interface to wrap rdseed IA
> instruction
>   SecurityPkg/RngLibRdSeed: add an instance of RngLib
> to make use rdseed
>   SecurityPkg/DxeRngLibRngProtocol: add RNG protocol
> version of RngLib
>   SecurityPkg/SecurityPkg.dsc: add new RngLib instances
> for build
>   OvmfPkg: specify RngLib instances in dsc files
>   ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances
> in dsc files
>   CryptoPkg/OpensslLib: use RngLib to get high quality
> random entropy
>   FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib
> instance
> 
>  ArmVirtPkg/ArmVirt.dsc.inc                    |   2 +
>  CryptoPkg/CryptoPkg.dsc                       |   1 +
>  CryptoPkg/Library/OpensslLib/OpensslLib.inf   |  15 +-
>  .../Library/OpensslLib/OpensslLibCrypto.inf   |  15 +-
>  CryptoPkg/Library/OpensslLib/rand_pool.c      | 253
> ++----------------
>  .../Library/OpensslLib/rand_pool_noise.c      |  29 --
>  .../Library/OpensslLib/rand_pool_noise.h      |  29 --
>  .../Library/OpensslLib/rand_pool_noise_tsc.c  |  43 --
> -
>  FmpDevicePkg/FmpDevicePkg.dsc                 |   2 +-
>  MdePkg/Include/Library/BaseLib.h              |  51
> ++++
>  MdePkg/Library/BaseLib/BaseLib.inf            |   4 +
>  MdePkg/Library/BaseLib/BaseLibInternals.h     |  46
> ++++
>  MdePkg/Library/BaseLib/Ia32/RdSeed.nasm       |  87
> ++++++
>  MdePkg/Library/BaseLib/X64/RdSeed.nasm        |  80
> ++++++
>  MdePkg/Library/BaseLib/X86RdSeed.c            |  73
> +++++
>  NetworkPkg/NetworkPkg.dsc                     |   1 +
>  OvmfPkg/OvmfPkgIa32.dsc                       |   5 +
>  OvmfPkg/OvmfPkgIa32X64.dsc                    |   5 +
>  OvmfPkg/OvmfPkgX64.dsc                        |   5 +
>  OvmfPkg/OvmfXen.dsc                           |   5 +
>  .../DxeRngLibRngProtocol.c                    | 200
> ++++++++++++++
>  .../DxeRngLibRngProtocol.inf                  |  42
> +++
>  .../DxeRngLibRngProtocol.uni                  |  14 +
>  .../RngLibRdSeed/RngLibRdSeed.inf             |  37
> +++
>  .../RngLibRdSeed/RngLibRdSeed.uni             |  18 ++
>  .../RngLibRdSeed/RngRdSeed.c                  | 189
> +++++++++++++
>  SecurityPkg/SecurityPkg.dsc                   |   6 +
>  SignedCapsulePkg/SignedCapsulePkg.dsc         |   6 +
>  28 files changed, 909 insertions(+), 354 deletions(-)
> delete mode 100644
> CryptoPkg/Library/OpensslLib/rand_pool_noise.c
>  delete mode 100644
> CryptoPkg/Library/OpensslLib/rand_pool_noise.h
>  delete mode 100644
> CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
>  create mode 100644
> MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
>  create mode 100644
> MdePkg/Library/BaseLib/X64/RdSeed.nasm
>  create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c
>  create mode 100644
> SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
> DxeRngLibRngProtocol.c
>  create mode 100644
> SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
> DxeRngLibRngProtocol.inf
>  create mode 100644
> SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
> DxeRngLibRngProtocol.uni
>  create mode 100644
> SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> Seed.inf
>  create mode 100644
> SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> Seed.uni
>  create mode 100644
> SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
> d.c
> 
> --
> 2.17.1.windows.2
> 
> 
> 


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

* Re: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
  2019-11-14  2:17 ` [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed Wang, Jian J
@ 2019-11-14  4:24   ` Michael D Kinney
  2019-11-14  4:38     ` Wang, Jian J
  0 siblings, 1 reply; 36+ messages in thread
From: Michael D Kinney @ 2019-11-14  4:24 UTC (permalink / raw)
  To: devel@edk2.groups.io, Wang, Jian J, Kinney, Michael D
  Cc: Yao, Jiewen, Zhang, Chao B, Gao, Liming, Ni, Ray

Jian,

Why is this lib instance in the SecurityPkg?  It only depends
on the MdePkg.  Can't non security feature related modules
that want to a random number use this lib without using the
SecurityPkg?  Could this lib instance be added to MdePkg?

Thanks,

Mike

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On
> Behalf Of Wang, Jian J
> Sent: Wednesday, November 13, 2019 6:18 PM
> To: devel@edk2.groups.io
> Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> <chao.b.zhang@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [edk2-devel] [PATCH 05/11]
> SecurityPkg/RngLibRdSeed: add an instance of RngLib to
> make use rdseed
> 
> This version of RngLib makes use of AsmRdSeed to get
> non-deterministic random number, which can be used for
> seeding other software DRNG like rand interface in
> openssl. It can be used only on IA32/X64 processors
> which supports rdseed instruction.
> 
> Ref:
> https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Chao Zhang <chao.b.zhang@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> ---
>  .../RngLibRdSeed/RngLibRdSeed.inf             |  37
> ++++
>  .../RngLibRdSeed/RngLibRdSeed.uni             |  18 ++
>  .../RngLibRdSeed/RngRdSeed.c                  | 189
> ++++++++++++++++++
>  3 files changed, 244 insertions(+)
>  create mode 100644
> SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> Seed.inf
>  create mode 100644
> SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> Seed.uni
>  create mode 100644
> SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
> d.c
> 
> diff --git
> a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> RdSeed.inf
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> RdSeed.inf
> new file mode 100644
> index 0000000000..8162408775
> --- /dev/null
> +++
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> RdSeed.inf
> @@ -0,0 +1,37 @@
> +## @file
> +#  Instance of RNG (Random Number Generator) Library.
> +#
> +#  Rng RdSeed Library that uses CPU RdSeed instruction
> access to
> +provide #  non-deterministic random number which can
> be used as seed
> +for other #  software deterministic RNGs.
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights
> reserved.<BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # # ##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010029
> +  BASE_NAME                      = RngLibRdSeed
> +  MODULE_UNI_FILE                = RngLibRdSeed.uni
> +  FILE_GUID                      = 8B613B2E-B944-40F9-
> B979-1B60D7CAA73C
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = RngLib
> +  CONSTRUCTOR                    =
> RngLibRdSeedConstructor
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64
> +#
> +
> +[Sources.Ia32, Sources.X64]
> +  RngRdSeed.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> diff --git
> a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> RdSeed.uni
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> RdSeed.uni
> new file mode 100644
> index 0000000000..051a3019bc
> --- /dev/null
> +++
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> RdSeed.uni
> @@ -0,0 +1,18 @@
> +// /** @file
> +// Instance of RNG (Random Number Generator) Library.
> +//
> +// Rng RdSeed Library that uses CPU RdSeed instruction
> access to
> +provide // non-deterministic random number which can
> be used as seed
> +for other // software deterministic RNGs.
> +//
> +// Copyright (c) 2019, Intel Corporation. All rights
> reserved.<BR> //
> +// SPDX-License-Identifier: BSD-2-Clause-Patent // //
> **/
> +
> +
> +#string STR_MODULE_ABSTRACT             #language en-
> US "Instance of RNG Library"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-
> US "RngRdSeed Library that uses CPU RdSeed instruction
> access to provide non-deterministic random numbers."
> +
> diff --git
> a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> eed.c
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> eed.c
> new file mode 100644
> index 0000000000..0036faa050
> --- /dev/null
> +++
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> eed.c
> @@ -0,0 +1,189 @@
> +/** @file
> +  Random number generator services that uses RdSeed
> instruction access
> +  to provide non-deterministic random numbers, which
> are usually used
> +  for seeding other pseudo-random number generators.
> +
> +Copyright (c) 2019, 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>
> +
> +//
> +// Bit mask used to determine if RdSeed instruction is
> supported.
> +//
> +#define RDSEED_MASK                  BIT18
> +
> +//
> +// Limited retry number when valid random data is
> returned.
> +// It varies between 1 and 100 according to "Intel(R)
> DRGN Software
> +Implementation // Guide". Let's use the same value as
> RDRAND in BaseRngLib.
> +//
> +#define RDSEED_RETRY_LIMIT           10
> +
> +/**
> +  The constructor function checks whether or not
> RDSEED instruction is
> +supported
> +  by the host hardware.
> +
> +  The constructor function checks whether or not
> RDSEED instruction is supported.
> +  It will ASSERT() if RDSEED instruction is not
> supported.
> +
> +  @retval RETURN_SUCCESS      The processor supports
> RDSEED instruction.
> +  @retval RETURN_UNSUPPORTED  RDSEED instruction is
> not supported.
> +
> +**/
> +RETURN_STATUS
> +EFIAPI
> +RngLibRdSeedConstructor (
> +  VOID
> +  )
> +{
> +  UINT32  RegEbx;
> +
> +  //
> +  // Determine RDSEED support by examining bit 18 of
> the EBX register
> + returned by  // CPUID(EAX=7, ECX=0). BIT18 of EBX
> indicates that
> + processor support RDSEED  // instruction.
> +  //
> +  AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL);  if
> ((RegEbx &
> + RDSEED_MASK) != RDSEED_MASK) {
> +    ASSERT ((RegEbx & RDSEED_MASK) == RDSEED_MASK);
> +    return RETURN_UNSUPPORTED;
> +  }
> +
> +  return RETURN_SUCCESS;
> +}
> +
> +/**
> +  Generates a 16-bit random number.
> +
> +  if Rand is NULL, then ASSERT().
> +
> +  @param[out] Rand     Buffer pointer to store the 16-
> bit random value.
> +
> +  @retval TRUE         Random number generated
> successfully.
> +  @retval FALSE        Failed to generate the random
> number.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +GetRandomNumber16 (
> +  OUT     UINT16                    *Rand
> +  )
> +{
> +  UINT32  Index;
> +
> +  ASSERT (Rand != NULL);
> +
> +  //
> +  // A loop to fetch a 16 bit random value with a
> retry count limit.
> +  //
> +  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
> {
> +    if (AsmRdSeed16 (Rand)) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Generates a 32-bit random number.
> +
> +  if Rand is NULL, then ASSERT().
> +
> +  @param[out] Rand     Buffer pointer to store the 32-
> bit random value.
> +
> +  @retval TRUE         Random number generated
> successfully.
> +  @retval FALSE        Failed to generate the random
> number.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +GetRandomNumber32 (
> +  OUT     UINT32                    *Rand
> +  )
> +{
> +  UINT32  Index;
> +
> +  ASSERT (Rand != NULL);
> +
> +  //
> +  // A loop to fetch a 32 bit random value with a
> retry count limit.
> +  //
> +  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
> {
> +    if (AsmRdSeed32 (Rand)) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Generates a 64-bit random number.
> +
> +  if Rand is NULL, then ASSERT().
> +
> +  @param[out] Rand     Buffer pointer to store the 64-
> bit random value.
> +
> +  @retval TRUE         Random number generated
> successfully.
> +  @retval FALSE        Failed to generate the random
> number.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +GetRandomNumber64 (
> +  OUT     UINT64                    *Rand
> +  )
> +{
> +  UINT32  Index;
> +
> +  ASSERT (Rand != NULL);
> +
> +  //
> +  // A loop to fetch a 64 bit random value with a
> retry count limit.
> +  //
> +  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
> {
> +    if (AsmRdSeed64 (Rand)) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Generates a 128-bit random number.
> +
> +  if Rand is NULL, then ASSERT().
> +
> +  @param[out] Rand     Buffer pointer to store the
> 128-bit random value.
> +
> +  @retval TRUE         Random number generated
> successfully.
> +  @retval FALSE        Failed to generate the random
> number.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +GetRandomNumber128 (
> +  OUT     UINT64                    *Rand
> +  )
> +{
> +  ASSERT (Rand != NULL);
> +
> +  //
> +  // Read first 64 bits
> +  //
> +  if (!GetRandomNumber64 (Rand)) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // Read second 64 bits
> +  //
> +  return GetRandomNumber64 (++Rand);
> +}
> --
> 2.17.1.windows.2
> 
> 
> 


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

* Re: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
  2019-11-14  4:24   ` [edk2-devel] " Michael D Kinney
@ 2019-11-14  4:38     ` Wang, Jian J
  2019-11-15 13:28       ` Ard Biesheuvel
  0 siblings, 1 reply; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  4:38 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Yao, Jiewen, Zhang, Chao B, Gao, Liming, Ni, Ray

Mike,

I figured that rdseed is only needed in cases demanding highest entropy,
like seeding other pseudo-RNG. It's not for general purpose randomness.
Then I put it in SecurityPkg. But I'm ok to put it into MdePkg. I have no
strong opinion for this.

Regards,
Jian

> -----Original Message-----
> From: Kinney, Michael D <michael.d.kinney@intel.com>
> Sent: Thursday, November 14, 2019 12:25 PM
> To: devel@edk2.groups.io; Wang, Jian J <jian.j.wang@intel.com>; Kinney,
> Michael D <michael.d.kinney@intel.com>
> Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> <chao.b.zhang@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
> <ray.ni@intel.com>
> Subject: RE: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an
> instance of RngLib to make use rdseed
> 
> Jian,
> 
> Why is this lib instance in the SecurityPkg?  It only depends
> on the MdePkg.  Can't non security feature related modules
> that want to a random number use this lib without using the
> SecurityPkg?  Could this lib instance be added to MdePkg?
> 
> Thanks,
> 
> Mike
> 
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On
> > Behalf Of Wang, Jian J
> > Sent: Wednesday, November 13, 2019 6:18 PM
> > To: devel@edk2.groups.io
> > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> > <chao.b.zhang@intel.com>; Kinney, Michael D
> > <michael.d.kinney@intel.com>; Gao, Liming
> > <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>
> > Subject: [edk2-devel] [PATCH 05/11]
> > SecurityPkg/RngLibRdSeed: add an instance of RngLib to
> > make use rdseed
> >
> > This version of RngLib makes use of AsmRdSeed to get
> > non-deterministic random number, which can be used for
> > seeding other software DRNG like rand interface in
> > openssl. It can be used only on IA32/X64 processors
> > which supports rdseed instruction.
> >
> > Ref:
> > https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Chao Zhang <chao.b.zhang@intel.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> > Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> > ---
> >  .../RngLibRdSeed/RngLibRdSeed.inf             |  37
> > ++++
> >  .../RngLibRdSeed/RngLibRdSeed.uni             |  18 ++
> >  .../RngLibRdSeed/RngRdSeed.c                  | 189
> > ++++++++++++++++++
> >  3 files changed, 244 insertions(+)
> >  create mode 100644
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > Seed.inf
> >  create mode 100644
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > Seed.uni
> >  create mode 100644
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
> > d.c
> >
> > diff --git
> > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > RdSeed.inf
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > RdSeed.inf
> > new file mode 100644
> > index 0000000000..8162408775
> > --- /dev/null
> > +++
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > RdSeed.inf
> > @@ -0,0 +1,37 @@
> > +## @file
> > +#  Instance of RNG (Random Number Generator) Library.
> > +#
> > +#  Rng RdSeed Library that uses CPU RdSeed instruction
> > access to
> > +provide #  non-deterministic random number which can
> > be used as seed
> > +for other #  software deterministic RNGs.
> > +#
> > +#  Copyright (c) 2019, Intel Corporation. All rights
> > reserved.<BR> # #
> > +SPDX-License-Identifier: BSD-2-Clause-Patent # # ##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010029
> > +  BASE_NAME                      = RngLibRdSeed
> > +  MODULE_UNI_FILE                = RngLibRdSeed.uni
> > +  FILE_GUID                      = 8B613B2E-B944-40F9-
> > B979-1B60D7CAA73C
> > +  MODULE_TYPE                    = BASE
> > +  VERSION_STRING                 = 1.0
> > +  LIBRARY_CLASS                  = RngLib
> > +  CONSTRUCTOR                    =
> > RngLibRdSeedConstructor
> > +
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64
> > +#
> > +
> > +[Sources.Ia32, Sources.X64]
> > +  RngRdSeed.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseLib
> > +  DebugLib
> > diff --git
> > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > RdSeed.uni
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > RdSeed.uni
> > new file mode 100644
> > index 0000000000..051a3019bc
> > --- /dev/null
> > +++
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > RdSeed.uni
> > @@ -0,0 +1,18 @@
> > +// /** @file
> > +// Instance of RNG (Random Number Generator) Library.
> > +//
> > +// Rng RdSeed Library that uses CPU RdSeed instruction
> > access to
> > +provide // non-deterministic random number which can
> > be used as seed
> > +for other // software deterministic RNGs.
> > +//
> > +// Copyright (c) 2019, Intel Corporation. All rights
> > reserved.<BR> //
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent // //
> > **/
> > +
> > +
> > +#string STR_MODULE_ABSTRACT             #language en-
> > US "Instance of RNG Library"
> > +
> > +#string STR_MODULE_DESCRIPTION          #language en-
> > US "RngRdSeed Library that uses CPU RdSeed instruction
> > access to provide non-deterministic random numbers."
> > +
> > diff --git
> > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > eed.c
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > eed.c
> > new file mode 100644
> > index 0000000000..0036faa050
> > --- /dev/null
> > +++
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > eed.c
> > @@ -0,0 +1,189 @@
> > +/** @file
> > +  Random number generator services that uses RdSeed
> > instruction access
> > +  to provide non-deterministic random numbers, which
> > are usually used
> > +  for seeding other pseudo-random number generators.
> > +
> > +Copyright (c) 2019, 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>
> > +
> > +//
> > +// Bit mask used to determine if RdSeed instruction is
> > supported.
> > +//
> > +#define RDSEED_MASK                  BIT18
> > +
> > +//
> > +// Limited retry number when valid random data is
> > returned.
> > +// It varies between 1 and 100 according to "Intel(R)
> > DRGN Software
> > +Implementation // Guide". Let's use the same value as
> > RDRAND in BaseRngLib.
> > +//
> > +#define RDSEED_RETRY_LIMIT           10
> > +
> > +/**
> > +  The constructor function checks whether or not
> > RDSEED instruction is
> > +supported
> > +  by the host hardware.
> > +
> > +  The constructor function checks whether or not
> > RDSEED instruction is supported.
> > +  It will ASSERT() if RDSEED instruction is not
> > supported.
> > +
> > +  @retval RETURN_SUCCESS      The processor supports
> > RDSEED instruction.
> > +  @retval RETURN_UNSUPPORTED  RDSEED instruction is
> > not supported.
> > +
> > +**/
> > +RETURN_STATUS
> > +EFIAPI
> > +RngLibRdSeedConstructor (
> > +  VOID
> > +  )
> > +{
> > +  UINT32  RegEbx;
> > +
> > +  //
> > +  // Determine RDSEED support by examining bit 18 of
> > the EBX register
> > + returned by  // CPUID(EAX=7, ECX=0). BIT18 of EBX
> > indicates that
> > + processor support RDSEED  // instruction.
> > +  //
> > +  AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL);  if
> > ((RegEbx &
> > + RDSEED_MASK) != RDSEED_MASK) {
> > +    ASSERT ((RegEbx & RDSEED_MASK) == RDSEED_MASK);
> > +    return RETURN_UNSUPPORTED;
> > +  }
> > +
> > +  return RETURN_SUCCESS;
> > +}
> > +
> > +/**
> > +  Generates a 16-bit random number.
> > +
> > +  if Rand is NULL, then ASSERT().
> > +
> > +  @param[out] Rand     Buffer pointer to store the 16-
> > bit random value.
> > +
> > +  @retval TRUE         Random number generated
> > successfully.
> > +  @retval FALSE        Failed to generate the random
> > number.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +GetRandomNumber16 (
> > +  OUT     UINT16                    *Rand
> > +  )
> > +{
> > +  UINT32  Index;
> > +
> > +  ASSERT (Rand != NULL);
> > +
> > +  //
> > +  // A loop to fetch a 16 bit random value with a
> > retry count limit.
> > +  //
> > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
> > {
> > +    if (AsmRdSeed16 (Rand)) {
> > +      return TRUE;
> > +    }
> > +  }
> > +
> > +  return FALSE;
> > +}
> > +
> > +/**
> > +  Generates a 32-bit random number.
> > +
> > +  if Rand is NULL, then ASSERT().
> > +
> > +  @param[out] Rand     Buffer pointer to store the 32-
> > bit random value.
> > +
> > +  @retval TRUE         Random number generated
> > successfully.
> > +  @retval FALSE        Failed to generate the random
> > number.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +GetRandomNumber32 (
> > +  OUT     UINT32                    *Rand
> > +  )
> > +{
> > +  UINT32  Index;
> > +
> > +  ASSERT (Rand != NULL);
> > +
> > +  //
> > +  // A loop to fetch a 32 bit random value with a
> > retry count limit.
> > +  //
> > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
> > {
> > +    if (AsmRdSeed32 (Rand)) {
> > +      return TRUE;
> > +    }
> > +  }
> > +
> > +  return FALSE;
> > +}
> > +
> > +/**
> > +  Generates a 64-bit random number.
> > +
> > +  if Rand is NULL, then ASSERT().
> > +
> > +  @param[out] Rand     Buffer pointer to store the 64-
> > bit random value.
> > +
> > +  @retval TRUE         Random number generated
> > successfully.
> > +  @retval FALSE        Failed to generate the random
> > number.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +GetRandomNumber64 (
> > +  OUT     UINT64                    *Rand
> > +  )
> > +{
> > +  UINT32  Index;
> > +
> > +  ASSERT (Rand != NULL);
> > +
> > +  //
> > +  // A loop to fetch a 64 bit random value with a
> > retry count limit.
> > +  //
> > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
> > {
> > +    if (AsmRdSeed64 (Rand)) {
> > +      return TRUE;
> > +    }
> > +  }
> > +
> > +  return FALSE;
> > +}
> > +
> > +/**
> > +  Generates a 128-bit random number.
> > +
> > +  if Rand is NULL, then ASSERT().
> > +
> > +  @param[out] Rand     Buffer pointer to store the
> > 128-bit random value.
> > +
> > +  @retval TRUE         Random number generated
> > successfully.
> > +  @retval FALSE        Failed to generate the random
> > number.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +GetRandomNumber128 (
> > +  OUT     UINT64                    *Rand
> > +  )
> > +{
> > +  ASSERT (Rand != NULL);
> > +
> > +  //
> > +  // Read first 64 bits
> > +  //
> > +  if (!GetRandomNumber64 (Rand)) {
> > +    return FALSE;
> > +  }
> > +
> > +  //
> > +  // Read second 64 bits
> > +  //
> > +  return GetRandomNumber64 (++Rand);
> > +}
> > --
> > 2.17.1.windows.2
> >
> >
> > 


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

* Re: [edk2-devel] [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction
  2019-11-14  4:17   ` [edk2-devel] " Michael D Kinney
@ 2019-11-14  4:40     ` Wang, Jian J
  0 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  4:40 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io; +Cc: Gao, Liming, Ni, Ray

Mike,

Thanks for finding it. I'll update the code in v2.

Regards,
Jian

> -----Original Message-----
> From: Kinney, Michael D <michael.d.kinney@intel.com>
> Sent: Thursday, November 14, 2019 12:17 PM
> To: devel@edk2.groups.io; Wang, Jian J <jian.j.wang@intel.com>; Kinney,
> Michael D <michael.d.kinney@intel.com>
> Cc: Gao, Liming <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: RE: [edk2-devel] [PATCH 04/11] MdePkg/BaseLib: add interface to wrap
> rdseed IA instruction
> 
> Jian,
> 
> According to the NASM docuimentation, the rdseed instruction
> has been supported since 2.10.02.
> 
> https://www.nasm.us/xdoc/2.10.09/html/nasmdocc.html
> 
> Please use rdseed instead of db bytes.
> 
> Thanks,
> 
> Mike
> 
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On
> > Behalf Of Wang, Jian J
> > Sent: Wednesday, November 13, 2019 6:18 PM
> > To: devel@edk2.groups.io
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>;
> > Gao, Liming <liming.gao@intel.com>; Ni, Ray
> > <ray.ni@intel.com>
> > Subject: [edk2-devel] [PATCH 04/11] MdePkg/BaseLib: add
> > interface to wrap rdseed IA instruction
> >
> > BaseRngLib uses rdrand instruction to get random number
> > from DRNG in the processor, which is not a good
> > candidate for seeding openssl rand interface.
> >
> > rdseed in x86 cpu provides non-deterministic random
> > number (NRBG) which meets NIST SP 800-90B and NIST
> > SP800-90C standards and can be used as seed for other
> > software DRNG. This patch adds a C interface
> > AsmRdSeed() to wrap it in BaseLib so that we can add a
> > new RngLib for users to choose in their platform, if
> > their processor support rdseed instruction.
> >
> > Ref:
> > https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> > Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> > ---
> >  MdePkg/Include/Library/BaseLib.h          | 51
> > +++++++++++++
> >  MdePkg/Library/BaseLib/BaseLib.inf        |  4 ++
> >  MdePkg/Library/BaseLib/BaseLibInternals.h | 46
> > ++++++++++++
> >  MdePkg/Library/BaseLib/Ia32/RdSeed.nasm   | 87
> > +++++++++++++++++++++++
> >  MdePkg/Library/BaseLib/X64/RdSeed.nasm    | 80
> > +++++++++++++++++++++
> >  MdePkg/Library/BaseLib/X86RdSeed.c        | 73
> > +++++++++++++++++++
> >  6 files changed, 341 insertions(+)
> >  create mode 100644
> > MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
> >  create mode 100644
> > MdePkg/Library/BaseLib/X64/RdSeed.nasm
> >  create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c
> >
> > diff --git a/MdePkg/Include/Library/BaseLib.h
> > b/MdePkg/Include/Library/BaseLib.h
> > index 2a75bc023f..e2f9bf121e 100644
> > --- a/MdePkg/Include/Library/BaseLib.h
> > +++ b/MdePkg/Include/Library/BaseLib.h
> > @@ -7856,6 +7856,57 @@ AsmRdRand64  (
> >    OUT     UINT64                    *Rand
> >    );
> >
> > +/**
> > +  Generates a 16-bit random seed through RDSEED
> > instruction.
> > +
> > +  if Seed is NULL, then ASSERT().
> > +
> > +  @param[out]  Seed     Buffer pointer to store the
> > seed data.
> > +
> > +  @retval TRUE          RDSEED call was successful.
> > +  @retval FALSE         Failed attempts to call
> > RDSEED.
> > +
> > + **/
> > +BOOLEAN
> > +EFIAPI
> > +AsmRdSeed16 (
> > +  OUT     UINT16                    *Seed
> > +  );
> > +
> > +/**
> > +  Generates a 32-bit random seed through RDSEED
> > instruction.
> > +
> > +  if Seed is NULL, then ASSERT().
> > +
> > +  @param[out]  Seed     Buffer pointer to store the
> > seed data.
> > +
> > +  @retval TRUE          RDSEED call was successful.
> > +  @retval FALSE         Failed attempts to call
> > RDSEED.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +AsmRdSeed32 (
> > +  OUT     UINT32                    *Seed
> > +  );
> > +
> > +/**
> > +  Generates a 64-bit random seed through RDSEED
> > instruction.
> > +
> > +  if Seed is NULL, then ASSERT().
> > +
> > +  @param[out]  Seed     Buffer pointer to store the
> > seed data.
> > +
> > +  @retval TRUE          RDSEED call was successful.
> > +  @retval FALSE         Failed attempts to call
> > RDSEED.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +AsmRdSeed64  (
> > +  OUT     UINT64                    *Seed
> > +  );
> > +
> >  /**
> >    Load given selector into TR register.
> >
> > diff --git a/MdePkg/Library/BaseLib/BaseLib.inf
> > b/MdePkg/Library/BaseLib/BaseLib.inf
> > index 3586beb0ab..5e12093ba3 100644
> > --- a/MdePkg/Library/BaseLib/BaseLib.inf
> > +++ b/MdePkg/Library/BaseLib/BaseLib.inf
> > @@ -181,6 +181,7 @@
> >    Ia32/EnableCache.nasm| GCC
> >    Ia32/DisableCache.nasm| GCC
> >    Ia32/RdRand.nasm
> > +  Ia32/RdSeed.nasm
> >
> >    Ia32/DivS64x64Remainder.c
> >    Ia32/InternalSwitchStack.c | MSFT
> > @@ -202,6 +203,7 @@
> >    X86DisablePaging64.c
> >    X86DisablePaging32.c
> >    X86RdRand.c
> > +  X86RdSeed.c
> >    X86PatchInstruction.c
> >    X86SpeculationBarrier.c
> >
> > @@ -306,12 +308,14 @@
> >    X86DisablePaging64.c
> >    X86DisablePaging32.c
> >    X86RdRand.c
> > +  X86RdSeed.c
> >    X86PatchInstruction.c
> >    X86SpeculationBarrier.c
> >    X64/GccInline.c | GCC
> >    X64/EnableDisableInterrupts.nasm
> >    X64/DisablePaging64.nasm
> >    X64/RdRand.nasm
> > +  X64/RdSeed.nasm
> >    ChkStkGcc.c  | GCC
> >
> >  [Sources.EBC]
> > diff --git a/MdePkg/Library/BaseLib/BaseLibInternals.h
> > b/MdePkg/Library/BaseLib/BaseLibInternals.h
> > index 6837d67d90..7b18b192c9 100644
> > --- a/MdePkg/Library/BaseLib/BaseLibInternals.h
> > +++ b/MdePkg/Library/BaseLib/BaseLibInternals.h
> > @@ -862,6 +862,52 @@ InternalX86RdRand64  (
> >    OUT     UINT64                    *Rand
> >    );
> >
> > +/**
> > +  Generates a 16-bit random seed through RDSEED
> > instruction.
> > +
> > +  @param[out]  Seed     Buffer pointer to store the
> > seed data.
> > +
> > +  @retval TRUE          RDSEED call was successful.
> > +  @retval FALSE         Failed attempts to call
> > RDSEED.
> > +
> > + **/
> > +BOOLEAN
> > +EFIAPI
> > +InternalX86RdSeed16 (
> > +  OUT     UINT16                    *Seed
> > +  );
> > +
> > +/**
> > +  Generates a 32-bit random seed through RDSEED
> > instruction.
> > +
> > +  @param[out]  Seed     Buffer pointer to store the
> > seed data.
> > +
> > +  @retval TRUE          RDSEED call was successful.
> > +  @retval FALSE         Failed attempts to call
> > RDSEED.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +InternalX86RdSeed32 (
> > +  OUT     UINT32                    *Seed
> > +  );
> > +
> > +/**
> > +  Generates a 64-bit random seed through RDSEED
> > instruction.
> > +
> > +
> > +  @param[out]  Seed     Buffer pointer to store the
> > seed data.
> > +
> > +  @retval TRUE          RDSEED call was successful.
> > +  @retval FALSE         Failed attempts to call
> > RDSEED.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +InternalX86RdSeed64  (
> > +  OUT     UINT64                    *Seed
> > +  );
> > +
> >  #else
> >
> >  #endif
> > diff --git a/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
> > b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
> > new file mode 100644
> > index 0000000000..0a4de30db6
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
> > @@ -0,0 +1,87 @@
> > +;-----------------------------------------------------
> > -----------------
> > +--------
> > +;
> > +; Copyright (c) 2019, Intel Corporation. All rights
> > reserved.<BR> ;
> > +SPDX-License-Identifier: BSD-2-Clause-Patent ; ;
> > Module Name:
> > +;
> > +;   RdSeed.nasm
> > +;
> > +; Abstract:
> > +;
> > +;   Generates random seed through CPU RdSeed
> > instruction under 32-bit platform.
> > +;
> > +; Notes:
> > +;
> > +;-----------------------------------------------------
> > -----------------
> > +--------
> > +
> > +SECTION .text
> > +
> > +;-----------------------------------------------------
> > -----------------
> > +-------- ;  Generates a 16 bit random seed through
> > RDSEED instruction.
> > +;  Return TRUE if Seed generated successfully, or
> > FALSE if not.
> > +;
> > +;  BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
> > +;-----------------------------------------------------
> > -----------------
> > +--------
> > +global ASM_PFX(InternalX86RdSeed16)
> > +ASM_PFX(InternalX86RdSeed16):
> > +    ; rdseed   ax                  ; generate a 16 bit
> > RN into ax
> > +                                   ; CF=1 if RN
> > generated ok, otherwise CF=0
> > +    db     0xf, 0xc7, 0xf8         ; rdseed r16: "0f
> > c7 /7  ModRM:r/m(w)"
> > +    jc     rn16_ok                 ; jmp if CF=1
> > +    xor    eax, eax                ; reg=0 if CF=0
> > +    pause
> > +    ret                            ; return with
> > failure status
> > +rn16_ok:
> > +    mov    edx, dword [esp + 4]
> > +    mov    [edx], ax
> > +    mov    eax,  1
> > +    ret
> > +
> > +;-----------------------------------------------------
> > -----------------
> > +-------- ;  Generates a 32 bit random seed through
> > RDSEED instruction.
> > +;  Return TRUE if Seed generated successfully, or
> > FALSE if not.
> > +;
> > +;  BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
> > +;-----------------------------------------------------
> > -----------------
> > +--------
> > +global ASM_PFX(InternalX86RdSeed32)
> > +ASM_PFX(InternalX86RdSeed32):
> > +    ; rdseed   eax                 ; generate a 32 bit
> > RN into eax
> > +                                   ; CF=1 if RN
> > generated ok, otherwise CF=0
> > +    db     0xf, 0xc7, 0xf8         ; rdseed r32: "0f
> > c7 /7  ModRM:r/m(w)"
> > +    jc     rn32_ok                 ; jmp if CF=1
> > +    xor    eax, eax                ; reg=0 if CF=0
> > +    pause
> > +    ret                            ; return with
> > failure status
> > +rn32_ok:
> > +    mov    edx, dword [esp + 4]
> > +    mov    [edx], eax
> > +    mov    eax,  1
> > +    ret
> > +
> > +;-----------------------------------------------------
> > -----------------
> > +-------- ;  Generates a 64 bit random seed through
> > RDSEED instruction.
> > +;  Return TRUE if Seed generated successfully, or
> > FALSE if not.
> > +;
> > +;  BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
> > +;-----------------------------------------------------
> > -----------------
> > +--------
> > +global ASM_PFX(InternalX86RdSeed64)
> > +ASM_PFX(InternalX86RdSeed64):
> > +    ; rdseed   eax                 ; generate a 32 bit
> > RN into eax
> > +                                   ; CF=1 if RN
> > generated ok, otherwise CF=0
> > +    db     0xf, 0xc7, 0xf8         ; rdseed r32: "0f
> > c7 /7  ModRM:r/m(w)"
> > +    jnc    rn64_ret                ; jmp if CF=0
> > +    mov    edx, dword [esp + 4]
> > +    mov    [edx], eax
> > +
> > +    db     0xf, 0xc7, 0xf0         ; generate another
> > 32 bit RN
> > +    jnc    rn64_ret                ; jmp if CF=0
> > +    mov    [edx + 4], eax
> > +
> > +    mov    eax,  1
> > +    ret
> > +rn64_ret:
> > +    xor    eax, eax
> > +    pause
> > +    ret                            ; return with
> > failure status
> > +
> > diff --git a/MdePkg/Library/BaseLib/X64/RdSeed.nasm
> > b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
> > new file mode 100644
> > index 0000000000..a60acfeace
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseLib/X64/RdSeed.nasm
> > @@ -0,0 +1,80 @@
> > +;-----------------------------------------------------
> > -----------------
> > +--------
> > +;
> > +; Copyright (c) 2019, Intel Corporation. All rights
> > reserved.<BR> ;
> > +SPDX-License-Identifier: BSD-2-Clause-Patent ; ;
> > Module Name:
> > +;
> > +;   RdSeed.nasm
> > +;
> > +; Abstract:
> > +;
> > +;   Generates random seed through CPU RdSeed
> > instruction under 64-bit platform.
> > +;
> > +; Notes:
> > +;
> > +;-----------------------------------------------------
> > -----------------
> > +--------
> > +
> > +    DEFAULT REL
> > +    SECTION .text
> > +
> > +;-----------------------------------------------------
> > -----------------
> > +-------- ;  Generates a 16 bit random seed through
> > RDSEED instruction.
> > +;  Return TRUE if Seed generated successfully, or
> > FALSE if not.
> > +;
> > +;  BOOLEAN EFIAPI InternalX86RdSeed16 (UINT16 *Seed);
> > +;-----------------------------------------------------
> > -----------------
> > +--------
> > +global ASM_PFX(InternalX86RdSeed16)
> > +ASM_PFX(InternalX86RdSeed16):
> > +    ; rdseed   ax                  ; generate a 16 bit
> > RN into eax,
> > +                                   ; CF=1 if RN
> > generated ok, otherwise CF=0
> > +    db     0xf, 0xc7, 0xf8         ; rdseed r16: "0f
> > c7 /7  ModRM:r/m(w)"
> > +    jc     rn16_ok                 ; jmp if CF=1
> > +    xor    rax, rax                ; reg=0 if CF=0
> > +    pause
> > +    ret                            ; return with
> > failure status
> > +rn16_ok:
> > +    mov    [rcx], ax
> > +    mov    rax,  1
> > +    ret
> > +
> > +;-----------------------------------------------------
> > -----------------
> > +-------- ;  Generates a 32 bit random seed through
> > RDSEED instruction.
> > +;  Return TRUE if Seed generated successfully, or
> > FALSE if not.
> > +;
> > +;  BOOLEAN EFIAPI InternalX86RdSeed32 (UINT32 *Seed);
> > +;-----------------------------------------------------
> > -----------------
> > +--------
> > +global ASM_PFX(InternalX86RdSeed32)
> > +ASM_PFX(InternalX86RdSeed32):
> > +    ; rdseed   eax                 ; generate a 32 bit
> > RN into eax,
> > +                                   ; CF=1 if RN
> > generated ok, otherwise CF=0
> > +    db     0xf, 0xc7, 0xf8         ; rdseed r32: "0f
> > c7 /7  ModRM:r/m(w)"
> > +    jc     rn32_ok                 ; jmp if CF=1
> > +    xor    rax, rax                ; reg=0 if CF=0
> > +    pause
> > +    ret                            ; return with
> > failure status
> > +rn32_ok:
> > +    mov    [rcx], eax
> > +    mov    rax,  1
> > +    ret
> > +
> > +;-----------------------------------------------------
> > -----------------
> > +-------- ;  Generates a 64 bit random seed through one
> > RDSEED
> > +instruction.
> > +;  Return TRUE if Seed generated successfully, or
> > FALSE if not.
> > +;
> > +;  BOOLEAN EFIAPI InternalX86RdSeed64 (UINT64 *Seed);
> > +;-----------------------------------------------------
> > -----------------
> > +--------
> > +global ASM_PFX(InternalX86RdSeed64)
> > +ASM_PFX(InternalX86RdSeed64):
> > +    ; rdseed   rax                 ; generate a 64 bit
> > RN into rax,
> > +                                   ; CF=1 if RN
> > generated ok, otherwise CF=0
> > +    db     0x48, 0xf, 0xc7, 0xf8   ; rdseed r64:
> > "REX.W + 0f c7 /7 ModRM:r/m(w)"
> > +    jc     rn64_ok                 ; jmp if CF=1
> > +    xor    rax, rax                ; reg=0 if CF=0
> > +    pause
> > +    ret                            ; return with
> > failure status
> > +rn64_ok:
> > +    mov    [rcx], rax
> > +    mov    rax, 1
> > +    ret
> > +
> > diff --git a/MdePkg/Library/BaseLib/X86RdSeed.c
> > b/MdePkg/Library/BaseLib/X86RdSeed.c
> > new file mode 100644
> > index 0000000000..9fa7948ff1
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseLib/X86RdSeed.c
> > @@ -0,0 +1,73 @@
> > +/** @file
> > +  IA-32/x64 AsmRdSeedxx()
> > +  Generates random seed through CPU RdSeed
> > instruction.
> > +
> > +  Copyright (c) 2019, Intel Corporation. All rights
> > reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "BaseLibInternals.h"
> > +
> > +/**
> > +  Generates a 16-bit random seed through RDSEED
> > instruction.
> > +
> > +  if Seed is NULL, then ASSERT().
> > +
> > +  @param[out]  Seed     Buffer pointer to store the
> > seed data.
> > +
> > +  @retval TRUE          RDSEED call was successful.
> > +  @retval FALSE         Failed attempts to call
> > RDSEED.
> > +
> > + **/
> > +BOOLEAN
> > +EFIAPI
> > +AsmRdSeed16 (
> > +  OUT     UINT16                    *Seed
> > +  )
> > +{
> > +  ASSERT (Seed != NULL);
> > +  return InternalX86RdSeed16 (Seed);
> > +}
> > +
> > +/**
> > +  Generates a 32-bit random seed through RDSEED
> > instruction.
> > +
> > +  if Seed is NULL, then ASSERT().
> > +
> > +  @param[out]  Seed     Buffer pointer to store the
> > seed data.
> > +
> > +  @retval TRUE          RDSEED call was successful.
> > +  @retval FALSE         Failed attempts to call
> > RDSEED.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +AsmRdSeed32 (
> > +  OUT     UINT32                    *Seed
> > +  )
> > +{
> > +  ASSERT (Seed != NULL);
> > +  return InternalX86RdSeed32 (Seed);
> > +}
> > +
> > +/**
> > +  Generates a 64-bit random seed through RDSEED
> > instruction.
> > +
> > +  if Seed is NULL, then ASSERT().
> > +
> > +  @param[out]  Seed     Buffer pointer to store the
> > seed data.
> > +
> > +  @retval TRUE          RDSEED call was successful.
> > +  @retval FALSE         Failed attempts to call
> > RDSEED.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +AsmRdSeed64  (
> > +  OUT     UINT64                    *Seed
> > +  )
> > +{
> > +  ASSERT (Seed != NULL);
> > +  return InternalX86RdSeed64 (Seed);
> > +}
> > --
> > 2.17.1.windows.2
> >
> >
> > 


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

* Re: [edk2-devel] [PATCH 00/11] Use proper entropy sources
  2019-11-14  4:21 ` [edk2-devel] [PATCH 00/11] Use proper entropy sources Michael D Kinney
@ 2019-11-14  5:15   ` Wang, Jian J
  0 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  5:15 UTC (permalink / raw)
  To: Kinney, Michael D, devel@edk2.groups.io
  Cc: Ard Biesheuvel, Bret Barkelew, Zhang, Chao B, Wu, Jiaxin,
	Yao, Jiewen, Justen, Jordan L, Laszlo Ersek, Leif Lindholm,
	Gao, Liming, Rabeda, Maciej, Matthew Carlson, Ni, Ray,
	Sean Brogan, Fu, Siyuan, Lu, XiaoyuX

Hi Mike,

Here're some suggestions:
  - If OpensslLib library is used, RngLib instance must be specified along
    with it.
  - For package dsc, BaseLibRngNull can be used because their main
    purpose is just for build.
  - For platforms which don't need random number at all, BaseLibRngNull
    is recommended.
  - If drivers HddPasswordDxe/TlsDxe (TlsLib) and/or crypto algorithm like
    AES/RSA-OAEP/RSA-PK1 are used in a platform, BaseLibRngNull must
    *not* be used. This rule might change due to the future code base
    change.
  - For IA32/X64 platforms, BaseLibRng is recommended as the default
    library instance to avoid unknown uses of RNG. But the users can
    choose
      - RngLibRdSeed, if rdseed is supported for sure and high quality
        of entropy source is needed; or
      - DxeRngLibRngProtocol, if EFI_RNG_PROTOCOL is implemented in
        the platform and only DXE drivers or applications use RNG, or
        arch independent is more important.
  - For OVMF, there's already a driver implemented EFI_RNG_PROTOCOL.
    DxeRngLibRngProtocol is always recommended.
  - For other ARCH platforms, I don't see implementation of RngLib nor
    EFI_RNG_PROTOCOL. They have to use BaseRngLibNull or implement
    their own version of RngLib. There's an ARCH independent solution
    called CPU Jitter RNG, which has been adopted by Linux. But there's
    concern that it won't work well in BIOS environment.
    (see https://www.chronox.de/jent/doc/CPU-Jitter-NPTRNG.html)
  - If BaseLibRngNull ASSERTs at boot time, there must be some use cases
    missed. Use a full implementation of RngLib instead.

Regards,
Jian

> -----Original Message-----
> From: Kinney, Michael D <michael.d.kinney@intel.com>
> Sent: Thursday, November 14, 2019 12:21 PM
> To: devel@edk2.groups.io; Wang, Jian J <jian.j.wang@intel.com>; Kinney,
> Michael D <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Bret Barkelew
> <bret.barkelew@microsoft.com>; Zhang, Chao B <chao.b.zhang@intel.com>;
> Wu, Jiaxin <jiaxin.wu@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>; Justen,
> Jordan L <jordan.l.justen@intel.com>; Laszlo Ersek <lersek@redhat.com>; Leif
> Lindholm <leif.lindholm@linaro.org>; Gao, Liming <liming.gao@intel.com>;
> Rabeda, Maciej <maciej.rabeda@intel.com>; Matthew Carlson
> <macarl@microsoft.com>; Ni, Ray <ray.ni@intel.com>; Sean Brogan
> <sean.brogan@microsoft.com>; Fu, Siyuan <siyuan.fu@intel.com>; Lu, XiaoyuX
> <xiaoyux.lu@intel.com>
> Subject: RE: [edk2-devel] [PATCH 00/11] Use proper entropy sources
> 
> Jian,
> 
> In this patch series I see mixed use of different RngLib instances.
> 
> How does a platform developer working on their DSC file know if the
> BaseCryptLib services they are using require a Null or a complete
> implementation of the RngLib?  How does a platform developer know
> if they made the wrong choice.
> 
> Thanks,
> 
> Mike
> 
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On
> > Behalf Of Wang, Jian J
> > Sent: Wednesday, November 13, 2019 6:18 PM
> > To: devel@edk2.groups.io
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>; Bret
> > Barkelew <bret.barkelew@microsoft.com>; Zhang, Chao B
> > <chao.b.zhang@intel.com>; Wu, Jiaxin
> > <jiaxin.wu@intel.com>; Yao, Jiewen
> > <jiewen.yao@intel.com>; Justen, Jordan L
> > <jordan.l.justen@intel.com>; Laszlo Ersek
> > <lersek@redhat.com>; Leif Lindholm
> > <leif.lindholm@linaro.org>; Gao, Liming
> > <liming.gao@intel.com>; Rabeda, Maciej
> > <maciej.rabeda@intel.com>; Matthew Carlson
> > <macarl@microsoft.com>; Kinney, Michael D
> > <michael.d.kinney@intel.com>; Ni, Ray
> > <ray.ni@intel.com>; Sean Brogan
> > <sean.brogan@microsoft.com>; Fu, Siyuan
> > <siyuan.fu@intel.com>; Lu, XiaoyuX
> > <xiaoyux.lu@intel.com>
> > Subject: [edk2-devel] [PATCH 00/11] Use proper entropy
> > sources
> >
> > REF:
> > https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> >
> > Patch series summary:
> >  - Add BaseRngLibNull to package dsc
> >  - Add DxeRngLibRngProtocol to make use
> > EFI_RNG_PROTOCOL
> >  - Add RdSeed interface and RngLibRdSeed for IA32/X64
> > arch
> >  - Remove following files
> >     rand_pool_noise.h
> >     rand_pool_noise_tsc.c
> >     rand_pool_noise.c
> >  - Update rand_pool.c to use RngLib interface directly
> >    and the drop the TimerLib depenency from OpensslLib
> >  - Update OVMF platform dsc to use DxeRngLibRngProtocol
> >    when necessary
> >
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Cc: Bret Barkelew <bret.barkelew@microsoft.com>
> > Cc: Chao Zhang <chao.b.zhang@intel.com>
> > Cc: Jiaxin Wu <jiaxin.wu@intel.com>
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Jordan Justen <jordan.l.justen@intel.com>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Cc: Leif Lindholm <leif.lindholm@linaro.org>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Maciej Rabeda <maciej.rabeda@intel.com>
> > Cc: Matthew Carlson <macarl@microsoft.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > Cc: Siyuan Fu <siyuan.fu@intel.com>
> > Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
> >
> > Jian J Wang (11):
> >   NetworkPkg/NetworkPkg.dsc: specify RngLib instance
> > for build
> >   SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib
> > instances
> >   FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib
> > instances in dsc files
> >   MdePkg/BaseLib: add interface to wrap rdseed IA
> > instruction
> >   SecurityPkg/RngLibRdSeed: add an instance of RngLib
> > to make use rdseed
> >   SecurityPkg/DxeRngLibRngProtocol: add RNG protocol
> > version of RngLib
> >   SecurityPkg/SecurityPkg.dsc: add new RngLib instances
> > for build
> >   OvmfPkg: specify RngLib instances in dsc files
> >   ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances
> > in dsc files
> >   CryptoPkg/OpensslLib: use RngLib to get high quality
> > random entropy
> >   FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib
> > instance
> >
> >  ArmVirtPkg/ArmVirt.dsc.inc                    |   2 +
> >  CryptoPkg/CryptoPkg.dsc                       |   1 +
> >  CryptoPkg/Library/OpensslLib/OpensslLib.inf   |  15 +-
> >  .../Library/OpensslLib/OpensslLibCrypto.inf   |  15 +-
> >  CryptoPkg/Library/OpensslLib/rand_pool.c      | 253
> > ++----------------
> >  .../Library/OpensslLib/rand_pool_noise.c      |  29 --
> >  .../Library/OpensslLib/rand_pool_noise.h      |  29 --
> >  .../Library/OpensslLib/rand_pool_noise_tsc.c  |  43 --
> > -
> >  FmpDevicePkg/FmpDevicePkg.dsc                 |   2 +-
> >  MdePkg/Include/Library/BaseLib.h              |  51
> > ++++
> >  MdePkg/Library/BaseLib/BaseLib.inf            |   4 +
> >  MdePkg/Library/BaseLib/BaseLibInternals.h     |  46
> > ++++
> >  MdePkg/Library/BaseLib/Ia32/RdSeed.nasm       |  87
> > ++++++
> >  MdePkg/Library/BaseLib/X64/RdSeed.nasm        |  80
> > ++++++
> >  MdePkg/Library/BaseLib/X86RdSeed.c            |  73
> > +++++
> >  NetworkPkg/NetworkPkg.dsc                     |   1 +
> >  OvmfPkg/OvmfPkgIa32.dsc                       |   5 +
> >  OvmfPkg/OvmfPkgIa32X64.dsc                    |   5 +
> >  OvmfPkg/OvmfPkgX64.dsc                        |   5 +
> >  OvmfPkg/OvmfXen.dsc                           |   5 +
> >  .../DxeRngLibRngProtocol.c                    | 200
> > ++++++++++++++
> >  .../DxeRngLibRngProtocol.inf                  |  42
> > +++
> >  .../DxeRngLibRngProtocol.uni                  |  14 +
> >  .../RngLibRdSeed/RngLibRdSeed.inf             |  37
> > +++
> >  .../RngLibRdSeed/RngLibRdSeed.uni             |  18 ++
> >  .../RngLibRdSeed/RngRdSeed.c                  | 189
> > +++++++++++++
> >  SecurityPkg/SecurityPkg.dsc                   |   6 +
> >  SignedCapsulePkg/SignedCapsulePkg.dsc         |   6 +
> >  28 files changed, 909 insertions(+), 354 deletions(-)
> > delete mode 100644
> > CryptoPkg/Library/OpensslLib/rand_pool_noise.c
> >  delete mode 100644
> > CryptoPkg/Library/OpensslLib/rand_pool_noise.h
> >  delete mode 100644
> > CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
> >  create mode 100644
> > MdePkg/Library/BaseLib/Ia32/RdSeed.nasm
> >  create mode 100644
> > MdePkg/Library/BaseLib/X64/RdSeed.nasm
> >  create mode 100644 MdePkg/Library/BaseLib/X86RdSeed.c
> >  create mode 100644
> > SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
> > DxeRngLibRngProtocol.c
> >  create mode 100644
> > SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
> > DxeRngLibRngProtocol.inf
> >  create mode 100644
> > SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/
> > DxeRngLibRngProtocol.uni
> >  create mode 100644
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > Seed.inf
> >  create mode 100644
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > Seed.uni
> >  create mode 100644
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
> > d.c
> >
> > --
> > 2.17.1.windows.2
> >
> >
> > 


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

* Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances in dsc files
  2019-11-14  2:17 ` [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: " Wang, Jian J
@ 2019-11-14  7:41   ` Ard Biesheuvel
  2019-11-14  8:03     ` Wang, Jian J
  2019-11-14 10:36   ` Laszlo Ersek
  1 sibling, 1 reply; 36+ messages in thread
From: Ard Biesheuvel @ 2019-11-14  7:41 UTC (permalink / raw)
  To: edk2-devel-groups-io, Jian J Wang; +Cc: Leif Lindholm, Laszlo Ersek

On Thu, 14 Nov 2019 at 02:18, Wang, Jian J <jian.j.wang@intel.com> wrote:
>
> Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib. Update
> ArmVirt.dsc.inc file to accommodate the coming changes. It's supposed
> that only TlsDxe needs random number. The RngDxeLib is added for it. For
> all other drivers, RngLibNull is used by default.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Signed-off-by: Jian J Wang <jian.j.wang@intel.com>

Does this mean we lose the ability to do HTTPS boot if we lack an
implementation of EFI_RNG_PROTOCOL?

> ---
>  ArmVirtPkg/ArmVirt.dsc.inc | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
> index 10037c938e..10e0890699 100644
> --- a/ArmVirtPkg/ArmVirt.dsc.inc
> +++ b/ArmVirtPkg/ArmVirt.dsc.inc
> @@ -156,8 +156,10 @@
>    IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
>  !if $(NETWORK_TLS_ENABLE) == TRUE
>    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
>  !else
>    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
> +  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
>  !endif
>    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
>
> --
> 2.17.1.windows.2
>
>
> 
>

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

* Re: [PATCH 10/11] CryptoPkg/OpensslLib: use RngLib to get high quality random entropy
  2019-11-14  2:17 ` [PATCH 10/11] CryptoPkg/OpensslLib: use RngLib to get high quality random entropy Wang, Jian J
@ 2019-11-14  7:42   ` Ard Biesheuvel
  0 siblings, 0 replies; 36+ messages in thread
From: Ard Biesheuvel @ 2019-11-14  7:42 UTC (permalink / raw)
  To: Jian J Wang
  Cc: edk2-devel-groups-io, Xiaoyu Lu, Laszlo Ersek, Jiewen Yao,
	Chao Zhang, Liming Gao, Ray Ni

On Thu, 14 Nov 2019 at 02:18, Jian J Wang <jian.j.wang@intel.com> wrote:
>
> Per BZ1871, OpensslLib should use RngLib to get high quality of random
> entropy. This patch remove all code depending on TimerLib for this job,
> and add RngLib interface to implement the rand interface required by
> openssl.
>
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> Cc: Xiaoyu Lu <xiaoyux.lu@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Chao Zhang <chao.b.zhang@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Signed-off-by: Jian J Wang <jian.j.wang@intel.com>

Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

> ---
>  CryptoPkg/CryptoPkg.dsc                       |   1 +
>  CryptoPkg/Library/OpensslLib/OpensslLib.inf   |  15 +-
>  .../Library/OpensslLib/OpensslLibCrypto.inf   |  15 +-
>  CryptoPkg/Library/OpensslLib/rand_pool.c      | 253 ++----------------
>  .../Library/OpensslLib/rand_pool_noise.c      |  29 --
>  .../Library/OpensslLib/rand_pool_noise.h      |  29 --
>  .../Library/OpensslLib/rand_pool_noise_tsc.c  |  43 ---
>  7 files changed, 32 insertions(+), 353 deletions(-)
>  delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.c
>  delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.h
>  delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
>
> diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
> index ec43c1f0a4..54f892996a 100644
> --- a/CryptoPkg/CryptoPkg.dsc
> +++ b/CryptoPkg/CryptoPkg.dsc
> @@ -44,6 +44,7 @@
>
>    IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
>    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
>
>  [LibraryClasses.ARM, LibraryClasses.AARCH64]
>    #
> diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
> index b28dd9e480..4c535dc1e6 100644
> --- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
> @@ -23,7 +23,6 @@
>
>  [Sources]
>    buildinf.h
> -  rand_pool_noise.h
>    $(OPENSSL_PATH)/e_os.h
>  # Autogenerated files list starts here
>    $(OPENSSL_PATH)/crypto/aes/aes_cbc.c
> @@ -602,18 +601,6 @@
>    ossl_store.c
>    rand_pool.c
>
> -[Sources.Ia32]
> -  rand_pool_noise_tsc.c
> -
> -[Sources.X64]
> -  rand_pool_noise_tsc.c
> -
> -[Sources.ARM]
> -  rand_pool_noise.c
> -
> -[Sources.AARCH64]
> -  rand_pool_noise.c
> -
>  [Packages]
>    MdePkg/MdePkg.dec
>    CryptoPkg/CryptoPkg.dec
> @@ -621,7 +608,7 @@
>  [LibraryClasses]
>    BaseLib
>    DebugLib
> -  TimerLib
> +  RngLib
>    PrintLib
>
>  [LibraryClasses.ARM]
> diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
> index 1b6ff5ed54..51159a6f2d 100644
> --- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
> +++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
> @@ -547,22 +547,9 @@
>    $(OPENSSL_PATH)/crypto/objects/obj_xref.h
>  # Autogenerated files list ends here
>    buildinf.h
> -  rand_pool_noise.h
>    ossl_store.c
>    rand_pool.c
>
> -[Sources.Ia32]
> -  rand_pool_noise_tsc.c
> -
> -[Sources.X64]
> -  rand_pool_noise_tsc.c
> -
> -[Sources.ARM]
> -  rand_pool_noise.c
> -
> -[Sources.AARCH64]
> -  rand_pool_noise.c
> -
>  [Packages]
>    MdePkg/MdePkg.dec
>    CryptoPkg/CryptoPkg.dec
> @@ -570,7 +557,7 @@
>  [LibraryClasses]
>    BaseLib
>    DebugLib
> -  TimerLib
> +  RngLib
>    PrintLib
>
>  [LibraryClasses.ARM]
> diff --git a/CryptoPkg/Library/OpensslLib/rand_pool.c b/CryptoPkg/Library/OpensslLib/rand_pool.c
> index 9d2a4ad138..f57c238fc4 100644
> --- a/CryptoPkg/Library/OpensslLib/rand_pool.c
> +++ b/CryptoPkg/Library/OpensslLib/rand_pool.c
> @@ -11,213 +11,9 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
>  #include <openssl/aes.h>
>
>  #include <Uefi.h>
> -#include <Library/TimerLib.h>
> -
> -#include "rand_pool_noise.h"
> -
> -/**
> -  Get some randomness from low-order bits of GetPerformanceCounter results.
> -  And combine them to the 64-bit value
> -
> -  @param[out] Rand    Buffer pointer to store the 64-bit random value.
> -
> -  @retval TRUE        Random number generated successfully.
> -  @retval FALSE       Failed to generate.
> -**/
> -STATIC
> -BOOLEAN
> -EFIAPI
> -GetRandNoise64FromPerformanceCounter(
> -  OUT UINT64      *Rand
> -  )
> -{
> -  UINT32 Index;
> -  UINT32 *RandPtr;
> -
> -  if (NULL == Rand) {
> -    return FALSE;
> -  }
> -
> -  RandPtr = (UINT32 *) Rand;
> -
> -  for (Index = 0; Index < 2; Index ++) {
> -    *RandPtr = (UINT32) (GetPerformanceCounter () & 0xFF);
> -    MicroSecondDelay (10);
> -    RandPtr++;
> -  }
> -
> -  return TRUE;
> -}
> -
> -/**
> -  Calls RandomNumber64 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.
> -
> -**/
> -STATIC
> -BOOLEAN
> -EFIAPI
> -RandGetBytes (
> -  IN UINTN         Length,
> -  OUT UINT8        *RandBuffer
> -  )
> -{
> -  BOOLEAN     Ret;
> -  UINT64      TempRand;
> -
> -  Ret = FALSE;
> -
> -  while (Length > 0) {
> -    //
> -    // Get random noise from platform.
> -    // If it failed, fallback to PerformanceCounter
> -    // If you really care about security, you must override
> -    // GetRandomNoise64FromPlatform.
> -    //
> -    Ret = GetRandomNoise64 (&TempRand);
> -    if (Ret == FALSE) {
> -      Ret = GetRandNoise64FromPerformanceCounter (&TempRand);
> -    }
> -    if (!Ret) {
> -      return Ret;
> -    }
> -    if (Length >= sizeof (TempRand)) {
> -      *((UINT64*) RandBuffer) = TempRand;
> -      RandBuffer += sizeof (UINT64);
> -      Length -= sizeof (TempRand);
> -    } else {
> -      CopyMem (RandBuffer, &TempRand, Length);
> -      Length = 0;
> -    }
> -  }
> -
> -  return Ret;
> -}
> -
> -/**
> -  Creates a 128bit random value that is fully forward and backward prediction resistant,
> -  suitable for seeding a NIST SP800-90 Compliant.
> -  This function takes multiple random numbers from PerformanceCounter to ensure reseeding
> -  and performs AES-CBC-MAC over the data to compute the seed value.
> -
> -  @param[out]  SeedBuffer    Pointer to a 128bit buffer to store the random seed.
> -
> -  @retval TRUE        Random seed generation succeeded.
> -  @retval FALSE      Failed to request random bytes.
> -
> -**/
> -STATIC
> -BOOLEAN
> -EFIAPI
> -RandGetSeed128 (
> -  OUT UINT8        *SeedBuffer
> -  )
> -{
> -  BOOLEAN     Ret;
> -  UINT8       RandByte[16];
> -  UINT8       Key[16];
> -  UINT8       Ffv[16];
> -  UINT8       Xored[16];
> -  UINT32      Index;
> -  UINT32      Index2;
> -  AES_KEY     AESKey;
> -
> -  //
> -  // Chose an arbitary key and zero the feed_forward_value (FFV)
> -  //
> -  for (Index = 0; Index < 16; Index++) {
> -    Key[Index] = (UINT8) Index;
> -    Ffv[Index] = 0;
> -  }
> -
> -  AES_set_encrypt_key (Key, 16 * 8, &AESKey);
> -
> -  //
> -  // Perform CBC_MAC over 32 * 128 bit values, with 10us gaps between 128 bit value
> -  // The 10us gaps will ensure multiple reseeds within the system time with a large
> -  // design margin.
> -  //
> -  for (Index = 0; Index < 32; Index++) {
> -    MicroSecondDelay (10);
> -    Ret = RandGetBytes (16, RandByte);
> -    if (!Ret) {
> -      return Ret;
> -    }
> -
> -    //
> -    // Perform XOR operations on two 128-bit value.
> -    //
> -    for (Index2 = 0; Index2 < 16; Index2++) {
> -      Xored[Index2] = RandByte[Index2] ^ Ffv[Index2];
> -    }
> -
> -    AES_encrypt (Xored, Ffv, &AESKey);
> -  }
> -
> -  for (Index = 0; Index < 16; Index++) {
> -    SeedBuffer[Index] = Ffv[Index];
> -  }
> -
> -  return Ret;
> -}
> -
> -/**
> -  Generate high-quality entropy source.
> -
> -  @param[in]   Length        Size of the buffer, in bytes, to fill with.
> -  @param[out]  Entropy       Pointer to the buffer to store the entropy data.
> -
> -  @retval EFI_SUCCESS        Entropy generation succeeded.
> -  @retval EFI_NOT_READY      Failed to request random data.
> -
> -**/
> -STATIC
> -BOOLEAN
> -EFIAPI
> -RandGenerateEntropy (
> -  IN UINTN         Length,
> -  OUT UINT8        *Entropy
> -  )
> -{
> -  BOOLEAN     Ret;
> -  UINTN       BlockCount;
> -  UINT8       Seed[16];
> -  UINT8       *Ptr;
> -
> -  BlockCount = Length / 16;
> -  Ptr        = (UINT8 *) Entropy;
> -
> -  //
> -  // Generate high-quality seed for DRBG Entropy
> -  //
> -  while (BlockCount > 0) {
> -    Ret = RandGetSeed128 (Seed);
> -    if (!Ret) {
> -      return Ret;
> -    }
> -    CopyMem (Ptr, Seed, 16);
> -
> -    BlockCount--;
> -    Ptr = Ptr + 16;
> -  }
> -
> -  //
> -  // Populate the remained data as request.
> -  //
> -  Ret = RandGetSeed128 (Seed);
> -  if (!Ret) {
> -    return Ret;
> -  }
> -  CopyMem (Ptr, Seed, (Length % 16));
> -
> -  return Ret;
> -}
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/RngLib.h>
>
>  /*
>   * Add random bytes to the pool to acquire requested amount of entropy
> @@ -229,17 +25,30 @@ RandGenerateEntropy (
>   */
>  size_t rand_pool_acquire_entropy(RAND_POOL *pool)
>  {
> -  BOOLEAN  Ret;
> -  size_t bytes_needed;
> -  unsigned char * buffer;
> +  BOOLEAN         ret;
> +  size_t          bytes_needed;
> +  size_t          len;
> +  unsigned char   *buffer;
> +  UINT64          data[2];
>
>    bytes_needed = rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
>    if (bytes_needed > 0) {
>      buffer = rand_pool_add_begin(pool, bytes_needed);
>
>      if (buffer != NULL) {
> -      Ret = RandGenerateEntropy(bytes_needed, buffer);
> -      if (FALSE == Ret) {
> +      ret = TRUE;
> +      while (bytes_needed > 0 && ret) {
> +        ret = GetRandomNumber128 (data);
> +        if (ret) {
> +          len = MIN (bytes_needed, sizeof(data));
> +          CopyMem (buffer, data, len);
> +
> +          bytes_needed  -= len;
> +          buffer        += len;
> +        }
> +      }
> +
> +      if (FALSE == ret) {
>          rand_pool_add_end(pool, 0, 0);
>        } else {
>          rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
> @@ -257,13 +66,11 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
>   */
>  int rand_pool_add_nonce_data(RAND_POOL *pool)
>  {
> -  struct {
> -    UINT64  Rand;
> -    UINT64  TimerValue;
> -  } data = { 0 };
> +  UINT64    data[2];
>
> -  RandGetBytes(8, (UINT8 *)&(data.Rand));
> -  data.TimerValue = GetPerformanceCounter();
> +  if (!GetRandomNumber128 (data)) {
> +    return 0;
> +  }
>
>    return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0);
>  }
> @@ -275,13 +82,11 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
>   */
>  int rand_pool_add_additional_data(RAND_POOL *pool)
>  {
> -  struct {
> -    UINT64  Rand;
> -    UINT64  TimerValue;
> -  } data = { 0 };
> +  UINT64    data[2];
>
> -  RandGetBytes(8, (UINT8 *)&(data.Rand));
> -  data.TimerValue = GetPerformanceCounter();
> +  if (!GetRandomNumber128 (data)) {
> +    return 0;
> +  }
>
>    return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0);
>  }
> diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise.c b/CryptoPkg/Library/OpensslLib/rand_pool_noise.c
> deleted file mode 100644
> index c16ed8b454..0000000000
> --- a/CryptoPkg/Library/OpensslLib/rand_pool_noise.c
> +++ /dev/null
> @@ -1,29 +0,0 @@
> -/** @file
> -  Provide rand noise source.
> -
> -Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include <Library/BaseLib.h>
> -
> -/**
> -  Get 64-bit noise source
> -
> -  @param[out] Rand         Buffer pointer to store 64-bit noise source
> -
> -  @retval FALSE            Failed to generate
> -**/
> -BOOLEAN
> -EFIAPI
> -GetRandomNoise64 (
> -  OUT UINT64         *Rand
> -  )
> -{
> -  //
> -  // Return FALSE will fallback to use PerformaceCounter to
> -  // generate noise.
> -  //
> -  return FALSE;
> -}
> diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise.h b/CryptoPkg/Library/OpensslLib/rand_pool_noise.h
> deleted file mode 100644
> index 75acc686a9..0000000000
> --- a/CryptoPkg/Library/OpensslLib/rand_pool_noise.h
> +++ /dev/null
> @@ -1,29 +0,0 @@
> -/** @file
> -  Provide rand noise source.
> -
> -Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#ifndef __RAND_POOL_NOISE_H__
> -#define __RAND_POOL_NOISE_H__
> -
> -#include <Uefi/UefiBaseType.h>
> -
> -/**
> -   Get 64-bit noise source.
> -
> -   @param[out] Rand         Buffer pointer to store 64-bit noise source
> -
> -   @retval TRUE             Get randomness successfully.
> -   @retval FALSE            Failed to generate
> -**/
> -BOOLEAN
> -EFIAPI
> -GetRandomNoise64 (
> -  OUT UINT64         *Rand
> -  );
> -
> -
> -#endif // __RAND_POOL_NOISE_H__
> diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c b/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
> deleted file mode 100644
> index 4158106231..0000000000
> --- a/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
> +++ /dev/null
> @@ -1,43 +0,0 @@
> -/** @file
> -  Provide rand noise source.
> -
> -Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> -SPDX-License-Identifier: BSD-2-Clause-Patent
> -
> -**/
> -
> -#include <Library/BaseLib.h>
> -#include <Library/DebugLib.h>
> -#include <Library/TimerLib.h>
> -
> -/**
> -  Get 64-bit noise source
> -
> -  @param[out] Rand         Buffer pointer to store 64-bit noise source
> -
> -  @retval TRUE             Get randomness successfully.
> -  @retval FALSE            Failed to generate
> -**/
> -BOOLEAN
> -EFIAPI
> -GetRandomNoise64 (
> -  OUT UINT64         *Rand
> -  )
> -{
> -  UINT32 Index;
> -  UINT32 *RandPtr;
> -
> -  if (NULL == Rand) {
> -    return FALSE;
> -  }
> -
> -  RandPtr = (UINT32 *)Rand;
> -
> -  for (Index = 0; Index < 2; Index ++) {
> -    *RandPtr = (UINT32) ((AsmReadTsc ()) & 0xFF);
> -    RandPtr++;
> -    MicroSecondDelay (10);
> -  }
> -
> -  return TRUE;
> -}
> --
> 2.17.1.windows.2
>

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

* Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances in dsc files
  2019-11-14  7:41   ` [edk2-devel] " Ard Biesheuvel
@ 2019-11-14  8:03     ` Wang, Jian J
  2019-11-14  8:14       ` Ard Biesheuvel
  0 siblings, 1 reply; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  8:03 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel-groups-io; +Cc: Leif Lindholm, Laszlo Ersek

Ard,


> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Sent: Thursday, November 14, 2019 3:41 PM
> To: edk2-devel-groups-io <devel@edk2.groups.io>; Wang, Jian J
> <jian.j.wang@intel.com>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>; Laszlo Ersek <lersek@redhat.com>
> Subject: Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify
> RngLib instances in dsc files
> 
> On Thu, 14 Nov 2019 at 02:18, Wang, Jian J <jian.j.wang@intel.com> wrote:
> >
> > Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib. Update
> > ArmVirt.dsc.inc file to accommodate the coming changes. It's supposed
> > that only TlsDxe needs random number. The RngDxeLib is added for it. For
> > all other drivers, RngLibNull is used by default.
> >
> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > Cc: Leif Lindholm <leif.lindholm@linaro.org>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> 
> Does this mean we lose the ability to do HTTPS boot if we lack an
> implementation of EFI_RNG_PROTOCOL?

The ArmVirtQemuXxx.dsc have EFI_RNG_PROTOCOL implemented. The
only one having problem is ArmVirtXen.dsc.

What's your suggestion? Implementing one (RngLib or EFI_RNG_PROTOCOL)
for ARM particually (you guys need to do it) or add a general RngLib (like
cpu jitter) this time (I can do that)?

Regards,
Jian
> 
> > ---
> >  ArmVirtPkg/ArmVirt.dsc.inc | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
> > index 10037c938e..10e0890699 100644
> > --- a/ArmVirtPkg/ArmVirt.dsc.inc
> > +++ b/ArmVirtPkg/ArmVirt.dsc.inc
> > @@ -156,8 +156,10 @@
> >    IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> >  !if $(NETWORK_TLS_ENABLE) == TRUE
> >    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> > +
> RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRng
> LibRngProtocol.inf
> >  !else
> >    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
> > +  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
> >  !endif
> >    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> >
> > --
> > 2.17.1.windows.2
> >
> >
> > 
> >

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

* Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances in dsc files
  2019-11-14  8:03     ` Wang, Jian J
@ 2019-11-14  8:14       ` Ard Biesheuvel
  2019-11-14  8:31         ` Wang, Jian J
  0 siblings, 1 reply; 36+ messages in thread
From: Ard Biesheuvel @ 2019-11-14  8:14 UTC (permalink / raw)
  To: edk2-devel-groups-io, Jian J Wang; +Cc: Leif Lindholm, Laszlo Ersek

On Thu, 14 Nov 2019 at 08:03, Wang, Jian J <jian.j.wang@intel.com> wrote:
>
> Ard,
>
>
> > -----Original Message-----
> > From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Sent: Thursday, November 14, 2019 3:41 PM
> > To: edk2-devel-groups-io <devel@edk2.groups.io>; Wang, Jian J
> > <jian.j.wang@intel.com>
> > Cc: Leif Lindholm <leif.lindholm@linaro.org>; Laszlo Ersek <lersek@redhat.com>
> > Subject: Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify
> > RngLib instances in dsc files
> >
> > On Thu, 14 Nov 2019 at 02:18, Wang, Jian J <jian.j.wang@intel.com> wrote:
> > >
> > > Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib. Update
> > > ArmVirt.dsc.inc file to accommodate the coming changes. It's supposed
> > > that only TlsDxe needs random number. The RngDxeLib is added for it. For
> > > all other drivers, RngLibNull is used by default.
> > >
> > > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > > Cc: Leif Lindholm <leif.lindholm@linaro.org>
> > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > > Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> >
> > Does this mean we lose the ability to do HTTPS boot if we lack an
> > implementation of EFI_RNG_PROTOCOL?
>
> The ArmVirtQemuXxx.dsc have EFI_RNG_PROTOCOL implemented. The
> only one having problem is ArmVirtXen.dsc.
>

No, it applies to all of them. The fact that a driver is available
does not mean the virtual hardware is being provided.

> What's your suggestion? Implementing one (RngLib or EFI_RNG_PROTOCOL)
> for ARM particually (you guys need to do it) or add a general RngLib (like
> cpu jitter) this time (I can do that)?
>

How does this work today? How does TLS obtain the entropy to generate
the symmetric key for encryption?

> >
> > > ---
> > >  ArmVirtPkg/ArmVirt.dsc.inc | 2 ++
> > >  1 file changed, 2 insertions(+)
> > >
> > > diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
> > > index 10037c938e..10e0890699 100644
> > > --- a/ArmVirtPkg/ArmVirt.dsc.inc
> > > +++ b/ArmVirtPkg/ArmVirt.dsc.inc
> > > @@ -156,8 +156,10 @@
> > >    IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> > >  !if $(NETWORK_TLS_ENABLE) == TRUE
> > >    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> > > +
> > RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRng
> > LibRngProtocol.inf
> > >  !else
> > >    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
> > > +  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
> > >  !endif
> > >    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> > >
> > > --
> > > 2.17.1.windows.2
> > >
> > >
> > >
> > >
>
> 
>

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

* Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances in dsc files
  2019-11-14  8:14       ` Ard Biesheuvel
@ 2019-11-14  8:31         ` Wang, Jian J
  0 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14  8:31 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel-groups-io; +Cc: Leif Lindholm, Laszlo Ersek

Ard,


> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Sent: Thursday, November 14, 2019 4:14 PM
> To: edk2-devel-groups-io <devel@edk2.groups.io>; Wang, Jian J
> <jian.j.wang@intel.com>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>; Laszlo Ersek <lersek@redhat.com>
> Subject: Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify
> RngLib instances in dsc files
> 
> On Thu, 14 Nov 2019 at 08:03, Wang, Jian J <jian.j.wang@intel.com> wrote:
> >
> > Ard,
> >
> >
> > > -----Original Message-----
> > > From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > > Sent: Thursday, November 14, 2019 3:41 PM
> > > To: edk2-devel-groups-io <devel@edk2.groups.io>; Wang, Jian J
> > > <jian.j.wang@intel.com>
> > > Cc: Leif Lindholm <leif.lindholm@linaro.org>; Laszlo Ersek
> <lersek@redhat.com>
> > > Subject: Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify
> > > RngLib instances in dsc files
> > >
> > > On Thu, 14 Nov 2019 at 02:18, Wang, Jian J <jian.j.wang@intel.com> wrote:
> > > >
> > > > Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib. Update
> > > > ArmVirt.dsc.inc file to accommodate the coming changes. It's supposed
> > > > that only TlsDxe needs random number. The RngDxeLib is added for it. For
> > > > all other drivers, RngLibNull is used by default.
> > > >
> > > > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > > > Cc: Leif Lindholm <leif.lindholm@linaro.org>
> > > > Cc: Laszlo Ersek <lersek@redhat.com>
> > > > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > > > Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> > >
> > > Does this mean we lose the ability to do HTTPS boot if we lack an
> > > implementation of EFI_RNG_PROTOCOL?
> >
> > The ArmVirtQemuXxx.dsc have EFI_RNG_PROTOCOL implemented. The
> > only one having problem is ArmVirtXen.dsc.
> >
> 
> No, it applies to all of them. The fact that a driver is available
> does not mean the virtual hardware is being provided.
> 

I see. Do you still want me to add the VirtioRngDxe into it?

> > What's your suggestion? Implementing one (RngLib or EFI_RNG_PROTOCOL)
> > for ARM particually (you guys need to do it) or add a general RngLib (like
> > cpu jitter) this time (I can do that)?
> >
> 
> How does this work today? How does TLS obtain the entropy to generate
> the symmetric key for encryption?
> 

I'm not expert of this area. I just read the code to find out the usages.
Here're some use cases (maybe more):
  - session id
  - IV for encryption
  - fill hello random data
  - generate RFC5077 ticket key
  - post-handshake auth

Regards,
Jian

> > >
> > > > ---
> > > >  ArmVirtPkg/ArmVirt.dsc.inc | 2 ++
> > > >  1 file changed, 2 insertions(+)
> > > >
> > > > diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
> > > > index 10037c938e..10e0890699 100644
> > > > --- a/ArmVirtPkg/ArmVirt.dsc.inc
> > > > +++ b/ArmVirtPkg/ArmVirt.dsc.inc
> > > > @@ -156,8 +156,10 @@
> > > >    IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> > > >  !if $(NETWORK_TLS_ENABLE) == TRUE
> > > >    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> > > > +
> > >
> RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRng
> > > LibRngProtocol.inf
> > > >  !else
> > > >    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
> > > > +  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
> > > >  !endif
> > > >    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> > > >
> > > > --
> > > > 2.17.1.windows.2
> > > >
> > > >
> > > >
> > > >
> >
> > 
> >

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

* Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances in dsc files
  2019-11-14  2:17 ` [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: " Wang, Jian J
  2019-11-14  7:41   ` [edk2-devel] " Ard Biesheuvel
@ 2019-11-14 10:36   ` Laszlo Ersek
  2019-11-14 14:26     ` Wang, Jian J
  1 sibling, 1 reply; 36+ messages in thread
From: Laszlo Ersek @ 2019-11-14 10:36 UTC (permalink / raw)
  To: devel, jian.j.wang; +Cc: Leif Lindholm, Ard Biesheuvel

On 11/14/19 03:17, Wang, Jian J wrote:
> Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib. Update
> ArmVirt.dsc.inc file to accommodate the coming changes. It's supposed
> that only TlsDxe needs random number. The RngDxeLib is added for it. For
> all other drivers, RngLibNull is used by default.
> 
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> Cc: Leif Lindholm <leif.lindholm@linaro.org>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> ---
>  ArmVirtPkg/ArmVirt.dsc.inc | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
> index 10037c938e..10e0890699 100644
> --- a/ArmVirtPkg/ArmVirt.dsc.inc
> +++ b/ArmVirtPkg/ArmVirt.dsc.inc
> @@ -156,8 +156,10 @@
>    IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
>  !if $(NETWORK_TLS_ENABLE) == TRUE
>    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> +  RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
>  !else
>    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
> +  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
>  !endif
>    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
>  
> 

(1) This is not right: the non-Null lib instance should be linked into
TlsDxe only, like in the OvmfPkg patch.

Please locate TlsAuthConfigDxe in both "ArmVirtQemu.dsc" and
"ArmVirtQemuKernel.dsc", and implement the same approach as in OvmfPkg
near "TlsAuthConfigDxe".

(2) See other comments in my OvmfPkg patch review.

Thanks
Laszlo


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

* Re: [edk2-devel] [PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files
  2019-11-14  2:17 ` [PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files Wang, Jian J
@ 2019-11-14 11:07   ` Laszlo Ersek
  2019-11-14 14:40     ` Wang, Jian J
  0 siblings, 1 reply; 36+ messages in thread
From: Laszlo Ersek @ 2019-11-14 11:07 UTC (permalink / raw)
  To: jian.j.wang, Ard Biesheuvel; +Cc: devel, Jordan Justen, Liming Gao, Ray Ni

Jian, Ard,

commenting for both OvmfPkg and ArmVirtPkg:

On 11/14/19 03:17, Wang, Jian J wrote:
> Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib.
> Update OVMF dsc files to accommodate the coming changes. It's supposed
> that only TlsDxe needs random number. The DxeRngLibRngProtocol is added
> for it. For all other drivers, BaseRngLibNull is used by default.
> 
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> Cc: Jordan Justen <jordan.l.justen@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> ---
>  OvmfPkg/OvmfPkgIa32.dsc    | 5 +++++
>  OvmfPkg/OvmfPkgIa32X64.dsc | 5 +++++
>  OvmfPkg/OvmfPkgX64.dsc     | 5 +++++
>  OvmfPkg/OvmfXen.dsc        | 5 +++++
>  4 files changed, 20 insertions(+)
> 
> diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> index d350b75630..5a709a95b2 100644
> --- a/OvmfPkg/OvmfPkgIa32.dsc
> +++ b/OvmfPkg/OvmfPkgIa32.dsc
> @@ -217,6 +217,7 @@
>  
>  [LibraryClasses.common]
>    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> +  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
>  
>  [LibraryClasses.common.SEC]
>    TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
> @@ -786,6 +787,10 @@
>      <LibraryClasses>
>        NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
>    }
> +  NetworkPkg/TlsDxe/TlsDxe.inf {
> +    <LibraryClasses>
> +      RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
> +  }
>  !endif
>    OvmfPkg/VirtioNetDxe/VirtioNet.inf
>  

This is not right for either OvmfPkg or ArmVirtPkg, because:

- the virtual hardware is dynamic and might change from boot to boot,

- EFI_RNG_PROTOCOL, implemented by VirtioRngDxe, only supports
EFI_RNG_ALGORITHM_RAW.

I propose the following approach.

(1) Jian, please do introduce all of the RngLib instances that you are
introducing in this v1 series, namely:

- the null lib instance,
- the RDSEED lib instance,
- the DXE / protocol lib instance that directly requires NIST/ANSI
conformant algorithm support from the RNG protocol.

(2) Jian, please add a *further* lib instance: a time based one. This
instance should basically extract the current functionality from
"rand_pool_noise.c" and "rand_pool_noise_tsc.c". (The code that you are
removing in patch #10.)

It's also fine with me if, rather than factoring out the
rand_pool_noise*.c logic, you add a new "CPU jitter" based RngLib
instance. (Ard might disagree with me about this alternative -- the
point is that we should have a library instance that provides *some*
(even if barely tolerable) randomness, but with no dependency on
*optional* hardware. In other words, this lib instance should depend on
*guaranteed* platform hardware only. TSC, TimerLib, etc.)

(3) For OvmfPkg and ArmVirtPkg, please write patches that:

- provide a default resolution to the Null instance,

- resolve RngLib to the time-based instance, for TlsDxe *only*.

At that point, we will have made ArmVirtPkg and OvmfPkg *independent* of
the rest of this series -- ArmVirtPkg and OvmfPkg will not block this
patch series, they will also not suffer any regressions, and we can go
ahead and implement a separate RngLib instance for TlsDxe ourselves.


Now, let me lay out my proposal for *that* RngLib instance. (I'm willing
to write it a good chunk of it, but I will need help from Ard minimally
in the crypto code.)

- The CONSTRUCTOR function should register an End-of-Dxe notification
function. In that function, (a) a boolean flag (such as "mEndOfDxe")
should be flipped from FALSE to TRUE, and (b) a pointer to
EFI_RNG_PROTOCOL should be saved (if such a protocol exists), such as
"mRngProtocol".

- each RngLib API in this lib instance should hang, if "mEndOfDxe" is
FALSE at the time of the call (--> CpuDeadLoop() etc)

- otherwise, if "mRngProtocol" is not NULL, it should be used to fetch
*raw* entropy. That raw entropy should be mixed sufficiently for NIST /
ANSI conformance. (I hope this statement makes sense.) This is where I'd
absolutely need help from Ard.

- otherwise, on IA32/X64 only, if CPUID indicates that RDSEED is
supported by the processor, call RDSEED.

- otherwise, on IA32/X64 only, if CPUID indicates that RDRAND is
supported by the processor, call RDRAND.

- otherwise, on all arches, scrape some timer-based entropy, "from the
bottom of the barrel" (possibly in an arch-specific way, e.g. we could
use TSC on IA32/X64).

- The platform BDS code for OVMF and ArmVirtQemu* should bind the
virtio-rng device to VirtioRngDxe *before* signaling End-of-Dxe.


The basic idea is that this RngLib instance should give the platform a
*chance* to produce an EFI_RNG_PROTOCOL instance until End-of-Dxe. If
that happens, then continue consuming raw entropy from *that* source,
and mix it manually for NIST / ANSI conformance. Otherwise, gracefully
degrade to the next strongest entropy source that's dynamically detected
on the platform (RDSEED or RDRAND, per CPUID -- on IA32/X64 only --, and
then timer-based -- on all platforms).

Thanks
Laszlo


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

* Re: [edk2-devel] [PATCH 06/11] SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib
  2019-11-14  2:17 ` [PATCH 06/11] SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib Wang, Jian J
@ 2019-11-14 11:15   ` Laszlo Ersek
  2019-11-14 14:52     ` Wang, Jian J
  0 siblings, 1 reply; 36+ messages in thread
From: Laszlo Ersek @ 2019-11-14 11:15 UTC (permalink / raw)
  To: devel, jian.j.wang
  Cc: Jiewen Yao, Chao Zhang, Ard Biesheuvel, Matthew Carlson,
	Sean Brogan, Bret Barkelew, Liming Gao, Ray Ni

On 11/14/19 03:17, Wang, Jian J wrote:
> From: Matthew Carlson <macarl@microsoft.com>
> 
> This version of RngLib makes use of EFI_RNG_PROTOCOL to provide random
> number. According to UEFI spec, EFI_RNG_PROTOCOL should meet NIST SP
> 800-90 and/or ANSI X9.31 standards.

I'd like to slightly correct the UEFI spec reference. In UEFI-2.8,
section "37.5.1 EFI RNG Algorithm Definitions" writes,

    [...] The algorithms listed are optional, not meant to be exhaustive
    and may be augmented by vendors or other industry standards. [...]

Meaning that an EFI_RNG_PROTOCOL instance is not "required", per spec,
to support any one of the
- gEfiRngAlgorithmSp80090Ctr256Guid
- gEfiRngAlgorithmSp80090Hmac256Guid
- gEfiRngAlgorithmSp80090Hash256Guid
algorithms.

It's of course fine to require one of those algorithms, as a policy
decision, in this particular library instance -- but, as far as I can
tell, that decision does not follow from the spec.

Thanks
Laszlo

> 
> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Chao Zhang <chao.b.zhang@intel.com>
> Cc: Laszlo Ersek <lersek@redhat.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Matthew Carlson <macarl@microsoft.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>
> Cc: Bret Barkelew <bret.barkelew@microsoft.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> ---
>  .../DxeRngLibRngProtocol.c                    | 200 ++++++++++++++++++
>  .../DxeRngLibRngProtocol.inf                  |  42 ++++
>  .../DxeRngLibRngProtocol.uni                  |  14 ++
>  3 files changed, 256 insertions(+)
>  create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c
>  create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
>  create mode 100644 SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni
> 
> diff --git a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c
> new file mode 100644
> index 0000000000..8ce4a7050d
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.c
> @@ -0,0 +1,200 @@
> +/** @file
> + Provides an implementation of the library class RngLib that uses the Rng protocol.
> +
> +Copyright (c) Microsoft Corporation. All rights reserved.
> +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include <Uefi.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/RngLib.h>
> +#include <Protocol/Rng.h>
> +
> +/**
> +  Generates a random number via the NIST 800-9A algorithm.  Refer to
> +  http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf
> +  for more information.
> +
> +  @param[out] Buffer      Buffer to receive the random number.
> +  @param[in]  BufferSize  Number of bytes in Buffer.
> +
> +  @retval EFI_SUCCESS  Random data generated successfully.
> +  @retval Others       Failed to generate the random number.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +GenerateRandomNumberViaNist800Algorithm(
> +  OUT UINT8* Buffer,
> +  IN  UINTN  BufferSize
> +  )
> +{
> +  EFI_STATUS        Status;
> +  EFI_RNG_PROTOCOL* RngProtocol;
> +
> +  Status = EFI_UNSUPPORTED;
> +  RngProtocol = NULL;
> +
> +  if (Buffer == NULL) {
> +    DEBUG ((DEBUG_ERROR, "[%a] Buffer == NULL.\n", __FUNCTION__));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (gBS == NULL) {
> +    DEBUG ((DEBUG_ERROR, "[%a] GenerateRandomNumber, gBS == NULL.  Called too soon.\n", __FUNCTION__));
> +    return EFI_LOAD_ERROR;
> +  }
> +
> +  Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&RngProtocol);
> +  if (EFI_ERROR (Status) || RngProtocol == NULL) {
> +    DEBUG ((DEBUG_ERROR, "[%a] Could not locate RNG prototocol, Status = %r\n", __FUNCTION__, Status));
> +    return Status;
> +  }
> +
> +  Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Ctr256Guid, BufferSize, Buffer);
> +  DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm CTR-256 - Status = %r\n", __FUNCTION__, Status));
> +  if (!EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hmac256Guid, BufferSize, Buffer);
> +  DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm HMAC-256 - Status = %r\n", __FUNCTION__, Status));
> +  if (!EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = RngProtocol->GetRNG (RngProtocol, &gEfiRngAlgorithmSp80090Hash256Guid, BufferSize, Buffer);
> +  DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm Hash-256 - Status = %r\n", __FUNCTION__, Status));
> +  if (!EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  //
> +  // If we get to this point, we have failed
> +  //
> +  DEBUG((DEBUG_ERROR, "[%a] GetRNG() failed, staus = %r\n", __FUNCTION__, Status));
> +
> +  return Status;
> +}
> +
> +
> +/**
> +  Generates a 16-bit random number.
> +
> +  if Rand is NULL, return FALSE.
> +
> +  @param[out] Rand     Buffer pointer to store the 16-bit random value.
> +
> +  @retval TRUE         Random number generated successfully.
> +  @retval FALSE        Failed to generate the random number.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +GetRandomNumber16 (
> +  OUT     UINT16                    *Rand
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  if (Rand == NULL) {
> +    return FALSE;
> +  }
> +
> +  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 2);
> +  if (EFI_ERROR (Status)) {
> +    return FALSE;
> +  }
> +  return TRUE;
> +}
> +
> +/**
> +  Generates a 32-bit random number.
> +
> +  if Rand is NULL, return FALSE.
> +
> +  @param[out] Rand     Buffer pointer to store the 32-bit random value.
> +
> +  @retval TRUE         Random number generated successfully.
> +  @retval FALSE        Failed to generate the random number.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +GetRandomNumber32 (
> +  OUT     UINT32                    *Rand
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  if (Rand == NULL) {
> +    return FALSE;
> +  }
> +
> +  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 4);
> +  if (EFI_ERROR (Status)) {
> +    return FALSE;
> +  }
> +  return TRUE;
> +}
> +
> +/**
> +  Generates a 64-bit random number.
> +
> +  if Rand is NULL, return FALSE.
> +
> +  @param[out] Rand     Buffer pointer to store the 64-bit random value.
> +
> +  @retval TRUE         Random number generated successfully.
> +  @retval FALSE        Failed to generate the random number.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +GetRandomNumber64 (
> +  OUT     UINT64                    *Rand
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  if (Rand == NULL) {
> +    return FALSE;
> +  }
> +
> +  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 8);
> +  if (EFI_ERROR (Status)) {
> +    return FALSE;
> +  }
> +  return TRUE;
> +}
> +
> +/**
> +  Generates a 128-bit random number.
> +
> +  if Rand is NULL, return FALSE.
> +
> +  @param[out] Rand     Buffer pointer to store the 128-bit random value.
> +
> +  @retval TRUE         Random number generated successfully.
> +  @retval FALSE        Failed to generate the random number.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +GetRandomNumber128 (
> +  OUT     UINT64                    *Rand
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  if (Rand == NULL) {
> +    return FALSE;
> +  }
> +
> +  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 16);
> +  if (EFI_ERROR (Status)) {
> +    return FALSE;
> +  }
> +  return TRUE;
> +}
> diff --git a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
> new file mode 100644
> index 0000000000..d47fe3be53
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.inf
> @@ -0,0 +1,42 @@
> +# @file
> +# Provides implementation of the library class RngLib that uses the RngProtocol
> +#
> +# @copyright
> +# Copyright (c) Microsoft Corporation. All rights reserved.
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION     = 0x00010029
> +  BASE_NAME       = DxeRngLibRngProtocol
> +  MODULE_UNI_FILE = DxeRngLibRngProtocol.uni
> +  FILE_GUID       = FF9F84C5-A33E-44E3-9BB5-0D654B2D4149
> +  MODULE_TYPE     = DXE_DRIVER
> +  VERSION_STRING  = 1.0
> +  LIBRARY_CLASS   = RngLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 EBC ARM AARCH64
> +#
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +
> +[Sources]
> +  DxeRngLibRngProtocol.c
> +
> +[LibraryClasses]
> +  DebugLib
> +  UefiBootServicesTableLib
> +
> +[Protocols]
> +  gEfiRngProtocolGuid                 ## CONSUMES
> +
> +[Depex]
> +  gEfiRngProtocolGuid
> +
> +[Guids]
> +  gEfiRngAlgorithmSp80090Ctr256Guid            ## CONSUMES
> +  gEfiRngAlgorithmSp80090Hash256Guid           ## CONSUMES
> +  gEfiRngAlgorithmSp80090Hmac256Guid           ## CONSUMES
> diff --git a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni
> new file mode 100644
> index 0000000000..09af056bd3
> --- /dev/null
> +++ b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngProtocol.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> +// Instance of RNG (Random Number Generator) Library Based on EFI_RNG_PROTOCOL.
> +//
> +// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "Instance of RNG Library Based on EFI_RNG_PROTOCOL."
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "This version of RNG library makes use of EFI_RNG_PROTOCOL to generate random number compliant with NIST 800-9A."
> +
> 


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

* Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify RngLib instances in dsc files
  2019-11-14 10:36   ` Laszlo Ersek
@ 2019-11-14 14:26     ` Wang, Jian J
  0 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14 14:26 UTC (permalink / raw)
  To: devel@edk2.groups.io, lersek@redhat.com; +Cc: Leif Lindholm, Ard Biesheuvel

Laszlo,


> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Laszlo Ersek
> Sent: Thursday, November 14, 2019 6:37 PM
> To: devel@edk2.groups.io; Wang, Jian J <jian.j.wang@intel.com>
> Cc: Leif Lindholm <leif.lindholm@linaro.org>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>
> Subject: Re: [edk2-devel] [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: specify
> RngLib instances in dsc files
> 
> On 11/14/19 03:17, Wang, Jian J wrote:
> > Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib. Update
> > ArmVirt.dsc.inc file to accommodate the coming changes. It's supposed
> > that only TlsDxe needs random number. The RngDxeLib is added for it. For
> > all other drivers, RngLibNull is used by default.
> >
> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > Cc: Leif Lindholm <leif.lindholm@linaro.org>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> > ---
> >  ArmVirtPkg/ArmVirt.dsc.inc | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
> > index 10037c938e..10e0890699 100644
> > --- a/ArmVirtPkg/ArmVirt.dsc.inc
> > +++ b/ArmVirtPkg/ArmVirt.dsc.inc
> > @@ -156,8 +156,10 @@
> >    IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> >  !if $(NETWORK_TLS_ENABLE) == TRUE
> >    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
> > +
> RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRng
> LibRngProtocol.inf
> >  !else
> >    OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
> > +  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
> >  !endif
> >    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> >
> >
> 
> (1) This is not right: the non-Null lib instance should be linked into
> TlsDxe only, like in the OvmfPkg patch.
> 
> Please locate TlsAuthConfigDxe in both "ArmVirtQemu.dsc" and
> "ArmVirtQemuKernel.dsc", and implement the same approach as in OvmfPkg
> near "TlsAuthConfigDxe".
> 

Got it. I'll update them all.

> (2) See other comments in my OvmfPkg patch review.
> 

Thanks,
Jian

> Thanks
> Laszlo
> 
> 
> 


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

* Re: [edk2-devel] [PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files
  2019-11-14 11:07   ` [edk2-devel] " Laszlo Ersek
@ 2019-11-14 14:40     ` Wang, Jian J
  2019-11-14 14:51       ` Laszlo Ersek
  0 siblings, 1 reply; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14 14:40 UTC (permalink / raw)
  To: devel@edk2.groups.io, lersek@redhat.com, Ard Biesheuvel
  Cc: Justen, Jordan L, Gao, Liming, Ni, Ray

Laszlo,


> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Laszlo Ersek
> Sent: Thursday, November 14, 2019 7:08 PM
> To: Wang, Jian J <jian.j.wang@intel.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>
> Cc: devel@edk2.groups.io; Justen, Jordan L <jordan.l.justen@intel.com>; Gao,
> Liming <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH 08/11] OvmfPkg: specify RngLib instances in
> dsc files
> 
> Jian, Ard,
> 
> commenting for both OvmfPkg and ArmVirtPkg:
> 
> On 11/14/19 03:17, Wang, Jian J wrote:
> > Per BZ1871, OpensslLib will depend on RngLib instead of TimerLib.
> > Update OVMF dsc files to accommodate the coming changes. It's supposed
> > that only TlsDxe needs random number. The DxeRngLibRngProtocol is added
> > for it. For all other drivers, BaseRngLibNull is used by default.
> >
> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > Cc: Jordan Justen <jordan.l.justen@intel.com>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> > Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> > ---
> >  OvmfPkg/OvmfPkgIa32.dsc    | 5 +++++
> >  OvmfPkg/OvmfPkgIa32X64.dsc | 5 +++++
> >  OvmfPkg/OvmfPkgX64.dsc     | 5 +++++
> >  OvmfPkg/OvmfXen.dsc        | 5 +++++
> >  4 files changed, 20 insertions(+)
> >
> > diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
> > index d350b75630..5a709a95b2 100644
> > --- a/OvmfPkg/OvmfPkgIa32.dsc
> > +++ b/OvmfPkg/OvmfPkgIa32.dsc
> > @@ -217,6 +217,7 @@
> >
> >  [LibraryClasses.common]
> >    BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> > +  RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf
> >
> >  [LibraryClasses.common.SEC]
> >    TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseRomAcpiTimerLib.inf
> > @@ -786,6 +787,10 @@
> >      <LibraryClasses>
> >        NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf
> >    }
> > +  NetworkPkg/TlsDxe/TlsDxe.inf {
> > +    <LibraryClasses>
> > +
> RngLib|SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRng
> LibRngProtocol.inf
> > +  }
> >  !endif
> >    OvmfPkg/VirtioNetDxe/VirtioNet.inf
> >
> 
> This is not right for either OvmfPkg or ArmVirtPkg, because:
> 
> - the virtual hardware is dynamic and might change from boot to boot,
> 
> - EFI_RNG_PROTOCOL, implemented by VirtioRngDxe, only supports
> EFI_RNG_ALGORITHM_RAW.
> 
> I propose the following approach.
> 
> (1) Jian, please do introduce all of the RngLib instances that you are
> introducing in this v1 series, namely:
> 
> - the null lib instance,
> - the RDSEED lib instance,
> - the DXE / protocol lib instance that directly requires NIST/ANSI
> conformant algorithm support from the RNG protocol.
> 

I agree.

> (2) Jian, please add a *further* lib instance: a time based one. This
> instance should basically extract the current functionality from
> "rand_pool_noise.c" and "rand_pool_noise_tsc.c". (The code that you are
> removing in patch #10.)
> 
> It's also fine with me if, rather than factoring out the
> rand_pool_noise*.c logic, you add a new "CPU jitter" based RngLib
> instance. (Ard might disagree with me about this alternative -- the
> point is that we should have a library instance that provides *some*
> (even if barely tolerable) randomness, but with no dependency on
> *optional* hardware. In other words, this lib instance should depend on
> *guaranteed* platform hardware only. TSC, TimerLib, etc.)
> 

Either is fine with me. I'll let you and Ard to make decision.

> (3) For OvmfPkg and ArmVirtPkg, please write patches that:
> 
> - provide a default resolution to the Null instance,
> 
> - resolve RngLib to the time-based instance, for TlsDxe *only*.
> 

Ok. I'll update those dsc in v2.

> At that point, we will have made ArmVirtPkg and OvmfPkg *independent* of
> the rest of this series -- ArmVirtPkg and OvmfPkg will not block this
> patch series, they will also not suffer any regressions, and we can go
> ahead and implement a separate RngLib instance for TlsDxe ourselves.
> 
> 
> Now, let me lay out my proposal for *that* RngLib instance. (I'm willing
> to write it a good chunk of it, but I will need help from Ard minimally
> in the crypto code.)
> 
> - The CONSTRUCTOR function should register an End-of-Dxe notification
> function. In that function, (a) a boolean flag (such as "mEndOfDxe")
> should be flipped from FALSE to TRUE, and (b) a pointer to
> EFI_RNG_PROTOCOL should be saved (if such a protocol exists), such as
> "mRngProtocol".
> 
> - each RngLib API in this lib instance should hang, if "mEndOfDxe" is
> FALSE at the time of the call (--> CpuDeadLoop() etc)
> 
> - otherwise, if "mRngProtocol" is not NULL, it should be used to fetch
> *raw* entropy. That raw entropy should be mixed sufficiently for NIST /
> ANSI conformance. (I hope this statement makes sense.) This is where I'd
> absolutely need help from Ard.
> 
> - otherwise, on IA32/X64 only, if CPUID indicates that RDSEED is
> supported by the processor, call RDSEED.
> 
> - otherwise, on IA32/X64 only, if CPUID indicates that RDRAND is
> supported by the processor, call RDRAND.
> 
> - otherwise, on all arches, scrape some timer-based entropy, "from the
> bottom of the barrel" (possibly in an arch-specific way, e.g. we could
> use TSC on IA32/X64).
> 
> - The platform BDS code for OVMF and ArmVirtQemu* should bind the
> virtio-rng device to VirtioRngDxe *before* signaling End-of-Dxe.
> 
> 
> The basic idea is that this RngLib instance should give the platform a
> *chance* to produce an EFI_RNG_PROTOCOL instance until End-of-Dxe. If
> that happens, then continue consuming raw entropy from *that* source,
> and mix it manually for NIST / ANSI conformance. Otherwise, gracefully
> degrade to the next strongest entropy source that's dynamically detected
> on the platform (RDSEED or RDRAND, per CPUID -- on IA32/X64 only --, and
> then timer-based -- on all platforms).
> 

I'm curious that you want to do the "degrade" dynamically at boot time not
build time, right?

Thanks,
Jian

> Thanks
> Laszlo
> 
> 
> 


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

* Re: [edk2-devel] [PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files
  2019-11-14 14:40     ` Wang, Jian J
@ 2019-11-14 14:51       ` Laszlo Ersek
  2019-11-14 14:55         ` Wang, Jian J
  0 siblings, 1 reply; 36+ messages in thread
From: Laszlo Ersek @ 2019-11-14 14:51 UTC (permalink / raw)
  To: Wang, Jian J, devel@edk2.groups.io, Ard Biesheuvel
  Cc: Justen, Jordan L, Gao, Liming, Ni, Ray

On 11/14/19 15:40, Wang, Jian J wrote:

> I'm curious that you want to do the "degrade" dynamically at boot time not
> build time, right?

Indeed, that's the whole point. When running on QEMU (considering all of
arm/aarch64/i386/x86_64), the firmware can assume quite little of the
underlying platform hardware; a single firmware binary is expected to
support multiple (virtual) hardware configurations. Therefore several
decisions have to be made dynamically at boot time, in the firmware,
that physical firmware platforms can hard-wire at build time.

(Of course this approach has its limits -- the most visible "platform
split" that we do implement at build time is "QEMU vs. Xen". ArmVirtPkg
implements this switch only at build time, and OvmfPkg will also fully
adopt that approach in the future.)

Thanks
Laszlo


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

* Re: [edk2-devel] [PATCH 06/11] SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib
  2019-11-14 11:15   ` [edk2-devel] " Laszlo Ersek
@ 2019-11-14 14:52     ` Wang, Jian J
  0 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14 14:52 UTC (permalink / raw)
  To: Laszlo Ersek, devel@edk2.groups.io
  Cc: Yao, Jiewen, Zhang, Chao B, Ard Biesheuvel, Matthew Carlson,
	Sean Brogan, Bret Barkelew, Gao, Liming, Ni, Ray

Laszlo,


> -----Original Message-----
> From: Laszlo Ersek <lersek@redhat.com>
> Sent: Thursday, November 14, 2019 7:16 PM
> To: devel@edk2.groups.io; Wang, Jian J <jian.j.wang@intel.com>
> Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> <chao.b.zhang@intel.com>; Ard Biesheuvel <ard.biesheuvel@linaro.org>;
> Matthew Carlson <macarl@microsoft.com>; Sean Brogan
> <sean.brogan@microsoft.com>; Bret Barkelew
> <bret.barkelew@microsoft.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
> <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH 06/11] SecurityPkg/DxeRngLibRngProtocol:
> add RNG protocol version of RngLib
> 
> On 11/14/19 03:17, Wang, Jian J wrote:
> > From: Matthew Carlson <macarl@microsoft.com>
> >
> > This version of RngLib makes use of EFI_RNG_PROTOCOL to provide random
> > number. According to UEFI spec, EFI_RNG_PROTOCOL should meet NIST SP
> > 800-90 and/or ANSI X9.31 standards.
> 
> I'd like to slightly correct the UEFI spec reference. In UEFI-2.8,
> section "37.5.1 EFI RNG Algorithm Definitions" writes,
> 
>     [...] The algorithms listed are optional, not meant to be exhaustive
>     and may be augmented by vendors or other industry standards. [...]
> 
> Meaning that an EFI_RNG_PROTOCOL instance is not "required", per spec,
> to support any one of the
> - gEfiRngAlgorithmSp80090Ctr256Guid
> - gEfiRngAlgorithmSp80090Hmac256Guid
> - gEfiRngAlgorithmSp80090Hash256Guid
> algorithms.
> 
> It's of course fine to require one of those algorithms, as a policy
> decision, in this particular library instance -- but, as far as I can
> tell, that decision does not follow from the spec.
> 

I think you're right about the spec. Although they're not "required"
ones, we can still suggest to follow the NIST/ANSI spec about random
entropy in the implementation of EFI_RNG_PROTOCOL.

Regards,
Jian

> Thanks
> Laszlo
> 
> >
> > Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Cc: Chao Zhang <chao.b.zhang@intel.com>
> > Cc: Laszlo Ersek <lersek@redhat.com>
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Cc: Matthew Carlson <macarl@microsoft.com>
> > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > Cc: Bret Barkelew <bret.barkelew@microsoft.com>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> > Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> > ---
> >  .../DxeRngLibRngProtocol.c                    | 200 ++++++++++++++++++
> >  .../DxeRngLibRngProtocol.inf                  |  42 ++++
> >  .../DxeRngLibRngProtocol.uni                  |  14 ++
> >  3 files changed, 256 insertions(+)
> >  create mode 100644
> SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngPr
> otocol.c
> >  create mode 100644
> SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngPr
> otocol.inf
> >  create mode 100644
> SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRngPr
> otocol.uni
> >
> > diff --git
> a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRn
> gProtocol.c
> b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRn
> gProtocol.c
> > new file mode 100644
> > index 0000000000..8ce4a7050d
> > --- /dev/null
> > +++
> b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRn
> gProtocol.c
> > @@ -0,0 +1,200 @@
> > +/** @file
> > + Provides an implementation of the library class RngLib that uses the Rng
> protocol.
> > +
> > +Copyright (c) Microsoft Corporation. All rights reserved.
> > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#include <Uefi.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/RngLib.h>
> > +#include <Protocol/Rng.h>
> > +
> > +/**
> > +  Generates a random number via the NIST 800-9A algorithm.  Refer to
> > +  http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf
> > +  for more information.
> > +
> > +  @param[out] Buffer      Buffer to receive the random number.
> > +  @param[in]  BufferSize  Number of bytes in Buffer.
> > +
> > +  @retval EFI_SUCCESS  Random data generated successfully.
> > +  @retval Others       Failed to generate the random number.
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +GenerateRandomNumberViaNist800Algorithm(
> > +  OUT UINT8* Buffer,
> > +  IN  UINTN  BufferSize
> > +  )
> > +{
> > +  EFI_STATUS        Status;
> > +  EFI_RNG_PROTOCOL* RngProtocol;
> > +
> > +  Status = EFI_UNSUPPORTED;
> > +  RngProtocol = NULL;
> > +
> > +  if (Buffer == NULL) {
> > +    DEBUG ((DEBUG_ERROR, "[%a] Buffer == NULL.\n", __FUNCTION__));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  if (gBS == NULL) {
> > +    DEBUG ((DEBUG_ERROR, "[%a] GenerateRandomNumber, gBS == NULL.
> Called too soon.\n", __FUNCTION__));
> > +    return EFI_LOAD_ERROR;
> > +  }
> > +
> > +  Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID
> **)&RngProtocol);
> > +  if (EFI_ERROR (Status) || RngProtocol == NULL) {
> > +    DEBUG ((DEBUG_ERROR, "[%a] Could not locate RNG prototocol, Status
> = %r\n", __FUNCTION__, Status));
> > +    return Status;
> > +  }
> > +
> > +  Status = RngProtocol->GetRNG (RngProtocol,
> &gEfiRngAlgorithmSp80090Ctr256Guid, BufferSize, Buffer);
> > +  DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm CTR-256 - Status
> = %r\n", __FUNCTION__, Status));
> > +  if (!EFI_ERROR (Status)) {
> > +    return Status;
> > +  }
> > +
> > +  Status = RngProtocol->GetRNG (RngProtocol,
> &gEfiRngAlgorithmSp80090Hmac256Guid, BufferSize, Buffer);
> > +  DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm HMAC-256 - Status
> = %r\n", __FUNCTION__, Status));
> > +  if (!EFI_ERROR (Status)) {
> > +    return Status;
> > +  }
> > +
> > +  Status = RngProtocol->GetRNG (RngProtocol,
> &gEfiRngAlgorithmSp80090Hash256Guid, BufferSize, Buffer);
> > +  DEBUG ((DEBUG_VERBOSE, "[%a] GetRNG algorithm Hash-256 - Status
> = %r\n", __FUNCTION__, Status));
> > +  if (!EFI_ERROR (Status)) {
> > +    return Status;
> > +  }
> > +  //
> > +  // If we get to this point, we have failed
> > +  //
> > +  DEBUG((DEBUG_ERROR, "[%a] GetRNG() failed, staus = %r\n",
> __FUNCTION__, Status));
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Generates a 16-bit random number.
> > +
> > +  if Rand is NULL, return FALSE.
> > +
> > +  @param[out] Rand     Buffer pointer to store the 16-bit random value.
> > +
> > +  @retval TRUE         Random number generated successfully.
> > +  @retval FALSE        Failed to generate the random number.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +GetRandomNumber16 (
> > +  OUT     UINT16                    *Rand
> > +  )
> > +{
> > +  EFI_STATUS Status;
> > +
> > +  if (Rand == NULL) {
> > +    return FALSE;
> > +  }
> > +
> > +  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 2);
> > +  if (EFI_ERROR (Status)) {
> > +    return FALSE;
> > +  }
> > +  return TRUE;
> > +}
> > +
> > +/**
> > +  Generates a 32-bit random number.
> > +
> > +  if Rand is NULL, return FALSE.
> > +
> > +  @param[out] Rand     Buffer pointer to store the 32-bit random value.
> > +
> > +  @retval TRUE         Random number generated successfully.
> > +  @retval FALSE        Failed to generate the random number.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +GetRandomNumber32 (
> > +  OUT     UINT32                    *Rand
> > +  )
> > +{
> > +  EFI_STATUS Status;
> > +
> > +  if (Rand == NULL) {
> > +    return FALSE;
> > +  }
> > +
> > +  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 4);
> > +  if (EFI_ERROR (Status)) {
> > +    return FALSE;
> > +  }
> > +  return TRUE;
> > +}
> > +
> > +/**
> > +  Generates a 64-bit random number.
> > +
> > +  if Rand is NULL, return FALSE.
> > +
> > +  @param[out] Rand     Buffer pointer to store the 64-bit random value.
> > +
> > +  @retval TRUE         Random number generated successfully.
> > +  @retval FALSE        Failed to generate the random number.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +GetRandomNumber64 (
> > +  OUT     UINT64                    *Rand
> > +  )
> > +{
> > +  EFI_STATUS Status;
> > +
> > +  if (Rand == NULL) {
> > +    return FALSE;
> > +  }
> > +
> > +  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 8);
> > +  if (EFI_ERROR (Status)) {
> > +    return FALSE;
> > +  }
> > +  return TRUE;
> > +}
> > +
> > +/**
> > +  Generates a 128-bit random number.
> > +
> > +  if Rand is NULL, return FALSE.
> > +
> > +  @param[out] Rand     Buffer pointer to store the 128-bit random value.
> > +
> > +  @retval TRUE         Random number generated successfully.
> > +  @retval FALSE        Failed to generate the random number.
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +GetRandomNumber128 (
> > +  OUT     UINT64                    *Rand
> > +  )
> > +{
> > +  EFI_STATUS Status;
> > +
> > +  if (Rand == NULL) {
> > +    return FALSE;
> > +  }
> > +
> > +  Status = GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 16);
> > +  if (EFI_ERROR (Status)) {
> > +    return FALSE;
> > +  }
> > +  return TRUE;
> > +}
> > diff --git
> a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRn
> gProtocol.inf
> b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRn
> gProtocol.inf
> > new file mode 100644
> > index 0000000000..d47fe3be53
> > --- /dev/null
> > +++
> b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRn
> gProtocol.inf
> > @@ -0,0 +1,42 @@
> > +# @file
> > +# Provides implementation of the library class RngLib that uses the
> RngProtocol
> > +#
> > +# @copyright
> > +# Copyright (c) Microsoft Corporation. All rights reserved.
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION     = 0x00010029
> > +  BASE_NAME       = DxeRngLibRngProtocol
> > +  MODULE_UNI_FILE = DxeRngLibRngProtocol.uni
> > +  FILE_GUID       = FF9F84C5-A33E-44E3-9BB5-0D654B2D4149
> > +  MODULE_TYPE     = DXE_DRIVER
> > +  VERSION_STRING  = 1.0
> > +  LIBRARY_CLASS   = RngLib|DXE_DRIVER DXE_RUNTIME_DRIVER
> DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
> > +
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64 EBC ARM AARCH64
> > +#
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +
> > +[Sources]
> > +  DxeRngLibRngProtocol.c
> > +
> > +[LibraryClasses]
> > +  DebugLib
> > +  UefiBootServicesTableLib
> > +
> > +[Protocols]
> > +  gEfiRngProtocolGuid                 ## CONSUMES
> > +
> > +[Depex]
> > +  gEfiRngProtocolGuid
> > +
> > +[Guids]
> > +  gEfiRngAlgorithmSp80090Ctr256Guid            ## CONSUMES
> > +  gEfiRngAlgorithmSp80090Hash256Guid           ## CONSUMES
> > +  gEfiRngAlgorithmSp80090Hmac256Guid           ## CONSUMES
> > diff --git
> a/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRn
> gProtocol.uni
> b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRn
> gProtocol.uni
> > new file mode 100644
> > index 0000000000..09af056bd3
> > --- /dev/null
> > +++
> b/SecurityPkg/RandomNumberGenerator/DxeRngLibRngProtocol/DxeRngLibRn
> gProtocol.uni
> > @@ -0,0 +1,14 @@
> > +// /** @file
> > +// Instance of RNG (Random Number Generator) Library Based on
> EFI_RNG_PROTOCOL.
> > +//
> > +// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > +//
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +
> > +#string STR_MODULE_ABSTRACT             #language en-US "Instance of RNG
> Library Based on EFI_RNG_PROTOCOL."
> > +
> > +#string STR_MODULE_DESCRIPTION          #language en-US "This version of
> RNG library makes use of EFI_RNG_PROTOCOL to generate random number
> compliant with NIST 800-9A."
> > +
> >


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

* Re: [edk2-devel] [PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files
  2019-11-14 14:51       ` Laszlo Ersek
@ 2019-11-14 14:55         ` Wang, Jian J
  0 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-14 14:55 UTC (permalink / raw)
  To: devel@edk2.groups.io, lersek@redhat.com, Ard Biesheuvel
  Cc: Justen, Jordan L, Gao, Liming, Ni, Ray

Laszlo,

That makes sense for virtual platforms. Thanks for the explanation.

Regards,
Jian

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Laszlo Ersek
> Sent: Thursday, November 14, 2019 10:51 PM
> To: Wang, Jian J <jian.j.wang@intel.com>; devel@edk2.groups.io; Ard
> Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Justen, Jordan L <jordan.l.justen@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH 08/11] OvmfPkg: specify RngLib instances in
> dsc files
> 
> On 11/14/19 15:40, Wang, Jian J wrote:
> 
> > I'm curious that you want to do the "degrade" dynamically at boot time not
> > build time, right?
> 
> Indeed, that's the whole point. When running on QEMU (considering all of
> arm/aarch64/i386/x86_64), the firmware can assume quite little of the
> underlying platform hardware; a single firmware binary is expected to
> support multiple (virtual) hardware configurations. Therefore several
> decisions have to be made dynamically at boot time, in the firmware,
> that physical firmware platforms can hard-wire at build time.
> 
> (Of course this approach has its limits -- the most visible "platform
> split" that we do implement at build time is "QEMU vs. Xen". ArmVirtPkg
> implements this switch only at build time, and OvmfPkg will also fully
> adopt that approach in the future.)
> 
> Thanks
> Laszlo
> 
> 
> 


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

* Re: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
  2019-11-14  4:38     ` Wang, Jian J
@ 2019-11-15 13:28       ` Ard Biesheuvel
  2019-11-15 17:21         ` Michael D Kinney
  2019-11-15 22:19         ` Laszlo Ersek
  0 siblings, 2 replies; 36+ messages in thread
From: Ard Biesheuvel @ 2019-11-15 13:28 UTC (permalink / raw)
  To: edk2-devel-groups-io, Jian J Wang
  Cc: Kinney, Michael D, Yao, Jiewen, Zhang, Chao B, Gao, Liming,
	Ni, Ray

On Thu, 14 Nov 2019 at 04:39, Wang, Jian J <jian.j.wang@intel.com> wrote:
>
> Mike,
>
> I figured that rdseed is only needed in cases demanding highest entropy,
> like seeding other pseudo-RNG. It's not for general purpose randomness.
> Then I put it in SecurityPkg. But I'm ok to put it into MdePkg. I have no
> strong opinion for this.
>

I think it is a bad idea to use the same library abstraction [RngLib]
for exposing
a) entropy sources used for seeding deterministic random number generators
b) deterministic random number generators themselves
c) low entropy pseudo-RNGs based on timestamp counters, etc

given that the use cases don't usually overlap. I.e., only a DRBG
implementation requires a), and exports RngLib itself based on that.
Use cases that can tolerate c) [like IV generators for block
encryption] are typically disjoint from ones that require b) [for key
generation]. The idea that you can use RngLib for all of them, and
plug arbitrary instantiations of it into each is misguided IMHO.



> > -----Original Message-----
> > From: Kinney, Michael D <michael.d.kinney@intel.com>
> > Sent: Thursday, November 14, 2019 12:25 PM
> > To: devel@edk2.groups.io; Wang, Jian J <jian.j.wang@intel.com>; Kinney,
> > Michael D <michael.d.kinney@intel.com>
> > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> > <chao.b.zhang@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
> > <ray.ni@intel.com>
> > Subject: RE: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an
> > instance of RngLib to make use rdseed
> >
> > Jian,
> >
> > Why is this lib instance in the SecurityPkg?  It only depends
> > on the MdePkg.  Can't non security feature related modules
> > that want to a random number use this lib without using the
> > SecurityPkg?  Could this lib instance be added to MdePkg?
> >
> > Thanks,
> >
> > Mike
> >
> > > -----Original Message-----
> > > From: devel@edk2.groups.io <devel@edk2.groups.io> On
> > > Behalf Of Wang, Jian J
> > > Sent: Wednesday, November 13, 2019 6:18 PM
> > > To: devel@edk2.groups.io
> > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> > > <chao.b.zhang@intel.com>; Kinney, Michael D
> > > <michael.d.kinney@intel.com>; Gao, Liming
> > > <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>
> > > Subject: [edk2-devel] [PATCH 05/11]
> > > SecurityPkg/RngLibRdSeed: add an instance of RngLib to
> > > make use rdseed
> > >
> > > This version of RngLib makes use of AsmRdSeed to get
> > > non-deterministic random number, which can be used for
> > > seeding other software DRNG like rand interface in
> > > openssl. It can be used only on IA32/X64 processors
> > > which supports rdseed instruction.
> > >
> > > Ref:
> > > https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > Cc: Chao Zhang <chao.b.zhang@intel.com>
> > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > Cc: Liming Gao <liming.gao@intel.com>
> > > Cc: Ray Ni <ray.ni@intel.com>
> > > Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
> > > ---
> > >  .../RngLibRdSeed/RngLibRdSeed.inf             |  37
> > > ++++
> > >  .../RngLibRdSeed/RngLibRdSeed.uni             |  18 ++
> > >  .../RngLibRdSeed/RngRdSeed.c                  | 189
> > > ++++++++++++++++++
> > >  3 files changed, 244 insertions(+)
> > >  create mode 100644
> > > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > > Seed.inf
> > >  create mode 100644
> > > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > > Seed.uni
> > >  create mode 100644
> > > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
> > > d.c
> > >
> > > diff --git
> > > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > RdSeed.inf
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > RdSeed.inf
> > > new file mode 100644
> > > index 0000000000..8162408775
> > > --- /dev/null
> > > +++
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > RdSeed.inf
> > > @@ -0,0 +1,37 @@
> > > +## @file
> > > +#  Instance of RNG (Random Number Generator) Library.
> > > +#
> > > +#  Rng RdSeed Library that uses CPU RdSeed instruction
> > > access to
> > > +provide #  non-deterministic random number which can
> > > be used as seed
> > > +for other #  software deterministic RNGs.
> > > +#
> > > +#  Copyright (c) 2019, Intel Corporation. All rights
> > > reserved.<BR> # #
> > > +SPDX-License-Identifier: BSD-2-Clause-Patent # # ##
> > > +
> > > +[Defines]
> > > +  INF_VERSION                    = 0x00010029
> > > +  BASE_NAME                      = RngLibRdSeed
> > > +  MODULE_UNI_FILE                = RngLibRdSeed.uni
> > > +  FILE_GUID                      = 8B613B2E-B944-40F9-
> > > B979-1B60D7CAA73C
> > > +  MODULE_TYPE                    = BASE
> > > +  VERSION_STRING                 = 1.0
> > > +  LIBRARY_CLASS                  = RngLib
> > > +  CONSTRUCTOR                    =
> > > RngLibRdSeedConstructor
> > > +
> > > +#
> > > +#  VALID_ARCHITECTURES           = IA32 X64
> > > +#
> > > +
> > > +[Sources.Ia32, Sources.X64]
> > > +  RngRdSeed.c
> > > +
> > > +[Packages]
> > > +  MdePkg/MdePkg.dec
> > > +
> > > +[LibraryClasses]
> > > +  BaseLib
> > > +  DebugLib
> > > diff --git
> > > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > RdSeed.uni
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > RdSeed.uni
> > > new file mode 100644
> > > index 0000000000..051a3019bc
> > > --- /dev/null
> > > +++
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > RdSeed.uni
> > > @@ -0,0 +1,18 @@
> > > +// /** @file
> > > +// Instance of RNG (Random Number Generator) Library.
> > > +//
> > > +// Rng RdSeed Library that uses CPU RdSeed instruction
> > > access to
> > > +provide // non-deterministic random number which can
> > > be used as seed
> > > +for other // software deterministic RNGs.
> > > +//
> > > +// Copyright (c) 2019, Intel Corporation. All rights
> > > reserved.<BR> //
> > > +// SPDX-License-Identifier: BSD-2-Clause-Patent // //
> > > **/
> > > +
> > > +
> > > +#string STR_MODULE_ABSTRACT             #language en-
> > > US "Instance of RNG Library"
> > > +
> > > +#string STR_MODULE_DESCRIPTION          #language en-
> > > US "RngRdSeed Library that uses CPU RdSeed instruction
> > > access to provide non-deterministic random numbers."
> > > +
> > > diff --git
> > > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > eed.c
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > eed.c
> > > new file mode 100644
> > > index 0000000000..0036faa050
> > > --- /dev/null
> > > +++
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > eed.c
> > > @@ -0,0 +1,189 @@
> > > +/** @file
> > > +  Random number generator services that uses RdSeed
> > > instruction access
> > > +  to provide non-deterministic random numbers, which
> > > are usually used
> > > +  for seeding other pseudo-random number generators.
> > > +
> > > +Copyright (c) 2019, 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>
> > > +
> > > +//
> > > +// Bit mask used to determine if RdSeed instruction is
> > > supported.
> > > +//
> > > +#define RDSEED_MASK                  BIT18
> > > +
> > > +//
> > > +// Limited retry number when valid random data is
> > > returned.
> > > +// It varies between 1 and 100 according to "Intel(R)
> > > DRGN Software
> > > +Implementation // Guide". Let's use the same value as
> > > RDRAND in BaseRngLib.
> > > +//
> > > +#define RDSEED_RETRY_LIMIT           10
> > > +
> > > +/**
> > > +  The constructor function checks whether or not
> > > RDSEED instruction is
> > > +supported
> > > +  by the host hardware.
> > > +
> > > +  The constructor function checks whether or not
> > > RDSEED instruction is supported.
> > > +  It will ASSERT() if RDSEED instruction is not
> > > supported.
> > > +
> > > +  @retval RETURN_SUCCESS      The processor supports
> > > RDSEED instruction.
> > > +  @retval RETURN_UNSUPPORTED  RDSEED instruction is
> > > not supported.
> > > +
> > > +**/
> > > +RETURN_STATUS
> > > +EFIAPI
> > > +RngLibRdSeedConstructor (
> > > +  VOID
> > > +  )
> > > +{
> > > +  UINT32  RegEbx;
> > > +
> > > +  //
> > > +  // Determine RDSEED support by examining bit 18 of
> > > the EBX register
> > > + returned by  // CPUID(EAX=7, ECX=0). BIT18 of EBX
> > > indicates that
> > > + processor support RDSEED  // instruction.
> > > +  //
> > > +  AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL);  if
> > > ((RegEbx &
> > > + RDSEED_MASK) != RDSEED_MASK) {
> > > +    ASSERT ((RegEbx & RDSEED_MASK) == RDSEED_MASK);
> > > +    return RETURN_UNSUPPORTED;
> > > +  }
> > > +
> > > +  return RETURN_SUCCESS;
> > > +}
> > > +
> > > +/**
> > > +  Generates a 16-bit random number.
> > > +
> > > +  if Rand is NULL, then ASSERT().
> > > +
> > > +  @param[out] Rand     Buffer pointer to store the 16-
> > > bit random value.
> > > +
> > > +  @retval TRUE         Random number generated
> > > successfully.
> > > +  @retval FALSE        Failed to generate the random
> > > number.
> > > +
> > > +**/
> > > +BOOLEAN
> > > +EFIAPI
> > > +GetRandomNumber16 (
> > > +  OUT     UINT16                    *Rand
> > > +  )
> > > +{
> > > +  UINT32  Index;
> > > +
> > > +  ASSERT (Rand != NULL);
> > > +
> > > +  //
> > > +  // A loop to fetch a 16 bit random value with a
> > > retry count limit.
> > > +  //
> > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
> > > {
> > > +    if (AsmRdSeed16 (Rand)) {
> > > +      return TRUE;
> > > +    }
> > > +  }
> > > +
> > > +  return FALSE;
> > > +}
> > > +
> > > +/**
> > > +  Generates a 32-bit random number.
> > > +
> > > +  if Rand is NULL, then ASSERT().
> > > +
> > > +  @param[out] Rand     Buffer pointer to store the 32-
> > > bit random value.
> > > +
> > > +  @retval TRUE         Random number generated
> > > successfully.
> > > +  @retval FALSE        Failed to generate the random
> > > number.
> > > +
> > > +**/
> > > +BOOLEAN
> > > +EFIAPI
> > > +GetRandomNumber32 (
> > > +  OUT     UINT32                    *Rand
> > > +  )
> > > +{
> > > +  UINT32  Index;
> > > +
> > > +  ASSERT (Rand != NULL);
> > > +
> > > +  //
> > > +  // A loop to fetch a 32 bit random value with a
> > > retry count limit.
> > > +  //
> > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
> > > {
> > > +    if (AsmRdSeed32 (Rand)) {
> > > +      return TRUE;
> > > +    }
> > > +  }
> > > +
> > > +  return FALSE;
> > > +}
> > > +
> > > +/**
> > > +  Generates a 64-bit random number.
> > > +
> > > +  if Rand is NULL, then ASSERT().
> > > +
> > > +  @param[out] Rand     Buffer pointer to store the 64-
> > > bit random value.
> > > +
> > > +  @retval TRUE         Random number generated
> > > successfully.
> > > +  @retval FALSE        Failed to generate the random
> > > number.
> > > +
> > > +**/
> > > +BOOLEAN
> > > +EFIAPI
> > > +GetRandomNumber64 (
> > > +  OUT     UINT64                    *Rand
> > > +  )
> > > +{
> > > +  UINT32  Index;
> > > +
> > > +  ASSERT (Rand != NULL);
> > > +
> > > +  //
> > > +  // A loop to fetch a 64 bit random value with a
> > > retry count limit.
> > > +  //
> > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT; Index++)
> > > {
> > > +    if (AsmRdSeed64 (Rand)) {
> > > +      return TRUE;
> > > +    }
> > > +  }
> > > +
> > > +  return FALSE;
> > > +}
> > > +
> > > +/**
> > > +  Generates a 128-bit random number.
> > > +
> > > +  if Rand is NULL, then ASSERT().
> > > +
> > > +  @param[out] Rand     Buffer pointer to store the
> > > 128-bit random value.
> > > +
> > > +  @retval TRUE         Random number generated
> > > successfully.
> > > +  @retval FALSE        Failed to generate the random
> > > number.
> > > +
> > > +**/
> > > +BOOLEAN
> > > +EFIAPI
> > > +GetRandomNumber128 (
> > > +  OUT     UINT64                    *Rand
> > > +  )
> > > +{
> > > +  ASSERT (Rand != NULL);
> > > +
> > > +  //
> > > +  // Read first 64 bits
> > > +  //
> > > +  if (!GetRandomNumber64 (Rand)) {
> > > +    return FALSE;
> > > +  }
> > > +
> > > +  //
> > > +  // Read second 64 bits
> > > +  //
> > > +  return GetRandomNumber64 (++Rand);
> > > +}
> > > --
> > > 2.17.1.windows.2
> > >
> > >
> > >
>
>
> 
>

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

* Re: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
  2019-11-15 13:28       ` Ard Biesheuvel
@ 2019-11-15 17:21         ` Michael D Kinney
  2019-11-15 17:35           ` Ard Biesheuvel
  2019-11-15 22:19         ` Laszlo Ersek
  1 sibling, 1 reply; 36+ messages in thread
From: Michael D Kinney @ 2019-11-15 17:21 UTC (permalink / raw)
  To: Ard Biesheuvel, edk2-devel-groups-io, Wang, Jian J,
	Kinney, Michael D
  Cc: Yao, Jiewen, Zhang, Chao B, Gao, Liming, Ni, Ray

Hi Ard,

What would you recommend as way to provide these different
types of services?  Some more new lib classes and instances?

Thanks,

Mike

> -----Original Message-----
> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Sent: Friday, November 15, 2019 5:29 AM
> To: edk2-devel-groups-io <devel@edk2.groups.io>; Wang,
> Jian J <jian.j.wang@intel.com>
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>;
> Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> <chao.b.zhang@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH 05/11]
> SecurityPkg/RngLibRdSeed: add an instance of RngLib to
> make use rdseed
> 
> On Thu, 14 Nov 2019 at 04:39, Wang, Jian J
> <jian.j.wang@intel.com> wrote:
> >
> > Mike,
> >
> > I figured that rdseed is only needed in cases
> demanding highest
> > entropy, like seeding other pseudo-RNG. It's not for
> general purpose randomness.
> > Then I put it in SecurityPkg. But I'm ok to put it
> into MdePkg. I have
> > no strong opinion for this.
> >
> 
> I think it is a bad idea to use the same library
> abstraction [RngLib] for exposing
> a) entropy sources used for seeding deterministic
> random number generators
> b) deterministic random number generators themselves
> c) low entropy pseudo-RNGs based on timestamp counters,
> etc
> 
> given that the use cases don't usually overlap. I.e.,
> only a DRBG implementation requires a), and exports
> RngLib itself based on that.
> Use cases that can tolerate c) [like IV generators for
> block encryption] are typically disjoint from ones that
> require b) [for key generation]. The idea that you can
> use RngLib for all of them, and plug arbitrary
> instantiations of it into each is misguided IMHO.
> 
> 
> 
> > > -----Original Message-----
> > > From: Kinney, Michael D
> <michael.d.kinney@intel.com>
> > > Sent: Thursday, November 14, 2019 12:25 PM
> > > To: devel@edk2.groups.io; Wang, Jian J
> <jian.j.wang@intel.com>;
> > > Kinney, Michael D <michael.d.kinney@intel.com>
> > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao
> B
> > > <chao.b.zhang@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Ni,
> > > Ray <ray.ni@intel.com>
> > > Subject: RE: [edk2-devel] [PATCH 05/11]
> SecurityPkg/RngLibRdSeed:
> > > add an instance of RngLib to make use rdseed
> > >
> > > Jian,
> > >
> > > Why is this lib instance in the SecurityPkg?  It
> only depends on the
> > > MdePkg.  Can't non security feature related modules
> that want to a
> > > random number use this lib without using the
> SecurityPkg?  Could
> > > this lib instance be added to MdePkg?
> > >
> > > Thanks,
> > >
> > > Mike
> > >
> > > > -----Original Message-----
> > > > From: devel@edk2.groups.io <devel@edk2.groups.io>
> On Behalf Of
> > > > Wang, Jian J
> > > > Sent: Wednesday, November 13, 2019 6:18 PM
> > > > To: devel@edk2.groups.io
> > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang,
> Chao B
> > > > <chao.b.zhang@intel.com>; Kinney, Michael D
> > > > <michael.d.kinney@intel.com>; Gao, Liming
> <liming.gao@intel.com>;
> > > > Ni, Ray <ray.ni@intel.com>
> > > > Subject: [edk2-devel] [PATCH 05/11]
> > > > SecurityPkg/RngLibRdSeed: add an instance of
> RngLib to make use
> > > > rdseed
> > > >
> > > > This version of RngLib makes use of AsmRdSeed to
> get
> > > > non-deterministic random number, which can be
> used for seeding
> > > > other software DRNG like rand interface in
> openssl. It can be used
> > > > only on IA32/X64 processors which supports rdseed
> instruction.
> > > >
> > > > Ref:
> > > >
> https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > Cc: Chao Zhang <chao.b.zhang@intel.com>
> > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > Cc: Liming Gao <liming.gao@intel.com>
> > > > Cc: Ray Ni <ray.ni@intel.com>
> > > > Signed-off-by: Jian J Wang
> <jian.j.wang@intel.com>
> > > > ---
> > > >  .../RngLibRdSeed/RngLibRdSeed.inf             |
> 37
> > > > ++++
> > > >  .../RngLibRdSeed/RngLibRdSeed.uni             |
> 18 ++
> > > >  .../RngLibRdSeed/RngRdSeed.c                  |
> 189
> > > > ++++++++++++++++++
> > > >  3 files changed, 244 insertions(+)  create mode
> 100644
> > > >
> SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > > > Seed.inf
> > > >  create mode 100644
> > > >
> SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > > > Seed.uni
> > > >  create mode 100644
> > > >
> SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
> > > > d.c
> > > >
> > > > diff --git
> > > >
> a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > RdSeed.inf
> > > >
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > RdSeed.inf
> > > > new file mode 100644
> > > > index 0000000000..8162408775
> > > > --- /dev/null
> > > > +++
> > > >
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > RdSeed.inf
> > > > @@ -0,0 +1,37 @@
> > > > +## @file
> > > > +#  Instance of RNG (Random Number Generator)
> Library.
> > > > +#
> > > > +#  Rng RdSeed Library that uses CPU RdSeed
> instruction
> > > > access to
> > > > +provide #  non-deterministic random number which
> can
> > > > be used as seed
> > > > +for other #  software deterministic RNGs.
> > > > +#
> > > > +#  Copyright (c) 2019, Intel Corporation. All
> rights
> > > > reserved.<BR> # #
> > > > +SPDX-License-Identifier: BSD-2-Clause-Patent # #
> ##
> > > > +
> > > > +[Defines]
> > > > +  INF_VERSION                    = 0x00010029
> > > > +  BASE_NAME                      = RngLibRdSeed
> > > > +  MODULE_UNI_FILE                =
> RngLibRdSeed.uni
> > > > +  FILE_GUID                      = 8B613B2E-
> B944-40F9-
> > > > B979-1B60D7CAA73C
> > > > +  MODULE_TYPE                    = BASE
> > > > +  VERSION_STRING                 = 1.0
> > > > +  LIBRARY_CLASS                  = RngLib
> > > > +  CONSTRUCTOR                    =
> > > > RngLibRdSeedConstructor
> > > > +
> > > > +#
> > > > +#  VALID_ARCHITECTURES           = IA32 X64
> > > > +#
> > > > +
> > > > +[Sources.Ia32, Sources.X64]
> > > > +  RngRdSeed.c
> > > > +
> > > > +[Packages]
> > > > +  MdePkg/MdePkg.dec
> > > > +
> > > > +[LibraryClasses]
> > > > +  BaseLib
> > > > +  DebugLib
> > > > diff --git
> > > >
> a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > RdSeed.uni
> > > >
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > RdSeed.uni
> > > > new file mode 100644
> > > > index 0000000000..051a3019bc
> > > > --- /dev/null
> > > > +++
> > > >
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > RdSeed.uni
> > > > @@ -0,0 +1,18 @@
> > > > +// /** @file
> > > > +// Instance of RNG (Random Number Generator)
> Library.
> > > > +//
> > > > +// Rng RdSeed Library that uses CPU RdSeed
> instruction
> > > > access to
> > > > +provide // non-deterministic random number which
> can
> > > > be used as seed
> > > > +for other // software deterministic RNGs.
> > > > +//
> > > > +// Copyright (c) 2019, Intel Corporation. All
> rights
> > > > reserved.<BR> //
> > > > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> // //
> > > > **/
> > > > +
> > > > +
> > > > +#string STR_MODULE_ABSTRACT
> #language en-
> > > > US "Instance of RNG Library"
> > > > +
> > > > +#string STR_MODULE_DESCRIPTION
> #language en-
> > > > US "RngRdSeed Library that uses CPU RdSeed
> instruction access to
> > > > provide non-deterministic random numbers."
> > > > +
> > > > diff --git
> > > >
> a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > eed.c
> > > >
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > eed.c
> > > > new file mode 100644
> > > > index 0000000000..0036faa050
> > > > --- /dev/null
> > > > +++
> > > >
> b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > eed.c
> > > > @@ -0,0 +1,189 @@
> > > > +/** @file
> > > > +  Random number generator services that uses
> RdSeed
> > > > instruction access
> > > > +  to provide non-deterministic random numbers,
> which
> > > > are usually used
> > > > +  for seeding other pseudo-random number
> generators.
> > > > +
> > > > +Copyright (c) 2019, 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>
> > > > +
> > > > +//
> > > > +// Bit mask used to determine if RdSeed
> instruction is
> > > > supported.
> > > > +//
> > > > +#define RDSEED_MASK                  BIT18
> > > > +
> > > > +//
> > > > +// Limited retry number when valid random data
> is
> > > > returned.
> > > > +// It varies between 1 and 100 according to
> "Intel(R)
> > > > DRGN Software
> > > > +Implementation // Guide". Let's use the same
> value as
> > > > RDRAND in BaseRngLib.
> > > > +//
> > > > +#define RDSEED_RETRY_LIMIT           10
> > > > +
> > > > +/**
> > > > +  The constructor function checks whether or not
> > > > RDSEED instruction is
> > > > +supported
> > > > +  by the host hardware.
> > > > +
> > > > +  The constructor function checks whether or not
> > > > RDSEED instruction is supported.
> > > > +  It will ASSERT() if RDSEED instruction is not
> > > > supported.
> > > > +
> > > > +  @retval RETURN_SUCCESS      The processor
> supports
> > > > RDSEED instruction.
> > > > +  @retval RETURN_UNSUPPORTED  RDSEED instruction
> is
> > > > not supported.
> > > > +
> > > > +**/
> > > > +RETURN_STATUS
> > > > +EFIAPI
> > > > +RngLibRdSeedConstructor (
> > > > +  VOID
> > > > +  )
> > > > +{
> > > > +  UINT32  RegEbx;
> > > > +
> > > > +  //
> > > > +  // Determine RDSEED support by examining bit
> 18 of
> > > > the EBX register
> > > > + returned by  // CPUID(EAX=7, ECX=0). BIT18 of
> EBX
> > > > indicates that
> > > > + processor support RDSEED  // instruction.
> > > > +  //
> > > > +  AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL);
> if
> > > > ((RegEbx &
> > > > + RDSEED_MASK) != RDSEED_MASK) {
> > > > +    ASSERT ((RegEbx & RDSEED_MASK) ==
> RDSEED_MASK);
> > > > +    return RETURN_UNSUPPORTED;
> > > > +  }
> > > > +
> > > > +  return RETURN_SUCCESS;
> > > > +}
> > > > +
> > > > +/**
> > > > +  Generates a 16-bit random number.
> > > > +
> > > > +  if Rand is NULL, then ASSERT().
> > > > +
> > > > +  @param[out] Rand     Buffer pointer to store
> the 16-
> > > > bit random value.
> > > > +
> > > > +  @retval TRUE         Random number generated
> > > > successfully.
> > > > +  @retval FALSE        Failed to generate the
> random
> > > > number.
> > > > +
> > > > +**/
> > > > +BOOLEAN
> > > > +EFIAPI
> > > > +GetRandomNumber16 (
> > > > +  OUT     UINT16                    *Rand
> > > > +  )
> > > > +{
> > > > +  UINT32  Index;
> > > > +
> > > > +  ASSERT (Rand != NULL);
> > > > +
> > > > +  //
> > > > +  // A loop to fetch a 16 bit random value with
> a
> > > > retry count limit.
> > > > +  //
> > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> Index++)
> > > > {
> > > > +    if (AsmRdSeed16 (Rand)) {
> > > > +      return TRUE;
> > > > +    }
> > > > +  }
> > > > +
> > > > +  return FALSE;
> > > > +}
> > > > +
> > > > +/**
> > > > +  Generates a 32-bit random number.
> > > > +
> > > > +  if Rand is NULL, then ASSERT().
> > > > +
> > > > +  @param[out] Rand     Buffer pointer to store
> the 32-
> > > > bit random value.
> > > > +
> > > > +  @retval TRUE         Random number generated
> > > > successfully.
> > > > +  @retval FALSE        Failed to generate the
> random
> > > > number.
> > > > +
> > > > +**/
> > > > +BOOLEAN
> > > > +EFIAPI
> > > > +GetRandomNumber32 (
> > > > +  OUT     UINT32                    *Rand
> > > > +  )
> > > > +{
> > > > +  UINT32  Index;
> > > > +
> > > > +  ASSERT (Rand != NULL);
> > > > +
> > > > +  //
> > > > +  // A loop to fetch a 32 bit random value with
> a
> > > > retry count limit.
> > > > +  //
> > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> Index++)
> > > > {
> > > > +    if (AsmRdSeed32 (Rand)) {
> > > > +      return TRUE;
> > > > +    }
> > > > +  }
> > > > +
> > > > +  return FALSE;
> > > > +}
> > > > +
> > > > +/**
> > > > +  Generates a 64-bit random number.
> > > > +
> > > > +  if Rand is NULL, then ASSERT().
> > > > +
> > > > +  @param[out] Rand     Buffer pointer to store
> the 64-
> > > > bit random value.
> > > > +
> > > > +  @retval TRUE         Random number generated
> > > > successfully.
> > > > +  @retval FALSE        Failed to generate the
> random
> > > > number.
> > > > +
> > > > +**/
> > > > +BOOLEAN
> > > > +EFIAPI
> > > > +GetRandomNumber64 (
> > > > +  OUT     UINT64                    *Rand
> > > > +  )
> > > > +{
> > > > +  UINT32  Index;
> > > > +
> > > > +  ASSERT (Rand != NULL);
> > > > +
> > > > +  //
> > > > +  // A loop to fetch a 64 bit random value with
> a
> > > > retry count limit.
> > > > +  //
> > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> Index++)
> > > > {
> > > > +    if (AsmRdSeed64 (Rand)) {
> > > > +      return TRUE;
> > > > +    }
> > > > +  }
> > > > +
> > > > +  return FALSE;
> > > > +}
> > > > +
> > > > +/**
> > > > +  Generates a 128-bit random number.
> > > > +
> > > > +  if Rand is NULL, then ASSERT().
> > > > +
> > > > +  @param[out] Rand     Buffer pointer to store
> the
> > > > 128-bit random value.
> > > > +
> > > > +  @retval TRUE         Random number generated
> > > > successfully.
> > > > +  @retval FALSE        Failed to generate the
> random
> > > > number.
> > > > +
> > > > +**/
> > > > +BOOLEAN
> > > > +EFIAPI
> > > > +GetRandomNumber128 (
> > > > +  OUT     UINT64                    *Rand
> > > > +  )
> > > > +{
> > > > +  ASSERT (Rand != NULL);
> > > > +
> > > > +  //
> > > > +  // Read first 64 bits
> > > > +  //
> > > > +  if (!GetRandomNumber64 (Rand)) {
> > > > +    return FALSE;
> > > > +  }
> > > > +
> > > > +  //
> > > > +  // Read second 64 bits
> > > > +  //
> > > > +  return GetRandomNumber64 (++Rand); }
> > > > --
> > > > 2.17.1.windows.2
> > > >
> > > >
> > > >
> >
> >
> > 
> >

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

* Re: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
  2019-11-15 17:21         ` Michael D Kinney
@ 2019-11-15 17:35           ` Ard Biesheuvel
  2019-11-16  2:17             ` Wang, Jian J
  0 siblings, 1 reply; 36+ messages in thread
From: Ard Biesheuvel @ 2019-11-15 17:35 UTC (permalink / raw)
  To: Kinney, Michael D
  Cc: edk2-devel-groups-io, Wang, Jian J, Yao, Jiewen, Zhang, Chao B,
	Gao, Liming, Ni, Ray

On Fri, 15 Nov 2019 at 17:21, Kinney, Michael D
<michael.d.kinney@intel.com> wrote:
>
> Hi Ard,
>
> What would you recommend as way to provide these different
> types of services?  Some more new lib classes and instances?
>

Basically, yes.

RngLib could be backed by RDRAND, or by a fully generic DRBG
implementation which depends on EntropySourceLib.

EntropySourceLib could be backed by RDSEED, by another arch-specific
method, or [assuming we can prove it works] a generic jitter entropy
library.

BlockEncryptionIvLib could be implemented using a counter and a CRC
library, or backed by RngLib, depending on the execution context.


For DXE phase, I think it would actually make sense to have a single
driver consuming EntropySourceLib and implementing the DRBG, and then
expose that via a EDK2 specific protocol that is consumed by
DxeRngLib.

For the x86 implementation of EFI_RNG_PROTOCOL, which currently has
some dreadful code to harvest entropy from RDRAND, we could actually
instantiate in different ways (and expose varying subsets of the
GUIDed DRBG flavours) depending on whether it has a working RngLib
only, or has a working EntropySourceLib as well.






> > -----Original Message-----
> > From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Sent: Friday, November 15, 2019 5:29 AM
> > To: edk2-devel-groups-io <devel@edk2.groups.io>; Wang,
> > Jian J <jian.j.wang@intel.com>
> > Cc: Kinney, Michael D <michael.d.kinney@intel.com>;
> > Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> > <chao.b.zhang@intel.com>; Gao, Liming
> > <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>
> > Subject: Re: [edk2-devel] [PATCH 05/11]
> > SecurityPkg/RngLibRdSeed: add an instance of RngLib to
> > make use rdseed
> >
> > On Thu, 14 Nov 2019 at 04:39, Wang, Jian J
> > <jian.j.wang@intel.com> wrote:
> > >
> > > Mike,
> > >
> > > I figured that rdseed is only needed in cases
> > demanding highest
> > > entropy, like seeding other pseudo-RNG. It's not for
> > general purpose randomness.
> > > Then I put it in SecurityPkg. But I'm ok to put it
> > into MdePkg. I have
> > > no strong opinion for this.
> > >
> >
> > I think it is a bad idea to use the same library
> > abstraction [RngLib] for exposing
> > a) entropy sources used for seeding deterministic
> > random number generators
> > b) deterministic random number generators themselves
> > c) low entropy pseudo-RNGs based on timestamp counters,
> > etc
> >
> > given that the use cases don't usually overlap. I.e.,
> > only a DRBG implementation requires a), and exports
> > RngLib itself based on that.
> > Use cases that can tolerate c) [like IV generators for
> > block encryption] are typically disjoint from ones that
> > require b) [for key generation]. The idea that you can
> > use RngLib for all of them, and plug arbitrary
> > instantiations of it into each is misguided IMHO.
> >
> >
> >
> > > > -----Original Message-----
> > > > From: Kinney, Michael D
> > <michael.d.kinney@intel.com>
> > > > Sent: Thursday, November 14, 2019 12:25 PM
> > > > To: devel@edk2.groups.io; Wang, Jian J
> > <jian.j.wang@intel.com>;
> > > > Kinney, Michael D <michael.d.kinney@intel.com>
> > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao
> > B
> > > > <chao.b.zhang@intel.com>; Gao, Liming
> > <liming.gao@intel.com>; Ni,
> > > > Ray <ray.ni@intel.com>
> > > > Subject: RE: [edk2-devel] [PATCH 05/11]
> > SecurityPkg/RngLibRdSeed:
> > > > add an instance of RngLib to make use rdseed
> > > >
> > > > Jian,
> > > >
> > > > Why is this lib instance in the SecurityPkg?  It
> > only depends on the
> > > > MdePkg.  Can't non security feature related modules
> > that want to a
> > > > random number use this lib without using the
> > SecurityPkg?  Could
> > > > this lib instance be added to MdePkg?
> > > >
> > > > Thanks,
> > > >
> > > > Mike
> > > >
> > > > > -----Original Message-----
> > > > > From: devel@edk2.groups.io <devel@edk2.groups.io>
> > On Behalf Of
> > > > > Wang, Jian J
> > > > > Sent: Wednesday, November 13, 2019 6:18 PM
> > > > > To: devel@edk2.groups.io
> > > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang,
> > Chao B
> > > > > <chao.b.zhang@intel.com>; Kinney, Michael D
> > > > > <michael.d.kinney@intel.com>; Gao, Liming
> > <liming.gao@intel.com>;
> > > > > Ni, Ray <ray.ni@intel.com>
> > > > > Subject: [edk2-devel] [PATCH 05/11]
> > > > > SecurityPkg/RngLibRdSeed: add an instance of
> > RngLib to make use
> > > > > rdseed
> > > > >
> > > > > This version of RngLib makes use of AsmRdSeed to
> > get
> > > > > non-deterministic random number, which can be
> > used for seeding
> > > > > other software DRNG like rand interface in
> > openssl. It can be used
> > > > > only on IA32/X64 processors which supports rdseed
> > instruction.
> > > > >
> > > > > Ref:
> > > > >
> > https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > > Cc: Chao Zhang <chao.b.zhang@intel.com>
> > > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > > Cc: Liming Gao <liming.gao@intel.com>
> > > > > Cc: Ray Ni <ray.ni@intel.com>
> > > > > Signed-off-by: Jian J Wang
> > <jian.j.wang@intel.com>
> > > > > ---
> > > > >  .../RngLibRdSeed/RngLibRdSeed.inf             |
> > 37
> > > > > ++++
> > > > >  .../RngLibRdSeed/RngLibRdSeed.uni             |
> > 18 ++
> > > > >  .../RngLibRdSeed/RngRdSeed.c                  |
> > 189
> > > > > ++++++++++++++++++
> > > > >  3 files changed, 244 insertions(+)  create mode
> > 100644
> > > > >
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > > > > Seed.inf
> > > > >  create mode 100644
> > > > >
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > > > > Seed.uni
> > > > >  create mode 100644
> > > > >
> > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
> > > > > d.c
> > > > >
> > > > > diff --git
> > > > >
> > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.inf
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.inf
> > > > > new file mode 100644
> > > > > index 0000000000..8162408775
> > > > > --- /dev/null
> > > > > +++
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.inf
> > > > > @@ -0,0 +1,37 @@
> > > > > +## @file
> > > > > +#  Instance of RNG (Random Number Generator)
> > Library.
> > > > > +#
> > > > > +#  Rng RdSeed Library that uses CPU RdSeed
> > instruction
> > > > > access to
> > > > > +provide #  non-deterministic random number which
> > can
> > > > > be used as seed
> > > > > +for other #  software deterministic RNGs.
> > > > > +#
> > > > > +#  Copyright (c) 2019, Intel Corporation. All
> > rights
> > > > > reserved.<BR> # #
> > > > > +SPDX-License-Identifier: BSD-2-Clause-Patent # #
> > ##
> > > > > +
> > > > > +[Defines]
> > > > > +  INF_VERSION                    = 0x00010029
> > > > > +  BASE_NAME                      = RngLibRdSeed
> > > > > +  MODULE_UNI_FILE                =
> > RngLibRdSeed.uni
> > > > > +  FILE_GUID                      = 8B613B2E-
> > B944-40F9-
> > > > > B979-1B60D7CAA73C
> > > > > +  MODULE_TYPE                    = BASE
> > > > > +  VERSION_STRING                 = 1.0
> > > > > +  LIBRARY_CLASS                  = RngLib
> > > > > +  CONSTRUCTOR                    =
> > > > > RngLibRdSeedConstructor
> > > > > +
> > > > > +#
> > > > > +#  VALID_ARCHITECTURES           = IA32 X64
> > > > > +#
> > > > > +
> > > > > +[Sources.Ia32, Sources.X64]
> > > > > +  RngRdSeed.c
> > > > > +
> > > > > +[Packages]
> > > > > +  MdePkg/MdePkg.dec
> > > > > +
> > > > > +[LibraryClasses]
> > > > > +  BaseLib
> > > > > +  DebugLib
> > > > > diff --git
> > > > >
> > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.uni
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.uni
> > > > > new file mode 100644
> > > > > index 0000000000..051a3019bc
> > > > > --- /dev/null
> > > > > +++
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > RdSeed.uni
> > > > > @@ -0,0 +1,18 @@
> > > > > +// /** @file
> > > > > +// Instance of RNG (Random Number Generator)
> > Library.
> > > > > +//
> > > > > +// Rng RdSeed Library that uses CPU RdSeed
> > instruction
> > > > > access to
> > > > > +provide // non-deterministic random number which
> > can
> > > > > be used as seed
> > > > > +for other // software deterministic RNGs.
> > > > > +//
> > > > > +// Copyright (c) 2019, Intel Corporation. All
> > rights
> > > > > reserved.<BR> //
> > > > > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > // //
> > > > > **/
> > > > > +
> > > > > +
> > > > > +#string STR_MODULE_ABSTRACT
> > #language en-
> > > > > US "Instance of RNG Library"
> > > > > +
> > > > > +#string STR_MODULE_DESCRIPTION
> > #language en-
> > > > > US "RngRdSeed Library that uses CPU RdSeed
> > instruction access to
> > > > > provide non-deterministic random numbers."
> > > > > +
> > > > > diff --git
> > > > >
> > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > > eed.c
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > > eed.c
> > > > > new file mode 100644
> > > > > index 0000000000..0036faa050
> > > > > --- /dev/null
> > > > > +++
> > > > >
> > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > > eed.c
> > > > > @@ -0,0 +1,189 @@
> > > > > +/** @file
> > > > > +  Random number generator services that uses
> > RdSeed
> > > > > instruction access
> > > > > +  to provide non-deterministic random numbers,
> > which
> > > > > are usually used
> > > > > +  for seeding other pseudo-random number
> > generators.
> > > > > +
> > > > > +Copyright (c) 2019, 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>
> > > > > +
> > > > > +//
> > > > > +// Bit mask used to determine if RdSeed
> > instruction is
> > > > > supported.
> > > > > +//
> > > > > +#define RDSEED_MASK                  BIT18
> > > > > +
> > > > > +//
> > > > > +// Limited retry number when valid random data
> > is
> > > > > returned.
> > > > > +// It varies between 1 and 100 according to
> > "Intel(R)
> > > > > DRGN Software
> > > > > +Implementation // Guide". Let's use the same
> > value as
> > > > > RDRAND in BaseRngLib.
> > > > > +//
> > > > > +#define RDSEED_RETRY_LIMIT           10
> > > > > +
> > > > > +/**
> > > > > +  The constructor function checks whether or not
> > > > > RDSEED instruction is
> > > > > +supported
> > > > > +  by the host hardware.
> > > > > +
> > > > > +  The constructor function checks whether or not
> > > > > RDSEED instruction is supported.
> > > > > +  It will ASSERT() if RDSEED instruction is not
> > > > > supported.
> > > > > +
> > > > > +  @retval RETURN_SUCCESS      The processor
> > supports
> > > > > RDSEED instruction.
> > > > > +  @retval RETURN_UNSUPPORTED  RDSEED instruction
> > is
> > > > > not supported.
> > > > > +
> > > > > +**/
> > > > > +RETURN_STATUS
> > > > > +EFIAPI
> > > > > +RngLibRdSeedConstructor (
> > > > > +  VOID
> > > > > +  )
> > > > > +{
> > > > > +  UINT32  RegEbx;
> > > > > +
> > > > > +  //
> > > > > +  // Determine RDSEED support by examining bit
> > 18 of
> > > > > the EBX register
> > > > > + returned by  // CPUID(EAX=7, ECX=0). BIT18 of
> > EBX
> > > > > indicates that
> > > > > + processor support RDSEED  // instruction.
> > > > > +  //
> > > > > +  AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL);
> > if
> > > > > ((RegEbx &
> > > > > + RDSEED_MASK) != RDSEED_MASK) {
> > > > > +    ASSERT ((RegEbx & RDSEED_MASK) ==
> > RDSEED_MASK);
> > > > > +    return RETURN_UNSUPPORTED;
> > > > > +  }
> > > > > +
> > > > > +  return RETURN_SUCCESS;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > +  Generates a 16-bit random number.
> > > > > +
> > > > > +  if Rand is NULL, then ASSERT().
> > > > > +
> > > > > +  @param[out] Rand     Buffer pointer to store
> > the 16-
> > > > > bit random value.
> > > > > +
> > > > > +  @retval TRUE         Random number generated
> > > > > successfully.
> > > > > +  @retval FALSE        Failed to generate the
> > random
> > > > > number.
> > > > > +
> > > > > +**/
> > > > > +BOOLEAN
> > > > > +EFIAPI
> > > > > +GetRandomNumber16 (
> > > > > +  OUT     UINT16                    *Rand
> > > > > +  )
> > > > > +{
> > > > > +  UINT32  Index;
> > > > > +
> > > > > +  ASSERT (Rand != NULL);
> > > > > +
> > > > > +  //
> > > > > +  // A loop to fetch a 16 bit random value with
> > a
> > > > > retry count limit.
> > > > > +  //
> > > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> > Index++)
> > > > > {
> > > > > +    if (AsmRdSeed16 (Rand)) {
> > > > > +      return TRUE;
> > > > > +    }
> > > > > +  }
> > > > > +
> > > > > +  return FALSE;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > +  Generates a 32-bit random number.
> > > > > +
> > > > > +  if Rand is NULL, then ASSERT().
> > > > > +
> > > > > +  @param[out] Rand     Buffer pointer to store
> > the 32-
> > > > > bit random value.
> > > > > +
> > > > > +  @retval TRUE         Random number generated
> > > > > successfully.
> > > > > +  @retval FALSE        Failed to generate the
> > random
> > > > > number.
> > > > > +
> > > > > +**/
> > > > > +BOOLEAN
> > > > > +EFIAPI
> > > > > +GetRandomNumber32 (
> > > > > +  OUT     UINT32                    *Rand
> > > > > +  )
> > > > > +{
> > > > > +  UINT32  Index;
> > > > > +
> > > > > +  ASSERT (Rand != NULL);
> > > > > +
> > > > > +  //
> > > > > +  // A loop to fetch a 32 bit random value with
> > a
> > > > > retry count limit.
> > > > > +  //
> > > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> > Index++)
> > > > > {
> > > > > +    if (AsmRdSeed32 (Rand)) {
> > > > > +      return TRUE;
> > > > > +    }
> > > > > +  }
> > > > > +
> > > > > +  return FALSE;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > +  Generates a 64-bit random number.
> > > > > +
> > > > > +  if Rand is NULL, then ASSERT().
> > > > > +
> > > > > +  @param[out] Rand     Buffer pointer to store
> > the 64-
> > > > > bit random value.
> > > > > +
> > > > > +  @retval TRUE         Random number generated
> > > > > successfully.
> > > > > +  @retval FALSE        Failed to generate the
> > random
> > > > > number.
> > > > > +
> > > > > +**/
> > > > > +BOOLEAN
> > > > > +EFIAPI
> > > > > +GetRandomNumber64 (
> > > > > +  OUT     UINT64                    *Rand
> > > > > +  )
> > > > > +{
> > > > > +  UINT32  Index;
> > > > > +
> > > > > +  ASSERT (Rand != NULL);
> > > > > +
> > > > > +  //
> > > > > +  // A loop to fetch a 64 bit random value with
> > a
> > > > > retry count limit.
> > > > > +  //
> > > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> > Index++)
> > > > > {
> > > > > +    if (AsmRdSeed64 (Rand)) {
> > > > > +      return TRUE;
> > > > > +    }
> > > > > +  }
> > > > > +
> > > > > +  return FALSE;
> > > > > +}
> > > > > +
> > > > > +/**
> > > > > +  Generates a 128-bit random number.
> > > > > +
> > > > > +  if Rand is NULL, then ASSERT().
> > > > > +
> > > > > +  @param[out] Rand     Buffer pointer to store
> > the
> > > > > 128-bit random value.
> > > > > +
> > > > > +  @retval TRUE         Random number generated
> > > > > successfully.
> > > > > +  @retval FALSE        Failed to generate the
> > random
> > > > > number.
> > > > > +
> > > > > +**/
> > > > > +BOOLEAN
> > > > > +EFIAPI
> > > > > +GetRandomNumber128 (
> > > > > +  OUT     UINT64                    *Rand
> > > > > +  )
> > > > > +{
> > > > > +  ASSERT (Rand != NULL);
> > > > > +
> > > > > +  //
> > > > > +  // Read first 64 bits
> > > > > +  //
> > > > > +  if (!GetRandomNumber64 (Rand)) {
> > > > > +    return FALSE;
> > > > > +  }
> > > > > +
> > > > > +  //
> > > > > +  // Read second 64 bits
> > > > > +  //
> > > > > +  return GetRandomNumber64 (++Rand); }
> > > > > --
> > > > > 2.17.1.windows.2
> > > > >
> > > > >
> > > > >
> > >
> > >
> > > 
> > >

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

* Re: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
  2019-11-15 13:28       ` Ard Biesheuvel
  2019-11-15 17:21         ` Michael D Kinney
@ 2019-11-15 22:19         ` Laszlo Ersek
  1 sibling, 0 replies; 36+ messages in thread
From: Laszlo Ersek @ 2019-11-15 22:19 UTC (permalink / raw)
  To: devel, ard.biesheuvel, Jian J Wang
  Cc: Kinney, Michael D, Yao, Jiewen, Zhang, Chao B, Gao, Liming,
	Ni, Ray

On 11/15/19 14:28, Ard Biesheuvel wrote:
> On Thu, 14 Nov 2019 at 04:39, Wang, Jian J <jian.j.wang@intel.com> wrote:
>>
>> Mike,
>>
>> I figured that rdseed is only needed in cases demanding highest entropy,
>> like seeding other pseudo-RNG. It's not for general purpose randomness.
>> Then I put it in SecurityPkg. But I'm ok to put it into MdePkg. I have no
>> strong opinion for this.
>>
> 
> I think it is a bad idea to use the same library abstraction [RngLib]
> for exposing
> a) entropy sources used for seeding deterministic random number generators
> b) deterministic random number generators themselves
> c) low entropy pseudo-RNGs based on timestamp counters, etc
> 
> given that the use cases don't usually overlap. I.e., only a DRBG
> implementation requires a), and exports RngLib itself based on that.
> Use cases that can tolerate c) [like IV generators for block
> encryption] are typically disjoint from ones that require b) [for key
> generation]. The idea that you can use RngLib for all of them, and
> plug arbitrary instantiations of it into each is misguided IMHO.

Thank you for this awesome explanation!
Laszlo


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

* Re: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed
  2019-11-15 17:35           ` Ard Biesheuvel
@ 2019-11-16  2:17             ` Wang, Jian J
  0 siblings, 0 replies; 36+ messages in thread
From: Wang, Jian J @ 2019-11-16  2:17 UTC (permalink / raw)
  To: devel@edk2.groups.io, ard.biesheuvel@linaro.org,
	Kinney, Michael D
  Cc: Yao, Jiewen, Zhang, Chao B, Gao, Liming, Ni, Ray

Ard,

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Ard
> Biesheuvel
> Sent: Saturday, November 16, 2019 1:35 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>
> Cc: edk2-devel-groups-io <devel@edk2.groups.io>; Wang, Jian J
> <jian.j.wang@intel.com>; Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> <chao.b.zhang@intel.com>; Gao, Liming <liming.gao@intel.com>; Ni, Ray
> <ray.ni@intel.com>
> Subject: Re: [edk2-devel] [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an
> instance of RngLib to make use rdseed
> 
> On Fri, 15 Nov 2019 at 17:21, Kinney, Michael D
> <michael.d.kinney@intel.com> wrote:
> >
> > Hi Ard,
> >
> > What would you recommend as way to provide these different
> > types of services?  Some more new lib classes and instances?
> >
> 
> Basically, yes.
> 
> RngLib could be backed by RDRAND, or by a fully generic DRBG
> implementation which depends on EntropySourceLib.
> 

I'm ok to introduce a EntropySourceLib. But that means OpenssLib needs
to depend on this one instead of RngLib (or both), right? 

> EntropySourceLib could be backed by RDSEED, by another arch-specific
> method, or [assuming we can prove it works] a generic jitter entropy
> library.
> 
> BlockEncryptionIvLib could be implemented using a counter and a CRC
> library, or backed by RngLib, depending on the execution context.
> 
> 
> For DXE phase, I think it would actually make sense to have a single
> driver consuming EntropySourceLib and implementing the DRBG, and then
> expose that via a EDK2 specific protocol that is consumed by
> DxeRngLib.
> 
> For the x86 implementation of EFI_RNG_PROTOCOL, which currently has
> some dreadful code to harvest entropy from RDRAND, we could actually
> instantiate in different ways (and expose varying subsets of the
> GUIDed DRBG flavours) depending on whether it has a working RngLib
> only, or has a working EntropySourceLib as well.
> 

I think those code is used to do re-seeding of RDRAND, which is required
by "Intel(r)64 and IA-32 architectures software developer's manual". For
processors which don't support RDSEED, this way can get better random
entropy than RDRAND. If the processor internal re-seeding procedure is
the same as RDSEED, the result should be equivalent to those got from
RDSEED directly, but less efficient, I guess.

If we introduce EntropySourceLib, for IA32/X64 arch, I think we can have
two version of instances of it: one backed by RDSEED, and one backed
by RDRAND re-seeding procedure.

For arch neutral libraries, as Laszlo mentioned in another patch email,
what's your suggestion? One implemented with removed code from
rand_pool_xxx.c or one implemented in cpu jitter way?

Thanks,
Jian
> 
> 
> 
> > > -----Original Message-----
> > > From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > > Sent: Friday, November 15, 2019 5:29 AM
> > > To: edk2-devel-groups-io <devel@edk2.groups.io>; Wang,
> > > Jian J <jian.j.wang@intel.com>
> > > Cc: Kinney, Michael D <michael.d.kinney@intel.com>;
> > > Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao B
> > > <chao.b.zhang@intel.com>; Gao, Liming
> > > <liming.gao@intel.com>; Ni, Ray <ray.ni@intel.com>
> > > Subject: Re: [edk2-devel] [PATCH 05/11]
> > > SecurityPkg/RngLibRdSeed: add an instance of RngLib to
> > > make use rdseed
> > >
> > > On Thu, 14 Nov 2019 at 04:39, Wang, Jian J
> > > <jian.j.wang@intel.com> wrote:
> > > >
> > > > Mike,
> > > >
> > > > I figured that rdseed is only needed in cases
> > > demanding highest
> > > > entropy, like seeding other pseudo-RNG. It's not for
> > > general purpose randomness.
> > > > Then I put it in SecurityPkg. But I'm ok to put it
> > > into MdePkg. I have
> > > > no strong opinion for this.
> > > >
> > >
> > > I think it is a bad idea to use the same library
> > > abstraction [RngLib] for exposing
> > > a) entropy sources used for seeding deterministic
> > > random number generators
> > > b) deterministic random number generators themselves
> > > c) low entropy pseudo-RNGs based on timestamp counters,
> > > etc
> > >
> > > given that the use cases don't usually overlap. I.e.,
> > > only a DRBG implementation requires a), and exports
> > > RngLib itself based on that.
> > > Use cases that can tolerate c) [like IV generators for
> > > block encryption] are typically disjoint from ones that
> > > require b) [for key generation]. The idea that you can
> > > use RngLib for all of them, and plug arbitrary
> > > instantiations of it into each is misguided IMHO.
> > >
> > >
> > >
> > > > > -----Original Message-----
> > > > > From: Kinney, Michael D
> > > <michael.d.kinney@intel.com>
> > > > > Sent: Thursday, November 14, 2019 12:25 PM
> > > > > To: devel@edk2.groups.io; Wang, Jian J
> > > <jian.j.wang@intel.com>;
> > > > > Kinney, Michael D <michael.d.kinney@intel.com>
> > > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang, Chao
> > > B
> > > > > <chao.b.zhang@intel.com>; Gao, Liming
> > > <liming.gao@intel.com>; Ni,
> > > > > Ray <ray.ni@intel.com>
> > > > > Subject: RE: [edk2-devel] [PATCH 05/11]
> > > SecurityPkg/RngLibRdSeed:
> > > > > add an instance of RngLib to make use rdseed
> > > > >
> > > > > Jian,
> > > > >
> > > > > Why is this lib instance in the SecurityPkg?  It
> > > only depends on the
> > > > > MdePkg.  Can't non security feature related modules
> > > that want to a
> > > > > random number use this lib without using the
> > > SecurityPkg?  Could
> > > > > this lib instance be added to MdePkg?
> > > > >
> > > > > Thanks,
> > > > >
> > > > > Mike
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: devel@edk2.groups.io <devel@edk2.groups.io>
> > > On Behalf Of
> > > > > > Wang, Jian J
> > > > > > Sent: Wednesday, November 13, 2019 6:18 PM
> > > > > > To: devel@edk2.groups.io
> > > > > > Cc: Yao, Jiewen <jiewen.yao@intel.com>; Zhang,
> > > Chao B
> > > > > > <chao.b.zhang@intel.com>; Kinney, Michael D
> > > > > > <michael.d.kinney@intel.com>; Gao, Liming
> > > <liming.gao@intel.com>;
> > > > > > Ni, Ray <ray.ni@intel.com>
> > > > > > Subject: [edk2-devel] [PATCH 05/11]
> > > > > > SecurityPkg/RngLibRdSeed: add an instance of
> > > RngLib to make use
> > > > > > rdseed
> > > > > >
> > > > > > This version of RngLib makes use of AsmRdSeed to
> > > get
> > > > > > non-deterministic random number, which can be
> > > used for seeding
> > > > > > other software DRNG like rand interface in
> > > openssl. It can be used
> > > > > > only on IA32/X64 processors which supports rdseed
> > > instruction.
> > > > > >
> > > > > > Ref:
> > > > > >
> > > https://bugzilla.tianocore.org/show_bug.cgi?id=1871
> > > > > > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > > > > > Cc: Chao Zhang <chao.b.zhang@intel.com>
> > > > > > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > > > > > Cc: Liming Gao <liming.gao@intel.com>
> > > > > > Cc: Ray Ni <ray.ni@intel.com>
> > > > > > Signed-off-by: Jian J Wang
> > > <jian.j.wang@intel.com>
> > > > > > ---
> > > > > >  .../RngLibRdSeed/RngLibRdSeed.inf             |
> > > 37
> > > > > > ++++
> > > > > >  .../RngLibRdSeed/RngLibRdSeed.uni             |
> > > 18 ++
> > > > > >  .../RngLibRdSeed/RngRdSeed.c                  |
> > > 189
> > > > > > ++++++++++++++++++
> > > > > >  3 files changed, 244 insertions(+)  create mode
> > > 100644
> > > > > >
> > > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > > > > > Seed.inf
> > > > > >  create mode 100644
> > > > > >
> > > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLibRd
> > > > > > Seed.uni
> > > > > >  create mode 100644
> > > > > >
> > > SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdSee
> > > > > > d.c
> > > > > >
> > > > > > diff --git
> > > > > >
> > > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > > RdSeed.inf
> > > > > >
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > > RdSeed.inf
> > > > > > new file mode 100644
> > > > > > index 0000000000..8162408775
> > > > > > --- /dev/null
> > > > > > +++
> > > > > >
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > > RdSeed.inf
> > > > > > @@ -0,0 +1,37 @@
> > > > > > +## @file
> > > > > > +#  Instance of RNG (Random Number Generator)
> > > Library.
> > > > > > +#
> > > > > > +#  Rng RdSeed Library that uses CPU RdSeed
> > > instruction
> > > > > > access to
> > > > > > +provide #  non-deterministic random number which
> > > can
> > > > > > be used as seed
> > > > > > +for other #  software deterministic RNGs.
> > > > > > +#
> > > > > > +#  Copyright (c) 2019, Intel Corporation. All
> > > rights
> > > > > > reserved.<BR> # #
> > > > > > +SPDX-License-Identifier: BSD-2-Clause-Patent # #
> > > ##
> > > > > > +
> > > > > > +[Defines]
> > > > > > +  INF_VERSION                    = 0x00010029
> > > > > > +  BASE_NAME                      = RngLibRdSeed
> > > > > > +  MODULE_UNI_FILE                =
> > > RngLibRdSeed.uni
> > > > > > +  FILE_GUID                      = 8B613B2E-
> > > B944-40F9-
> > > > > > B979-1B60D7CAA73C
> > > > > > +  MODULE_TYPE                    = BASE
> > > > > > +  VERSION_STRING                 = 1.0
> > > > > > +  LIBRARY_CLASS                  = RngLib
> > > > > > +  CONSTRUCTOR                    =
> > > > > > RngLibRdSeedConstructor
> > > > > > +
> > > > > > +#
> > > > > > +#  VALID_ARCHITECTURES           = IA32 X64
> > > > > > +#
> > > > > > +
> > > > > > +[Sources.Ia32, Sources.X64]
> > > > > > +  RngRdSeed.c
> > > > > > +
> > > > > > +[Packages]
> > > > > > +  MdePkg/MdePkg.dec
> > > > > > +
> > > > > > +[LibraryClasses]
> > > > > > +  BaseLib
> > > > > > +  DebugLib
> > > > > > diff --git
> > > > > >
> > > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > > RdSeed.uni
> > > > > >
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > > RdSeed.uni
> > > > > > new file mode 100644
> > > > > > index 0000000000..051a3019bc
> > > > > > --- /dev/null
> > > > > > +++
> > > > > >
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngLib
> > > > > > RdSeed.uni
> > > > > > @@ -0,0 +1,18 @@
> > > > > > +// /** @file
> > > > > > +// Instance of RNG (Random Number Generator)
> > > Library.
> > > > > > +//
> > > > > > +// Rng RdSeed Library that uses CPU RdSeed
> > > instruction
> > > > > > access to
> > > > > > +provide // non-deterministic random number which
> > > can
> > > > > > be used as seed
> > > > > > +for other // software deterministic RNGs.
> > > > > > +//
> > > > > > +// Copyright (c) 2019, Intel Corporation. All
> > > rights
> > > > > > reserved.<BR> //
> > > > > > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > > // //
> > > > > > **/
> > > > > > +
> > > > > > +
> > > > > > +#string STR_MODULE_ABSTRACT
> > > #language en-
> > > > > > US "Instance of RNG Library"
> > > > > > +
> > > > > > +#string STR_MODULE_DESCRIPTION
> > > #language en-
> > > > > > US "RngRdSeed Library that uses CPU RdSeed
> > > instruction access to
> > > > > > provide non-deterministic random numbers."
> > > > > > +
> > > > > > diff --git
> > > > > >
> > > a/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > > > eed.c
> > > > > >
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > > > eed.c
> > > > > > new file mode 100644
> > > > > > index 0000000000..0036faa050
> > > > > > --- /dev/null
> > > > > > +++
> > > > > >
> > > b/SecurityPkg/RandomNumberGenerator/RngLibRdSeed/RngRdS
> > > > > > eed.c
> > > > > > @@ -0,0 +1,189 @@
> > > > > > +/** @file
> > > > > > +  Random number generator services that uses
> > > RdSeed
> > > > > > instruction access
> > > > > > +  to provide non-deterministic random numbers,
> > > which
> > > > > > are usually used
> > > > > > +  for seeding other pseudo-random number
> > > generators.
> > > > > > +
> > > > > > +Copyright (c) 2019, 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>
> > > > > > +
> > > > > > +//
> > > > > > +// Bit mask used to determine if RdSeed
> > > instruction is
> > > > > > supported.
> > > > > > +//
> > > > > > +#define RDSEED_MASK                  BIT18
> > > > > > +
> > > > > > +//
> > > > > > +// Limited retry number when valid random data
> > > is
> > > > > > returned.
> > > > > > +// It varies between 1 and 100 according to
> > > "Intel(R)
> > > > > > DRGN Software
> > > > > > +Implementation // Guide". Let's use the same
> > > value as
> > > > > > RDRAND in BaseRngLib.
> > > > > > +//
> > > > > > +#define RDSEED_RETRY_LIMIT           10
> > > > > > +
> > > > > > +/**
> > > > > > +  The constructor function checks whether or not
> > > > > > RDSEED instruction is
> > > > > > +supported
> > > > > > +  by the host hardware.
> > > > > > +
> > > > > > +  The constructor function checks whether or not
> > > > > > RDSEED instruction is supported.
> > > > > > +  It will ASSERT() if RDSEED instruction is not
> > > > > > supported.
> > > > > > +
> > > > > > +  @retval RETURN_SUCCESS      The processor
> > > supports
> > > > > > RDSEED instruction.
> > > > > > +  @retval RETURN_UNSUPPORTED  RDSEED instruction
> > > is
> > > > > > not supported.
> > > > > > +
> > > > > > +**/
> > > > > > +RETURN_STATUS
> > > > > > +EFIAPI
> > > > > > +RngLibRdSeedConstructor (
> > > > > > +  VOID
> > > > > > +  )
> > > > > > +{
> > > > > > +  UINT32  RegEbx;
> > > > > > +
> > > > > > +  //
> > > > > > +  // Determine RDSEED support by examining bit
> > > 18 of
> > > > > > the EBX register
> > > > > > + returned by  // CPUID(EAX=7, ECX=0). BIT18 of
> > > EBX
> > > > > > indicates that
> > > > > > + processor support RDSEED  // instruction.
> > > > > > +  //
> > > > > > +  AsmCpuidEx (7, 0, NULL, &RegEbx, NULL, NULL);
> > > if
> > > > > > ((RegEbx &
> > > > > > + RDSEED_MASK) != RDSEED_MASK) {
> > > > > > +    ASSERT ((RegEbx & RDSEED_MASK) ==
> > > RDSEED_MASK);
> > > > > > +    return RETURN_UNSUPPORTED;
> > > > > > +  }
> > > > > > +
> > > > > > +  return RETURN_SUCCESS;
> > > > > > +}
> > > > > > +
> > > > > > +/**
> > > > > > +  Generates a 16-bit random number.
> > > > > > +
> > > > > > +  if Rand is NULL, then ASSERT().
> > > > > > +
> > > > > > +  @param[out] Rand     Buffer pointer to store
> > > the 16-
> > > > > > bit random value.
> > > > > > +
> > > > > > +  @retval TRUE         Random number generated
> > > > > > successfully.
> > > > > > +  @retval FALSE        Failed to generate the
> > > random
> > > > > > number.
> > > > > > +
> > > > > > +**/
> > > > > > +BOOLEAN
> > > > > > +EFIAPI
> > > > > > +GetRandomNumber16 (
> > > > > > +  OUT     UINT16                    *Rand
> > > > > > +  )
> > > > > > +{
> > > > > > +  UINT32  Index;
> > > > > > +
> > > > > > +  ASSERT (Rand != NULL);
> > > > > > +
> > > > > > +  //
> > > > > > +  // A loop to fetch a 16 bit random value with
> > > a
> > > > > > retry count limit.
> > > > > > +  //
> > > > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> > > Index++)
> > > > > > {
> > > > > > +    if (AsmRdSeed16 (Rand)) {
> > > > > > +      return TRUE;
> > > > > > +    }
> > > > > > +  }
> > > > > > +
> > > > > > +  return FALSE;
> > > > > > +}
> > > > > > +
> > > > > > +/**
> > > > > > +  Generates a 32-bit random number.
> > > > > > +
> > > > > > +  if Rand is NULL, then ASSERT().
> > > > > > +
> > > > > > +  @param[out] Rand     Buffer pointer to store
> > > the 32-
> > > > > > bit random value.
> > > > > > +
> > > > > > +  @retval TRUE         Random number generated
> > > > > > successfully.
> > > > > > +  @retval FALSE        Failed to generate the
> > > random
> > > > > > number.
> > > > > > +
> > > > > > +**/
> > > > > > +BOOLEAN
> > > > > > +EFIAPI
> > > > > > +GetRandomNumber32 (
> > > > > > +  OUT     UINT32                    *Rand
> > > > > > +  )
> > > > > > +{
> > > > > > +  UINT32  Index;
> > > > > > +
> > > > > > +  ASSERT (Rand != NULL);
> > > > > > +
> > > > > > +  //
> > > > > > +  // A loop to fetch a 32 bit random value with
> > > a
> > > > > > retry count limit.
> > > > > > +  //
> > > > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> > > Index++)
> > > > > > {
> > > > > > +    if (AsmRdSeed32 (Rand)) {
> > > > > > +      return TRUE;
> > > > > > +    }
> > > > > > +  }
> > > > > > +
> > > > > > +  return FALSE;
> > > > > > +}
> > > > > > +
> > > > > > +/**
> > > > > > +  Generates a 64-bit random number.
> > > > > > +
> > > > > > +  if Rand is NULL, then ASSERT().
> > > > > > +
> > > > > > +  @param[out] Rand     Buffer pointer to store
> > > the 64-
> > > > > > bit random value.
> > > > > > +
> > > > > > +  @retval TRUE         Random number generated
> > > > > > successfully.
> > > > > > +  @retval FALSE        Failed to generate the
> > > random
> > > > > > number.
> > > > > > +
> > > > > > +**/
> > > > > > +BOOLEAN
> > > > > > +EFIAPI
> > > > > > +GetRandomNumber64 (
> > > > > > +  OUT     UINT64                    *Rand
> > > > > > +  )
> > > > > > +{
> > > > > > +  UINT32  Index;
> > > > > > +
> > > > > > +  ASSERT (Rand != NULL);
> > > > > > +
> > > > > > +  //
> > > > > > +  // A loop to fetch a 64 bit random value with
> > > a
> > > > > > retry count limit.
> > > > > > +  //
> > > > > > +  for (Index = 0; Index < RDSEED_RETRY_LIMIT;
> > > Index++)
> > > > > > {
> > > > > > +    if (AsmRdSeed64 (Rand)) {
> > > > > > +      return TRUE;
> > > > > > +    }
> > > > > > +  }
> > > > > > +
> > > > > > +  return FALSE;
> > > > > > +}
> > > > > > +
> > > > > > +/**
> > > > > > +  Generates a 128-bit random number.
> > > > > > +
> > > > > > +  if Rand is NULL, then ASSERT().
> > > > > > +
> > > > > > +  @param[out] Rand     Buffer pointer to store
> > > the
> > > > > > 128-bit random value.
> > > > > > +
> > > > > > +  @retval TRUE         Random number generated
> > > > > > successfully.
> > > > > > +  @retval FALSE        Failed to generate the
> > > random
> > > > > > number.
> > > > > > +
> > > > > > +**/
> > > > > > +BOOLEAN
> > > > > > +EFIAPI
> > > > > > +GetRandomNumber128 (
> > > > > > +  OUT     UINT64                    *Rand
> > > > > > +  )
> > > > > > +{
> > > > > > +  ASSERT (Rand != NULL);
> > > > > > +
> > > > > > +  //
> > > > > > +  // Read first 64 bits
> > > > > > +  //
> > > > > > +  if (!GetRandomNumber64 (Rand)) {
> > > > > > +    return FALSE;
> > > > > > +  }
> > > > > > +
> > > > > > +  //
> > > > > > +  // Read second 64 bits
> > > > > > +  //
> > > > > > +  return GetRandomNumber64 (++Rand); }
> > > > > > --
> > > > > > 2.17.1.windows.2
> > > > > >
> > > > > >
> > > > > >
> > > >
> > > >
> > > >
> > > >
> 
> 


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

end of thread, other threads:[~2019-11-16  2:17 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-11-14  2:17 [PATCH 00/11] Use proper entropy sources Wang, Jian J
2019-11-14  2:17 ` [PATCH 01/11] NetworkPkg/NetworkPkg.dsc: specify RngLib instance for build Wang, Jian J
2019-11-14  2:17 ` [PATCH 02/11] SignedCapsulePkg/SignedCapsulePkg.dsc: specify RngLib instances Wang, Jian J
2019-11-14  2:17 ` [PATCH 03/11] FmpDevicePkg/FmpDevicePkg.dsc: specify RngLib instances in dsc files Wang, Jian J
2019-11-14  2:17 ` [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction Wang, Jian J
2019-11-14  4:17   ` [edk2-devel] " Michael D Kinney
2019-11-14  4:40     ` Wang, Jian J
2019-11-14  2:17 ` [PATCH 05/11] SecurityPkg/RngLibRdSeed: add an instance of RngLib to make use rdseed Wang, Jian J
2019-11-14  4:24   ` [edk2-devel] " Michael D Kinney
2019-11-14  4:38     ` Wang, Jian J
2019-11-15 13:28       ` Ard Biesheuvel
2019-11-15 17:21         ` Michael D Kinney
2019-11-15 17:35           ` Ard Biesheuvel
2019-11-16  2:17             ` Wang, Jian J
2019-11-15 22:19         ` Laszlo Ersek
2019-11-14  2:17 ` [PATCH 06/11] SecurityPkg/DxeRngLibRngProtocol: add RNG protocol version of RngLib Wang, Jian J
2019-11-14 11:15   ` [edk2-devel] " Laszlo Ersek
2019-11-14 14:52     ` Wang, Jian J
2019-11-14  2:17 ` [PATCH 07/11] SecurityPkg/SecurityPkg.dsc: add new RngLib instances for build Wang, Jian J
2019-11-14  2:17 ` [PATCH 08/11] OvmfPkg: specify RngLib instances in dsc files Wang, Jian J
2019-11-14 11:07   ` [edk2-devel] " Laszlo Ersek
2019-11-14 14:40     ` Wang, Jian J
2019-11-14 14:51       ` Laszlo Ersek
2019-11-14 14:55         ` Wang, Jian J
2019-11-14  2:17 ` [PATCH 09/11] ArmVirtPkg/ArmVirt.dsc.inc: " Wang, Jian J
2019-11-14  7:41   ` [edk2-devel] " Ard Biesheuvel
2019-11-14  8:03     ` Wang, Jian J
2019-11-14  8:14       ` Ard Biesheuvel
2019-11-14  8:31         ` Wang, Jian J
2019-11-14 10:36   ` Laszlo Ersek
2019-11-14 14:26     ` Wang, Jian J
2019-11-14  2:17 ` [PATCH 10/11] CryptoPkg/OpensslLib: use RngLib to get high quality random entropy Wang, Jian J
2019-11-14  7:42   ` Ard Biesheuvel
2019-11-14  2:17 ` [PATCH 11/11] FmpDevicePkg/FmpDevicePkg.dsc: remove TimerLib instance Wang, Jian J
2019-11-14  4:21 ` [edk2-devel] [PATCH 00/11] Use proper entropy sources Michael D Kinney
2019-11-14  5:15   ` Wang, Jian J

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