Home | History | Annotate | Download | only in RngTest
      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