summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQin Long <qin.long@intel.com>2015-09-21 05:53:52 +0000
committerqlong <qlong@Edk2>2015-09-21 05:53:52 +0000
commit3cfc7813bb7e904c4a940d638facc10be5e22645 (patch)
tree714169431ab0af3ca0faecb44e0faa212b2ffff4
parent82f3edf26a7f60e50b0133cdc5ec689d2b7f502e (diff)
downloadedk2-3cfc7813bb7e904c4a940d638facc10be5e22645.zip
edk2-3cfc7813bb7e904c4a940d638facc10be5e22645.tar.gz
edk2-3cfc7813bb7e904c4a940d638facc10be5e22645.tar.bz2
MdePkg: Add CPU RdRand access APIs for random number generation
Add AsmRdRand16/32/64 APIs for RdRand instruction access to generate high-quality random number. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Qin Long <qin.long@intel.com> Reviewed-by: Michael Kinney <michael.d.kinney@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18518 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--MdePkg/Include/Library/BaseLib.h51
-rw-r--r--MdePkg/Library/BaseLib/BaseLib.inf6
-rw-r--r--MdePkg/Library/BaseLib/Ia32/RdRand.S80
-rw-r--r--MdePkg/Library/BaseLib/Ia32/RdRand.asm94
-rw-r--r--MdePkg/Library/BaseLib/X64/RdRand.S72
-rw-r--r--MdePkg/Library/BaseLib/X64/RdRand.asm83
6 files changed, 386 insertions, 0 deletions
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 7e10804..c41fa78 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -7647,6 +7647,57 @@ AsmPrepareAndThunk16 (
IN OUT THUNK_CONTEXT *ThunkContext
);
+/**
+ Generates a 16-bit random number through RDRAND instruction.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+ **/
+BOOLEAN
+EFIAPI
+AsmRdRand16 (
+ OUT UINT16 *Rand
+ );
+
+/**
+ Generates a 32-bit random number through RDRAND instruction.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdRand32 (
+ OUT UINT32 *Rand
+ );
+
+/**
+ Generates a 64-bit random number through RDRAND instruction.
+
+ if Rand is NULL, then ASSERT().
+
+ @param[out] Rand Buffer pointer to store the random result.
+
+ @retval TRUE RDRAND call was successful.
+ @retval FALSE Failed attempts to call RDRAND.
+
+**/
+BOOLEAN
+EFIAPI
+AsmRdRand64 (
+ OUT UINT64 *Rand
+ );
+
#endif
#endif
diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf
index 4a37e60..4cc86d7 100644
--- a/MdePkg/Library/BaseLib/BaseLib.inf
+++ b/MdePkg/Library/BaseLib/BaseLib.inf
@@ -159,6 +159,7 @@
Ia32/EnablePaging64.asm | MSFT
Ia32/EnableCache.c | MSFT
Ia32/DisableCache.c | MSFT
+ Ia32/RdRand.asm | MSFT
Ia32/Wbinvd.asm | INTEL
Ia32/WriteMm7.asm | INTEL
@@ -252,6 +253,7 @@
Ia32/EnablePaging64.asm | INTEL
Ia32/EnableCache.asm | INTEL
Ia32/DisableCache.asm | INTEL
+ Ia32/RdRand.asm | INTEL
Ia32/GccInline.c | GCC
Ia32/Thunk16.nasm | GCC
@@ -279,6 +281,7 @@
Ia32/LShiftU64.S | GCC
Ia32/EnableCache.S | GCC
Ia32/DisableCache.S | GCC
+ Ia32/RdRand.S | GCC
Ia32/DivS64x64Remainder.c
Ia32/InternalSwitchStack.c | MSFT
@@ -383,10 +386,12 @@
X64/CpuBreakpoint.c | MSFT
X64/WriteMsr64.c | MSFT
X64/ReadMsr64.c | MSFT
+ X64/RdRand.asm | MSFT
X64/CpuBreakpoint.asm | INTEL
X64/WriteMsr64.asm | INTEL
X64/ReadMsr64.asm | INTEL
+ X64/RdRand.asm | INTEL
X64/Non-existing.c
Math64.c
@@ -417,6 +422,7 @@
X64/CpuIdEx.S | GCC
X64/EnableCache.S | GCC
X64/DisableCache.S | GCC
+ X64/RdRand.S | GCC
ChkStkGcc.c | GCC
[Sources.IPF]
diff --git a/MdePkg/Library/BaseLib/Ia32/RdRand.S b/MdePkg/Library/BaseLib/Ia32/RdRand.S
new file mode 100644
index 0000000..503f65a
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ia32/RdRand.S
@@ -0,0 +1,80 @@
+#------------------------------------------------------------------------------ ;
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# RdRand.S
+#
+# Abstract:
+#
+# Generates random number through CPU RdRand instruction under 32-bit platform.
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Generates a 16 bit random number through RDRAND instruction.
+// Return TRUE if Rand generated successfully, or FALSE if not.
+//
+// BOOLEAN EFIAPI AsmRdRand16 (UINT16 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand16)
+ASM_PFX(AsmRdRand16):
+ .byte 0x0f, 0xc7, 0xf0 // rdrand r16: "0f c7 /6 ModRM:r/m(w)"
+ jc rn16_ok // jmp if CF=1
+ xor %eax, %eax // reg=0 if CF=0
+ ret // return with failure status
+rn16_ok:
+ mov 0x4(%esp), %edx
+ mov %ax, (%edx)
+ mov $0x1, %eax
+ ret
+
+//------------------------------------------------------------------------------
+// Generates a 32 bit random number through RDRAND instruction.
+// Return TRUE if Rand generated successfully, or FALSE if not.
+//
+// BOOLEAN EFIAPI AsmRdRand32 (UINT32 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand32)
+ASM_PFX(AsmRdRand32):
+ .byte 0x0f, 0xc7, 0xf0 // rdrand r32: "0f c7 /6 ModRM:r/m(w)"
+ jc rn32_ok // jmp if CF=1
+ xor %eax, %eax // reg=0 if CF=0
+ ret // return with failure status
+rn32_ok:
+ mov 0x4(%esp), %edx
+ mov %eax, (%edx)
+ mov $0x1, %eax
+ ret
+
+//------------------------------------------------------------------------------
+// Generates a 64 bit random number through RDRAND instruction.
+// Return TRUE if Rand generated successfully, or FALSE if not.
+//
+// BOOLEAN EFIAPI AsmRdRand64 (UINT64 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand64)
+ASM_PFX(AsmRdRand64):
+ .byte 0x0f, 0xc7, 0xf0 // rdrand r32: "0f c7 /6 ModRM:r/m(w)"
+ jnc rn64_ret // jmp if CF=0
+ mov 0x4(%esp), %edx
+ mov %eax, (%edx)
+
+ .byte 0x0f, 0xc7, 0xf0 // generate another 32 bit RN
+ jnc rn64_ret // jmp if CF=0
+ mov %eax, 0x4(%edx)
+
+ mov $0x1, %eax
+ ret
+rn64_ret:
+ xor %eax, %eax
+ ret // return with failure status
diff --git a/MdePkg/Library/BaseLib/Ia32/RdRand.asm b/MdePkg/Library/BaseLib/Ia32/RdRand.asm
new file mode 100644
index 0000000..21349b0
--- /dev/null
+++ b/MdePkg/Library/BaseLib/Ia32/RdRand.asm
@@ -0,0 +1,94 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+;
+; RdRand.asm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction under 32-bit platform.
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+.686P
+.model flat, C
+
+.code
+
+;------------------------------------------------------------------------------
+; Generates a 16 bit random number through RDRAND instruction.
+; Return TRUE if Rand generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI AsmRdRand16 (UINT16 *Rand);
+;------------------------------------------------------------------------------
+AsmRdRand16 PROC
+ ; rdrand ax ; generate a 16 bit RN into ax
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0fh, 0c7h, 0f0h ; rdrand r16: "0f c7 /6 ModRM:r/m(w)"
+ jc rn16_ok ; jmp if CF=1
+ xor eax, eax ; reg=0 if CF=0
+ ret ; return with failure status
+rn16_ok:
+ mov edx, dword ptr [esp + 4]
+ mov [edx], ax
+ mov eax, 1
+ ret
+AsmRdRand16 ENDP
+
+;------------------------------------------------------------------------------
+; Generates a 32 bit random number through RDRAND instruction.
+; Return TRUE if Rand generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI AsmRdRand32 (UINT32 *Rand);
+;------------------------------------------------------------------------------
+AsmRdRand32 PROC
+ ; rdrand eax ; generate a 32 bit RN into eax
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0fh, 0c7h, 0f0h ; rdrand r32: "0f c7 /6 ModRM:r/m(w)"
+ jc rn32_ok ; jmp if CF=1
+ xor eax, eax ; reg=0 if CF=0
+ ret ; return with failure status
+rn32_ok:
+ mov edx, dword ptr [esp + 4]
+ mov [edx], eax
+ mov eax, 1
+ ret
+AsmRdRand32 ENDP
+
+;------------------------------------------------------------------------------
+; Generates a 64 bit random number through RDRAND instruction.
+; Return TRUE if Rand generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI AsmRdRand64 (UINT64 *Rand);
+;------------------------------------------------------------------------------
+AsmRdRand64 PROC
+ ; rdrand eax ; generate a 32 bit RN into eax
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0fh, 0c7h, 0f0h ; rdrand r32: "0f c7 /6 ModRM:r/m(w)"
+ jnc rn64_ret ; jmp if CF=0
+ mov edx, dword ptr [esp + 4]
+ mov [edx], eax
+
+ db 0fh, 0c7h, 0f0h ; 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
+ ret ; return with failure status
+AsmRdRand64 ENDP
+
+ END
diff --git a/MdePkg/Library/BaseLib/X64/RdRand.S b/MdePkg/Library/BaseLib/X64/RdRand.S
new file mode 100644
index 0000000..49b50e6
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/RdRand.S
@@ -0,0 +1,72 @@
+#------------------------------------------------------------------------------ ;
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# RdRand.S
+#
+# Abstract:
+#
+# Generates random number through CPU RdRand instruction under 64-bit platform.
+#
+# Notes:
+#
+#------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Generates a 16 bit random number through RDRAND instruction.
+// Return TRUE if Rand generated successfully, or FALSE if not.
+//
+// BOOLEAN EFIAPI AsmRdRand16 (UINT16 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand16)
+ASM_PFX(AsmRdRand16):
+ .byte 0x0f, 0xc7, 0xf0 // rdrand r16: "0f c7 /6 ModRM:r/m(w)"
+ jc rn16_ok // jmp if CF=1
+ xor %rax, %rax // reg=0 if CF=0
+ ret // return with failure status
+rn16_ok:
+ mov %ax, (%rcx)
+ mov $0x1, %rax
+ ret
+
+//------------------------------------------------------------------------------
+// Generates a 32 bit random number through RDRAND instruction.
+// Return TRUE if Rand generated successfully, or FALSE if not.
+//
+// BOOLEAN EFIAPI AsmRdRand32 (UINT32 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand32)
+ASM_PFX(AsmRdRand32):
+ .byte 0x0f, 0xc7, 0xf0 // rdrand r32: "0f c7 /6 ModRM:r/m(w)"
+ jc rn32_ok // jmp if CF=1
+ xor %rax, %rax // reg=0 if CF=0
+ ret // return with failure status
+rn32_ok:
+ mov %eax, (%rcx)
+ mov $0x1, %rax
+ ret
+
+//------------------------------------------------------------------------------
+// Generates a 64 bit random number through RDRAND instruction.
+// Return TRUE if Rand generated successfully, or FALSE if not.
+//
+// BOOLEAN EFIAPI AsmRdRand64 (UINT64 *Rand);
+//------------------------------------------------------------------------------
+ASM_GLOBAL ASM_PFX(AsmRdRand64)
+ASM_PFX(AsmRdRand64):
+ .byte 0x48, 0x0f, 0xc7, 0xf0 // rdrand r64: "REX.W + 0f c7 /6 ModRM:r/m(w)"
+ jc rn64_ok // jmp if CF=1
+ xor %rax, %rax // reg=0 if CF=0
+ ret // return with failure status
+rn64_ok:
+ mov %rax, (%rcx)
+ mov $0x1, %rax
+ ret
diff --git a/MdePkg/Library/BaseLib/X64/RdRand.asm b/MdePkg/Library/BaseLib/X64/RdRand.asm
new file mode 100644
index 0000000..370cdb6
--- /dev/null
+++ b/MdePkg/Library/BaseLib/X64/RdRand.asm
@@ -0,0 +1,83 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+;
+; RdRand.asm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction under 64-bit platform.
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+ .code
+
+;------------------------------------------------------------------------------
+; Generates a 16 bit random number through RDRAND instruction.
+; Return TRUE if Rand generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI AsmRdRand16 (UINT16 *Rand);
+;------------------------------------------------------------------------------
+AsmRdRand16 PROC
+ ; rdrand ax ; generate a 16 bit RN into eax,
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0fh, 0c7h, 0f0h ; rdrand r16: "0f c7 /6 ModRM:r/m(w)"
+ jc rn16_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ ret ; return with failure status
+rn16_ok:
+ mov [rcx], ax
+ mov rax, 1
+ ret
+AsmRdRand16 ENDP
+
+;------------------------------------------------------------------------------
+; Generates a 32 bit random number through RDRAND instruction.
+; Return TRUE if Rand generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI AsmRdRand32 (UINT32 *Rand);
+;------------------------------------------------------------------------------
+AsmRdRand32 PROC
+ ; rdrand eax ; generate a 32 bit RN into eax,
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 0fh, 0c7h, 0f0h ; rdrand r32: "0f c7 /6 ModRM:r/m(w)"
+ jc rn32_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ ret ; return with failure status
+rn32_ok:
+ mov [rcx], eax
+ mov rax, 1
+ ret
+AsmRdRand32 ENDP
+
+;------------------------------------------------------------------------------
+; Generates a 64 bit random number through one RDRAND instruction.
+; Return TRUE if Rand generated successfully, or FALSE if not.
+;
+; BOOLEAN EFIAPI AsmRdRand64 (UINT64 *Random);
+;------------------------------------------------------------------------------
+AsmRdRand64 PROC
+ ; rdrand rax ; generate a 64 bit RN into rax,
+ ; CF=1 if RN generated ok, otherwise CF=0
+ db 048h, 0fh, 0c7h, 0f0h ; rdrand r64: "REX.W + 0f c7 /6 ModRM:r/m(w)"
+ jc rn64_ok ; jmp if CF=1
+ xor rax, rax ; reg=0 if CF=0
+ ret ; return with failure status
+rn64_ok:
+ mov [rcx], rax
+ mov rax, 1
+ ret
+AsmRdRand64 ENDP
+
+ END