Home | History | Annotate | Download | only in HashLibBaseCryptoRouter
      1 /** @file
      2   This library is BaseCrypto router. It will redirect hash request to each individual
      3   hash handler registerd, such as SHA1, SHA256.
      4   Platform can use PcdTpm2HashMask to mask some hash engines.
      5 
      6 Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved. <BR>
      7 This program and the accompanying materials
      8 are licensed and made available under the terms and conditions of the BSD License
      9 which accompanies this distribution.  The full text of the license may be found at
     10 http://opensource.org/licenses/bsd-license.php
     11 
     12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15 **/
     16 
     17 #include <PiPei.h>
     18 #include <Library/BaseLib.h>
     19 #include <Library/BaseMemoryLib.h>
     20 #include <Library/Tpm2CommandLib.h>
     21 #include <Library/DebugLib.h>
     22 #include <Library/MemoryAllocationLib.h>
     23 #include <Library/PcdLib.h>
     24 #include <Library/HobLib.h>
     25 #include <Library/HashLib.h>
     26 
     27 #include "HashLibBaseCryptoRouterCommon.h"
     28 
     29 #define HASH_LIB_PEI_ROUTER_GUID \
     30   { 0x84681c08, 0x6873, 0x46f3, { 0x8b, 0xb7, 0xab, 0x66, 0x18, 0x95, 0xa1, 0xb3 } }
     31 
     32 EFI_GUID mHashLibPeiRouterGuid = HASH_LIB_PEI_ROUTER_GUID;
     33 
     34 typedef struct {
     35   UINTN            HashInterfaceCount;
     36   HASH_INTERFACE   HashInterface[HASH_COUNT];
     37 } HASH_INTERFACE_HOB;
     38 
     39 /**
     40   This function get hash interface.
     41 
     42   @retval hash interface.
     43 **/
     44 HASH_INTERFACE_HOB *
     45 InternalGetHashInterface (
     46   VOID
     47   )
     48 {
     49   EFI_HOB_GUID_TYPE *Hob;
     50 
     51   Hob = GetFirstGuidHob (&mHashLibPeiRouterGuid);
     52   if (Hob == NULL) {
     53     return NULL;
     54   }
     55   return (HASH_INTERFACE_HOB *)(Hob + 1);
     56 }
     57 
     58 /**
     59   Start hash sequence.
     60 
     61   @param HashHandle Hash handle.
     62 
     63   @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.
     64   @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
     65 **/
     66 EFI_STATUS
     67 EFIAPI
     68 HashStart (
     69   OUT HASH_HANDLE    *HashHandle
     70   )
     71 {
     72   HASH_INTERFACE_HOB *HashInterfaceHob;
     73   HASH_HANDLE        *HashCtx;
     74   UINTN              Index;
     75   UINT32             HashMask;
     76 
     77   HashInterfaceHob = InternalGetHashInterface ();
     78   if (HashInterfaceHob == NULL) {
     79     return EFI_UNSUPPORTED;
     80   }
     81 
     82   if (HashInterfaceHob->HashInterfaceCount == 0) {
     83     return EFI_UNSUPPORTED;
     84   }
     85 
     86   HashCtx = AllocatePool (sizeof(*HashCtx) * HashInterfaceHob->HashInterfaceCount);
     87   ASSERT (HashCtx != NULL);
     88 
     89   for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
     90     HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);
     91     if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
     92       HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]);
     93     }
     94   }
     95 
     96   *HashHandle = (HASH_HANDLE)HashCtx;
     97 
     98   return EFI_SUCCESS;
     99 }
    100 
    101 /**
    102   Update hash sequence data.
    103 
    104   @param HashHandle    Hash handle.
    105   @param DataToHash    Data to be hashed.
    106   @param DataToHashLen Data size.
    107 
    108   @retval EFI_SUCCESS     Hash sequence updated.
    109 **/
    110 EFI_STATUS
    111 EFIAPI
    112 HashUpdate (
    113   IN HASH_HANDLE    HashHandle,
    114   IN VOID           *DataToHash,
    115   IN UINTN          DataToHashLen
    116   )
    117 {
    118   HASH_INTERFACE_HOB *HashInterfaceHob;
    119   HASH_HANDLE        *HashCtx;
    120   UINTN              Index;
    121   UINT32             HashMask;
    122 
    123   HashInterfaceHob = InternalGetHashInterface ();
    124   if (HashInterfaceHob == NULL) {
    125     return EFI_UNSUPPORTED;
    126   }
    127 
    128   if (HashInterfaceHob->HashInterfaceCount == 0) {
    129     return EFI_UNSUPPORTED;
    130   }
    131 
    132   HashCtx = (HASH_HANDLE *)HashHandle;
    133 
    134   for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
    135     HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);
    136     if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
    137       HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
    138     }
    139   }
    140 
    141   return EFI_SUCCESS;
    142 }
    143 
    144 /**
    145   Hash sequence complete and extend to PCR.
    146 
    147   @param HashHandle    Hash handle.
    148   @param PcrIndex      PCR to be extended.
    149   @param DataToHash    Data to be hashed.
    150   @param DataToHashLen Data size.
    151   @param DigestList    Digest list.
    152 
    153   @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.
    154 **/
    155 EFI_STATUS
    156 EFIAPI
    157 HashCompleteAndExtend (
    158   IN HASH_HANDLE         HashHandle,
    159   IN TPMI_DH_PCR         PcrIndex,
    160   IN VOID                *DataToHash,
    161   IN UINTN               DataToHashLen,
    162   OUT TPML_DIGEST_VALUES *DigestList
    163   )
    164 {
    165   TPML_DIGEST_VALUES Digest;
    166   HASH_INTERFACE_HOB *HashInterfaceHob;
    167   HASH_HANDLE        *HashCtx;
    168   UINTN              Index;
    169   EFI_STATUS         Status;
    170   UINT32             HashMask;
    171 
    172   HashInterfaceHob = InternalGetHashInterface ();
    173   if (HashInterfaceHob == NULL) {
    174     return EFI_UNSUPPORTED;
    175   }
    176 
    177   if (HashInterfaceHob->HashInterfaceCount == 0) {
    178     return EFI_UNSUPPORTED;
    179   }
    180 
    181   HashCtx = (HASH_HANDLE *)HashHandle;
    182   ZeroMem (DigestList, sizeof(*DigestList));
    183 
    184   for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
    185     HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid);
    186     if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
    187       HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
    188       HashInterfaceHob->HashInterface[Index].HashFinal (HashCtx[Index], &Digest);
    189       Tpm2SetHashToDigestList (DigestList, &Digest);
    190     }
    191   }
    192 
    193   FreePool (HashCtx);
    194 
    195   Status = Tpm2PcrExtend (
    196              PcrIndex,
    197              DigestList
    198              );
    199   return Status;
    200 }
    201 
    202 /**
    203   Hash data and extend to PCR.
    204 
    205   @param PcrIndex      PCR to be extended.
    206   @param DataToHash    Data to be hashed.
    207   @param DataToHashLen Data size.
    208   @param DigestList    Digest list.
    209 
    210   @retval EFI_SUCCESS     Hash data and DigestList is returned.
    211 **/
    212 EFI_STATUS
    213 EFIAPI
    214 HashAndExtend (
    215   IN TPMI_DH_PCR                    PcrIndex,
    216   IN VOID                           *DataToHash,
    217   IN UINTN                          DataToHashLen,
    218   OUT TPML_DIGEST_VALUES            *DigestList
    219   )
    220 {
    221   HASH_INTERFACE_HOB *HashInterfaceHob;
    222   HASH_HANDLE        HashHandle;
    223   EFI_STATUS         Status;
    224 
    225   HashInterfaceHob = InternalGetHashInterface ();
    226   if (HashInterfaceHob == NULL) {
    227     return EFI_UNSUPPORTED;
    228   }
    229 
    230   if (HashInterfaceHob->HashInterfaceCount == 0) {
    231     return EFI_UNSUPPORTED;
    232   }
    233 
    234   HashStart (&HashHandle);
    235   HashUpdate (HashHandle, DataToHash, DataToHashLen);
    236   Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
    237 
    238   return Status;
    239 }
    240 
    241 /**
    242   This service register Hash.
    243 
    244   @param HashInterface  Hash interface
    245 
    246   @retval EFI_SUCCESS          This hash interface is registered successfully.
    247   @retval EFI_UNSUPPORTED      System does not support register this interface.
    248   @retval EFI_ALREADY_STARTED  System already register this interface.
    249 **/
    250 EFI_STATUS
    251 EFIAPI
    252 RegisterHashInterfaceLib (
    253   IN HASH_INTERFACE   *HashInterface
    254   )
    255 {
    256   UINTN              Index;
    257   HASH_INTERFACE_HOB *HashInterfaceHob;
    258   HASH_INTERFACE_HOB LocalHashInterfaceHob;
    259   UINT32             HashMask;
    260   UINT32             BiosSupportedHashMask;
    261   EFI_STATUS         Status;
    262 
    263   //
    264   // Check allow
    265   //
    266   HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
    267   if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
    268     return EFI_UNSUPPORTED;
    269   }
    270 
    271   HashInterfaceHob = InternalGetHashInterface ();
    272   if (HashInterfaceHob == NULL) {
    273     ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
    274     HashInterfaceHob = BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob));
    275     if (HashInterfaceHob == NULL) {
    276       return EFI_OUT_OF_RESOURCES;
    277     }
    278   }
    279 
    280   if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) {
    281     return EFI_OUT_OF_RESOURCES;
    282   }
    283   BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);
    284   Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask);
    285   ASSERT_EFI_ERROR (Status);
    286 
    287   //
    288   // Check duplication
    289   //
    290   for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) {
    291     if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
    292       //
    293       // In PEI phase, there will be shadow driver dispatched again.
    294       //
    295       DEBUG ((EFI_D_INFO, "RegisterHashInterfaceLib - Override\n"));
    296       CopyMem (&HashInterfaceHob->HashInterface[Index], HashInterface, sizeof(*HashInterface));
    297       return EFI_SUCCESS;
    298     }
    299   }
    300 
    301   CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface));
    302   HashInterfaceHob->HashInterfaceCount ++;
    303 
    304   return EFI_SUCCESS;
    305 }