public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec
@ 2024-04-08  1:46 Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 1/9] MdePkg: Add SPDM1.2 support Wenxing Hou
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Wenxing Hou @ 2024-04-08  1:46 UTC (permalink / raw)
  To: devel
  Cc: Sean Brogan, Joey Vagedes, Michael D Kinney, Liming Gao,
	Andrew Fish, Zhiguang Liu, Rahul Kumar, Jiewen Yao

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2479

In PFP spec 1.06, platform firmware records the device certificate and device measurement for each SPDM responder.
This PATCH set implement the DeviceSecurityLib to support spdm device Authentication and Measurement.

Libspdm as submodule is to support DeviceSecurity feature:
https://github.com/DMTF/libspdm

TCG PFP spec 1.06:
https://trustedcomputinggroup.org/resource/pc-client-specific-platform-firmware-profile-specification/

The POC branch:
https://github.com/tianocore/edk2-staging/tree/DeviceSecurity

And the PATCH set has passed the EDKII CI:
https://github.com/tianocore/edk2/pull/5508

v2 changes:
 - Fix typo: PcdEnableSpdmDeviceAuthenticaion -> PcdEnableSpdmDeviceAuthentication

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Joey Vagedes <joey.vagedes@gmail.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Andrew Fish <afish@apple.com>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>

Wenxing Hou (9):
  MdePkg: Add SPDM1.2 support.
  MdePkg: Add TCG PFP 1.06 support.
  MdePkg: Add devAuthBoot GlobalVariable
  MdeModulePkg/Variable: Add TCG SPDM device measurement update
  SecurityPkg: Add TCG PFP 1.06 support.
  SecurityPkg: add DeviceSecurity support
  .pytool/CISettings.py: add libspdm submodule.
  .gitmodule: Add libspdm submodule for EDKII
  SecurityPkg: Add libspdm submodule

 .gitmodules                                   |    3 +
 .pytool/CISettings.py                         |    2 +
 MdeModulePkg/MdeModulePkg.dec                 |    5 +
 .../Variable/RuntimeDxe/Measurement.c         |   38 +-
 .../RuntimeDxe/VariableRuntimeDxe.inf         |    3 +
 .../RuntimeDxe/VariableSmmRuntimeDxe.inf      |    3 +
 MdePkg/Include/Guid/GlobalVariable.h          |    8 +-
 MdePkg/Include/Guid/ImageAuthentication.h     |    5 +-
 MdePkg/Include/IndustryStandard/Spdm.h        | 1112 ++++++++++++++++-
 .../IndustryStandard/UefiTcgPlatform.h        |  186 ++-
 .../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 +
 SecurityPkg/DeviceSecurity/SpdmLib/libspdm    |    1 +
 .../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 +++++++
 SecurityPkg/Include/Library/Tpm2CommandLib.h  |   23 +-
 .../Include/Protocol/DeviceSecurityPolicy.h   |  133 ++
 .../HashLibBaseCryptoRouterDxe.c              |   88 +-
 .../Library/Tpm2CommandLib/Tpm2NVStorage.c    |  122 +-
 SecurityPkg/SecurityPkg.ci.yaml               |   17 +-
 SecurityPkg/SecurityPkg.dec                   |   13 +-
 SecurityPkg/SecurityPkg.dsc                   |   31 +-
 SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c             |   61 +-
 SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf           |    4 +-
 48 files changed, 7196 insertions(+), 85 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 160000 SecurityPkg/DeviceSecurity/SpdmLib/libspdm
 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

-- 
2.26.2.windows.1



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



^ permalink raw reply	[flat|nested] 12+ messages in thread

