/** This service register Hash. @param HashInterface Hash interface @retval EFI_SUCCESS This hash interface is registered successfully. @retval EFI_UNSUPPORTED System does not support register this interface. @retval EFI_ALREADY_STARTED System already register this interface. **/ EFI_STATUS EFIAPI RegisterHashInterfaceLib ( IN HASH_INTERFACE *HashInterface ) { UINTN Index; UINT32 HashMask; // // Check allow // HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) { return EFI_UNSUPPORTED; } if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) { return EFI_OUT_OF_RESOURCES; } // // Check duplication // for (Index = 0; Index < mHashInterfaceCount; Index++) { if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) { return EFI_ALREADY_STARTED; } } CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface)); mHashInterfaceCount ++; return EFI_SUCCESS; }
/** Update hash sequence data. @param HashHandle Hash handle. @param DataToHash Data to be hashed. @param DataToHashLen Data size. @retval EFI_SUCCESS Hash sequence updated. **/ EFI_STATUS EFIAPI HashUpdate ( IN HASH_HANDLE HashHandle, IN VOID *DataToHash, IN UINTN DataToHashLen ) { HASH_INTERFACE_HOB *HashInterfaceHob; HASH_HANDLE *HashCtx; UINTN Index; UINT32 HashMask; HashInterfaceHob = InternalGetHashInterface (); if (HashInterfaceHob == NULL) { return EFI_UNSUPPORTED; } if (HashInterfaceHob->HashInterfaceCount == 0) { return EFI_UNSUPPORTED; } HashCtx = (HASH_HANDLE *)HashHandle; for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) { HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) { HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen); } } return EFI_SUCCESS; }
/** Start hash sequence. @param HashHandle Hash handle. @retval EFI_SUCCESS Hash sequence start and HandleHandle returned. @retval EFI_OUT_OF_RESOURCES No enough resource to start hash. **/ EFI_STATUS EFIAPI HashStart ( OUT HASH_HANDLE *HashHandle ) { HASH_INTERFACE_HOB *HashInterfaceHob; HASH_HANDLE *HashCtx; UINTN Index; UINT32 HashMask; HashInterfaceHob = InternalGetHashInterface (); if (HashInterfaceHob == NULL) { return EFI_UNSUPPORTED; } if (HashInterfaceHob->HashInterfaceCount == 0) { return EFI_UNSUPPORTED; } HashCtx = AllocatePool (sizeof(*HashCtx) * HashInterfaceHob->HashInterfaceCount); ASSERT (HashCtx != NULL); for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) { HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) { HashInterfaceHob->HashInterface[Index].HashInit (&HashCtx[Index]); } } *HashHandle = (HASH_HANDLE)HashCtx; return EFI_SUCCESS; }
/** This service register Hash. @param HashInterface Hash interface @retval EFI_SUCCESS This hash interface is registered successfully. @retval EFI_UNSUPPORTED System does not support register this interface. @retval EFI_ALREADY_STARTED System already register this interface. **/ EFI_STATUS EFIAPI RegisterHashInterfaceLib ( IN HASH_INTERFACE *HashInterface ) { UINTN Index; HASH_INTERFACE_HOB *HashInterfaceHob; HASH_INTERFACE_HOB LocalHashInterfaceHob; UINT32 HashMask; UINT32 BiosSupportedHashMask; EFI_STATUS Status; // // Check allow // HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) { return EFI_UNSUPPORTED; } HashInterfaceHob = InternalGetHashInterface (); if (HashInterfaceHob == NULL) { ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob)); HashInterfaceHob = BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob)); if (HashInterfaceHob == NULL) { return EFI_OUT_OF_RESOURCES; } } if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) { return EFI_OUT_OF_RESOURCES; } BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap); Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask); ASSERT_EFI_ERROR (Status); // // Check duplication // for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) { if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) { // // In PEI phase, there will be shadow driver dispatched again. // DEBUG ((EFI_D_INFO, "RegisterHashInterfaceLib - Override\n")); CopyMem (&HashInterfaceHob->HashInterface[Index], HashInterface, sizeof(*HashInterface)); return EFI_SUCCESS; } } CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface)); HashInterfaceHob->HashInterfaceCount ++; return EFI_SUCCESS; }
/** This service register Hash. @param HashInterface Hash interface @retval EFI_SUCCESS This hash interface is registered successfully. @retval EFI_UNSUPPORTED System does not support register this interface. @retval EFI_ALREADY_STARTED System already register this interface. **/ EFI_STATUS EFIAPI RegisterHashInterfaceLib ( IN HASH_INTERFACE *HashInterface ) { UINTN Index; HASH_INTERFACE_HOB *HashInterfaceHob; UINT32 HashMask; EFI_STATUS Status; // // Check allow // HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) { return EFI_UNSUPPORTED; } HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid); if (HashInterfaceHob == NULL) { HashInterfaceHob = InternalCreateHashInterfaceHob (&gEfiCallerIdGuid); if (HashInterfaceHob == NULL) { return EFI_OUT_OF_RESOURCES; } } if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) { return EFI_OUT_OF_RESOURCES; } // // Check duplication // for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) { if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) { DEBUG ((DEBUG_ERROR, "Hash Interface (%g) has been registered\n", &HashInterface->HashGuid)); return EFI_ALREADY_STARTED; } } // // Record hash algorithm bitmap of CURRENT module which consumes HashLib. // HashInterfaceHob->SupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap) | HashMask; Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, HashInterfaceHob->SupportedHashMask); ASSERT_EFI_ERROR (Status); CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface)); HashInterfaceHob->HashInterfaceCount ++; return EFI_SUCCESS; }
/** Hash sequence complete and extend to PCR. @param HashHandle Hash handle. @param PcrIndex PCR to be extended. @param DataToHash Data to be hashed. @param DataToHashLen Data size. @param DigestList Digest list. @retval EFI_SUCCESS Hash sequence complete and DigestList is returned. **/ EFI_STATUS EFIAPI HashCompleteAndExtend ( IN HASH_HANDLE HashHandle, IN TPMI_DH_PCR PcrIndex, IN VOID *DataToHash, IN UINTN DataToHashLen, OUT TPML_DIGEST_VALUES *DigestList ) { TPML_DIGEST_VALUES Digest; HASH_INTERFACE_HOB *HashInterfaceHob; HASH_HANDLE *HashCtx; UINTN Index; EFI_STATUS Status; UINT32 HashMask; HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid); if (HashInterfaceHob == NULL) { return EFI_UNSUPPORTED; } if (HashInterfaceHob->HashInterfaceCount == 0) { return EFI_UNSUPPORTED; } CheckSupportedHashMaskMismatch (HashInterfaceHob); HashCtx = (HASH_HANDLE *)HashHandle; ZeroMem (DigestList, sizeof(*DigestList)); for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) { HashMask = Tpm2GetHashMaskFromAlgo (&HashInterfaceHob->HashInterface[Index].HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) { HashInterfaceHob->HashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen); HashInterfaceHob->HashInterface[Index].HashFinal (HashCtx[Index], &Digest); Tpm2SetHashToDigestList (DigestList, &Digest); } } FreePool (HashCtx); Status = Tpm2PcrExtend ( PcrIndex, DigestList ); return Status; }
/** This service register Hash. @param HashInterface Hash interface @retval EFI_SUCCESS This hash interface is registered successfully. @retval EFI_UNSUPPORTED System does not support register this interface. @retval EFI_ALREADY_STARTED System already register this interface. **/ EFI_STATUS EFIAPI RegisterHashInterfaceLib ( IN HASH_INTERFACE *HashInterface ) { UINTN Index; UINT32 HashMask; UINT32 BiosSupportedHashMask; EFI_STATUS Status; // // Check allow // HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) { return EFI_UNSUPPORTED; } if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) { return EFI_OUT_OF_RESOURCES; } BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap); Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask); ASSERT_EFI_ERROR (Status); // // Check duplication // for (Index = 0; Index < mHashInterfaceCount; Index++) { if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) { return EFI_ALREADY_STARTED; } } CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface)); mHashInterfaceCount ++; return EFI_SUCCESS; }
/** Hash sequence complete and extend to PCR. @param HashHandle Hash handle. @param PcrIndex PCR to be extended. @param DataToHash Data to be hashed. @param DataToHashLen Data size. @param DigestList Digest list. @retval EFI_SUCCESS Hash sequence complete and DigestList is returned. **/ EFI_STATUS EFIAPI HashCompleteAndExtend ( IN HASH_HANDLE HashHandle, IN TPMI_DH_PCR PcrIndex, IN VOID *DataToHash, IN UINTN DataToHashLen, OUT TPML_DIGEST_VALUES *DigestList ) { TPML_DIGEST_VALUES Digest; HASH_HANDLE *HashCtx; UINTN Index; EFI_STATUS Status; UINT32 HashMask; if (mHashInterfaceCount == 0) { return EFI_UNSUPPORTED; } HashCtx = (HASH_HANDLE *)HashHandle; ZeroMem (DigestList, sizeof(*DigestList)); for (Index = 0; Index < mHashInterfaceCount; Index++) { HashMask = Tpm2GetHashMaskFromAlgo (&mHashInterface[Index].HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) != 0) { mHashInterface[Index].HashUpdate (HashCtx[Index], DataToHash, DataToHashLen); mHashInterface[Index].HashFinal (HashCtx[Index], &Digest); Tpm2SetHashToDigestList (DigestList, &Digest); } } FreePool (HashCtx); Status = Tpm2PcrExtend ( PcrIndex, DigestList ); return Status; }