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
next prev 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