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 }