* [edk2-devel] [PATCH v2 1/9] MdePkg: Add SPDM1.2 support.
  2024-04-08  1:46 [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
@ 2024-04-08  1:46 ` Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 2/9] MdePkg: Add TCG PFP 1.06 support Wenxing Hou
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Wenxing Hou @ 2024-04-08  1:46 UTC (permalink / raw)
  To: devel; +Cc: Michael D Kinney, Liming Gao, Zhiguang Liu, Jiewen Yao

Update Spdm.h to support 1.2 new features, such as:
Authentication and measurement. It wil be used in DeviceSecurity.
The DeviceSecurity feature is from
TCG PC Client Platform Firmware Profile Specification 1.06.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 MdePkg/Include/IndustryStandard/Spdm.h | 1110 ++++++++++++++++++++++--
 1 file changed, 1061 insertions(+), 49 deletions(-)

diff --git a/MdePkg/Include/IndustryStandard/Spdm.h b/MdePkg/Include/IndustryStandard/Spdm.h
index 4ec7a5ed1f..7940caa95e 100644
--- a/MdePkg/Include/IndustryStandard/Spdm.h
+++ b/MdePkg/Include/IndustryStandard/Spdm.h
@@ -1,8 +1,8 @@
 /** @file
-  Definitions of Security Protocol & Data Model Specification (SPDM)
-  version 1.0.0 in Distributed Management Task Force (DMTF).
+  Definitions of DSP0274 Security Protocol & Data Model Specification (SPDM)
+  version 1.2.0 in Distributed Management Task Force (DMTF).
 
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2019 - 2024, Intel Corporation. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -12,29 +12,72 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 #pragma pack(1)
 
+#define SPDM_MAX_SLOT_COUNT        8
+#define SPDM_MAX_OPAQUE_DATA_SIZE  1024
+#define SPDM_NONCE_SIZE            32
+#define SPDM_RANDOM_DATA_SIZE      32
 ///
-/// SPDM response code
+/// SPDM response code (1.0)
 ///
-#define SPDM_DIGESTS            0x01
-#define SPDM_CERTIFICATE        0x02
-#define SPDM_CHALLENGE_AUTH     0x03
-#define SPDM_VERSION            0x04
-#define SPDM_MEASUREMENTS       0x60
-#define SPDM_CAPABILITIES       0x61
-#define SPDM_SET_CERT_RESPONSE  0x62
-#define SPDM_ALGORITHMS         0x63
-#define SPDM_ERROR              0x7F
+#define SPDM_DIGESTS                  0x01
+#define SPDM_CERTIFICATE              0x02
+#define SPDM_CHALLENGE_AUTH           0x03
+#define SPDM_VERSION                  0x04
+#define SPDM_MEASUREMENTS             0x60
+#define SPDM_CAPABILITIES             0x61
+#define SPDM_ALGORITHMS               0x63
+#define SPDM_VENDOR_DEFINED_RESPONSE  0x7E
+#define SPDM_ERROR                    0x7F
 ///
-/// SPDM request code
+/// SPDM response code (1.1)
 ///
-#define SPDM_GET_DIGESTS           0x81
-#define SPDM_GET_CERTIFICATE       0x82
-#define SPDM_CHALLENGE             0x83
-#define SPDM_GET_VERSION           0x84
-#define SPDM_GET_MEASUREMENTS      0xE0
-#define SPDM_GET_CAPABILITIES      0xE1
-#define SPDM_NEGOTIATE_ALGORITHMS  0xE3
-#define SPDM_RESPOND_IF_READY      0xFF
+#define SPDM_KEY_EXCHANGE_RSP           0x64
+#define SPDM_FINISH_RSP                 0x65
+#define SPDM_PSK_EXCHANGE_RSP           0x66
+#define SPDM_PSK_FINISH_RSP             0x67
+#define SPDM_HEARTBEAT_ACK              0x68
+#define SPDM_KEY_UPDATE_ACK             0x69
+#define SPDM_ENCAPSULATED_REQUEST       0x6A
+#define SPDM_ENCAPSULATED_RESPONSE_ACK  0x6B
+#define SPDM_END_SESSION_ACK            0x6C
+///
+/// SPDM response code (1.2)
+///
+#define SPDM_CSR                  0x6D
+#define SPDM_SET_CERTIFICATE_RSP  0x6E
+#define SPDM_CHUNK_SEND_ACK       0x05
+#define SPDM_CHUNK_RESPONSE       0x06
+///
+/// SPDM request code (1.0)
+///
+#define SPDM_GET_DIGESTS             0x81
+#define SPDM_GET_CERTIFICATE         0x82
+#define SPDM_CHALLENGE               0x83
+#define SPDM_GET_VERSION             0x84
+#define SPDM_GET_MEASUREMENTS        0xE0
+#define SPDM_GET_CAPABILITIES        0xE1
+#define SPDM_NEGOTIATE_ALGORITHMS    0xE3
+#define SPDM_VENDOR_DEFINED_REQUEST  0xFE
+#define SPDM_RESPOND_IF_READY        0xFF
+///
+/// SPDM request code (1.1)
+///
+#define SPDM_KEY_EXCHANGE                   0xE4
+#define SPDM_FINISH                         0xE5
+#define SPDM_PSK_EXCHANGE                   0xE6
+#define SPDM_PSK_FINISH                     0xE7
+#define SPDM_HEARTBEAT                      0xE8
+#define SPDM_KEY_UPDATE                     0xE9
+#define SPDM_GET_ENCAPSULATED_REQUEST       0xEA
+#define SPDM_DELIVER_ENCAPSULATED_RESPONSE  0xEB
+#define SPDM_END_SESSION                    0xEC
+///
+/// SPDM request code (1.2)
+///
+#define SPDM_GET_CSR          0xED
+#define SPDM_SET_CERTIFICATE  0xEE
+#define SPDM_CHUNK_SEND       0x85
+#define SPDM_CHUNK_GET        0x86
 
 ///
 /// SPDM message header
@@ -46,13 +89,18 @@ typedef struct {
   UINT8    Param2;
 } SPDM_MESSAGE_HEADER;
 
-#define SPDM_MESSAGE_VERSION  0x10
+#define SPDM_MESSAGE_VERSION_10  0x10
+#define SPDM_MESSAGE_VERSION_11  0x11
+#define SPDM_MESSAGE_VERSION_12  0x12
+#define SPDM_MESSAGE_VERSION     SPDM_MESSAGE_VERSION_10
 
 ///
 /// SPDM GET_VERSION request
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
 } SPDM_GET_VERSION_REQUEST;
 
 ///
@@ -60,6 +108,8 @@ typedef struct {
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
   UINT8                  Reserved;
   UINT8                  VersionNumberEntryCount;
   // SPDM_VERSION_NUMBER  VersionNumberEntry[VersionNumberEntryCount];
@@ -68,18 +118,32 @@ typedef struct {
 ///
 /// SPDM VERSION structure
 ///
-typedef struct {
-  UINT16    Alpha               : 4;
-  UINT16    UpdateVersionNumber : 4;
-  UINT16    MinorVersion        : 4;
-  UINT16    MajorVersion        : 4;
-} SPDM_VERSION_NUMBER;
+/// bit[15:12] major_version
+/// bit[11:8]  minor_version
+/// bit[7:4]   update_version_number
+/// bit[3:0]   alpha
+typedef UINT16 SPDM_VERSION_NUMBER;
+#define SPDM_VERSION_NUMBER_SHIFT_BIT  8
 
+#define SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT  "dmtf-spdm-v1.2.*"
+#define SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT_SIZE \
+    (sizeof(SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT) - 1)
+#define SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE  100
 ///
 /// SPDM GET_CAPABILITIES request
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
+  // Below field is added in 1.1.
+  UINT8                  Reserved;
+  UINT8                  CTExponent;
+  UINT16                 Reserved2;
+  UINT32                 Flags;
+  // Below field is added in 1.2.
+  UINT32                 DataTransferSize;
+  UINT32                 MaxSpdmMsgSize;
 } SPDM_GET_CAPABILITIES_REQUEST;
 
 ///
@@ -87,14 +151,58 @@ typedef struct {
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
   UINT8                  Reserved;
   UINT8                  CTExponent;
   UINT16                 Reserved2;
   UINT32                 Flags;
+  // Below field is added in 1.2.
+  UINT32                 DataTransferSize;
+  UINT32                 MaxSpdmMsgSize;
 } SPDM_CAPABILITIES_RESPONSE;
 
+#define SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12  42
+
+///
+/// SPDM GET_CAPABILITIES request Flags (1.1)
+///
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP                    BIT1
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP                    BIT2
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP                 BIT6
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP                     BIT7
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP                BIT8
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP                  BIT9
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP                     (BIT10 | BIT11)
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP_REQUESTER           BIT10
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP                   BIT12
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP                   BIT13
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP                 BIT14
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP  BIT15
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PUB_KEY_ID_CAP              BIT16
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_11_MASK                     (\
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PUB_KEY_ID_CAP)
+
+///
+/// SPDM GET_CAPABILITIES request Flags (1.2)
 ///
-/// SPDM GET_CAPABILITIES response Flags
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP  BIT17
+#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_12_MASK    (\
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_11_MASK | \
+        SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP)
+///
+/// SPDM GET_CAPABILITIES response Flags (1.0)
 ///
 #define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CACHE_CAP        BIT0
 #define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP         BIT1
@@ -103,27 +211,118 @@ typedef struct {
 #define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_NO_SIG  BIT3
 #define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG     BIT4
 #define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_FRESH_CAP   BIT5
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_10_MASK          (\
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CACHE_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_FRESH_CAP)
+///
+/// SPDM GET_CAPABILITIES response Flags (1.1)
+///
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP                     BIT6
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP                         BIT7
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP                    BIT8
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP                      BIT9
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP                         (BIT10 | BIT11)
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP_RESPONDER               BIT10
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP_RESPONDER_WITH_CONTEXT  BIT11
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP                       BIT12
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP                       BIT13
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_UPD_CAP                     BIT14
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP      BIT15
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PUB_KEY_ID_CAP                  BIT16
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_11_MASK                         (\
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_10_MASK | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_UPD_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PUB_KEY_ID_CAP)
+///
+/// SPDM GET_CAPABILITIES response Flags (1.2)
+///
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP       BIT17
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP  BIT18
 
+///
+/// SPDM GET_CAPABILITIES response Flags (1.2.1)
+///
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP            BIT19
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP                 BIT20
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP  BIT21
+#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_12_MASK                 (\
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_11_MASK | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP | \
+        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP)
 ///
 /// SPDM NEGOTIATE_ALGORITHMS request
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == Number of Algorithms Structure Tables
+  // Param2 == RSVD
   UINT16                 Length;
   UINT8                  MeasurementSpecification;
-  UINT8                  Reserved;
+
+  // OtherParamsSupport is added in 1.2.
+  // BIT[0:3]=opaque_data_format support
+  // BIT[4:7]=Reserved
+  UINT8                  OtherParamsSupport;
   UINT32                 BaseAsymAlgo;
   UINT32                 BaseHashAlgo;
   UINT8                  Reserved2[12];
   UINT8                  ExtAsymCount;
   UINT8                  ExtHashCount;
   UINT16                 Reserved3;
-  // UINT32               ExtAsym[ExtAsymCount];
-  // UINT32               ExtHash[ExtHashCount];
+  // SPDM_EXTENDED_ALGORITHM                 ExtAsym[ExtAsymCount];
+  // SPDM_EXTENDED_ALGORITHM                 ExtHash[ExtHashCount];
+  // Below field is added in 1.1.
+  // SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE  AlgStruct[Param1];
 } SPDM_NEGOTIATE_ALGORITHMS_REQUEST;
 
+#define SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_LENGTH_VERSION_10         BIT6
+#define SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_LENGTH_VERSION_11         BIT7
+#define SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_LENGTH_VERSION_12         BIT7
+#define SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_EXT_ALG_COUNT_VERSION_10  BIT3
+#define SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_EXT_ALG_COUNT_VERSION_11  (BIT4 | BIT2)
+#define SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_EXT_ALG_COUNT_VERSION_12  (BIT4 | BIT2)
+
+typedef struct {
+  UINT8    AlgType;
+  UINT8    AlgCount;             // BIT[0:3]=ExtAlgCount, BIT[4:7]=FixedAlgByteCount
+  // UINT8                AlgSupported[FixedAlgByteCount];
+  // UINT32               AlgExternal[ExtAlgCount];
+} SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE;
+
+typedef struct {
+  UINT8    ExtAlgCount       : 4;
+  UINT8    FixedAlgByteCount : 4;
+} SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_COUNT;
+
+#define SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG  4
+
+#define SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE                2
+#define SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD               3
+#define SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG  4
+#define SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE       5
+
+typedef struct {
+  UINT8     AlgType;
+  UINT8     AlgCount;
+  UINT16    AlgSupported;
+} SPDM_NEGOTIATE_ALGORITHMS_COMMON_STRUCT_TABLE;
+
 ///
-/// SPDM NEGOTIATE_ALGORITHMS request BaseAsymAlgo
+/// SPDM NEGOTIATE_ALGORITHMS request BaseAsymAlgo/REQ_BASE_ASYM_ALG
 ///
 #define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048          BIT0
 #define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048          BIT1
@@ -135,6 +334,13 @@ typedef struct {
 #define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384  BIT7
 #define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521  BIT8
 
+///
+/// SPDM NEGOTIATE_ALGORITHMS request base_asym_algo/REQ_BASE_ASYM_ALG (1.2)
+///
+#define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256  BIT9
+#define SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519             BIT10
+#define SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448               BIT11
+
 ///
 /// SPDM NEGOTIATE_ALGORITHMS request BaseHashAlgo
 ///
@@ -145,14 +351,56 @@ typedef struct {
 #define SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384  BIT4
 #define SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512  BIT5
 
+///
+/// SPDM NEGOTIATE_ALGORITHMS request base_hash_algo (1.2)
+///
+#define SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256  BIT6
+
+///
+/// SPDM NEGOTIATE_ALGORITHMS request DHE
+///
+#define SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048   BIT0
+#define SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072   BIT1
+#define SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096   BIT2
+#define SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1  BIT3
+#define SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1  BIT4
+#define SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1  BIT5
+
+///
+/// SPDM NEGOTIATE_ALGORITHMS request DHE (1.2)
+///
+#define SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256  BIT6
+
+///
+/// SPDM NEGOTIATE_ALGORITHMS request AEAD
+///
+#define SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM        BIT0
+#define SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM        BIT1
+#define SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305  BIT2
+
+///
+/// SPDM NEGOTIATE_ALGORITHMS request AEAD (1.2)
+///
+#define SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM  BIT3
+///
+/// SPDM NEGOTIATE_ALGORITHMS request KEY_SCHEDULE
+///
+#define SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH  BIT0
+
 ///
 /// SPDM NEGOTIATE_ALGORITHMS response
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == Number of Algorithms Structure Tables
+  // Param2 == RSVD
   UINT16                 Length;
   UINT8                  MeasurementSpecificationSel;
-  UINT8                  Reserved;
+
+  // OtherParamsSelection is added in 1.2.
+  // BIT[0:3]=opaque_data_format select,
+  // BIT[4:7]=Reserved
+  UINT8                  OtherParamsSelection;
   UINT32                 MeasurementHashAlgo;
   UINT32                 BaseAsymSel;
   UINT32                 BaseHashSel;
@@ -160,8 +408,10 @@ typedef struct {
   UINT8                  ExtAsymSelCount;
   UINT8                  ExtHashSelCount;
   UINT16                 Reserved3;
-  // UINT32               ExtAsymSel[ExtAsymSelCount];
-  // UINT32               ExtHashSel[ExtHashSelCount];
+  // SPDM_EXTENDED_ALGORITHM                 ExtAsymSel[ExtAsymSelCount];
+  // SPDM_EXTENDED_ALGORITHM                 ExtHashSel[ExtHashSelCount];
+  // Below field is added in 1.1.
+  // SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE  AlgStruct[Param1];
 } SPDM_ALGORITHMS_RESPONSE;
 
 ///
@@ -175,11 +425,57 @@ typedef struct {
 #define SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_384     BIT5
 #define SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_512     BIT6
 
+///
+/// SPDM NEGOTIATE_ALGORITHMS response measurement_hash_algo (1.2)
+///
+#define SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SM3_256  BIT7
+
+///
+/// SPDM Opaque Data Format (1.2)
+///
+#define SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE  0x0
+#define SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0     0x1
+#define SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1     0x2
+#define SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK  0xF
+
+///
+/// SPDM Opaque Data Format 1 (1.2)
+///
+typedef struct {
+  UINT8    TotalElements;
+  UINT8    Reserved[3];
+  // opaque_element_table_t  opaque_list[];
+} SPDM_GENERAL_OPAQUE_DATA_TABLE_HEADER;
+
+///
+/// SPDM extended algorithm
+///
+typedef struct {
+  UINT8     RegistryID;
+  UINT8     Reserved;
+  UINT16    AlgorithmID;
+} SPDM_EXTENDED_ALGORITHM;
+
+///
+/// SPDM RegistryID
+///
+#define SPDM_REGISTRY_ID_DMTF     0
+#define SPDM_REGISTRY_ID_TCG      1
+#define SPDM_REGISTRY_ID_USB      2
+#define SPDM_REGISTRY_ID_PCISIG   3
+#define SPDM_REGISTRY_ID_IANA     4
+#define SPDM_REGISTRY_ID_HDBASET  5
+#define SPDM_REGISTRY_ID_MIPI     6
+#define SPDM_REGISTRY_ID_CXL      7
+#define SPDM_REGISTRY_ID_JEDEC    8
+
 ///
 /// SPDM GET_DIGESTS request
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
 } SPDM_GET_DIGESTS_REQUEST;
 
 ///
@@ -187,33 +483,69 @@ typedef struct {
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
-  // UINT8                Digest[DigestSize];
+  // Param1 == RSVD
+  // Param2 == SlotMask
+  // UINT8                Digest[DigestSize][SlotCount];
 } SPDM_DIGESTS_RESPONSE;
 
 ///
-/// SPDM GET_DIGESTS request
+/// SPDM GET_CERTIFICATE request
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == SlotNum
+  // Param2 == RSVD
   UINT16                 Offset;
   UINT16                 Length;
 } SPDM_GET_CERTIFICATE_REQUEST;
 
+#define SPDM_GET_CERTIFICATE_REQUEST_SLOT_ID_MASK  0xF
 ///
-/// SPDM GET_DIGESTS response
+/// SPDM GET_CERTIFICATE response
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == SlotNum
+  // Param2 == RSVD
   UINT16                 PortionLength;
   UINT16                 RemainderLength;
-  // UINT8                CertChain[CertChainSize];
+  // UINT8                CertChain[PortionLength];
 } SPDM_CERTIFICATE_RESPONSE;
 
+#define SPDM_CERTIFICATE_RESPONSE_SLOT_ID_MASK  0xF
+
+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;
+
+///
+/// Maximum size, in bytes, of a certificate chain.
+///
+#define SPDM_MAX_CERTIFICATE_CHAIN_SIZE  65535
 ///
 /// SPDM CHALLENGE request
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == SlotNum
+  // Param2 == HashType
   UINT8                  Nonce[32];
 } SPDM_CHALLENGE_REQUEST;
 
@@ -222,6 +554,8 @@ typedef struct {
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == ResponseAttribute
+  // Param2 == SlotMask
   // UINT8                CertChainHash[DigestSize];
   // UINT8                Nonce[32];
   // UINT8                MeasurementSummaryHash[DigestSize];
@@ -230,14 +564,75 @@ typedef struct {
   // UINT8                Signature[KeySize];
 } SPDM_CHALLENGE_AUTH_RESPONSE;
 
+///
+/// SPDM generic request measurement summary HashType
+///
+#define SPDM_REQUEST_NO_MEASUREMENT_SUMMARY_HASH     0
+#define SPDM_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH  1
+#define SPDM_REQUEST_ALL_MEASUREMENTS_HASH           0xFF
+
+///
+/// SPDM CHALLENGE request measurement summary HashType
+///
+#define SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH  SPDM_REQUEST_NO_MEASUREMENT_SUMMARY_HASH
+#define SPDM_CHALLENGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH \
+    SPDM_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH
+#define SPDM_CHALLENGE_REQUEST_ALL_MEASUREMENTS_HASH  SPDM_REQUEST_ALL_MEASUREMENTS_HASH
+
+#define SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_SLOT_ID_MASK  0xF
+
+typedef struct {
+  UINT8    SlotNum         : 4;
+  UINT8    Reserved        : 3;
+  UINT8    BasicMutAuthReq : 1;
+} SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE;
+
+///
+/// Deprecated in SPDM 1.2
+///
+#define SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_BASIC_MUT_AUTH_REQ  BIT7
+
+#define SPDM_CHALLENGE_AUTH_SIGN_CONTEXT           "responder-challenge_auth signing"
+#define SPDM_CHALLENGE_AUTH_SIGN_CONTEXT_SIZE      (sizeof(SPDM_CHALLENGE_AUTH_SIGN_CONTEXT) - 1)
+#define SPDM_MUT_CHALLENGE_AUTH_SIGN_CONTEXT       "requester-challenge_auth signing"
+#define SPDM_MUT_CHALLENGE_AUTH_SIGN_CONTEXT_SIZE  (sizeof(SPDM_MUT_CHALLENGE_AUTH_SIGN_CONTEXT) - 1)
+
 ///
 /// SPDM GET_MEASUREMENTS request
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == Attributes
+  // Param2 == MeasurementOperation
   UINT8                  Nonce[32];
+  // Below field is added in 1.1.
+  UINT8                  SlotIDParam; // BIT[0:3]=SlotNum, BIT[4:7]=Reserved
 } SPDM_GET_MEASUREMENTS_REQUEST;
 
+typedef struct {
+  UINT8    SlotNum  : 4;
+  UINT8    Reserved : 4;
+} SPDM_GET_MEASUREMENTS_REQUEST_SLOT_ID_PARAMETER;
+
+#define SPDM_GET_MEASUREMENTS_REQUEST_SLOT_ID_MASK  0xF
+
+///
+/// SPDM GET_MEASUREMENTS request Attributes
+///
+#define SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE         BIT0
+#define SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_RAW_BIT_STREAM_REQUESTED   BIT1
+#define SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_NEW_MEASUREMENT_REQUESTED  BIT2
+
+///
+/// SPDM GET_MEASUREMENTS request MeasurementOperation
+///
+#define SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS  0
+
+///
+/// SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_INDEX
+///
+#define SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_ALL_MEASUREMENTS  0xFF
+
 ///
 /// SPDM MEASUREMENTS block common header
 ///
@@ -259,6 +654,17 @@ typedef struct {
   // 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;
+
+typedef struct {
+  UINT8    Content      : 7;
+  UINT8    Presentation : 1;
+} SPDM_MEASUREMENTS_BLOCK_MEASUREMENT_TYPE;
+
 ///
 /// SPDM MEASUREMENTS block MeasurementValueType
 ///
@@ -266,13 +672,54 @@ typedef struct {
 #define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MUTABLE_FIRMWARE        1
 #define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_HARDWARE_CONFIGURATION  2
 #define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_FIRMWARE_CONFIGURATION  3
+#define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MEASUREMENT_MANIFEST    4
+#define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_DEVICE_MODE             5
+#define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_VERSION                 6
+#define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_SECURE_VERSION_NUMBER   7
+#define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MASK                    0x7
 #define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_RAW_BIT_STREAM          BIT7
 
+///
+/// SPDM MEASUREMENTS block index
+///
+#define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_INDEX_MEASUREMENT_MANIFEST  0xFD
+#define SPDM_MEASUREMENT_BLOCK_MEASUREMENT_INDEX_DEVICE_MODE           0xFE
+
+///
+/// SPDM MEASUREMENTS device mode
+///
+typedef struct {
+  UINT32    OperationalModeCapabilities;
+  UINT32    OperationalModeState;
+  UINT32    DeviceModeCapabilities;
+  UINT32    DeviceModeState;
+} SPDM_MEASUREMENT_DEVICE_MODE;
+
+#define SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_MANUFACTURING_MODE   BIT0
+#define SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_VALIDATION_MODE      BIT1
+#define SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_NORMAL_MODE          BIT2
+#define SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_RECOVERY_MODE        BIT3
+#define SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_RMA_MODE             BIT4
+#define SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_DECOMMISSIONED_MODE  BIT5
+
+#define SPDM_MEASUREMENT_DEVICE_MODE_NON_INVASIVE_DEBUG_MODE_IS_ACTIVE              BIT0
+#define SPDM_MEASUREMENT_DEVICE_MODE_INVASIVE_DEBUG_MODE_IS_ACTIVE                  BIT1
+#define SPDM_MEASUREMENT_DEVICE_MODE_NON_INVASIVE_DEBUG_MODE_HAS_BEEN_ACTIVE        BIT2
+#define SPDM_MEASUREMENT_DEVICE_MODE_INVASIVE_DEBUG_MODE_HAS_BEEN_ACTIVE            BIT3
+#define SPDM_MEASUREMENT_DEVICE_MODE_INVASIVE_DEBUG_MODE_HAS_BEEN_ACTIVE_AFTER_MFG  BIT4
+
+///
+/// SPDM MEASUREMENTS SVN
+///
+typedef UINT64 SPDM_MEASUREMENTS_SECURE_VERSION_NUMBER;
+
 ///
 /// SPDM GET_MEASUREMENTS response
 ///
 typedef struct {
   SPDM_MESSAGE_HEADER    Header;
+  // Param1 == TotalNumberOfMeasurement/RSVD
+  // Param2 == SlotNum
   UINT8                  NumberOfBlocks;
   UINT8                  MeasurementRecordLength[3];
   // UINT8                MeasurementRecord[MeasurementRecordLength];
@@ -282,6 +729,21 @@ typedef struct {
   // UINT8                Signature[KeySize];
 } SPDM_MEASUREMENTS_RESPONSE;
 
+#define SPDM_MEASUREMENTS_RESPONSE_SLOT_ID_MASK  0xF
+
+///
+/// SPDM MEASUREMENTS content changed
+///
+#define SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK          0x30
+#define SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_NO_DETECTION  0x00
+#define SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_DETECTED      0x10
+#define SPDM_MEASUREMENTS_RESPONSE_CONTENT_NO_CHANGE_DETECTED   0x20
+
+#define SPDM_MEASUREMENTS_SIGN_CONTEXT       "responder-measurements signing"
+#define SPDM_MEASUREMENTS_SIGN_CONTEXT_SIZE  (sizeof(SPDM_MEASUREMENTS_SIGN_CONTEXT) - 1)
+
+#define SPDM_MEL_SPECIFICATION_DMTF  BIT0
+
 ///
 /// SPDM ERROR response
 ///
@@ -292,17 +754,69 @@ typedef struct {
   // UINT8                ExtendedErrorData[];
 } SPDM_ERROR_RESPONSE;
 
+#define SPDM_EXTENDED_ERROR_DATA_MAX_SIZE  32
+
 ///
 /// SPDM error code
 ///
-#define SPDM_ERROR_CODE_INVALID_REQUEST         0x01
-#define SPDM_ERROR_CODE_BUSY                    0x03
-#define SPDM_ERROR_CODE_UNEXPECTED_REQUEST      0x04
-#define SPDM_ERROR_CODE_UNSPECIFIED             0x05
-#define SPDM_ERROR_CODE_UNSUPPORTED_REQUEST     0x07
-#define SPDM_ERROR_CODE_MAJOR_VERSION_MISMATCH  0x41
-#define SPDM_ERROR_CODE_RESPONSE_NOT_READY      0x42
-#define SPDM_ERROR_CODE_REQUEST_RESYNCH         0x43
+#define SPDM_ERROR_CODE_INVALID_REQUEST      0x01
+#define SPDM_ERROR_CODE_BUSY                 0x03
+#define SPDM_ERROR_CODE_UNEXPECTED_REQUEST   0x04
+#define SPDM_ERROR_CODE_UNSPECIFIED          0x05
+#define SPDM_ERROR_CODE_UNSUPPORTED_REQUEST  0x07
+#define SPDM_ERROR_CODE_VERSION_MISMATCH     0x41
+#define SPDM_ERROR_CODE_RESPONSE_NOT_READY   0x42
+#define SPDM_ERROR_CODE_REQUEST_RESYNCH      0x43
+#define SPDM_ERROR_CODE_VENDOR_DEFINED       0xFF
+///
+/// SPDM error code (1.1)
+///
+#define SPDM_ERROR_CODE_DECRYPT_ERROR           0x06
+#define SPDM_ERROR_CODE_REQUEST_IN_FLIGHT       0x08
+#define SPDM_ERROR_CODE_INVALID_RESPONSE_CODE   0x09
+#define SPDM_ERROR_CODE_SESSION_LIMIT_EXCEEDED  0x0A
+
+///
+/// SPDM error code (1.2)
+///
+#define SPDM_ERROR_CODE_SESSION_REQUIRED    0x0B
+#define SPDM_ERROR_CODE_RESET_REQUIRED      0x0C
+#define SPDM_ERROR_CODE_RESPONSE_TOO_LARGE  0x0D
+#define SPDM_ERROR_CODE_REQUEST_TOO_LARGE   0x0E
+#define SPDM_ERROR_CODE_LARGE_RESPONSE      0x0F
+#define SPDM_ERROR_CODE_MESSAGE_LOST        0x10
+///
+/// SPDM ResponseNotReady extended data
+///
+typedef struct {
+  UINT8    RDTExponent;
+  UINT8    RequestCode;
+  UINT8    Token;
+  UINT8    Rdtm;
+} SPDM_ERROR_DATA_RESPONSE_NOT_READY;
+
+typedef struct {
+  SPDM_MESSAGE_HEADER                   Header;
+  // Param1 == Error Code
+  // Param2 == Error Data
+  SPDM_ERROR_DATA_RESPONSE_NOT_READY    ExtendErrorData;
+} SPDM_ERROR_RESPONSE_DATA_RESPONSE_NOT_READY;
+
+///
+/// SPDM LargeResponse extended data
+///
+typedef struct {
+  UINT8    Handle;
+} SPDM_ERROR_DATA_LARGE_RESPONSE;
+
+typedef struct {
+  SPDM_MESSAGE_HEADER               Header;
+
+  // param1 == Error Code
+  // param2 == Error data
+  //
+  SPDM_ERROR_DATA_LARGE_RESPONSE    ExtendErrorData;
+} SPDM_ERROR_RESPONSE_LARGE_RESPONSE;
 
 ///
 /// SPDM RESPONSE_IF_READY request
@@ -313,6 +827,504 @@ typedef struct {
   // Param2 == Token
 } SPDM_RESPONSE_IF_READY_REQUEST;
 
+///
+/// Maximum size of a vendor defined message data length
+/// limited by the length field size which is 2 bytes
+///
+#define SPDM_MAX_VENDOR_DEFINED_DATA_LEN  65535
+
+///
+/// Maximum size of a vendor defined vendor id length
+/// limited by the length field size which is 1 byte
+///
+#define SPDM_MAX_VENDOR_ID_LENGTH  255
+
+///
+/// SPDM VENDOR_DEFINED request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
+  UINT16                 StandardID;
+  UINT8                  Len;
+  // UINT8                VendorID[Len];
+  // UINT16               PayloadLength;
+  // UINT8                VendorDefinedPayload[PayloadLength];
+} SPDM_VENDOR_DEFINED_REQUEST_MSG;
+
+///
+/// SPDM VENDOR_DEFINED response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
+  UINT16                 StandardID;
+  UINT8                  Len;
+  // UINT8                VendorID[Len];
+  // UINT16               PayloadLength;
+  // UINT8                VendorDefinedPayload[PayloadLength];
+} SPDM_VENDOR_DEFINED_RESPONSE_MSG;
+
+//
+// Below command is defined in SPDM 1.1
+//
+
+///
+/// SPDM KEY_EXCHANGE request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == HashType
+  // Param2 == SlotNum
+  UINT16                 ReqSessionID;
+  UINT16                 Reserved;
+  UINT8                  RandomData[32];
+  // UINT8                ExchangeData[D];
+  // UINT16               OpaqueLength;
+  // UINT8                OpaqueData[OpaqueLength];
+} SPDM_KEY_EXCHANGE_REQUEST;
+
+///
+/// SPDM KEY_EXCHANGE request session_policy
+///
+#define SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_TERMINATION_POLICY_RUNTIME_UPDATE  BIT0
+
+///
+/// SPDM KEY_EXCHANGE request measurement summary HashType
+///
+#define SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH \
+    SPDM_REQUEST_NO_MEASUREMENT_SUMMARY_HASH
+#define SPDM_KEY_EXCHANGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH \
+    SPDM_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH
+#define SPDM_KEY_EXCHANGE_REQUEST_ALL_MEASUREMENTS_HASH  SPDM_REQUEST_ALL_MEASUREMENTS_HASH
+
+///
+/// SPDM KEY_EXCHANGE response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == HeartbeatPeriod
+  // Param2 == RSVD
+  UINT16                 RspSessionID;
+  UINT8                  MutAuthRequested;
+  UINT8                  ReqSlotIDParam;
+  UINT8                  RandomData[32];
+  // UINT8                ExchangeData[D];
+  // UINT8                MeasurementSummaryHash[DigestSize];
+  // UINT16               OpaqueLength;
+  // UINT8                OpaqueData[OpaqueLength];
+  // UINT8                Signature[S];
+  // UINT8                ResponderVerifyData[H];
+} SPDM_KEY_EXCHANGE_RESPONSE;
+
+///
+/// SPDM KEY_EXCHANGE response MutAuthRequested
+///
+#define SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED                     BIT0
+#define SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST  BIT1
+#define SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS    BIT2
+
+#define SPDM_KEY_EXCHANGE_RESPONSE_SIGN_CONTEXT  "responder-key_exchange_rsp signing"
+#define SPDM_KEY_EXCHANGE_RESPONSE_SIGN_CONTEXT_SIZE \
+    (sizeof(SPDM_KEY_EXCHANGE_RESPONSE_SIGN_CONTEXT) - 1)
+
+#define SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT  "Requester-KEP-dmtf-spdm-v1.2"
+#define SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT_SIZE \
+    (sizeof(SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT) - 1)
+
+#define SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT  "Responder-KEP-dmtf-spdm-v1.2"
+#define SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT_SIZE \
+    (sizeof(SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT) - 1)
+
+///
+/// SPDM FINISH request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == SignatureIncluded
+  // Param2 == ReqSlotNum
+  // UINT8                Signature[S];
+  // UINT8                RequesterVerifyData[H];
+} SPDM_FINISH_REQUEST;
+
+///
+/// SPDM FINISH request SignatureIncluded
+///
+#define SPDM_FINISH_REQUEST_ATTRIBUTES_SIGNATURE_INCLUDED  BIT0
+
+///
+/// SPDM FINISH response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
+  // UINT8                ResponderVerifyData[H];
+} SPDM_FINISH_RESPONSE;
+
+#define SPDM_FINISH_SIGN_CONTEXT       "requester-finish signing"
+#define SPDM_FINISH_SIGN_CONTEXT_SIZE  (sizeof(SPDM_FINISH_SIGN_CONTEXT) - 1)
+
+///
+/// SPDM PSK_EXCHANGE request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == HashType
+  // Param2 == RSVD/session_policy (1.2)
+  UINT16                 ReqSessionID;
+  UINT16                 PSKHintLength;
+  UINT16                 RequesterContextLength;
+  UINT16                 OpaqueLength;
+  // UINT8                PSKHint[PSKHintLength];
+  // UINT8                RequesterContext[RequesterContextLength];
+  // UINT8                OpaqueData[OpaqueLength];
+} SPDM_PSK_EXCHANGE_REQUEST;
+
+///
+/// SPDM PSK_EXCHANGE request measurement summary HashType
+///
+#define SPDM_PSK_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH \
+    SPDM_REQUEST_NO_MEASUREMENT_SUMMARY_HASH
+#define SPDM_PSK_EXCHANGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH \
+    SPDM_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH
+#define SPDM_PSK_EXCHANGE_REQUEST_ALL_MEASUREMENTS_HASH  SPDM_REQUEST_ALL_MEASUREMENTS_HASH
+
+///
+/// SPDM PSK_EXCHANGE response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == HeartbeatPeriod
+  // Param2 == RSVD
+  UINT16                 RspSessionID;
+  UINT16                 Reserved;
+  UINT16                 ResponderContextLength;
+  UINT16                 OpaqueLength;
+  // UINT8                MeasurementSummaryHash[DigestSize];
+  // UINT8                ResponderContext[ResponderContextLength];
+  // UINT8                OpaqueData[OpaqueLength];
+  // UINT8                ResponderVerifyData[H];
+} SPDM_PSK_EXCHANGE_RESPONSE;
+
+///
+/// SPDM PSK_FINISH request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
+  // UINT8                RequesterVerifyData[H];
+} SPDM_PSK_FINISH_REQUEST;
+
+///
+/// SPDM PSK_FINISH response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
+} SPDM_PSK_FINISH_RESPONSE;
+
+///
+/// SPDM HEARTBEAT request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
+} SPDM_HEARTBEAT_REQUEST;
+
+///
+/// SPDM HEARTBEAT response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
+} SPDM_HEARTBEAT_RESPONSE;
+
+///
+/// SPDM KEY_UPDATE request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == KeyOperation
+  // Param2 == Tag
+} SPDM_KEY_UPDATE_REQUEST;
+
+///
+/// SPDM KEY_UPDATE Operations Table
+///
+#define SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_KEY       1
+#define SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_ALL_KEYS  2
+#define SPDM_KEY_UPDATE_OPERATIONS_TABLE_VERIFY_NEW_KEY   3
+
+///
+/// SPDM KEY_UPDATE response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == KeyOperation
+  // Param2 == Tag
+} SPDM_KEY_UPDATE_RESPONSE;
+
+///
+/// SPDM GET_ENCAPSULATED_REQUEST request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
+} SPDM_GET_ENCAPSULATED_REQUEST_REQUEST;
+
+///
+/// SPDM ENCAPSULATED_REQUEST response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RequestID
+  // Param2 == RSVD
+  // UINT8                EncapsulatedRequest[];
+} SPDM_ENCAPSULATED_REQUEST_RESPONSE;
+
+///
+/// SPDM DELIVER_ENCAPSULATED_RESPONSE request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RequestID
+  // Param2 == RSVD
+  // UINT8                EncapsulatedResponse[];
+} SPDM_DELIVER_ENCAPSULATED_RESPONSE_REQUEST;
+
+///
+/// SPDM ENCAPSULATED_RESPONSE_ACK response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RequestID
+  // Param2 == PayloadType
+  // below 4 bytes are added in 1.2.
+  UINT8                  AckRequestId;
+  UINT8                  Reserved[3];
+  // UINT8                EncapsulatedRequest[];
+} SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE;
+
+///
+/// SPDM ENCAPSULATED_RESPONSE_ACK_RESPONSE Payload Type
+///
+#define SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_ABSENT           0
+#define SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_PRESENT          1
+#define SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_REQ_SLOT_NUMBER  2
+
+///
+/// SPDM END_SESSION request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == EndSessionRequestAttributes
+  // Param2 == RSVD
+} SPDM_END_SESSION_REQUEST;
+
+///
+/// SPDM END_SESSION request Attributes
+///
+#define SPDM_END_SESSION_REQUEST_ATTRIBUTES_PRESERVE_NEGOTIATED_STATE_CLEAR  BIT0
+
+///
+/// SPDM END_SESSION response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  // Param1 == RSVD
+  // Param2 == RSVD
+} SPDM_END_SESSION_RESPONSE;
+
+//
+// Below command is defined in SPDM 1.2
+//
+
+///
+/// SPDM SET_CERTIFICATE request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+
+  // param1 == BIT[0:3]=slot_id, BIT[4:7]=RSVD
+  // param2 == RSVD
+  // param1 and param2 are updated in 1.3
+  // param1 == Request attributes, BIT[0:3]=slot_id, BIT[4:6]=SetCertModel, BIT[7]=Erase
+  // param2 == KeyPairID
+  // void * CertChain
+} SPDM_SET_CERTIFICATE_REQUEST;
+
+#define SPDM_SET_CERTIFICATE_REQUEST_SLOT_ID_MASK  0xF
+
+///
+/// SPDM SET_CERTIFICATE request Attributes
+///
+#define SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_CERT_MODEL_MASK    0x70
+#define SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_CERT_MODEL_OFFSET  4
+#define SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_ERASE              0x80
+
+///
+/// SPDM SET_CERTIFICATE_RSP response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+
+  // param1 == BIT[0:3]=slot_id, BIT[4:7]=RSVD
+  // param2 == RSVD
+} SPDM_SET_CERTIFICATE_RESPONSE;
+
+#define SPDM_SET_CERTIFICATE_RESPONSE_SLOT_ID_MASK  0xF
+
+///
+/// SPDM GET_CSR request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+  UINT16                 RequesterInfoLength;
+  UINT16                 OpaqueDataLength;
+
+  // UINT8 RequesterInfo[RequesterInfoLength];
+  // UINT8 OpaqueData[OpaqueDataLength];
+} SPDM_GET_CSR_REQUEST;
+
+///
+/// SPDM GET_CSR request Attributes
+///
+#define SPDM_GET_CSR_REQUEST_ATTRIBUTES_CERT_MODEL_MASK          0x07
+#define SPDM_GET_CSR_REQUEST_ATTRIBUTES_CSR_TRACKING_TAG_MASK    0x38
+#define SPDM_GET_CSR_REQUEST_ATTRIBUTES_CSR_TRACKING_TAG_OFFSET  3
+#define SPDM_GET_CSR_REQUEST_ATTRIBUTES_OVERWRITE                0x80
+#define SPDM_GET_CSR_REQUEST_ATTRIBUTES_MAX_CSR_CERT_MODEL       4
+
+///
+/// Maximum size, in bytes, of a CSR.
+///
+#define SPDM_MAX_CSR_SIZE  65535
+
+///
+/// SPDM CSR response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+
+  // param1 == RSVD
+  // param2 == RSVD
+  UINT16                 CsrLength;
+  UINT16                 Reserved;
+} SPDM_CSR_RESPONSE;
+
+///
+/// SPDM CHUNK_SEND request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+
+  // param1 - Request Attributes
+  // param2 - Handle
+  UINT16                 ChunkSeqNo;
+  UINT16                 Reserved;
+  UINT32                 ChunkSize;
+
+  // UINT32 LargeMessageSize;
+  // UINT8  SpdmChunk[ChunkSize];
+} SPDM_CHUNK_SEND_REQUEST;
+
+#define SPDM_CHUNK_SEND_REQUEST_ATTRIBUTE_LAST_CHUNK  (1 << 0)
+
+///
+/// SPDM CHUNK_SEND_ACK response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+
+  // param1 - Response Attributes
+  // param2 - Handle
+  UINT16                 ChunkSeqNo;
+  // UINT8 response_to_large_request[variable]
+} SPDM_CHUNK_SEND_ACK_RESPONSE;
+
+#define SPDM_CHUNK_SEND_ACK_RESPONSE_ATTRIBUTE_EARLY_ERROR_DETECTED  (1 << 0)
+
+///
+/// SPDM CHUNK_GET request
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+
+  // param1 - Reserved
+  // param2 - Handle
+  UINT16                 ChunkSeqNo;
+} SPDM_CHUNK_GET_REQUEST;
+
+///
+/// SPDM CHUNK_RESPONSE response
+///
+typedef struct {
+  SPDM_MESSAGE_HEADER    Header;
+
+  // param1 - Response Attributes
+  // param2 - Handle
+  UINT16                 ChunkSeqNo;
+  UINT16                 Reserved;
+  UINT32                 ChunkSize;
+
+  // UINT32 LargeMessageSize;
+  // UINT8  SpdmChunk[ChunkSize];
+} SPDM_CHUNK_RESPONSE_RESPONSE;
+
+#define SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK  (1 << 0)
 #pragma pack()
 
+#define SPDM_VERSION_1_1_BIN_CONCAT_LABEL  "spdm1.1 "
+#define SPDM_VERSION_1_2_BIN_CONCAT_LABEL  "spdm1.2 "
+#define SPDM_BIN_STR_0_LABEL               "derived"
+#define SPDM_BIN_STR_1_LABEL               "req hs data"
+#define SPDM_BIN_STR_2_LABEL               "rsp hs data"
+#define SPDM_BIN_STR_3_LABEL               "req app data"
+#define SPDM_BIN_STR_4_LABEL               "rsp app data"
+#define SPDM_BIN_STR_5_LABEL               "key"
+#define SPDM_BIN_STR_6_LABEL               "iv"
+#define SPDM_BIN_STR_7_LABEL               "finished"
+#define SPDM_BIN_STR_8_LABEL               "exp master"
+#define SPDM_BIN_STR_9_LABEL               "traffic upd"
+
+///
+/// The maximum amount of time in microseconds the Responder has to provide a response
+/// to requests that do not require cryptographic processing.
+///
+#define SPDM_ST1_VALUE_US  100000
+
+///
+/// id-DMTF 1.3.6.1.4.1.412
+///
+#define SPDM_OID_DMTF \
+    {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C }
+// id-DMTF-spdm, { id-DMTF 274 }, 1.3.6.1.4.1.412.274
+#define SPDM_OID_DMTF_SPDM \
+    {0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12 }
+// id-DMTF-device-info, { id-DMTF-spdm 1 }, 1.3.6.1.4.1.412.274.1
+#define SPDM_OID_DMTF_DEVICE_INFO \
+    {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x01 }
+// id-DMTF-hardware-identity, { id-DMTF-spdm 2 }, 1.3.6.1.4.1.412.274.2
+#define SPDM_OID_DMTF_HARDWARE_IDENTITY \
+    {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x02 }
+// id-DMTF-eku-responder-auth, { id-DMTF-spdm 3 }, 1.3.6.1.4.1.412.274.3
+#define SPDM_OID_DMTF_EKU_RESPONDER_AUTH \
+    {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x03 }
+// id-DMTF-eku-requester-auth, { id-DMTF-spdm 4 }, 1.3.6.1.4.1.412.274.4
+#define SPDM_OID_DMTF_EKU_REQUESTER_AUTH \
+    {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x04 }
+// id-DMTF-mutable-certificate, { id-DMTF-spdm 5 }, 1.3.6.1.4.1.412.274.5
+#define SPDM_OID_DMTF_MUTABLE_CERTIFICATE \
+    {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x05 }
+// id-DMTF-SPDM-extension, { id-DMTF-spdm 6 }, 1.3.6.1.4.1.412.274.6
+#define SPDM_OID_DMTF_SPDM_EXTENSION \
+    {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C, 0x82, 0x12, 0x06 }
 #endif
-- 
2.26.2.windows.1



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



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [edk2-devel] [PATCH v2 2/9] MdePkg: Add TCG PFP 1.06 support.
  2024-04-08  1:46 [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 1/9] MdePkg: Add SPDM1.2 support Wenxing Hou
@ 2024-04-08  1:46 ` Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 3/9] MdePkg: Add devAuthBoot GlobalVariable Wenxing Hou
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Wenxing Hou @ 2024-04-08  1:46 UTC (permalink / raw)
  To: devel; +Cc: Michael D Kinney, Liming Gao, Zhiguang Liu, Jiewen Yao

