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
This commit is contained in:
Qin Long 2015-09-21 05:53:52 +00:00 committed by qlong
parent 82f3edf26a
commit 3cfc7813bb
6 changed files with 386 additions and 0 deletions

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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