Skip to content

Commit 81fcc82

Browse files
committed
Add SPDM 1.3 feature GET_ENDPOINT_INFO
Fix the issue: #2294 ENDPOINT_INFO is SPDM spec 1.3 new feature. Add ENDPOINT_INFO for Libspdm. Signed-off-by: Aaron Li <[email protected]>
1 parent 5271753 commit 81fcc82

24 files changed

+6758
-8
lines changed

include/industry_standard/spdm.h

+61
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#define SPDM_CHUNK_RESPONSE 0x06
5656

5757
/* SPDM response code (1.3) */
58+
#define SPDM_ENDPOINT_INFO 0x07
5859
#define SPDM_SUPPORTED_EVENT_TYPES 0x62
5960
#define SPDM_SUBSCRIBE_EVENT_TYPES_ACK 0x70
6061
#define SPDM_EVENT_ACK 0x71
@@ -91,6 +92,7 @@
9192
#define SPDM_CHUNK_GET 0x86
9293

9394
/* SPDM request code (1.3) */
95+
#define SPDM_GET_ENDPOINT_INFO 0x87
9496
#define SPDM_GET_SUPPORTED_EVENT_TYPES 0xE2
9597
#define SPDM_SUBSCRIBE_EVENT_TYPES 0xF0
9698
#define SPDM_SEND_EVENT 0xF1
@@ -1277,6 +1279,65 @@ typedef struct {
12771279

12781280
#define SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK (1 << 0)
12791281

1282+
/* SPDM GET_ENDPOINT_INFO request */
1283+
typedef struct {
1284+
spdm_message_header_t header;
1285+
/* param1 - subcode of the request
1286+
* param2 - Bit[7:4]: reserved
1287+
* Bit[3:0]: slot_id */
1288+
uint8_t request_attributes;
1289+
uint8_t reserved[3];
1290+
/* uint8_t nonce[32]; */
1291+
} spdm_get_endpoint_info_request_t;
1292+
1293+
#define SPDM_GET_ENDPOINT_INFO_REQUEST_SLOT_ID_MASK 0xF
1294+
1295+
/* SPDM GET_ENDPOINT_INFO request subcode */
1296+
#define SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER 0x01
1297+
1298+
/* SPDM GET_ENDPOINT_INFO request attribute */
1299+
#define SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED (1 << 0)
1300+
1301+
/* SPDM ENDPOINT_INFO response */
1302+
typedef struct {
1303+
spdm_message_header_t header;
1304+
/* param1 - reserved
1305+
* param2 - Bit[7:4]: reserved
1306+
* Bit[3:0]: slot_id*/
1307+
uint32_t reserved;
1308+
/* uint8_t nonce[32];
1309+
* uint32_t ep_info_len
1310+
* uint8_t ep_info[ep_info_len];
1311+
* uint8_t signature[sig_len]; */
1312+
} spdm_endpoint_info_response_t;
1313+
1314+
#define SPDM_ENDPOINT_INFO_RESPONSE_SLOT_ID_MASK 0xF
1315+
1316+
typedef struct {
1317+
uint8_t num_identifiers;
1318+
uint8_t reserved[3];
1319+
/* uint8_t identifier_elements; */
1320+
} spdm_endpoint_info_device_class_identifier_t;
1321+
1322+
typedef struct {
1323+
uint8_t id_elem_length;
1324+
spdm_svh_header_t svh;
1325+
/* size of svh is 2 + vendor_id_len */
1326+
1327+
/* uint8_t num_sub_ids;
1328+
* uint8_t subordinate_id[]; */
1329+
} spdm_endpoint_info_device_class_identifier_element_t;
1330+
1331+
typedef struct {
1332+
uint8_t sub_id_len;
1333+
/* uint8_t sub_identifier[sub_id_len]; */
1334+
} spdm_endpoint_info_device_class_identifier_subordinate_id_t;
1335+
1336+
#define SPDM_ENDPOINT_INFO_SIGN_CONTEXT "responder-endpoint_info signing"
1337+
#define SPDM_ENDPOINT_INFO_SIGN_CONTEXT_SIZE (sizeof(SPDM_ENDPOINT_INFO_SIGN_CONTEXT) - 1)
1338+
#define SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT "requester-endpoint_info signing"
1339+
#define SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT_SIZE (sizeof(SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT) - 1)
1340+
12801341
typedef struct {
12811342
spdm_message_header_t header;
12821343
/* param1 == RSVD

include/internal/libspdm_common_lib.h

+128
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,15 @@ typedef struct {
243243
#define LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE (8 + LIBSPDM_MAX_HASH_SIZE * 2 + \
244244
LIBSPDM_MAX_ASYM_KEY_SIZE)
245245

246+
/*
247+
* +--------------------------+------------------------------------------+---------+
248+
* | GET_EP_INFO 1.3 | 8 + Nonce (0 or 32) = [8, 40] | 1 |
249+
* | EP_INFO 1.3 | 12 + Nonce + EPInfoLen = [12, 1024] | [1, 25] |
250+
* +--------------------------+------------------------------------------+---------+
251+
*/
252+
#define LIBSPDM_MAX_MESSAGE_E_BUFFER_SIZE (20 + SPDM_NONCE_SIZE * 2 + \
253+
LIBSPDM_MAX_ENDPOINT_INFO_LENGTH)
254+
246255
#define LIBSPDM_MAX_MESSAGE_L1L2_BUFFER_SIZE \
247256
(LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE + LIBSPDM_MAX_MESSAGE_M_BUFFER_SIZE)
248257

@@ -257,6 +266,9 @@ typedef struct {
257266
LIBSPDM_MAX_MESSAGE_D_BUFFER_SIZE + \
258267
LIBSPDM_MAX_HASH_SIZE + LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE)
259268

269+
#define LIBSPDM_MAX_MESSAGE_IL1IL2_BUFFER_SIZE \
270+
(LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE + LIBSPDM_MAX_MESSAGE_E_BUFFER_SIZE)
271+
260272
typedef struct {
261273
size_t max_buffer_size;
262274
size_t buffer_size;
@@ -287,6 +299,12 @@ typedef struct {
287299
uint8_t buffer[LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE];
288300
} libspdm_message_f_managed_buffer_t;
289301

302+
typedef struct {
303+
size_t max_buffer_size;
304+
size_t buffer_size;
305+
uint8_t buffer[LIBSPDM_MAX_MESSAGE_E_BUFFER_SIZE];
306+
} libspdm_message_e_managed_buffer_t;
307+
290308
typedef struct {
291309
size_t max_buffer_size;
292310
size_t buffer_size;
@@ -299,6 +317,12 @@ typedef struct {
299317
uint8_t buffer[LIBSPDM_MAX_MESSAGE_M1M2_BUFFER_SIZE];
300318
} libspdm_m1m2_managed_buffer_t;
301319

320+
typedef struct {
321+
size_t max_buffer_size;
322+
size_t buffer_size;
323+
uint8_t buffer[LIBSPDM_MAX_MESSAGE_IL1IL2_BUFFER_SIZE];
324+
} libspdm_il1il2_managed_buffer_t;
325+
302326
typedef struct {
303327
size_t max_buffer_size;
304328
size_t buffer_size;
@@ -325,6 +349,12 @@ typedef struct {
325349
/* L1/L2 = Concatenate (M)
326350
* M = Concatenate (GET_MEASUREMENT, MEASUREMENT\signature)*/
327351

352+
/* IL1/IL2 = Concatenate (A, E)
353+
* E = Concatenate (GET_ENDPOINT_INFO, ENDPOINT_INFO\signature)*/
354+
355+
/* Mut IL1/IL2 = Concatenate (A, Mut E)
356+
* Mut E = Concatenate (GET_ENDPOINT_INFO, ENDPOINT_INFO\signature)*/
357+
328358
typedef struct {
329359
/* the message_a must be plan text because we do not know the algorithm yet.*/
330360
libspdm_vca_managed_buffer_t message_a;
@@ -335,10 +365,14 @@ typedef struct {
335365
libspdm_message_b_managed_buffer_t message_mut_b;
336366
libspdm_message_c_managed_buffer_t message_mut_c;
337367
libspdm_message_m_managed_buffer_t message_m;
368+
libspdm_message_e_managed_buffer_t message_e;
369+
libspdm_message_e_managed_buffer_t message_mut_e;
338370
#else
339371
void *digest_context_m1m2;
340372
void *digest_context_mut_m1m2;
341373
void *digest_context_l1l2;
374+
void *digest_context_il1il2;
375+
void *digest_context_mut_il1il2;
342376
#endif
343377
} libspdm_transcript_t;
344378

@@ -405,10 +439,14 @@ typedef struct {
405439
libspdm_message_k_managed_buffer_t message_k;
406440
libspdm_message_f_managed_buffer_t message_f;
407441
libspdm_message_m_managed_buffer_t message_m;
442+
libspdm_message_e_managed_buffer_t message_e;
443+
libspdm_message_e_managed_buffer_t message_mut_e;
408444
#else
409445
bool message_f_initialized;
410446
void *digest_context_th;
411447
void *digest_context_l1l2;
448+
void *digest_context_il1il2;
449+
void *digest_context_mut_il1il2;
412450
/* this is back up for message F reset.*/
413451
void *digest_context_th_backup;
414452
#endif
@@ -619,6 +657,10 @@ typedef struct {
619657
* This field is ignored for other SPDM versions */
620658
uint8_t spdm_10_11_verify_signature_endian;
621659

660+
#if LIBSPDM_ENABLE_ENDPOINT_INFO_CAP
661+
libspdm_endpoint_info_device_func endpoint_info_device_func;
662+
#endif /* LIBSPDM_ENABLE_ENDPOINT_INFO_CAP */
663+
622664
#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
623665
libspdm_vendor_response_callback_func vendor_response_callback;
624666
libspdm_vendor_get_id_callback_func vendor_response_get_id;
@@ -1006,6 +1048,40 @@ uint32_t libspdm_get_measurement_summary_hash_size(libspdm_context_t *spdm_conte
10061048
bool is_requester,
10071049
uint8_t measurement_summary_hash_type);
10081050

1051+
/**
1052+
* This function generates the endpoint info signature based upon il1il2 for authentication.
1053+
*
1054+
* @param spdm_context A pointer to the SPDM context.
1055+
* @param session_info A pointer to the SPDM session context.
1056+
* @param is_requester Indicate of the signature generation for a requester or a responder.
1057+
* @param signature The buffer to store the endpoint info signature.
1058+
*
1059+
* @retval true challenge signature is generated.
1060+
* @retval false challenge signature is not generated.
1061+
**/
1062+
bool libspdm_generate_endpoint_info_signature(libspdm_context_t *spdm_context,
1063+
libspdm_session_info_t *session_info,
1064+
bool is_requester,
1065+
uint8_t *signature);
1066+
1067+
/**
1068+
* This function verifies the challenge signature based upon m1m2.
1069+
*
1070+
* @param spdm_context A pointer to the SPDM context.
1071+
* @param session_info A pointer to the SPDM session context.
1072+
* @param is_requester Indicate of the signature verification for a requester or a responder.
1073+
* @param sign_data The signature data buffer.
1074+
* @param sign_data_size size in bytes of the signature data buffer.
1075+
*
1076+
* @retval true signature verification pass.
1077+
* @retval false signature verification fail.
1078+
**/
1079+
bool libspdm_verify_endpoint_info_signature(libspdm_context_t *spdm_context,
1080+
libspdm_session_info_t *session_info,
1081+
bool is_requester,
1082+
const void *sign_data,
1083+
size_t sign_data_size);
1084+
10091085
#if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
10101086
/*
10111087
* This function calculates l1l2.
@@ -1306,6 +1382,26 @@ void libspdm_reset_message_encap_d(libspdm_context_t *spdm_context, void *spdm_s
13061382
**/
13071383
void libspdm_reset_message_f(libspdm_context_t *spdm_context, void *spdm_session_info);
13081384

1385+
/**
1386+
* Reset message E cache in SPDM context.
1387+
* If session_info is NULL, this function will use E cache of SPDM context,
1388+
* else will use E cache of SPDM session context.
1389+
*
1390+
* @param spdm_context A pointer to the SPDM context.
1391+
* @param spdm_session_info A pointer to the SPDM session context.
1392+
**/
1393+
void libspdm_reset_message_e(libspdm_context_t *spdm_context, void *session_info);
1394+
1395+
/**
1396+
* Reset message mut E cache in SPDM context.
1397+
* If session_info is NULL, this function will use mut E cache of SPDM context,
1398+
* else will use mut E cache of SPDM session context.
1399+
*
1400+
* @param spdm_context A pointer to the SPDM context.
1401+
* @param spdm_session_info A pointer to the SPDM session context.
1402+
**/
1403+
void libspdm_reset_message_mut_e(libspdm_context_t *spdm_context, void *session_info);
1404+
13091405
/**
13101406
* Append message A cache in SPDM context.
13111407
*
@@ -1452,6 +1548,38 @@ libspdm_return_t libspdm_append_message_f(libspdm_context_t *spdm_context,
14521548
bool is_requester, const void *message,
14531549
size_t message_size);
14541550

1551+
/**
1552+
* Append message E cache in SPDM context.
1553+
* If session_info is NULL, this function will use E cache of SPDM context,
1554+
* else will use E cache of SPDM session context.
1555+
*
1556+
* @param spdm_context A pointer to the SPDM context.
1557+
* @param session_info A pointer to the SPDM session context.
1558+
* @param message message buffer.
1559+
* @param message_size size in bytes of message buffer.
1560+
*
1561+
* @return RETURN_SUCCESS message is appended.
1562+
* @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1563+
**/
1564+
libspdm_return_t libspdm_append_message_e(libspdm_context_t *spdm_context, void *session_info,
1565+
const void *message, size_t message_size);
1566+
1567+
/**
1568+
* Append message mut E cache in SPDM context.
1569+
* If session_info is NULL, this function will use mut E cache of SPDM context,
1570+
* else will use mut E cache of SPDM session context.
1571+
*
1572+
* @param spdm_context A pointer to the SPDM context.
1573+
* @param session_info A pointer to the SPDM session context.
1574+
* @param message message buffer.
1575+
* @param message_size size in bytes of message buffer.
1576+
*
1577+
* @return RETURN_SUCCESS message is appended.
1578+
* @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1579+
**/
1580+
libspdm_return_t libspdm_append_message_mut_e(libspdm_context_t *spdm_context, void *session_info,
1581+
const void *message, size_t message_size);
1582+
14551583
/**
14561584
* This function generates a session ID by concatenating req_session_id and rsp_session_id.
14571585
*

include/internal/libspdm_responder_lib.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Copyright Notice:
3-
* Copyright 2021-2024 DMTF. All rights reserved.
3+
* Copyright 2021-2025 DMTF. All rights reserved.
44
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
55
**/
66

@@ -957,4 +957,13 @@ libspdm_return_t libspdm_get_response_set_key_pair_info_ack(libspdm_context_t *s
957957
void *response);
958958
#endif /* LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP */
959959

960+
961+
#if LIBSPDM_ENABLE_ENDPOINT_INFO_CAP
962+
libspdm_return_t libspdm_get_response_endpoint_info(libspdm_context_t *spdm_context,
963+
size_t request_size,
964+
const void *request,
965+
size_t *response_size,
966+
void *response);
967+
#endif /* LIBSPDM_ENABLE_ENDPOINT_INFO_CAP */
968+
960969
#endif /* SPDM_RESPONDER_LIB_INTERNAL_H */

include/library/spdm_common_lib.h

+25
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,31 @@ uint32_t libspdm_module_version(void);
958958
/*true: FIPS enabled, false: FIPS disabled*/
959959
bool libspdm_get_fips_mode(void);
960960

961+
962+
#if LIBSPDM_ENABLE_ENDPOINT_INFO_CAP
963+
964+
/**
965+
* Endpoint Info Response Get Device Class Identifier Function Pointer.
966+
* Required to be able to return the Device Class Identifier correctly
967+
*
968+
* @param spdm_context A pointer to the SPDM context.
969+
* @param sub_code The subcode of endpoint info.
970+
* @param endpoint_info_size Length in bytes of the size of device class identifier.
971+
* @param endpoint_info The buffer to store device class identifier content.
972+
* If NULL, only return the size of device class identifier.
973+
* If not NULL, copy the device class identifier to the buffer.
974+
*
975+
* @retval LIBSPDM_STATUS_SUCCESS Success
976+
* @retval LIBSPDM_STATUS_INVALID_PARAMETER Some parameters invalid or NULL
977+
**/
978+
typedef libspdm_return_t (*libspdm_endpoint_info_device_func)(
979+
void *spdm_context,
980+
uint8_t sub_code,
981+
uint32_t *endpoint_info_size,
982+
void *endpoint_info);
983+
984+
#endif /* LIBSPDM_ENABLE_ENDPOINT_INFO_CAP */
985+
961986
#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
962987

963988
/**

include/library/spdm_lib_config.h

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Copyright Notice:
3-
* Copyright 2021-2024 DMTF. All rights reserved.
3+
* Copyright 2021-2025 DMTF. All rights reserved.
44
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
55
**/
66

@@ -82,6 +82,10 @@
8282
#define LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP 1
8383
#endif
8484

85+
#ifndef LIBSPDM_ENABLE_ENDPOINT_INFO_CAP
86+
#define LIBSPDM_ENABLE_ENDPOINT_INFO_CAP 1
87+
#endif
88+
8589
/* Includes SPDM 1.3 features for CSR messages. If enabled then LIBSPDM_ENABLE_CAPABILITY_CSR_CAP
8690
* must also be enabled.
8791
*/
@@ -213,6 +217,13 @@
213217
#define LIBSPDM_MAX_MEL_BLOCK_LEN 1024
214218
#endif
215219

220+
/* This value specifies the maximum size, in bytes, of a endpoint info that can be stored in a
221+
* libspdm context.
222+
*/
223+
#ifndef LIBSPDM_MAX_ENDPOINT_INFO_LENGTH
224+
#define LIBSPDM_MAX_ENDPOINT_INFO_LENGTH 1024
225+
#endif
226+
216227
/* To ensure integrity in communication between the Requester and the Responder libspdm calculates
217228
* cryptographic digests and signatures over multiple requests and responses. This value specifies
218229
* whether libspdm will use a running calculation over the transcript, where requests and responses

0 commit comments

Comments
 (0)