public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Wenxing Hou" <wenxing.hou@intel.com>
To: devel@edk2.groups.io
Cc: Jiewen Yao <jiewen.yao@intel.com>
Subject: [edk2-devel] [PATCH 6/9] SecurityPkg: add DeviceSecurity support
Date: Tue,  2 Apr 2024 10:31:22 +0800	[thread overview]
Message-ID: <20240402023125.4168-7-wenxing.hou@intel.com> (raw)
In-Reply-To: <20240402023125.4168-1-wenxing.hou@intel.com>

This patch implement the SpdmSecurityLib,
which is the core of DeviceSecurity.
And the SpdmSecurityLib include Device Authentication and Measurement.
The other library is to support SpdmSecurityLib.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 .../OsStub/CryptlibWrapper/CryptlibWrapper.c  | 970 ++++++++++++++++++
 .../CryptlibWrapper/CryptlibWrapper.inf       |  38 +
 .../OsStub/MemLibWrapper/MemLibWrapper.c      | 177 ++++
 .../OsStub/MemLibWrapper/MemLibWrapper.inf    |  33 +
 .../PlatformLibWrapper/PlatformLibWrapper.c   |  85 ++
 .../PlatformLibWrapper/PlatformLibWrapper.inf |  33 +
 .../SpdmLib/Include/Stub/SpdmLibStub.h        | 347 +++++++
 .../SpdmLib/Include/hal/LibspdmStdBoolAlt.h   |  23 +
 .../SpdmLib/Include/hal/LibspdmStdDefAlt.h    |  16 +
 .../SpdmLib/Include/hal/LibspdmStdIntAlt.h    |  25 +
 .../DeviceSecurity/SpdmLib/Include/hal/base.h |  94 ++
 .../SpdmLib/Include/hal/library/debuglib.h    |  39 +
 .../SpdmLib/Include/library/spdm_lib_config.h | 394 +++++++
 .../DeviceSecurity/SpdmLib/SpdmCommonLib.inf  |  47 +
 .../DeviceSecurity/SpdmLib/SpdmCryptLib.inf   |  45 +
 .../SpdmLib/SpdmDeviceSecretLibNull.inf       |  36 +
 .../SpdmLib/SpdmRequesterLib.inf              |  59 ++
 .../SpdmLib/SpdmResponderLib.inf              |  61 ++
 .../SpdmLib/SpdmSecuredMessageLib.inf         |  44 +
 .../SpdmLib/SpdmTransportMctpLib.inf          |  38 +
 .../SpdmLib/SpdmTransportPciDoeLib.inf        |  38 +
 .../SpdmSecurityLib/SpdmAuthentication.c      | 697 +++++++++++++
 .../SpdmSecurityLib/SpdmConnectionInit.c      | 481 +++++++++
 .../SpdmSecurityLib/SpdmMeasurement.c         | 714 +++++++++++++
 .../SpdmSecurityLib/SpdmSecurityLib.c         | 148 +++
 .../SpdmSecurityLib/SpdmSecurityLib.inf       |  54 +
 .../SpdmSecurityLib/SpdmSecurityLibInternal.h | 250 +++++
 SecurityPkg/Include/Library/SpdmSecurityLib.h | 437 ++++++++
 .../Include/Protocol/DeviceSecurityPolicy.h   | 133 +++
 SecurityPkg/SecurityPkg.ci.yaml               |  17 +-
 SecurityPkg/SecurityPkg.dec                   |  13 +-
 SecurityPkg/SecurityPkg.dsc                   |  31 +-
 32 files changed, 5611 insertions(+), 6 deletions(-)
 create mode 100644 SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.c
 create mode 100644 SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.inf
 create mode 100644 SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.c
 create mode 100644 SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf
 create mode 100644 SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.c
 create mode 100644 SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.inf
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/Stub/SpdmLibStub.h
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdBoolAlt.h
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdDefAlt.h
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdIntAlt.h
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/base.h
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/library/debuglib.h
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/Include/library/spdm_lib_config.h
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf
 create mode 100644 SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLibInternal.h
 create mode 100644 SecurityPkg/Include/Library/SpdmSecurityLib.h
 create mode 100644 SecurityPkg/Include/Protocol/DeviceSecurityPolicy.h

