/** Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result, and add an entry to the Event Log. @param[in] TcgData TCG_DXE_DATA structure. @param[in] HashData Physical address of the start of the data buffer to be hashed, extended, and logged. @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData @param[in, out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. @param[in] NewEventData Pointer to the new event data. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI TcgDxeHashLogExtendEventI ( IN TCG_DXE_DATA *TcgData, IN UINT8 *HashData, IN UINT64 HashDataLen, IN OUT TCG_PCR_EVENT_HDR *NewEventHdr, IN UINT8 *NewEventData ) { EFI_STATUS Status; if (!TcgData->BsCap.TPMPresentFlag) { return EFI_DEVICE_ERROR; } if (HashDataLen > 0 || HashData != NULL) { Status = TpmCommHashAll ( HashData, (UINTN) HashDataLen, &NewEventHdr->Digest ); if (EFI_ERROR(Status)) { DEBUG ((DEBUG_ERROR, "TpmCommHashAll Failed. %x\n", Status)); goto Done; } } Status = Tpm12Extend ( &NewEventHdr->Digest, NewEventHdr->PCRIndex, NULL ); if (!EFI_ERROR (Status)) { Status = TcgDxeLogEventI (TcgData, NewEventHdr, NewEventData); } Done: if ((Status == EFI_DEVICE_ERROR) || (Status == EFI_TIMEOUT)) { DEBUG ((EFI_D_ERROR, "TcgDxeHashLogExtendEventI - %r. Disable TPM.\n", Status)); TcgData->BsCap.TPMPresentFlag = FALSE; REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) ); Status = EFI_DEVICE_ERROR; } return Status; }
/** Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result, and build a GUIDed HOB recording the event which will be passed to the DXE phase and added into the Event Log. @param[in] PeiServices Describes the list of possible PEI Services. @param[in] HashData Physical address of the start of the data buffer to be hashed, extended, and logged. @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData. @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. @param[in] NewEventData Pointer to the new event data. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS HashLogExtendEvent ( IN EFI_PEI_SERVICES **PeiServices, IN UINT8 *HashData, IN UINTN HashDataLen, IN TCG_PCR_EVENT_HDR *NewEventHdr, IN UINT8 *NewEventData ) { EFI_STATUS Status; VOID *HobData; if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { return EFI_DEVICE_ERROR; } HobData = NULL; if (HashDataLen != 0) { Status = TpmCommHashAll ( HashData, HashDataLen, &NewEventHdr->Digest ); if (EFI_ERROR (Status)) { goto Done; } } Status = Tpm12Extend ( &NewEventHdr->Digest, NewEventHdr->PCRIndex, NULL ); if (EFI_ERROR (Status)) { goto Done; } HobData = BuildGuidHob ( &gTcgEventEntryHobGuid, sizeof (*NewEventHdr) + NewEventHdr->EventSize ); if (HobData == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Done; } CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr)); HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr)); CopyMem (HobData, NewEventData, NewEventHdr->EventSize); Done: if ((Status == EFI_DEVICE_ERROR) || (Status == EFI_TIMEOUT)) { DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status)); BuildGuidHob (&gTpmErrorHobGuid,0); REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) ); Status = EFI_DEVICE_ERROR; } return Status; }