1 /** @file 2 UEFI RNG (Random Number Generator) Protocol test application. 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 <Uefi.h> 16 #include <Library/UefiLib.h> 17 #include <Library/UefiApplicationEntryPoint.h> 18 #include <Library/UefiBootServicesTableLib.h> 19 #include <Library/MemoryAllocationLib.h> 20 #include <Library/DebugLib.h> 21 #include <Protocol/Rng.h> 22 23 /** 24 The user Entry Point for Application. The user code starts with this function 25 as the real entry point for the application. 26 27 @param[in] ImageHandle The firmware allocated handle for the EFI image. 28 @param[in] SystemTable A pointer to the EFI System Table. 29 30 @retval EFI_SUCCESS The entry point is executed successfully. 31 @retval other Some error occurs when executing this entry point. 32 33 **/ 34 EFI_STATUS 35 EFIAPI 36 UefiMain ( 37 IN EFI_HANDLE ImageHandle, 38 IN EFI_SYSTEM_TABLE *SystemTable 39 ) 40 { 41 EFI_STATUS Status; 42 EFI_RNG_PROTOCOL *Rng; 43 UINTN RngAlgListSize; 44 EFI_RNG_ALGORITHM RngAlgList[10]; 45 EFI_RNG_ALGORITHM *PtrRngAlg; 46 UINTN RngAlgCount; 47 UINT8 *Rand; 48 UINTN RandSize; 49 UINTN Index; 50 UINTN Index2; 51 52 Status = EFI_SUCCESS; 53 PtrRngAlg = NULL; 54 Rand = NULL; 55 56 Print (L"UEFI RNG Protocol Testing :\n"); 57 Print (L"----------------------------\n"); 58 59 //----------------------------------------- 60 // Basic UEFI RNG Protocol Test 61 //----------------------------------------- 62 Print (L" -- Locate UEFI RNG Protocol : "); 63 Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&Rng); 64 if (EFI_ERROR (Status)) { 65 Print (L"[Fail - Status = %r]\n", Status); 66 goto Exit; 67 } else { 68 Print (L"[Pass]\n"); 69 } 70 71 //----------------------------------------- 72 // Rng->GetInfo() interface test. 73 //----------------------------------------- 74 75 Print (L" -- Call RNG->GetInfo() interface : "); 76 RngAlgListSize = 0; 77 Status = Rng->GetInfo (Rng, &RngAlgListSize, NULL); 78 if (Status != EFI_BUFFER_TOO_SMALL) { 79 Print (L"[Fail - Status = %r]\n", Status); 80 } 81 // 82 // Print out the supported RNG algorithm GUIDs 83 // 84 RngAlgCount = RngAlgListSize / sizeof (EFI_RNG_ALGORITHM); 85 Print (L"\n >> Supported RNG Algorithm (Count = %d) : ", RngAlgCount); 86 Status = Rng->GetInfo (Rng, &RngAlgListSize, RngAlgList); 87 for (Index = 0; Index < RngAlgCount; Index++) { 88 PtrRngAlg = (EFI_RNG_ALGORITHM *)(&RngAlgList[Index]); 89 Print (L"\n %d) ", Index); 90 Print (L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", PtrRngAlg->Data1, 91 PtrRngAlg->Data2, PtrRngAlg->Data3, PtrRngAlg->Data4[0], PtrRngAlg->Data4[1], 92 PtrRngAlg->Data4[2], PtrRngAlg->Data4[3], PtrRngAlg->Data4[4], 93 PtrRngAlg->Data4[5], PtrRngAlg->Data4[6], PtrRngAlg->Data4[7]); 94 } 95 96 //----------------------------------------- 97 // Rng->GetRNG() interface test. 98 //----------------------------------------- 99 Print (L"\n -- Call RNG->GetRNG() interface : "); 100 101 // 102 // Allocate one buffer to store random data. 103 // 104 RandSize = 32; 105 Rand = AllocatePool (RandSize); 106 if (Rand == NULL) { 107 goto Exit; 108 } 109 110 // 111 // RNG with default algorithm 112 // 113 Print (L"\n >> RNG with default algorithm : "); 114 Status = Rng->GetRNG (Rng, NULL, RandSize, Rand); 115 if (EFI_ERROR (Status)) { 116 Print (L"[Fail - Status = %r]", Status); 117 } else { 118 Print (L"[Pass]"); 119 } 120 121 // 122 // RNG with SP800-90-HMAC-256 123 // 124 Print (L"\n >> RNG with SP800-90-HMAC-256 : "); 125 Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmSp80090Hmac256Guid, RandSize, Rand); 126 if (EFI_ERROR (Status)) { 127 Print (L"[Fail - Status = %r]", Status); 128 } else { 129 Print (L"[Pass]"); 130 } 131 132 // 133 // RNG with SP800-90-HASH-256 134 // 135 Print (L"\n >> RNG with SP800-90-Hash-256 : "); 136 Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmSp80090Hash256Guid, RandSize, Rand); 137 if (EFI_ERROR (Status)) { 138 Print (L"[Fail - Status = %r]", Status); 139 } else { 140 Print (L"[Pass]"); 141 } 142 143 // 144 // RNG with SP800-90-CTR-256 145 // 146 Print (L"\n >> RNG with SP800-90-CTR-256 : "); 147 Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmSp80090Ctr256Guid, RandSize, Rand); 148 if (EFI_ERROR (Status)) { 149 Print (L"[Fail - Status = %r]", Status); 150 } else { 151 Print (L"[Pass]"); 152 } 153 154 // 155 // RNG with X9.31-3DES 156 // 157 Print (L"\n >> RNG with X9.31-3DES : "); 158 Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmX9313DesGuid, RandSize, Rand); 159 if (EFI_ERROR (Status)) { 160 Print (L"[Fail - Status = %r]", Status); 161 } else { 162 Print (L"[Pass]"); 163 } 164 165 // 166 // RNG with X9.31-AES 167 // 168 Print (L"\n >> RNG with X9.31-AES : "); 169 Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmX931AesGuid, RandSize, Rand); 170 if (EFI_ERROR (Status)) { 171 Print (L"[Fail - Status = %r]", Status); 172 } else { 173 Print (L"[Pass]"); 174 } 175 176 // 177 // RNG with RAW Entropy 178 // 179 Print (L"\n >> RNG with RAW Entropy : "); 180 Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmRaw, RandSize, Rand); 181 if (EFI_ERROR (Status)) { 182 Print (L"[Fail - Status = %r]", Status); 183 } else { 184 Print (L"[Pass]"); 185 } 186 187 //----------------------------------------- 188 // Random Number Generator test. 189 //----------------------------------------- 190 Print (L"\n -- Random Number Generation Test with default RNG Algorithm (20 Rounds): "); 191 192 RandSize = 1; 193 for (Index = 0; Index < 20; Index++) { 194 Status = Rng->GetRNG (Rng, NULL, RandSize, Rand); 195 if (EFI_ERROR (Status)) { 196 Print (L"[Fail - Status = %r]", Status); 197 break; 198 } else { 199 Print (L"\n %02d) - ", Index + 1); 200 for (Index2 = 0; Index2 < RandSize; Index2++) { 201 Print (L"%02x", Rand[Index2]); 202 } 203 } 204 205 RandSize +=1; 206 } 207 208 //----------------------------------------- 209 // Random Number Generator test. 210 //----------------------------------------- 211 Print (L"\n -- RAW Entropy Generation Test (20 Rounds) : "); 212 213 RandSize = 32; 214 for (Index = 0; Index < 20; Index++) { 215 Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmRaw, RandSize, Rand); 216 if (EFI_ERROR (Status)) { 217 Print (L"[Fail - Status = %r]", Status); 218 break; 219 } else { 220 Print (L"\n %02d) - ", Index + 1); 221 for (Index2 = 0; Index2 < RandSize; Index2++) { 222 Print (L"%02x", Rand[Index2]); 223 } 224 } 225 } 226 227 Print (L"\n -- Exit UEFI RNG Protocol Test (Status = %r).\n", Status); 228 229 Exit: 230 if (Rand != NULL) { 231 FreePool (Rand); 232 } 233 return Status; 234 } 235