--- /dev/null
+/** @file\r
+\r
+ Extends one of the RTMR measurement registers in TDCS with the provided\r
+ extension data in memory.\r
+\r
+ Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Uefi/UefiBaseType.h>\r
+#include <Library/TdxLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <IndustryStandard/Tpm20.h>\r
+#include <IndustryStandard/Tdx.h>\r
+\r
+#define RTMR_COUNT 4\r
+#define TD_EXTEND_BUFFER_LEN (64 + 48)\r
+\r
+UINT8 mExtendBuffer[TD_EXTEND_BUFFER_LEN];\r
+\r
+/**\r
+ This function extends one of the RTMR measurement register\r
+ in TDCS with the provided extension data in memory.\r
+ RTMR extending supports SHA384 which length is 48 bytes.\r
+\r
+ @param[in] Data Point to the data to be extended\r
+ @param[in] DataLen Length of the data. Must be 48\r
+ @param[in] Index RTMR index\r
+\r
+ @return EFI_SUCCESS\r
+ @return EFI_INVALID_PARAMETER\r
+ @return EFI_DEVICE_ERROR\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+TdExtendRtmr (\r
+ IN UINT32 *Data,\r
+ IN UINT32 DataLen,\r
+ IN UINT8 Index\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT64 TdCallStatus;\r
+ UINT8 *ExtendBuffer;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ ASSERT (Data != NULL);\r
+ ASSERT (DataLen == SHA384_DIGEST_SIZE);\r
+ ASSERT (Index >= 0 && Index < RTMR_COUNT);\r
+\r
+ if ((Data == NULL) || (DataLen != SHA384_DIGEST_SIZE) || (Index >= RTMR_COUNT)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ // TD.RTMR.EXTEND requires 64B-aligned guest physical address of\r
+ // 48B-extension data. We use ALIGN_POINTER(Pointer, 64) to get\r
+ // the 64B-aligned guest physical address.\r
+ ExtendBuffer = ALIGN_POINTER (mExtendBuffer, 64);\r
+ ASSERT (((UINTN)ExtendBuffer & 0x3f) == 0);\r
+\r
+ ZeroMem (ExtendBuffer, SHA384_DIGEST_SIZE);\r
+ CopyMem (ExtendBuffer, Data, SHA384_DIGEST_SIZE);\r
+\r
+ TdCallStatus = TdCall (TDCALL_TDEXTENDRTMR, (UINT64)(UINTN)ExtendBuffer, Index, 0, 0);\r
+\r
+ if (TdCallStatus == TDX_EXIT_REASON_SUCCESS) {\r
+ Status = EFI_SUCCESS;\r
+ } else if (TdCallStatus == TDX_EXIT_REASON_OPERAND_INVALID) {\r
+ Status = EFI_INVALID_PARAMETER;\r
+ } else {\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+\r
+ if (Status != EFI_SUCCESS) {\r
+ DEBUG ((DEBUG_ERROR, "Error returned from TdExtendRtmr call - 0x%lx\n", TdCallStatus));\r
+ }\r
+\r
+ return Status;\r
+}\r