From b0fe59dc9b5d718c580b5e9e3c881a1c5724b84b Mon Sep 17 00:00:00 2001 From: Steven Bellock Date: Sun, 12 Jan 2025 16:39:33 -0800 Subject: [PATCH] Add mask for `AlgSupported` reserved bits Fix #2950. Signed-off-by: Steven Bellock --- include/industry_standard/spdm.h | 9 +++ .../libspdm_rsp_algorithms.c | 67 ++++++++++++------- unit_test/test_spdm_responder/algorithms.c | 9 ++- 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/include/industry_standard/spdm.h b/include/industry_standard/spdm.h index 302a63bc279..37ccd1ad1b8 100644 --- a/include/industry_standard/spdm.h +++ b/include/industry_standard/spdm.h @@ -348,6 +348,15 @@ 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 +#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_DHE_MASK_11 0x003f +#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_AEAD_MASK_11 0x0007 +#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_REQ_BASE_ASYM_ALG_MASK_11 0x01ff +#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_KEY_SCHEDULE_11 0x0001 + +#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_DHE_MASK_12 0x007f +#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_AEAD_MASK_12 0x000f +#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_REQ_BASE_ASYM_ALG_MASK_12 0x0fff + typedef struct { uint8_t alg_type; uint8_t alg_count; diff --git a/library/spdm_responder_lib/libspdm_rsp_algorithms.c b/library/spdm_responder_lib/libspdm_rsp_algorithms.c index 488b1cd8de9..14712256c78 100644 --- a/library/spdm_responder_lib/libspdm_rsp_algorithms.c +++ b/library/spdm_responder_lib/libspdm_rsp_algorithms.c @@ -55,6 +55,39 @@ static uint32_t libspdm_prioritize_algorithm(const uint32_t *priority_table, return 0; } +static uint16_t get_alg_supported_mask(uint8_t spdm_version, uint8_t alg_type) +{ + LIBSPDM_ASSERT(spdm_version >= SPDM_MESSAGE_VERSION_11); + + switch (alg_type) { + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE: + if (spdm_version >= SPDM_MESSAGE_VERSION_12) { + return SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_DHE_MASK_12; + } else { + return SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_DHE_MASK_11; + } + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD: + if (spdm_version >= SPDM_MESSAGE_VERSION_12) { + return SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_AEAD_MASK_12; + } else { + return SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_AEAD_MASK_11; + } + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG: + if (spdm_version >= SPDM_MESSAGE_VERSION_12) { + return SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_REQ_BASE_ASYM_ALG_MASK_12; + } else { + return SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_AEAD_MASK_11; + } + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE: + return SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_KEY_SCHEDULE_11; + default: + return 0; + } +} + libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context, size_t request_size, const void *request, @@ -316,6 +349,9 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) { alg_type_pre = struct_table->alg_type; for (index = 0; index < spdm_request->header.param1; index++) { + const uint16_t alg_supported_mask = + get_alg_supported_mask(spdm_request->header.spdm_version, struct_table->alg_type); + if ((size_t)spdm_request + request_size < (size_t)struct_table) { return libspdm_generate_error_response( spdm_context, @@ -362,6 +398,13 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response); } + /* If Requester sends AlgType then AlgSupported must be populated. */ + if ((struct_table->alg_supported & alg_supported_mask) == 0) { + return libspdm_generate_error_response( + spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, + 0, response_size, response); + } + struct_table = (void *)((size_t)struct_table + sizeof(spdm_negotiate_algorithms_common_struct_table_t) + @@ -455,12 +498,6 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context for (index = 0; index < spdm_request->header.param1; index++) { switch (struct_table->alg_type) { case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE: - if (struct_table->alg_supported == 0) { - return libspdm_generate_error_response( - spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, - 0, response_size, response); - } - spdm_context->connection_info.algorithm.dhe_named_group = struct_table->alg_supported; spdm_response->struct_table[index].alg_type = @@ -473,12 +510,6 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context spdm_context->connection_info.algorithm.dhe_named_group); break; case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD: - if (struct_table->alg_supported == 0) { - return libspdm_generate_error_response( - spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, - 0, response_size, response); - } - spdm_context->connection_info.algorithm.aead_cipher_suite = struct_table->alg_supported; spdm_response->struct_table[index].alg_type = @@ -491,12 +522,6 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context spdm_context->connection_info.algorithm.aead_cipher_suite); break; case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG: - if (struct_table->alg_supported == 0) { - return libspdm_generate_error_response( - spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, - 0, response_size, response); - } - spdm_context->connection_info.algorithm.req_base_asym_alg = struct_table->alg_supported; spdm_response->struct_table[index].alg_type = @@ -510,12 +535,6 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context spdm_context->connection_info.algorithm.req_base_asym_alg); break; case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE: - if (struct_table->alg_supported == 0) { - return libspdm_generate_error_response( - spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, - 0, response_size, response); - } - spdm_context->connection_info.algorithm.key_schedule = struct_table->alg_supported; spdm_response->struct_table[index].alg_type = diff --git a/unit_test/test_spdm_responder/algorithms.c b/unit_test/test_spdm_responder/algorithms.c index a327dbc3264..dc20f159500 100644 --- a/unit_test/test_spdm_responder/algorithms.c +++ b/unit_test/test_spdm_responder/algorithms.c @@ -456,8 +456,8 @@ libspdm_negotiate_algorithms_request_spdm11_t 3, 0 }, - sizeof(libspdm_negotiate_algorithms_request_spdm11_t)- - sizeof(spdm_negotiate_algorithms_common_struct_table_t), + /* Size is too large for param1 == 3. */ + sizeof(libspdm_negotiate_algorithms_request_spdm11_t), SPDM_MEASUREMENT_SPECIFICATION_DMTF, }, { @@ -484,9 +484,8 @@ libspdm_negotiate_algorithms_request_spdm11_t } }; size_t m_libspdm_negotiate_algorithm_request13_size = - sizeof(m_libspdm_negotiate_algorithm_request13)- - sizeof( - spdm_negotiate_algorithms_common_struct_table_t); + sizeof(m_libspdm_negotiate_algorithm_request13) - + sizeof(spdm_negotiate_algorithms_common_struct_table_t); libspdm_negotiate_algorithms_request_spdm11_t m_libspdm_negotiate_algorithm_request14 =