Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SPDM 1.3 feature GET_ENDPOINT_INFO #3000

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ jobs:
- CLANG
- ARM_GNU
configurations:
- "-DLIBSPDM_ENABLE_CAPABILITY_CERT_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_CHAL_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_MEAS_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_PSK_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_CSR_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_EVENT_CAP=1 -DLIBSPDM_RESPOND_IF_READY_SUPPORT=1 -DLIBSPDM_SEND_GET_CERTIFICATE_SUPPORT=1 -DLIBSPDM_SEND_CHALLENGE_SUPPORT=1 -DLIBSPDM_EVENT_RECIPIENT_SUPPORT=1 -DLIBSPDM_HAL_PASS_SPDM_CONTEXT=1 -DLIBSPDM_SET_CERT_CSR_PARAMS=1"
- "-DLIBSPDM_ENABLE_CAPABILITY_CERT_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_CHAL_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_MEAS_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_PSK_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_CSR_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_EVENT_CAP=0 -DLIBSPDM_RESPOND_IF_READY_SUPPORT=0 -DLIBSPDM_SEND_GET_CERTIFICATE_SUPPORT=0 -DLIBSPDM_SEND_CHALLENGE_SUPPORT=0 -DLIBSPDM_EVENT_RECIPIENT_SUPPORT=0 -DLIBSPDM_HAL_PASS_SPDM_CONTEXT=0 -DLIBSPDM_SET_CERT_CSR_PARAMS=0"
- "-DLIBSPDM_ENABLE_CAPABILITY_CERT_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_CHAL_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_MEAS_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_PSK_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_CSR_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP=1 -DLIBSPDM_ENABLE_CAPABILITY_EVENT_CAP=1 -DLIBSPDM_RESPOND_IF_READY_SUPPORT=1 -DLIBSPDM_SEND_GET_CERTIFICATE_SUPPORT=1 -DLIBSPDM_SEND_CHALLENGE_SUPPORT=1 -DLIBSPDM_EVENT_RECIPIENT_SUPPORT=1 -DLIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP=1 -DLIBSPDM_SEND_GET_ENDPOINT_INFO_SUPPORT=1 -DLIBSPDM_HAL_PASS_SPDM_CONTEXT=1 -DLIBSPDM_SET_CERT_CSR_PARAMS=1"
- "-DLIBSPDM_ENABLE_CAPABILITY_CERT_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_CHAL_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_MEAS_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_PSK_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_CSR_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP=0 -DLIBSPDM_ENABLE_CAPABILITY_EVENT_CAP=0 -DLIBSPDM_RESPOND_IF_READY_SUPPORT=0 -DLIBSPDM_SEND_GET_CERTIFICATE_SUPPORT=0 -DLIBSPDM_SEND_CHALLENGE_SUPPORT=0 -DLIBSPDM_EVENT_RECIPIENT_SUPPORT=0 -DLIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP=0 -DLIBSPDM_SEND_GET_ENDPOINT_INFO_SUPPORT=0 -DLIBSPDM_HAL_PASS_SPDM_CONTEXT=0 -DLIBSPDM_SET_CERT_CSR_PARAMS=0"
- "-DLIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT=0 -DLIBSPDM_FIPS_MODE=0 -DLIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX=0"
- "-DLIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT=1 -DLIBSPDM_FIPS_MODE=1 -DLIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX=1"
- "-DDISABLE_TESTS=1"
Expand Down
42 changes: 42 additions & 0 deletions include/hal/library/endpointinfolib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright Notice:
* Copyright 2025 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

#ifndef ENDPOINTINFOLIB_H
#define ENDPOINTINFOLIB_H

#include "hal/base.h"
#include "internal/libspdm_lib_config.h"
#include "library/spdm_return_status.h"
#include "industry_standard/spdm.h"

#if LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP

/**
* Endpoint Info Response Get Device Class Identifier Function Pointer.
* Required to be able to return the Device Class Identifier correctly
*
* @param spdm_context A pointer to the SPDM context.
* @param sub_code The subcode of endpoint info, should be one of the
* SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_* values.
* @param request_attributes The request attributes of the endpoint info.
* @param endpoint_info_size On output, the size, in bytes, of the buffer to
* hold the device class identifier.
* @param endpoint_info On output, the buffer to hold the device class identifier
* content.
*
* @retval LIBSPDM_STATUS_SUCCESS Success.
* @retval LIBSPDM_STATUS_UNSUPPORTED_CAP The operation is not supported.
**/
extern libspdm_return_t libspdm_generate_device_endpoint_info(
void *spdm_context,
uint8_t sub_code,
uint8_t request_attributes,
uint32_t *endpoint_info_size,
void *endpoint_info);

#endif /* LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP */

#endif /* ENDPOINTINFOLIB_H */
61 changes: 61 additions & 0 deletions include/industry_standard/spdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
#define SPDM_CHUNK_RESPONSE 0x06

/* SPDM response code (1.3) */
#define SPDM_ENDPOINT_INFO 0x07
#define SPDM_SUPPORTED_EVENT_TYPES 0x62
#define SPDM_SUBSCRIBE_EVENT_TYPES_ACK 0x70
#define SPDM_EVENT_ACK 0x71
Expand Down Expand Up @@ -91,6 +92,7 @@
#define SPDM_CHUNK_GET 0x86

/* SPDM request code (1.3) */
#define SPDM_GET_ENDPOINT_INFO 0x87
#define SPDM_GET_SUPPORTED_EVENT_TYPES 0xE2
#define SPDM_SUBSCRIBE_EVENT_TYPES 0xF0
#define SPDM_SEND_EVENT 0xF1
Expand Down Expand Up @@ -1277,6 +1279,65 @@ typedef struct {

#define SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK (1 << 0)

/* SPDM GET_ENDPOINT_INFO request */
typedef struct {
spdm_message_header_t header;
/* param1 - subcode of the request
* param2 - Bit[7:4]: reserved
* Bit[3:0]: slot_id */
uint8_t request_attributes;
uint8_t reserved[3];
/* uint8_t nonce[32]; */
} spdm_get_endpoint_info_request_t;

#define SPDM_GET_ENDPOINT_INFO_REQUEST_SLOT_ID_MASK 0xF

/* SPDM GET_ENDPOINT_INFO request subcode */
#define SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER 0x01

/* SPDM GET_ENDPOINT_INFO request attribute */
#define SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED (1 << 0)

/* SPDM ENDPOINT_INFO response */
typedef struct {
spdm_message_header_t header;
/* param1 - reserved
* param2 - Bit[7:4]: reserved
* Bit[3:0]: slot_id*/
uint32_t reserved;
/* uint8_t nonce[32];
* uint32_t ep_info_len
* uint8_t ep_info[ep_info_len];
* uint8_t signature[sig_len]; */
} spdm_endpoint_info_response_t;

#define SPDM_ENDPOINT_INFO_RESPONSE_SLOT_ID_MASK 0xF

typedef struct {
uint8_t num_identifiers;
uint8_t reserved[3];
/* uint8_t identifier_elements; */
} spdm_endpoint_info_device_class_identifier_t;

typedef struct {
uint8_t id_elem_length;
spdm_svh_header_t svh;
/* size of svh is 2 + vendor_id_len */

/* uint8_t num_sub_ids;
* uint8_t subordinate_id[]; */
} spdm_endpoint_info_device_class_identifier_element_t;

typedef struct {
uint8_t sub_id_len;
/* uint8_t sub_identifier[sub_id_len]; */
} spdm_endpoint_info_device_class_identifier_subordinate_id_t;

#define SPDM_ENDPOINT_INFO_SIGN_CONTEXT "responder-endpoint_info signing"
#define SPDM_ENDPOINT_INFO_SIGN_CONTEXT_SIZE (sizeof(SPDM_ENDPOINT_INFO_SIGN_CONTEXT) - 1)
#define SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT "requester-endpoint_info signing"
#define SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT_SIZE (sizeof(SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT) - 1)

typedef struct {
spdm_message_header_t header;
/* param1 == RSVD
Expand Down
125 changes: 125 additions & 0 deletions include/internal/libspdm_common_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "hal/library/responder/key_pair_info.h"
#include "hal/library/responder/psklib.h"
#include "hal/library/responder/setcertlib.h"
#include "hal/library/endpointinfolib.h"
#include "hal/library/eventlib.h"
#include "hal/library/cryptlib.h"

Expand Down Expand Up @@ -243,6 +244,15 @@ typedef struct {
#define LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE (8 + LIBSPDM_MAX_HASH_SIZE * 2 + \
LIBSPDM_MAX_ASYM_KEY_SIZE)

/*
* +--------------------------+------------------------------------------+---------+
* | GET_EP_INFO 1.3 | 8 + Nonce (0 or 32) = [8, 40] | 1 |
* | EP_INFO 1.3 | 12 + Nonce + EPInfoLen = [12, 1024] | [1, 25] |
* +--------------------------+------------------------------------------+---------+
*/
#define LIBSPDM_MAX_MESSAGE_E_BUFFER_SIZE (20 + SPDM_NONCE_SIZE * 2 + \
LIBSPDM_MAX_ENDPOINT_INFO_LENGTH)

#define LIBSPDM_MAX_MESSAGE_L1L2_BUFFER_SIZE \
(LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE + LIBSPDM_MAX_MESSAGE_M_BUFFER_SIZE)

Expand All @@ -257,6 +267,9 @@ typedef struct {
LIBSPDM_MAX_MESSAGE_D_BUFFER_SIZE + \
LIBSPDM_MAX_HASH_SIZE + LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE)

#define LIBSPDM_MAX_MESSAGE_IL1IL2_BUFFER_SIZE \
(LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE + LIBSPDM_MAX_MESSAGE_E_BUFFER_SIZE)

typedef struct {
size_t max_buffer_size;
size_t buffer_size;
Expand Down Expand Up @@ -287,6 +300,12 @@ typedef struct {
uint8_t buffer[LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE];
} libspdm_message_f_managed_buffer_t;

typedef struct {
size_t max_buffer_size;
size_t buffer_size;
uint8_t buffer[LIBSPDM_MAX_MESSAGE_E_BUFFER_SIZE];
} libspdm_message_e_managed_buffer_t;

typedef struct {
size_t max_buffer_size;
size_t buffer_size;
Expand All @@ -299,6 +318,12 @@ typedef struct {
uint8_t buffer[LIBSPDM_MAX_MESSAGE_M1M2_BUFFER_SIZE];
} libspdm_m1m2_managed_buffer_t;

typedef struct {
size_t max_buffer_size;
size_t buffer_size;
uint8_t buffer[LIBSPDM_MAX_MESSAGE_IL1IL2_BUFFER_SIZE];
} libspdm_il1il2_managed_buffer_t;

typedef struct {
size_t max_buffer_size;
size_t buffer_size;
Expand All @@ -325,6 +350,12 @@ typedef struct {
/* L1/L2 = Concatenate (M)
* M = Concatenate (GET_MEASUREMENT, MEASUREMENT\signature)*/

/* IL1/IL2 = Concatenate (A, E)
* E = Concatenate (GET_ENDPOINT_INFO, ENDPOINT_INFO\signature)*/

/* Encap IL1/IL2 = Concatenate (A, Encap E)
* Encap E = Concatenate (GET_ENDPOINT_INFO, ENDPOINT_INFO\signature)*/

typedef struct {
/* the message_a must be plan text because we do not know the algorithm yet.*/
libspdm_vca_managed_buffer_t message_a;
Expand All @@ -335,10 +366,14 @@ typedef struct {
libspdm_message_b_managed_buffer_t message_mut_b;
libspdm_message_c_managed_buffer_t message_mut_c;
libspdm_message_m_managed_buffer_t message_m;
libspdm_message_e_managed_buffer_t message_e;
libspdm_message_e_managed_buffer_t message_encap_e;
#else
void *digest_context_m1m2;
void *digest_context_mut_m1m2;
void *digest_context_l1l2;
void *digest_context_il1il2;
void *digest_context_encap_il1il2;
#endif
} libspdm_transcript_t;

Expand Down Expand Up @@ -405,10 +440,14 @@ typedef struct {
libspdm_message_k_managed_buffer_t message_k;
libspdm_message_f_managed_buffer_t message_f;
libspdm_message_m_managed_buffer_t message_m;
libspdm_message_e_managed_buffer_t message_e;
libspdm_message_e_managed_buffer_t message_encap_e;
#else
bool message_f_initialized;
void *digest_context_th;
void *digest_context_l1l2;
void *digest_context_il1il2;
void *digest_context_encap_il1il2;
/* this is back up for message F reset.*/
void *digest_context_th_backup;
#endif
Expand Down Expand Up @@ -1006,6 +1045,40 @@ uint32_t libspdm_get_measurement_summary_hash_size(libspdm_context_t *spdm_conte
bool is_requester,
uint8_t measurement_summary_hash_type);

/**
* This function generates the endpoint info signature based upon il1il2 for authentication.
*
* @param spdm_context A pointer to the SPDM context.
* @param session_info A pointer to the SPDM session context.
* @param is_requester Indicate of the signature generation for a requester or a responder.
* @param signature The buffer to store the endpoint info signature.
*
* @retval true challenge signature is generated.
* @retval false challenge signature is not generated.
**/
bool libspdm_generate_endpoint_info_signature(libspdm_context_t *spdm_context,
libspdm_session_info_t *session_info,
bool is_requester,
uint8_t *signature);

/**
* This function verifies the challenge signature based upon m1m2.
*
* @param spdm_context A pointer to the SPDM context.
* @param session_info A pointer to the SPDM session context.
* @param is_requester Indicate of the signature verification for a requester or a responder.
* @param sign_data The signature data buffer.
* @param sign_data_size size in bytes of the signature data buffer.
*
* @retval true signature verification pass.
* @retval false signature verification fail.
**/
bool libspdm_verify_endpoint_info_signature(libspdm_context_t *spdm_context,
libspdm_session_info_t *session_info,
bool is_requester,
const void *sign_data,
size_t sign_data_size);

#if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
/*
* This function calculates l1l2.
Expand Down Expand Up @@ -1306,6 +1379,26 @@ void libspdm_reset_message_encap_d(libspdm_context_t *spdm_context, void *spdm_s
**/
void libspdm_reset_message_f(libspdm_context_t *spdm_context, void *spdm_session_info);

/**
* Reset message E cache in SPDM context.
* If session_info is NULL, this function will use E cache of SPDM context,
* else will use E cache of SPDM session context.
*
* @param spdm_context A pointer to the SPDM context.
* @param spdm_session_info A pointer to the SPDM session context.
**/
void libspdm_reset_message_e(libspdm_context_t *spdm_context, void *session_info);

/**
* Reset message encap E cache in SPDM context.
* If session_info is NULL, this function will use encap E cache of SPDM context,
* else will use encap E cache of SPDM session context.
*
* @param spdm_context A pointer to the SPDM context.
* @param spdm_session_info A pointer to the SPDM session context.
**/
void libspdm_reset_message_encap_e(libspdm_context_t *spdm_context, void *session_info);

/**
* Append message A cache in SPDM context.
*
Expand Down Expand Up @@ -1452,6 +1545,38 @@ libspdm_return_t libspdm_append_message_f(libspdm_context_t *spdm_context,
bool is_requester, const void *message,
size_t message_size);

/**
* Append message E cache in SPDM context.
* If session_info is NULL, this function will use E cache of SPDM context,
* else will use E cache of SPDM session context.
*
* @param spdm_context A pointer to the SPDM context.
* @param session_info A pointer to the SPDM session context.
* @param message message buffer.
* @param message_size size in bytes of message buffer.
*
* @return RETURN_SUCCESS message is appended.
* @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
**/
libspdm_return_t libspdm_append_message_e(libspdm_context_t *spdm_context, void *session_info,
const void *message, size_t message_size);

/**
* Append message encap E cache in SPDM context.
* If session_info is NULL, this function will use encap E cache of SPDM context,
* else will use encap E cache of SPDM session context.
*
* @param spdm_context A pointer to the SPDM context.
* @param session_info A pointer to the SPDM session context.
* @param message message buffer.
* @param message_size size in bytes of message buffer.
*
* @return RETURN_SUCCESS message is appended.
* @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
**/
libspdm_return_t libspdm_append_message_encap_e(libspdm_context_t *spdm_context, void *session_info,
const void *message, size_t message_size);

/**
* This function generates a session ID by concatenating req_session_id and rsp_session_id.
*
Expand Down
11 changes: 10 additions & 1 deletion include/internal/libspdm_responder_lib.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright Notice:
* Copyright 2021-2024 DMTF. All rights reserved.
* Copyright 2021-2025 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

Expand Down Expand Up @@ -957,4 +957,13 @@ libspdm_return_t libspdm_get_response_set_key_pair_info_ack(libspdm_context_t *s
void *response);
#endif /* LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP */


#if LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP
libspdm_return_t libspdm_get_response_endpoint_info(libspdm_context_t *spdm_context,
size_t request_size,
const void *request,
size_t *response_size,
void *response);
#endif /* LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP */

#endif /* SPDM_RESPONDER_LIB_INTERNAL_H */
Loading
Loading