diff --git a/include/internal/libspdm_common_lib.h b/include/internal/libspdm_common_lib.h index 30965c47f49..cb116703ba1 100644 --- a/include/internal/libspdm_common_lib.h +++ b/include/internal/libspdm_common_lib.h @@ -1158,24 +1158,47 @@ bool libspdm_calculate_l1l2_hash(libspdm_context_t *spdm_context, #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */ /** - * Get element from multi element opaque data by element id. + * Get element from multi element opaque data by element id and element index + * + * @param[in] spdm_context A pointer to the SPDM context. + * @param[in] data_in_size Size of multi element opaque data. + * @param[in] data_in A pointer to the multi element opaque data. + * @param[in] element_id Element id. + * @param[in] element_index Element index, start from 0. + * It is used to get the nth element with the same element id. + * @param[out] total_matched_element_cnt Pointer to store total matched element count with the same element id. + * @param[out] get_element_ptr Pointer to store found element. + * @param[out] get_element_len Pointer to length of found element. + * + * @retval true Get element successfully + * @retval false Get element failed + **/ +bool libspdm_get_element_from_opaque_data_with_element_id (libspdm_context_t *spdm_context, + size_t data_in_size, const void *data_in, + uint8_t element_id, uint8_t element_index, + uint8_t *total_matched_element_cnt, + const void **get_element_ptr, size_t *get_element_len); + +/** + * Get secured message opaque data element from multi element opaque data by sm data id * * This function should be called in * libspdm_process_opaque_data_supported_version_data/libspdm_process_opaque_data_version_selection_data. * - * @param[in] data_in_size Size of multi element opaque data. - * @param[in] data_in A pointer to the multi element opaque data. - * @param[in] element_id Element id. - * @param[in] sm_data_id ID for the Secured Message data type. - * @param[out] get_element_ptr Pointer to store found element. + * @param[in] spdm_context A pointer to the SPDM context. + * @param[in] data_in_size Size of multi element opaque data. + * @param[in] data_in A pointer to the multi element opaque data. + * @param[in] sm_data_id ID for the Secured Message data type. + * @param[out] get_element_ptr Pointer to store found element. + * @param[out] get_element_len Pointer to length of found element. * * @retval true Get element successfully * @retval false Get element failed **/ -bool libspdm_get_element_from_opaque_data(libspdm_context_t *spdm_context, - size_t data_in_size, const void *data_in, - uint8_t element_id, uint8_t sm_data_id, - const void **get_element_ptr, size_t *get_element_len); +bool libspdm_get_sm_data_element_from_opaque_data (libspdm_context_t *spdm_context, + size_t data_in_size, const void *data_in, + uint8_t sm_data_id, + const void **get_element_ptr, size_t *get_element_len); /** * Process opaque data version selection. diff --git a/library/spdm_common_lib/libspdm_com_opaque_data.c b/library/spdm_common_lib/libspdm_com_opaque_data.c index c4ff94702f4..8e56485ba7e 100644 --- a/library/spdm_common_lib/libspdm_com_opaque_data.c +++ b/library/spdm_common_lib/libspdm_com_opaque_data.c @@ -72,21 +72,21 @@ size_t libspdm_get_untrusted_opaque_data_supported_version_data_size( return (size + 3) & ~3; } -bool libspdm_get_element_from_opaque_data(libspdm_context_t *spdm_context, - size_t data_in_size, const void *data_in, - uint8_t element_id, uint8_t sm_data_id, - const void **get_element_ptr, size_t *get_element_len) +bool libspdm_get_element_from_opaque_data_with_element_id (libspdm_context_t *spdm_context, + size_t data_in_size, const void *data_in, + uint8_t element_id, uint8_t element_index, + uint8_t *total_matched_element_cnt, + const void **get_element_ptr, size_t *get_element_len) { const secured_message_general_opaque_data_table_header_t *general_opaque_data_table_header; const spdm_general_opaque_data_table_header_t *spdm_general_opaque_data_table_header; const opaque_element_table_header_t *opaque_element_table_header; uint16_t opaque_element_data_len; - const secured_message_opaque_element_table_header_t *secured_message_element_table_header; - const secured_message_opaque_element_header_t *secured_message_element_header; bool result; uint8_t element_num; - uint8_t element_index; + uint8_t index; + uint8_t matched_element_cnt; size_t data_element_size; size_t current_element_len; size_t total_element_len; @@ -133,7 +133,9 @@ bool libspdm_get_element_from_opaque_data(libspdm_context_t *spdm_context, total_element_len = 0; result = false; - for (element_index = 0; element_index < element_num; element_index++) { + /* find the Nth element with specific element_id, N = element_index. */ + matched_element_cnt = 0; + for (index = 0; index < element_num; index++) { /*ensure the opaque_element_table_header is valid*/ if (total_element_len + sizeof(opaque_element_table_header_t) > data_element_size) { @@ -166,25 +168,13 @@ bool libspdm_get_element_from_opaque_data(libspdm_context_t *spdm_context, } if (opaque_element_table_header->id == element_id) { - secured_message_element_table_header = (const void *)opaque_element_table_header; - if (secured_message_element_table_header->vendor_len == 0) { - secured_message_element_header = - (const void *)(secured_message_element_table_header + 1); - if ((const uint8_t *)secured_message_element_header + - sizeof(secured_message_opaque_element_header_t) > - (const uint8_t *)data_in + data_in_size) { - return false; - } - - if ((secured_message_element_header->sm_data_id == sm_data_id) && - (secured_message_element_header->sm_data_version == - SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION)) { - /*get element by element id*/ - *get_element_ptr = opaque_element_table_header; - *get_element_len = current_element_len; - result = true; - } + /*get element by element id*/ + if (matched_element_cnt == element_index) { + *get_element_ptr = opaque_element_table_header; + *get_element_len = current_element_len; + result = true; } + matched_element_cnt += 1; } /*move to next element*/ @@ -198,9 +188,72 @@ bool libspdm_get_element_from_opaque_data(libspdm_context_t *spdm_context, return false; } + *total_matched_element_cnt = matched_element_cnt; return result; } +bool libspdm_get_sm_data_element_from_opaque_data (libspdm_context_t *spdm_context, + size_t data_in_size, const void *data_in, + uint8_t sm_data_id, + const void **get_element_ptr, size_t *get_element_len) +{ + const opaque_element_table_header_t *opaque_element_table_header; + size_t opaque_element_len; + const secured_message_opaque_element_table_header_t *secured_message_element_table_header; + const secured_message_opaque_element_header_t *secured_message_element_header; + bool result; + uint8_t element_index; + uint8_t element_num; + uint8_t total_matched_element_cnt; + + /*check parameter in*/ + if ((data_in_size == 0) || (data_in == NULL)) { + return false; + } + + /*get the total matched element count*/ + result = libspdm_get_element_from_opaque_data_with_element_id( + spdm_context, data_in_size, data_in, + SPDM_REGISTRY_ID_DMTF, 0, &total_matched_element_cnt, + (const void **) &opaque_element_table_header, &opaque_element_len); + if (!result) { + return false; + } + + element_num = total_matched_element_cnt; + for (element_index = 0; element_index < element_num; element_index++) { + /*get element by element id*/ + result = libspdm_get_element_from_opaque_data_with_element_id( + spdm_context, data_in_size, data_in, + SPDM_REGISTRY_ID_DMTF, element_index, &total_matched_element_cnt, + (const void **) &opaque_element_table_header, &opaque_element_len); + if (!result) { + return false; + } + + secured_message_element_table_header = (const void *)opaque_element_table_header; + if (secured_message_element_table_header->vendor_len == 0) { + secured_message_element_header = + (const void *)(secured_message_element_table_header + 1); + if ((const uint8_t *)secured_message_element_header + + sizeof(secured_message_opaque_element_header_t) > + (const uint8_t *)data_in + data_in_size) { + return false; + } + + if ((secured_message_element_header->sm_data_id == sm_data_id) && + (secured_message_element_header->sm_data_version == + SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION)) { + *get_element_ptr = opaque_element_table_header; + *get_element_len = opaque_element_len; + return true; + } + } + } + + return false; +} + bool libspdm_process_general_opaque_data_check(libspdm_context_t *spdm_context, size_t data_in_size, const void *data_in) @@ -321,9 +374,8 @@ libspdm_return_t libspdm_process_opaque_data_version_selection_data( return LIBSPDM_STATUS_SUCCESS; } - result = libspdm_get_element_from_opaque_data( - spdm_context, data_in_size, - data_in, SPDM_REGISTRY_ID_DMTF, + result = libspdm_get_sm_data_element_from_opaque_data( + spdm_context, data_in_size, data_in, SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION, &get_element_ptr, &get_element_len); if ((!result) || (get_element_ptr == NULL)) { diff --git a/library/spdm_responder_lib/libspdm_rsp_common.c b/library/spdm_responder_lib/libspdm_rsp_common.c index 73ca5d2b20a..6d91460919b 100644 --- a/library/spdm_responder_lib/libspdm_rsp_common.c +++ b/library/spdm_responder_lib/libspdm_rsp_common.c @@ -1,6 +1,6 @@ /** * Copyright Notice: - * Copyright 2021-2025 DMTF. All rights reserved. + * Copyright 2021-2026 DMTF. All rights reserved. * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md **/ @@ -118,10 +118,9 @@ libspdm_return_t libspdm_process_opaque_data_supported_version_data( return LIBSPDM_STATUS_INVALID_MSG_FIELD; } - result = libspdm_get_element_from_opaque_data( + result = libspdm_get_sm_data_element_from_opaque_data( spdm_context, data_in_size, - data_in, SPDM_REGISTRY_ID_DMTF, - SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_SUPPORTED_VERSION, + data_in, SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_SUPPORTED_VERSION, &get_element_ptr, &get_element_len); if ((!result) || (get_element_ptr == NULL)) { LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,"get element error!\n")); diff --git a/unit_test/test_spdm_common/context_data.c b/unit_test/test_spdm_common/context_data.c index bbcd0c21b34..5a86f03f289 100644 --- a/unit_test/test_spdm_common/context_data.c +++ b/unit_test/test_spdm_common/context_data.c @@ -1,6 +1,6 @@ /** * Copyright Notice: - * Copyright 2021-2025 DMTF. All rights reserved. + * Copyright 2021-2026 DMTF. All rights reserved. * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md **/ @@ -1695,19 +1695,17 @@ static void libspdm_test_process_opaque_data_case22(void **state) opaque_data_ptr = (uint8_t *)&opaque_data; opaque_data_size = sizeof(opaque_data); - status = libspdm_get_element_from_opaque_data(spdm_context, - opaque_data_size, opaque_data_ptr, - SPDM_REGISTRY_ID_DMTF, - SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION, - &get_element_ptr, &get_element_len - ); + status = libspdm_get_sm_data_element_from_opaque_data(spdm_context, + opaque_data_size, opaque_data_ptr, + SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION, + &get_element_ptr, &get_element_len + ); assert_int_equal (status, true); - status = libspdm_get_element_from_opaque_data(spdm_context, - opaque_data_size, opaque_data_ptr, - SPDM_REGISTRY_ID_DMTF, - SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_SUPPORTED_VERSION, - &get_element_ptr, &get_element_len - ); + status = libspdm_get_sm_data_element_from_opaque_data(spdm_context, + opaque_data_size, opaque_data_ptr, + SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_SUPPORTED_VERSION, + &get_element_ptr, &get_element_len + ); assert_int_equal (status, true); }