Skip to content

Commit c0d1cd5

Browse files
committed
CAPABILITIES: Add SupportedAlgorithms
fix #2279 Signed-off-by: Shital Jumbad <[email protected]>
1 parent 0f6c6a3 commit c0d1cd5

File tree

6 files changed

+300
-17
lines changed

6 files changed

+300
-17
lines changed

include/industry_standard/spdm.h

+32-7
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,36 @@ typedef struct {
161161
uint32_t max_spdm_msg_size;
162162
} spdm_get_capabilities_request_t;
163163

164+
typedef struct {
165+
uint8_t alg_type;
166+
uint8_t alg_count;
167+
uint16_t alg_supported;
168+
} spdm_negotiate_algorithms_common_struct_table_t;
169+
170+
#define SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG 4
171+
172+
/* SPDM supported algorithms block */
173+
typedef struct {
174+
uint8_t param1; /* Number of Algorithms Structure Tables */
175+
uint8_t param2; /* Reserved */
176+
uint16_t length;
177+
uint8_t measurement_specification;
178+
uint8_t other_params_support;
179+
uint32_t base_asym_algo;
180+
uint32_t base_hash_algo;
181+
uint8_t reserved2[12];
182+
uint8_t ext_asym_count;
183+
uint8_t ext_hash_count;
184+
uint8_t reserved3;
185+
uint8_t mel_specification;
186+
/* Followed by dynamic arrays for ext_asym and ext_hash, if needed
187+
* spdm_extended_algorithm_t ext_asym[ext_asym_count];
188+
* spdm_extended_algorithm_t ext_hash[ext_hash_count]; */
189+
spdm_negotiate_algorithms_common_struct_table_t struct_table[
190+
SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG];
191+
} spdm_supported_algorithms_block_t;
192+
193+
164194
/* SPDM GET_CAPABILITIES response*/
165195

166196
typedef struct {
@@ -174,6 +204,8 @@ typedef struct {
174204
/* Below field is added in 1.2.*/
175205
uint32_t data_transfer_size;
176206
uint32_t max_spdm_msg_size;
207+
/* Below field is added in 1.3.*/
208+
spdm_supported_algorithms_block_t supported_algorithms;
177209
} spdm_capabilities_response_t;
178210

179211
#define SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12 42
@@ -348,13 +380,6 @@ typedef struct {
348380
#define SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG 4
349381
#define SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE 5
350382

351-
typedef struct {
352-
uint8_t alg_type;
353-
uint8_t alg_count;
354-
uint16_t alg_supported;
355-
} spdm_negotiate_algorithms_common_struct_table_t;
356-
357-
358383
/* SPDM NEGOTIATE_ALGORITHMS request base_asym_algo/REQ_BASE_ASYM_ALG */
359384
#define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 0x00000001
360385
#define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 0x00000002

include/internal/libspdm_common_lib.h

+3-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

@@ -43,6 +43,7 @@ typedef struct {
4343
} libspdm_device_version_t;
4444

4545
typedef struct {
46+
uint8_t param1;
4647
uint8_t ct_exponent;
4748
uint64_t rtt;
4849
uint32_t st1;
@@ -55,6 +56,7 @@ typedef struct {
5556
} libspdm_device_capability_t;
5657

5758
typedef struct {
59+
uint8_t param1;
5860
uint8_t measurement_spec;
5961
uint8_t other_params_support;
6062
uint8_t mel_spec;

library/spdm_requester_lib/libspdm_req_get_capabilities.c

+22-4
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_con
251251
}
252252
spdm_request->header.request_response_code = SPDM_GET_CAPABILITIES;
253253
spdm_request->header.param1 = 0;
254+
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
255+
((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) == 0)) {
256+
spdm_request->header.param1 = spdm_context->local_context.capability.param1;
257+
}
254258
spdm_request->header.param2 = 0;
255259
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
256260
spdm_request->ct_exponent = spdm_context->local_context.capability.ct_exponent;
@@ -308,22 +312,36 @@ static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_con
308312
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
309313
goto receive_done;
310314
}
311-
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
315+
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
312316
if (spdm_response_size < sizeof(spdm_capabilities_response_t)) {
313317
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
314318
goto receive_done;
315319
}
320+
} else if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
321+
if (spdm_response_size < (sizeof(spdm_capabilities_response_t) -
322+
sizeof(spdm_supported_algorithms_block_t))) {
323+
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
324+
goto receive_done;
325+
}
316326
} else {
317-
if (spdm_response_size < sizeof(spdm_capabilities_response_t) -
318-
sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)) {
327+
if (spdm_response_size < (sizeof(spdm_capabilities_response_t) -
328+
sizeof(spdm_supported_algorithms_block_t) -
329+
sizeof(spdm_response->data_transfer_size) -
330+
sizeof(spdm_response->max_spdm_msg_size))) {
319331
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
320332
goto receive_done;
321333
}
322334
}
323-
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
335+
336+
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
337+
(spdm_request->header.param1 & 0x01)) {
324338
spdm_response_size = sizeof(spdm_capabilities_response_t);
339+
} else if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
340+
spdm_response_size = sizeof(spdm_capabilities_response_t)-
341+
sizeof(spdm_supported_algorithms_block_t);
325342
} else {
326343
spdm_response_size = sizeof(spdm_capabilities_response_t) -
344+
sizeof(spdm_supported_algorithms_block_t) -
327345
sizeof(spdm_response->data_transfer_size) -
328346
sizeof(spdm_response->max_spdm_msg_size);
329347
}

library/spdm_responder_lib/libspdm_rsp_capabilities.c

+63-1
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,72 @@ libspdm_return_t libspdm_get_response_capabilities(libspdm_context_t *spdm_conte
264264
spdm_context->local_context.capability.max_spdm_msg_size;
265265
}
266266

267-
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
267+
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
268+
(spdm_request->header.param1 & 0x01) &&
269+
((spdm_request->flags &
270+
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) == 0)) {
268271
*response_size = sizeof(spdm_capabilities_response_t);
272+
273+
spdm_response->supported_algorithms.param1 = spdm_context->local_context.algorithm.param1;
274+
spdm_response->supported_algorithms.param2 = 0;
275+
spdm_response->supported_algorithms.length = sizeof(spdm_supported_algorithms_block_t);
276+
spdm_response->supported_algorithms.measurement_specification =
277+
spdm_context->local_context.algorithm.measurement_spec;
278+
spdm_response->supported_algorithms.other_params_support =
279+
spdm_context->local_context.algorithm.other_params_support;
280+
spdm_response->supported_algorithms.base_asym_algo=
281+
spdm_context->local_context.algorithm.base_asym_algo;
282+
spdm_response->supported_algorithms.base_hash_algo=
283+
spdm_context->local_context.algorithm.base_hash_algo;
284+
spdm_response->supported_algorithms.ext_asym_count = 0;
285+
spdm_response->supported_algorithms.ext_hash_count = 0;
286+
spdm_response->supported_algorithms.mel_specification =
287+
spdm_context->local_context.algorithm.mel_spec;
288+
289+
if (spdm_response->supported_algorithms.param1 > 0) {
290+
size_t index = 0;
291+
spdm_response->supported_algorithms.length +=
292+
spdm_response->supported_algorithms.param1*
293+
sizeof(spdm_negotiate_algorithms_common_struct_table_t);
294+
if (spdm_context->local_context.algorithm.dhe_named_group) {
295+
spdm_response->supported_algorithms.struct_table[index].alg_type =
296+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
297+
spdm_response->supported_algorithms.struct_table[index].alg_count = 0x20;
298+
spdm_response->supported_algorithms.struct_table[index].alg_supported =
299+
spdm_context->local_context.algorithm.dhe_named_group;
300+
index++;
301+
}
302+
if (spdm_context->local_context.algorithm.aead_cipher_suite) {
303+
spdm_response->supported_algorithms.struct_table[index].alg_type =
304+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
305+
spdm_response->supported_algorithms.struct_table[index].alg_count = 0x20;
306+
spdm_response->supported_algorithms.struct_table[index].alg_supported =
307+
spdm_context->local_context.algorithm.aead_cipher_suite;
308+
index++;
309+
}
310+
if (spdm_context->local_context.algorithm.req_base_asym_alg) {
311+
spdm_response->supported_algorithms.struct_table[index].alg_type =
312+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
313+
spdm_response->supported_algorithms.struct_table[index].alg_count = 0x20;
314+
spdm_response->supported_algorithms.struct_table[index].alg_supported =
315+
spdm_context->local_context.algorithm.req_base_asym_alg;
316+
index++;
317+
}
318+
if (spdm_context->local_context.algorithm.key_schedule) {
319+
spdm_response->supported_algorithms.struct_table[index].alg_type =
320+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
321+
spdm_response->supported_algorithms.struct_table[index].alg_count = 0x20;
322+
spdm_response->supported_algorithms.struct_table[index].alg_supported =
323+
spdm_context->local_context.algorithm.key_schedule;
324+
index++;
325+
}
326+
}
327+
} else if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
328+
*response_size = sizeof(spdm_capabilities_response_t) -
329+
sizeof(spdm_supported_algorithms_block_t);
269330
} else {
270331
*response_size = sizeof(spdm_capabilities_response_t) -
332+
sizeof(spdm_supported_algorithms_block_t)-
271333
sizeof(spdm_response->data_transfer_size) -
272334
sizeof(spdm_response->max_spdm_msg_size);
273335
}

unit_test/test_spdm_requester/get_capabilities.c

+110-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* Copyright Notice:
3-
* Copyright 2021-2022 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

@@ -145,6 +145,8 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_send_message(
145145
return LIBSPDM_STATUS_SUCCESS;
146146
case 0x23:
147147
return LIBSPDM_STATUS_SUCCESS;
148+
case 0x24:
149+
return LIBSPDM_STATUS_SUCCESS;
148150
default:
149151
return LIBSPDM_STATUS_SEND_FAIL;
150152
}
@@ -417,7 +419,8 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
417419
size_t spdm_response_size;
418420
size_t transport_header_size;
419421

420-
spdm_response_size = sizeof(spdm_capabilities_response_t);
422+
spdm_response_size = sizeof(spdm_capabilities_response_t) -
423+
sizeof(spdm_supported_algorithms_block_t);
421424
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
422425
spdm_response = (void *)((uint8_t *)*response + transport_header_size);
423426

@@ -913,7 +916,8 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
913916
size_t spdm_response_size;
914917
size_t transport_header_size;
915918

916-
spdm_response_size = sizeof(spdm_capabilities_response_t);
919+
spdm_response_size = sizeof(spdm_capabilities_response_t) -
920+
sizeof(spdm_supported_algorithms_block_t);
917921
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
918922
spdm_response = (void *)((uint8_t *)*response + transport_header_size);
919923

@@ -926,6 +930,7 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
926930
spdm_response->flags = LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11;
927931

928932
spdm_response_size = sizeof(spdm_capabilities_response_t) -
933+
sizeof(spdm_supported_algorithms_block_t)-
929934
sizeof(spdm_response->data_transfer_size) -
930935
sizeof(spdm_response->max_spdm_msg_size);
931936

@@ -1008,6 +1013,67 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
10081013
spdm_response->flags = LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_13;
10091014
spdm_response->data_transfer_size = LIBSPDM_DATA_TRANSFER_SIZE;
10101015
spdm_response->max_spdm_msg_size = LIBSPDM_MAX_SPDM_MSG_SIZE;
1016+
libspdm_transport_test_encode_message(spdm_context, NULL, false,
1017+
false, spdm_response_size,
1018+
spdm_response,
1019+
response_size, response);
1020+
}
1021+
return LIBSPDM_STATUS_SUCCESS;
1022+
case 0x24: {
1023+
spdm_capabilities_response_t *spdm_response;
1024+
size_t spdm_response_size;
1025+
size_t transport_header_size;
1026+
1027+
spdm_response_size = sizeof(spdm_capabilities_response_t);
1028+
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1029+
spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1030+
1031+
libspdm_zero_mem(spdm_response, spdm_response_size);
1032+
spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
1033+
spdm_response->header.request_response_code = SPDM_CAPABILITIES;
1034+
spdm_response->header.param1 = 0;
1035+
spdm_response->header.param2 = 0;
1036+
spdm_response->ct_exponent = 0;
1037+
spdm_response->flags = LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_13;
1038+
spdm_response->data_transfer_size = LIBSPDM_DATA_TRANSFER_SIZE;
1039+
spdm_response->max_spdm_msg_size = LIBSPDM_MAX_SPDM_MSG_SIZE;
1040+
1041+
spdm_response->supported_algorithms.param1 = 4;
1042+
spdm_response->supported_algorithms.param2 = 0;
1043+
spdm_response->supported_algorithms.length = sizeof(spdm_supported_algorithms_block_t);
1044+
spdm_response->supported_algorithms.measurement_specification =
1045+
SPDM_MEASUREMENT_SPECIFICATION_DMTF;
1046+
spdm_response->supported_algorithms.other_params_support = 0;
1047+
spdm_response->supported_algorithms.base_asym_algo = m_libspdm_use_asym_algo;
1048+
spdm_response->supported_algorithms.base_hash_algo = m_libspdm_use_hash_algo;
1049+
spdm_response->supported_algorithms.ext_asym_count = 0;
1050+
spdm_response->supported_algorithms.ext_hash_count = 0;
1051+
spdm_response->supported_algorithms.mel_specification = SPDM_MEL_SPECIFICATION_DMTF;
1052+
1053+
spdm_response->supported_algorithms.struct_table[0].alg_type =
1054+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
1055+
spdm_response->supported_algorithms.struct_table[0].alg_count = 0x20;
1056+
spdm_response->supported_algorithms.struct_table[0].alg_supported =
1057+
SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1;
1058+
1059+
spdm_response->supported_algorithms.struct_table[1].alg_type =
1060+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
1061+
spdm_response->supported_algorithms.struct_table[1].alg_count = 0x20;
1062+
spdm_response->supported_algorithms.struct_table[1].alg_supported =
1063+
SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM;;
1064+
1065+
spdm_response->supported_algorithms.struct_table[2].alg_type =
1066+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
1067+
spdm_response->supported_algorithms.struct_table[2].alg_count = 0x20;
1068+
spdm_response->supported_algorithms.struct_table[2].alg_supported =
1069+
SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048;
1070+
1071+
spdm_response->supported_algorithms.struct_table[3].alg_type =
1072+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
1073+
spdm_response->supported_algorithms.struct_table[3].alg_count = 0x20;
1074+
spdm_response->supported_algorithms.struct_table[3].alg_supported =
1075+
SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH;
1076+
10111077
libspdm_transport_test_encode_message(spdm_context, NULL, false,
10121078
false, spdm_response_size,
10131079
spdm_response,
@@ -1405,6 +1471,46 @@ static void libspdm_test_requester_get_capabilities_case35(void **state)
14051471
SPDM_VERSION_NUMBER_SHIFT_BIT;
14061472
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION;
14071473
spdm_context->local_context.capability.ct_exponent = 0;
1474+
spdm_context->local_context.capability.param1 = 0;
1475+
1476+
status = libspdm_get_capabilities(spdm_context);
1477+
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1478+
assert_int_equal(spdm_context->connection_info.capability.max_spdm_msg_size,
1479+
LIBSPDM_MAX_SPDM_MSG_SIZE);
1480+
assert_int_equal(spdm_context->connection_info.capability.data_transfer_size,
1481+
LIBSPDM_DATA_TRANSFER_SIZE);
1482+
assert_int_equal(spdm_context->connection_info.capability.ct_exponent, 0);
1483+
assert_int_equal(spdm_context->connection_info.capability.flags,
1484+
LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_13);
1485+
}
1486+
1487+
static void libspdm_test_requester_get_capabilities_case36(void **state)
1488+
{
1489+
libspdm_return_t status;
1490+
libspdm_test_context_t *spdm_test_context;
1491+
libspdm_context_t *spdm_context;
1492+
1493+
spdm_test_context = *state;
1494+
spdm_context = spdm_test_context->spdm_context;
1495+
spdm_test_context->case_id = 0x24;
1496+
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
1497+
SPDM_VERSION_NUMBER_SHIFT_BIT;
1498+
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION;
1499+
spdm_context->local_context.capability.ct_exponent = 0;
1500+
1501+
spdm_context->local_context.capability.param1 = 1;
1502+
1503+
spdm_context->local_context.algorithm.param1=4;
1504+
spdm_context->local_context.algorithm.measurement_spec = SPDM_MEASUREMENT_SPECIFICATION_DMTF;
1505+
spdm_context->local_context.algorithm.other_params_support = 0;
1506+
spdm_context->local_context.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
1507+
spdm_context->local_context.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1508+
spdm_context->local_context.algorithm.mel_spec = SPDM_MEL_SPECIFICATION_DMTF;
1509+
1510+
spdm_context->local_context.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
1511+
spdm_context->local_context.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
1512+
spdm_context->local_context.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
1513+
spdm_context->local_context.algorithm.key_schedule = m_libspdm_use_key_schedule_algo;
14081514

14091515
status = libspdm_get_capabilities(spdm_context);
14101516
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
@@ -1455,6 +1561,7 @@ int libspdm_requester_get_capabilities_test_main(void)
14551561
cmocka_unit_test(libspdm_test_requester_get_capabilities_case33),
14561562
/* cmocka_unit_test(libspdm_test_requester_get_capabilities_case34), */
14571563
cmocka_unit_test(libspdm_test_requester_get_capabilities_case35),
1564+
cmocka_unit_test(libspdm_test_requester_get_capabilities_case36),
14581565
};
14591566

14601567
libspdm_test_context_t test_context = {

0 commit comments

Comments
 (0)