Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4a737ff

Browse files
committedMar 20, 2025
CAPABILITIES: Add SupportedAlgorithms
fix DMTF#2279 Signed-off-by: Shital Jumbad <[email protected]>
1 parent 18a2654 commit 4a737ff

File tree

11 files changed

+603
-83
lines changed

11 files changed

+603
-83
lines changed
 

‎doc/api/requester_api.md

+23
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,29 @@ returns early with value not equal to `LIBSPDM_STATUS_SUCCESS` then the SPDM con
3131
before attempting establish a new connection.
3232
<br/><br/>
3333

34+
---
35+
### libspdm_get_supported_algorithms
36+
---
37+
38+
### Description
39+
Sends the `GET_VERSION` and `GET_CAPABILITIES` requests, where GET_CAPABILITIES.Param1[0] is set.
40+
If the Responder supports this extended capability, the Responder will include the Supported
41+
Algorithms Block in its CAPABILITIES response. If the requester wishes to continue with the
42+
connection, they can call `libspdm_init_connection` to restart the connection process.
43+
44+
### Parameters
45+
46+
**spdm_context**<br/>
47+
The SPDM context.
48+
49+
### Details
50+
Before calling this function, the integrator must ensure that the SPDM context is initialized
51+
with the necessary configuration, including the requester's capabilities and supported
52+
cryptographic algorithms. When this function returns with the value `RETURN_SUCCESS`,
53+
the SPDM context can be queried to determine the capabilities and algorithms supported
54+
by the responder. If this function returns with a value not equal to `RETURN_SUCCESS`,
55+
the SPDM context should be reset before attempting to establish a new connection.
56+
<br/><br/>
3457

3558
---
3659
### libspdm_get_digest

‎include/industry_standard/spdm.h

+56-14
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,61 @@ typedef struct {
161161
uint32_t max_spdm_msg_size;
162162
} spdm_get_capabilities_request_t;
163163

164-
/* SPDM GET_CAPABILITIES response*/
164+
/* SPDM extended algorithm */
165+
typedef struct {
166+
uint8_t registry_id;
167+
uint8_t reserved;
168+
uint16_t algorithm_id;
169+
} spdm_extended_algorithm_t;
170+
171+
typedef struct {
172+
uint8_t alg_type;
173+
uint8_t alg_count;
174+
uint16_t alg_supported;
175+
} spdm_negotiate_algorithms_common_struct_table_t;
165176

177+
/* SPDM supported algorithms block */
178+
typedef struct {
179+
uint8_t param1; /* Number of Algorithms Structure Tables */
180+
uint8_t param2; /* Reserved */
181+
uint16_t length;
182+
uint8_t measurement_specification;
183+
uint8_t other_params_support;
184+
uint32_t base_asym_algo;
185+
uint32_t base_hash_algo;
186+
uint8_t reserved2[12];
187+
uint8_t ext_asym_count;
188+
uint8_t ext_hash_count;
189+
uint8_t reserved3;
190+
uint8_t mel_specification;
191+
/* Followed by dynamic arrays for ext_asym, ext_hash, and struct_tableif needed
192+
* spdm_extended_algorithm_t ext_asym[ext_asym_count];
193+
* spdm_extended_algorithm_t ext_hash[ext_hash_count];
194+
* spdm_negotiate_algorithms_common_struct_table_t struct_table[
195+
* SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG];*/
196+
} spdm_supported_algorithms_block_t;
197+
198+
/* Specification states that total Extended algorithms count is less than or equal to 20*/
199+
#define SPDM_ALGORITHMS_MAX_NUM_EXT_ASYM_COUNT 20
200+
#define SPDM_ALGORITHMS_MAX_NUM_EXT_HASH_COUNT 20
201+
#define SPDM_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG 4
202+
203+
/* SPDM supported algorithms by responder */
204+
typedef struct {
205+
uint8_t measurement_specification;
206+
uint8_t other_params_support;
207+
uint32_t base_asym_algo;
208+
uint32_t base_hash_algo;
209+
uint8_t ext_asym_count;
210+
uint8_t ext_hash_count;
211+
uint8_t mel_specification;
212+
spdm_extended_algorithm_t ext_asym[SPDM_ALGORITHMS_MAX_NUM_EXT_ASYM_COUNT];
213+
spdm_extended_algorithm_t ext_hash[SPDM_ALGORITHMS_MAX_NUM_EXT_HASH_COUNT];
214+
spdm_negotiate_algorithms_common_struct_table_t struct_table[
215+
SPDM_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG];
216+
} spdm_responder_supported_algorithms_t;
217+
218+
/* SPDM GET_CAPABILITIES response*/
166219
typedef struct {
167220
spdm_message_header_t header;
168221
/* param1 == RSVD
@@ -174,6 +227,8 @@ typedef struct {
174227
/* Below field is added in 1.2.*/
175228
uint32_t data_transfer_size;
176229
uint32_t max_spdm_msg_size;
230+
/* Below field is added in 1.3.*/
231+
spdm_supported_algorithms_block_t supported_algorithms;
177232
} spdm_capabilities_response_t;
178233

179234
#define SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12 42
@@ -357,12 +412,6 @@ typedef struct {
357412
#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_AEAD_12_MASK 0x000f
358413
#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_REQ_BASE_ASYM_ALG_12_MASK 0x0fff
359414

360-
typedef struct {
361-
uint8_t alg_type;
362-
uint8_t alg_count;
363-
uint16_t alg_supported;
364-
} spdm_negotiate_algorithms_common_struct_table_t;
365-
366415

367416
/* SPDM NEGOTIATE_ALGORITHMS request base_asym_algo/REQ_BASE_ASYM_ALG */
368417
#define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 0x00000001
@@ -481,13 +530,6 @@ typedef struct {
481530
/*opaque_element_table_t opaque_list[];*/
482531
} spdm_general_opaque_data_table_header_t;
483532

484-
/* SPDM extended algorithm */
485-
typedef struct {
486-
uint8_t registry_id;
487-
uint8_t reserved;
488-
uint16_t algorithm_id;
489-
} spdm_extended_algorithm_t;
490-
491533
/* SPDM registry_id */
492534
#define SPDM_REGISTRY_ID_DMTF 0x0
493535
#define SPDM_REGISTRY_ID_TCG 0x1

‎include/internal/libspdm_requester_lib.h

+5-2
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

@@ -133,6 +133,7 @@ libspdm_return_t libspdm_get_version(libspdm_context_t *spdm_context,
133133
* This function sends GET_CAPABILITIES and receives CAPABILITIES.
134134
*
135135
* @param spdm_context A pointer to the SPDM context.
136+
* @param get_supported_algorithms If true, indicates that the requester wants the responder to include its supported algorithms in the CAPABILITIES response.
136137
* @param RequesterCTExponent RequesterCTExponent to the GET_CAPABILITIES request.
137138
* @param RequesterFlags RequesterFlags to the GET_CAPABILITIES request.
138139
* @param ResponderCTExponent ResponderCTExponent from the CAPABILITIES response.
@@ -141,7 +142,9 @@ libspdm_return_t libspdm_get_version(libspdm_context_t *spdm_context,
141142
* @retval RETURN_SUCCESS The GET_CAPABILITIES is sent and the CAPABILITIES is received.
142143
* @retval RETURN_DEVICE_ERROR A device error occurs when communicates with the device.
143144
**/
144-
libspdm_return_t libspdm_get_capabilities(libspdm_context_t *spdm_context);
145+
libspdm_return_t libspdm_get_capabilities(libspdm_context_t *spdm_context,
146+
bool get_supported_algorithms,
147+
spdm_responder_supported_algorithms_t *supported_algs);
145148

146149
/**
147150
* This function sends NEGOTIATE_ALGORITHMS and receives ALGORITHMS.

‎include/library/spdm_requester_lib.h

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

@@ -491,6 +491,19 @@ libspdm_return_t libspdm_start_session(void *spdm_context, bool use_psk,
491491
uint8_t *heartbeat_period,
492492
void *measurement_hash);
493493

494+
/**
495+
* Sends the `GET_VERSION` and `GET_CAPABILITIES` requests, where GET_CAPABILITIES.Param1[0] is set
496+
* If the Responder supports this extended capability, the Responder will include the Supported
497+
* Algorithms Block in its CAPABILITIES response.
498+
*
499+
* @param spdm_context The SPDM context.
500+
*
501+
* @retval RETURN_SUCCESS The connection is initialized successfully.
502+
* @retval RETURN_DEVICE_ERROR A device error occurs when communicates with the device.
503+
**/
504+
libspdm_return_t libspdm_get_supported_algorithms(
505+
void *spdm_context, void *responder_supported_algorithms);
506+
494507
/**
495508
* This function sends KEY_EXCHANGE/FINISH or PSK_EXCHANGE/PSK_FINISH to start an SPDM Session.
496509
*

‎library/spdm_requester_lib/libspdm_req_communication.c

+47-2
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

@@ -19,7 +19,7 @@ libspdm_return_t libspdm_init_connection(void *spdm_context, bool get_version_on
1919
}
2020

2121
if (!get_version_only) {
22-
status = libspdm_get_capabilities(context);
22+
status = libspdm_get_capabilities(context, false, NULL);
2323
if (LIBSPDM_STATUS_IS_ERROR(status)) {
2424
return status;
2525
}
@@ -31,6 +31,51 @@ libspdm_return_t libspdm_init_connection(void *spdm_context, bool get_version_on
3131
return LIBSPDM_STATUS_SUCCESS;
3232
}
3333

34+
libspdm_return_t libspdm_get_supported_algorithms(void *spdm_context,
35+
void *responder_supported_algorithms)
36+
{
37+
libspdm_return_t status;
38+
libspdm_context_t *context;
39+
spdm_responder_supported_algorithms_t *algorithms;
40+
bool has_version_1_3_or_above;
41+
size_t index;
42+
43+
context = spdm_context;
44+
algorithms = responder_supported_algorithms;
45+
has_version_1_3_or_above = false;
46+
47+
/* Pre-check: Verify requester supports at least one version >= 1.3 */
48+
for (index = 0; index < context->local_context.version.spdm_version_count; index++) {
49+
if (context->local_context.version.spdm_version[index] >= SPDM_MESSAGE_VERSION_13) {
50+
has_version_1_3_or_above = true;
51+
break;
52+
}
53+
}
54+
LIBSPDM_ASSERT(has_version_1_3_or_above);
55+
if (!has_version_1_3_or_above) {
56+
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
57+
}
58+
59+
LIBSPDM_ASSERT((context->local_context.capability.flags &
60+
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) != 0);
61+
62+
status = libspdm_get_version(context, NULL, NULL);
63+
if (LIBSPDM_STATUS_IS_ERROR(status)) {
64+
return status;
65+
}
66+
67+
if (context->connection_info.version < SPDM_MESSAGE_VERSION_13) {
68+
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
69+
}
70+
71+
status = libspdm_get_capabilities(context, true, algorithms);
72+
if (LIBSPDM_STATUS_IS_ERROR(status)) {
73+
return status;
74+
}
75+
76+
return LIBSPDM_STATUS_SUCCESS;
77+
}
78+
3479
#if (LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)
3580
libspdm_return_t libspdm_start_session(void *spdm_context, bool use_psk,
3681
const void *psk_hint,

‎library/spdm_requester_lib/libspdm_req_get_capabilities.c

+114-8
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t ve
211211
* @retval LIBSPDM_STATUS_BUFFER_FULL
212212
* The buffer used to store transcripts is exhausted.
213213
**/
214-
static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_context)
214+
static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_context,
215+
bool get_supported_algorithms,
216+
spdm_responder_supported_algorithms_t *supported_algs)
215217
{
216218
libspdm_return_t status;
217219
spdm_get_capabilities_request_t *spdm_request;
@@ -241,6 +243,11 @@ static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_con
241243
spdm_context->local_context.capability.transport_tail_size;
242244

243245
LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_request->header));
246+
247+
LIBSPDM_ASSERT(!((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
248+
get_supported_algorithms &&
249+
((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) == 0)));
250+
244251
libspdm_zero_mem(spdm_request, spdm_request_size);
245252
spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
246253
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
@@ -258,6 +265,10 @@ static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_con
258265
}
259266
spdm_request->header.request_response_code = SPDM_GET_CAPABILITIES;
260267
spdm_request->header.param1 = 0;
268+
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
269+
get_supported_algorithms) {
270+
spdm_request->header.param1 |= 0x01;
271+
}
261272
spdm_request->header.param2 = 0;
262273
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
263274
spdm_request->ct_exponent = spdm_context->local_context.capability.ct_exponent;
@@ -315,22 +326,60 @@ static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_con
315326
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
316327
goto receive_done;
317328
}
318-
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
329+
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
319330
if (spdm_response_size < sizeof(spdm_capabilities_response_t)) {
320331
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
321332
goto receive_done;
322333
}
334+
} else if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
335+
if (spdm_response_size < (sizeof(spdm_capabilities_response_t) -
336+
sizeof(spdm_supported_algorithms_block_t))) {
337+
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
338+
goto receive_done;
339+
}
323340
} else {
324-
if (spdm_response_size < sizeof(spdm_capabilities_response_t) -
325-
sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)) {
341+
if (spdm_response_size < (sizeof(spdm_capabilities_response_t) -
342+
sizeof(spdm_supported_algorithms_block_t) -
343+
sizeof(spdm_response->data_transfer_size) -
344+
sizeof(spdm_response->max_spdm_msg_size))) {
326345
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
327346
goto receive_done;
328347
}
329348
}
330-
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
331-
spdm_response_size = sizeof(spdm_capabilities_response_t);
349+
350+
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
351+
(spdm_request->header.param1 & 0x01)) {
352+
353+
uint8_t index = 0;
354+
if (spdm_context->connection_info.capability.flags &
355+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) {
356+
index++;
357+
}
358+
if ((spdm_context->connection_info.capability.flags &
359+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) ||
360+
(spdm_context->connection_info.capability.flags &
361+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
362+
index++;
363+
}
364+
if (spdm_context->connection_info.capability.flags &
365+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP) {
366+
index++;
367+
}
368+
if ((spdm_context->connection_info.capability.flags &
369+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_UPD_CAP) ||
370+
(spdm_context->connection_info.capability.flags &
371+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
372+
index++;
373+
}
374+
spdm_response_size = sizeof(spdm_capabilities_response_t)+
375+
index*sizeof(spdm_negotiate_algorithms_common_struct_table_t);
376+
377+
} else if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
378+
spdm_response_size = sizeof(spdm_capabilities_response_t)-
379+
sizeof(spdm_supported_algorithms_block_t);
332380
} else {
333381
spdm_response_size = sizeof(spdm_capabilities_response_t) -
382+
sizeof(spdm_supported_algorithms_block_t) -
334383
sizeof(spdm_response->data_transfer_size) -
335384
sizeof(spdm_response->max_spdm_msg_size);
336385
}
@@ -383,6 +432,60 @@ static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_con
383432
spdm_context->connection_info.capability.max_spdm_msg_size = 0;
384433
}
385434

435+
/* Copy algorithms if requested and received */
436+
if (get_supported_algorithms && supported_algs != NULL &&
437+
spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
438+
(spdm_request->header.param1 & 0x01)) {
439+
440+
spdm_supported_algorithms_block_t *src = &spdm_response->supported_algorithms;
441+
spdm_responder_supported_algorithms_t *dst = supported_algs;
442+
uint8_t *src_bytes = (uint8_t *)src;
443+
444+
dst->measurement_specification = src->measurement_specification;
445+
dst->other_params_support = src->other_params_support;
446+
dst->base_asym_algo = src->base_asym_algo;
447+
dst->base_hash_algo = src->base_hash_algo;
448+
dst->ext_asym_count = src->ext_asym_count;
449+
dst->ext_hash_count = src->ext_hash_count;
450+
dst->mel_specification = src->mel_specification;
451+
452+
if (src->ext_asym_count > SPDM_ALGORITHMS_MAX_NUM_EXT_ASYM_COUNT ||
453+
src->ext_hash_count > SPDM_ALGORITHMS_MAX_NUM_EXT_HASH_COUNT ||
454+
src->param1 > SPDM_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG) {
455+
return LIBSPDM_STATUS_INVALID_MSG_FIELD;
456+
}
457+
458+
size_t offset = sizeof(spdm_supported_algorithms_block_t);
459+
460+
if (src->ext_asym_count > 0) {
461+
size_t copy_size = src->ext_asym_count * sizeof(spdm_extended_algorithm_t);
462+
libspdm_copy_mem(dst->ext_asym,
463+
sizeof(dst->ext_asym),
464+
src_bytes + offset,
465+
copy_size);
466+
offset += copy_size;
467+
}
468+
469+
if (src->ext_hash_count > 0) {
470+
size_t copy_size = src->ext_hash_count * sizeof(spdm_extended_algorithm_t);
471+
libspdm_copy_mem(dst->ext_hash,
472+
sizeof(dst->ext_hash),
473+
src_bytes + offset,
474+
copy_size);
475+
offset += copy_size;
476+
}
477+
478+
if (src->param1 > 0) {
479+
size_t copy_size = src->param1 * sizeof(spdm_negotiate_algorithms_common_struct_table_t);
480+
libspdm_copy_mem(dst->struct_table,
481+
sizeof(dst->struct_table),
482+
src_bytes + offset,
483+
copy_size);
484+
}
485+
486+
}
487+
488+
386489
/* -=[Update State Phase]=- */
387490
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
388491
status = LIBSPDM_STATUS_SUCCESS;
@@ -397,7 +500,9 @@ static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_con
397500
return status;
398501
}
399502

400-
libspdm_return_t libspdm_get_capabilities(libspdm_context_t *spdm_context)
503+
libspdm_return_t libspdm_get_capabilities(libspdm_context_t *spdm_context,
504+
bool get_supported_algorithms,
505+
spdm_responder_supported_algorithms_t *supported_algs)
401506
{
402507
size_t retry;
403508
uint64_t retry_delay_time;
@@ -407,7 +512,8 @@ libspdm_return_t libspdm_get_capabilities(libspdm_context_t *spdm_context)
407512
retry = spdm_context->retry_times;
408513
retry_delay_time = spdm_context->retry_delay_time;
409514
do {
410-
status = libspdm_try_get_capabilities(spdm_context);
515+
status =
516+
libspdm_try_get_capabilities(spdm_context, get_supported_algorithms, supported_algs);
411517
if (status != LIBSPDM_STATUS_BUSY_PEER) {
412518
return status;
413519
}

‎library/spdm_responder_lib/libspdm_rsp_capabilities.c

+86-1
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,96 @@ libspdm_return_t libspdm_get_response_capabilities(libspdm_context_t *spdm_conte
270270
spdm_response->max_spdm_msg_size =
271271
spdm_context->local_context.capability.max_spdm_msg_size;
272272
}
273+
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
274+
(spdm_request->header.param1 & 0x01) &&
275+
(spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) &&
276+
(spdm_response->flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP)) {
273277

274-
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
278+
uint8_t index = 0;
275279
*response_size = sizeof(spdm_capabilities_response_t);
280+
281+
spdm_response->supported_algorithms.param2 = 0;
282+
spdm_response->supported_algorithms.length = sizeof(spdm_supported_algorithms_block_t);
283+
spdm_response->supported_algorithms.measurement_specification =
284+
spdm_context->local_context.algorithm.measurement_spec;
285+
spdm_response->supported_algorithms.other_params_support =
286+
spdm_context->local_context.algorithm.other_params_support;
287+
spdm_response->supported_algorithms.base_asym_algo=
288+
spdm_context->local_context.algorithm.base_asym_algo;
289+
spdm_response->supported_algorithms.base_hash_algo=
290+
spdm_context->local_context.algorithm.base_hash_algo;
291+
spdm_response->supported_algorithms.ext_asym_count = 0;
292+
spdm_response->supported_algorithms.ext_hash_count = 0;
293+
spdm_response->supported_algorithms.mel_specification =
294+
spdm_context->local_context.algorithm.mel_spec;
295+
296+
spdm_negotiate_algorithms_common_struct_table_t *struct_table =
297+
(spdm_negotiate_algorithms_common_struct_table_t*)(
298+
(uint8_t*)&spdm_response->supported_algorithms +
299+
sizeof(spdm_supported_algorithms_block_t)
300+
);
301+
302+
if ((spdm_context->connection_info.capability.flags &
303+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) &&
304+
(spdm_context->local_context.algorithm.dhe_named_group != 0)) {
305+
struct_table[index].alg_type =
306+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
307+
struct_table[index].alg_count = 0x20;
308+
struct_table[index].alg_supported =
309+
spdm_context->local_context.algorithm.dhe_named_group;
310+
index++;
311+
}
312+
313+
if (((spdm_context->connection_info.capability.flags &
314+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) ||
315+
(spdm_context->connection_info.capability.flags &
316+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) &&
317+
(spdm_context->local_context.algorithm.aead_cipher_suite != 0)) {
318+
struct_table[index].alg_type =
319+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
320+
struct_table[index].alg_count = 0x20;
321+
struct_table[index].alg_supported =
322+
spdm_context->local_context.algorithm.aead_cipher_suite;
323+
index++;
324+
}
325+
326+
if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
327+
struct_table[index].alg_type =
328+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
329+
struct_table[index].alg_count = 0x20;
330+
struct_table[index].alg_supported =
331+
spdm_context->local_context.algorithm.req_base_asym_alg;
332+
index++;
333+
}
334+
335+
if (spdm_context->local_context.algorithm.key_schedule != 0) {
336+
struct_table[index].alg_type =
337+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
338+
struct_table[index].alg_count = 0x20;
339+
struct_table[index].alg_supported =
340+
spdm_context->local_context.algorithm.key_schedule;
341+
index++;
342+
}
343+
344+
if (index == 0) {
345+
struct_table = NULL;
346+
}
347+
348+
spdm_response->supported_algorithms.param1 = index;
349+
spdm_response->supported_algorithms.length +=
350+
spdm_response->supported_algorithms.param1*
351+
sizeof(spdm_negotiate_algorithms_common_struct_table_t);
352+
353+
*response_size = sizeof(spdm_capabilities_response_t) +
354+
(spdm_response->supported_algorithms.param1*
355+
sizeof(spdm_negotiate_algorithms_common_struct_table_t));
356+
357+
} else if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
358+
*response_size = sizeof(spdm_capabilities_response_t) -
359+
sizeof(spdm_supported_algorithms_block_t);
276360
} else {
277361
*response_size = sizeof(spdm_capabilities_response_t) -
362+
sizeof(spdm_supported_algorithms_block_t)-
278363
sizeof(spdm_response->data_transfer_size) -
279364
sizeof(spdm_response->max_spdm_msg_size);
280365
}

‎unit_test/fuzzing/test_requester/test_spdm_requester_get_capabilities/get_capabilities.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void libspdm_test_requester_get_capabilities(void **State)
7373
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION;
7474
libspdm_reset_message_a(spdm_context);
7575

76-
libspdm_get_capabilities(spdm_context);
76+
libspdm_get_capabilities(spdm_context, false, NULL);
7777
}
7878
}
7979

‎unit_test/test_spdm_requester/error_test/get_capabilities_err.c

+40-40
Large diffs are not rendered by default.

‎unit_test/test_spdm_requester/get_capabilities.c

+138-12
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,10 +145,20 @@ 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;
150+
case 0x25:
151+
return LIBSPDM_STATUS_SUCCESS;
148152
default:
149153
return LIBSPDM_STATUS_SEND_FAIL;
150154
}
151155
}
156+
typedef struct {
157+
spdm_message_header_t header;
158+
uint8_t reserved;
159+
uint8_t version_number_entry_count;
160+
spdm_version_number_t version_number_entry[LIBSPDM_MAX_VERSION_COUNT];
161+
} libspdm_version_response_mine_t;
152162

153163
static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
154164
void *spdm_context, size_t *response_size,
@@ -417,7 +427,8 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
417427
size_t spdm_response_size;
418428
size_t transport_header_size;
419429

420-
spdm_response_size = sizeof(spdm_capabilities_response_t);
430+
spdm_response_size = sizeof(spdm_capabilities_response_t) -
431+
sizeof(spdm_supported_algorithms_block_t);
421432
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
422433
spdm_response = (void *)((uint8_t *)*response + transport_header_size);
423434

@@ -913,7 +924,8 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
913924
size_t spdm_response_size;
914925
size_t transport_header_size;
915926

916-
spdm_response_size = sizeof(spdm_capabilities_response_t);
927+
spdm_response_size = sizeof(spdm_capabilities_response_t) -
928+
sizeof(spdm_supported_algorithms_block_t);
917929
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
918930
spdm_response = (void *)((uint8_t *)*response + transport_header_size);
919931

@@ -926,6 +938,7 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
926938
spdm_response->flags = LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11;
927939

928940
spdm_response_size = sizeof(spdm_capabilities_response_t) -
941+
sizeof(spdm_supported_algorithms_block_t)-
929942
sizeof(spdm_response->data_transfer_size) -
930943
sizeof(spdm_response->max_spdm_msg_size);
931944

@@ -1008,6 +1021,75 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
10081021
spdm_response->flags = LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_13;
10091022
spdm_response->data_transfer_size = LIBSPDM_DATA_TRANSFER_SIZE;
10101023
spdm_response->max_spdm_msg_size = LIBSPDM_MAX_SPDM_MSG_SIZE;
1024+
libspdm_transport_test_encode_message(spdm_context, NULL, false,
1025+
false, spdm_response_size,
1026+
spdm_response,
1027+
response_size, response);
1028+
}
1029+
return LIBSPDM_STATUS_SUCCESS;
1030+
case 0x24: {
1031+
spdm_capabilities_response_t *spdm_response;
1032+
size_t spdm_response_size;
1033+
size_t transport_header_size;
1034+
1035+
spdm_response_size = sizeof(spdm_capabilities_response_t) + 4*
1036+
sizeof(spdm_negotiate_algorithms_common_struct_table_t);
1037+
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1038+
spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1039+
1040+
libspdm_zero_mem(spdm_response, spdm_response_size);
1041+
spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
1042+
spdm_response->header.request_response_code = SPDM_CAPABILITIES;
1043+
spdm_response->header.param1 = 0;
1044+
spdm_response->header.param2 = 0;
1045+
spdm_response->ct_exponent = 0;
1046+
spdm_response->flags = LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_13;
1047+
spdm_response->data_transfer_size = LIBSPDM_DATA_TRANSFER_SIZE;
1048+
spdm_response->max_spdm_msg_size = LIBSPDM_MAX_SPDM_MSG_SIZE;
1049+
1050+
spdm_response->supported_algorithms.param1 = 4;
1051+
spdm_response->supported_algorithms.param2 = 0;
1052+
spdm_response->supported_algorithms.length = sizeof(spdm_supported_algorithms_block_t) +
1053+
4 *
1054+
sizeof(
1055+
spdm_negotiate_algorithms_common_struct_table_t);
1056+
spdm_response->supported_algorithms.measurement_specification =
1057+
SPDM_MEASUREMENT_SPECIFICATION_DMTF;
1058+
spdm_response->supported_algorithms.other_params_support = 0;
1059+
spdm_response->supported_algorithms.base_asym_algo = m_libspdm_use_asym_algo;
1060+
spdm_response->supported_algorithms.base_hash_algo = m_libspdm_use_hash_algo;
1061+
spdm_response->supported_algorithms.ext_asym_count = 0;
1062+
spdm_response->supported_algorithms.ext_hash_count = 0;
1063+
spdm_response->supported_algorithms.mel_specification = SPDM_MEL_SPECIFICATION_DMTF;
1064+
1065+
spdm_negotiate_algorithms_common_struct_table_t *struct_table =
1066+
(spdm_negotiate_algorithms_common_struct_table_t *)(&spdm_response->supported_algorithms
1067+
+ 1);
1068+
1069+
struct_table[0].alg_type =
1070+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
1071+
struct_table[0].alg_count = 0x20;
1072+
struct_table[0].alg_supported =
1073+
SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1;
1074+
1075+
struct_table[1].alg_type =
1076+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
1077+
struct_table[1].alg_count = 0x20;
1078+
struct_table[1].alg_supported =
1079+
SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM;;
1080+
1081+
struct_table[2].alg_type =
1082+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
1083+
struct_table[2].alg_count = 0x20;
1084+
struct_table[2].alg_supported =
1085+
SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048;
1086+
1087+
struct_table[3].alg_type =
1088+
SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
1089+
struct_table[3].alg_count = 0x20;
1090+
struct_table[3].alg_supported =
1091+
SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH;
1092+
10111093
libspdm_transport_test_encode_message(spdm_context, NULL, false,
10121094
false, spdm_response_size,
10131095
spdm_response,
@@ -1044,7 +1126,7 @@ static void libspdm_test_requester_get_capabilities_case2(void **state)
10441126

10451127
spdm_context->local_context.capability.ct_exponent = 0;
10461128
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG;
1047-
status = libspdm_get_capabilities(spdm_context);
1129+
status = libspdm_get_capabilities(spdm_context, false, NULL);
10481130
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
10491131
assert_int_equal(spdm_context->connection_info.capability.ct_exponent, 0);
10501132
assert_int_equal(spdm_context->connection_info.capability.flags,
@@ -1089,7 +1171,7 @@ static void libspdm_test_requester_get_capabilities_case6(void **state)
10891171

10901172
spdm_context->local_context.capability.ct_exponent = 0;
10911173
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG;
1092-
status = libspdm_get_capabilities(spdm_context);
1174+
status = libspdm_get_capabilities(spdm_context, false, NULL);
10931175
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
10941176
assert_int_equal(spdm_context->connection_info.capability.ct_exponent, 0);
10951177
assert_int_equal(spdm_context->connection_info.capability.flags,
@@ -1130,7 +1212,7 @@ static void libspdm_test_requester_get_capabilities_case10(void **state)
11301212

11311213
spdm_context->local_context.capability.ct_exponent = 0;
11321214
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG;
1133-
status = libspdm_get_capabilities(spdm_context);
1215+
status = libspdm_get_capabilities(spdm_context, false, NULL);
11341216
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
11351217
assert_int_equal(spdm_context->connection_info.capability.ct_exponent, 0);
11361218
assert_int_equal(spdm_context->connection_info.capability.flags,
@@ -1156,7 +1238,7 @@ static void libspdm_test_requester_get_capabilities_case11(void **state)
11561238

11571239
spdm_context->local_context.capability.ct_exponent = 0;
11581240
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG;
1159-
status = libspdm_get_capabilities(spdm_context);
1241+
status = libspdm_get_capabilities(spdm_context, false, NULL);
11601242
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
11611243
assert_int_equal(spdm_context->connection_info.capability.ct_exponent, 0);
11621244
assert_int_equal(
@@ -1183,7 +1265,7 @@ static void libspdm_test_requester_get_capabilities_case12(void **state)
11831265

11841266
spdm_context->local_context.capability.ct_exponent = 0;
11851267
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG;
1186-
status = libspdm_get_capabilities(spdm_context);
1268+
status = libspdm_get_capabilities(spdm_context, false, NULL);
11871269
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
11881270
assert_int_equal(spdm_context->connection_info.capability.ct_exponent, 0);
11891271
assert_int_equal(spdm_context->connection_info.capability.flags,
@@ -1224,7 +1306,7 @@ static void libspdm_test_requester_get_capabilities_case16(void **state)
12241306

12251307
spdm_context->local_context.capability.ct_exponent = 0;
12261308
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG_VERSION_11;
1227-
status = libspdm_get_capabilities(spdm_context);
1309+
status = libspdm_get_capabilities(spdm_context, false, NULL);
12281310
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
12291311
assert_int_equal(spdm_context->connection_info.capability.ct_exponent, 0);
12301312
assert_int_equal(spdm_context->connection_info.capability.flags,
@@ -1343,7 +1425,7 @@ static void libspdm_test_requester_get_capabilities_case32(void **state)
13431425

13441426
spdm_context->local_context.capability.ct_exponent = 0;
13451427
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG_VERSION_11;
1346-
status = libspdm_get_capabilities(spdm_context);
1428+
status = libspdm_get_capabilities(spdm_context, false, NULL);
13471429
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
13481430
assert_int_equal(spdm_context->connection_info.capability.ct_exponent, 0);
13491431
assert_int_equal(spdm_context->connection_info.capability.flags,
@@ -1374,7 +1456,7 @@ static void libspdm_test_requester_get_capabilities_case33(void **state)
13741456

13751457
spdm_context->local_context.capability.ct_exponent = 0;
13761458
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG_VERSION_12;
1377-
status = libspdm_get_capabilities(spdm_context);
1459+
status = libspdm_get_capabilities(spdm_context, false, NULL);
13781460
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
13791461
assert_int_equal(spdm_context->connection_info.capability.max_spdm_msg_size,
13801462
LIBSPDM_MAX_SPDM_MSG_SIZE);
@@ -1406,7 +1488,50 @@ static void libspdm_test_requester_get_capabilities_case35(void **state)
14061488
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION;
14071489
spdm_context->local_context.capability.ct_exponent = 0;
14081490

1409-
status = libspdm_get_capabilities(spdm_context);
1491+
status = libspdm_get_capabilities(spdm_context, false, NULL);
1492+
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1493+
assert_int_equal(spdm_context->connection_info.capability.max_spdm_msg_size,
1494+
LIBSPDM_MAX_SPDM_MSG_SIZE);
1495+
assert_int_equal(spdm_context->connection_info.capability.data_transfer_size,
1496+
LIBSPDM_DATA_TRANSFER_SIZE);
1497+
assert_int_equal(spdm_context->connection_info.capability.ct_exponent, 0);
1498+
assert_int_equal(spdm_context->connection_info.capability.flags,
1499+
LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_13);
1500+
}
1501+
1502+
static void libspdm_test_requester_get_capabilities_case36(void **state)
1503+
{
1504+
libspdm_return_t status;
1505+
libspdm_test_context_t *spdm_test_context;
1506+
libspdm_context_t *spdm_context;
1507+
spdm_responder_supported_algorithms_t supported_algs;
1508+
1509+
spdm_test_context = *state;
1510+
spdm_context = spdm_test_context->spdm_context;
1511+
spdm_test_context->case_id = 0x24;
1512+
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
1513+
SPDM_VERSION_NUMBER_SHIFT_BIT;
1514+
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION;
1515+
spdm_context->local_context.capability.ct_exponent = 0;
1516+
1517+
spdm_context->local_context.algorithm.measurement_spec = SPDM_MEASUREMENT_SPECIFICATION_DMTF;
1518+
spdm_context->local_context.algorithm.other_params_support = 0;
1519+
spdm_context->local_context.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
1520+
spdm_context->local_context.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1521+
spdm_context->local_context.algorithm.mel_spec = SPDM_MEL_SPECIFICATION_DMTF;
1522+
1523+
spdm_context->connection_info.capability.flags |=
1524+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP;
1525+
spdm_context->connection_info.capability.flags |=
1526+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
1527+
spdm_context->connection_info.capability.flags |=
1528+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP;
1529+
1530+
spdm_context->local_context.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
1531+
spdm_context->local_context.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
1532+
spdm_context->local_context.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
1533+
spdm_context->local_context.algorithm.key_schedule = m_libspdm_use_key_schedule_algo;
1534+
status = libspdm_get_capabilities(spdm_context, true, &supported_algs);
14101535
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
14111536
assert_int_equal(spdm_context->connection_info.capability.max_spdm_msg_size,
14121537
LIBSPDM_MAX_SPDM_MSG_SIZE);
@@ -1455,6 +1580,7 @@ int libspdm_requester_get_capabilities_test_main(void)
14551580
cmocka_unit_test(libspdm_test_requester_get_capabilities_case33),
14561581
/* cmocka_unit_test(libspdm_test_requester_get_capabilities_case34), */
14571582
cmocka_unit_test(libspdm_test_requester_get_capabilities_case35),
1583+
cmocka_unit_test(libspdm_test_requester_get_capabilities_case36),
14581584
};
14591585

14601586
libspdm_test_context_t test_context = {

‎unit_test/test_spdm_responder/capabilities.c

+79-2
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,22 @@ spdm_get_capabilities_request_t m_libspdm_get_capabilities_request27 = {
467467
};
468468
size_t m_libspdm_get_capabilities_request27_size = sizeof(m_libspdm_get_capabilities_request27);
469469

470+
spdm_get_capabilities_request_t m_libspdm_get_capabilities_request28 = {
471+
{
472+
SPDM_MESSAGE_VERSION_13,
473+
SPDM_GET_CAPABILITIES,
474+
0x01,
475+
},
476+
0x00, /*reserved*/
477+
0x01, /*ct_exponent*/
478+
0x0000, /*reserved, 2 bytes*/
479+
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP |
480+
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY,
481+
LIBSPDM_DATA_TRANSFER_SIZE,
482+
LIBSPDM_MAX_SPDM_MSG_SIZE,
483+
};
484+
size_t m_libspdm_get_capabilities_request28_size = sizeof(m_libspdm_get_capabilities_request28);
485+
470486
void libspdm_test_responder_capabilities_case1(void **state)
471487
{
472488
libspdm_return_t status;
@@ -491,6 +507,7 @@ void libspdm_test_responder_capabilities_case1(void **state)
491507
&m_libspdm_get_capabilities_request1, &response_size, response);
492508
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
493509
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) -
510+
sizeof(spdm_supported_algorithms_block_t) -
494511
sizeof(spdm_response->data_transfer_size) -
495512
sizeof(spdm_response->max_spdm_msg_size));
496513
spdm_response = (void *)response;
@@ -527,6 +544,7 @@ void libspdm_test_responder_capabilities_case2(void **state)
527544
&m_libspdm_get_capabilities_request2, &response_size, response);
528545
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
529546
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) -
547+
sizeof(spdm_supported_algorithms_block_t) -
530548
sizeof(spdm_response->data_transfer_size) -
531549
sizeof(spdm_response->max_spdm_msg_size));
532550
spdm_response = (void *)response;
@@ -691,6 +709,7 @@ void libspdm_test_responder_capabilities_case8(void **state)
691709
&m_libspdm_get_capabilities_request4, &response_size, response);
692710
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
693711
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) -
712+
sizeof(spdm_supported_algorithms_block_t) -
694713
sizeof(spdm_response->data_transfer_size) -
695714
sizeof(spdm_response->max_spdm_msg_size));
696715
spdm_response = (void *)response;
@@ -721,6 +740,7 @@ void libspdm_test_responder_capabilities_case9(void **state)
721740
&m_libspdm_get_capabilities_request5, &response_size, response);
722741
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
723742
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) -
743+
sizeof(spdm_supported_algorithms_block_t) -
724744
sizeof(spdm_response->data_transfer_size) -
725745
sizeof(spdm_response->max_spdm_msg_size));
726746
spdm_response = (void *)response;
@@ -1017,6 +1037,7 @@ void libspdm_test_responder_capabilities_case22(void **state)
10171037
&m_libspdm_get_capabilities_request18, &response_size, response);
10181038
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
10191039
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) -
1040+
sizeof(spdm_supported_algorithms_block_t) -
10201041
sizeof(spdm_response->data_transfer_size) -
10211042
sizeof(spdm_response->max_spdm_msg_size));
10221043
spdm_response = (void *)response;
@@ -1053,6 +1074,7 @@ void libspdm_test_responder_capabilities_case23(void **state)
10531074
&m_libspdm_get_capabilities_request4, &response_size, response);
10541075
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
10551076
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) -
1077+
sizeof(spdm_supported_algorithms_block_t) -
10561078
sizeof(spdm_response->data_transfer_size) -
10571079
sizeof(spdm_response->max_spdm_msg_size));
10581080
spdm_response = (void *)response;
@@ -1094,7 +1116,8 @@ void libspdm_test_responder_capabilities_case24(void **state)
10941116
assert_int_equal(spdm_context->connection_info.capability.data_transfer_size,
10951117
m_libspdm_get_capabilities_request19.data_transfer_size);
10961118
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1097-
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t));
1119+
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) -
1120+
sizeof(spdm_supported_algorithms_block_t));
10981121
spdm_response = (void *)response;
10991122
assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
11001123
assert_int_equal(spdm_response->header.request_response_code,
@@ -1185,7 +1208,8 @@ void libspdm_test_responder_capabilities_case27(void **state)
11851208
&m_libspdm_get_capabilities_request27, &response_size, response);
11861209

11871210
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1188-
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t));
1211+
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) -
1212+
sizeof(spdm_supported_algorithms_block_t));
11891213
spdm_response = (void *)response;
11901214
assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_13);
11911215
assert_int_equal(spdm_response->header.request_response_code,
@@ -1196,6 +1220,57 @@ void libspdm_test_responder_capabilities_case27(void **state)
11961220
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY);
11971221
}
11981222

1223+
void libspdm_test_responder_capabilities_case28(void **state)
1224+
{
1225+
libspdm_return_t status;
1226+
libspdm_test_context_t *spdm_test_context;
1227+
libspdm_context_t *spdm_context;
1228+
size_t response_size;
1229+
uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1230+
spdm_capabilities_response_t *spdm_response;
1231+
1232+
spdm_test_context = *state;
1233+
spdm_context = spdm_test_context->spdm_context;
1234+
spdm_test_context->case_id = 0x1C;
1235+
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION;
1236+
1237+
spdm_context->local_context.algorithm.measurement_spec = SPDM_MEASUREMENT_SPECIFICATION_DMTF;
1238+
spdm_context->local_context.algorithm.other_params_support = 0;
1239+
spdm_context->local_context.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
1240+
spdm_context->local_context.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1241+
spdm_context->local_context.algorithm.mel_spec = SPDM_MEL_SPECIFICATION_DMTF;
1242+
spdm_context->local_context.capability.flags = SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1243+
1244+
spdm_context->connection_info.capability.flags |=
1245+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP;
1246+
spdm_context->connection_info.capability.flags |=
1247+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
1248+
spdm_context->connection_info.capability.flags |=
1249+
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP;
1250+
1251+
spdm_context->local_context.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
1252+
spdm_context->local_context.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
1253+
spdm_context->local_context.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
1254+
spdm_context->local_context.algorithm.key_schedule = m_libspdm_use_key_schedule_algo;
1255+
1256+
response_size = sizeof(response);
1257+
status = libspdm_get_response_capabilities(
1258+
spdm_context, m_libspdm_get_capabilities_request28_size,
1259+
&m_libspdm_get_capabilities_request28, &response_size, response);
1260+
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1261+
assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) +
1262+
4 * sizeof(spdm_negotiate_algorithms_common_struct_table_t));
1263+
spdm_response = (void *)response;
1264+
assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_13);
1265+
assert_int_equal(spdm_response->header.request_response_code,
1266+
SPDM_CAPABILITIES);
1267+
assert_int_equal(spdm_response->data_transfer_size, LIBSPDM_DATA_TRANSFER_SIZE);
1268+
assert_int_equal(spdm_response->max_spdm_msg_size, LIBSPDM_MAX_SPDM_MSG_SIZE);
1269+
assert_int_equal(spdm_context->connection_info.capability.flags,
1270+
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP |
1271+
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY);
1272+
}
1273+
11991274
int libspdm_responder_capabilities_test_main(void)
12001275
{
12011276
const struct CMUnitTest spdm_responder_capabilities_tests[] = {
@@ -1251,6 +1326,8 @@ int libspdm_responder_capabilities_test_main(void)
12511326
cmocka_unit_test(libspdm_test_responder_capabilities_case26),
12521327
/* Success Case , capability supports MULTI_KEY_CAP */
12531328
cmocka_unit_test(libspdm_test_responder_capabilities_case27),
1329+
/* Success Case , capability supports MULTI_KEY_CAP */
1330+
cmocka_unit_test(libspdm_test_responder_capabilities_case28),
12541331
};
12551332

12561333
libspdm_test_context_t test_context = {

0 commit comments

Comments
 (0)
Please sign in to comment.