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 }