]>
git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/RandomNumberGenerator/RngDxe/RdRand.c
2 Support routines for RDRAND instruction access.
4 Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <Library/RngLib.h>
15 Calls RDRAND to fill a buffer of arbitrary size with random bytes.
17 @param[in] Length Size of the buffer, in bytes, to fill with.
18 @param[out] RandBuffer Pointer to the buffer to store the random result.
20 @retval EFI_SUCCESS Random bytes generation succeeded.
21 @retval EFI_NOT_READY Failed to request random bytes.
35 IsRandom
= GetRandomNumber128 (TempRand
);
39 if (Length
>= sizeof (TempRand
)) {
40 WriteUnaligned64 ((UINT64
*)RandBuffer
, TempRand
[0]);
41 RandBuffer
+= sizeof (UINT64
);
42 WriteUnaligned64 ((UINT64
*)RandBuffer
, TempRand
[1]);
43 RandBuffer
+= sizeof (UINT64
);
44 Length
-= sizeof (TempRand
);
46 CopyMem (RandBuffer
, TempRand
, Length
);
55 Creates a 128bit random value that is fully forward and backward prediction resistant,
56 suitable for seeding a NIST SP800-90 Compliant, FIPS 1402-2 certifiable SW DRBG.
57 This function takes multiple random numbers through RDRAND without intervening
58 delays to ensure reseeding and performs AES-CBC-MAC over the data to compute the
61 @param[out] SeedBuffer Pointer to a 128bit buffer to store the random seed.
63 @retval EFI_SUCCESS Random seed generation succeeded.
64 @retval EFI_NOT_READY Failed to request random bytes.
82 // Chose an arbitary key and zero the feed_forward_value (FFV)
84 for (Index
= 0; Index
< 16; Index
++) {
85 Key
[Index
] = (UINT8
) Index
;
90 // Perform CBC_MAC over 32 * 128 bit values, with 10us gaps between 128 bit value
91 // The 10us gaps will ensure multiple reseeds within the HW RNG with a large design margin.
93 for (Index
= 0; Index
< 32; Index
++) {
94 MicroSecondDelay (10);
95 Status
= RdRandGetBytes (16, RandByte
);
96 if (EFI_ERROR (Status
)) {
101 // Perform XOR operations on two 128-bit value.
103 for (Index2
= 0; Index2
< 16; Index2
++) {
104 Xored
[Index2
] = RandByte
[Index2
] ^ Ffv
[Index2
];
107 AesEncrypt (Key
, Xored
, Ffv
);
110 for (Index
= 0; Index
< 16; Index
++) {
111 SeedBuffer
[Index
] = Ffv
[Index
];
118 Generate high-quality entropy source through RDRAND.
120 @param[in] Length Size of the buffer, in bytes, to fill with.
121 @param[out] Entropy Pointer to the buffer to store the entropy data.
123 @retval EFI_SUCCESS Entropy generation succeeded.
124 @retval EFI_NOT_READY Failed to request random data.
129 RdRandGenerateEntropy (
139 Status
= EFI_NOT_READY
;
140 BlockCount
= Length
/ 16;
141 Ptr
= (UINT8
*)Entropy
;
144 // Generate high-quality seed for DRBG Entropy
146 while (BlockCount
> 0) {
147 Status
= RdRandGetSeed128 (Seed
);
148 if (EFI_ERROR (Status
)) {
151 CopyMem (Ptr
, Seed
, 16);
158 // Populate the remained data as request.
160 Status
= RdRandGetSeed128 (Seed
);
161 if (EFI_ERROR (Status
)) {
164 CopyMem (Ptr
, Seed
, (Length
% 16));