diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index a429fb1f37..c0a9e9fc3c 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -162,6 +162,7 @@ Ia32/EnablePaging64.asm | MSFT Ia32/EnableCache.c | MSFT Ia32/DisableCache.c | MSFT + Ia32/RdRand.nasm| MSFT Ia32/RdRand.asm | MSFT Ia32/Wbinvd.asm | INTEL @@ -259,6 +260,7 @@ Ia32/EnablePaging64.asm | INTEL Ia32/EnableCache.asm | INTEL Ia32/DisableCache.asm | INTEL + Ia32/RdRand.nasm| INTEL Ia32/RdRand.asm | INTEL Ia32/GccInline.c | GCC @@ -290,6 +292,7 @@ Ia32/LShiftU64.S | GCC Ia32/EnableCache.S | GCC Ia32/DisableCache.S | GCC + Ia32/RdRand.nasm| GCC Ia32/RdRand.S | GCC Ia32/DivS64x64Remainder.c diff --git a/MdePkg/Library/BaseLib/Ia32/RdRand.nasm b/MdePkg/Library/BaseLib/Ia32/RdRand.nasm new file mode 100644 index 0000000000..1365dfcdbb --- /dev/null +++ b/MdePkg/Library/BaseLib/Ia32/RdRand.nasm @@ -0,0 +1,90 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2015, Intel Corporation. All rights reserved.
+; 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.nasm +; +; Abstract: +; +; Generates random number through CPU RdRand instruction under 32-bit platform. +; +; Notes: +; +;------------------------------------------------------------------------------ + +SECTION .text + +;------------------------------------------------------------------------------ +; Generates a 16 bit random number through RDRAND instruction. +; Return TRUE if Rand generated successfully, or FALSE if not. +; +; BOOLEAN EFIAPI AsmRdRand16 (UINT16 *Rand); +;------------------------------------------------------------------------------ +global ASM_PFX(AsmRdRand16) +ASM_PFX(AsmRdRand16): + ; rdrand ax ; generate a 16 bit RN into ax + ; CF=1 if RN generated ok, otherwise CF=0 + db 0xf, 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 edx, dword [esp + 4] + mov [edx], ax + mov eax, 1 + 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); +;------------------------------------------------------------------------------ +global ASM_PFX(AsmRdRand32) +ASM_PFX(AsmRdRand32): + ; rdrand eax ; generate a 32 bit RN into eax + ; CF=1 if RN generated ok, otherwise CF=0 + db 0xf, 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 edx, dword [esp + 4] + mov [edx], eax + mov eax, 1 + 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); +;------------------------------------------------------------------------------ +global ASM_PFX(AsmRdRand64) +ASM_PFX(AsmRdRand64): + ; rdrand eax ; generate a 32 bit RN into eax + ; CF=1 if RN generated ok, otherwise CF=0 + db 0xf, 0xc7, 0xf0 ; rdrand r32: "0f c7 /6 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 + ret ; return with failure status +