Add support for
TCG PC Client Platform Firmware Profile Specification 1.06.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 MdePkg/Include/IndustryStandard/Spdm.h        |   4 +-
 .../IndustryStandard/UefiTcgPlatform.h        | 186 +++++++++++++++++-
 2 files changed, 187 insertions(+), 3 deletions(-)

diff --git a/MdePkg/Include/IndustryStandard/Spdm.h b/MdePkg/Include/IndustryStandard/Spdm.h
index 7940caa95e..3d511b4768 100644
--- a/MdePkg/Include/IndustryStandard/Spdm.h
+++ b/MdePkg/Include/IndustryStandard/Spdm.h
@@ -1302,7 +1302,9 @@ typedef struct {
 #define SPDM_ST1_VALUE_US  100000
 
 ///
-/// id-DMTF 1.3.6.1.4.1.412
+/// id-DMTF 1.3.6.1.4.1.412.
+/// These OID are defiend in ANNEX C (informative) OID reference section from the DMTF SPDM spec.
+/// https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.2.2.pdf
 ///
 #define SPDM_OID_DMTF \
     {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1C }
diff --git a/MdePkg/Include/IndustryStandard/UefiTcgPlatform.h b/MdePkg/Include/IndustryStandard/UefiTcgPlatform.h
index e07840c9dd..61bd4e4667 100644
--- a/MdePkg/Include/IndustryStandard/UefiTcgPlatform.h
+++ b/MdePkg/Include/IndustryStandard/UefiTcgPlatform.h
@@ -1,8 +1,8 @@
 /** @file
   TCG EFI Platform Definition in TCG_EFI_Platform_1_20_Final and
-  TCG PC Client Platform Firmware Profile Specification, Revision 1.05
+  TCG PC Client Platform Firmware Profile Specification, Revision 1.06
 
-  Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -53,6 +53,18 @@
 #define EV_EFI_VARIABLE_AUTHORITY         (EV_EFI_EVENT_BASE + 0xE0)
 #define EV_EFI_SPDM_FIRMWARE_BLOB         (EV_EFI_EVENT_BASE + 0xE1)
 #define EV_EFI_SPDM_FIRMWARE_CONFIG       (EV_EFI_EVENT_BASE + 0xE2)
+#define EV_EFI_SPDM_DEVICE_BLOB           EV_EFI_SPDM_FIRMWARE_BLOB
+#define EV_EFI_SPDM_DEVICE_CONFIG         EV_EFI_SPDM_FIRMWARE_CONFIG
+//
+// The SPDM policy database for SPDM verification.
+// It goes to PCR7
+//
+#define EV_EFI_SPDM_DEVICE_POLICY  (EV_EFI_EVENT_BASE + 0xE3)
+//
+// The SPDM policy authority for SPDM verification for the signature
+// of GET_MEASUREMENT or CHALLENGE_AUTH. It goes to PCR7.
+//
+#define EV_EFI_SPDM_DEVICE_AUTHORITY  (EV_EFI_EVENT_BASE + 0xE4)
 
 #define EFI_CALLING_EFI_APPLICATION         \
   "Calling EFI Application from Boot Option"
@@ -374,6 +386,7 @@ typedef struct {
 #define TCG_EfiSpecIDEventStruct_SPEC_VERSION_MINOR_TPM2   0
 #define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2          0
 #define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_105  105
+#define TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106  106
 
 typedef struct {
   UINT8     signature[16];
@@ -492,4 +505,173 @@ typedef struct tdTCG_EfiStartupLocalityEvent {
 //
 #pragma pack ()
 
+//
+// ======================================================================================================================
+// Event Type                    PCR  Event Log                                   Usage
+// ======================================================================================================================
+// EV_EFI_SPDM_DEVICE_BLOB       2    SPDM_MEASUREMENT_BLOCK (subtype)            MEASUREMENT from device
+// EV_EFI_SPDM_DEVICE_CONFIG     3    SPDM_MEASUREMENT_BLOCK (subtype)            MEASUREMENT from device
+// EV_EFI_SPDM_DEVICE_BLOB       2    SPDM_MEASUREMENT_SUMMARY_HASH.TCB (subtype) SUMMARY_HASH from device
+
+// EV_EFI_SPDM_DEVICE_POLICY     7    UEFI_VARIABLE_DATA with EFI_SIGNATURE_LIST  Provisioned device public cert.
+// EV_EFI_SPDM_DEVICE_AUTHORITY  7    UEFI_VARIABLE_DATA with EFI_SIGNATURE_DATA  CHALLENGE_AUTH signature verification
+// ======================================================================================================================
+//
+
+#define PCR_INDEX_FOR_SIGNATURE_DB  7
+
+#pragma pack(1)
+
+#define TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_1    1
+#define TCG_DEVICE_SECURITY_EVENT_DATA_VERSION_2    2
+#define TCG_DEVICE_SECURITY_EVENT_DATA_SIGNATURE_2  "SPDM Device Sec2"
+
+typedef struct {
+  UINT8     Signature[16];
+  UINT16    Version;
+  UINT8     AuthState;
+  UINT8     Reserved;
+  UINT32    Length;                      // Length in bytes for all following structures.
+  UINT32    DeviceType;
+  UINT32    SubHeaderType;
+  UINT32    SubHeaderLength;                      // Length in bytes of the sub header followed by.
+  UINT64    SubHeaderUID;                         // Universal identifier assigned by the event log creator. It can be used to bind two sub header structure together.
+  // UINT64                         DevicePathLength;
+  // UINT8                          DevicePath[DevicePathLength];
+} TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2;
+
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_SUCCESS       0
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_AUTH       1
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_BINDING    2
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG   3
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_INVALID  4
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_NO_SPDM       0xFF
+
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_MEASUREMENT_BLOCK  0
+#define TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_SUB_HEADER_TYPE_SPDM_CERT_CHAIN         1
+
+typedef struct {
+  UINT16    SpdmVersion;
+  UINT8     SpdmMeasurementBlockCount;
+  UINT8     Reserved;
+  UINT32    SpdmMeasurementHashAlgo;
+  // SPDM_MEASUREMENT_BLOCK         SpdmMeasurementBlock;
+} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK;
+
+typedef struct {
+  UINT16    SpdmVersion;
+  UINT8     SpdmSlotId;
+  UINT8     Reserved;
+  UINT32    SpdmHashAlgo;
+  // SPDM_CERT_CHAIN                SpdmCertChain;
+} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN;
+
+typedef struct {
+  UINT32    Type;
+  UINT32    Length;
+  UINT8     Value[1];
+} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_OEM_MEASUREMENT;
+
+typedef union {
+  TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_MEASUREMENT_BLOCK    SpdmMeasurementBlock;
+  TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_SPDM_CERT_CHAIN           SpdmCertChain;
+  TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER_OEM_MEASUREMENT           OemMeasurement;
+} TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER;
+
+typedef union {
+  TCG_DEVICE_SECURITY_EVENT_DATA_PCI_CONTEXT    Pci;
+  TCG_DEVICE_SECURITY_EVENT_DATA_USB_CONTEXT    Usb;
+} TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT;
+
+typedef struct {
+  TCG_DEVICE_SECURITY_EVENT_DATA_HEADER2           EventDataHeader;
+  TCG_DEVICE_SECURITY_EVENT_DATA_SUB_HEADER        EventDataSubHeader;
+  TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_CONTEXT    DeviceContext;
+} TCG_DEVICE_SECURITY_EVENT_DATA2;
+
+#pragma pack()
+
+//
+// EventType:EV_NO_ACTION
+// ======================================================================================================================
+// NVIndex Name                                PCR/NvIndex  Event Log                            Usage
+// ======================================================================================================================
+// NV_EXTEND_INDEX_FOR_INSTANCE                0x01C40200   NV_INDEX_INSTANCE_EVENT_LOG_STRUCT   NV Extend Record for instance data (CertChain)
+// NV_EXTEND_INDEX_FOR_DYNAMIC                 0x01C40201   NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT    NV Extend Record for dynamic data  (Nonce)
+
+// EVENT_LOG_INTEGRITY_NV_INDEX_EXIT_PM_AUTH   0x01C40202   EVENT_LOG_INTEGRITY_NV_INDEX_STRUCT  Event Log Integrity for ExitPmAuth
+// EVENT_LOG_INTEGRITY_NV_INDEX_READY_TO_BOOT  0x01C40203   EVENT_LOG_INTEGRITY_NV_INDEX_STRUCT  Event Log Integrity for ReadyToBoot
+// ======================================================================================================================
+//
+
+#define TCG_NV_EXTEND_INDEX_FOR_INSTANCE                0x01C40200
+#define TCG_NV_EXTEND_INDEX_FOR_DYNAMIC                 0x01C40201
+#define TCG_EVENT_LOG_INTEGRITY_NV_INDEX_EXIT_PM_AUTH   0x01C40202
+#define TCG_EVENT_LOG_INTEGRITY_NV_INDEX_READY_TO_BOOT  0x01C40203
+
+#pragma pack(1)
+
+#define TCG_NV_EXTEND_INDEX_FOR_INSTANCE_SIGNATURE      "NvIndexInstance"
+#define TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT_VERSION  1
+
+typedef struct {
+  UINT8     Signature[16];
+  UINT16    Version;
+  UINT8     Reserved[6];
+  // TCG_DEVICE_SECURITY_EVENT_DATA2  Data;
+} TCG_NV_INDEX_INSTANCE_EVENT_LOG_STRUCT;
+
+#define TCG_NV_EXTEND_INDEX_FOR_DYNAMIC_SIGNATURE      "NvIndexDynamic "
+#define TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_VERSION  1
+
+#define TCG_SPDM_CHALLENGE_DESCRIPTION         "SPDM CHALLENGE"
+#define TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION    "SPDM CHALLENGE_AUTH"
+#define TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION  "SPDM GET_MEASUREMENTS"
+#define TCG_SPDM_MEASUREMENTS_DESCRIPTION      "SPDM MEASUREMENTS"
+
+typedef struct {
+  UINT8     Signature[16];
+  UINT16    Version;
+  UINT8     Reserved[6];
+  UINT64    Uid;
+  // UINT16                           DescriptionSize;
+  // UINT8                            Description[DescriptionSize];
+  // UINT16                           DataSize;
+  // UINT8                            Data[DataSize];
+} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT;
+
+typedef struct {
+  TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT    Header;
+  UINT16                                   DescriptionSize;
+  UINT8                                    Description[sizeof (TCG_SPDM_CHALLENGE_DESCRIPTION)];
+  UINT16                                   DataSize;
+  UINT8                                    Data[32];
+} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE;
+
+typedef struct {
+  TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT    Header;
+  UINT16                                   DescriptionSize;
+  UINT8                                    Description[sizeof (TCG_SPDM_CHALLENGE_AUTH_DESCRIPTION)];
+  UINT16                                   DataSize;
+  UINT8                                    Data[32];
+} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_CHALLENGE_AUTH;
+
+typedef struct {
+  TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT    Header;
+  UINT16                                   DescriptionSize;
+  UINT8                                    Description[sizeof (TCG_SPDM_GET_MEASUREMENTS_DESCRIPTION)];
+  UINT16                                   DataSize;
+  UINT8                                    Data[32];
+} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_GET_MEASUREMENTS;
+
+typedef struct {
+  TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT    Header;
+  UINT16                                   DescriptionSize;
+  UINT8                                    Description[sizeof (TCG_SPDM_MEASUREMENTS_DESCRIPTION)];
+  UINT16                                   DataSize;
+  UINT8                                    Data[32];
+} TCG_NV_INDEX_DYNAMIC_EVENT_LOG_STRUCT_SPDM_MEASUREMENTS;
+
+#pragma pack()
+
 #endif
-- 
2.26.2.windows.1



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



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [edk2-devel] [PATCH v2 3/9] MdePkg: Add devAuthBoot GlobalVariable
  2024-04-08  1:46 [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 1/9] MdePkg: Add SPDM1.2 support Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 2/9] MdePkg: Add TCG PFP 1.06 support Wenxing Hou
@ 2024-04-08  1:46 ` Wenxing Hou
  2024-04-09  6:17   ` 回复: " gaoliming via groups.io
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 4/9] MdeModulePkg/Variable: Add TCG SPDM device measurement update Wenxing Hou
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 12+ messages in thread
From: Wenxing Hou @ 2024-04-08  1:46 UTC (permalink / raw)
  To: devel; +Cc: Michael D Kinney, Liming Gao, Zhiguang Liu, Jiewen Yao

According to UEFI 2.10 spec 3.3 Globally Defined Variables section,
add devAuthBoot GlobalVariable.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 MdePkg/Include/Guid/GlobalVariable.h      | 8 +++++++-
 MdePkg/Include/Guid/ImageAuthentication.h | 5 ++++-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/MdePkg/Include/Guid/GlobalVariable.h b/MdePkg/Include/Guid/GlobalVariable.h
index eb2ce6aaf2..eb6e5a043e 100644
--- a/MdePkg/Include/Guid/GlobalVariable.h
+++ b/MdePkg/Include/Guid/GlobalVariable.h
@@ -1,7 +1,7 @@
 /** @file
   GUID for EFI (NVRAM) Variables.
 
-  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Revision Reference:
@@ -183,4 +183,10 @@ extern EFI_GUID  gEfiGlobalVariableGuid;
 ///
 #define EFI_VENDOR_KEYS_VARIABLE_NAME  L"VendorKeys"
 
+///
+/// Whether the platform firmware is operating in device authentication boot mode (1) or not (0).
+/// The content is UINT8.
+///
+#define EFI_DEVICE_AUTH_BOOT_MODE_NAME  L"devAuthBoot"
+
 #endif
diff --git a/MdePkg/Include/Guid/ImageAuthentication.h b/MdePkg/Include/Guid/ImageAuthentication.h
index fe83596571..f95255c0fb 100644
--- a/MdePkg/Include/Guid/ImageAuthentication.h
+++ b/MdePkg/Include/Guid/ImageAuthentication.h
@@ -1,7 +1,7 @@
 /** @file
   Image signature database are defined for the signed image validation.
 
-  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Revision Reference:
@@ -41,6 +41,9 @@
 #define SETUP_MODE  1
 #define USER_MODE   0
 
+#define DEVICE_AUTH_BOOT_MODE_ENABLE   1
+#define DEVICE_AUTH_BOOT_MODE_DISABLE  0
+
 // ***********************************************************************
 // Signature Database
 // ***********************************************************************
-- 
2.26.2.windows.1



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



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [edk2-devel] [PATCH v2 4/9] MdeModulePkg/Variable: Add TCG SPDM device measurement update
  2024-04-08  1:46 [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
                   ` (2 preceding siblings ...)
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 3/9] MdePkg: Add devAuthBoot GlobalVariable Wenxing Hou
@ 2024-04-08  1:46 ` Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 5/9] SecurityPkg: Add TCG PFP 1.06 support Wenxing Hou
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Wenxing Hou @ 2024-04-08  1:46 UTC (permalink / raw)
  To: devel; +Cc: Liming Gao, Jiewen Yao

Add EV_EFI_SPDM_DEVICE_POLICY support for MeasureVariable.

Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 MdeModulePkg/MdeModulePkg.dec                 |  5 +++
 .../Variable/RuntimeDxe/Measurement.c         | 38 ++++++++++++++++---
 .../RuntimeDxe/VariableRuntimeDxe.inf         |  3 ++
 .../RuntimeDxe/VariableSmmRuntimeDxe.inf      |  3 ++
 4 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index a82dedc070..1a5fd5a190 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -2139,6 +2139,11 @@
   # @Prompt TCG Platform Firmware Profile revision.
   gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision|0|UINT32|0x00010077
 
+  ## Specify whether to enable the state of SPDM device authentication and measurement.<BR><BR>
+  #  0: Platform Firmware not supports SPDM device authentication and measurement.
+  #  1: Platform Firmware supports SPDM device authentication and measurement.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthentication|0|UINT8|0x00010033
+
   ## Indicates if StatusCode is reported via Serial port.<BR><BR>
   #   TRUE  - Reports StatusCode via Serial port.<BR>
   #   FALSE - Does not report StatusCode via Serial port.<BR>
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/Measurement.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/Measurement.c
index c15cce9716..a52683a9e3 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/Measurement.c
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/Measurement.c
@@ -8,6 +8,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 #include <PiDxe.h>
 #include <Guid/ImageAuthentication.h>
+#include <Guid/DeviceAuthentication.h>
 #include <IndustryStandard/UefiTcgPlatform.h>
 
 #include <Library/UefiBootServicesTableLib.h>
@@ -26,12 +27,13 @@ typedef struct {
 } VARIABLE_TYPE;
 
 VARIABLE_TYPE  mVariableType[] = {
-  { EFI_SECURE_BOOT_MODE_NAME,    &gEfiGlobalVariableGuid        },
-  { EFI_PLATFORM_KEY_NAME,        &gEfiGlobalVariableGuid        },
-  { EFI_KEY_EXCHANGE_KEY_NAME,    &gEfiGlobalVariableGuid        },
-  { EFI_IMAGE_SECURITY_DATABASE,  &gEfiImageSecurityDatabaseGuid },
-  { EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid },
-  { EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid },
+  { EFI_SECURE_BOOT_MODE_NAME,    &gEfiGlobalVariableGuid          },
+  { EFI_PLATFORM_KEY_NAME,        &gEfiGlobalVariableGuid          },
+  { EFI_KEY_EXCHANGE_KEY_NAME,    &gEfiGlobalVariableGuid          },
+  { EFI_IMAGE_SECURITY_DATABASE,  &gEfiImageSecurityDatabaseGuid   },
+  { EFI_IMAGE_SECURITY_DATABASE1, &gEfiImageSecurityDatabaseGuid   },
+  { EFI_IMAGE_SECURITY_DATABASE2, &gEfiImageSecurityDatabaseGuid   },
+  { EFI_DEVICE_SECURITY_DATABASE, &gEfiDeviceSignatureDatabaseGuid },
 };
 
 //
@@ -123,6 +125,22 @@ MeasureVariable (
       );
   }
 
+  if (CompareGuid (VendorGuid, &gEfiDeviceSignatureDatabaseGuid)) {
+    DEBUG ((DEBUG_INFO, "VariableDxe: MeasureVariable (Pcr - %x, EventType - %x, ", PCR_INDEX_FOR_SIGNATURE_DB, (UINTN)EV_EFI_SPDM_DEVICE_POLICY));
+    DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
+
+    Status = TpmMeasureAndLogData (
+               PCR_INDEX_FOR_SIGNATURE_DB,
+               EV_EFI_SPDM_DEVICE_POLICY,
+               VarLog,
+               VarLogSize,
+               VarLog,
+               VarLogSize
+               );
+    FreePool (VarLog);
+    return Status;
+  }
+
   DEBUG ((DEBUG_INFO, "VariableDxe: MeasureVariable (Pcr - %x, EventType - %x, ", (UINTN)7, (UINTN)EV_EFI_VARIABLE_DRIVER_CONFIG));
   DEBUG ((DEBUG_INFO, "VariableName - %s, VendorGuid - %g)\n", VarName, VendorGuid));
 
@@ -228,6 +246,14 @@ SecureBootHook (
     return;
   }
 
+  if (CompareGuid (VendorGuid, &gEfiDeviceSignatureDatabaseGuid)) {
+    if ((PcdGet32 (PcdTcgPfpMeasurementRevision) < TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106) ||
+        (PcdGet8 (PcdEnableSpdmDeviceAuthentication) == 0))
+    {
+      return;
+    }
+  }
+
   //
   // We should NOT use Data and DataSize here,because it may include signature,
   // or is just partial with append attributes, or is deleted.
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
index 3858adf673..f90ec70b77 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
@@ -125,6 +125,7 @@
   ## SOMETIMES_CONSUMES   ## Variable:L"dbx"
   ## SOMETIMES_CONSUMES   ## Variable:L"dbt"
   gEfiImageSecurityDatabaseGuid
+  gEfiDeviceSignatureDatabaseGuid
 
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize                 ## CONSUMES
@@ -138,6 +139,8 @@
   gEfiMdeModulePkgTokenSpaceGuid.PcdReclaimVariableSpaceAtEndOfDxe  ## CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable         ## SOMETIMES_CONSUMES
   gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved      ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision       ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthentication   ## PRODUCES AND CONSUMES
 
 [FeaturePcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics  ## CONSUMES # statistic the information of variable.
diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
index a0d8b2267e..e1085653fe 100644
--- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
+++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
@@ -80,6 +80,8 @@
 
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdAllowVariablePolicyEnforcementDisable     ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision                 ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthentication             ## PRODUCES AND CONSUMES
 
 [Guids]
   ## PRODUCES             ## GUID # Signature of Variable store header
@@ -110,6 +112,7 @@
 
   gVarCheckPolicyLibMmiHandlerGuid
   gEfiEndOfDxeEventGroupGuid
+  gEfiDeviceSignatureDatabaseGuid
 
 [Depex]
   gEfiMmCommunication2ProtocolGuid
-- 
2.26.2.windows.1



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



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [edk2-devel] [PATCH v2 5/9] SecurityPkg: Add TCG PFP 1.06 support.
  2024-04-08  1:46 [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
                   ` (3 preceding siblings ...)
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 4/9] MdeModulePkg/Variable: Add TCG SPDM device measurement update Wenxing Hou
@ 2024-04-08  1:46 ` Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 6/9] SecurityPkg: add DeviceSecurity support Wenxing Hou
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Wenxing Hou @ 2024-04-08  1:46 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao, Rahul Kumar

Add new api Tpm2ExtendNvIndex.
It is uesd in HashCompleteAndExtend when PcrIndex > MAX_PCR_INDEX.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 SecurityPkg/Include/Library/Tpm2CommandLib.h  |  23 +++-
 .../HashLibBaseCryptoRouterDxe.c              |  88 +++++++++++--
 .../Library/Tpm2CommandLib/Tpm2NVStorage.c    | 122 +++++++++++++++++-
 SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c             |  61 ++++++++-
 SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf           |   4 +-
 5 files changed, 278 insertions(+), 20 deletions(-)

diff --git a/SecurityPkg/Include/Library/Tpm2CommandLib.h b/SecurityPkg/Include/Library/Tpm2CommandLib.h
index a2fb97f18d..70eec84c90 100644
--- a/SecurityPkg/Include/Library/Tpm2CommandLib.h
+++ b/SecurityPkg/Include/Library/Tpm2CommandLib.h
@@ -1,7 +1,7 @@
 /** @file
   This library is used by other modules to send TPM2 command.
 
-Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -467,6 +467,27 @@ Tpm2NvGlobalWriteLock (
   IN      TPMS_AUTH_COMMAND  *AuthSession OPTIONAL
   );
 
+/**
+  This command extends a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().
+
+  @param[in]  AuthHandle         the handle indicating the source of the authorization value.
+  @param[in]  NvIndex            The NV Index of the area to extend.
+  @param[in]  AuthSession        Auth Session context
+  @param[in]  InData             The data to extend.
+
+  @retval EFI_SUCCESS            Operation completed successfully.
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.
+  @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2NvExtend (
+  IN      TPMI_RH_NV_AUTH    AuthHandle,
+  IN      TPMI_RH_NV_INDEX   NvIndex,
+  IN      TPMS_AUTH_COMMAND  *AuthSession  OPTIONAL,
+  IN      TPM2B_MAX_BUFFER   *InData
+  );
+
 /**
   This command is used to cause an update to the indicated PCR.
   The digests parameter contains one or more tagged digest value identified by an algorithm ID.
diff --git a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
index ee8fe6e06e..2169c5e185 100644
--- a/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
+++ b/SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.c
@@ -3,7 +3,7 @@
   hash handler registered, such as SHA1, SHA256.
   Platform can use PcdTpm2HashMask to mask some hash engines.
 
-Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -16,6 +16,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/MemoryAllocationLib.h>
 #include <Library/PcdLib.h>
 #include <Library/HashLib.h>
+#include <Protocol/Tcg2Protocol.h>
 
 #include "HashLibBaseCryptoRouterCommon.h"
 
@@ -128,6 +129,49 @@ HashUpdate (
   return EFI_SUCCESS;
 }
 
+/**
+  Extend to TPM NvIndex.
+
+  @param[in]  NvIndex            The NV Index of the area to extend.
+  @param[in]  DataSize           The data size to extend.
+  @param[in]  Data               The data to extend.
+
+  @retval EFI_SUCCESS            Operation completed successfully.
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.
+  @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2ExtendNvIndex (
+  TPMI_RH_NV_INDEX  NvIndex,
+  UINT16            DataSize,
+  BYTE              *Data
+  )
+{
+  EFI_STATUS        Status;
+  TPMI_RH_NV_AUTH   AuthHandle;
+  TPM2B_MAX_BUFFER  NvExtendData;
+
+  AuthHandle = TPM_RH_PLATFORM;
+  ZeroMem (&NvExtendData, sizeof (NvExtendData));
+  CopyMem (NvExtendData.buffer, Data, DataSize);
+  NvExtendData.size = DataSize;
+  Status            = Tpm2NvExtend (
+                        AuthHandle,
+                        NvIndex,
+                        NULL,
+                        &NvExtendData
+                        );
+  if (EFI_ERROR (Status)) {
+    DEBUG (
+      (DEBUG_ERROR, "Extend TPM NV index failed, Index: 0x%x Status: %d\n",
+       NvIndex, Status)
+      );
+  }
+
+  return Status;
+}
+
 /**
   Hash sequence complete and extend to PCR.
 
@@ -149,11 +193,16 @@ HashCompleteAndExtend (
   OUT TPML_DIGEST_VALUES  *DigestList
   )
 {
-  TPML_DIGEST_VALUES  Digest;
-  HASH_HANDLE         *HashCtx;
-  UINTN               Index;
-  EFI_STATUS          Status;
-  UINT32              HashMask;
+  TPML_DIGEST_VALUES               Digest;
+  HASH_HANDLE                      *HashCtx;
+  UINTN                            Index;
+  EFI_STATUS                       Status;
+  UINT32                           HashMask;
+  TPML_DIGEST_VALUES               TcgPcrEvent2Digest;
+  EFI_TCG2_EVENT_ALGORITHM_BITMAP  TpmHashAlgorithmBitmap;
+  UINT32                           ActivePcrBanks;
+  UINT32                           *BufferPtr;
+  UINT32                           DigestListBinSize;
 
   if (mHashInterfaceCount == 0) {
     return EFI_UNSUPPORTED;
@@ -175,10 +224,29 @@ HashCompleteAndExtend (
 
   FreePool (HashCtx);
 
-  Status = Tpm2PcrExtend (
-             PcrIndex,
-             DigestList
-             );
+  if (PcrIndex <= MAX_PCR_INDEX) {
+    Status = Tpm2PcrExtend (
+               PcrIndex,
+               DigestList
+               );
+  } else {
+    Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &ActivePcrBanks);
+    ASSERT_EFI_ERROR (Status);
+    ActivePcrBanks = ActivePcrBanks & mSupportedHashMaskCurrent;
+    ZeroMem (&TcgPcrEvent2Digest, sizeof (TcgPcrEvent2Digest));
+    BufferPtr         = CopyDigestListToBuffer (&TcgPcrEvent2Digest, DigestList, ActivePcrBanks);
+    DigestListBinSize = (UINT32)((UINT8 *)BufferPtr - (UINT8 *)&TcgPcrEvent2Digest);
+
+    //
+    // Extend to TPM NvIndex
+    //
+    Status = Tpm2ExtendNvIndex (
+               PcrIndex,
+               (UINT16)DigestListBinSize,
+               (BYTE *)&TcgPcrEvent2Digest
+               );
+  }
+
   return Status;
 }
 
diff --git a/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c b/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
index 5077ace7c2..f11f7696b1 100644
--- a/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
+++ b/SecurityPkg/Library/Tpm2CommandLib/Tpm2NVStorage.c
@@ -1,7 +1,7 @@
 /** @file
   Implement TPM2 NVStorage related command.
 
-Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved. <BR>
+Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved. <BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -148,6 +148,22 @@ typedef struct {
   TPMS_AUTH_RESPONSE      AuthSession;
 } TPM2_NV_GLOBALWRITELOCK_RESPONSE;
 
+typedef struct {
+  TPM2_COMMAND_HEADER    Header;
+  TPMI_RH_NV_AUTH        AuthHandle;
+  TPMI_RH_NV_INDEX       NvIndex;
+  UINT32                 AuthSessionSize;
+  TPMS_AUTH_COMMAND      AuthSession;
+  TPM2B_MAX_BUFFER       Data;
+  UINT16                 Offset;
+} TPM2_NV_EXTEND_COMMAND;
+
+typedef struct {
+  TPM2_RESPONSE_HEADER    Header;
+  UINT32                  AuthSessionSize;
+  TPMS_AUTH_RESPONSE      AuthSession;
+} TPM2_NV_EXTEND_RESPONSE;
+
 #pragma pack()
 
 /**
@@ -1052,3 +1068,107 @@ Done:
   ZeroMem (&RecvBuffer, sizeof (RecvBuffer));
   return Status;
 }
+
+/**
+  This command extends a value to an area in NV memory that was previously defined by TPM2_NV_DefineSpace().
+
+  @param[in]  AuthHandle         the handle indicating the source of the authorization value.
+  @param[in]  NvIndex            The NV Index of the area to extend.
+  @param[in]  AuthSession        Auth Session context
+  @param[in]  InData             The data to extend.
+
+  @retval EFI_SUCCESS            Operation completed successfully.
+  @retval EFI_DEVICE_ERROR       The command was unsuccessful.
+  @retval EFI_NOT_FOUND          The command was returned successfully, but NvIndex is not found.
+**/
+EFI_STATUS
+EFIAPI
+Tpm2NvExtend (
+  IN      TPMI_RH_NV_AUTH    AuthHandle,
+  IN      TPMI_RH_NV_INDEX   NvIndex,
+  IN      TPMS_AUTH_COMMAND  *AuthSession  OPTIONAL,
+  IN      TPM2B_MAX_BUFFER   *InData
+  )
+{
+  EFI_STATUS               Status;
+  TPM2_NV_EXTEND_COMMAND   SendBuffer;
+  TPM2_NV_EXTEND_RESPONSE  RecvBuffer;
+  UINT32                   SendBufferSize;
+  UINT32                   RecvBufferSize;
+  UINT8                    *Buffer;
+  UINT32                   SessionInfoSize;
+  TPM_RC                   ResponseCode;
+
+  //
+  // Construct command
+  //
+  SendBuffer.Header.tag         = SwapBytes16 (TPM_ST_SESSIONS);
+  SendBuffer.Header.commandCode = SwapBytes32 (TPM_CC_NV_Extend);
+
+  SendBuffer.AuthHandle = SwapBytes32 (AuthHandle);
+  SendBuffer.NvIndex    = SwapBytes32 (NvIndex);
+
+  //
+  // Add in Auth session
+  //
+  Buffer = (UINT8 *)&SendBuffer.AuthSession;
+
+  // sessionInfoSize
+  SessionInfoSize            = CopyAuthSessionCommand (AuthSession, Buffer);
+  Buffer                    += SessionInfoSize;
+  SendBuffer.AuthSessionSize = SwapBytes32 (SessionInfoSize);
+
+  WriteUnaligned16 ((UINT16 *)Buffer, SwapBytes16 (InData->size));
+  Buffer += sizeof (UINT16);
+  CopyMem (Buffer, InData->buffer, InData->size);
+  Buffer += InData->size;
+
+  SendBufferSize              = (UINT32)(Buffer - (UINT8 *)&SendBuffer);
+  SendBuffer.Header.paramSize = SwapBytes32 (SendBufferSize);
+
+  //
+  // send Tpm command
+  //
+  RecvBufferSize = sizeof (RecvBuffer);
+  Status         = Tpm2SubmitCommand (SendBufferSize, (UINT8 *)&SendBuffer, &RecvBufferSize, (UINT8 *)&RecvBuffer);
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  if (RecvBufferSize < sizeof (TPM2_RESPONSE_HEADER)) {
+    DEBUG ((DEBUG_ERROR, "Tpm2NvExtend - RecvBufferSize Error - %x\n", RecvBufferSize));
+    Status = EFI_DEVICE_ERROR;
+    goto Done;
+  }
+
+  ResponseCode = SwapBytes32 (RecvBuffer.Header.responseCode);
+  if (ResponseCode != TPM_RC_SUCCESS) {
+    DEBUG ((DEBUG_ERROR, "Tpm2NvExtend - responseCode - %x\n", ResponseCode));
+  }
+
+  switch (ResponseCode) {
+    case TPM_RC_SUCCESS:
+      // return data
+      break;
+    case TPM_RC_ATTRIBUTES:
+      Status = EFI_UNSUPPORTED;
+      break;
+    case TPM_RC_NV_AUTHORIZATION:
+      Status = EFI_SECURITY_VIOLATION;
+      break;
+    case TPM_RC_NV_LOCKED:
+      Status = EFI_ACCESS_DENIED;
+      break;
+    default:
+      Status = EFI_DEVICE_ERROR;
+      break;
+  }
+
+Done:
+  //
+  // Clear AuthSession Content
+  //
+  ZeroMem (&SendBuffer, sizeof (SendBuffer));
+  ZeroMem (&RecvBuffer, sizeof (RecvBuffer));
+  return Status;
+}
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
index f6ea8b2bbf..b8f50e25df 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.c
@@ -1,7 +1,7 @@
 /** @file
   This module implements Tcg2 Protocol.
 
-Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -19,6 +19,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Guid/EventExitBootServiceFailed.h>
 #include <Guid/ImageAuthentication.h>
 #include <Guid/TpmInstance.h>
+#include <Guid/DeviceAuthentication.h>
 
 #include <Protocol/DevicePath.h>
 #include <Protocol/MpService.h>
@@ -1230,10 +1231,25 @@ TcgDxeHashLogExtendEvent (
     //
     // Do not do TPM extend for EV_NO_ACTION
     //
-    Status = EFI_SUCCESS;
-    InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);
-    if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
-      Status = TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData);
+    if (NewEventHdr->PCRIndex <= MAX_PCR_INDEX) {
+      Status = EFI_SUCCESS;
+      InitNoActionEvent (&NoActionEvent, NewEventHdr->EventSize);
+      if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) {
+        Status = TcgDxeLogHashEvent (&(NoActionEvent.Digests), NewEventHdr, NewEventData);
+      }
+    } else {
+      //
+      // Extend to NvIndex
+      //
+      Status = HashAndExtend (
+                 NewEventHdr->PCRIndex,
+                 HashData,
+                 (UINTN)HashDataLen,
+                 &DigestList
+                 );
+      if (!EFI_ERROR (Status)) {
+        Status = TcgDxeLogHashEvent (&DigestList, NewEventHdr, NewEventData);
+      }
     }
 
     return Status;
@@ -1317,7 +1333,7 @@ Tcg2HashLogExtendEvent (
     return EFI_INVALID_PARAMETER;
   }
 
-  if (Event->Header.PCRIndex > MAX_PCR_INDEX) {
+  if ((Event->Header.EventType != EV_NO_ACTION) && (Event->Header.PCRIndex > MAX_PCR_INDEX)) {
     return EFI_INVALID_PARAMETER;
   }
 
@@ -2063,7 +2079,7 @@ MeasureVariable (
       );
   }
 
-  if (EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) {
+  if ((EventType == EV_EFI_VARIABLE_DRIVER_CONFIG) || (EventType == EV_EFI_SPDM_DEVICE_POLICY)) {
     //
     // Digest is the event data (UEFI_VARIABLE_DATA)
     //
@@ -2319,6 +2335,37 @@ MeasureAllSecureVariables (
     DEBUG ((DEBUG_INFO, "Skip measuring variable %s since it's deleted\n", EFI_IMAGE_SECURITY_DATABASE2));
   }
 
+  //
+  // Meaurement UEFI device signature database
+  //
+  if ((PcdGet32 (PcdTcgPfpMeasurementRevision) >= TCG_EfiSpecIDEventStruct_SPEC_ERRATA_TPM2_REV_106) &&
+      (PcdGet8 (PcdEnableSpdmDeviceAuthentication) != 0))
+  {
+    Status = GetVariable2 (EFI_DEVICE_SECURITY_DATABASE, &gEfiDeviceSignatureDatabaseGuid, &Data, &DataSize);
+    if (Status == EFI_SUCCESS) {
+      Status = MeasureVariable (
+                 PCR_INDEX_FOR_SIGNATURE_DB,
+                 EV_EFI_SPDM_DEVICE_POLICY,
+                 EFI_DEVICE_SECURITY_DATABASE,
+                 &gEfiDeviceSignatureDatabaseGuid,
+                 Data,
+                 DataSize
+                 );
+      FreePool (Data);
+    } else if (Status == EFI_NOT_FOUND) {
+      Data     = NULL;
+      DataSize = 0;
+      Status   = MeasureVariable (
+                   PCR_INDEX_FOR_SIGNATURE_DB,
+                   EV_EFI_SPDM_DEVICE_POLICY,
+                   EFI_DEVICE_SECURITY_DATABASE,
+                   &gEfiDeviceSignatureDatabaseGuid,
+                   Data,
+                   DataSize
+                   );
+    }
+  }
+
   return EFI_SUCCESS;
 }
 
diff --git a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
index 7dc7a2683d..a645474bf3 100644
--- a/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
+++ b/SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf
@@ -16,7 +16,7 @@
 #  This external input must be validated carefully to avoid security issue like
 #  buffer overflow, integer overflow.
 #
-# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
@@ -86,6 +86,7 @@
   gTcgEvent2EntryHobGuid                             ## SOMETIMES_CONSUMES  ## HOB
   gTpm2StartupLocalityHobGuid                        ## SOMETIMES_CONSUMES  ## HOB
   gTcg800155PlatformIdEventHobGuid                   ## SOMETIMES_CONSUMES  ## HOB
+  gEfiDeviceSignatureDatabaseGuid
 
 [Protocols]
   gEfiTcg2ProtocolGuid                               ## PRODUCES
@@ -107,6 +108,7 @@
   gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLaml                        ## PRODUCES
   gEfiSecurityPkgTokenSpaceGuid.PcdTpm2AcpiTableLasa                        ## PRODUCES
   gEfiMdeModulePkgTokenSpaceGuid.PcdTcgPfpMeasurementRevision               ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdEnableSpdmDeviceAuthentication           ## CONSUMES
 
 [Depex]
   # According to PcdTpm2AcpiTableRev definition in SecurityPkg.dec
-- 
2.26.2.windows.1



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



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [edk2-devel] [PATCH v2 6/9] SecurityPkg: add DeviceSecurity support
  2024-04-08  1:46 [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
                   ` (4 preceding siblings ...)
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 5/9] SecurityPkg: Add TCG PFP 1.06 support Wenxing Hou
@ 2024-04-08  1:46 ` Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 7/9] .pytool/CISettings.py: add libspdm submodule Wenxing Hou
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Wenxing Hou @ 2024-04-08  1:46 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao

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..f438c16563
--- /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 (PcdEnableSpdmDeviceAuthentication) == 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..4f77020bd8
--- /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.PcdEnableSpdmDeviceAuthentication        ## 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 (#117483): https://edk2.groups.io/g/devel/message/117483
Mute This Topic: https://groups.io/mt/105394120/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [edk2-devel] [PATCH v2 7/9] .pytool/CISettings.py: add libspdm submodule.
  2024-04-08  1:46 [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
                   ` (5 preceding siblings ...)
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 6/9] SecurityPkg: add DeviceSecurity support Wenxing Hou
@ 2024-04-08  1:46 ` Wenxing Hou
  2024-04-09 14:51   ` Joey Vagedes via groups.io
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 8/9] .gitmodule: Add libspdm submodule for EDKII Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 9/9] SecurityPkg: Add libspdm submodule Wenxing Hou
  8 siblings, 1 reply; 12+ messages in thread
From: Wenxing Hou @ 2024-04-08  1:46 UTC (permalink / raw)
  To: devel; +Cc: Sean Brogan, Joey Vagedes, Michael D Kinney, Liming Gao

Add DeviceSecurity submodule libspdm.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Joey Vagedes <joey.vagedes@gmail.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Joey Vagedes <joey.vagedes@gmail.com>
---
 .pytool/CISettings.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.pytool/CISettings.py b/.pytool/CISettings.py
index ec3beb0dcf..314758da32 100644
--- a/.pytool/CISettings.py
+++ b/.pytool/CISettings.py
@@ -237,6 +237,8 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
             "MdePkg/Library/MipiSysTLib/mipisyst", False))
         rs.append(RequiredSubmodule(
             "CryptoPkg/Library/MbedTlsLib/mbedtls", False))
+        rs.append(RequiredSubmodule(
+            "SecurityPkg/DeviceSecurity/SpdmLib/libspdm", False))
         return rs
 
     def GetName(self):
-- 
2.26.2.windows.1



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



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [edk2-devel] [PATCH v2 8/9] .gitmodule: Add libspdm submodule for EDKII
  2024-04-08  1:46 [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
                   ` (6 preceding siblings ...)
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 7/9] .pytool/CISettings.py: add libspdm submodule Wenxing Hou
@ 2024-04-08  1:46 ` Wenxing Hou
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 9/9] SecurityPkg: Add libspdm submodule Wenxing Hou
  8 siblings, 0 replies; 12+ messages in thread
From: Wenxing Hou @ 2024-04-08  1:46 UTC (permalink / raw)
  To: devel; +Cc: Andrew Fish, Michael D Kinney, Jiewen Yao

libspdm is submodule, which will be used in DeviceSecurity.

Cc: Andrew Fish <afish@apple.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 .gitmodules                                | 3 +++
 SecurityPkg/DeviceSecurity/SpdmLib/libspdm | 1 +
 2 files changed, 4 insertions(+)
 create mode 160000 SecurityPkg/DeviceSecurity/SpdmLib/libspdm

diff --git a/.gitmodules b/.gitmodules
index 60d54b45eb..7f069abd3d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -35,3 +35,6 @@
 [submodule "CryptoPkg/Library/MbedTlsLib/mbedtls"]
 	path = CryptoPkg/Library/MbedTlsLib/mbedtls
 	url = https://github.com/ARMmbed/mbedtls
+[submodule "SecurityPkg/DeviceSecurity/SpdmLib/libspdm"]
+	path = SecurityPkg/DeviceSecurity/SpdmLib/libspdm
+	url = https://github.com/DMTF/libspdm.git
diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/libspdm b/SecurityPkg/DeviceSecurity/SpdmLib/libspdm
new file mode 160000
index 0000000000..4c92ff5ced
--- /dev/null
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/libspdm
@@ -0,0 +1 @@
+Subproject commit 4c92ff5ced7862e4f2eea945dd723d2e1b1fc476
-- 
2.26.2.windows.1



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



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [edk2-devel] [PATCH v2 9/9] SecurityPkg: Add libspdm submodule
  2024-04-08  1:46 [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
                   ` (7 preceding siblings ...)
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 8/9] .gitmodule: Add libspdm submodule for EDKII Wenxing Hou
@ 2024-04-08  1:46 ` Wenxing Hou
  8 siblings, 0 replies; 12+ messages in thread
From: Wenxing Hou @ 2024-04-08  1:46 UTC (permalink / raw)
  To: devel; +Cc: Jiewen Yao

libspdm is submodule to support DeviceSecurity feature.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
 SecurityPkg/DeviceSecurity/SpdmLib/libspdm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/libspdm b/SecurityPkg/DeviceSecurity/SpdmLib/libspdm
index 4c92ff5ced..f6558cc7da 160000
--- a/SecurityPkg/DeviceSecurity/SpdmLib/libspdm
+++ b/SecurityPkg/DeviceSecurity/SpdmLib/libspdm
@@ -1 +1 @@
-Subproject commit 4c92ff5ced7862e4f2eea945dd723d2e1b1fc476
+Subproject commit f6558cc7da31ccc882a3bf6a2b4a53f6b8551b45
-- 
2.26.2.windows.1



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



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* 回复: [edk2-devel] [PATCH v2 3/9] MdePkg: Add devAuthBoot GlobalVariable
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 3/9] MdePkg: Add devAuthBoot GlobalVariable Wenxing Hou
@ 2024-04-09  6:17   ` gaoliming via groups.io
  0 siblings, 0 replies; 12+ messages in thread
From: gaoliming via groups.io @ 2024-04-09  6:17 UTC (permalink / raw)
  To: devel, wenxing.hou
  Cc: 'Michael D Kinney', 'Zhiguang Liu',
	'Jiewen Yao'

Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>

> -----邮件原件-----
> 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Wenxing Hou
> 发送时间: 2024年4月8日 9:47
> 收件人: devel@edk2.groups.io
> 抄送: Michael D Kinney <michael.d.kinney@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>; Jiewen
> Yao <jiewen.yao@intel.com>
> 主题: [edk2-devel] [PATCH v2 3/9] MdePkg: Add devAuthBoot GlobalVariable
> 
> According to UEFI 2.10 spec 3.3 Globally Defined Variables section,
> add devAuthBoot GlobalVariable.
> 
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
> ---
>  MdePkg/Include/Guid/GlobalVariable.h      | 8 +++++++-
>  MdePkg/Include/Guid/ImageAuthentication.h | 5 ++++-
>  2 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/MdePkg/Include/Guid/GlobalVariable.h
> b/MdePkg/Include/Guid/GlobalVariable.h
> index eb2ce6aaf2..eb6e5a043e 100644
> --- a/MdePkg/Include/Guid/GlobalVariable.h
> +++ b/MdePkg/Include/Guid/GlobalVariable.h
> @@ -1,7 +1,7 @@
>  /** @file
> 
>    GUID for EFI (NVRAM) Variables.
> 
> 
> 
> -  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
> 
> +  Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR>
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> 
> 
>    @par Revision Reference:
> 
> @@ -183,4 +183,10 @@ extern EFI_GUID  gEfiGlobalVariableGuid;
>  ///
> 
>  #define EFI_VENDOR_KEYS_VARIABLE_NAME  L"VendorKeys"
> 
> 
> 
> +///
> 
> +/// Whether the platform firmware is operating in device authentication
boot
> mode (1) or not (0).
> 
> +/// The content is UINT8.
> 
> +///
> 
> +#define EFI_DEVICE_AUTH_BOOT_MODE_NAME  L"devAuthBoot"
> 
> +
> 
>  #endif
> 
> diff --git a/MdePkg/Include/Guid/ImageAuthentication.h
> b/MdePkg/Include/Guid/ImageAuthentication.h
> index fe83596571..f95255c0fb 100644
> --- a/MdePkg/Include/Guid/ImageAuthentication.h
> +++ b/MdePkg/Include/Guid/ImageAuthentication.h
> @@ -1,7 +1,7 @@
>  /** @file
> 
>    Image signature database are defined for the signed image validation.
> 
> 
> 
> -  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
> 
> +  Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
> 
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> 
> 
>    @par Revision Reference:
> 
> @@ -41,6 +41,9 @@
>  #define SETUP_MODE  1
> 
>  #define USER_MODE   0
> 
> 
> 
> +#define DEVICE_AUTH_BOOT_MODE_ENABLE   1
> 
> +#define DEVICE_AUTH_BOOT_MODE_DISABLE  0
> 
> +
> 
>  //
> **************************************************************
> *********
> 
>  // Signature Database
> 
>  //
> **************************************************************
> *********
> 
> --
> 2.26.2.windows.1
> 
> 
> 
> -=-=-=-=-=-=
> Groups.io Links: You receive all messages sent to this group.
> View/Reply Online (#117480):
> https://edk2.groups.io/g/devel/message/117480
> Mute This Topic: https://groups.io/mt/105394115/4905953
> Group Owner: devel+owner@edk2.groups.io
> Unsubscribe: https://edk2.groups.io/g/devel/unsub
> [gaoliming@byosoft.com.cn]
> -=-=-=-=-=-=
> 





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



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [edk2-devel] [PATCH v2 7/9] .pytool/CISettings.py: add libspdm submodule.
  2024-04-08  1:46 ` [edk2-devel] [PATCH v2 7/9] .pytool/CISettings.py: add libspdm submodule Wenxing Hou
@ 2024-04-09 14:51   ` Joey Vagedes via groups.io
  0 siblings, 0 replies; 12+ messages in thread
From: Joey Vagedes via groups.io @ 2024-04-09 14:51 UTC (permalink / raw)
  To: Wenxing Hou, devel

[-- Attachment #1: Type: text/plain, Size: 403 bytes --]

Reviewed-by: Joey.vagedes@gmail.com


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



[-- Attachment #2: Type: text/html, Size: 815 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2024-04-09 14:51 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-08  1:46 [edk2-devel] [PATCH v2 0/9] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
2024-04-08  1:46 ` [edk2-devel] [PATCH v2 1/9] MdePkg: Add SPDM1.2 support Wenxing Hou
2024-04-08  1:46 ` [edk2-devel] [PATCH v2 2/9] MdePkg: Add TCG PFP 1.06 support Wenxing Hou
2024-04-08  1:46 ` [edk2-devel] [PATCH v2 3/9] MdePkg: Add devAuthBoot GlobalVariable Wenxing Hou
2024-04-09  6:17   ` 回复: " gaoliming via groups.io
2024-04-08  1:46 ` [edk2-devel] [PATCH v2 4/9] MdeModulePkg/Variable: Add TCG SPDM device measurement update Wenxing Hou
2024-04-08  1:46 ` [edk2-devel] [PATCH v2 5/9] SecurityPkg: Add TCG PFP 1.06 support Wenxing Hou
2024-04-08  1:46 ` [edk2-devel] [PATCH v2 6/9] SecurityPkg: add DeviceSecurity support Wenxing Hou
2024-04-08  1:46 ` [edk2-devel] [PATCH v2 7/9] .pytool/CISettings.py: add libspdm submodule Wenxing Hou
2024-04-09 14:51   ` Joey Vagedes via groups.io
2024-04-08  1:46 ` [edk2-devel] [PATCH v2 8/9] .gitmodule: Add libspdm submodule for EDKII Wenxing Hou
2024-04-08  1:46 ` [edk2-devel] [PATCH v2 9/9] SecurityPkg: Add libspdm submodule Wenxing Hou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox