public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Wang, Jian J" <jian.j.wang@intel.com>
To: devel@edk2.groups.io
Cc: Michael D Kinney <michael.d.kinney@intel.com>,
	Liming Gao <liming.gao@intel.com>, Ray Ni <ray.ni@intel.com>
Subject: [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction
Date: Thu, 14 Nov 2019 10:17:36 +0800	[thread overview]
Message-ID: <20191114021743.3876-5-jian.j.wang@intel.com> (raw)
In-Reply-To: <20191114021743.3876-1-jian.j.wang@intel.com>

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


  parent reply	other threads:[~2019-11-14  2:17 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` Wang, Jian J [this message]
2019-11-14  4:17   ` [edk2-devel] [PATCH 04/11] MdePkg/BaseLib: add interface to wrap rdseed IA instruction 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191114021743.3876-5-jian.j.wang@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox