1;------------------------------------------------------------------------------
2;
3; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
4; This program and the accompanying materials
5; are licensed and made available under the terms and conditions of the BSD License
6; which accompanies this distribution.  The full text of the license may be found at
7; http://opensource.org/licenses/bsd-license.php.
8;
9; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11;
12; Module Name:
13;
14;   RdRand.asm
15;
16; Abstract:
17;
18;   Generates random number through CPU RdRand instruction under 32-bit platform.
19;
20; Notes:
21;
22;------------------------------------------------------------------------------
23
24.686P
25.model flat, C
26
27.code
28
29;------------------------------------------------------------------------------
30;  Generates a 16 bit random number through RDRAND instruction.
31;  Return TRUE if Rand generated successfully, or FALSE if not.
32;
33;  BOOLEAN EFIAPI InternalX86RdRand16 (UINT16 *Rand);
34;------------------------------------------------------------------------------
35InternalX86RdRand16  PROC
36    ; rdrand   ax                  ; generate a 16 bit RN into ax
37                                   ; CF=1 if RN generated ok, otherwise CF=0
38    db     0fh, 0c7h, 0f0h         ; rdrand r16: "0f c7 /6  ModRM:r/m(w)"
39    jc     rn16_ok                 ; jmp if CF=1
40    xor    eax, eax                ; reg=0 if CF=0
41    ret                            ; return with failure status
42rn16_ok:
43    mov    edx, dword ptr [esp + 4]
44    mov    [edx], ax
45    mov    eax,  1
46    ret
47InternalX86RdRand16 ENDP
48
49;------------------------------------------------------------------------------
50;  Generates a 32 bit random number through RDRAND instruction.
51;  Return TRUE if Rand generated successfully, or FALSE if not.
52;
53;  BOOLEAN EFIAPI InternalX86RdRand32 (UINT32 *Rand);
54;------------------------------------------------------------------------------
55InternalX86RdRand32  PROC
56    ; rdrand   eax                 ; generate a 32 bit RN into eax
57                                   ; CF=1 if RN generated ok, otherwise CF=0
58    db     0fh, 0c7h, 0f0h         ; rdrand r32: "0f c7 /6  ModRM:r/m(w)"
59    jc     rn32_ok                 ; jmp if CF=1
60    xor    eax, eax                ; reg=0 if CF=0
61    ret                            ; return with failure status
62rn32_ok:
63    mov    edx, dword ptr [esp + 4]
64    mov    [edx], eax
65    mov    eax,  1
66    ret
67InternalX86RdRand32 ENDP
68
69;------------------------------------------------------------------------------
70;  Generates a 64 bit random number through RDRAND instruction.
71;  Return TRUE if Rand generated successfully, or FALSE if not.
72;
73;  BOOLEAN EFIAPI InternalX86RdRand64 (UINT64 *Rand);
74;------------------------------------------------------------------------------
75InternalX86RdRand64  PROC
76    ; rdrand   eax                 ; generate a 32 bit RN into eax
77                                   ; CF=1 if RN generated ok, otherwise CF=0
78    db     0fh, 0c7h, 0f0h         ; rdrand r32: "0f c7 /6  ModRM:r/m(w)"
79    jnc    rn64_ret                ; jmp if CF=0
80    mov    edx, dword ptr [esp + 4]
81    mov    [edx], eax
82
83    db     0fh, 0c7h, 0f0h         ; generate another 32 bit RN
84    jnc    rn64_ret                ; jmp if CF=0
85    mov    [edx + 4], eax
86
87    mov    eax,  1
88    ret
89rn64_ret:
90    xor    eax, eax
91    ret                            ; return with failure status
92InternalX86RdRand64 ENDP
93
94    END
95