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/HashLib.h>
     25 
     26 #include "HashLibBaseCryptoRouterCommon.h"
     27 
     28 HASH_INTERFACE   mHashInterface[HASH_COUNT] = {{{0}, NULL, NULL, NULL}};
     29 UINTN            mHashInterfaceCount = 0;
     30 
     31 /**
     32   Start hash sequence.
     33 
     34   @param HashHandle Hash handle.
     35 
     36   @retval EFI_SUCCESS          Hash sequence start and HandleHandle returned.
     37   @retval EFI_OUT_OF_RESOURCES No enough resource to start hash.
     38 **/
     39 EFI_STATUS
     40 EFIAPI
     41 HashStart (
     42   OUT HASH_HANDLE    *HashHandle
     43   )
     44 {
     45   HASH_HANDLE  *HashCtx;
     46   UINTN        Index;
     47   UINT32       HashMask;
     48 
     49   if (mHashInterfaceCount == 0) {
     50     return EFI_UNSUPPORTED;
     51   }
     52 
     53   HashCtx = AllocatePool (sizeof(*HashCtx) * mHashInterfaceCount);
     54   ASSERT (HashCtx != NULL);
     55 
     56   for (Index = 0; Index < mHashInterfaceCount; Index++) {
     57     HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
     58     if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
     59       mHashInterface[Index].HashInit (&HashCtx[Index]);
     60     }
     61   }
     62 
     63   *HashHandle = (HASH_HANDLE)HashCtx;
     64 
     65   return EFI_SUCCESS;
     66 }
     67 
     68 /**
     69   Update hash sequence data.
     70 
     71   @param HashHandle    Hash handle.
     72   @param DataToHash    Data to be hashed.
     73   @param DataToHashLen Data size.
     74 
     75   @retval EFI_SUCCESS     Hash sequence updated.
     76 **/
     77 EFI_STATUS
     78 EFIAPI
     79 HashUpdate (
     80   IN HASH_HANDLE    HashHandle,
     81   IN VOID           *DataToHash,
     82   IN UINTN          DataToHashLen
     83   )
     84 {
     85   HASH_HANDLE  *HashCtx;
     86   UINTN        Index;
     87   UINT32       HashMask;
     88 
     89   if (mHashInterfaceCount == 0) {
     90     return EFI_UNSUPPORTED;
     91   }
     92 
     93   HashCtx = (HASH_HANDLE *)HashHandle;
     94 
     95   for (Index = 0; Index < mHashInterfaceCount; Index++) {
     96     HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
     97     if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
     98       mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
     99     }
    100   }
    101 
    102   return EFI_SUCCESS;
    103 }
    104 
    105 /**
    106   Hash sequence complete and extend to PCR.
    107 
    108   @param HashHandle    Hash handle.
    109   @param PcrIndex      PCR to be extended.
    110   @param DataToHash    Data to be hashed.
    111   @param DataToHashLen Data size.
    112   @param DigestList    Digest list.
    113 
    114   @retval EFI_SUCCESS     Hash sequence complete and DigestList is returned.
    115 **/
    116 EFI_STATUS
    117 EFIAPI
    118 HashCompleteAndExtend (
    119   IN HASH_HANDLE         HashHandle,
    120   IN TPMI_DH_PCR         PcrIndex,
    121   IN VOID                *DataToHash,
    122   IN UINTN               DataToHashLen,
    123   OUT TPML_DIGEST_VALUES *DigestList
    124   )
    125 {
    126   TPML_DIGEST_VALUES Digest;
    127   HASH_HANDLE        *HashCtx;
    128   UINTN              Index;
    129   EFI_STATUS         Status;
    130   UINT32             HashMask;
    131 
    132   if (mHashInterfaceCount == 0) {
    133     return EFI_UNSUPPORTED;
    134   }
    135 
    136   HashCtx = (HASH_HANDLE *)HashHandle;
    137   ZeroMem (DigestList, sizeof(*DigestList));
    138 
    139   for (Index = 0; Index < mHashInterfaceCount; Index++) {
    140     HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid);
    141     if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) {
    142       mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen);
    143       mHashInterface[Index].HashFinal (HashCtx[Index], &Digest);
    144       Tpm2SetHashToDigestList (DigestList, &Digest);
    145     }
    146   }
    147 
    148   FreePool (HashCtx);
    149 
    150   Status = Tpm2PcrExtend (
    151              PcrIndex,
    152              DigestList
    153              );
    154   return Status;
    155 }
    156 
    157 /**
    158   Hash data and extend to PCR.
    159 
    160   @param PcrIndex      PCR to be extended.
    161   @param DataToHash    Data to be hashed.
    162   @param DataToHashLen Data size.
    163   @param DigestList    Digest list.
    164 
    165   @retval EFI_SUCCESS     Hash data and DigestList is returned.
    166 **/
    167 EFI_STATUS
    168 EFIAPI
    169 HashAndExtend (
    170   IN TPMI_DH_PCR                    PcrIndex,
    171   IN VOID                           *DataToHash,
    172   IN UINTN                          DataToHashLen,
    173   OUT TPML_DIGEST_VALUES            *DigestList
    174   )
    175 {
    176   HASH_HANDLE    HashHandle;
    177   EFI_STATUS     Status;
    178 
    179   if (mHashInterfaceCount == 0) {
    180     return EFI_UNSUPPORTED;
    181   }
    182 
    183   HashStart (&HashHandle);
    184   HashUpdate (HashHandle, DataToHash, DataToHashLen);
    185   Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, DigestList);
    186 
    187   return Status;
    188 }
    189 
    190 /**
    191   This service register Hash.
    192 
    193   @param HashInterface  Hash interface
    194 
    195   @retval EFI_SUCCESS          This hash interface is registered successfully.
    196   @retval EFI_UNSUPPORTED      System does not support register this interface.
    197   @retval EFI_ALREADY_STARTED  System already register this interface.
    198 **/
    199 EFI_STATUS
    200 EFIAPI
    201 RegisterHashInterfaceLib (
    202   IN HASH_INTERFACE   *HashInterface
    203   )
    204 {
    205   UINTN              Index;
    206   UINT32             HashMask;
    207   UINT32             BiosSupportedHashMask;
    208   EFI_STATUS         Status;
    209 
    210   //
    211   // Check allow
    212   //
    213   HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid);
    214   if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) {
    215     return EFI_UNSUPPORTED;
    216   }
    217 
    218   if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) {
    219     return EFI_OUT_OF_RESOURCES;
    220   }
    221   BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap);
    222   Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask);
    223   ASSERT_EFI_ERROR (Status);
    224 
    225   //
    226   // Check duplication
    227   //
    228   for (Index = 0; Index < mHashInterfaceCount; Index++) {
    229     if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) {
    230       return EFI_ALREADY_STARTED;
    231     }
    232   }
    233 
    234   CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface));
    235   mHashInterfaceCount ++;
    236 
    237   return EFI_SUCCESS;
    238 }