/** @file
  EDKII Device Security library for SPDM device.
  It follows the SPDM Specification.

Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "SpdmSecurityLibInternal.h"

/**
  Measure and log an EFI variable, and extend the measurement result into a specific PCR.

  @param[in]  PcrIndex          PCR Index.
  @param[in]  EventType         Event type.
  @param[in]  VarName           A Null-terminated string that is the name of the vendor's variable.
  @param[in]  VendorGuid        A unique identifier for the vendor.
  @param[in]  VarData           The content of the variable data.
  @param[in]  VarSize           The size of the variable data.

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  Out of memory.
  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.

**/
EFI_STATUS
EFIAPI
MeasureVariable (
  IN      UINT32    PcrIndex,
  IN      UINT32    EventType,
  IN      CHAR16    *VarName,
  IN      EFI_GUID  *VendorGuid,
  IN      VOID      *VarData,
  IN      UINTN     VarSize
  )
{
  EFI_STATUS          Status;
  UINTN               VarNameLength;
  UEFI_VARIABLE_DATA  *VarLog;
  UINT32              VarLogSize;

  if (!(((VarSize == 0) && (VarData == NULL)) || ((VarSize != 0) && (VarData != NULL)))) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return EFI_INVALID_PARAMETER;
  }

  VarNameLength = StrLen (VarName);
  VarLogSize    = (UINT32)(sizeof (*VarLog) + VarNameLength * sizeof (*VarName) + VarSize
                           - sizeof (VarLog->UnicodeName) - sizeof (VarLog->VariableData));

  VarLog = (UEFI_VARIABLE_DATA *)AllocateZeroPool (VarLogSize);
  if (VarLog == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (&VarLog->VariableName, VendorGuid, sizeof (VarLog->VariableName));
  VarLog->UnicodeNameLength  = VarNameLength;
  VarLog->VariableDataLength = VarSize;
  CopyMem (
    VarLog->UnicodeName,
    VarName,
    VarNameLength * sizeof (*VarName)
    );
  if (VarSize != 0) {
    CopyMem (
      (CHAR16 *)VarLog->UnicodeName + VarNameLength,
      VarData,
      VarSize
      );
  }

  DEBUG ((DEBUG_INFO, "VariableDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)PcrIndex, (UINTN)EventType));
  DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));

  Status = TpmMeasureAndLogData (
             PcrIndex,
             EventType,
             VarLog,
             VarLogSize,
             VarLog,
             VarLogSize
             );
  FreePool (VarLog);
  return Status;
}

/**
  Extend Certicate and auth state to NV Index and measure trust anchor to PCR.

  @param[in]  SpdmDeviceContext          The SPDM context for the device.
  @param[in]  AuthState                  The auth state of this deice.
  @param[in]  CertChainSize              The size of cert chain.
  @param[in]  CertChain                  A pointer to a destination buffer to store the certificate chain.
  @param[in]  TrustAnchor                A buffer to hold the trust_anchor which is used to validate the peer
                                         certificate, if not NULL.
  @param[in]  TrustAnchorSize            A buffer to hold the trust_anchor_size, if not NULL..
  @param[in]  SlotId                     The number of slot for the certificate chain.
  @param[out]  SecurityState             A pointer to the security state of the requester.

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  Out of memory.
  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.

**/
EFI_STATUS
ExtendCertificate (
  IN  SPDM_DEVICE_CONTEXT          *SpdmDeviceContext,
  IN UINT8                         AuthState,
  IN UINTN                         CertChainSize,
  IN UINT8                         *CertChain,
  IN VOID                          *TrustAnchor,
  IN UINTN                         TrustAnchorSize,
  IN UINT8                         SlotId,
  OUT EDKII_DEVICE_SECURITY_STATE  *SecurityState
  )
{
  VOID                                                       *EventLog;
  UINT32                                                     EventLogSize;
  UINT8                                                      *EventLogPtr;
  TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT                     *NvIndexInstance;
  TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2                     *EventData2;
  TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN  *TcgSpdmCertChain;
  VOID                                                       *DeviceContext;
  UINTN                                                      DeviceContextSize;
  EFI_STATUS                                                 Status;
  UINTN                                                      DevicePathSize;
  UINT32                                                     BaseHashAlgo;
  UINTN                                                      DataSize;
  VOID                                                       *SpdmContext;
  SPDM_DATA_PARAMETER                                        Parameter;
  EFI_SIGNATURE_DATA                                         *SignatureData;
  UINTN                                                      SignatureDataSize;

  SpdmContext = SpdmDeviceContext->SpdmContext;

  EventLog = NULL;
  ZeroMem (&Parameter, sizeof (Parameter));
  Parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
  DataSize           = sizeof (BaseHashAlgo);
  Status             = SpdmGetData (SpdmContext, LIBSPDM_DATA_BASE_HASH_ALGO, &Parameter, &BaseHashAlgo, &DataSize);
  ASSERT_EFI_ERROR (Status);

  DeviceContextSize = GetDeviceMeasurementContextSize (SpdmDeviceContext);
  DevicePathSize    = GetDevicePathSize (SpdmDeviceContext->DevicePath);

  switch (AuthState) {
    case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS:
    case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_AUTH:
    case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_BINDING:
      EventLogSize = (UINT32)(sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT) +
                              sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
                              sizeof (UINT64) + DevicePathSize +
                              sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN) +
                              CertChainSize +
                              DeviceContextSize);
      EventLog = AllocatePool (EventLogSize);
      if (EventLog == NULL) {
        SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
        return EFI_OUT_OF_RESOURCES;
      }

      EventLogPtr = EventLog;

      NvIndexInstance = (VOID *)EventLogPtr;
      CopyMem (NvIndexInstance->Signature, TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE));
      NvIndexInstance->Version = TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_VERSION;
      ZeroMem (NvIndexInstance->Reserved, sizeof (NvIndexInstance->Reserved));
      EventLogPtr += sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT);

      EventData2 = (VOID *)EventLogPtr;
      CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2, sizeof (EventData2->Signature));
      EventData2->Version    = TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;
      EventData2->AuthState  = AuthState;
      EventData2->Reserved   = 0;
      EventData2->Length     = (UINT32)EventLogSize;
      EventData2->DeviceType = GetSpdmDeviceType (SpdmDeviceContext);

      EventData2->SubHeaderType   = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_CERT_CHAIN;
      EventData2->SubHeaderLength = (UINT32)(sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN) + CertChainSize);
      EventData2->SubHeaderUID    = SpdmDeviceContext->DeviceUID;

      EventLogPtr = (VOID *)(EventData2 + 1);

      *(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
      EventLogPtr           += sizeof (UINT64);
      CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
      EventLogPtr += DevicePathSize;

      TcgSpdmCertChain               = (VOID *)EventLogPtr;
      TcgSpdmCertChain->SpdmVersion  = SpdmDeviceContext->SpdmVersion;
      TcgSpdmCertChain->SpdmSlotId   = SlotId;
      TcgSpdmCertChain->Reserved     = 0;
      TcgSpdmCertChain->SpdmHashAlgo = BaseHashAlgo;
      EventLogPtr                   += sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN);

      CopyMem (EventLogPtr, CertChain, CertChainSize);
      EventLogPtr += CertChainSize;

      if (DeviceContextSize != 0) {
        DeviceContext = (VOID *)EventLogPtr;
        Status        = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
        if (Status != EFI_SUCCESS) {
          SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
          Status                             = EFI_DEVICE_ERROR;
          goto Exit;
        }
      }

      Status = TpmMeasureAndLogData (
                 TCG_NV_EXTEND_INDEX_FOR_INSTANCE,
                 EV_NO_ACTION,
                 EventLog,
                 EventLogSize,
                 EventLog,
                 EventLogSize
                 );
      if (EFI_ERROR (Status)) {
        SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
      }

      DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Instance) - %r\n", Status));

      break;
    case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID:
      EventLogSize = (UINT32)(sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT) +
                              sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
                              sizeof (UINT64) + DevicePathSize +
                              sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN) +
                              DeviceContextSize);
      EventLog = AllocatePool (EventLogSize);
      if (EventLog == NULL) {
        SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
        return EFI_OUT_OF_RESOURCES;
      }

      EventLogPtr = EventLog;

      NvIndexInstance = (VOID *)EventLogPtr;
      CopyMem (NvIndexInstance->Signature, TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE));
      NvIndexInstance->Version = TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_VERSION;
      ZeroMem (NvIndexInstance->Reserved, sizeof (NvIndexInstance->Reserved));
      EventLogPtr += sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT);

      EventData2 = (VOID *)EventLogPtr;
      CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2, sizeof (EventData2->Signature));
      EventData2->Version    = TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;
      EventData2->AuthState  = AuthState;
      EventData2->Reserved   = 0;
      EventData2->Length     = (UINT32)EventLogSize;
      EventData2->DeviceType = GetSpdmDeviceType (SpdmDeviceContext);

      EventData2->SubHeaderType   = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_CERT_CHAIN;
      EventData2->SubHeaderLength = sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN);
      EventData2->SubHeaderUID    = SpdmDeviceContext->DeviceUID;

      EventLogPtr = (VOID *)(EventData2 + 1);

      *(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
      EventLogPtr           += sizeof (UINT64);
      CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
      EventLogPtr += DevicePathSize;

      TcgSpdmCertChain               = (VOID *)EventLogPtr;
      TcgSpdmCertChain->SpdmVersion  = SpdmDeviceContext->SpdmVersion;
      TcgSpdmCertChain->SpdmSlotId   = SlotId;
      TcgSpdmCertChain->Reserved     = 0;
      TcgSpdmCertChain->SpdmHashAlgo = BaseHashAlgo;
      EventLogPtr                   += sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN);

      if (DeviceContextSize != 0) {
        DeviceContext = (VOID *)EventLogPtr;
        Status        = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
        if (Status != EFI_SUCCESS) {
          SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
          Status                             = EFI_DEVICE_ERROR;
          goto Exit;
        }
      }

      Status = TpmMeasureAndLogData (
                 TCG_NV_EXTEND_INDEX_FOR_INSTANCE,
                 EV_NO_ACTION,
                 EventLog,
                 EventLogSize,
                 EventLog,
                 EventLogSize
                 );
      if (EFI_ERROR (Status)) {
        SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
      }

      DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Instance) - %r\n", Status));

      goto Exit;
    case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG:
    case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_SPDM:
      EventLogSize = (UINT32)(sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT) +
                              sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
                              sizeof (UINT64) + DevicePathSize +
                              DeviceContextSize);
      EventLog = AllocatePool (EventLogSize);
      if (EventLog == NULL) {
        SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
        return EFI_OUT_OF_RESOURCES;
      }

      EventLogPtr = EventLog;

      NvIndexInstance = (VOID *)EventLogPtr;
      CopyMem (NvIndexInstance->Signature, TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE));
      NvIndexInstance->Version = TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_VERSION;
      ZeroMem (NvIndexInstance->Reserved, sizeof (NvIndexInstance->Reserved));
      EventLogPtr += sizeof (TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT);

      EventData2 = (VOID *)EventLogPtr;
      CopyMem (EventData2->Signature, TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2, sizeof (EventData2->Signature));
      EventData2->Version    = TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2;
      EventData2->AuthState  = AuthState;
      EventData2->Reserved   = 0;
      EventData2->Length     = (UINT32)EventLogSize;
      EventData2->DeviceType = GetSpdmDeviceType (SpdmDeviceContext);

      EventData2->SubHeaderType   = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_CERT_CHAIN;
      EventData2->SubHeaderLength = 0;
      EventData2->SubHeaderUID    = SpdmDeviceContext->DeviceUID;

      EventLogPtr = (VOID *)(EventData2 + 1);

      *(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
      EventLogPtr           += sizeof (UINT64);
      CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
      EventLogPtr += DevicePathSize;

      if (DeviceContextSize != 0) {
        DeviceContext = (VOID *)EventLogPtr;
        Status        = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
        if (Status != EFI_SUCCESS) {
          SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
          Status                             = EFI_DEVICE_ERROR;
          goto Exit;
        }
      }

      Status = TpmMeasureAndLogData (
                 TCG_NV_EXTEND_INDEX_FOR_INSTANCE,
                 EV_NO_ACTION,
                 EventLog,
                 EventLogSize,
                 EventLog,
                 EventLogSize
                 );
      if (EFI_ERROR (Status)) {
        SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
      }

      DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Instance) - %r\n", Status));

      goto Exit;
    default:
      SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED;
      return EFI_UNSUPPORTED;
  }

  if ((TrustAnchor != NULL) && (TrustAnchorSize != 0)) {
    SignatureDataSize = sizeof (EFI_GUID) + TrustAnchorSize;
    SignatureData     = AllocateZeroPool (SignatureDataSize);
    if (SignatureData == NULL) {
      ASSERT (SignatureData != NULL);
      SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
      Status                             = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    CopyGuid (&SignatureData->SignatureOwner, &gEfiCallerIdGuid);
    CopyMem (
      (UINT8 *)SignatureData + sizeof (EFI_GUID),
      TrustAnchor,
      TrustAnchorSize
      );

    MeasureVariable (
      PCR_INDEX_FOR_SIGNATURE_DB,
      EV_EFI_SPDM_DEVICE_AUTHORITY,
      EFI_DEVICE_SECURITY_DATABASE,
      &gEfiDeviceSignatureDatabaseGuid,
      SignatureData,
      SignatureDataSize
      );
    FreePool (SignatureData);
  }

Exit:
  if (EventLog != NULL) {
    FreePool (EventLog);
  }

  return Status;
}

/**
  Measure and log Auth state and Requester and responder Nonce into NV Index.

  @param[in]  SpdmDeviceContext        The SPDM context for the device.
  @param[in]  AuthState                The auth state of this deice.
  @param[in]  RequesterNonce           A buffer to hold the requester nonce (32 bytes), if not NULL.
  @param[in]  ResponderNonce           A buffer to hold the responder nonce (32 bytes), if not NULL.
  @param[out]  SecurityState           A pointer to the security state of the requester.

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  Out of memory.
  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.

**/
EFI_STATUS
ExtendAuthentication (
  IN  SPDM_DEVICE_CONTEXT          *SpdmDeviceContext,
  IN UINT8                         AuthState,
  IN UINT8                         *RequesterNonce,
  IN UINT8                         *ResponderNonce,
  OUT EDKII_DEVICE_SECURITY_STATE  *SecurityState
  )
{
  EFI_STATUS  Status;

  {
    TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE       DynamicEventLogSpdmChallengeEvent;
    TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE_AUTH  DynamicEventLogSpdmChallengeAuthEvent;

    CopyMem (DynamicEventLogSpdmChallengeEvent.Header.Signature, TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE));
    DynamicEventLogSpdmChallengeEvent.Header.Version = TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION;
    ZeroMem (DynamicEventLogSpdmChallengeEvent.Header.Reserved, sizeof (DynamicEventLogSpdmChallengeEvent.Header.Reserved));
    DynamicEventLogSpdmChallengeEvent.Header.Uid      = SpdmDeviceContext->DeviceUID;
    DynamicEventLogSpdmChallengeEvent.DescriptionSize = sizeof (TCG_SPDM_CHALLENGE_DESCRIPTION);
    CopyMem (DynamicEventLogSpdmChallengeEvent.Description, TCG_SPDM_CHALLENGE_DESCRIPTION, sizeof (TCG_SPDM_CHALLENGE_DESCRIPTION));
    DynamicEventLogSpdmChallengeEvent.DataSize = SPDM_NONCE_SIZE;
    CopyMem (DynamicEventLogSpdmChallengeEvent.Data, RequesterNonce, SPDM_NONCE_SIZE);

    Status = TpmMeasureAndLogData (
               TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,
               EV_NO_ACTION,
               &DynamicEventLogSpdmChallengeEvent,
               sizeof (DynamicEventLogSpdmChallengeEvent),
               &DynamicEventLogSpdmChallengeEvent,
               sizeof (DynamicEventLogSpdmChallengeEvent)
               );
    if (EFI_ERROR (Status)) {
      SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
    }

    DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));

    CopyMem (DynamicEventLogSpdmChallengeAuthEvent.Header.Signature, TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE));
    DynamicEventLogSpdmChallengeAuthEvent.Header.Version = TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION;
    ZeroMem (DynamicEventLogSpdmChallengeAuthEvent.Header.Reserved, sizeof (DynamicEventLogSpdmChallengeAuthEvent.Header.Reserved));
    DynamicEventLogSpdmChallengeAuthEvent.Header.Uid      = SpdmDeviceContext->DeviceUID;
    DynamicEventLogSpdmChallengeAuthEvent.DescriptionSize = sizeof (TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION);
    CopyMem (DynamicEventLogSpdmChallengeAuthEvent.Description, TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION, sizeof (TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION));
    DynamicEventLogSpdmChallengeAuthEvent.DataSize = SPDM_NONCE_SIZE;
    CopyMem (DynamicEventLogSpdmChallengeAuthEvent.Data, ResponderNonce, SPDM_NONCE_SIZE);

    Status = TpmMeasureAndLogData (
               TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,
               EV_NO_ACTION,
               &DynamicEventLogSpdmChallengeAuthEvent,
               sizeof (DynamicEventLogSpdmChallengeAuthEvent),
               &DynamicEventLogSpdmChallengeAuthEvent,
               sizeof (DynamicEventLogSpdmChallengeAuthEvent)
               );
    if (EFI_ERROR (Status)) {
      SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
    }

    DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));
  }

  return Status;
}

/**
  This function gets SPDM digest and certificates.

  @param[in]  SpdmDeviceContext           The SPDM context for the device.
  @param[out]  AuthState                  The auth state of the devices.
  @param[out]  ValidSlotId                The number of slot for the certificate chain.
  @param[out]  SecurityState              The security state of the requester.
  @param[out]  IsValidCertChain           The validity of the certificate chain.
  @param[out]  RootCertMatch              The authority of the certificate chain.

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  Out of memory.
  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.

**/
EFI_STATUS
EFIAPI
DoDeviceCertificate (
  IN  SPDM_DEVICE_CONTEXT          *SpdmDeviceContext,
  OUT UINT8                        *AuthState,
  OUT UINT8                        *ValidSlotId,
  OUT EDKII_DEVICE_SECURITY_STATE  *SecurityState,
  OUT BOOLEAN                      *IsValidCertChain,
  OUT BOOLEAN                      *RootCertMatch
  )
{
  EFI_STATUS           Status;
  SPDM_RETURN          SpdmReturn;
  VOID                 *SpdmContext;
  UINT32               CapabilityFlags;
  UINTN                DataSize;
  SPDM_DATA_PARAMETER  Parameter;
  UINT8                SlotMask;
  UINT8                TotalDigestBuffer[LIBSPDM_MAX_HASH_SIZE * SPDM_MAX_SLOT_COUNT];
  UINTN                CertChainSize;
  UINT8                CertChain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
  VOID                 *TrustAnchor;
  UINTN                TrustAnchorSize;
  UINT8                SlotId;

  SpdmContext = SpdmDeviceContext->SpdmContext;

  ZeroMem (&Parameter, sizeof (Parameter));
  Parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
  DataSize           = sizeof (CapabilityFlags);
  SpdmReturn         = SpdmGetData (SpdmContext, LIBSPDM_DATA_CAPABILITY_FLAGS, &Parameter, &CapabilityFlags, &DataSize);
  if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
    SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
    return EFI_DEVICE_ERROR;
  }

  *IsValidCertChain = FALSE;
  *RootCertMatch    = FALSE;
  CertChainSize     = sizeof (CertChain);
  ZeroMem (CertChain, sizeof (CertChain));
  TrustAnchor     = NULL;
  TrustAnchorSize = 0;

  //
  // Init *ValidSlotId to invalid slot_id
  //
  *ValidSlotId = SPDM_MAX_SLOT_COUNT;

  if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) {
    *AuthState                         = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG;
    SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES;
    Status                             = ExtendCertificate (SpdmDeviceContext, *AuthState, 0, NULL, NULL, 0, 0, SecurityState);
    return Status;
  } else {
    ZeroMem (TotalDigestBuffer, sizeof (TotalDigestBuffer));
    SpdmReturn = SpdmGetDigest (SpdmContext, NULL, &SlotMask, TotalDigestBuffer);
    if ((LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) || ((SlotMask & 0x01) == 0)) {
      *AuthState                         = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
      SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_CERTIFIACTE_FAILURE;
      SlotId                             = 0;
      Status                             = ExtendCertificate (SpdmDeviceContext, *AuthState, 0, NULL, NULL, 0, SlotId, SecurityState);
      return Status;
    }

    for (SlotId = 0; SlotId < SPDM_MAX_SLOT_COUNT; SlotId++) {
      if (((SlotMask >> SlotId) & 0x01) == 0) {
        continue;
      }

      CertChainSize = sizeof (CertChain);
      ZeroMem (CertChain, sizeof (CertChain));
      SpdmReturn = SpdmGetCertificateEx (SpdmContext, NULL, SlotId, &CertChainSize, CertChain, (CONST VOID **)&TrustAnchor, &TrustAnchorSize);
      if (LIBSPDM_STATUS_IS_SUCCESS (SpdmReturn)) {
        SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
        *AuthState                         = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
        *IsValidCertChain                  = TRUE;
        break;
      } else if (SpdmReturn == LIBSPDM_STATUS_VERIF_FAIL) {
        *IsValidCertChain                  = FALSE;
        *AuthState                         = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
        SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_CERTIFIACTE_FAILURE;
        Status                             = ExtendCertificate (SpdmDeviceContext, *AuthState, 0, NULL, NULL, 0, SlotId, SecurityState);
      } else if (SpdmReturn == LIBSPDM_STATUS_VERIF_NO_AUTHORITY) {
        *IsValidCertChain                  = TRUE;
        *AuthState                         = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_AUTH;
        SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_CERTIFIACTE_FAILURE;
        *ValidSlotId                       = SlotId;
      }
    }

    if ((SlotId >= SPDM_MAX_SLOT_COUNT) && (*ValidSlotId == SPDM_MAX_SLOT_COUNT)) {
      SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
      return EFI_DEVICE_ERROR;
    }

    if (TrustAnchor != NULL) {
      *RootCertMatch = TRUE;
      *ValidSlotId   = SlotId;
    } else {
      *ValidSlotId = 0;
    }

    DEBUG ((DEBUG_INFO, "SpdmGetCertificateEx - SpdmReturn %p, TrustAnchorSize 0x%x, RootCertMatch %d\n", SpdmReturn, TrustAnchorSize, *RootCertMatch));

    return EFI_SUCCESS;
  }
}

/**
  This function does authentication.

  @param[in]  SpdmDeviceContext           The SPDM context for the device.
  @param[out]  AuthState                  The auth state of the devices.
  @param[in]  ValidSlotId                 The number of slot for the certificate chain.
  @param[in]  IsValidCertChain            Indicate the validity of CertChain
  @param[in]  RootCertMatch               Indicate the match or mismatch for Rootcert
  @param[out]  SecurityState              The security state of the requester.

  @retval EFI_SUCCESS           Operation completed successfully.
  @retval EFI_OUT_OF_RESOURCES  Out of memory.
  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.

**/
EFI_STATUS
EFIAPI
DoDeviceAuthentication (
  IN  SPDM_DEVICE_CONTEXT          *SpdmDeviceContext,
  OUT UINT8                        *AuthState,
  IN  UINT8                        ValidSlotId,
  IN  BOOLEAN                      IsValidCertChain,
  IN  BOOLEAN                      RootCertMatch,
  OUT EDKII_DEVICE_SECURITY_STATE  *SecurityState
  )
{
  EFI_STATUS           Status;
  SPDM_RETURN          SpdmReturn;
  VOID                 *SpdmContext;
  UINT32               CapabilityFlags;
  UINTN                DataSize;
  SPDM_DATA_PARAMETER  Parameter;
  UINTN                CertChainSize;
  UINT8                CertChain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
  UINT8                RequesterNonce[SPDM_NONCE_SIZE];
  UINT8                ResponderNonce[SPDM_NONCE_SIZE];
  VOID                 *TrustAnchor;
  UINTN                TrustAnchorSize;
  BOOLEAN              IsValidChallengeAuthSig;

  SpdmContext = SpdmDeviceContext->SpdmContext;

  ZeroMem (&Parameter, sizeof (Parameter));
  Parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
  DataSize           = sizeof (CapabilityFlags);
  SpdmReturn         = SpdmGetData (SpdmContext, LIBSPDM_DATA_CAPABILITY_FLAGS, &Parameter, &CapabilityFlags, &DataSize);
  if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
    SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
    return EFI_DEVICE_ERROR;
  }

  IsValidChallengeAuthSig = FALSE;

  // get the valid CertChain
  CertChainSize = sizeof (CertChain);
  ZeroMem (CertChain, sizeof (CertChain));
  SpdmReturn = SpdmGetCertificateEx (SpdmContext, NULL, ValidSlotId, &CertChainSize, CertChain, (CONST VOID **)&TrustAnchor, &TrustAnchorSize);
  if ((!LIBSPDM_STATUS_IS_SUCCESS (SpdmReturn)) && (!(SpdmReturn == LIBSPDM_STATUS_VERIF_NO_AUTHORITY))) {
    return EFI_DEVICE_ERROR;
  }

  if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == 0) {
    *AuthState                         = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_BINDING;
    SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES;
    Status                             = ExtendCertificate (SpdmDeviceContext, *AuthState, CertChainSize, CertChain, NULL, 0, ValidSlotId, SecurityState);
    return Status;
  } else {
    ZeroMem (RequesterNonce, sizeof (RequesterNonce));
    ZeroMem (ResponderNonce, sizeof (ResponderNonce));
    SpdmReturn = SpdmChallengeEx (SpdmContext, NULL, ValidSlotId, SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, NULL, NULL, NULL, RequesterNonce, ResponderNonce, NULL, 0);
    if (SpdmReturn == LIBSPDM_STATUS_SUCCESS) {
      IsValidChallengeAuthSig = TRUE;
    } else if ((LIBSPDM_STATUS_IS_ERROR (SpdmReturn))) {
      IsValidChallengeAuthSig            = FALSE;
      *AuthState                         = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
      SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_CHALLENGE_FAILURE;
      Status                             = ExtendCertificate (SpdmDeviceContext, *AuthState, 0, NULL, NULL, 0, ValidSlotId, SecurityState);
      return Status;
    } else {
      return EFI_DEVICE_ERROR;
    }

    if (IsValidCertChain && IsValidChallengeAuthSig && !RootCertMatch) {
      *AuthState                         = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_AUTH;
      SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_NO_CERT_PROVISION;
      Status                             = ExtendCertificate (SpdmDeviceContext, *AuthState, CertChainSize, CertChain, NULL, 0, ValidSlotId, SecurityState);
    } else if (IsValidCertChain && IsValidChallengeAuthSig && RootCertMatch) {
      *AuthState                         = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
      SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
      Status                             = ExtendCertificate (SpdmDeviceContext, *AuthState, CertChainSize, CertChain, TrustAnchor, TrustAnchorSize, ValidSlotId, SecurityState);
    }

    Status = ExtendAuthentication (SpdmDeviceContext, *AuthState, RequesterNonce, ResponderNonce, SecurityState);
  }

  return Status;
}
