Skip to content

Commit

Permalink
CAPABILITIES: Add SupportedAlgorithms
Browse files Browse the repository at this point in the history
fix #2279

Signed-off-by: Shital Jumbad <[email protected]>
  • Loading branch information
ShitalJumbad committed Jan 25, 2025
1 parent 0f6c6a3 commit a061ee9
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 17 deletions.
39 changes: 32 additions & 7 deletions include/industry_standard/spdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion include/internal/libspdm_common_lib.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright Notice:
* Copyright 2021-2024 DMTF. All rights reserved.
* Copyright 2021-2025 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
26 changes: 22 additions & 4 deletions library/spdm_requester_lib/libspdm_req_get_capabilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
64 changes: 63 additions & 1 deletion library/spdm_responder_lib/libspdm_rsp_capabilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
113 changes: 110 additions & 3 deletions unit_test/test_spdm_requester/get_capabilities.c
Original file line number Diff line number Diff line change
@@ -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
**/

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 = {
Expand Down
Loading

0 comments on commit a061ee9

Please sign in to comment.