]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/RandomNumberGenerator/RngDxe/IA32/RdRandWord.c
Add UEFI RNG Protocol support. The driver will leverage Intel Secure Key technology...
[mirror_edk2.git] / SecurityPkg / RandomNumberGenerator / RngDxe / IA32 / RdRandWord.c
1 /** @file
2 RDRAND Support Routines.
3
4 Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "RdRand.h"
16
17 /**
18 Generates a 64-bit random number through RDRAND instruction.
19
20 @param[out] Rand Buffer pointer to store the random result.
21
22 @retval TRUE RDRAND call was successful.
23 @retval FALSE Failed attempts to call RDRAND.
24
25 **/
26 BOOLEAN
27 EFIAPI
28 RdRand64Step (
29 OUT UINT64 *Rand
30 )
31 {
32 UINT32 RandLow;
33 UINT32 RandHigh;
34
35 //
36 // Generating a 64-bit rand on a 32-bit system by
37 // mapping two 32-bit RDRAND instructions.
38 //
39 if (!RdRand32Step (&RandLow)) {
40 return FALSE;
41 }
42 if (!RdRand32Step (&RandHigh)) {
43 return FALSE;
44 }
45
46 *Rand = (UINT64) RandLow | LShiftU64 ((UINT64)RandHigh, 32);
47
48 return TRUE;
49 }
50
51 /**
52 Calls RDRAND to request a word-length random number.
53
54 @param[out] Rand Buffer pointer to store the random number.
55 @param[in] NeedRetry Determine whether or not to loop retry.
56
57 @retval EFI_SUCCESS Random word generation succeeded.
58 @retval EFI_NOT_READY Failed to request random word.
59
60 **/
61 EFI_STATUS
62 EFIAPI
63 RdRandWord (
64 OUT UINTN *Rand,
65 IN BOOLEAN NeedRetry
66 )
67 {
68 return RdRand32 (Rand, NeedRetry);
69 }
70
71 /**
72 Calls RDRAND to request multiple word-length random numbers.
73
74 @param[in] Length Size of the buffer, in words, to fill with.
75 @param[out] RandBuffer Pointer to the buffer to store the random result.
76
77 @retval EFI_SUCCESS Random words generation succeeded.
78 @retval EFI_NOT_READY Failed to request random words.
79
80 **/
81 EFI_STATUS
82 EFIAPI
83 RdRandGetWords (
84 IN UINTN Length,
85 OUT UINTN *RandBuffer
86 )
87 {
88 EFI_STATUS Status;
89 UINT32 Index;
90
91 for (Index = 0; Index < Length; Index++) {
92 //
93 // Obtain one word-length (32-bit) Random Number with possible retry-loop.
94 //
95 Status = RdRand32 (RandBuffer, TRUE);
96 if (EFI_ERROR (Status)) {
97 return Status;
98 }
99
100 RandBuffer++;
101 }
102
103 return EFI_SUCCESS;
104 }