* [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec
@ 2024-04-15 1:58 Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 01/10] MdePkg: Add SPDM1.2 support Wenxing Hou
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 UTC (permalink / raw)
To: devel
Cc: Andrew Fish, Leif Lindholm, Michael D Kinney, Liming Gao,
Sean Brogan, Joey Vagedes, 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
v3 changes:
- Add new patch 10: Update ReadMe.rst for libspdm submodule license
PATCH 3: Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
PATCH 7: Reviewed-by: Joey Vagedes <joey.vagedes@gmail.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Joey Vagedes <joey.vagedes@gmail.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 (10):
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
ReadMe.rst: Add libspdm submodule license
.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 ++-
ReadMe.rst | 1 +
.../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 +-
49 files changed, 7197 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 (#117726): https://edk2.groups.io/g/devel/message/117726
Mute This Topic: https://groups.io/mt/105528198/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 11+ messages in thread
* [edk2-devel] [PATCH v3 01/10] MdePkg: Add SPDM1.2 support.
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
@ 2024-04-15 1:58 ` Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 02/10] MdePkg: Add TCG PFP 1.06 support Wenxing Hou
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 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 (#117727): https://edk2.groups.io/g/devel/message/117727
Mute This Topic: https://groups.io/mt/105528199/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] 11+ messages in thread
* [edk2-devel] [PATCH v3 02/10] MdePkg: Add TCG PFP 1.06 support.
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 01/10] MdePkg: Add SPDM1.2 support Wenxing Hou
@ 2024-04-15 1:58 ` Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 03/10] MdePkg: Add devAuthBoot GlobalVariable Wenxing Hou
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 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 (#117728): https://edk2.groups.io/g/devel/message/117728
Mute This Topic: https://groups.io/mt/105528202/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] 11+ messages in thread
* [edk2-devel] [PATCH v3 03/10] MdePkg: Add devAuthBoot GlobalVariable
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 01/10] MdePkg: Add SPDM1.2 support Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 02/10] MdePkg: Add TCG PFP 1.06 support Wenxing Hou
@ 2024-04-15 1:58 ` Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 04/10] MdeModulePkg/Variable: Add TCG SPDM device measurement update Wenxing Hou
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 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>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
---
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 (#117729): https://edk2.groups.io/g/devel/message/117729
Mute This Topic: https://groups.io/mt/105528204/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] 11+ messages in thread
* [edk2-devel] [PATCH v3 04/10] MdeModulePkg/Variable: Add TCG SPDM device measurement update
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
` (2 preceding siblings ...)
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 03/10] MdePkg: Add devAuthBoot GlobalVariable Wenxing Hou
@ 2024-04-15 1:58 ` Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 05/10] SecurityPkg: Add TCG PFP 1.06 support Wenxing Hou
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 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 (#117730): https://edk2.groups.io/g/devel/message/117730
Mute This Topic: https://groups.io/mt/105528205/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] 11+ messages in thread
* [edk2-devel] [PATCH v3 05/10] SecurityPkg: Add TCG PFP 1.06 support.
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
` (3 preceding siblings ...)
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 04/10] MdeModulePkg/Variable: Add TCG SPDM device measurement update Wenxing Hou
@ 2024-04-15 1:58 ` Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 06/10] SecurityPkg: add DeviceSecurity support Wenxing Hou
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 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 (#117731): https://edk2.groups.io/g/devel/message/117731
Mute This Topic: https://groups.io/mt/105528206/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] 11+ messages in thread
* [edk2-devel] [PATCH v3 06/10] SecurityPkg: add DeviceSecurity support
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
` (4 preceding siblings ...)
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 05/10] SecurityPkg: Add TCG PFP 1.06 support Wenxing Hou
@ 2024-04-15 1:58 ` Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 07/10] .pytool/CISettings.py: add libspdm submodule Wenxing Hou
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 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 (#117732): https://edk2.groups.io/g/devel/message/117732
Mute This Topic: https://groups.io/mt/105528207/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] 11+ messages in thread
* [edk2-devel] [PATCH v3 07/10] .pytool/CISettings.py: add libspdm submodule.
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
` (5 preceding siblings ...)
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 06/10] SecurityPkg: add DeviceSecurity support Wenxing Hou
@ 2024-04-15 1:58 ` Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 08/10] .gitmodule: Add libspdm submodule for EDKII Wenxing Hou
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 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 (#117733): https://edk2.groups.io/g/devel/message/117733
Mute This Topic: https://groups.io/mt/105528208/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] 11+ messages in thread
* [edk2-devel] [PATCH v3 08/10] .gitmodule: Add libspdm submodule for EDKII
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
` (6 preceding siblings ...)
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 07/10] .pytool/CISettings.py: add libspdm submodule Wenxing Hou
@ 2024-04-15 1:58 ` Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 09/10] SecurityPkg: Add libspdm submodule Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 10/10] ReadMe.rst: Add libspdm submodule license Wenxing Hou
9 siblings, 0 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 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 (#117734): https://edk2.groups.io/g/devel/message/117734
Mute This Topic: https://groups.io/mt/105528209/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] 11+ messages in thread
* [edk2-devel] [PATCH v3 09/10] SecurityPkg: Add libspdm submodule
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
` (7 preceding siblings ...)
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 08/10] .gitmodule: Add libspdm submodule for EDKII Wenxing Hou
@ 2024-04-15 1:58 ` Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 10/10] ReadMe.rst: Add libspdm submodule license Wenxing Hou
9 siblings, 0 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 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 (#117735): https://edk2.groups.io/g/devel/message/117735
Mute This Topic: https://groups.io/mt/105528210/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] 11+ messages in thread
* [edk2-devel] [PATCH v3 10/10] ReadMe.rst: Add libspdm submodule license
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
` (8 preceding siblings ...)
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 09/10] SecurityPkg: Add libspdm submodule Wenxing Hou
@ 2024-04-15 1:58 ` Wenxing Hou
9 siblings, 0 replies; 11+ messages in thread
From: Wenxing Hou @ 2024-04-15 1:58 UTC (permalink / raw)
To: devel; +Cc: Andrew Fish, Leif Lindholm, Michael D Kinney
This patch add libspdm submodule license.
Cc: Andrew Fish <afish@apple.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
---
ReadMe.rst | 1 +
1 file changed, 1 insertion(+)
diff --git a/ReadMe.rst b/ReadMe.rst
index 808ccd37af..cfd522fdbd 100644
--- a/ReadMe.rst
+++ b/ReadMe.rst
@@ -99,6 +99,7 @@ that are covered by additional licenses.
- `RedfishPkg/Library/JsonLib/jansson <https://github.com/akheron/jansson/blob/2882ead5bb90cf12a01b07b2c2361e24960fae02/LICENSE>`__
- `MdePkg/Library/BaseFdtLib/libfdt <https://github.com/devicetree-org/pylibfdt/blob/f39368a217496d32c4091a2dba4045b60649e3a5/BSD-2-Clause>`__
- `MdePkg/Library/MipiSysTLib/mipisyst <https://github.com/MIPI-Alliance/public-mipi-sys-t/blob/aae857d0d05ac65152ed24992a4acd834a0a107c/LICENSE>`__
+- `SecurityPkg/DeviceSecurity/SpdmLib/libspdm <https://github.com/DMTF/libspdm/blob/main/LICENSE.md>`__
The EDK II Project is composed of packages. The maintainers for each package
are listed in `Maintainers.txt <Maintainers.txt>`__.
--
2.26.2.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#117736): https://edk2.groups.io/g/devel/message/117736
Mute This Topic: https://groups.io/mt/105528212/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] 11+ messages in thread
end of thread, other threads:[~2024-04-15 1:59 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-15 1:58 [edk2-devel] [PATCH v3 00/10] Add DeviceSecurity feature based on PFP 1.06 spec Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 01/10] MdePkg: Add SPDM1.2 support Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 02/10] MdePkg: Add TCG PFP 1.06 support Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 03/10] MdePkg: Add devAuthBoot GlobalVariable Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 04/10] MdeModulePkg/Variable: Add TCG SPDM device measurement update Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 05/10] SecurityPkg: Add TCG PFP 1.06 support Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 06/10] SecurityPkg: add DeviceSecurity support Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 07/10] .pytool/CISettings.py: add libspdm submodule Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 08/10] .gitmodule: Add libspdm submodule for EDKII Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 09/10] SecurityPkg: Add libspdm submodule Wenxing Hou
2024-04-15 1:58 ` [edk2-devel] [PATCH v3 10/10] ReadMe.rst: Add libspdm submodule license Wenxing Hou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox