]>
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 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/RngLib.h>
21 Calls RDRAND to fill a buffer of arbitrary size with random bytes.
23 @param[in] Length Size of the buffer, in bytes, to fill with.
24 @param[out] RandBuffer Pointer to the buffer to store the random result.
26 @retval EFI_SUCCESS Random bytes generation succeeded.
27 @retval EFI_NOT_READY Failed to request random bytes.
41 IsRandom
= GetRandomNumber128 (TempRand
);
45 if (Length
>= sizeof (TempRand
)) {
46 WriteUnaligned64 ((UINT64
*)RandBuffer
, TempRand
[0]);
47 RandBuffer
+= sizeof (UINT64
);
48 WriteUnaligned64 ((UINT64
*)RandBuffer
, TempRand
[1]);
49 RandBuffer
+= sizeof (UINT64
);
50 Length
-= sizeof (TempRand
);
52 CopyMem (RandBuffer
, TempRand
, Length
);
61 Creates a 128bit random value that is fully forward and backward prediction resistant,
62 suitable for seeding a NIST SP800-90 Compliant, FIPS 1402-2 certifiable SW DRBG.
63 This function takes multiple random numbers through RDRAND without intervening
64 delays to ensure reseeding and performs AES-CBC-MAC over the data to compute the
67 @param[out] SeedBuffer Pointer to a 128bit buffer to store the random seed.
69 @retval EFI_SUCCESS Random seed generation succeeded.
70 @retval EFI_NOT_READY Failed to request random bytes.
88 // Chose an arbitary key and zero the feed_forward_value (FFV)
90 for (Index
= 0; Index
< 16; Index
++) {
91 Key
[Index
] = (UINT8
) Index
;
96 // Perform CBC_MAC over 32 * 128 bit values, with 10us gaps between 128 bit value
97 // The 10us gaps will ensure multiple reseeds within the HW RNG with a large design margin.
99 for (Index
= 0; Index
< 32; Index
++) {
100 MicroSecondDelay (10);
101 Status
= RdRandGetBytes (16, RandByte
);
102 if (EFI_ERROR (Status
)) {
107 // Perform XOR operations on two 128-bit value.
109 for (Index2
= 0; Index2
< 16; Index2
++) {
110 Xored
[Index2
] = RandByte
[Index2
] ^ Ffv
[Index2
];
113 AesEncrypt (Key
, Xored
, Ffv
);
116 for (Index
= 0; Index
< 16; Index
++) {
117 SeedBuffer
[Index
] = Ffv
[Index
];
124 Generate high-quality entropy source through RDRAND.
126 @param[in] Length Size of the buffer, in bytes, to fill with.
127 @param[out] Entropy Pointer to the buffer to store the entropy data.
129 @retval EFI_SUCCESS Entropy generation succeeded.
130 @retval EFI_NOT_READY Failed to request random data.
135 RdRandGenerateEntropy (
145 Status
= EFI_NOT_READY
;
146 BlockCount
= Length
/ 16;
147 Ptr
= (UINT8
*)Entropy
;
150 // Generate high-quality seed for DRBG Entropy
152 while (BlockCount
> 0) {
153 Status
= RdRandGetSeed128 (Seed
);
154 if (EFI_ERROR (Status
)) {
157 CopyMem (Ptr
, Seed
, 16);
164 // Populate the remained data as request.
166 Status
= RdRandGetSeed128 (Seed
);
167 if (EFI_ERROR (Status
)) {
170 CopyMem (Ptr
, Seed
, (Length
% 16));