summaryrefslogtreecommitdiff
path: root/SecurityPkg/Include
diff options
context:
space:
mode:
authorWenxing Hou <wenxing.hou@intel.com>2024-04-18 17:28:15 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-04-30 02:21:13 +0000
commit750d763623fd1ff4a69d2e350310333dcbc19d4f (patch)
tree3ce5671d442e72592c2bb920a6a6cba13f88d7f9 /SecurityPkg/Include
parentc3f615a1bd7d64f42e7962f5a4d53f1f1a4423e6 (diff)
downloadedk2-750d763623fd1ff4a69d2e350310333dcbc19d4f.zip
edk2-750d763623fd1ff4a69d2e350310333dcbc19d4f.tar.gz
edk2-750d763623fd1ff4a69d2e350310333dcbc19d4f.tar.bz2
SecurityPkg: add DeviceSecurity support
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> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Diffstat (limited to 'SecurityPkg/Include')
-rw-r--r--SecurityPkg/Include/Library/SpdmSecurityLib.h437
-rw-r--r--SecurityPkg/Include/Protocol/DeviceSecurityPolicy.h133
2 files changed, 570 insertions, 0 deletions
diff --git a/SecurityPkg/Include/Library/SpdmSecurityLib.h b/SecurityPkg/Include/Library/SpdmSecurityLib.h
new file mode 100644
index 0000000..96a7841
--- /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 0000000..69148ba
--- /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