diff --git a/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.c b/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.c
new file mode 100644
index 0000000000..64db9750ff
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.c
@@ -0,0 +1,970 @@
+/** @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 <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include "hal/base.h"
+#include "hal/library/cryptlib.h"
+
+void *
+libspdm_sha256_new (
+  void
+  )
+{
+  size_t  CtxSize;
+  void    *HashCtx;
+
+  HashCtx = NULL;
+  CtxSize = Sha256GetContextSize ();
+  HashCtx = AllocatePool (CtxSize);
+
+  return HashCtx;
+}
+
+void
+libspdm_sha256_free (
+  void  *Sha256Ctx
+  )
+{
+  if (Sha256Ctx != NULL) {
+    FreePool (Sha256Ctx);
+    Sha256Ctx = NULL;
+  }
+}
+
+bool
+libspdm_sha256_init (
+  void  *Sha256Ctx
+  )
+{
+  return Sha256Init (Sha256Ctx);
+}
+
+bool
+libspdm_sha256_duplicate (
+  const void  *Sha256Context,
+  void        *NewSha256Context
+  )
+{
+  return Sha256Duplicate (Sha256Context, NewSha256Context);
+}
+
+bool
+libspdm_sha256_update (
+  void        *Sha256Context,
+  const void  *Data,
+  size_t      DataSize
+  )
+{
+  return Sha256Update (Sha256Context, Data, DataSize);
+}
+
+bool
+libspdm_sha256_final (
+  void     *sha256_context,
+  uint8_t  *hash_value
+  )
+{
+  return Sha256Final (sha256_context, hash_value);
+}
+
+bool
+libspdm_sha256_hash_all (
+  const void  *data,
+  size_t      data_size,
+  uint8_t     *hash_value
+  )
+{
+  return Sha256HashAll (data, data_size, hash_value);
+}
+
+void *
+libspdm_sha384_new (
+  void
+  )
+{
+  size_t  CtxSize;
+  void    *HashCtx;
+
+  HashCtx = NULL;
+  CtxSize = Sha384GetContextSize ();
+  HashCtx = AllocatePool (CtxSize);
+
+  return HashCtx;
+}
+
+void
+libspdm_sha384_free (
+  void  *Sha384Ctx
+  )
+{
+  if (Sha384Ctx != NULL) {
+    FreePool (Sha384Ctx);
+    Sha384Ctx = NULL;
+  }
+}
+
+bool
+libspdm_sha384_init (
+  void  *sha384_context
+  )
+{
+  return Sha384Init (sha384_context);
+}
+
+bool
+libspdm_sha384_duplicate (
+  const void  *sha384_context,
+  void        *new_sha384_context
+  )
+{
+  return Sha384Duplicate (sha384_context, new_sha384_context);
+}
+
+bool
+libspdm_sha384_update (
+  void        *sha384_context,
+  const void  *data,
+  size_t      data_size
+  )
+{
+  return Sha384Update (sha384_context, data, data_size);
+}
+
+bool
+libspdm_sha384_final (
+  void     *sha384_context,
+  uint8_t  *hash_value
+  )
+{
+  return Sha384Final (sha384_context, hash_value);
+}
+
+bool
+libspdm_sha384_hash_all (
+  const void  *data,
+  size_t      data_size,
+  uint8_t     *hash_value
+  )
+{
+  return Sha384HashAll (data, data_size, hash_value);
+}
+
+void *
+libspdm_hmac_sha256_new (
+  void
+  )
+{
+  return HmacSha256New ();
+}
+
+void
+libspdm_hmac_sha256_free (
+  void  *hmac_sha256_ctx
+  )
+{
+  HmacSha256Free (hmac_sha256_ctx);
+}
+
+bool
+libspdm_hmac_sha256_set_key (
+  void           *hmac_sha256_ctx,
+  const uint8_t  *key,
+  size_t         key_size
+  )
+{
+  return HmacSha256SetKey (hmac_sha256_ctx, key, key_size);
+}
+
+bool
+libspdm_hmac_sha256_duplicate (
+  const void  *hmac_sha256_ctx,
+  void        *new_hmac_sha256_ctx
+  )
+{
+  return HmacSha256Duplicate (hmac_sha256_ctx, new_hmac_sha256_ctx);
+}
+
+bool
+libspdm_hmac_sha256_update (
+  void        *hmac_sha256_ctx,
+  const void  *data,
+  size_t      data_size
+  )
+{
+  return HmacSha256Update (hmac_sha256_ctx, data, data_size);
+}
+
+bool
+libspdm_hmac_sha256_final (
+  void     *hmac_sha256_ctx,
+  uint8_t  *hmac_value
+  )
+{
+  return HmacSha256Final (hmac_sha256_ctx, hmac_value);
+}
+
+bool
+libspdm_hmac_sha256_all (
+  const void     *data,
+  size_t         data_size,
+  const uint8_t  *key,
+  size_t         key_size,
+  uint8_t        *hmac_value
+  )
+{
+  return HmacSha256All (data, data_size, key, key_size, hmac_value);
+}
+
+void *
+libspdm_hmac_sha384_new (
+  void
+  )
+{
+  return HmacSha384New ();
+}
+
+void
+libspdm_hmac_sha384_free (
+  void  *hmac_sha384_ctx
+  )
+{
+  HmacSha384Free (hmac_sha384_ctx);
+}
+
+bool
+libspdm_hmac_sha384_set_key (
+  void           *hmac_sha384_ctx,
+  const uint8_t  *key,
+  size_t         key_size
+  )
+{
+  return HmacSha384SetKey (hmac_sha384_ctx, key, key_size);
+}
+
+bool
+libspdm_hmac_sha384_duplicate (
+  const void  *hmac_sha384_ctx,
+  void        *new_hmac_sha384_ctx
+  )
+{
+  return HmacSha384Duplicate (hmac_sha384_ctx, new_hmac_sha384_ctx);
+}
+
+bool
+libspdm_hmac_sha384_update (
+  void        *hmac_sha384_ctx,
+  const void  *data,
+  size_t      data_size
+  )
+{
+  return HmacSha384Update (hmac_sha384_ctx, data, data_size);
+}
+
+bool
+libspdm_hmac_sha384_final (
+  void     *hmac_sha384_ctx,
+  uint8_t  *hmac_value
+  )
+{
+  return HmacSha384Final (hmac_sha384_ctx, hmac_value);
+}
+
+bool
+libspdm_hmac_sha384_all (
+  const void     *data,
+  size_t         data_size,
+  const uint8_t  *key,
+  size_t         key_size,
+  uint8_t        *hmac_value
+  )
+{
+  return HmacSha384All (data, data_size, key, key_size, hmac_value);
+}
+
+bool
+libspdm_aead_aes_gcm_encrypt (
+  const uint8_t  *key,
+  size_t         key_size,
+  const uint8_t  *iv,
+  size_t         iv_size,
+  const uint8_t  *a_data,
+  size_t         a_data_size,
+  const uint8_t  *data_in,
+  size_t         data_in_size,
+  uint8_t        *tag_out,
+  size_t         tag_size,
+  uint8_t        *data_out,
+  size_t         *data_out_size
+  )
+{
+  return AeadAesGcmEncrypt (
+           key,
+           key_size,
+           iv,
+           iv_size,
+           a_data,
+           a_data_size,
+           data_in,
+           data_in_size,
+           tag_out,
+           tag_size,
+           data_out,
+           data_out_size
+           );
+}
+
+bool
+libspdm_aead_aes_gcm_decrypt (
+  const uint8_t  *key,
+  size_t         key_size,
+  const uint8_t  *iv,
+  size_t         iv_size,
+  const uint8_t  *a_data,
+  size_t         a_data_size,
+  const uint8_t  *data_in,
+  size_t         data_in_size,
+  const uint8_t  *tag,
+  size_t         tag_size,
+  uint8_t        *data_out,
+  size_t         *data_out_size
+  )
+{
+  return AeadAesGcmDecrypt (
+           key,
+           key_size,
+           iv,
+           iv_size,
+           a_data,
+           a_data_size,
+           data_in,
+           data_in_size,
+           tag,
+           tag_size,
+           data_out,
+           data_out_size
+           );
+}
+
+void
+libspdm_rsa_free (
+  void  *rsa_context
+  )
+{
+  RsaFree (rsa_context);
+}
+
+bool
+libspdm_rsa_pkcs1_sign_with_nid (
+  void           *rsa_context,
+  size_t         hash_nid,
+  const uint8_t  *message_hash,
+  size_t         hash_size,
+  uint8_t        *signature,
+  size_t         *sig_size
+  )
+{
+  switch (hash_nid) {
+    case CRYPTO_NID_SHA256:
+      if (hash_size != SHA256_DIGEST_SIZE) {
+        return FALSE;
+      }
+
+      break;
+
+    case CRYPTO_NID_SHA384:
+      if (hash_size != SHA384_DIGEST_SIZE) {
+        return FALSE;
+      }
+
+      break;
+
+    case CRYPTO_NID_SHA512:
+      if (hash_size != SHA512_DIGEST_SIZE) {
+        return FALSE;
+      }
+
+      break;
+
+    default:
+      return FALSE;
+  }
+
+  return RsaPkcs1Sign (
+           rsa_context,
+           message_hash,
+           hash_size,
+           signature,
+           sig_size
+           );
+}
+
+bool
+libspdm_rsa_pkcs1_verify_with_nid (
+  void           *rsa_context,
+  size_t         hash_nid,
+  const uint8_t  *message_hash,
+  size_t         hash_size,
+  const uint8_t  *signature,
+  size_t         sig_size
+  )
+{
+  switch (hash_nid) {
+    case CRYPTO_NID_SHA256:
+      if (hash_size != SHA256_DIGEST_SIZE) {
+        return false;
+      }
+
+      break;
+
+    case CRYPTO_NID_SHA384:
+      if (hash_size != SHA384_DIGEST_SIZE) {
+        return false;
+      }
+
+      break;
+
+    case CRYPTO_NID_SHA512:
+      if (hash_size != SHA512_DIGEST_SIZE) {
+        return false;
+      }
+
+      break;
+
+    default:
+      return false;
+  }
+
+  return RsaPkcs1Verify (
+           rsa_context,
+           message_hash,
+           hash_size,
+           signature,
+           sig_size
+           );
+}
+
+bool
+libspdm_rsa_get_private_key_from_pem (
+  const uint8_t  *pem_data,
+  size_t         pem_size,
+  const char     *password,
+  void           **rsa_context
+  )
+{
+  return RsaGetPrivateKeyFromPem (pem_data, pem_size, password, rsa_context);
+}
+
+bool
+libspdm_rsa_get_public_key_from_x509 (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  void           **rsa_context
+  )
+{
+  return RsaGetPublicKeyFromX509 (cert, cert_size, rsa_context);
+}
+
+bool
+libspdm_ec_get_public_key_from_der (
+  const uint8_t  *der_data,
+  size_t         der_size,
+  void           **ec_context
+  )
+{
+  return false;
+}
+
+bool
+libspdm_rsa_get_public_key_from_der (
+  const uint8_t  *der_data,
+  size_t         der_size,
+  void           **rsa_context
+  )
+{
+  return false;
+}
+
+bool
+libspdm_ec_get_private_key_from_pem (
+  const uint8_t  *pem_data,
+  size_t         pem_size,
+  const char     *password,
+  void           **ec_context
+  )
+{
+  return EcGetPrivateKeyFromPem (pem_data, pem_size, password, ec_context);
+}
+
+bool
+libspdm_ec_get_public_key_from_x509 (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  void           **ec_context
+  )
+{
+  return EcGetPublicKeyFromX509 (cert, cert_size, ec_context);
+}
+
+bool
+libspdm_asn1_get_tag (
+  uint8_t        **ptr,
+  const uint8_t  *end,
+  size_t         *length,
+  uint32_t       tag
+  )
+{
+  return Asn1GetTag (ptr, end, length, tag);
+}
+
+bool
+libspdm_x509_get_subject_name (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  uint8_t        *cert_subject,
+  size_t         *subject_size
+  )
+{
+  return X509GetSubjectName (cert, cert_size, cert_subject, subject_size);
+}
+
+bool
+libspdm_x509_get_common_name (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  char           *common_name,
+  size_t         *common_name_size
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = X509GetCommonName (cert, cert_size, common_name, common_name_size);
+  if (EFI_ERROR (Status)) {
+    return false;
+  } else {
+    return true;
+  }
+}
+
+bool
+libspdm_x509_get_organization_name (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  char           *name_buffer,
+  size_t         *name_buffer_size
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = X509GetOrganizationName (cert, cert_size, name_buffer, name_buffer_size);
+  if (EFI_ERROR (Status)) {
+    return false;
+  } else {
+    return true;
+  }
+}
+
+bool
+libspdm_x509_get_version (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  size_t         *version
+  )
+{
+  return X509GetVersion (cert, cert_size, version);
+}
+
+bool
+libspdm_x509_get_serial_number (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  uint8_t        *serial_number,
+  size_t         *serial_number_size
+  )
+{
+  return X509GetSerialNumber (cert, cert_size, serial_number, serial_number_size);
+}
+
+bool
+libspdm_x509_get_issuer_name (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  uint8_t        *cert_issuer,
+  size_t         *issuer_size
+  )
+{
+  return X509GetIssuerName (cert, cert_size, cert_issuer, issuer_size);
+}
+
+bool
+libspdm_x509_get_signature_algorithm (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  uint8_t        *oid,
+  size_t         *oid_size
+  )
+{
+  return X509GetSignatureAlgorithm (cert, cert_size, oid, oid_size);
+}
+
+bool
+libspdm_x509_get_extension_data (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  const uint8_t  *oid,
+  size_t         oid_size,
+  uint8_t        *extension_data,
+  size_t         *extension_data_size
+  )
+{
+  return X509GetExtensionData (
+           cert,
+           cert_size,
+           oid,
+           oid_size,
+           extension_data,
+           extension_data_size
+           );
+}
+
+bool
+libspdm_x509_get_validity (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  uint8_t        *from,
+  size_t         *from_size,
+  uint8_t        *to,
+  size_t         *to_size
+  )
+{
+  return X509GetValidity (cert, cert_size, from, from_size, to, to_size);
+}
+
+bool
+libspdm_x509_set_date_time (
+  const char  *date_time_str,
+  void        *date_time,
+  size_t      *date_time_size
+  )
+{
+  return X509FormatDateTime (date_time_str, date_time, date_time_size);
+}
+
+int32_t
+libspdm_x509_compare_date_time (
+  const void  *date_time1,
+  const void  *date_time2
+  )
+{
+  return X509CompareDateTime (date_time1, date_time2);
+}
+
+bool
+libspdm_x509_get_key_usage (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  size_t         *usage
+  )
+{
+  return X509GetKeyUsage (cert, cert_size, usage);
+}
+
+bool
+libspdm_x509_get_extended_key_usage (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  uint8_t        *usage,
+  size_t         *usage_size
+  )
+{
+  return X509GetExtendedKeyUsage (cert, cert_size, usage, usage_size);
+}
+
+bool
+libspdm_x509_verify_cert (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  const uint8_t  *ca_cert,
+  size_t         ca_cert_size
+  )
+{
+  return X509VerifyCert (cert, cert_size, ca_cert, ca_cert_size);
+}
+
+bool
+libspdm_x509_verify_cert_chain (
+  const uint8_t  *root_cert,
+  size_t         root_cert_length,
+  const uint8_t  *cert_chain,
+  size_t         cert_chain_length
+  )
+{
+  return X509VerifyCertChain (root_cert, root_cert_length, cert_chain, cert_chain_length);
+}
+
+bool
+libspdm_x509_get_cert_from_cert_chain (
+  const uint8_t  *cert_chain,
+  size_t         cert_chain_length,
+  const int32_t  cert_index,
+  const uint8_t  **cert,
+  size_t         *cert_length
+  )
+{
+  return X509GetCertFromCertChain (
+           cert_chain,
+           cert_chain_length,
+           cert_index,
+           cert,
+           cert_length
+           );
+}
+
+bool
+libspdm_x509_construct_certificate (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  uint8_t        **single_x509_cert
+  )
+{
+  return X509ConstructCertificate (cert, cert_size, single_x509_cert);
+}
+
+bool
+libspdm_x509_get_extended_basic_constraints (
+  const uint8_t  *cert,
+  size_t         cert_size,
+  uint8_t        *basic_constraints,
+  size_t         *basic_constraints_size
+  )
+{
+  return X509GetExtendedBasicConstraints (
+           cert,
+           cert_size,
+           basic_constraints,
+           basic_constraints_size
+           );
+}
+
+void *
+libspdm_ec_new_by_nid (
+  size_t  nid
+  )
+{
+  return EcNewByNid (nid);
+}
+
+void
+libspdm_ec_free (
+  void  *ec_context
+  )
+{
+  EcFree (ec_context);
+}
+
+bool
+libspdm_ec_generate_key (
+  void     *ec_context,
+  uint8_t  *public_data,
+  size_t   *public_size
+  )
+{
+  return EcGenerateKey (ec_context, public_data, public_size);
+}
+
+bool
+libspdm_ec_compute_key (
+  void           *ec_context,
+  const uint8_t  *peer_public,
+  size_t         peer_public_size,
+  uint8_t        *key,
+  size_t         *key_size
+  )
+{
+  return EcDhComputeKey (ec_context, peer_public, peer_public_size, NULL, key, key_size);
+}
+
+bool
+libspdm_ecdsa_sign (
+  void           *ec_context,
+  size_t         hash_nid,
+  const uint8_t  *message_hash,
+  size_t         hash_size,
+  uint8_t        *signature,
+  size_t         *sig_size
+  )
+{
+  return EcDsaSign (
+           ec_context,
+           hash_nid,
+           message_hash,
+           hash_size,
+           signature,
+           sig_size
+           );
+}
+
+bool
+libspdm_ecdsa_verify (
+  void           *ec_context,
+  size_t         hash_nid,
+  const uint8_t  *message_hash,
+  size_t         hash_size,
+  const uint8_t  *signature,
+  size_t         sig_size
+  )
+{
+  return EcDsaVerify (
+           ec_context,
+           hash_nid,
+           message_hash,
+           hash_size,
+           signature,
+           sig_size
+           );
+}
+
+bool
+libspdm_random_bytes (
+  uint8_t  *output,
+  size_t   size
+  )
+{
+  return RandomBytes (output, size);
+}
+
+bool
+libspdm_hkdf_sha256_extract_and_expand (
+  const uint8_t  *key,
+  size_t         key_size,
+  const uint8_t  *salt,
+  size_t         salt_size,
+  const uint8_t  *info,
+  size_t         info_size,
+  uint8_t        *out,
+  size_t         out_size
+  )
+{
+  return HkdfSha256ExtractAndExpand (
+           key,
+           key_size,
+           salt,
+           salt_size,
+           info,
+           info_size,
+           out,
+           out_size
+           );
+}
+
+bool
+libspdm_hkdf_sha256_extract (
+  const uint8_t  *key,
+  size_t         key_size,
+  const uint8_t  *salt,
+  size_t         salt_size,
+  uint8_t        *prk_out,
+  size_t         prk_out_size
+  )
+{
+  return HkdfSha256Extract (
+           key,
+           key_size,
+           salt,
+           salt_size,
+           prk_out,
+           prk_out_size
+           );
+}
+
+bool
+libspdm_hkdf_sha256_expand (
+  const uint8_t  *prk,
+  size_t         prk_size,
+  const uint8_t  *info,
+  size_t         info_size,
+  uint8_t        *out,
+  size_t         out_size
+  )
+{
+  return HkdfSha256Expand (
+           prk,
+           prk_size,
+           info,
+           info_size,
+           out,
+           out_size
+           );
+}
+
+bool
+libspdm_hkdf_sha384_extract_and_expand (
+  const uint8_t  *key,
+  size_t         key_size,
+  const uint8_t  *salt,
+  size_t         salt_size,
+  const uint8_t  *info,
+  size_t         info_size,
+  uint8_t        *out,
+  size_t         out_size
+  )
+{
+  return HkdfSha384ExtractAndExpand (
+           key,
+           key_size,
+           salt,
+           salt_size,
+           info,
+           info_size,
+           out,
+           out_size
+           );
+}
+
+bool
+libspdm_hkdf_sha384_extract (
+  const uint8_t  *key,
+  size_t         key_size,
+  const uint8_t  *salt,
+  size_t         salt_size,
+  uint8_t        *prk_out,
+  size_t         prk_out_size
+  )
+{
+  return HkdfSha384Extract (
+           key,
+           key_size,
+           salt,
+           salt_size,
+           prk_out,
+           prk_out_size
+           );
+}
+
+bool
+libspdm_hkdf_sha384_expand (
+  const uint8_t  *prk,
+  size_t         prk_size,
+  const uint8_t  *info,
+  size_t         info_size,
+  uint8_t        *out,
+  size_t         out_size
+  )
+{
+  return HkdfSha384Expand (
+           prk,
+           prk_size,
+           info,
+           info_size,
+           out,
+           out_size
+           );
+}
diff --git a/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.inf b/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.inf
new file mode 100644
index 0000000000..0b64ab0f4f
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.inf
@@ -0,0 +1,38 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = CryptlibWrapper
+  FILE_GUID                      = 156C1B1B-6C2F-496a-496A-0548D1A9ED5B
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = CryptlibWrapper
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  CryptlibWrapper.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  MemoryAllocationLib
+  DebugLib
+  BaseCryptLib
+  RngLib
diff --git a/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.c b/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.c
new file mode 100644
index 0000000000..42eeecd68c
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.c
@@ -0,0 +1,177 @@
+/** @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 <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include "hal/base.h"
+#include "hal/library/memlib.h"
+
+/**
+ * Copies bytes from a source buffer to a destination buffer.
+ *
+ * This function copies "src_len" bytes from "src_buf" to "dst_buf".
+ *
+ * Asserts and returns a non-zero value if any of the following are true:
+ *   1) "src_buf" or "dst_buf" are NULL.
+ *   2) "src_len" or "dst_len" is greater than (SIZE_MAX >> 1).
+ *   3) "src_len" is greater than "dst_len".
+ *   4) "src_buf" and "dst_buf" overlap.
+ *
+ * If any of these cases fail, a non-zero value is returned. Additionally if
+ * "dst_buf" points to a non-NULL value and "dst_len" is valid, then "dst_len"
+ * bytes of "dst_buf" are zeroed.
+ *
+ * This function follows the C11 cppreference description of memcpy_s.
+ * https://en.cppreference.com/w/c/string/byte/memcpy
+ * The cppreferece description does NOT allow the source or destination
+ * buffers to be NULL.
+ *
+ * This function differs from the Microsoft and Safeclib memcpy_s implementations
+ * in that the Microsoft and Safeclib implementations allow for NULL source and
+ * destinations pointers when the number of bytes to copy (src_len) is zero.
+ *
+ * In addition the Microsoft and Safeclib memcpy_s functions return different
+ * negative values on error. For best support, clients should generally check
+ * against zero for success or failure.
+ *
+ * @param    dst_buf   Destination buffer to copy to.
+ * @param    dst_len   Maximum length in bytes of the destination buffer.
+ * @param    src_buf   Source buffer to copy from.
+ * @param    src_len   The number of bytes to copy from the source buffer.
+ *
+ * @return   0 on success. non-zero on error.
+ *
+ **/
+void
+libspdm_copy_mem (
+  void        *dst_buf,
+  size_t      dst_len,
+  const void  *src_buf,
+  size_t      src_len
+  )
+{
+  volatile uint8_t        *dst;
+  const volatile uint8_t  *src;
+
+  dst = (volatile uint8_t *)dst_buf;
+  src = (const volatile uint8_t *)src_buf;
+
+  /* Check for case where "dst" or "dst_len" may be invalid.
+   * Do not zero "dst" in this case. */
+  if ((dst == NULL) || (dst_len > (SIZE_MAX >> 1))) {
+    ASSERT (0);
+  }
+
+  /* Gaurd against invalid source. Zero "dst" in this case. */
+  if (src == NULL) {
+    ZeroMem (dst_buf, dst_len);
+    ASSERT (0);
+  }
+
+  /* Guard against overlap case. Zero "dst" in these cases. */
+  if (((src < dst) && (src + src_len > dst)) || ((dst < src) && (dst + src_len > src))) {
+    ZeroMem (dst_buf, dst_len);
+    ASSERT (0);
+  }
+
+  /* Guard against invalid lengths. Zero "dst" in these cases. */
+  if ((src_len > dst_len) ||
+      (src_len > (SIZE_MAX >> 1)))
+  {
+    ZeroMem (dst_buf, dst_len);
+    ASSERT (0);
+  }
+
+  while (src_len-- != 0) {
+    *(dst++) = *(src++);
+  }
+}
+
+/**
+ * Fills a target buffer with a byte value, and returns the target buffer.
+ *
+ * This function fills length bytes of buffer with value, and returns buffer.
+ *
+ * If length is greater than (MAX_ADDRESS - buffer + 1), then ASSERT().
+ *
+ * @param  buffer    The memory to set.
+ * @param  length    The number of bytes to set.
+ * @param  value     The value with which to fill length bytes of buffer.
+ *
+ * @return buffer.
+ *
+ **/
+void
+libspdm_set_mem (
+  void     *buffer,
+  size_t   length,
+  uint8_t  value
+  )
+{
+  SetMem (buffer, length, value);
+}
+
+/**
+ * Fills a target buffer with zeros, and returns the target buffer.
+ *
+ * This function fills length bytes of buffer with zeros, and returns buffer.
+ *
+ * If length > 0 and buffer is NULL, then ASSERT().
+ * If length is greater than (MAX_ADDRESS - buffer + 1), then ASSERT().
+ *
+ * @param  buffer      The pointer to the target buffer to fill with zeros.
+ * @param  length      The number of bytes in buffer to fill with zeros.
+ *
+ * @return buffer.
+ *
+ **/
+void
+libspdm_zero_mem (
+  void    *buffer,
+  size_t  length
+  )
+{
+  ZeroMem (buffer, length);
+}
+
+/**
+ * Compares the contents of two buffers in const time.
+ *
+ * This function compares length bytes of source_buffer to length bytes of destination_buffer.
+ * If all length bytes of the two buffers are identical, then 0 is returned.  Otherwise, the
+ * value returned is the first mismatched byte in source_buffer subtracted from the first
+ * mismatched byte in destination_buffer.
+ *
+ * If length > 0 and destination_buffer is NULL, then ASSERT().
+ * If length > 0 and source_buffer is NULL, then ASSERT().
+ * If length is greater than (MAX_ADDRESS - destination_buffer + 1), then ASSERT().
+ * If length is greater than (MAX_ADDRESS - source_buffer + 1), then ASSERT().
+ *
+ * @param  destination_buffer A pointer to the destination buffer to compare.
+ * @param  source_buffer      A pointer to the source buffer to compare.
+ * @param  length            The number of bytes to compare.
+ *
+ * @return 0                 All length bytes of the two buffers are identical.
+ * @retval Non-zero          There is mismatched between source_buffer and destination_buffer.
+ *
+ **/
+bool
+libspdm_consttime_is_mem_equal (
+  const void  *destination_buffer,
+  const void  *source_buffer,
+  size_t      length
+  )
+{
+  if (CompareMem (destination_buffer, source_buffer, length) == 0) {
+    return true;
+  } else {
+    return false;
+  }
+}
diff --git a/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf b/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf
new file mode 100644
index 0000000000..f5b92aae6b
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf
@@ -0,0 +1,33 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MemLibWrapper
+  FILE_GUID                      = d97bb726-6640-47dc-ae00-0cf2fbfb60f0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MemLibWrapper
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  MemLibWrapper.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
diff --git a/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.c b/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.c
new file mode 100644
index 0000000000..6e9256e6ea
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.c
@@ -0,0 +1,85 @@
+/** @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 <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include "hal/base.h"
+
+/**
+ * Suspends the execution of the current thread until the time-out interval elapses.
+ *
+ * @param milliseconds     The time interval for which execution is to be suspended, in milliseconds.
+ *
+ **/
+void
+libspdm_sleep (
+  uint64_t  milliseconds
+  )
+{
+  return;
+}
+
+/**
+ * Suspends the execution of the current thread until the time-out interval elapses.
+ *
+ * @param microseconds     The time interval for which execution is to be suspended, in milliseconds.
+ *
+ **/
+void
+libspdm_sleep_in_us (
+  uint64_t  microseconds
+  )
+{
+  return;
+}
+
+/**
+ * If no heartbeat arrives in seconds, the watchdog timeout event
+ * should terminate the session.
+ *
+ * @param  session_id     Indicate the SPDM session ID.
+ * @param  seconds        heartbeat period, in seconds.
+ *
+ **/
+bool
+libspdm_start_watchdog (
+  uint32_t  session_id,
+  uint16_t  seconds
+  )
+{
+  return true;
+}
+
+/**
+ * stop watchdog.
+ *
+ * @param  session_id     Indicate the SPDM session ID.
+ *
+ **/
+bool
+libspdm_stop_watchdog (
+  uint32_t  session_id
+  )
+{
+  return true;
+}
+
+/**
+ * Reset the watchdog in heartbeat response.
+ *
+ * @param  session_id     Indicate the SPDM session ID.
+ *
+ **/
+bool
+libspdm_reset_watchdog (
+  uint32_t  session_id
+  )
+{
+  return true;
+}
diff --git a/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.inf b/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.inf
new file mode 100644
index 0000000000..269b4bfbe1
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.inf
@@ -0,0 +1,33 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PlatformLibWrapper
+  FILE_GUID                      = 2f8979d1-f9f0-4d51-9cbd-4f41dee59057
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformLibWrapper
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  PlatformLibWrapper.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/Stub/SpdmLibStub.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/Stub/SpdmLibStub.h
new file mode 100644
index 0000000000..8ec6e61675
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/Stub/SpdmLibStub.h
@@ -0,0 +1,347 @@
+/** @file
+
+  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __LIBSPDM_STUB_H__
+#define __LIBSPDM_STUB_H__
+
+#include <library/spdm_common_lib.h>
+#include <library/spdm_return_status.h>
+#include <library/spdm_crypt_lib.h>
+#include <library/spdm_requester_lib.h>
+#include <library/spdm_responder_lib.h>
+#include <library/spdm_transport_pcidoe_lib.h>
+
+#pragma pack(1)
+
+/* The layout of SPDM_RETURN is
+ * [31:28] - Severity
+ * [27:24] - Reserved
+ * [23:16] - Source
+ * [15:00] - Code
+ */
+typedef UINT32 SPDM_RETURN;
+
+/*Interface of spdm.h*/
+/* SPDM message header*/
+typedef struct {
+  UINT8    SPDMVersion;
+  UINT8    RequestResponseCode;
+  UINT8    Param1;
+  UINT8    Param2;
+} SPDM_MESSAGE_HEADER;
+
+/* SPDM VERSION structure
+ * Bit[15:12] MajorVersion
+ * Bit[11:8]  MinorVersion
+ * Bit[7:4]   UpdateVersionNumber
+ * Bit[3:0]   Alpha*/
+typedef UINT16 SPDM_VERSION_NUMBER;
+
+typedef struct {
+  /* Total length of the certificate chain, in bytes,
+   * including all fields in this table.*/
+
+  UINT16    Length;
+  UINT16    Reserved;
+
+  /* digest of the Root Certificate.
+   * Note that Root Certificate is ASN.1 DER-encoded for this digest.
+   * The hash size is determined by the SPDM device.*/
+
+  /*UINT8    RootHash[HashSize];*/
+
+  /* One or more ASN.1 DER-encoded X509v3 certificates where the first certificate is signed by the Root
+   * Certificate or is the Root Certificate itself and each subsequent certificate is signed by the preceding
+   * certificate. The last certificate is the Leaf Certificate.*/
+
+  /*UINT8    Certificates[length - 4 - HashSize];*/
+} SPDM_CERT_CHAIN;
+
+/* SPDM MEASUREMENTS block common header */
+typedef struct {
+  UINT8     Index;
+  UINT8     MeasurementSpecification;
+  UINT16    MeasurementSize;
+  /*UINT8                Measurement[MeasurementSize];*/
+} SPDM_MEASUREMENT_BLOCK_COMMON_HEADER;
+
+/* SPDM MEASUREMENTS block DMTF header */
+typedef struct {
+  UINT8     DMTFSpecMeasurementValueType;
+  UINT16    DMTFSpecMeasurementValueSize;
+  /*UINT8                DMTFSpecMeasurementValue[DMTFSpecMeasurementValueSize];*/
+} SPDM_MEASUREMENT_BLOCK_DMTF_HEADER;
+
+typedef struct {
+  SPDM_MEASUREMENT_BLOCK_COMMON_HEADER    MeasurementBlockCommonHeader;
+  SPDM_MEASUREMENT_BLOCK_DMTF_HEADER      MeasurementBlockDmtfHeader;
+  /*UINT8                                 HashValue[HashSize];*/
+} SPDM_MEASUREMENT_BLOCK_DMTF;
+
+#define  SPDM_DATA_PARAMETER  libspdm_data_parameter_t
+
+typedef enum {
+  //
+  // SPDM parameter
+  //
+  SpdmDataSpdmVersion,
+  SpdmDataSecuredMessageVersion,
+  //
+  // SPDM capability
+  //
+  SpdmDataCapabilityFlags,
+  SpdmDataCapabilityCTExponent,
+  SpdmDataCapabilityRttUs,
+  SpdmDataCapabilityDataTransferSize,
+  SpdmDataCapabilityMaxSpdmMsgSize,
+  SpdmDataCapabilitySenderDataTransferSize,
+
+  //
+  // SPDM Algorithm setting
+  //
+  SpdmDataMeasurementSpec,
+  SpdmDataMeasurementHashAlgo,
+  SpdmDataBaseAsymAlgo,
+  SpdmDataBaseHashAlgo,
+  SpdmDataDHENameGroup,
+  SpdmDataAEADCipherSuite,
+  SpdmDataReqBaseAsymAlg,
+  SpdmDataKeySchedule,
+  SpdmDataOtherParamsSupport,
+  SpdmDataMelSpec,
+
+  //
+  // Connection State
+  //
+  SpdmDataConnectionState,
+  //
+  // ResponseState
+  //
+  SpdmDataResponseState,
+  //
+  // Certificate info
+  //
+  SpdmDataLocalPublicCertChain,
+  SpdmDataPeerPublicRootCert,
+  SpdmDataPeerPublicKey,
+  SpdmDataLocalPublicKey,
+  SpdmDataLocalSupportedSlotMask,
+  SpdmDataLocalKeyPairId,
+  SpdmDataLocalCertInfo,
+  SpdmDataLocalKeyUsageBitMask,
+
+  SpdmDataBasicMutAuthRequested,
+  SpdmDataMutAuthRequested,
+  SpdmDataHeartBeatPeriod,
+  //
+  // Negotiated result
+  //
+  SpdmDataPeerUsedCertChainBuffer,
+  SpdmDataPeerSlotMask,
+  SpdmDataPeerProvisionedSlotMask = SpdmDataPeerSlotMask,
+  SpdmDataPeerSupportedSlotMask,
+  SpdmDataPeerTotalDigestBuffer,
+  SpdmDataPeerKeyPairId,
+  SpdmDataPeerCertInfo,
+  SpdmDataPeerKeyUsageBitMask,
+
+  //
+  // Pre-shared Key Hint
+  // If PSK is present, then PSK_EXCHANGE is used.
+  // Otherwise, the KEY_EXCHANGE is used.
+  //
+  SpdmDataPskHint,
+  //
+  // SessionData
+  //
+  SpdmDataSessionUsePsk,
+  SpdmDataSessionMutAuthRequested,
+  SpdmDataSessionEndSessionAttributes,
+  SpdmDataSessionPolicy,
+
+  SpdmDataAppContextData,
+
+  SpdmDataHandleErrorReturnPolicy,
+
+  /* VCA cached for CACHE_CAP in 1.2 for transcript.*/
+  SpdmDataVcaCache,
+
+  /* if the context is for a requester. It only needs to be set in VCA cache.*/
+  SpdmDataIsRequester,
+
+  // If the Responder replies with a Busy `ERROR` response to a request
+  // then the Requester is free to retry sending the request.
+  // This value specifies the maximum number of times libspdm will retry
+  // sending the request before returning an error.
+  // If its value is 0 then libspdm will not send any retry requests.
+  SpdmDataRequestRetryTimes,
+
+  // If the Responder replies with a Busy `ERROR` response to a request
+  // then the Requester is free to retry sending the request.
+  // This value specifies the delay time in microseconds between each retry requests.
+  // If its value is 0 then libspdm will send retry request immediately.
+  SpdmDataRequestRetryDelayTime,
+
+  /* limit the number of DHE session and PSK session separately.*/
+  SpdmDataMaxDheSessionConut,
+  SpdmDataMaxPskSessionConut,
+
+  SpdmDataSessionSequenceNumberRspDir,
+  SpdmDataSessionSequenceNumberReqDir,
+  SpdmDataMaxSessionSequenceNumber,
+
+  /* For SPDM 1.0 and 1.1, allow signature verification in big, little, or both endians. */
+  SpdmDataSpdmVersion1011VerifySigatureEndian,
+
+  SpdmDataSequenceNumberEndian,
+  SpdmDataSessionSequenceNumberEndian,
+
+  SpdmDataMultiKeyConnReq,
+  SpdmDataMultiKeyConnRsp,
+  //
+  // MAX
+  //
+  SpdmDataMax,
+} SPDM_DATA_TYPE;
+
+typedef enum {
+  SpdmDataLocationLocal,
+  SpdmDataLocationConnection,
+  SpdmDataLocationSession,
+  SpdmDataLocationMax,
+} SPDM_DATA_LOCATION;
+
+typedef enum {
+  //
+  // Before GET_VERSION/VERSION
+  //
+  SpdmConnectionStateNotStarted,
+  //
+  // After GET_VERSION/VERSION
+  //
+  SpdmConnectionStateAfterVersion,
+  //
+  // After GET_CAPABILITIES/CAPABILITIES
+  //
+  SpdmConnectionStateAfterCapabilities,
+  //
+  // After NEGOTIATE_ALGORITHMS/ALGORITHMS
+  //
+  SpdmConnectionStateNegotiated,
+  //
+  // After GET_DIGESTS/DIGESTS
+  //
+  SpdmConnectionStateAfterDigests,
+  //
+  // After GET_CERTIFICATE/CERTIFICATE
+  //
+  SpdmConnectionStateAfterCertificate,
+  //
+  // After CHALLENGE/CHALLENGE_AUTH, and ENCAP CALLENGE/CHALLENG_AUTH if MUT_AUTH is enabled.
+  //
+  SpdmConnectionStateAuthenticated,
+  //
+  // MAX
+  //
+  SpdmConnectionStateMax,
+} SPDM_CONNECTION_STATE;
+
+typedef enum {
+  //
+  // Normal response.
+  //
+  SpdmResponseStateNormal,
+  //
+  // Other component is busy.
+  //
+  SpdmResponseStateBusy,
+ #if LIBSPDM_RESPOND_IF_READY_SUPPORT
+  //
+  // Hardware is not ready.
+  //
+  SpdmResponseStateNotReady,
+ #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
+  //
+  // Firmware Update is done. Need resync.
+  //
+  SpdmResponseStateNeedResync,
+  //
+  // Processing Encapsulated message.
+  //
+  SpdmResponseStateProcessingEncap,
+  //
+  // MAX
+  //
+  SpdmResponseStateMax,
+} SPDM_RESPONSE_STATE;
+
+/* DOE header*/
+
+typedef struct {
+  UINT16    VendorId;
+  UINT8     DataObjectType;
+  UINT8     Reserved;
+
+  /* length of the data object being transfered in number of DW, including the header (2 DW)
+   * It only includes bit[0~17], bit[18~31] are reserved.
+   * A value of 00000h indicate 2^18 DW == 2^20 byte.*/
+  UINT32    Length;
+  /*UINT32   DataObjectDw[Length];*/
+} PCI_DOE_DATA_OBJECT_HEADER;
+
+#pragma pack()
+
+/* FUNCTION */
+#define SpdmSetData                         libspdm_set_data
+#define SpdmGetData                         libspdm_get_data
+#define SpdmInitContext                     libspdm_init_context
+#define SpdmGetContextSize                  libspdm_get_context_size
+#define SpdmRegisterDeviceIoFunc            libspdm_register_device_io_func
+#define SpdmRegisterTransportLayerFunc      libspdm_register_transport_layer_func
+#define SpdmGetSizeofRequiredScratchBuffer  libspdm_get_sizeof_required_scratch_buffer
+#define SpdmRegisterDeviceBufferFunc        libspdm_register_device_buffer_func
+#define SpdmSetScratchBuffer                libspdm_set_scratch_buffer
+
+#define SpdmGetHashSize               libspdm_get_hash_size
+#define SpdmHashAll                   libspdm_hash_all
+#define SpdmGetMeasurementHashSize    libspdm_get_measurement_hash_size
+#define SpdmMeasurementHashAll        libspdm_measurement_hash_all
+#define SpdmHmacAll                   libspdm_hmac_all
+#define SpdmHkdfExpand                libspdm_hkdf_expand
+#define SpdmAsymFree                  libspdm_asym_free
+#define SpdmAsymGetPrivateKeyFromPem  libspdm_asym_get_private_key_from_pem
+#define SpdmAsymSign                  libspdm_asym_sign
+#define SpdmAsymSignHash              libspdm_asym_sign_hash
+
+#define SpdmInitConnection                libspdm_init_connection
+#define SpdmGetDigest                     libspdm_get_digest
+#define SpdmGetCertificate                libspdm_get_certificate
+#define SpdmGetCertificateEx              libspdm_get_certificate_ex
+#define SpdmChallenge                     libspdm_challenge
+#define SpdmChallengeEx                   libspdm_challenge_ex
+#define SpdmGetMeasurement                libspdm_get_measurement
+#define SpdmGetMeasurementEx              libspdm_get_measurement_ex
+#define SpdmStartSession                  libspdm_start_session
+#define SpdmStopSession                   libspdm_stop_session
+#define SpdmSendReceiveData               libspdm_send_receive_data
+#define SpdmRegisterGetResponseFunc       libspdm_register_get_response_func
+#define SpdmProcessRequest                libspdm_process_request
+#define SpdmBuildResponse                 libspdm_build_response
+#define SpdmGenerateErrorResponse         libspdm_generate_error_response
+#define SpdmTransportPciDoeEncodeMessage  libspdm_transport_pci_doe_encode_message
+#define SpdmTransportPciDoeDecodeMessage  libspdm_transport_pci_doe_decode_message
+
+#define SpdmMeasurementCollectionFunc         libspdm_measurement_collection
+#define SpdmRequesterDataSignFunc             libspdm_requester_data_sign
+#define SpdmResponderDataSignFunc             libspdm_responder_data_sign
+#define SpdmGenerateMeasurementSummaryHash    libspdm_generate_measurement_summary_hash
+#define SpdmPskMasterSecretHkdfExpandFunc     libspdm_psk_master_secret_hkdf_expand
+#define SpdmPskHandshakeSecretHkdfExpandFunc  libspdm_psk_handshake_secret_hkdf_expand
+#define SpdmMeasurementOpaqueData             libspdm_measurement_opaque_data
+#define SpdmChallengeOpaqueData               libspdm_challenge_opaque_data
+
+#endif
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdBoolAlt.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdBoolAlt.h
new file mode 100644
index 0000000000..08af7296d0
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdBoolAlt.h
@@ -0,0 +1,23 @@
+/** @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
+
+**/
+
+#ifndef LIBSPDM_STDBOOL_ALT_H
+#define LIBSPDM_STDBOOL_ALT_H
+
+typedef BOOLEAN bool;
+
+#ifndef true
+#define true  TRUE
+#endif
+
+#ifndef false
+#define false  FALSE
+#endif
+
+#endif /* LIBSPDM_STDBOOL_ALT */
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdDefAlt.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdDefAlt.h
new file mode 100644
index 0000000000..3b31c23722
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdDefAlt.h
@@ -0,0 +1,16 @@
+/** @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
+
+**/
+
+#ifndef LIBSPDM_STD_DEF_ALT_H
+#define LIBSPDM_STD_DEF_ALT_H
+
+typedef UINTN size_t;
+#define offsetof(type, member)  OFFSET_OF(type,member)
+
+#endif /* LIBSPDM_STDDEF_ALT */
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdIntAlt.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdIntAlt.h
new file mode 100644
index 0000000000..e63e17f8c6
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/LibspdmStdIntAlt.h
@@ -0,0 +1,25 @@
+/** @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
+
+**/
+
+#ifndef LIBSPDM_STD_INT_ALT_H
+#define LIBSPDM_STD_INT_ALT_H
+
+typedef UINT64  uint64_t;
+typedef INT64   int64_t;
+typedef UINT32  uint32_t;
+typedef INT32   int32_t;
+typedef UINT16  uint16_t;
+typedef INT16   int16_t;
+typedef UINT8   uint8_t;
+
+#ifndef SIZE_MAX
+#define SIZE_MAX  MAX_UINTN
+#endif
+
+#endif /* LIBSPDM_STDINT_ALT */
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/base.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/base.h
new file mode 100644
index 0000000000..09cef567c6
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/base.h
@@ -0,0 +1,94 @@
+/** @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
+
+**/
+
+#ifndef BASE_H
+#define BASE_H
+
+#define LIBSPDM_STDINT_ALT   "hal/LibspdmStdIntAlt.h"
+#define LIBSPDM_STDBOOL_ALT  "hal/LibspdmStdBoolAlt.h"
+#define LIBSPDM_STDDEF_ALT   "hal/LibspdmStdDefAlt.h"
+
+#ifndef LIBSPDM_STDINT_ALT
+
+  #include <stdint.h>
+
+/* LIBSPDM_OPENSSL_STDINT_WORKAROUND */
+
+/* This is a workaround for OpenSSL compilation problems when used with <stdint.h>
+ * on Windows platforms built with Visual Studio. Including <stdint.h> pulls in
+ * <vcruntime.h>, which causes the type size_t to be defined. The size_t type
+ * depends on if _WIN32 or _WIN64 is defined. The default if neither is defined
+ * is the 32-bit version of size_t. */
+
+/* Our OpenSSL compilation requires _WIN32 and _WIN64 to NOT be defined.
+ * This will force the <vcruntime.h> to use the wrong 32-bit definition of size_t
+ * if we are compiling as 64-bit. This 32-bit definition then does not agree with
+ * the 64-bit definition defined in libspdm and generates compile errors. */
+
+/* To workaround this issue, LIBSPDM_OPENSSL_STDINT_WORKAROUND was created
+ * that is only defined for compilation via tha makefile of the OpenSSL library
+ * portion of libspdm. */
+
+/* This will lead to _WIN32 and _WIN64 to be NOT defined when reaching the OpenSSL
+ * portions of a compilation unit (header files + c file), thus meeting the
+ * no Win32/Win64 requirement for OpenSSL, but will still be defined when compiling
+ * the <vcruntime.h> file in the compilation unit (and getting the right size_t). */
+
+/* In the future libspdm intends to use the Windows native compilation flags and defines,
+ * in place of the UEFI profile / personality. */
+
+  #ifdef LIBSPDM_OPENSSL_STDINT_WORKAROUND
+    #undef _WIN32
+    #undef _WIN64
+  #endif
+
+#else /* LIBSPDM_STDINT_ALT */
+  #include LIBSPDM_STDINT_ALT
+#endif /* LIBSPDM_STDINT_ALT */
+
+#ifndef LIBSPDM_STDBOOL_ALT
+  #include <stdbool.h>
+#else
+  #include LIBSPDM_STDBOOL_ALT
+#endif
+
+#ifndef LIBSPDM_STDDEF_ALT
+  #include <stddef.h>
+#else
+  #include LIBSPDM_STDDEF_ALT
+#endif
+
+/**
+ * Return the minimum of two operands.
+ *
+ * This macro returns the minimal of two operand specified by a and b.
+ * Both a and b must be the same numerical types, signed or unsigned.
+ *
+ * @param   a        The first operand with any numerical type.
+ * @param   b        The second operand. It should be the same any numerical type with a.
+ *
+ * @return  Minimum of two operands.
+ *
+ **/
+#define LIBSPDM_MIN(a, b)  (((a) < (b)) ? (a) : (b))
+
+/**
+ * Return the number of elements in an array.
+ *
+ * @param  array  An object of array type. Array is only used as an argument to
+ *               the sizeof operator, therefore Array is never evaluated. The
+ *               caller is responsible for ensuring that Array's type is not
+ *               incomplete; that is, Array must have known constant size.
+ *
+ * @return The number of elements in Array. The result has type size_t.
+ *
+ **/
+#define LIBSPDM_ARRAY_SIZE(array)  (sizeof(array) / sizeof((array)[0]))
+
+#endif /* BASE_H */
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/library/debuglib.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/library/debuglib.h
new file mode 100644
index 0000000000..9b31df4ad8
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/hal/library/debuglib.h
@@ -0,0 +1,39 @@
+/** @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
+
+**/
+
+/** @file
+  Provides services to print debug and assert messages to a debug output device.
+
+  The Debug library supports debug print and asserts based on a combination of macros and code.
+  The debug library can be turned on and off so that the debug code does not increase the size of an image.
+
+  Note that a reserved macro named MDEPKG_NDEBUG is introduced for the intention
+  of size reduction when compiler optimization is disabled. If MDEPKG_NDEBUG is
+  defined, then debug and assert related macros wrapped by it are the NULL implementations.
+**/
+
+#ifndef DEBUG_LIB_H
+#define DEBUG_LIB_H
+
+#include <Library/DebugLib.h>
+
+#define LIBSPDM_DEBUG_INFO     DEBUG_INFO
+#define LIBSPDM_DEBUG_VERBOSE  DEBUG_VERBOSE
+#define LIBSPDM_DEBUG_ERROR    DEBUG_ERROR
+
+#define LIBSPDM_DEBUG                DEBUG
+#define LIBSPDM_ASSERT               ASSERT
+#define LIBSPDM_ASSERT_RETURN_ERROR  ASSERT_RETURN_ERROR
+
+#define LIBSPDM_DEBUG_CODE_BEGIN  DEBUG_CODE_BEGIN
+#define LIBSPDM_DEBUG_CODE_END    DEBUG_CODE_END
+
+#define LIBSPDM_DEBUG_CODE  DEBUG_CODE
+
+#endif /* DEBUG_LIB_H */
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/Include/library/spdm_lib_config.h b/SecurityPkg/DeviceSecurity/SpdmLib/Include/library/spdm_lib_config.h
new file mode 100644
index 0000000000..51dfd3c8fc
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/Include/library/spdm_lib_config.h
@@ -0,0 +1,394 @@
+/** @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
+
+**/
+
+#ifndef SPDM_LIB_CONFIG_H
+#define SPDM_LIB_CONFIG_H
+
+/* Enables assertions and debug printing. When `LIBSPDM_DEBUG_ENABLE` is defined it overrides or
+ * sets the values of `LIBSPDM_DEBUG_PRINT_ENABLE`, `LIBSPDM_DEBUG_ASSERT_ENABLE`, and
+ * `LIBSPDM_BLOCK_ENABLE` to the value of `LIBSPDM_DEBUG_ENABLE`.
+ *
+ * Note that if this file is used with CMake and `DTARGET=Release` is defined, then all debugging
+ * is disabled.
+ */
+#ifndef LIBSPDM_DEBUG_ENABLE
+#define LIBSPDM_DEBUG_ENABLE  1
+#endif
+
+/* The SPDM specification allows a Responder to return up to 256 version entries in the `VERSION`
+ * response to the Requester, including duplicate entries. For a Requester this value specifies the
+ * maximum number of entries that libspdm will tolerate in a `VERSION` response before returning an
+ * error. A similiar macro, `SPDM_MAX_VERSION_COUNT`, exists for the Responder. However this macro
+ * is not meant to be configured by the integrator.
+ */
+#ifndef LIBSPDM_MAX_VERSION_COUNT
+#define LIBSPDM_MAX_VERSION_COUNT  5
+#endif
+
+/* This value specifies the maximum size, in bytes, of the `PSK_EXCHANGE.RequesterContext` and,
+ * if supported by the Responder, `PSK_EXCHANGE_RSP.ResponderContext` fields. The fields are
+ * typically random or monotonically increasing numbers.
+ */
+#ifndef LIBSPDM_PSK_CONTEXT_LENGTH
+#define LIBSPDM_PSK_CONTEXT_LENGTH  LIBSPDM_MAX_HASH_SIZE
+#endif
+/* This value specifies the maximum size, in bytes, of the `PSK_EXCHANGE.PSKHint` field.*/
+#ifndef LIBSPDM_PSK_MAX_HINT_LENGTH
+#define LIBSPDM_PSK_MAX_HINT_LENGTH  16
+#endif
+
+/* libspdm allows an integrator to specify multiple root certificates as trust anchors when
+ * verifying certificate chains from an endpoint. This value specifies the maximum number of root
+ * certificates that libspdm can support.
+ */
+#ifndef LIBSPDM_MAX_ROOT_CERT_SUPPORT
+#define LIBSPDM_MAX_ROOT_CERT_SUPPORT  10
+#endif
+
+/* If the Responder supports it a Requester is allowed to establish multiple secure sessions with
+ * the Responder. This value specifies the maximum number of sessions libspdm can support.
+ */
+#ifndef LIBSPDM_MAX_SESSION_COUNT
+#define LIBSPDM_MAX_SESSION_COUNT  4
+#endif
+
+/* This value specifies the maximum size, in bytes, of a certificate chain that can be stored in a
+ * libspdm context.
+ */
+#ifndef LIBSPDM_MAX_CERT_CHAIN_SIZE
+#define LIBSPDM_MAX_CERT_CHAIN_SIZE  0x1000
+#endif
+#ifndef LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE
+#define LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE  0x1000
+#endif
+
+/* Partial certificates can be retrieved from a Requester or Responder and through multiple messages
+ * the complete certificate chain can be constructed. This value specifies the maximum size,
+ * in bytes, of a partial certificate that can be sent or received.
+ */
+#ifndef LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
+#define LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN  1024
+#endif
+
+/* To ensure integrity in communication between the Requester and the Responder libspdm calculates
+ * cryptographic digests and signatures over multiple requests and responses. This value specifies
+ * whether libspdm will use a running calculation over the transcript, where requests and responses
+ * are discarded as they are cryptographically consumed, or whether libspdm will buffer the entire
+ * transcript before calculating the digest or signature.
+ */
+#ifndef LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
+#define LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT  0
+#endif
+
+/* Cryptography Configuration
+ * In each category, at least one should be selected.
+ * NOTE: Not all combination can be supported. E.g. Don't mix NIST algo with SMx.*/
+
+#ifndef LIBSPDM_RSA_SSA_2048_SUPPORT
+#define LIBSPDM_RSA_SSA_2048_SUPPORT  1
+#endif
+#ifndef LIBSPDM_RSA_SSA_3072_SUPPORT
+#define LIBSPDM_RSA_SSA_3072_SUPPORT  1
+#endif
+#ifndef LIBSPDM_RSA_SSA_4096_SUPPORT
+#define LIBSPDM_RSA_SSA_4096_SUPPORT  1
+#endif
+
+#ifndef LIBSPDM_RSA_PSS_2048_SUPPORT
+#define LIBSPDM_RSA_PSS_2048_SUPPORT  0
+#endif
+#ifndef LIBSPDM_RSA_PSS_3072_SUPPORT
+#define LIBSPDM_RSA_PSS_3072_SUPPORT  0
+#endif
+#ifndef LIBSPDM_RSA_PSS_4096_SUPPORT
+#define LIBSPDM_RSA_PSS_4096_SUPPORT  0
+#endif
+
+#ifndef LIBSPDM_ECDSA_P256_SUPPORT
+#define LIBSPDM_ECDSA_P256_SUPPORT  1
+#endif
+#ifndef LIBSPDM_ECDSA_P384_SUPPORT
+#define LIBSPDM_ECDSA_P384_SUPPORT  1
+#endif
+#ifndef LIBSPDM_ECDSA_P521_SUPPORT
+#define LIBSPDM_ECDSA_P521_SUPPORT  1
+#endif
+
+#ifndef LIBSPDM_SM2_DSA_P256_SUPPORT
+#define LIBSPDM_SM2_DSA_P256_SUPPORT  0
+#endif
+
+#ifndef LIBSPDM_EDDSA_ED25519_SUPPORT
+#define LIBSPDM_EDDSA_ED25519_SUPPORT  0
+#endif
+#ifndef LIBSPDM_EDDSA_ED448_SUPPORT
+#define LIBSPDM_EDDSA_ED448_SUPPORT  0
+#endif
+
+#ifndef LIBSPDM_FFDHE_2048_SUPPORT
+#define LIBSPDM_FFDHE_2048_SUPPORT  0
+#endif
+#ifndef LIBSPDM_FFDHE_3072_SUPPORT
+#define LIBSPDM_FFDHE_3072_SUPPORT  0
+#endif
+#ifndef LIBSPDM_FFDHE_4096_SUPPORT
+#define LIBSPDM_FFDHE_4096_SUPPORT  0
+#endif
+
+#ifndef LIBSPDM_ECDHE_P256_SUPPORT
+#define LIBSPDM_ECDHE_P256_SUPPORT  1
+#endif
+#ifndef LIBSPDM_ECDHE_P384_SUPPORT
+#define LIBSPDM_ECDHE_P384_SUPPORT  1
+#endif
+#ifndef LIBSPDM_ECDHE_P521_SUPPORT
+#define LIBSPDM_ECDHE_P521_SUPPORT  1
+#endif
+
+#ifndef LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT
+#define LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT  0
+#endif
+
+#ifndef LIBSPDM_AEAD_AES_128_GCM_SUPPORT
+#define LIBSPDM_AEAD_AES_128_GCM_SUPPORT  1
+#endif
+#ifndef LIBSPDM_AEAD_AES_256_GCM_SUPPORT
+#define LIBSPDM_AEAD_AES_256_GCM_SUPPORT  1
+#endif
+
+#ifndef LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT
+#define LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT  0
+#endif
+
+#ifndef LIBSPDM_AEAD_SM4_128_GCM_SUPPORT
+#define LIBSPDM_AEAD_SM4_128_GCM_SUPPORT  0
+#endif
+
+#ifndef LIBSPDM_SHA256_SUPPORT
+#define LIBSPDM_SHA256_SUPPORT  1
+#endif
+#ifndef LIBSPDM_SHA384_SUPPORT
+#define LIBSPDM_SHA384_SUPPORT  1
+#endif
+#ifndef LIBSPDM_SHA512_SUPPORT
+#define LIBSPDM_SHA512_SUPPORT  0
+#endif
+
+#ifndef LIBSPDM_SHA3_256_SUPPORT
+#define LIBSPDM_SHA3_256_SUPPORT  0
+#endif
+#ifndef LIBSPDM_SHA3_384_SUPPORT
+#define LIBSPDM_SHA3_384_SUPPORT  0
+#endif
+#ifndef LIBSPDM_SHA3_512_SUPPORT
+#define LIBSPDM_SHA3_512_SUPPORT  0
+#endif
+
+#ifndef LIBSPDM_SM3_256_SUPPORT
+#define LIBSPDM_SM3_256_SUPPORT  0
+#endif
+
+/* This can be set to 0 for the device which does not need X509 parser.*/
+#ifndef LIBSPDM_CERT_PARSE_SUPPORT
+#define LIBSPDM_CERT_PARSE_SUPPORT  1
+#endif
+
+/* Code space optimization for Optional request/response messages.*/
+
+/* Consumers of libspdm may wish to not fully implement all of the optional
+ * SPDM request/response messages. Therefore we have provided these
+ * SPDM_ENABLE_CAPABILITY_***_CAP compile time switches as an optimization
+ * disable the code (#if 0) related to said optional capability, thereby
+ * reducing the code space used in the image.*/
+
+/* A single switch may enable/disable a single capability or group of related
+ * capabilities.*/
+
+/* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP - Enable/Disable single CERT capability.
+ * LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP - Enable/Disable single CHAL capability.
+ * LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP - Enable/Disables multiple MEAS capabilities:
+ *                                  (MEAS_CAP_NO_SIG, MEAS_CAP_SIG, MEAS_FRESH_CAP)*/
+
+/* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP - Enable/Disable single Key Exchange capability.
+ * LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP - Enable/Disable PSK_EX and PSK_FINISH.*/
+
+/* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP - Enable/Disable mutual authentication.
+* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP    - Enable/Disable encapsulated message.*/
+
+/* LIBSPDM_ENABLE_CAPABILITY_CSR_CAP - Enable/Disable get csr capability.
+ * LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP - Enable/Disable set certificate capability. */
+
+#ifndef LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_CERT_CAP  1
+#endif
+#ifndef LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP  1
+#endif
+#ifndef LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP  1
+#endif
+
+#ifndef LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP  0
+#endif
+#ifndef LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_PSK_EX_CAP  0
+#endif
+
+#ifndef LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP  0
+#endif
+
+#ifndef LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP  0
+#endif
+
+#ifndef LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP  0
+#endif
+
+#ifndef LIBSPDM_ENABLE_CAPABILITY_CSR_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_CSR_CAP  0
+#endif
+
+#ifndef LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP  0
+#endif
+
+#ifndef LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
+#define LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP  0
+#endif
+
+/* If 1 then endpoint supports sending GET_CERTIFICATE and GET_DIGESTS requests.
+ * If enabled and endpoint is a Responder then LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
+ * must also be enabled.
+ */
+#ifndef LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT
+#define LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT  1
+#endif
+
+/* If 1 then endpoint supports sending CHALLENGE request.
+ * If enabled and endpoint is a Responder then LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
+ * must also be enabled.
+ */
+#ifndef LIBSPDM_SEND_CHALLENGE_SUPPORT
+#define LIBSPDM_SEND_CHALLENGE_SUPPORT  1
+#endif
+
+/* When LIBSPDM_RESPOND_IF_READY_SUPPORT is 0 then
+ *      - For a Requester, if the Responder sends a ResponseNotReady ERROR response then the error
+ *        is immediately returned to the Integrator. The Requester cannot send a RESPOND_IF_READY
+ *        request.
+ *      - For a Responder, it cannot send a RESPOND_IF_READY ERROR response and does not support
+ *        RESPOND_IF_READY.
+ * When LIBSPDM_RESPOND_IF_READY_SUPPORT is 1 then
+ *      - For a Requester, if the Responder sends a ResponseNotReady ERROR response then libspdm
+ *        waits an amount of time, as specified by the RDTExponent parameter, before sending
+ *        RESPOND_IF_READY.
+ *      - For a Responder, if its response state is NOT_READY then it will send a ResponseNotReady
+ *        ERROR response to the Requester, and will accept a subsequent RESPOND_IF_READY request.
+ */
+#ifndef LIBSPDM_RESPOND_IF_READY_SUPPORT
+#define LIBSPDM_RESPOND_IF_READY_SUPPORT  1
+#endif
+
+/*
+ * MinDataTransferSize = 42
+ *
+ * H = HashLen = HmacLen = [32, 64]
+ * S = SigLen = [64, 512]
+ * D = ExchangeDataLen = [64, 512]
+ * R = RequesterContextLen >= 32
+ * R = ResponderContextLen >= 0
+ * O = OpaqueDataLen <= 1024
+ *
+ * Max Chunk No = 1, if (message size <= 42)
+ * Max Chunk No = [(message size + 4) / 30] roundup, if (message size > 42)
+ *
+ * +==========================+==========================================+=========+
+ * |  Command                 |   Size                                   |MaxChunk |
+ * +==========================+==========================================+=========+
+ * | GET_VERSION              | 4                                        | 1       |
+ * | VERSION {1.0, 1.1, 1.2}  | 6 + 2 * 3 = 12                           | 1       |
+ * +--------------------------+------------------------------------------+---------+
+ * | GET_CAPABILITIES 1.2     | 20                                       | 1       |
+ * | CAPABILITIES 1.2         | 20                                       | 1       |
+ * +--------------------------+------------------------------------------+---------+
+ * | ERROR                    | 4                                        | 1       |
+ * | ERROR(ResponseTooLarge)  | 4 + 4 = 8                                | 1       |
+ * | ERROR(LargeResponse)     | 4 + 1 = 5                                | 1       |
+ * | ERROR(ResponseNotReady)  | 4 + 4 = 8                                | 1       |
+ * +--------------------------+------------------------------------------+---------+
+ * | CHUNK_SEND header        | 12 + L0 (0 or 4)                         | 1       |
+ * | CHUNK_RESPONSE header    | 12 + L0 (0 or 4)                         | 1       |
+ * +==========================+==========================================+=========+
+ * | NEGOTIATE_ALGORITHMS 1.2 | 32 + 4 * 4 = 48                          | 2       |
+ * | ALGORITHMS 1.2           | 36 + 4 * 4 = 52                          | 2       |
+ * +--------------------------+------------------------------------------+---------+
+ * | GET_DIGESTS 1.2          | 4                                        | 1       |
+ * | DIGESTS 1.2              | 4 + H * SlotNum = [36, 516]              | [1, 18] |
+ * +--------------------------+------------------------------------------+---------+
+ * | GET_CERTIFICATE 1.2      | 8                                        | 1       |
+ * | CERTIFICATE 1.2          | 8 + PortionLen                           | [1, ]   |
+ * +--------------------------+------------------------------------------+---------+
+ * | CHALLENGE 1.2            | 40                                       | 1       |
+ * | CHALLENGE_AUTH 1.2       | 38 + H * 2 + S [+ O] = [166, 678]        | [6, 23] |
+ * +--------------------------+------------------------------------------+---------+
+ * | GET_MEASUREMENTS 1.2     | 5 + Nonce (0 or 32)                      | 1       |
+ * | MEASUREMENTS 1.2         | 42 + MeasRecLen (+ S) [+ O] = [106, 554] | [4, 19] |
+ * +--------------------------+------------------------------------------+---------+
+ * | KEY_EXCHANGE 1.2         | 42 + D [+ O] = [106, 554]                | [4, 19] |
+ * | KEY_EXCHANGE_RSP 1.2     | 42 + D + H + S (+ H) [+ O] = [234, 1194] | [8, 40] |
+ * +--------------------------+------------------------------------------+---------+
+ * | FINISH 1.2               | 4 (+ S) + H = [100, 580]                 | [4, 20] |
+ * | FINISH_RSP 1.2           | 4 (+ H) = [36, 69]                       | [1, 3]  |
+ * +--------------------------+------------------------------------------+---------+
+ * | PSK_EXCHANGE 1.2         | 12 [+ PSKHint] + R [+ O] = 44            | 2       |
+ * | PSK_EXCHANGE_RSP 1.2     | 12 + R + H (+ H) [+ O] = [108, 172]      | [4, 6]  |
+ * +--------------------------+------------------------------------------+---------+
+ * | PSK_FINISH 1.2           | 4 + H = [36, 68]                         | [1, 3]  |
+ * | PSK_FINISH_RSP 1.2       | 4                                        | 1       |
+ * +--------------------------+------------------------------------------+---------+
+ * | GET_CSR 1.2              | 8 + RequesterInfoLen [+ O]               | [1, ]   |
+ * | CSR 1.2                  | 8 + CSRLength                            | [1, ]   |
+ * +--------------------------+------------------------------------------+---------+
+ * | SET_CERTIFICATE 1.2      | 4 + CertChainLen                         | [1, ]   |
+ * | SET_CERTIFICATE_RSP 1.2  | 4                                        | 1       |
+ * +==========================+==========================================+=========+
+ */
+
+/* Required sender/receive buffer in device io.
+ * NOTE: This is transport specific. Below configuration is just an example.
+ * +-------+--------+---------------------------+------+--+------+---+--------+-----+
+ * | TYPE  |TransHdr|      EncryptionHeader     |AppHdr|  |Random|MAC|AlignPad|FINAL|
+ * |       |        |SessionId|SeqNum|Len|AppLen|      |  |      |   |        |     |
+ * +-------+--------+---------------------------+------+  +------+---+--------+-----+
+ * | MCTP  |    1   |    4    |   2  | 2 |   2  |   1  |  |  32  | 12|   0    |  56 |
+ * |PCI_DOE|    8   |    4    |   0  | 2 |   2  |   0  |  |   0  | 12|   3    |  31 |
+ * +-------+--------+---------------------------+------+--+------+---+--------+-----+
+ */
+
+/* Enable message logging.
+ * See https://github.com/DMTF/libspdm/blob/main/doc/user_guide.md#message-logging
+ * for more information */
+#ifndef LIBSPDM_ENABLE_MSG_LOG
+#define LIBSPDM_ENABLE_MSG_LOG  1
+#endif
+
+/* Enable macro checking during compilation. */
+#ifndef LIBSPDM_CHECK_MACRO
+#define LIBSPDM_CHECK_MACRO  0
+#endif
+
+/* Enable checks to the SPDM context during runtime. */
+#ifndef LIBSPDM_CHECK_SPDM_CONTEXT
+#define LIBSPDM_CHECK_SPDM_CONTEXT  1
+#endif
+
+#endif /* SPDM_LIB_CONFIG_H */
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf
new file mode 100644
index 0000000000..a0c62bbad0
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf
@@ -0,0 +1,47 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SpdmCommonLib
+  FILE_GUID                      = 4D42800D-2197-46EC-8E04-6B41BFD60687
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SpdmCommonLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  libspdm/library/spdm_common_lib/libspdm_com_context_data.c
+  libspdm/library/spdm_common_lib/libspdm_com_context_data_session.c
+  libspdm/library/spdm_common_lib/libspdm_com_crypto_service.c
+  libspdm/library/spdm_common_lib/libspdm_com_crypto_service_session.c
+  libspdm/library/spdm_common_lib/libspdm_com_opaque_data.c
+  libspdm/library/spdm_common_lib/libspdm_com_support.c
+  libspdm/library/spdm_common_lib/libspdm_com_msg_log.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  BaseCryptLib
+  RngLib
+  SpdmCryptLib
+  SpdmDeviceSecretLib
+  MemLibWrapper
+  CryptlibWrapper
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf
new file mode 100644
index 0000000000..5e91968576
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf
@@ -0,0 +1,45 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SpdmCryptLib
+  FILE_GUID                      = 2FF3E7F6-D95A-48A2-B418-9B6D585C1D7E
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SpdmCryptLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  libspdm/library/spdm_crypt_lib/libspdm_crypt_aead.c
+  libspdm/library/spdm_crypt_lib/libspdm_crypt_asym.c
+  libspdm/library/spdm_crypt_lib/libspdm_crypt_cert.c
+  libspdm/library/spdm_crypt_lib/libspdm_crypt_dhe.c
+  libspdm/library/spdm_crypt_lib/libspdm_crypt_hash.c
+  libspdm/library/spdm_crypt_lib/libspdm_crypt_hkdf.c
+  libspdm/library/spdm_crypt_lib/libspdm_crypt_hmac.c
+  libspdm/library/spdm_crypt_lib/libspdm_crypt_rng.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  BaseCryptLib
+  RngLib
+  MemLibWrapper
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf
new file mode 100644
index 0000000000..47f9fe9fe5
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf
@@ -0,0 +1,36 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SpdmDeviceSecretLibNull
+  FILE_GUID                      = E2FFA5F9-CD19-4B63-AE3E-7EA288243EED
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SpdmDeviceSecretLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  libspdm/os_stub/spdm_device_secret_lib_null/lib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  MemLibWrapper
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf
new file mode 100644
index 0000000000..4fcefe32dc
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf
@@ -0,0 +1,59 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SpdmRequesterLib
+  FILE_GUID                      = 8B6024A3-270A-410F-91AB-9E99F05C2A58
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SpdmRequesterLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  libspdm/library/spdm_requester_lib/libspdm_req_challenge.c
+  libspdm/library/spdm_requester_lib/libspdm_req_common.c
+  libspdm/library/spdm_requester_lib/libspdm_req_communication.c
+  libspdm/library/spdm_requester_lib/libspdm_req_encap_certificate.c
+  libspdm/library/spdm_requester_lib/libspdm_req_encap_challenge_auth.c
+  libspdm/library/spdm_requester_lib/libspdm_req_encap_digests.c
+  libspdm/library/spdm_requester_lib/libspdm_req_encap_error.c
+  libspdm/library/spdm_requester_lib/libspdm_req_encap_key_update.c
+  libspdm/library/spdm_requester_lib/libspdm_req_encap_request.c
+  libspdm/library/spdm_requester_lib/libspdm_req_end_session.c
+  libspdm/library/spdm_requester_lib/libspdm_req_finish.c
+  libspdm/library/spdm_requester_lib/libspdm_req_get_capabilities.c
+  libspdm/library/spdm_requester_lib/libspdm_req_get_certificate.c
+  libspdm/library/spdm_requester_lib/libspdm_req_get_digests.c
+  libspdm/library/spdm_requester_lib/libspdm_req_get_measurements.c
+  libspdm/library/spdm_requester_lib/libspdm_req_get_version.c
+  libspdm/library/spdm_requester_lib/libspdm_req_handle_error_response.c
+  libspdm/library/spdm_requester_lib/libspdm_req_heartbeat.c
+  libspdm/library/spdm_requester_lib/libspdm_req_key_exchange.c
+  libspdm/library/spdm_requester_lib/libspdm_req_key_update.c
+  libspdm/library/spdm_requester_lib/libspdm_req_negotiate_algorithms.c
+  libspdm/library/spdm_requester_lib/libspdm_req_psk_exchange.c
+  libspdm/library/spdm_requester_lib/libspdm_req_psk_finish.c
+  libspdm/library/spdm_requester_lib/libspdm_req_send_receive.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  SpdmCommonLib
+  SpdmSecuredMessageLib
+  PlatformLibWrapper
+  MemLibWrapper
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf
new file mode 100644
index 0000000000..61528a80ab
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf
@@ -0,0 +1,61 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SpdmResponderLib
+  FILE_GUID                      = 9005B3A3-45F1-4DE9-93FF-2512D4B9CCFA
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SpdmResponderLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  libspdm/library/spdm_responder_lib/libspdm_rsp_algorithms.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_capabilities.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_certificate.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_challenge_auth.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_common.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_communication.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_digests.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_encap_challenge.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_encap_get_certificate.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_encap_get_digests.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_encap_key_update.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_encap_response.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_end_session.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_error.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_finish.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_handle_response_state.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_heartbeat.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_key_exchange.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_key_update.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_measurements.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_psk_exchange.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_psk_finish.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_receive_send.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_respond_if_ready.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_version.c
+  libspdm/library/spdm_responder_lib/libspdm_rsp_csr.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  SpdmCommonLib
+  SpdmSecuredMessageLib
+  PlatformLibWrapper
+  MemLibWrapper
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf
new file mode 100644
index 0000000000..062bf77158
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf
@@ -0,0 +1,44 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SpdmSecuredMessageLib
+  FILE_GUID                      = C5E91542-9B57-4BC4-988C-2DEB0B17D381
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SpdmSecuredMessageLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  libspdm/library/spdm_secured_message_lib/libspdm_secmes_context_data.c
+  libspdm/library/spdm_secured_message_lib/libspdm_secmes_encode_decode.c
+  libspdm/library/spdm_secured_message_lib/libspdm_secmes_encode_decode.c
+  libspdm/library/spdm_secured_message_lib/libspdm_secmes_key_exchange.c
+  libspdm/library/spdm_secured_message_lib/libspdm_secmes_session.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  BaseCryptLib
+  RngLib
+  SpdmCryptLib
+  SpdmDeviceSecretLib
+  MemLibWrapper
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf
new file mode 100644
index 0000000000..a597d35913
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf
@@ -0,0 +1,38 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SpdmTransportMctpLib
+  FILE_GUID                      = C6ED3DB8-852A-40A8-8099-9D87D93669C4
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SpdmTransportMctpLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  libspdm/library/spdm_transport_mctp_lib/libspdm_mctp_common.c
+  libspdm/library/spdm_transport_mctp_lib/libspdm_mctp_mctp.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  SpdmSecuredMessageLib
+  MemLibWrapper
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf
new file mode 100644
index 0000000000..a0f47d6c7d
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf
@@ -0,0 +1,38 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SpdmTransportPciDoeLib
+  FILE_GUID                      = 21094151-1A91-4261-8EB7-C94453491FF8
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SpdmTransportPciDoeLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  libspdm/library/spdm_transport_pcidoe_lib/libspdm_doe_common.c
+  libspdm/library/spdm_transport_pcidoe_lib/libspdm_doe_pcidoe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  SpdmSecuredMessageLib
+  MemLibWrapper
diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c
new file mode 100644
index 0000000000..86cf9b225c
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c
@@ -0,0 +1,697 @@
+/** @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 = SpdmDataLocationConnection;
+  DataSize           = sizeof (BaseHashAlgo);
+  Status             = SpdmGetData (SpdmContext, SpdmDataBaseHashAlgo, &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 = SpdmDataLocationConnection;
+  DataSize           = sizeof (CapabilityFlags);
+  SpdmReturn         = SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &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)) {
+        *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 = SpdmDataLocationConnection;
+  DataSize           = sizeof (CapabilityFlags);
+  SpdmReturn         = SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &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;
+}
diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c
new file mode 100644
index 0000000000..d61aa01698
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c
@@ -0,0 +1,481 @@
+/** @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"
+
+LIST_ENTRY  mSpdmDeviceContextList = INITIALIZE_LIST_HEAD_VARIABLE (mSpdmDeviceContextList);
+
+#define CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED      "Fail to get Spdm Uid"
+#define CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING  "The Signature database devdb is full"
+
+/**
+  record Spdm Io protocol into the context list.
+
+  @param[in]  SpdmDeviceContext      The SPDM context of the device.
+
+**/
+VOID
+RecordSpdmDeviceContextInList (
+  IN SPDM_DEVICE_CONTEXT  *SpdmDeviceContext
+  )
+{
+  SPDM_DEVICE_CONTEXT_INSTANCE  *NewSpdmDeviceContext;
+  LIST_ENTRY                    *SpdmDeviceContextList;
+
+  SpdmDeviceContextList = &mSpdmDeviceContextList;
+
+  NewSpdmDeviceContext = AllocateZeroPool (sizeof (*NewSpdmDeviceContext));
+  if (NewSpdmDeviceContext == NULL) {
+    ASSERT (NewSpdmDeviceContext != NULL);
+    return;
+  }
+
+  NewSpdmDeviceContext->Signature         = SPDM_DEVICE_CONTEXT_INSTANCE_SIGNATURE;
+  NewSpdmDeviceContext->SpdmDeviceContext = SpdmDeviceContext;
+
+  InsertTailList (SpdmDeviceContextList, &NewSpdmDeviceContext->Link);
+}
+
+/**
+  get Spdm Io protocol from Context list via spdm context.
+
+  @param[in]  SpdmContext        The SPDM context of the requester.
+
+  return a pointer to the Spdm Io protocol.
+
+**/
+VOID *
+EFIAPI
+GetSpdmIoProtocolViaSpdmContext (
+  IN VOID  *SpdmContext
+  )
+{
+  LIST_ENTRY                    *Link;
+  SPDM_DEVICE_CONTEXT_INSTANCE  *CurrentSpdmDeviceContext;
+  LIST_ENTRY                    *SpdmDeviceContextList;
+
+  SpdmDeviceContextList = &mSpdmDeviceContextList;
+
+  Link = GetFirstNode (SpdmDeviceContextList);
+  while (!IsNull (SpdmDeviceContextList, Link)) {
+    CurrentSpdmDeviceContext = SPDM_DEVICE_CONTEXT_INSTANCE_FROM_LINK (Link);
+
+    if (CurrentSpdmDeviceContext->SpdmDeviceContext->SpdmContext == SpdmContext) {
+      return CurrentSpdmDeviceContext->SpdmDeviceContext->SpdmIoProtocol;
+    }
+
+    Link = GetNextNode (SpdmDeviceContextList, Link);
+  }
+
+  return NULL;
+}
+
+/**
+  creates and returns Spdm Uid from the volatile variable.
+
+  @param[in]  SpdmUid        A pointer to Spdm Uid.
+
+  @retval EFI_SUCCESS           Operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
+
+**/
+EFI_STATUS
+GetSpdmUid (
+  UINT64  *SpdmUid
+  )
+{
+  EFI_STATUS  Status;
+  UINTN       VarSize;
+  UINT64      Uid;
+
+  VarSize = sizeof (*SpdmUid);
+  Status  = gRT->GetVariable (
+                   L"SpdmUid",
+                   &gEfiDeviceSecuritySpdmUidGuid,
+                   NULL,
+                   &VarSize,
+                   &Uid
+                   );
+  if (Status == EFI_NOT_FOUND) {
+    Uid = 0;
+  } else if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  *SpdmUid = Uid++;
+  Status   = gRT->SetVariable (
+                    L"SpdmUid",
+                    &gEfiDeviceSecuritySpdmUidGuid,
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                    sizeof (Uid),
+                    &Uid
+                    );
+
+  return Status;
+}
+
+/**
+  Record and log the connection failure string to PCR1.
+
+  @param[in]  FailureString     The failure string.
+  @param[in]  StringLen         The length of the string.
+
+  @retval EFI_SUCCESS           Operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES  Out of memory.
+  @retval EFI_DEVICE_ERROR      The operation was unsuccessful.
+
+**/
+EFI_STATUS
+RecordConnectionFailureStatus (
+  IN CHAR8   *FailureString,
+  IN UINT32  StringLen
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = TpmMeasureAndLogData (
+             1,
+             EV_PLATFORM_CONFIG_FLAGS,
+             FailureString,
+             StringLen,
+             FailureString,
+             StringLen
+             );
+  DEBUG ((DEBUG_INFO, "RecordConnectionFailureStatus  %r\n", Status));
+  return Status;
+}
+
+/**
+  This function creates the spdm device context and init connection to the
+  responder with the device info.
+
+  @param[in]  SpdmDeviceInfo        A pointer to device info.
+  @param[out] SecurityState         A pointer to the security state of the requester.
+
+  @return the spdm device conext after the init connection succeeds.
+
+**/
+SPDM_DEVICE_CONTEXT *
+EFIAPI
+CreateSpdmDeviceContext (
+  IN  EDKII_SPDM_DEVICE_INFO       *SpdmDeviceInfo,
+  OUT EDKII_DEVICE_SECURITY_STATE  *SecurityState
+  )
+{
+  SPDM_DEVICE_CONTEXT  *SpdmDeviceContext;
+  VOID                 *SpdmContext;
+  UINTN                SpdmContextSize;
+  VOID                 *ScratchBuffer;
+  UINTN                ScratchBufferSize;
+  EFI_STATUS           Status;
+  SPDM_RETURN          SpdmReturn;
+  EFI_SIGNATURE_LIST   *DbList;
+  EFI_SIGNATURE_DATA   *Cert;
+  UINTN                CertCount;
+  UINTN                Index;
+  UINTN                SiglistHeaderSize;
+  UINTN                DbSize;
+  VOID                 *Data;
+  UINTN                DataSize;
+  SPDM_DATA_PARAMETER  Parameter;
+  UINT8                Data8;
+  UINT16               Data16;
+  UINT32               Data32;
+  UINT8                AuthState;
+
+  SpdmDeviceContext = AllocateZeroPool (sizeof (*SpdmDeviceContext));
+  if (SpdmDeviceContext == NULL) {
+    ASSERT (SpdmDeviceContext != NULL);
+    return NULL;
+  }
+
+  SpdmDeviceContext->Signature = SPDM_DEVICE_CONTEXT_SIGNATURE;
+  CopyMem (&SpdmDeviceContext->DeviceId, SpdmDeviceInfo->DeviceId, sizeof (EDKII_DEVICE_IDENTIFIER));
+  SpdmDeviceContext->IsEmbeddedDevice = SpdmDeviceInfo->IsEmbeddedDevice;
+
+  SpdmContextSize = SpdmGetContextSize ();
+  SpdmContext     = AllocateZeroPool (SpdmContextSize);
+  if (SpdmContext == NULL) {
+    ASSERT (SpdmContext != NULL);
+    goto Error;
+  }
+
+  SpdmReturn = SpdmInitContext (SpdmContext);
+  if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+    goto Error;
+  }
+
+  SpdmRegisterDeviceIoFunc (
+    SpdmContext,
+    SpdmDeviceInfo->SendMessage,
+    SpdmDeviceInfo->ReceiveMessage
+    );
+  SpdmRegisterTransportLayerFunc (
+    SpdmContext,
+    SpdmDeviceInfo->MaxSpdmMsgSize,
+    SpdmDeviceInfo->TransportHeaderSize,
+    SpdmDeviceInfo->TransportTailSize,
+    SpdmDeviceInfo->TransportEncodeMessage,
+    SpdmDeviceInfo->TransportDecodeMessage
+    );
+
+  SpdmRegisterDeviceBufferFunc (
+    SpdmContext,
+    SpdmDeviceInfo->SenderBufferSize,
+    SpdmDeviceInfo->ReceiverBufferSize,
+    SpdmDeviceInfo->AcquireSenderBuffer,
+    SpdmDeviceInfo->ReleaseSenderBuffer,
+    SpdmDeviceInfo->AcquireReceiverBuffer,
+    SpdmDeviceInfo->ReleaseReceiverBuffer
+    );
+
+  ScratchBufferSize = SpdmGetSizeofRequiredScratchBuffer (SpdmContext);
+  ScratchBuffer     = AllocateZeroPool (ScratchBufferSize);
+  if (ScratchBuffer == NULL) {
+    ASSERT (ScratchBuffer != NULL);
+    goto Error;
+  }
+
+  SpdmSetScratchBuffer (SpdmContext, ScratchBuffer, ScratchBufferSize);
+
+  SpdmDeviceContext->SpdmContextSize   = SpdmContextSize;
+  SpdmDeviceContext->SpdmContext       = SpdmContext;
+  SpdmDeviceContext->ScratchBufferSize = ScratchBufferSize;
+  SpdmDeviceContext->ScratchBuffer     = ScratchBuffer;
+
+  Status = gBS->HandleProtocol (
+                  SpdmDeviceContext->DeviceId.DeviceHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **)&SpdmDeviceContext->DevicePath
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Locate - DevicePath - %r\n", Status));
+    goto Error;
+  }
+
+  Status = gBS->HandleProtocol (
+                  SpdmDeviceContext->DeviceId.DeviceHandle,
+                  &SpdmDeviceContext->DeviceId.DeviceType,
+                  (VOID **)&SpdmDeviceContext->DeviceIo
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Locate - DeviceIo - %r\n", Status));
+    // This is optional, only check known device type later.
+  }
+
+  if (SpdmDeviceInfo->SpdmIoProtocolGuid != NULL) {
+    Status = gBS->HandleProtocol (
+                    SpdmDeviceContext->DeviceId.DeviceHandle,
+                    SpdmDeviceInfo->SpdmIoProtocolGuid,
+                    (VOID **)&SpdmDeviceContext->SpdmIoProtocol
+                    );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "Locate - SpdmIoProtocol - %r\n", Status));
+      goto Error;
+    }
+  }
+
+  if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
+    if (SpdmDeviceContext->DeviceIo == NULL) {
+      DEBUG ((DEBUG_ERROR, "Locate - PciIo - %r\n", Status));
+      goto Error;
+    }
+  }
+
+  Status = GetSpdmUid (&SpdmDeviceContext->DeviceUID);
+  if (EFI_ERROR (Status)) {
+    Status = RecordConnectionFailureStatus (
+               CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED,
+               sizeof (CONNECTUIN_FAILURE_GET_SPDM_UID_FAILED)
+               );
+    if (EFI_ERROR (Status)) {
+      goto Error;
+    }
+
+    ASSERT (FALSE);
+    DEBUG ((DEBUG_ERROR, "Fail to get UID - %r\n", Status));
+    goto Error;
+  }
+
+  RecordSpdmDeviceContextInList (SpdmDeviceContext);
+
+  Status = GetVariable2 (
+             EFI_DEVICE_SECURITY_DATABASE,
+             &gEfiDeviceSignatureDatabaseGuid,
+             (VOID **)&SpdmDeviceContext->SignatureList,
+             &SpdmDeviceContext->SignatureListSize
+             );
+  if ((!EFI_ERROR (Status)) && (SpdmDeviceContext->SignatureList != NULL)) {
+    DbList = SpdmDeviceContext->SignatureList;
+    DbSize = SpdmDeviceContext->SignatureListSize;
+    while ((DbSize > 0) && (SpdmDeviceContext->SignatureListSize >= DbList->SignatureListSize)) {
+      if (DbList->SignatureListSize == 0) {
+        break;
+      }
+
+      if (  (!CompareGuid (&DbList->SignatureType, &gEfiCertX509Guid))
+         || (DbList->SignatureHeaderSize != 0)
+         || (DbList->SignatureSize < sizeof (EFI_SIGNATURE_DATA)))
+      {
+        DbSize -= DbList->SignatureListSize;
+        DbList  = (EFI_SIGNATURE_LIST *)((UINT8 *)DbList + DbList->SignatureListSize);
+        continue;
+      }
+
+      SiglistHeaderSize = sizeof (EFI_SIGNATURE_LIST) + DbList->SignatureHeaderSize;
+      Cert              = (EFI_SIGNATURE_DATA *)((UINT8 *)DbList + SiglistHeaderSize);
+      CertCount         = (DbList->SignatureListSize - SiglistHeaderSize) / DbList->SignatureSize;
+
+      for (Index = 0; Index < CertCount; Index++) {
+        Data     = Cert->SignatureData;
+        DataSize = DbList->SignatureSize - sizeof (EFI_GUID);
+
+        ZeroMem (&Parameter, sizeof (Parameter));
+        Parameter.location = SpdmDataLocationLocal;
+        SpdmReturn         = SpdmSetData (SpdmContext, SpdmDataPeerPublicRootCert, &Parameter, Data, DataSize);
+        if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+          if (SpdmReturn == LIBSPDM_STATUS_BUFFER_FULL) {
+            Status = RecordConnectionFailureStatus (
+                       CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING,
+                       sizeof (CONNECTUIN_FAILURE_STGNATURE_DB_FUL_STRING)
+                       );
+            if (EFI_ERROR (Status)) {
+              goto Error;
+            }
+
+            ASSERT (FALSE);
+          }
+
+          goto Error;
+        }
+
+        Cert = (EFI_SIGNATURE_DATA *)((UINT8 *)Cert + DbList->SignatureSize);
+      }
+
+      DbSize -= DbList->SignatureListSize;
+      DbList  = (EFI_SIGNATURE_LIST *)((UINT8 *)DbList + DbList->SignatureListSize);
+    }
+  }
+
+  Data8 = 0;
+  ZeroMem (&Parameter, sizeof (Parameter));
+  Parameter.location = SpdmDataLocationLocal;
+  SpdmReturn         = SpdmSetData (SpdmContext, SpdmDataCapabilityCTExponent, &Parameter, &Data8, sizeof (Data8));
+  if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+    ASSERT (FALSE);
+    goto Error;
+  }
+
+  Data32     = 0;
+  SpdmReturn = SpdmSetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &Data32, sizeof (Data32));
+  if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+    ASSERT (FALSE);
+    goto Error;
+  }
+
+  Data8      = SPDM_MEASUREMENT_SPECIFICATION_DMTF;
+  SpdmReturn = SpdmSetData (SpdmContext, SpdmDataMeasurementSpec, &Parameter, &Data8, sizeof (Data8));
+  if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+    ASSERT (FALSE);
+    goto Error;
+  }
+
+  if (SpdmDeviceInfo->BaseAsymAlgo != 0) {
+    Data32 = SpdmDeviceInfo->BaseAsymAlgo;
+  } else {
+    Data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 |
+             SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 |
+             SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 |
+             SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 |
+             SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 |
+             SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521;
+  }
+
+  SpdmReturn = SpdmSetData (SpdmContext, SpdmDataBaseAsymAlgo, &Parameter, &Data32, sizeof (Data32));
+  if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+    ASSERT (FALSE);
+    goto Error;
+  }
+
+  if (SpdmDeviceInfo->BaseHashAlgo != 0) {
+    Data32 = SpdmDeviceInfo->BaseHashAlgo;
+  } else {
+    Data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 |
+             SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 |
+             SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512;
+  }
+
+  SpdmReturn = SpdmSetData (SpdmContext, SpdmDataBaseHashAlgo, &Parameter, &Data32, sizeof (Data32));
+  if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+    ASSERT (FALSE);
+    goto Error;
+  }
+
+  SpdmReturn = SpdmInitConnection (SpdmContext, FALSE);
+  if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+    DEBUG ((DEBUG_ERROR, "SpdmInitConnection - %p\n", SpdmReturn));
+
+    AuthState                          = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_SPDM;
+    SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES;
+    Status                             = ExtendCertificate (SpdmDeviceContext, AuthState, 0, NULL, NULL, 0, 0, SecurityState);
+    if (Status != EFI_SUCCESS) {
+      DEBUG ((DEBUG_ERROR, "ExtendCertificate  AUTH_STATE_NO_SPDM failed\n"));
+    }
+
+    goto Error;
+  }
+
+  ZeroMem (&Parameter, sizeof (Parameter));
+  Parameter.location = SpdmDataLocationConnection;
+  DataSize           = sizeof (Data16);
+  SpdmReturn         = SpdmGetData (SpdmContext, SpdmDataSpdmVersion, &Parameter, &Data16, &DataSize);
+  if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+    DEBUG ((DEBUG_ERROR, "SpdmGetData - %p\n", SpdmReturn));
+    goto Error;
+  }
+
+  SpdmDeviceContext->SpdmVersion = (Data16 >> SPDM_VERSION_NUMBER_SHIFT_BIT);
+
+  return SpdmDeviceContext;
+Error:
+  DestroySpdmDeviceContext (SpdmDeviceContext);
+  return NULL;
+}
+
+/**
+  This function destories the spdm device context.
+
+  @param[in]  SpdmDeviceContext      A pointer to device info.
+
+**/
+VOID
+EFIAPI
+DestroySpdmDeviceContext (
+  IN SPDM_DEVICE_CONTEXT  *SpdmDeviceContext
+  )
+{
+  // need zero memory in case of secret in memory.
+  if (SpdmDeviceContext->SpdmContext != NULL) {
+    ZeroMem (SpdmDeviceContext->SpdmContext, SpdmDeviceContext->SpdmContextSize);
+    FreePool (SpdmDeviceContext->SpdmContext);
+  }
+
+  if (SpdmDeviceContext->ScratchBuffer != NULL) {
+    ZeroMem (SpdmDeviceContext->ScratchBuffer, SpdmDeviceContext->ScratchBufferSize);
+    FreePool (SpdmDeviceContext->ScratchBuffer);
+  }
+
+  if (SpdmDeviceContext->SignatureList != NULL) {
+    ZeroMem (SpdmDeviceContext->SignatureList, SpdmDeviceContext->SignatureListSize);
+    FreePool (SpdmDeviceContext->SignatureList);
+  }
+
+  FreePool (SpdmDeviceContext);
+}
diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c
new file mode 100644
index 0000000000..f94ec1e7bf
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c
@@ -0,0 +1,714 @@
+/** @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"
+
+/**
+  This function returns the SPDM device type for TCG SPDM event.
+
+  @param[in]  SpdmDeviceContext           The SPDM context for the device.
+
+  @return TCG SPDM device type
+**/
+UINT32
+EFIAPI
+GetSpdmDeviceType (
+  IN  SPDM_DEVICE_CONTEXT  *SpdmDeviceContext
+  )
+{
+  if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
+    return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_PCI;
+  }
+
+  if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypeUsbGuid)) {
+    return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_USB;
+  }
+
+  return TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_TYPE_NULL;
+}
+
+/**
+  This function returns the SPDM device measurement context size for TCG SPDM event.
+
+  @param[in]  SpdmDeviceContext          The SPDM context for the device.
+
+  @return TCG SPDM device measurement context size
+**/
+UINTN
+EFIAPI
+GetDeviceMeasurementContextSize (
+  IN  SPDM_DEVICE_CONTEXT  *SpdmDeviceContext
+  )
+{
+  if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
+    return sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT);
+  }
+
+  if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypeUsbGuid)) {
+    // TBD - usb context
+    return 0;
+  }
+
+  return 0;
+}
+
+/**
+  This function creates the SPDM PCI device measurement context for TCG SPDM event.
+
+  @param[in]       SpdmDeviceContext       The SPDM context for the device.
+  @param[in, out]  DeviceContext           The TCG SPDM PCI device measurement context.
+  @param[in]       DeviceContextSize       The size of TCG SPDM PCI device measurement context.
+
+  @retval EFI_SUCCESS      The TCG SPDM PCI device measurement context is returned.
+**/
+EFI_STATUS
+CreatePciDeviceMeasurementContext (
+  IN  SPDM_DEVICE_CONTEXT  *SpdmDeviceContext,
+  IN OUT VOID              *DeviceContext,
+  IN UINTN                 DeviceContextSize
+  )
+{
+  TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT  *PciContext;
+  PCI_TYPE00                                  PciData;
+  EFI_PCI_IO_PROTOCOL                         *PciIo;
+  EFI_STATUS                                  Status;
+
+  if (DeviceContextSize != sizeof (*PciContext)) {
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  PciIo  = SpdmDeviceContext->DeviceIo;
+  Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0, sizeof (PciData), &PciData);
+  ASSERT_EFI_ERROR (Status);
+
+  PciContext               = DeviceContext;
+  PciContext->Version      = TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT_VERSION;
+  PciContext->Length       = sizeof (*PciContext);
+  PciContext->VendorId     = PciData.Hdr.VendorId;
+  PciContext->DeviceId     = PciData.Hdr.DeviceId;
+  PciContext->RevisionID   = PciData.Hdr.RevisionID;
+  PciContext->ClassCode[0] = PciData.Hdr.ClassCode[0];
+  PciContext->ClassCode[1] = PciData.Hdr.ClassCode[1];
+  PciContext->ClassCode[2] = PciData.Hdr.ClassCode[2];
+  if ((PciData.Hdr.HeaderType & HEADER_LAYOUT_CODE) == HEADER_TYPE_DEVICE) {
+    PciContext->SubsystemVendorID = PciData.Device.SubsystemVendorID;
+    PciContext->SubsystemID       = PciData.Device.SubsystemID;
+  } else {
+    PciContext->SubsystemVendorID = 0;
+    PciContext->SubsystemID       = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function creates the SPDM device measurement context for TCG SPDM event.
+
+  @param[in]       SpdmDeviceContext       The SPDM context for the device.
+  @param[in, out]  DeviceContext           The TCG SPDM device measurement context.
+  @param[in]       DeviceContextSize       The size of TCG SPDM device measurement context.
+
+  @retval EFI_SUCCESS      The TCG SPDM device measurement context is returned.
+  @retval EFI_UNSUPPORTED  The TCG SPDM device measurement context is unsupported.
+**/
+EFI_STATUS
+EFIAPI
+CreateDeviceMeasurementContext (
+  IN  SPDM_DEVICE_CONTEXT  *SpdmDeviceContext,
+  IN OUT VOID              *DeviceContext,
+  IN UINTN                 DeviceContextSize
+  )
+{
+  if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid)) {
+    return CreatePciDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
+  }
+
+  if (CompareGuid (&SpdmDeviceContext->DeviceId.DeviceType, &gEdkiiDeviceIdentifierTypeUsbGuid)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  This function dumps data.
+
+  @param[in]  Data             A pointer to Data.
+  @param[in]  Size             The size of Data.
+
+**/
+VOID
+EFIAPI
+InternalDumpData (
+  CONST UINT8  *Data,
+  UINTN        Size
+  )
+{
+  UINTN  Index;
+
+  for (Index = 0; Index < Size; Index++) {
+    DEBUG ((DEBUG_INFO, "%02x ", (UINTN)Data[Index]));
+  }
+}
+
+/**
+  This function extend the PCI digest from the DvSec register.
+
+  @param[in]  SpdmDeviceContext       The SPDM context for the device.
+  @param[in]  AuthState               The auth state of the device.
+  @param[in]  MeasurementRecordLength The length of the SPDM measurement record
+  @param[in]  MeasurementRecord       The SPDM measurement record
+  @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            The Device Security state associated with the device.
+
+  @retval EFI_SUCCESS                 Operation completed successfully.
+  @retval EFI_OUT_OF_RESOURCES          Out of memory.
+  @retval EFI_DEVICE_ERROR              The operation was unsuccessful.
+
+**/
+EFI_STATUS
+ExtendMeasurement (
+  IN  SPDM_DEVICE_CONTEXT          *SpdmDeviceContext,
+  IN UINT8                         AuthState,
+  IN UINT32                        MeasurementRecordLength,
+  IN UINT8                         *MeasurementRecord,
+  IN UINT8                         *RequesterNonce,
+  IN UINT8                         *ResponderNonce,
+  OUT EDKII_DEVICE_SECURITY_STATE  *SecurityState
+  )
+{
+  UINT32  PcrIndex;
+  UINT32  EventType;
+  VOID    *EventLog;
+  UINT32  EventLogSize;
+  UINT8   *EventLogPtr;
+
+  TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2                            *EventData2;
+  TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK  *TcgSpdmMeasurementBlock;
+  VOID                                                              *DeviceContext;
+  UINTN                                                             DeviceContextSize;
+  EFI_STATUS                                                        Status;
+  SPDM_MEASUREMENT_BLOCK_COMMON_HEADER                              *SpdmMeasurementBlockCommonHeader;
+  SPDM_MEASUREMENT_BLOCK_DMTF_HEADER                                *SpdmMeasurementBlockDmtfHeader;
+  VOID                                                              *Digest;
+  UINTN                                                             DigestSize;
+  UINTN                                                             DevicePathSize;
+  UINT32                                                            MeasurementHashAlgo;
+  UINTN                                                             DataSize;
+  VOID                                                              *SpdmContext;
+  SPDM_DATA_PARAMETER                                               Parameter;
+
+  SpdmContext = SpdmDeviceContext->SpdmContext;
+
+  EventLog = NULL;
+  ZeroMem (&Parameter, sizeof (Parameter));
+  Parameter.location = SpdmDataLocationConnection;
+  DataSize           = sizeof (MeasurementHashAlgo);
+  Status             = SpdmGetData (SpdmContext, SpdmDataMeasurementHashAlgo, &Parameter, &MeasurementHashAlgo, &DataSize);
+  ASSERT_EFI_ERROR (Status);
+
+  if (MeasurementRecord != NULL) {
+    SpdmMeasurementBlockCommonHeader = (VOID *)MeasurementRecord;
+    SpdmMeasurementBlockDmtfHeader   = (VOID *)(SpdmMeasurementBlockCommonHeader + 1);
+    Digest                           = (SpdmMeasurementBlockDmtfHeader + 1);
+    DigestSize                       = MeasurementRecordLength - sizeof (SPDM_MEASUREMENT_BLOCK_DMTF);
+
+    DEBUG ((DEBUG_INFO, "SpdmMeasurementBlockCommonHeader\n"));
+    DEBUG ((DEBUG_INFO, "  Index                        - 0x%02x\n", SpdmMeasurementBlockCommonHeader->Index));
+    DEBUG ((DEBUG_INFO, "  MeasurementSpecification     - 0x%02x\n", SpdmMeasurementBlockCommonHeader->MeasurementSpecification));
+    DEBUG ((DEBUG_INFO, "  MeasurementSize              - 0x%04x\n", SpdmMeasurementBlockCommonHeader->MeasurementSize));
+    DEBUG ((DEBUG_INFO, "SpdmMeasurementBlockDmtfHeader\n"));
+    DEBUG ((DEBUG_INFO, "  DMTFSpecMeasurementValueType - 0x%02x\n", SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueType));
+    DEBUG ((DEBUG_INFO, "  DMTFSpecMeasurementValueSize - 0x%04x\n", SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueSize));
+    DEBUG ((DEBUG_INFO, "Measurement - "));
+    InternalDumpData (Digest, DigestSize);
+    DEBUG ((DEBUG_INFO, "\n"));
+    if (MeasurementRecordLength <= sizeof (SPDM_MEASUREMENT_BLOCK_COMMON_HEADER) + sizeof (SPDM_MEASUREMENT_BLOCK_DMTF_HEADER)) {
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
+      return EFI_SECURITY_VIOLATION;
+    }
+
+    if ((SpdmMeasurementBlockCommonHeader->MeasurementSpecification & SPDM_MEASUREMENT_SPECIFICATION_DMTF) == 0) {
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
+      return EFI_SECURITY_VIOLATION;
+    }
+
+    if (SpdmMeasurementBlockCommonHeader->MeasurementSize != MeasurementRecordLength - sizeof (SPDM_MEASUREMENT_BLOCK_COMMON_HEADER)) {
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
+      return EFI_SECURITY_VIOLATION;
+    }
+
+    if (SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueSize != SpdmMeasurementBlockCommonHeader->MeasurementSize - sizeof (SPDM_MEASUREMENT_BLOCK_DMTF_HEADER)) {
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
+      return EFI_SECURITY_VIOLATION;
+    }
+
+    //
+    // Use PCR 2 for Firmware Blob code.
+    //
+    switch (SpdmMeasurementBlockDmtfHeader->DMTFSpecMeasurementValueType & 0x7F) {
+      case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_IMMUTABLE_ROM:
+      case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MUTABLE_FIRMWARE:
+      case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_VERSION:
+      case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_SECURE_VERSION_NUMBER:
+        if (SpdmDeviceContext->IsEmbeddedDevice) {
+          PcrIndex = 0;
+        } else {
+          PcrIndex = 2;
+        }
+
+        EventType = EV_EFI_SPDM_FIRMWARE_BLOB;
+        break;
+      case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_HARDWARE_CONFIGURATION:
+      case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_FIRMWARE_CONFIGURATION:
+      case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_DEVICE_MODE:
+        if (SpdmDeviceContext->IsEmbeddedDevice) {
+          PcrIndex = 1;
+        } else {
+          PcrIndex = 3;
+        }
+
+        EventType = EV_EFI_SPDM_FIRMWARE_CONFIG;
+        break;
+      case SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MEASUREMENT_MANIFEST:
+      // skip manifest, because manifest doesn't belong to the EV_EFI_SPDM_FIRMWARE_BLOB and EV_EFI_SPDM_FIRMWARE_CONFIG
+      default:
+        return EFI_SUCCESS;
+    }
+  } else {
+    if (SpdmDeviceContext->IsEmbeddedDevice) {
+      PcrIndex = 0;
+    } else {
+      PcrIndex = 2;
+    }
+
+    EventType = EV_EFI_SPDM_FIRMWARE_BLOB;
+  }
+
+  DeviceContextSize = GetDeviceMeasurementContextSize (SpdmDeviceContext);
+  DevicePathSize    = GetDevicePathSize (SpdmDeviceContext->DevicePath);
+
+  switch (AuthState) {
+    case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS:
+      EventLogSize = (UINT32)(sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
+                              sizeof (UINT64) + DevicePathSize +
+                              sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK) +
+                              MeasurementRecordLength +
+                              DeviceContextSize);
+      EventLog = AllocatePool (EventLogSize);
+      if (EventLog == NULL) {
+        SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      EventLogPtr = EventLog;
+
+      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_MEASUREMENT_BLOCK;
+      EventData2->SubHeaderLength = sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK) + MeasurementRecordLength;
+      EventData2->SubHeaderUID    = SpdmDeviceContext->DeviceUID;
+
+      EventLogPtr = (VOID *)(EventData2 + 1);
+
+      *(UINT64 *)EventLogPtr = (UINT64)DevicePathSize;
+      EventLogPtr           += sizeof (UINT64);
+      CopyMem (EventLogPtr, SpdmDeviceContext->DevicePath, DevicePathSize);
+      EventLogPtr += DevicePathSize;
+
+      TcgSpdmMeasurementBlock                            = (VOID *)EventLogPtr;
+      TcgSpdmMeasurementBlock->SpdmVersion               = SpdmDeviceContext->SpdmVersion;
+      TcgSpdmMeasurementBlock->SpdmMeasurementBlockCount = 1;
+      TcgSpdmMeasurementBlock->Reserved                  = 0;
+      TcgSpdmMeasurementBlock->SpdmMeasurementHashAlgo   = MeasurementHashAlgo;
+      EventLogPtr                                       += sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK);
+
+      if ((MeasurementRecord != NULL) && (MeasurementRecordLength != 0)) {
+        CopyMem (EventLogPtr, MeasurementRecord, MeasurementRecordLength);
+        EventLogPtr += MeasurementRecordLength;
+      }
+
+      if (DeviceContextSize != 0) {
+        DeviceContext = (VOID *)EventLogPtr;
+        Status        = CreateDeviceMeasurementContext (SpdmDeviceContext, DeviceContext, DeviceContextSize);
+        if (Status != EFI_SUCCESS) {
+          SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
+          Status                          = EFI_DEVICE_ERROR;
+          goto Exit;
+        }
+      }
+
+      Status = TpmMeasureAndLogData (
+                 PcrIndex,
+                 EventType,
+                 EventLog,
+                 EventLogSize,
+                 EventLog,
+                 EventLogSize
+                 );
+      if (EFI_ERROR (Status)) {
+        SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
+      }
+
+      DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Measurement) - %r\n", Status));
+      break;
+    case TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID:
+      EventLogSize = (UINT32)(sizeof (TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2) +
+                              sizeof (UINT64) + DevicePathSize +
+                              DeviceContextSize);
+      EventLog = AllocatePool (EventLogSize);
+      if (EventLog == NULL) {
+        SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE;
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      EventLogPtr = EventLog;
+
+      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_MEASUREMENT_BLOCK;
+      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->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
+          Status                          = EFI_DEVICE_ERROR;
+          goto Exit;
+        }
+      }
+
+      Status = TpmMeasureAndLogData (
+                 PcrIndex,
+                 EventType,
+                 EventLog,
+                 EventLogSize,
+                 EventLog,
+                 EventLogSize
+                 );
+      if (EFI_ERROR (Status)) {
+        SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
+      }
+
+      DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Measurement) - %r\n", Status));
+      goto Exit;
+    default:
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED;
+      return EFI_UNSUPPORTED;
+  }
+
+  if (RequesterNonce != NULL) {
+    TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_GET_MEASUREMENTS  DynamicEventLogSpdmGetMeasurementsEvent;
+
+    CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Header.Signature, TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE));
+    DynamicEventLogSpdmGetMeasurementsEvent.Header.Version = TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION;
+    ZeroMem (DynamicEventLogSpdmGetMeasurementsEvent.Header.Reserved, sizeof (DynamicEventLogSpdmGetMeasurementsEvent.Header.Reserved));
+    DynamicEventLogSpdmGetMeasurementsEvent.Header.Uid      = SpdmDeviceContext->DeviceUID;
+    DynamicEventLogSpdmGetMeasurementsEvent.DescriptionSize = sizeof (TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION);
+    CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Description, TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION, sizeof (TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION));
+    DynamicEventLogSpdmGetMeasurementsEvent.DataSize = SPDM_NONCE_SIZE;
+    CopyMem (DynamicEventLogSpdmGetMeasurementsEvent.Data, RequesterNonce, SPDM_NONCE_SIZE);
+
+    Status = TpmMeasureAndLogData (
+               TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,
+               EV_NO_ACTION,
+               &DynamicEventLogSpdmGetMeasurementsEvent,
+               sizeof (DynamicEventLogSpdmGetMeasurementsEvent),
+               &DynamicEventLogSpdmGetMeasurementsEvent,
+               sizeof (DynamicEventLogSpdmGetMeasurementsEvent)
+               );
+    if (EFI_ERROR (Status)) {
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
+    }
+
+    DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));
+  }
+
+  if (ResponderNonce != NULL) {
+    TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_MEASUREMENTS  DynamicEventLogSpdmMeasurementsEvent;
+
+    CopyMem (DynamicEventLogSpdmMeasurementsEvent.Header.Signature, TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE, sizeof (TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE));
+    DynamicEventLogSpdmMeasurementsEvent.Header.Version = TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION;
+    ZeroMem (DynamicEventLogSpdmMeasurementsEvent.Header.Reserved, sizeof (DynamicEventLogSpdmMeasurementsEvent.Header.Reserved));
+    DynamicEventLogSpdmMeasurementsEvent.Header.Uid      = SpdmDeviceContext->DeviceUID;
+    DynamicEventLogSpdmMeasurementsEvent.DescriptionSize = sizeof (TCG_SPDM_MEASUREMENTS_DESCRIPTION);
+    CopyMem (DynamicEventLogSpdmMeasurementsEvent.Description, TCG_SPDM_MEASUREMENTS_DESCRIPTION, sizeof (TCG_SPDM_MEASUREMENTS_DESCRIPTION));
+    DynamicEventLogSpdmMeasurementsEvent.DataSize = SPDM_NONCE_SIZE;
+    CopyMem (DynamicEventLogSpdmMeasurementsEvent.Data, ResponderNonce, SPDM_NONCE_SIZE);
+
+    Status = TpmMeasureAndLogData (
+               TCG_NV_EXTEND_INDEX_FOR_DYNAMIC,
+               EV_NO_ACTION,
+               &DynamicEventLogSpdmMeasurementsEvent,
+               sizeof (DynamicEventLogSpdmMeasurementsEvent),
+               &DynamicEventLogSpdmMeasurementsEvent,
+               sizeof (DynamicEventLogSpdmMeasurementsEvent)
+               );
+    if (EFI_ERROR (Status)) {
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR;
+    }
+
+    DEBUG ((DEBUG_INFO, "TpmMeasureAndLogData (Dynamic) - %r\n", Status));
+  }
+
+Exit:
+  if (EventLog != NULL) {
+    FreePool (EventLog);
+  }
+
+  return Status;
+}
+
+/**
+  This function gets SPDM measurement and extend to TPM.
+
+  @param[in]  SpdmDeviceContext            The SPDM context for the device.
+  @param[in]  SlotId                       The number of slot id of the certificate.
+  @param[out] SecurityState                A poniter to 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
+DoDeviceMeasurement (
+  IN  SPDM_DEVICE_CONTEXT          *SpdmDeviceContext,
+  IN  UINT8                        SlotId,
+  OUT EDKII_DEVICE_SECURITY_STATE  *SecurityState
+  )
+{
+  EFI_STATUS                   Status;
+  SPDM_RETURN                  SpdmReturn;
+  VOID                         *SpdmContext;
+  UINT32                       CapabilityFlags;
+  UINTN                        DataSize;
+  SPDM_DATA_PARAMETER          Parameter;
+  UINT8                        NumberOfBlocks;
+  UINT32                       MeasurementRecordLength;
+  UINT8                        MeasurementRecord[LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE];
+  UINT8                        Index;
+  UINT8                        RequesterNonce[SPDM_NONCE_SIZE];
+  UINT8                        ResponderNonce[SPDM_NONCE_SIZE];
+  UINT8                        RequestAttribute;
+  UINT32                       MeasurementsBlockSize;
+  SPDM_MEASUREMENT_BLOCK_DMTF  *MeasurementBlock;
+  UINT8                        NumberOfBlock;
+  UINT8                        ReceivedNumberOfBlock;
+  UINT8                        AuthState;
+  UINT8                        ContentChanged;
+  UINT8                        ContentChangedCount;
+
+  SpdmContext = SpdmDeviceContext->SpdmContext;
+
+  ZeroMem (&Parameter, sizeof (Parameter));
+  Parameter.location = SpdmDataLocationConnection;
+  DataSize           = sizeof (CapabilityFlags);
+  SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize);
+
+  if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == 0) {
+    AuthState                       = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG;
+    Status                          = ExtendCertificate (SpdmDeviceContext, AuthState, 0, NULL, NULL, 0, 0, SecurityState);
+    SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES;
+    if (Status != EFI_SUCCESS) {
+      return Status;
+    } else {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  RequestAttribute  = 0;
+  RequestAttribute |= SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE;
+
+  MeasurementRecordLength = sizeof (MeasurementRecord);
+  ZeroMem (RequesterNonce, sizeof (RequesterNonce));
+  ZeroMem (ResponderNonce, sizeof (ResponderNonce));
+
+  //
+  // get all measurement once, with signature.
+  //
+  SpdmReturn = SpdmGetMeasurementEx (
+                 SpdmContext,
+                 NULL,
+                 RequestAttribute,
+                 SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_ALL_MEASUREMENTS,
+                 SlotId,
+                 NULL,
+                 &NumberOfBlocks,
+                 &MeasurementRecordLength,
+                 MeasurementRecord,
+                 NULL,
+                 RequesterNonce,
+                 ResponderNonce,
+                 NULL,
+                 0
+                 );
+  if (LIBSPDM_STATUS_IS_SUCCESS (SpdmReturn)) {
+    DEBUG ((DEBUG_INFO, "NumberOfBlocks %d\n", NumberOfBlocks));
+
+    MeasurementBlock = (VOID *)MeasurementRecord;
+    for (Index = 0; Index < NumberOfBlocks; Index++) {
+      MeasurementsBlockSize =
+        sizeof (SPDM_MEASUREMENT_BLOCK_DMTF) +
+        MeasurementBlock
+          ->MeasurementBlockDmtfHeader
+          .DMTFSpecMeasurementValueSize;
+
+      AuthState                       = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
+      if (Index == NumberOfBlocks - 1) {
+        Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementsBlockSize, (UINT8 *)MeasurementBlock, RequesterNonce, ResponderNonce, SecurityState);
+      } else {
+        Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementsBlockSize, (UINT8 *)MeasurementBlock, NULL, NULL, SecurityState);
+      }
+
+      MeasurementBlock = (VOID *)((size_t)MeasurementBlock + MeasurementsBlockSize);
+      if (Status != EFI_SUCCESS) {
+        return Status;
+      }
+    }
+  } else if (SpdmReturn == LIBSPDM_STATUS_VERIF_FAIL) {
+    AuthState                       = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
+    SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
+    Status                          = ExtendMeasurement (SpdmDeviceContext, AuthState, 0, NULL, NULL, NULL, SecurityState);
+    return Status;
+  } else {
+    ContentChangedCount = 0;
+ContentChangedFlag:
+    RequestAttribute      = 0;
+    ContentChanged        = SPDM_MEASUREMENTS_RESPONSE_CONTENT_NO_CHANGE_DETECTED;
+    ReceivedNumberOfBlock = 0;
+
+    //
+    // 1. Query the total number of measurements available.
+    //
+    SpdmReturn = SpdmGetMeasurement (
+                   SpdmContext,
+                   NULL,
+                   RequestAttribute,
+                   SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS,
+                   SlotId,
+                   NULL,
+                   &NumberOfBlocks,
+                   NULL,
+                   NULL
+                   );
+    if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
+      return EFI_DEVICE_ERROR;
+    }
+
+    DEBUG ((DEBUG_INFO, "NumberOfBlocks - 0x%x\n", NumberOfBlocks));
+
+    ReceivedNumberOfBlock = 0;
+    for (Index = 1; Index <= 0xFE; Index++) {
+      if (ReceivedNumberOfBlock == NumberOfBlocks) {
+        break;
+      }
+
+      DEBUG ((DEBUG_INFO, "Index - 0x%x\n", Index));
+      //
+      // 2. query measurement one by one
+      //    get signature in last message only.
+      //
+      if (ReceivedNumberOfBlock == NumberOfBlocks - 1) {
+        RequestAttribute |= SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE;
+      }
+
+      MeasurementRecordLength = sizeof (MeasurementRecord);
+      ZeroMem (RequesterNonce, sizeof (RequesterNonce));
+      ZeroMem (ResponderNonce, sizeof (ResponderNonce));
+      SpdmReturn = SpdmGetMeasurementEx (
+                     SpdmContext,
+                     NULL,
+                     RequestAttribute,
+                     Index,
+                     SlotId,
+                     &ContentChanged,
+                     &NumberOfBlock,
+                     &MeasurementRecordLength,
+                     MeasurementRecord,
+                     NULL,
+                     RequesterNonce,
+                     ResponderNonce,
+                     NULL,
+                     0
+                     );
+      if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) {
+        if (SpdmReturn == LIBSPDM_STATUS_VERIF_FAIL) {
+          AuthState                       = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
+          SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
+          Status                          = ExtendMeasurement (SpdmDeviceContext, AuthState, 0, NULL, NULL, NULL, SecurityState);
+          return Status;
+        } else {
+          continue;
+        }
+      }
+
+      if ((ReceivedNumberOfBlock == NumberOfBlocks - 1) &&
+          (ContentChanged == SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_DETECTED))
+      {
+        if (ContentChangedCount == 0) {
+          ContentChangedCount++;
+          goto ContentChangedFlag;
+        } else {
+          AuthState                       = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID;
+          SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR;
+          Status                          = ExtendMeasurement (SpdmDeviceContext, AuthState, 0, NULL, NULL, NULL, SecurityState);
+          return Status;
+        }
+      }
+
+      DEBUG ((DEBUG_INFO, "ExtendMeasurement...\n"));
+      AuthState                       = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_SUCCESS;
+      if (ReceivedNumberOfBlock == NumberOfBlocks - 1) {
+        Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementRecordLength, MeasurementRecord, RequesterNonce, ResponderNonce, SecurityState);
+      } else {
+        Status = ExtendMeasurement (SpdmDeviceContext, AuthState, MeasurementRecordLength, MeasurementRecord, NULL, ResponderNonce, SecurityState);
+      }
+
+      if (Status != EFI_SUCCESS) {
+        return Status;
+      }
+
+      ReceivedNumberOfBlock += 1;
+    }
+
+    if (ReceivedNumberOfBlock != NumberOfBlocks) {
+      SecurityState->MeasurementState = EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE;
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c
new file mode 100644
index 0000000000..a4e1f412ac
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.c
@@ -0,0 +1,148 @@
+/** @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"
+
+/**
+  Helper function to quickly determine whether device authentication boot is enabled.
+
+  @retval     TRUE    device authentication boot is verifiably enabled.
+  @retval     FALSE   device authentication boot is either disabled or an error prevented checking.
+
+**/
+BOOLEAN
+EFIAPI
+IsDeviceAuthBootEnabled (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       *DeviceAuthBootMode;
+
+  DeviceAuthBootMode = NULL;
+
+  Status = GetEfiGlobalVariable2 (EFI_DEVICE_AUTH_BOOT_MODE_NAME, (VOID **)&DeviceAuthBootMode, NULL);
+  //
+  // Skip verification if DeviceAuthBootMode variable doesn't exist.
+  //
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Cannot check DeviceAuthBootMode variable %r \n ", Status));
+    return FALSE;
+  }
+
+  //
+  // Skip verification if DeviceAuthBootMode is disabled but not AuditMode
+  //
+  if (*DeviceAuthBootMode == DEVICE_AUTH_BOOT_MODE_DISABLE) {
+    FreePool (DeviceAuthBootMode);
+    return FALSE;
+  } else {
+    FreePool (DeviceAuthBootMode);
+    return TRUE;
+  }
+}
+
+/**
+  The device driver uses this service to authenticate and measure an SPDM device.
+
+  @param[in]  SpdmDeviceInfo            The SPDM context for the device.
+  @param[in]  SecurityPolicy            The security policy of this device.
+  @param[out] SecurityState             A pointer to security state if this device.
+
+  @retval EFI_SUCCESS   The TCG SPDM device measurement context is returned.
+  @retval EFI_UNSUPPORTED  The TCG SPDM device measurement context is unsupported.
+
+**/
+EFI_STATUS
+EFIAPI
+SpdmDeviceAuthenticationAndMeasurement (
+  IN  EDKII_SPDM_DEVICE_INFO        *SpdmDeviceInfo,
+  IN  EDKII_DEVICE_SECURITY_POLICY  *SecurityPolicy,
+  OUT EDKII_DEVICE_SECURITY_STATE   *SecurityState
+  )
+{
+  EFI_STATUS           Status;
+  SPDM_DEVICE_CONTEXT  *SpdmDeviceContext;
+  UINT8                AuthState;
+  UINT8                SlotId;
+  BOOLEAN              IsValidCertChain;
+  BOOLEAN              RootCertMatch;
+
+  if ((PcdGet32 (PcdTcgPfpMeasurementRevision) < TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106) ||
+      (PcdGet8 (PcdEnableSpdmDeviceAuthenticaion) == 0))
+  {
+    return EFI_UNSUPPORTED;
+  }
+
+  SpdmDeviceContext = CreateSpdmDeviceContext (SpdmDeviceInfo, SecurityState);
+  if (SpdmDeviceContext == NULL) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status           = EFI_SUCCESS;
+  AuthState        = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS;
+  SlotId           = 0;
+  IsValidCertChain = FALSE;
+  RootCertMatch    = FALSE;
+
+  if (((SecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION_REQUIRED) != 0) ||
+      ((SecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_REQUIRED) != 0))
+  {
+    Status = DoDeviceCertificate (SpdmDeviceContext, &AuthState, &SlotId, SecurityState, &IsValidCertChain, &RootCertMatch);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "DoDeviceCertificate failed - %r\n", Status));
+      goto Ret;
+    } else if ((AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG) ||
+               (AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID))
+    {
+      goto Ret;
+    }
+  }
+
+  if (((SecurityPolicy->AuthenticationPolicy & EDKII_DEVICE_AUTHENTICATION_REQUIRED) != 0) && (IsDeviceAuthBootEnabled ())) {
+    Status = DoDeviceAuthentication (SpdmDeviceContext, &AuthState, SlotId, IsValidCertChain, RootCertMatch, SecurityState);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "DoDeviceAuthentication failed - %r\n", Status));
+      goto Ret;
+    } else if ((AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG) ||
+               (AuthState == TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID))
+    {
+      goto Ret;
+    }
+  }
+
+  if ((SecurityPolicy->MeasurementPolicy & EDKII_DEVICE_MEASUREMENT_REQUIRED) != 0) {
+    Status = DoDeviceMeasurement (SpdmDeviceContext, SlotId, SecurityState);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "DoDeviceMeasurement failed - %r\n", Status));
+    }
+  }
+
+Ret:
+  DestroySpdmDeviceContext (SpdmDeviceContext);
+
+  return Status;
+}
+
+/**
+  This function will get SpdmIoProtocol via Context.
+
+  @param[in]   SpdmContext   The SPDM context for the device.
+
+  return the pointer of Spdm Io protocol
+
+**/
+VOID *
+EFIAPI
+SpdmGetIoProtocolViaSpdmContext (
+  IN VOID  *SpdmContext
+  )
+{
+  return GetSpdmIoProtocolViaSpdmContext (SpdmContext);
+}
diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf
new file mode 100644
index 0000000000..838b115ab0
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf
@@ -0,0 +1,54 @@
+## @file
+#  SPDM library.
+#
+#  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = SpdmSecurityLib
+  FILE_GUID                      = 77D7770D-158E-4354-B813-B8792A0E982D
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SpdmSecurityLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 AARCH64
+#
+
+[Sources]
+  SpdmSecurityLibInternal.h
+  SpdmSecurityLib.c
+  SpdmConnectionInit.c
+  SpdmMeasurement.c
+  SpdmAuthentication.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  SecurityPkg/SecurityPkg.dec
+  CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  BaseCryptLib
+  RngLib
+  TpmMeasurementLib
+  SpdmRequesterLib
+  SpdmCommonLib
+
+[Guids]
+  gEfiDeviceSignatureDatabaseGuid         ## CONSUMES
+  gEfiCertX509Guid                        ## CONSUMES
+  gEfiDeviceSecuritySpdmUidGuid           ## PRODUCES AND CONSUMES
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision            ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthenticaion        ## CONSUMES
diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLibInternal.h b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLibInternal.h
new file mode 100644
index 0000000000..611274cb7d
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLibInternal.h
@@ -0,0 +1,250 @@
+/** @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
+
+**/
+
+#ifndef SPDM_SECURITY_LIB_INTERNAL_H_
+#define SPDM_SECURITY_LIB_INTERNAL_H_
+
+#include <Uefi.h>
+#include <hal/base.h>
+#include <Stub/SpdmLibStub.h>
+#include <industry_standard/spdm.h>
+#include <industry_standard/spdm_secured_message.h>
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Tpm20.h>
+#include <IndustryStandard/UefiTcgPlatform.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/TpmMeasurementLib.h>
+#include <Library/RngLib.h>
+#include <Library/BaseCryptLib.h>
+#include <library/spdm_requester_lib.h>
+
+#include <Guid/DeviceAuthentication.h>
+#include <Guid/ImageAuthentication.h>
+
+#include <Protocol/PciIo.h>
+#include <Library/SpdmSecurityLib.h>
+#include "library/spdm_crypt_lib.h"
+
+#define SPDM_DEVICE_CONTEXT_SIGNATURE  SIGNATURE_32 ('S', 'P', 'D', 'C')
+
+typedef struct {
+  UINT32                      Signature;
+  // UEFI Context
+  EDKII_DEVICE_IDENTIFIER     DeviceId;
+  BOOLEAN                     IsEmbeddedDevice;
+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
+  VOID                        *DeviceIo;
+  UINT64                      DeviceUID;
+  // SPDM Context
+  UINTN                       SpdmContextSize;
+  VOID                        *SpdmContext;
+  UINTN                       ScratchBufferSize;
+  VOID                        *ScratchBuffer;
+  UINT8                       SpdmVersion;
+  VOID                        *SpdmIoProtocol;
+  EFI_SIGNATURE_LIST          *SignatureList;
+  UINTN                       SignatureListSize;
+} SPDM_DEVICE_CONTEXT;
+
+typedef struct {
+  UINTN                  Signature;
+  LIST_ENTRY             Link;
+  SPDM_DEVICE_CONTEXT    *SpdmDeviceContext;
+} SPDM_DEVICE_CONTEXT_INSTANCE;
+
+#define SPDM_DEVICE_CONTEXT_INSTANCE_SIGNATURE  SIGNATURE_32 ('S', 'D', 'C', 'S')
+#define SPDM_DEVICE_CONTEXT_INSTANCE_FROM_LINK(a)  CR (a, SPDM_DEVICE_CONTEXT_INSTANCE, Link, SPDM_DEVICE_CONTEXT_INSTANCE_SIGNATURE)
+
+VOID *
+EFIAPI
+GetSpdmIoProtocolViaSpdmContext (
+  IN VOID  *SpdmContext
+  );
+
+/**
+  This function creates the spdm device context and init connection to the
+  responder with the device info.
+
+  @param[in]  SpdmDeviceInfo        A pointer to device info.
+  @param[out] SecurityState         A pointer to the security state of the requester.
+
+  @return the spdm device conext after the init connection succeeds.
+
+**/
+SPDM_DEVICE_CONTEXT *
+EFIAPI
+CreateSpdmDeviceContext (
+  IN  EDKII_SPDM_DEVICE_INFO       *SpdmDeviceInfo,
+  OUT EDKII_DEVICE_SECURITY_STATE  *SecurityState
+  );
+
+VOID
+EFIAPI
+DestroySpdmDeviceContext (
+  IN SPDM_DEVICE_CONTEXT  *SpdmDeviceContext
+  );
+
+/**
+  This function returns the SPDM device type for TCG SPDM event.
+
+  @param[in]  SpdmDeviceContext             The SPDM context for the device.
+
+  @return TCG SPDM device type
+**/
+UINT32
+EFIAPI
+GetSpdmDeviceType (
+  IN  SPDM_DEVICE_CONTEXT  *SpdmDeviceContext
+  );
+
+/**
+  This function returns the SPDM device measurement context size for TCG SPDM event.
+
+  @param[in]  SpdmDeviceContext             The SPDM context for the device.
+
+  @return TCG SPDM device measurement context size
+**/
+UINTN
+EFIAPI
+GetDeviceMeasurementContextSize (
+  IN  SPDM_DEVICE_CONTEXT  *SpdmDeviceContext
+  );
+
+/**
+  This function creates the SPDM device measurement context for TCG SPDM event.
+
+  @param[in]       SpdmDeviceContext       The SPDM context for the device.
+  @param[in, OUT]  DeviceContext           The TCG SPDM device measurement context.
+  @param[in]       DeviceContextSize       The size of TCG SPDM device measurement context.
+
+  @retval EFI_SUCCESS      The TCG SPDM device measurement context is returned.
+  @retval EFI_UNSUPPORTED  The TCG SPDM device measurement context is unsupported.
+**/
+EFI_STATUS
+EFIAPI
+CreateDeviceMeasurementContext (
+  IN  SPDM_DEVICE_CONTEXT  *SpdmDeviceContext,
+  IN OUT VOID              *DeviceContext,
+  IN UINTN                 DeviceContextSize
+  );
+
+/**
+  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
+  );
+
+/**
+  This function executes SPDM measurement and extend to TPM.
+
+  @param[in]  SpdmDeviceContext            The SPDM context for the device.
+**/
+EFI_STATUS
+EFIAPI
+DoDeviceMeasurement (
+  IN  SPDM_DEVICE_CONTEXT          *SpdmDeviceContext,
+  IN  UINT8                        SlotId,
+  OUT EDKII_DEVICE_SECURITY_STATE  *SecurityState
+  );
+
+/**
+  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
+  );
+
+/**
+  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[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
+  );
+
+/**
+ * This function dump raw data.
+ *
+ * @param  data  raw data
+ * @param  size  raw data size
+ **/
+VOID
+EFIAPI
+InternalDumpData (
+  CONST UINT8  *Data,
+  UINTN        Size
+  );
+
+#endif
diff --git a/SecurityPkg/Include/Library/SpdmSecurityLib.h b/SecurityPkg/Include/Library/SpdmSecurityLib.h
new file mode 100644
index 0000000000..96a7841381
--- /dev/null
+++ b/SecurityPkg/Include/Library/SpdmSecurityLib.h
@@ -0,0 +1,437 @@
+/** @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
+
+**/
+
+#ifndef SPDM_SECURITY_LIB_H_
+#define SPDM_SECURITY_LIB_H_
+
+#include <Protocol/DeviceSecurity.h>
+#include <Protocol/DeviceSecurityPolicy.h>
+
+/**
+ * Send an SPDM transport layer message to a device.
+ *
+ * The message is an SPDM message with transport layer wrapper,
+ * or a secured SPDM message with transport layer wrapper.
+ *
+ * For requester, the message is a transport layer SPDM request.
+ * For responder, the message is a transport layer SPDM response.
+ *
+ * @param  spdm_context                  A pointer to the SPDM context.
+ * @param  message_size                  size in bytes of the message data buffer.
+ * @param  message                      A pointer to a destination buffer to store the message.
+ *                                     The caller is responsible for having
+ *                                     either implicit or explicit ownership of the buffer.
+ *                                     The message pointer shall be inside of
+ *                                     [msg_buf_ptr, msg_buf_ptr + max_msg_size] from
+ *                                     acquired sender_buffer.
+ * @param  timeout                      The timeout, in 100ns units, to use for the execution
+ *                                     of the message. A timeout value of 0
+ *                                     means that this function will wait indefinitely for the
+ *                                     message to execute. If timeout is greater
+ *                                     than zero, then this function will return RETURN_TIMEOUT if the
+ *                                     time required to execute the message is greater
+ *                                     than timeout.
+ *
+ * @retval RETURN_SUCCESS               The SPDM message is sent successfully.
+ * @retval RETURN_DEVICE_ERROR          A device error occurs when the SPDM message is sent to the device.
+ * @retval RETURN_INVALID_PARAMETER     The message is NULL or the message_size is zero.
+ * @retval RETURN_TIMEOUT              A timeout occurred while waiting for the SPDM message
+ *                                     to execute.
+ **/
+typedef
+  SPDM_RETURN
+(*SPDM_DEVICE_SEND_MESSAGE_FUNC)(
+  IN VOID            *SpdmContext,
+  IN UINTN           MessageSize,
+  IN OUT CONST VOID  *Message,
+  IN UINT64          Timeout
+  );
+
+/**
+ * Receive an SPDM transport layer message from a device.
+ *
+ * The message is an SPDM message with transport layer wrapper,
+ * or a secured SPDM message with transport layer wrapper.
+ *
+ * For requester, the message is a transport layer SPDM response.
+ * For responder, the message is a transport layer SPDM request.
+ *
+ * @param  spdm_context                  A pointer to the SPDM context.
+ * @param  message_size                  size in bytes of the message data buffer.
+ * @param  message                      A pointer to a destination buffer to store the message.
+ *                                     The caller is responsible for having
+ *                                     either implicit or explicit ownership of the buffer.
+ *                                     On input, the message pointer shall be msg_buf_ptr from
+ *                                     acquired receiver_buffer.
+ *                                     On output, the message pointer shall be inside of
+ *                                     [msg_buf_ptr, msg_buf_ptr + max_msg_size] from
+ *                                     acquired receiver_buffer.
+ * @param  timeout                      The timeout, in 100ns units, to use for the execution
+ *                                     of the message. A timeout value of 0
+ *                                     means that this function will wait indefinitely for the
+ *                                     message to execute. If timeout is greater
+ *                                     than zero, then this function will return RETURN_TIMEOUT if the
+ *                                     time required to execute the message is greater
+ *                                     than timeout.
+ *
+ * @retval RETURN_SUCCESS               The SPDM message is received successfully.
+ * @retval RETURN_DEVICE_ERROR          A device error occurs when the SPDM message is received from the device.
+ * @retval RETURN_INVALID_PARAMETER     The message is NULL, message_size is NULL or
+ *                                     the *message_size is zero.
+ * @retval RETURN_TIMEOUT              A timeout occurred while waiting for the SPDM message
+ *                                     to execute.
+ **/
+typedef
+  SPDM_RETURN
+(*SPDM_DEVICE_RECEIVE_MESSAGE_FUNC)(
+  IN VOID       *SpdmContext,
+  IN OUT UINTN  *MessageSize,
+  IN OUT VOID   **Message,
+  IN UINT64     Timeout
+  );
+
+/**
+ * Encode an SPDM or APP message to a transport layer message.
+ *
+ * For normal SPDM message, it adds the transport layer wrapper.
+ * For secured SPDM message, it encrypts a secured message then adds the transport layer wrapper.
+ * For secured APP message, it encrypts a secured message then adds the transport layer wrapper.
+ *
+ * The APP message is encoded to a secured message directly in SPDM session.
+ * The APP message format is defined by the transport layer.
+ * Take MCTP as example: APP message == MCTP header (MCTP_MESSAGE_TYPE_SPDM) + SPDM message
+ *
+ * @param  spdm_context                  A pointer to the SPDM context.
+ * @param  session_id                    Indicates if it is a secured message protected via SPDM session.
+ *                                     If session_id is NULL, it is a normal message.
+ *                                     If session_id is NOT NULL, it is a secured message.
+ * @param  is_app_message                 Indicates if it is an APP message or SPDM message.
+ * @param  is_requester                  Indicates if it is a requester message.
+ * @param  message_size                  size in bytes of the message data buffer.
+ * @param  message                      A pointer to a source buffer to store the message.
+ *                                      For normal message, it shall point to the acquired sender buffer.
+ *                                      For secured message, it shall point to the scratch buffer in spdm_context.
+ * @param  transport_message_size         size in bytes of the transport message data buffer.
+ * @param  transport_message             A pointer to a destination buffer to store the transport message.
+ *                                      On input, it shall be msg_buf_ptr from sender buffer.
+ *                                      On output, it will point to acquired sender buffer.
+ *
+ * @retval RETURN_SUCCESS               The message is encoded successfully.
+ * @retval RETURN_INVALID_PARAMETER     The message is NULL or the message_size is zero.
+ **/
+typedef
+  SPDM_RETURN
+(*SPDM_TRANSPORT_ENCODE_MESSAGE_FUNC)(
+  IN VOID              *SpdmContext,
+  IN OUT CONST UINT32  *SessionId,
+  IN BOOLEAN           IsAppMessage,
+  IN BOOLEAN           IsRequester,
+  IN UINTN             MessageSize,
+  IN OUT VOID          *Message,
+  IN OUT UINTN         *TransportMessageSize,
+  IN VOID              **TransportMessage
+  );
+
+/**
+ * Decode an SPDM or APP message from a transport layer message.
+ *
+ * For normal SPDM message, it removes the transport layer wrapper,
+ * For secured SPDM message, it removes the transport layer wrapper, then decrypts and verifies a secured message.
+ * For secured APP message, it removes the transport layer wrapper, then decrypts and verifies a secured message.
+ *
+ * The APP message is decoded from a secured message directly in SPDM session.
+ * The APP message format is defined by the transport layer.
+ * Take MCTP as example: APP message == MCTP header (MCTP_MESSAGE_TYPE_SPDM) + SPDM message
+ *
+ * @param  spdm_context                  A pointer to the SPDM context.
+ * @param  session_id                    Indicates if it is a secured message protected via SPDM session.
+ *                                     If *session_id is NULL, it is a normal message.
+ *                                     If *session_id is NOT NULL, it is a secured message.
+ * @param  is_app_message                 Indicates if it is an APP message or SPDM message.
+ * @param  is_requester                  Indicates if it is a requester message.
+ * @param  transport_message_size         size in bytes of the transport message data buffer.
+ * @param  transport_message             A pointer to a source buffer to store the transport message.
+ *                                      For normal message or secured message, it shall point to acquired receiver buffer.
+ * @param  message_size                  size in bytes of the message data buffer.
+ * @param  message                      A pointer to a destination buffer to store the message.
+ *                                      On input, it shall point to the scratch buffer in spdm_context.
+ *                                      On output, for normal message, it will point to the original receiver buffer.
+ *                                      On output, for secured message, it will point to the scratch buffer in spdm_context.
+ *
+ * @retval RETURN_SUCCESS               The message is decoded successfully.
+ * @retval RETURN_INVALID_PARAMETER     The message is NULL or the message_size is zero.
+ * @retval RETURN_UNSUPPORTED           The transport_message is unsupported.
+ **/
+typedef
+  SPDM_RETURN
+(*SPDM_TRANSPORT_DECODE_MESSAGE_FUNC)(
+  IN VOID        *SpdmContext,
+  IN OUT UINT32  **SessionId,
+  IN BOOLEAN     *IsAppMessage,
+  IN BOOLEAN     IsRequester,
+  IN UINTN       TransportMessageSize,
+  IN OUT VOID    *TransportMessage,
+  IN OUT UINTN   *MessageSize,
+  IN OUT VOID    **Message
+  );
+
+/**
+ * Acquire a device sender buffer for transport layer message.
+ *
+ * The max_msg_size must be larger than
+ * MAX (non-secure Transport Message Header Size +
+ *          SPDM_CAPABILITIES.DataTransferSize +
+ *          max alignment pad size (transport specific),
+ *      secure Transport Message Header Size +
+ *          sizeof(spdm_secured_message_a_data_header1_t) +
+ *          length of sequence_number (transport specific) +
+ *          sizeof(spdm_secured_message_a_data_header2_t) +
+ *          sizeof(spdm_secured_message_cipher_header_t) +
+ *          App Message Header Size (transport specific) +
+ *          SPDM_CAPABILITIES.DataTransferSize +
+ *          maximum random data size (transport specific) +
+ *          AEAD MAC size (16) +
+ *          max alignment pad size (transport specific))
+ *
+ *   For MCTP,
+ *          Transport Message Header Size = sizeof(mctp_message_header_t)
+ *          length of sequence_number = 2
+ *          App Message Header Size = sizeof(mctp_message_header_t)
+ *          maximum random data size = MCTP_MAX_RANDOM_NUMBER_COUNT
+ *          max alignment pad size = 0
+ *   For PCI_DOE,
+ *          Transport Message Header Size = sizeof(pci_doe_data_object_header_t)
+ *          length of sequence_number = 0
+ *          App Message Header Size = 0
+ *          maximum random data size = 0
+ *          max alignment pad size = 3
+ *
+ * @param  context                       A pointer to the SPDM context.
+ * @param  max_msg_size                  size in bytes of the maximum size of sender buffer.
+ * @param  msg_buf_ptr                   A pointer to a sender buffer.
+ *
+ * @retval RETURN_SUCCESS               The sender buffer is acquired.
+ **/
+typedef
+  SPDM_RETURN
+(*SPDM_DEVICE_ACQUIRE_SENDER_BUFFER_FUNC)(
+  IN VOID      *SpdmContext,
+  IN OUT VOID  **MsgBufPtr
+  );
+
+/**
+ * Release a device sender buffer for transport layer message.
+ *
+ * @param  context                       A pointer to the SPDM context.
+ * @param  msg_buf_ptr                   A pointer to a sender buffer.
+ *
+ * @retval RETURN_SUCCESS               The sender buffer is Released.
+ **/
+typedef
+  VOID
+(*SPDM_DEVICE_RELEASE_SENDER_BUFFER_FUNC)(
+  IN VOID        *SpdmContext,
+  IN CONST VOID  *MsgBufPtr
+  );
+
+/**
+ * Acquire a device receiver buffer for transport layer message.
+ *
+ * The max_msg_size must be larger than
+ * MAX (non-secure Transport Message Header Size +
+ *          SPDM_CAPABILITIES.DataTransferSize +
+ *          max alignment pad size (transport specific),
+ *      secure Transport Message Header Size +
+ *          sizeof(spdm_secured_message_a_data_header1_t) +
+ *          length of sequence_number (transport specific) +
+ *          sizeof(spdm_secured_message_a_data_header2_t) +
+ *          sizeof(spdm_secured_message_cipher_header_t) +
+ *          App Message Header Size (transport specific) +
+ *          SPDM_CAPABILITIES.DataTransferSize +
+ *          maximum random data size (transport specific) +
+ *          AEAD MAC size (16) +
+ *          max alignment pad size (transport specific))
+ *
+ *   For MCTP,
+ *          Transport Message Header Size = sizeof(mctp_message_header_t)
+ *          length of sequence_number = 2
+ *          App Message Header Size = sizeof(mctp_message_header_t)
+ *          maximum random data size = MCTP_MAX_RANDOM_NUMBER_COUNT
+ *          max alignment pad size = 0
+ *   For PCI_DOE,
+ *          Transport Message Header Size = sizeof(pci_doe_data_object_header_t)
+ *          length of sequence_number = 0
+ *          App Message Header Size = 0
+ *          maximum random data size = 0
+ *          max alignment pad size = 3
+ *
+ * @param  context                       A pointer to the SPDM context.
+ * @param  max_msg_size                  size in bytes of the maximum size of receiver buffer.
+ * @param  msg_buf_pt                    A pointer to a receiver buffer.
+ *
+ * @retval RETURN_SUCCESS               The receiver buffer is acquired.
+ **/
+typedef
+  SPDM_RETURN
+(*SPDM_DEVICE_ACQUIRE_RECEIVER_BUFFER_FUNC)(
+  IN VOID      *SpdmContext,
+  IN OUT VOID  **MsgBufPtr
+  );
+
+/**
+ * Release a device receiver buffer for transport layer message.
+ *
+ * @param  context                       A pointer to the SPDM context.
+ * @param  msg_buf_ptr                   A pointer to a receiver buffer.
+ *
+ * @retval RETURN_SUCCESS               The receiver buffer is Released.
+ **/
+typedef
+  VOID
+(*SPDM_DEVICE_RELEASE_RECEIVER_BUFFER_FUNC)(
+  IN VOID        *SpdmContext,
+  IN CONST VOID  *MsgBufPtr
+  );
+
+typedef struct {
+  UINT32                     Version;
+  //
+  // DeviceType is used to create TCG event log context_data.
+  // DeviceHandle is used to create TCG event log device_path information.
+  //
+  EDKII_DEVICE_IDENTIFIER    *DeviceId;
+
+  //
+  // TRUE  means to use PCR 0 (code) / 1 (config).
+  // FALSE means to use PCR 2 (code) / 3 (config).
+  //
+  BOOLEAN                    IsEmbeddedDevice;
+
+  //
+  // Below 9 APIs are used to send/receive SPDM request/response.
+  //
+  // The request flow is:
+  //   |<---                       SenderBufferSize                     --->|
+  //      |<---                TransportRequestBufferSize            --->|
+  //   |<---MaxHeaderSize--->|<-SpdmRequestBufferSize ->|
+  //   +--+------------------+==========================+----------------+--+
+  //   |  | Transport Header |       SPDM Message       | Transport Tail |  |
+  //   +--+------------------+==========================+----------------+--+
+  //   ^  ^                  ^
+  //   |  |                  | SpdmRequestBuffer
+  //   |  | TransportRequestBuffer
+  //   | SenderBuffer
+  //
+  //   AcquireSenderBuffer (&SenderBuffer, &SenderBufferSize);
+  //   SpdmRequestBuffer = SenderBuffer + TransportHeaderSize;
+  //   /* build SPDM request in SpdmRequestBuffer */
+  //   TransportEncodeMessage (SpdmRequestBuffer, SpdmRequestBufferSize,
+  //       &TransportRequestBuffer, &TransportRequestBufferSize);
+  //   SendMessage (TransportRequestBuffer, TransportRequestBufferSize);
+  //   ReleaseSenderBuffer (SenderBuffer);
+  //
+  // The response flow is:
+  //   |<---                       ReceiverBufferSize                   --->|
+  //      |<---                TransportResponseBufferSize           --->|
+  //                         |<-SpdmResponseBufferSize->|
+  //   +--+------------------+==========================+----------------+--+
+  //   |  | Transport Header |       SPDM Message       | Transport Tail |  |
+  //   +--+------------------+==========================+----------------+--+
+  //   ^  ^                  ^
+  //   |  |                  | SpdmResponseBuffer
+  //   |  | TransportResponseBuffer
+  //   | ReceiverBuffer
+  //
+  //   AcquireReceiverBuffer (&ReceiverBuffer, &ReceiverBufferSize);
+  //   TransportResponseBuffer = ReceiverBuffer;
+  //   ReceiveMessage (&TransportResponseBuffer, &TransportResponseBufferSize);
+  //   TransportDecodeMessage (TransportResponseBuffer, TransportResponseBufferSize,
+  //       &SpdmResponseBuffer, &SpdmResponseBufferSize);
+  //   /* process SPDM response in SpdmResponseBuffer */
+  //   ReleaseReceiverBuffer (ReceiverBuffer);
+  //
+
+  //
+  // API required by SpdmRegisterDeviceIoFunc in libspdm
+  // It is used to send/receive transport message (SPDM + transport header).
+  //
+  SPDM_DEVICE_SEND_MESSAGE_FUNC               SendMessage;
+  SPDM_DEVICE_RECEIVE_MESSAGE_FUNC            ReceiveMessage;
+  //
+  // API required by SpdmRegisterTransportLayerFunc in libspdm
+  // It is used to add/remove transport header for SPDM.
+  //
+  SPDM_TRANSPORT_ENCODE_MESSAGE_FUNC          TransportEncodeMessage;
+  SPDM_TRANSPORT_DECODE_MESSAGE_FUNC          TransportDecodeMessage;
+  //
+  // API required by SpdmRegisterDeviceBufferFunc in libspdm
+  // It is used to get the sender/receiver buffer for transport message (SPDM + transport header).
+  // The size MUST be big enough to send or receive one transport message (SPDM + transport header).
+  // Tthe sender/receiver buffer MAY be overlapped.
+  //
+  SPDM_DEVICE_ACQUIRE_SENDER_BUFFER_FUNC      AcquireSenderBuffer;
+  SPDM_DEVICE_RELEASE_SENDER_BUFFER_FUNC      ReleaseSenderBuffer;
+  SPDM_DEVICE_ACQUIRE_RECEIVER_BUFFER_FUNC    AcquireReceiverBuffer;
+  SPDM_DEVICE_RELEASE_RECEIVER_BUFFER_FUNC    ReleaseReceiverBuffer;
+
+  //
+  // Preferred Algorithm List for SPDM negotiation.
+  // If it is none zero, it will be used directly.
+  // If it is zero, then the SpdmSecurityLib will set the default value.
+  //
+  UINT32                                      BaseHashAlgo;
+  UINT32                                      BaseAsymAlgo;
+
+  //
+  // transfer size
+  //
+  UINT32                                      MaxSpdmMsgSize;
+  UINT32                                      TransportHeaderSize;
+  UINT32                                      TransportTailSize;
+  UINT32                                      SenderBufferSize;
+  UINT32                                      ReceiverBufferSize;
+
+  EFI_GUID                                    *SpdmIoProtocolGuid;
+} EDKII_SPDM_DEVICE_INFO;
+
+/**
+  This function will send SPDM VCA, GET_CERTIFICATE, CHALLENGE, GET_MEASUREMENT,
+  The certificate and measurement will be extended to TPM PCR/NvIndex.
+**/
+RETURN_STATUS
+EFIAPI
+SpdmDeviceAuthenticationAndMeasurement (
+  IN  EDKII_SPDM_DEVICE_INFO        *SpdmDeviceInfo,
+  IN  EDKII_DEVICE_SECURITY_POLICY  *SecurityPolicy,
+  OUT EDKII_DEVICE_SECURITY_STATE   *SecurityState
+  );
+
+/**
+  This function will get SpdmIoProtocol via Context.
+**/
+VOID *
+EFIAPI
+SpdmGetIoProtocolViaSpdmContext (
+  IN VOID  *SpdmContext
+  );
+
+/**
+  Helper function to quickly determine whether device authentication boot is enabled.
+
+  @retval     TRUE    device authentication boot is verifiably enabled.
+  @retval     FALSE   device authentication boot is either disabled or an error prevented checking.
+
+**/
+BOOLEAN
+EFIAPI
+IsDeviceAuthBootEnabled (
+  VOID
+  );
+
+#endif
diff --git a/SecurityPkg/Include/Protocol/DeviceSecurityPolicy.h b/SecurityPkg/Include/Protocol/DeviceSecurityPolicy.h
new file mode 100644
index 0000000000..69148badb6
--- /dev/null
+++ b/SecurityPkg/Include/Protocol/DeviceSecurityPolicy.h
@@ -0,0 +1,133 @@
+/** @file
+  Platform Device Security Policy Protocol definition
+
+  Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H_
+#define EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_H_
+
+#include <Uefi.h>
+#include <Protocol/DeviceSecurity.h>
+
+typedef struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL EDKII_DEVICE_SECURITY_POLICY_PROTOCOL;
+
+//
+// Revision The revision to which the DEVICE_SECURITY_POLICY protocol interface adheres.
+//          All future revisions must be backwards compatible.
+//          If a future version is not back wards compatible it is not the same GUID.
+//
+#define EDKII_DEVICE_SECURITY_POLICY_PROTOCOL_REVISION  0x00010000
+
+//
+// Revision The revision to which the DEVICE_SECURITY_POLICY structure adheres.
+//          All future revisions must be backwards compatible.
+//
+#define EDKII_DEVICE_SECURITY_POLICY_REVISION  0x00010000
+
+///
+/// The macro for the policy defined in EDKII_DEVICE_SECURITY_POLICY
+///
+#define EDKII_DEVICE_MEASUREMENT_REQUIRED     BIT0
+#define EDKII_DEVICE_AUTHENTICATION_REQUIRED  BIT0
+
+///
+/// The device security policy data structure
+///
+typedef struct {
+  UINT32    Revision;
+  UINT32    MeasurementPolicy;
+  UINT32    AuthenticationPolicy;
+} EDKII_DEVICE_SECURITY_POLICY;
+
+//
+// Revision The revision to which the DEVICE_SECURITY_STATE structure adheres.
+//          All future revisions must be backwards compatible.
+//
+#define EDKII_DEVICE_SECURITY_STATE_REVISION  0x00010000
+
+///
+/// The macro for the state defined in EDKII_DEVICE_SECURITY_STATE
+///
+#define EDKII_DEVICE_SECURITY_STATE_SUCCESS                         0
+#define EDKII_DEVICE_SECURITY_STATE_ERROR                           BIT31
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_UNSUPPORTED          (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x0)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_GET_POLICY_PROTOCOL  (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x1)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_UEFI_OUT_OF_RESOURCE      (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x2)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_NO_CAPABILITIES    (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x10)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR              (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x11)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_TCG_EXTEND_TPM_PCR        (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x20)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_MEASUREMENT_AUTH_FAILURE  (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x21)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_CHALLENGE_FAILURE         (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x30)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_CERTIFIACTE_FAILURE       (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x31)
+#define EDKII_DEVICE_SECURITY_STATE_ERROR_NO_CERT_PROVISION         (EDKII_DEVICE_SECURITY_STATE_ERROR + 0x32)
+
+///
+/// The device security state data structure
+///
+typedef struct {
+  UINT32    Revision;
+  UINT32    MeasurementState;
+  UINT32    AuthenticationState;
+} EDKII_DEVICE_SECURITY_STATE;
+
+/**
+  This function returns the device security policy associated with the device.
+
+  The device security driver may call this interface to get the platform policy
+  for the specific device and determine if the measurement or authentication
+  is required.
+
+  @param[in]  This                   The protocol instance pointer.
+  @param[in]  DeviceId               The Identifier for the device.
+  @param[out] DeviceSecurityPolicy   The Device Security Policy associated with the device.
+
+  @retval EFI_SUCCESS                The device security policy is returned
+  @retval EFI_UNSUPPORTED            The function is unsupported for the specific Device.
+**/
+typedef
+  EFI_STATUS
+(EFIAPI *EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY)(
+  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
+  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
+  OUT EDKII_DEVICE_SECURITY_POLICY           *DeviceSecurityPolicy
+  );
+
+/**
+  This function sets the device state based upon the authentication result.
+
+  The device security driver may call this interface to give the platform
+  a notify based upon the measurement or authentication result.
+  If the authentication or measurement fails, the platform may choose:
+  1) Do nothing.
+  2) Disable this device or slot temporarily and continue boot.
+  3) Reset the platform and retry again.
+  4) Disable this device or slot permanently.
+  5) Any other platform specific action.
+
+  @param[in]  This                   The protocol instance pointer.
+  @param[in]  DeviceId               The Identifier for the device.
+  @param[in]  DeviceSecurityState    The Device Security state associated with the device.
+
+  @retval EFI_SUCCESS                The device state is set.
+  @retval EFI_UNSUPPORTED            The function is unsupported for the specific Device.
+**/
+typedef
+  EFI_STATUS
+(EFIAPI *EDKII_DEVICE_SECURITY_NOTIFY_DEVICE_STATE)(
+  IN  EDKII_DEVICE_SECURITY_POLICY_PROTOCOL  *This,
+  IN  EDKII_DEVICE_IDENTIFIER                *DeviceId,
+  IN  EDKII_DEVICE_SECURITY_STATE            *DeviceSecurityState
+  );
+
+struct _EDKII_DEVICE_SECURITY_POLICY_PROTOCOL {
+  UINT32                                       Revision;
+  EDKII_DEVICE_SECURITY_GET_DEVICE_POLICY      GetDevicePolicy;
+  EDKII_DEVICE_SECURITY_NOTIFY_DEVICE_STATE    NotifyDeviceState;
+};
+
+extern EFI_GUID  gEdkiiDeviceSecurityPolicyProtocolGuid;
+
+#endif
diff --git a/SecurityPkg/SecurityPkg.ci.yaml b/SecurityPkg/SecurityPkg.ci.yaml
index 53e5b1fd8e..2a4cbd3795 100644
--- a/SecurityPkg/SecurityPkg.ci.yaml
+++ b/SecurityPkg/SecurityPkg.ci.yaml
@@ -2,12 +2,14 @@
 # CI configuration for SecurityPkg
 #
 # Copyright (c) Microsoft Corporation
-# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2020 - 2024, Intel Corporation. All rights reserved.<BR>
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 ##
 {
     "LicenseCheck": {
-        "IgnoreFiles": []
+        "IgnoreFiles": [
+            "DeviceSecurity/SpdmLib/Include",
+        ]
     },
     "EccCheck": {
         ## Exception sample looks like below:
@@ -23,7 +25,10 @@
         "IgnoreFiles": [
             "Library/TcgStorageCoreLib/TcgStorageUtil.c",
             "Library/TcgStorageCoreLib/TcgStorageCore.c",
-            "Library/Tpm2CommandLib/Tpm2NVStorage.c"
+            "Library/Tpm2CommandLib/Tpm2NVStorage.c",
+            "DeviceSecurity/SpdmLib/Include",
+            "DeviceSecurity/SpdmLib/libspdm",
+            "DeviceSecurity/OsStub"
         ]
     },
     "CompilerPlugin": {
@@ -69,7 +74,11 @@
         ]
     },
     "LibraryClassCheck": {
-        "IgnoreHeaderFile": []
+        "IgnoreHeaderFile": [
+            "DeviceSecurity/SpdmLib/Include/library",
+            "DeviceSecurity/SpdmLib/libspdm/include/library",
+        ],
+        "skip": True
     },
 
     ## options defined ci/Plugin/SpellCheck
diff --git a/SecurityPkg/SecurityPkg.dec b/SecurityPkg/SecurityPkg.dec
index 00c4ebdbed..a91e3ea028 100644
--- a/SecurityPkg/SecurityPkg.dec
+++ b/SecurityPkg/SecurityPkg.dec
@@ -5,7 +5,7 @@
 #  It also provides the definitions(including PPIs/PROTOCOLs/GUIDs and library classes)
 #  and libraries instances, which are used for those features.
 #
-# Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
 # (C) Copyright 2015 Hewlett Packard Enterprise Development LP <BR>
 # Copyright (c) Microsoft Corporation.<BR>
 # SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -23,6 +23,10 @@
   Include
   Test/Mock/Include
 
+[Includes.Common.Private]
+  DeviceSecurity/SpdmLib/Include
+  DeviceSecurity/SpdmLib/libspdm/include
+
 [LibraryClasses]
   ##  @libraryclass  Provides hash interfaces from different implementations.
   #
@@ -97,6 +101,10 @@
   #
   PlatformPKProtectionLib|Include/Library/PlatformPKProtectionLib.h
 
+  ##  @libraryclass Perform SPDM (following SPDM spec) and measure data to TPM (following TCG PFP spec).
+  ##
+  SpdmSecurityLib|Include/Library/SpdmSecurityLib.h
+
 [Guids]
   ## Security package token space guid.
   # Include/Guid/SecurityPkgTokenSpace.h
@@ -219,6 +227,9 @@
   ## GUID used to specify section with default dbt content
   gDefaultdbtFileGuid                = { 0x36c513ee, 0xa338, 0x4976, { 0xa0, 0xfb, 0x6d, 0xdb, 0xa3, 0xda, 0xfe, 0x87 } }
 
+  ## GUID used to generate Spdm Uid
+  gEfiDeviceSecuritySpdmUidGuid = {0xe37b5665, 0x5ef9, 0x4e7e, {0xb4, 0x91, 0xd6, 0x78, 0xab, 0xff, 0xfb, 0xcb }}
+
 [Ppis]
   ## The PPI GUID for that TPM physical presence should be locked.
   # Include/Ppi/LockPhysicalPresence.h
diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc
index 7682066cd9..1926d908eb 100644
--- a/SecurityPkg/SecurityPkg.dsc
+++ b/SecurityPkg/SecurityPkg.dsc
@@ -1,7 +1,7 @@
 ## @file
 #  Security Module Package for All Architectures.
 #
-# Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
 # (C) Copyright 2015-2020 Hewlett Packard Enterprise Development LP<BR>
 # Copyright (c) 2022, Loongson Technology Corporation Limited. All rights reserved.<BR>
 # Copyright (c) 2021 - 2022, Arm Limited. All rights reserved.<BR>
@@ -76,6 +76,19 @@
   TdxLib|MdePkg/Library/TdxLib/TdxLib.inf
   VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
 
+  SpdmSecurityLib|SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf
+  SpdmDeviceSecretLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf
+  SpdmCryptLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf
+  SpdmCommonLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf
+  SpdmRequesterLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf
+  SpdmResponderLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf
+  SpdmSecuredMessageLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf
+  SpdmTransportMctpLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf
+  SpdmTransportPciDoeLib|SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf
+  CryptlibWrapper|SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.inf
+  PlatformLibWrapper|SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.inf
+  MemLibWrapper|SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf
+
 [LibraryClasses.ARM, LibraryClasses.AARCH64]
   #
   # It is not possible to prevent the ARM compiler for generic intrinsic functions.
@@ -294,6 +307,22 @@
   #
   SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf
 
+  #
+  # SPDM
+  #
+  SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmSecurityLib.inf
+  SecurityPkg/DeviceSecurity/SpdmLib/SpdmDeviceSecretLibNull.inf
+  SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf
+  SecurityPkg/DeviceSecurity/SpdmLib/SpdmCommonLib.inf
+  SecurityPkg/DeviceSecurity/SpdmLib/SpdmRequesterLib.inf
+  SecurityPkg/DeviceSecurity/SpdmLib/SpdmResponderLib.inf
+  SecurityPkg/DeviceSecurity/SpdmLib/SpdmSecuredMessageLib.inf
+  SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportMctpLib.inf
+  SecurityPkg/DeviceSecurity/SpdmLib/SpdmTransportPciDoeLib.inf
+  SecurityPkg/DeviceSecurity/OsStub/CryptlibWrapper/CryptlibWrapper.inf
+  SecurityPkg/DeviceSecurity/OsStub/PlatformLibWrapper/PlatformLibWrapper.inf
+  SecurityPkg/DeviceSecurity/OsStub/MemLibWrapper/MemLibWrapper.inf
+
 [Components.X64]
   SecurityPkg/Library/HashLibTdx/HashLibTdx.inf
   SecurityPkg/Library/SecTpmMeasurementLib/SecTpmMeasurementLibTdx.inf
-- 
2.26.2.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117312): https://edk2.groups.io/g/devel/message/117312
Mute This Topic: https://groups.io/mt/105281055/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2024-04-02  2:31 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-04-02  2:31 [edk2-devel] [PATCH 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
2024-04-02  2:31 ` [edk2-devel] [PATCH 1/9] MdePkg: Add SPDM1.2 support Wenxing Hou
2024-04-02  2:31 ` [edk2-devel] [PATCH 2/9] MdePkg: Add TCG PFP 1.06 support Wenxing Hou
2024-04-02  2:31 ` [edk2-devel] [PATCH 3/9] MdePkg: Add devAuthBoot GlobalVariable Wenxing Hou
2024-04-02  2:31 ` [edk2-devel] [PATCH 4/9] MdeModulePkg/Variable: Add TCG SPDM device measurement update Wenxing Hou
2024-04-04 15:57   ` Michael Kubacki
2024-04-08  1:59     ` Wenxing Hou
2024-04-02  2:31 ` [edk2-devel] [PATCH 5/9] SecurityPkg: Add TCG PFP 1.06 support Wenxing Hou
2024-04-02  2:31 ` Wenxing Hou [this message]
2024-04-02  2:31 ` [edk2-devel] [PATCH 7/9] .pytool/CISettings.py: add libspdm submodule Wenxing Hou
2024-04-03 17:32   ` Joey Vagedes via groups.io
2024-04-02  2:31 ` [edk2-devel] [PATCH 8/9] .gitmodule: Add libspdm submodule for EDKII Wenxing Hou
2024-04-02  2:31 ` [edk2-devel] [PATCH 9/9] SecurityPkg: Add libspdm submodule Wenxing Hou
2024-04-09 15:13 ` [edk2-devel] [PATCH 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Michael D Kinney
2024-04-15  2:08   ` Wenxing Hou
2024-04-16  9:25     ` Yao, Jiewen
     [not found]     ` <17C6B87A036D5709.13290@groups.io>
2024-04-16  9:36       ` Yao, Jiewen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240402023125.4168-7-wenxing.hou@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox