From a061ee9278b88345ba0f8f945a81b7ebad503d9e Mon Sep 17 00:00:00 2001 From: Shital Jumbad Date: Tue, 21 Jan 2025 16:39:35 -0800 Subject: [PATCH] CAPABILITIES: Add SupportedAlgorithms fix #2279 Signed-off-by: Shital Jumbad --- include/industry_standard/spdm.h | 39 ++++-- include/internal/libspdm_common_lib.h | 4 +- .../libspdm_req_get_capabilities.c | 26 +++- .../libspdm_rsp_capabilities.c | 64 +++++++++- .../test_spdm_requester/get_capabilities.c | 113 +++++++++++++++++- unit_test/test_spdm_responder/capabilities.c | 71 ++++++++++- 6 files changed, 300 insertions(+), 17 deletions(-) diff --git a/include/industry_standard/spdm.h b/include/industry_standard/spdm.h index 9148bb93ca4..87928042567 100644 --- a/include/industry_standard/spdm.h +++ b/include/industry_standard/spdm.h @@ -161,6 +161,36 @@ typedef struct { uint32_t max_spdm_msg_size; } spdm_get_capabilities_request_t; +typedef struct { + uint8_t alg_type; + uint8_t alg_count; + uint16_t alg_supported; +} spdm_negotiate_algorithms_common_struct_table_t; + +#define SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG 4 + +/* SPDM supported algorithms block */ +typedef struct { + uint8_t param1; /* Number of Algorithms Structure Tables */ + uint8_t param2; /* Reserved */ + uint16_t length; + uint8_t measurement_specification; + uint8_t other_params_support; + uint32_t base_asym_algo; + uint32_t base_hash_algo; + uint8_t reserved2[12]; + uint8_t ext_asym_count; + uint8_t ext_hash_count; + uint8_t reserved3; + uint8_t mel_specification; + /* Followed by dynamic arrays for ext_asym and ext_hash, if needed + * spdm_extended_algorithm_t ext_asym[ext_asym_count]; + * spdm_extended_algorithm_t ext_hash[ext_hash_count]; */ + spdm_negotiate_algorithms_common_struct_table_t struct_table[ + SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG]; +} spdm_supported_algorithms_block_t; + + /* SPDM GET_CAPABILITIES response*/ typedef struct { @@ -174,6 +204,8 @@ typedef struct { /* Below field is added in 1.2.*/ uint32_t data_transfer_size; uint32_t max_spdm_msg_size; + /* Below field is added in 1.3.*/ + spdm_supported_algorithms_block_t supported_algorithms; } spdm_capabilities_response_t; #define SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12 42 @@ -348,13 +380,6 @@ typedef struct { #define SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG 4 #define SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE 5 -typedef struct { - uint8_t alg_type; - uint8_t alg_count; - uint16_t alg_supported; -} spdm_negotiate_algorithms_common_struct_table_t; - - /* SPDM NEGOTIATE_ALGORITHMS request base_asym_algo/REQ_BASE_ASYM_ALG */ #define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 0x00000001 #define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 0x00000002 diff --git a/include/internal/libspdm_common_lib.h b/include/internal/libspdm_common_lib.h index 81a059f4198..7a9e81878e9 100644 --- a/include/internal/libspdm_common_lib.h +++ b/include/internal/libspdm_common_lib.h @@ -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 **/ @@ -43,6 +43,7 @@ typedef struct { } libspdm_device_version_t; typedef struct { + uint8_t param1; uint8_t ct_exponent; uint64_t rtt; uint32_t st1; @@ -55,6 +56,7 @@ typedef struct { } libspdm_device_capability_t; typedef struct { + uint8_t param1; uint8_t measurement_spec; uint8_t other_params_support; uint8_t mel_spec; diff --git a/library/spdm_requester_lib/libspdm_req_get_capabilities.c b/library/spdm_requester_lib/libspdm_req_get_capabilities.c index de92a765046..f678bd2e368 100644 --- a/library/spdm_requester_lib/libspdm_req_get_capabilities.c +++ b/library/spdm_requester_lib/libspdm_req_get_capabilities.c @@ -251,6 +251,10 @@ static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_con } spdm_request->header.request_response_code = SPDM_GET_CAPABILITIES; spdm_request->header.param1 = 0; + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13 && + ((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) == 0)) { + spdm_request->header.param1 = spdm_context->local_context.capability.param1; + } spdm_request->header.param2 = 0; if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) { 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 status = LIBSPDM_STATUS_INVALID_MSG_FIELD; goto receive_done; } - if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) { + if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { if (spdm_response_size < sizeof(spdm_capabilities_response_t)) { status = LIBSPDM_STATUS_INVALID_MSG_SIZE; goto receive_done; } + } else if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) { + if (spdm_response_size < (sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t))) { + status = LIBSPDM_STATUS_INVALID_MSG_SIZE; + goto receive_done; + } } else { - if (spdm_response_size < sizeof(spdm_capabilities_response_t) - - sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)) { + if (spdm_response_size < (sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t) - + sizeof(spdm_response->data_transfer_size) - + sizeof(spdm_response->max_spdm_msg_size))) { status = LIBSPDM_STATUS_INVALID_MSG_SIZE; goto receive_done; } } - if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) { + + if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 && + (spdm_request->header.param1 & 0x01)) { spdm_response_size = sizeof(spdm_capabilities_response_t); + } else if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) { + spdm_response_size = sizeof(spdm_capabilities_response_t)- + sizeof(spdm_supported_algorithms_block_t); } else { spdm_response_size = sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t) - sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size); } diff --git a/library/spdm_responder_lib/libspdm_rsp_capabilities.c b/library/spdm_responder_lib/libspdm_rsp_capabilities.c index eeb7d827cc7..5fd23a582ac 100644 --- a/library/spdm_responder_lib/libspdm_rsp_capabilities.c +++ b/library/spdm_responder_lib/libspdm_rsp_capabilities.c @@ -264,10 +264,72 @@ libspdm_return_t libspdm_get_response_capabilities(libspdm_context_t *spdm_conte spdm_context->local_context.capability.max_spdm_msg_size; } - if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) { + if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 && + (spdm_request->header.param1 & 0x01) && + ((spdm_request->flags & + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) == 0)) { *response_size = sizeof(spdm_capabilities_response_t); + + spdm_response->supported_algorithms.param1 = spdm_context->local_context.algorithm.param1; + spdm_response->supported_algorithms.param2 = 0; + spdm_response->supported_algorithms.length = sizeof(spdm_supported_algorithms_block_t); + spdm_response->supported_algorithms.measurement_specification = + spdm_context->local_context.algorithm.measurement_spec; + spdm_response->supported_algorithms.other_params_support = + spdm_context->local_context.algorithm.other_params_support; + spdm_response->supported_algorithms.base_asym_algo= + spdm_context->local_context.algorithm.base_asym_algo; + spdm_response->supported_algorithms.base_hash_algo= + spdm_context->local_context.algorithm.base_hash_algo; + spdm_response->supported_algorithms.ext_asym_count = 0; + spdm_response->supported_algorithms.ext_hash_count = 0; + spdm_response->supported_algorithms.mel_specification = + spdm_context->local_context.algorithm.mel_spec; + + if (spdm_response->supported_algorithms.param1 > 0) { + size_t index = 0; + spdm_response->supported_algorithms.length += + spdm_response->supported_algorithms.param1* + sizeof(spdm_negotiate_algorithms_common_struct_table_t); + if (spdm_context->local_context.algorithm.dhe_named_group) { + spdm_response->supported_algorithms.struct_table[index].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE; + spdm_response->supported_algorithms.struct_table[index].alg_count = 0x20; + spdm_response->supported_algorithms.struct_table[index].alg_supported = + spdm_context->local_context.algorithm.dhe_named_group; + index++; + } + if (spdm_context->local_context.algorithm.aead_cipher_suite) { + spdm_response->supported_algorithms.struct_table[index].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD; + spdm_response->supported_algorithms.struct_table[index].alg_count = 0x20; + spdm_response->supported_algorithms.struct_table[index].alg_supported = + spdm_context->local_context.algorithm.aead_cipher_suite; + index++; + } + if (spdm_context->local_context.algorithm.req_base_asym_alg) { + spdm_response->supported_algorithms.struct_table[index].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG; + spdm_response->supported_algorithms.struct_table[index].alg_count = 0x20; + spdm_response->supported_algorithms.struct_table[index].alg_supported = + spdm_context->local_context.algorithm.req_base_asym_alg; + index++; + } + if (spdm_context->local_context.algorithm.key_schedule) { + spdm_response->supported_algorithms.struct_table[index].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE; + spdm_response->supported_algorithms.struct_table[index].alg_count = 0x20; + spdm_response->supported_algorithms.struct_table[index].alg_supported = + spdm_context->local_context.algorithm.key_schedule; + index++; + } + } + } else if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) { + *response_size = sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t); } else { *response_size = sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t)- sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size); } diff --git a/unit_test/test_spdm_requester/get_capabilities.c b/unit_test/test_spdm_requester/get_capabilities.c index 7117466f437..d8ec1dbd7f7 100644 --- a/unit_test/test_spdm_requester/get_capabilities.c +++ b/unit_test/test_spdm_requester/get_capabilities.c @@ -1,6 +1,6 @@ /** * Copyright Notice: - * Copyright 2021-2022 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 **/ @@ -145,6 +145,8 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_send_message( return LIBSPDM_STATUS_SUCCESS; case 0x23: return LIBSPDM_STATUS_SUCCESS; + case 0x24: + return LIBSPDM_STATUS_SUCCESS; default: return LIBSPDM_STATUS_SEND_FAIL; } @@ -417,7 +419,8 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message( size_t spdm_response_size; size_t transport_header_size; - spdm_response_size = sizeof(spdm_capabilities_response_t); + spdm_response_size = sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t); transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE; spdm_response = (void *)((uint8_t *)*response + transport_header_size); @@ -913,7 +916,8 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message( size_t spdm_response_size; size_t transport_header_size; - spdm_response_size = sizeof(spdm_capabilities_response_t); + spdm_response_size = sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t); transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE; spdm_response = (void *)((uint8_t *)*response + transport_header_size); @@ -926,6 +930,7 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message( spdm_response->flags = LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11; spdm_response_size = sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t)- sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size); @@ -1008,6 +1013,67 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message( spdm_response->flags = LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_13; spdm_response->data_transfer_size = LIBSPDM_DATA_TRANSFER_SIZE; spdm_response->max_spdm_msg_size = LIBSPDM_MAX_SPDM_MSG_SIZE; + libspdm_transport_test_encode_message(spdm_context, NULL, false, + false, spdm_response_size, + spdm_response, + response_size, response); + } + return LIBSPDM_STATUS_SUCCESS; + case 0x24: { + spdm_capabilities_response_t *spdm_response; + size_t spdm_response_size; + size_t transport_header_size; + + spdm_response_size = sizeof(spdm_capabilities_response_t); + transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE; + spdm_response = (void *)((uint8_t *)*response + transport_header_size); + + libspdm_zero_mem(spdm_response, spdm_response_size); + spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13; + spdm_response->header.request_response_code = SPDM_CAPABILITIES; + spdm_response->header.param1 = 0; + spdm_response->header.param2 = 0; + spdm_response->ct_exponent = 0; + spdm_response->flags = LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_13; + spdm_response->data_transfer_size = LIBSPDM_DATA_TRANSFER_SIZE; + spdm_response->max_spdm_msg_size = LIBSPDM_MAX_SPDM_MSG_SIZE; + + spdm_response->supported_algorithms.param1 = 4; + spdm_response->supported_algorithms.param2 = 0; + spdm_response->supported_algorithms.length = sizeof(spdm_supported_algorithms_block_t); + spdm_response->supported_algorithms.measurement_specification = + SPDM_MEASUREMENT_SPECIFICATION_DMTF; + spdm_response->supported_algorithms.other_params_support = 0; + spdm_response->supported_algorithms.base_asym_algo = m_libspdm_use_asym_algo; + spdm_response->supported_algorithms.base_hash_algo = m_libspdm_use_hash_algo; + spdm_response->supported_algorithms.ext_asym_count = 0; + spdm_response->supported_algorithms.ext_hash_count = 0; + spdm_response->supported_algorithms.mel_specification = SPDM_MEL_SPECIFICATION_DMTF; + + spdm_response->supported_algorithms.struct_table[0].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE; + spdm_response->supported_algorithms.struct_table[0].alg_count = 0x20; + spdm_response->supported_algorithms.struct_table[0].alg_supported = + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1; + + spdm_response->supported_algorithms.struct_table[1].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD; + spdm_response->supported_algorithms.struct_table[1].alg_count = 0x20; + spdm_response->supported_algorithms.struct_table[1].alg_supported = + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM;; + + spdm_response->supported_algorithms.struct_table[2].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG; + spdm_response->supported_algorithms.struct_table[2].alg_count = 0x20; + spdm_response->supported_algorithms.struct_table[2].alg_supported = + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048; + + spdm_response->supported_algorithms.struct_table[3].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE; + spdm_response->supported_algorithms.struct_table[3].alg_count = 0x20; + spdm_response->supported_algorithms.struct_table[3].alg_supported = + SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + libspdm_transport_test_encode_message(spdm_context, NULL, false, false, spdm_response_size, spdm_response, @@ -1405,6 +1471,46 @@ static void libspdm_test_requester_get_capabilities_case35(void **state) SPDM_VERSION_NUMBER_SHIFT_BIT; spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION; spdm_context->local_context.capability.ct_exponent = 0; + spdm_context->local_context.capability.param1 = 0; + + status = libspdm_get_capabilities(spdm_context); + assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); + assert_int_equal(spdm_context->connection_info.capability.max_spdm_msg_size, + LIBSPDM_MAX_SPDM_MSG_SIZE); + assert_int_equal(spdm_context->connection_info.capability.data_transfer_size, + LIBSPDM_DATA_TRANSFER_SIZE); + assert_int_equal(spdm_context->connection_info.capability.ct_exponent, 0); + assert_int_equal(spdm_context->connection_info.capability.flags, + LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_13); +} + +static void libspdm_test_requester_get_capabilities_case36(void **state) +{ + libspdm_return_t status; + libspdm_test_context_t *spdm_test_context; + libspdm_context_t *spdm_context; + + spdm_test_context = *state; + spdm_context = spdm_test_context->spdm_context; + spdm_test_context->case_id = 0x24; + spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 << + SPDM_VERSION_NUMBER_SHIFT_BIT; + spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION; + spdm_context->local_context.capability.ct_exponent = 0; + + spdm_context->local_context.capability.param1 = 1; + + spdm_context->local_context.algorithm.param1=4; + spdm_context->local_context.algorithm.measurement_spec = SPDM_MEASUREMENT_SPECIFICATION_DMTF; + spdm_context->local_context.algorithm.other_params_support = 0; + spdm_context->local_context.algorithm.base_asym_algo = m_libspdm_use_asym_algo; + spdm_context->local_context.algorithm.base_hash_algo = m_libspdm_use_hash_algo; + spdm_context->local_context.algorithm.mel_spec = SPDM_MEL_SPECIFICATION_DMTF; + + spdm_context->local_context.algorithm.dhe_named_group = m_libspdm_use_dhe_algo; + spdm_context->local_context.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo; + spdm_context->local_context.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo; + spdm_context->local_context.algorithm.key_schedule = m_libspdm_use_key_schedule_algo; status = libspdm_get_capabilities(spdm_context); assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); @@ -1455,6 +1561,7 @@ int libspdm_requester_get_capabilities_test_main(void) cmocka_unit_test(libspdm_test_requester_get_capabilities_case33), /* cmocka_unit_test(libspdm_test_requester_get_capabilities_case34), */ cmocka_unit_test(libspdm_test_requester_get_capabilities_case35), + cmocka_unit_test(libspdm_test_requester_get_capabilities_case36), }; libspdm_test_context_t test_context = { diff --git a/unit_test/test_spdm_responder/capabilities.c b/unit_test/test_spdm_responder/capabilities.c index 3eaa7d48186..88e9ed9bd68 100644 --- a/unit_test/test_spdm_responder/capabilities.c +++ b/unit_test/test_spdm_responder/capabilities.c @@ -467,6 +467,21 @@ spdm_get_capabilities_request_t m_libspdm_get_capabilities_request27 = { }; size_t m_libspdm_get_capabilities_request27_size = sizeof(m_libspdm_get_capabilities_request27); +spdm_get_capabilities_request_t m_libspdm_get_capabilities_request28 = { + { + SPDM_MESSAGE_VERSION_13, + SPDM_GET_CAPABILITIES, + 0x01, + }, + 0x00, /*reserved*/ + 0x01, /*ct_exponent*/ + 0x0000, /*reserved, 2 bytes*/ + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY, + LIBSPDM_DATA_TRANSFER_SIZE, + LIBSPDM_MAX_SPDM_MSG_SIZE, +}; +size_t m_libspdm_get_capabilities_request28_size = sizeof(m_libspdm_get_capabilities_request28); + void libspdm_test_responder_capabilities_case1(void **state) { libspdm_return_t status; @@ -491,6 +506,7 @@ void libspdm_test_responder_capabilities_case1(void **state) &m_libspdm_get_capabilities_request1, &response_size, response); assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t) - sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)); spdm_response = (void *)response; @@ -527,6 +543,7 @@ void libspdm_test_responder_capabilities_case2(void **state) &m_libspdm_get_capabilities_request2, &response_size, response); assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t) - sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)); spdm_response = (void *)response; @@ -691,6 +708,7 @@ void libspdm_test_responder_capabilities_case8(void **state) &m_libspdm_get_capabilities_request4, &response_size, response); assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t) - sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)); spdm_response = (void *)response; @@ -721,6 +739,7 @@ void libspdm_test_responder_capabilities_case9(void **state) &m_libspdm_get_capabilities_request5, &response_size, response); assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t) - sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)); spdm_response = (void *)response; @@ -1017,6 +1036,7 @@ void libspdm_test_responder_capabilities_case22(void **state) &m_libspdm_get_capabilities_request18, &response_size, response); assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t) - sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)); spdm_response = (void *)response; @@ -1053,6 +1073,7 @@ void libspdm_test_responder_capabilities_case23(void **state) &m_libspdm_get_capabilities_request4, &response_size, response); assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t) - sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)); spdm_response = (void *)response; @@ -1094,7 +1115,8 @@ void libspdm_test_responder_capabilities_case24(void **state) assert_int_equal(spdm_context->connection_info.capability.data_transfer_size, m_libspdm_get_capabilities_request19.data_transfer_size); assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); - assert_int_equal(response_size, sizeof(spdm_capabilities_response_t)); + assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t)); spdm_response = (void *)response; assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12); assert_int_equal(spdm_response->header.request_response_code, @@ -1185,6 +1207,51 @@ void libspdm_test_responder_capabilities_case27(void **state) &m_libspdm_get_capabilities_request27, &response_size, response); assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); + assert_int_equal(response_size, sizeof(spdm_capabilities_response_t) - + sizeof(spdm_supported_algorithms_block_t)); + spdm_response = (void *)response; + assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_13); + assert_int_equal(spdm_response->header.request_response_code, + SPDM_CAPABILITIES); + assert_int_equal(spdm_response->data_transfer_size, LIBSPDM_DATA_TRANSFER_SIZE); + assert_int_equal(spdm_response->max_spdm_msg_size, LIBSPDM_MAX_SPDM_MSG_SIZE); + assert_int_equal(spdm_context->connection_info.capability.flags, + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY); +} + +void libspdm_test_responder_capabilities_case28(void **state) +{ + libspdm_return_t status; + libspdm_test_context_t *spdm_test_context; + libspdm_context_t *spdm_context; + size_t response_size; + uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE]; + spdm_capabilities_response_t *spdm_response; + + spdm_test_context = *state; + spdm_context = spdm_test_context->spdm_context; + spdm_test_context->case_id = 0x1C; + spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION; + + spdm_context->local_context.capability.param1 = 1; + + spdm_context->local_context.algorithm.param1=4; + spdm_context->local_context.algorithm.measurement_spec = SPDM_MEASUREMENT_SPECIFICATION_DMTF; + spdm_context->local_context.algorithm.other_params_support = 0; + spdm_context->local_context.algorithm.base_asym_algo = m_libspdm_use_asym_algo; + spdm_context->local_context.algorithm.base_hash_algo = m_libspdm_use_hash_algo; + spdm_context->local_context.algorithm.mel_spec = SPDM_MEL_SPECIFICATION_DMTF; + + spdm_context->local_context.algorithm.dhe_named_group = m_libspdm_use_dhe_algo; + spdm_context->local_context.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo; + spdm_context->local_context.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo; + spdm_context->local_context.algorithm.key_schedule = m_libspdm_use_key_schedule_algo; + + response_size = sizeof(response); + status = libspdm_get_response_capabilities( + spdm_context, m_libspdm_get_capabilities_request28_size, + &m_libspdm_get_capabilities_request28, &response_size, response); + assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); assert_int_equal(response_size, sizeof(spdm_capabilities_response_t)); spdm_response = (void *)response; assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_13); @@ -1251,6 +1318,8 @@ int libspdm_responder_capabilities_test_main(void) cmocka_unit_test(libspdm_test_responder_capabilities_case26), /* Success Case , capability supports MULTI_KEY_CAP */ cmocka_unit_test(libspdm_test_responder_capabilities_case27), + /* Success Case , capability supports MULTI_KEY_CAP */ + cmocka_unit_test(libspdm_test_responder_capabilities_case28), }; libspdm_test_context_t test_context = {