/** @file | |
UEFI RNG (Random Number Generator) Protocol test application. | |
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR> | |
This program and the accompanying materials | |
are licensed and made available under the terms and conditions of the BSD License | |
which accompanies this distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
**/ | |
#include <Uefi.h> | |
#include <Library/UefiLib.h> | |
#include <Library/UefiApplicationEntryPoint.h> | |
#include <Library/UefiBootServicesTableLib.h> | |
#include <Library/MemoryAllocationLib.h> | |
#include <Library/DebugLib.h> | |
#include <Protocol/Rng.h> | |
/** | |
The user Entry Point for Application. The user code starts with this function | |
as the real entry point for the application. | |
@param[in] ImageHandle The firmware allocated handle for the EFI image. | |
@param[in] SystemTable A pointer to the EFI System Table. | |
@retval EFI_SUCCESS The entry point is executed successfully. | |
@retval other Some error occurs when executing this entry point. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
UefiMain ( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE *SystemTable | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_RNG_PROTOCOL *Rng; | |
UINTN RngAlgListSize; | |
EFI_RNG_ALGORITHM RngAlgList[10]; | |
EFI_RNG_ALGORITHM *PtrRngAlg; | |
UINTN RngAlgCount; | |
UINT8 *Rand; | |
UINTN RandSize; | |
UINTN Index; | |
UINTN Index2; | |
Status = EFI_SUCCESS; | |
PtrRngAlg = NULL; | |
Rand = NULL; | |
Print (L"UEFI RNG Protocol Testing :\n"); | |
Print (L"----------------------------\n"); | |
//----------------------------------------- | |
// Basic UEFI RNG Protocol Test | |
//----------------------------------------- | |
Print (L" -- Locate UEFI RNG Protocol : "); | |
Status = gBS->LocateProtocol (&gEfiRngProtocolGuid, NULL, (VOID **)&Rng); | |
if (EFI_ERROR (Status)) { | |
Print (L"[Fail - Status = %r]\n", Status); | |
goto Exit; | |
} else { | |
Print (L"[Pass]\n"); | |
} | |
//----------------------------------------- | |
// Rng->GetInfo() interface test. | |
//----------------------------------------- | |
Print (L" -- Call RNG->GetInfo() interface : "); | |
RngAlgListSize = 0; | |
Status = Rng->GetInfo (Rng, &RngAlgListSize, NULL); | |
if (Status != EFI_BUFFER_TOO_SMALL) { | |
Print (L"[Fail - Status = %r]\n", Status); | |
} | |
// | |
// Print out the supported RNG algorithm GUIDs | |
// | |
RngAlgCount = RngAlgListSize / sizeof (EFI_RNG_ALGORITHM); | |
Print (L"\n >> Supported RNG Algorithm (Count = %d) : ", RngAlgCount); | |
Status = Rng->GetInfo (Rng, &RngAlgListSize, RngAlgList); | |
for (Index = 0; Index < RngAlgCount; Index++) { | |
PtrRngAlg = (EFI_RNG_ALGORITHM *)(&RngAlgList[Index]); | |
Print (L"\n %d) ", Index); | |
Print (L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", PtrRngAlg->Data1, | |
PtrRngAlg->Data2, PtrRngAlg->Data3, PtrRngAlg->Data4[0], PtrRngAlg->Data4[1], | |
PtrRngAlg->Data4[2], PtrRngAlg->Data4[3], PtrRngAlg->Data4[4], | |
PtrRngAlg->Data4[5], PtrRngAlg->Data4[6], PtrRngAlg->Data4[7]); | |
} | |
//----------------------------------------- | |
// Rng->GetRNG() interface test. | |
//----------------------------------------- | |
Print (L"\n -- Call RNG->GetRNG() interface : "); | |
// | |
// Allocate one buffer to store random data. | |
// | |
RandSize = 32; | |
Rand = AllocatePool (RandSize); | |
if (Rand == NULL) { | |
goto Exit; | |
} | |
// | |
// RNG with default algorithm | |
// | |
Print (L"\n >> RNG with default algorithm : "); | |
Status = Rng->GetRNG (Rng, NULL, RandSize, Rand); | |
if (EFI_ERROR (Status)) { | |
Print (L"[Fail - Status = %r]", Status); | |
} else { | |
Print (L"[Pass]"); | |
} | |
// | |
// RNG with SP800-90-HMAC-256 | |
// | |
Print (L"\n >> RNG with SP800-90-HMAC-256 : "); | |
Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmSp80090Hmac256Guid, RandSize, Rand); | |
if (EFI_ERROR (Status)) { | |
Print (L"[Fail - Status = %r]", Status); | |
} else { | |
Print (L"[Pass]"); | |
} | |
// | |
// RNG with SP800-90-HASH-256 | |
// | |
Print (L"\n >> RNG with SP800-90-Hash-256 : "); | |
Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmSp80090Hash256Guid, RandSize, Rand); | |
if (EFI_ERROR (Status)) { | |
Print (L"[Fail - Status = %r]", Status); | |
} else { | |
Print (L"[Pass]"); | |
} | |
// | |
// RNG with SP800-90-CTR-256 | |
// | |
Print (L"\n >> RNG with SP800-90-CTR-256 : "); | |
Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmSp80090Ctr256Guid, RandSize, Rand); | |
if (EFI_ERROR (Status)) { | |
Print (L"[Fail - Status = %r]", Status); | |
} else { | |
Print (L"[Pass]"); | |
} | |
// | |
// RNG with X9.31-3DES | |
// | |
Print (L"\n >> RNG with X9.31-3DES : "); | |
Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmX9313DesGuid, RandSize, Rand); | |
if (EFI_ERROR (Status)) { | |
Print (L"[Fail - Status = %r]", Status); | |
} else { | |
Print (L"[Pass]"); | |
} | |
// | |
// RNG with X9.31-AES | |
// | |
Print (L"\n >> RNG with X9.31-AES : "); | |
Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmX931AesGuid, RandSize, Rand); | |
if (EFI_ERROR (Status)) { | |
Print (L"[Fail - Status = %r]", Status); | |
} else { | |
Print (L"[Pass]"); | |
} | |
// | |
// RNG with RAW Entropy | |
// | |
Print (L"\n >> RNG with RAW Entropy : "); | |
Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmRaw, RandSize, Rand); | |
if (EFI_ERROR (Status)) { | |
Print (L"[Fail - Status = %r]", Status); | |
} else { | |
Print (L"[Pass]"); | |
} | |
//----------------------------------------- | |
// Random Number Generator test. | |
//----------------------------------------- | |
Print (L"\n -- Random Number Generation Test with default RNG Algorithm (20 Rounds): "); | |
RandSize = 1; | |
for (Index = 0; Index < 20; Index++) { | |
Status = Rng->GetRNG (Rng, NULL, RandSize, Rand); | |
if (EFI_ERROR (Status)) { | |
Print (L"[Fail - Status = %r]", Status); | |
break; | |
} else { | |
Print (L"\n %02d) - ", Index + 1); | |
for (Index2 = 0; Index2 < RandSize; Index2++) { | |
Print (L"%02x", Rand[Index2]); | |
} | |
} | |
RandSize +=1; | |
} | |
//----------------------------------------- | |
// Random Number Generator test. | |
//----------------------------------------- | |
Print (L"\n -- RAW Entropy Generation Test (20 Rounds) : "); | |
RandSize = 32; | |
for (Index = 0; Index < 20; Index++) { | |
Status = Rng->GetRNG (Rng, &gEfiRngAlgorithmRaw, RandSize, Rand); | |
if (EFI_ERROR (Status)) { | |
Print (L"[Fail - Status = %r]", Status); | |
break; | |
} else { | |
Print (L"\n %02d) - ", Index + 1); | |
for (Index2 = 0; Index2 < RandSize; Index2++) { | |
Print (L"%02x", Rand[Index2]); | |
} | |
} | |
} | |
Print (L"\n -- Exit UEFI RNG Protocol Test (Status = %r).\n", Status); | |
Exit: | |
if (Rand != NULL) { | |
FreePool (Rand); | |
} | |
return Status; | |
} |