/** @file This library is HashLib for Tdx. Copyright (c) 2021 - 2022, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include EFI_GUID mSha384Guid = HASH_ALGORITHM_SHA384_GUID; // // Currently TDX supports SHA384. // HASH_INTERFACE mHashInterface = { { 0 }, NULL, NULL, NULL }; UINTN mHashInterfaceCount = 0; /** 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_HANDLE HashCtx; if (mHashInterfaceCount == 0) { ASSERT (FALSE); return EFI_UNSUPPORTED; } HashCtx = 0; mHashInterface.HashInit (&HashCtx); *HashHandle = HashCtx; 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 ) { if (mHashInterfaceCount == 0) { ASSERT (FALSE); return EFI_UNSUPPORTED; } mHashInterface.HashUpdate (HashHandle, DataToHash, DataToHashLen); 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; EFI_STATUS Status; if (mHashInterfaceCount == 0) { ASSERT (FALSE); return EFI_UNSUPPORTED; } ZeroMem (DigestList, sizeof (*DigestList)); mHashInterface.HashUpdate (HashHandle, DataToHash, DataToHashLen); mHashInterface.HashFinal (HashHandle, &Digest); CopyMem ( &DigestList->digests[0], &Digest.digests[0], sizeof (Digest.digests[0]) ); DigestList->count++; ASSERT (DigestList->count == 1 && DigestList->digests[0].hashAlg == TPM_ALG_SHA384); Status = TdExtendRtmr ( (UINT32 *)DigestList->digests[0].digest.sha384, SHA384_DIGEST_SIZE, (UINT8)PcrIndex ); ASSERT (!EFI_ERROR (Status)); return Status; } /** Hash data and extend to RTMR. @param PcrIndex PCR to be extended. @param DataToHash Data to be hashed. @param DataToHashLen Data size. @param DigestList Digest list. @retval EFI_SUCCESS Hash data and DigestList is returned. **/ EFI_STATUS EFIAPI HashAndExtend ( IN TPMI_DH_PCR PcrIndex, IN VOID *DataToHash, IN UINTN DataToHashLen, OUT TPML_DIGEST_VALUES *DigestList ) { HASH_HANDLE HashHandle; EFI_STATUS Status; if (mHashInterfaceCount == 0) { ASSERT (FALSE); return EFI_UNSUPPORTED; } ASSERT (TdIsEnabled ()); HashStart (&HashHandle); HashUpdate (HashHandle, DataToHash, DataToHashLen); Status = HashCompleteAndExtend (HashHandle, PcrIndex, NULL, 0, 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 ) { // // HashLibTdx is designed for Tdx guest. So if it is not Tdx guest, // return EFI_UNSUPPORTED. // if (!TdIsEnabled ()) { return EFI_UNSUPPORTED; } // // Only SHA384 is allowed. // if (!CompareGuid (&mSha384Guid, &HashInterface->HashGuid)) { return EFI_UNSUPPORTED; } if (mHashInterfaceCount != 0) { ASSERT (FALSE); return EFI_OUT_OF_RESOURCES; } CopyMem (&mHashInterface, HashInterface, sizeof (*HashInterface)); mHashInterfaceCount++; return EFI_SUCCESS; }