diff --git a/include/internal/libspdm_common_lib.h b/include/internal/libspdm_common_lib.h index 5e9bb63a082..ff550476abd 100644 --- a/include/internal/libspdm_common_lib.h +++ b/include/internal/libspdm_common_lib.h @@ -128,6 +128,10 @@ typedef struct { /* Specifies whether the cached negotiated state should be invalidated. (responder only) * This is a "sticky" bit wherein if it is set to 1 then it cannot be set to 0. */ uint8_t end_session_attributes; + + /* multi-key negotiated result */ + bool multi_key_conn_req; + bool multi_key_conn_rsp; } libspdm_connection_info_t; typedef struct { diff --git a/library/spdm_common_lib/libspdm_com_opaque_data.c b/library/spdm_common_lib/libspdm_com_opaque_data.c index 76739e596a3..6dcbbc10155 100644 --- a/library/spdm_common_lib/libspdm_com_opaque_data.c +++ b/library/spdm_common_lib/libspdm_com_opaque_data.c @@ -261,8 +261,8 @@ bool libspdm_process_general_opaque_data_check(libspdm_context_t *spdm_context, LIBSPDM_ASSERT(data_in_size <= SPDM_MAX_OPAQUE_DATA_SIZE); if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) { - if (spdm_context->connection_info.algorithm.other_params_support == - SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) { + if ((spdm_context->connection_info.algorithm.other_params_support & + SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) == SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) { /* Check byte alignment */ if ((data_in_size & 3) != 0) { return false; diff --git a/library/spdm_requester_lib/libspdm_req_negotiate_algorithms.c b/library/spdm_requester_lib/libspdm_req_negotiate_algorithms.c index 23abff6e530..c9d74938ac0 100644 --- a/library/spdm_requester_lib/libspdm_req_negotiate_algorithms.c +++ b/library/spdm_requester_lib/libspdm_req_negotiate_algorithms.c @@ -140,6 +140,32 @@ static libspdm_return_t libspdm_try_negotiate_algorithms(libspdm_context_t *spdm spdm_request->other_params_support = spdm_context->local_context.algorithm.other_params_support; } + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + switch (spdm_context->connection_info.capability.flags & + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) { + case 0: + spdm_context->connection_info.multi_key_conn_rsp = false; + break; + case SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_ONLY: + spdm_context->connection_info.multi_key_conn_rsp = true; + break; + case SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_NEG: + if ((spdm_context->local_context.algorithm.other_params_support & + SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) { + spdm_context->connection_info.multi_key_conn_rsp = false; + } else { + spdm_context->connection_info.multi_key_conn_rsp = true; + } + break; + default: + return LIBSPDM_STATUS_INVALID_MSG_FIELD; + } + if (spdm_context->connection_info.multi_key_conn_rsp) { + spdm_request->other_params_support |= SPDM_ALGORITHMS_MULTI_KEY_CONN; + } else { + spdm_request->other_params_support &= ~SPDM_ALGORITHMS_MULTI_KEY_CONN; + } + } spdm_request->base_asym_algo = spdm_context->local_context.algorithm.base_asym_algo; spdm_request->base_hash_algo = spdm_context->local_context.algorithm.base_hash_algo; spdm_request->ext_asym_count = 0; @@ -536,6 +562,26 @@ static libspdm_return_t libspdm_try_negotiate_algorithms(libspdm_context_t *spdm } } } + + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + if ((spdm_context->connection_info.algorithm.other_params_support & + SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) { + if ((spdm_context->local_context.capability.flags & + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) == + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY) { + status = LIBSPDM_STATUS_NEGOTIATION_FAIL; + goto receive_done; + } + spdm_context->connection_info.multi_key_conn_req = false; + } else { + if ((spdm_context->local_context.capability.flags & + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) == 0) { + status = LIBSPDM_STATUS_NEGOTIATION_FAIL; + goto receive_done; + } + spdm_context->connection_info.multi_key_conn_req = true; + } + } } else { spdm_context->connection_info.algorithm.dhe_named_group = 0; spdm_context->connection_info.algorithm.aead_cipher_suite = 0; diff --git a/library/spdm_responder_lib/libspdm_rsp_algorithms.c b/library/spdm_responder_lib/libspdm_rsp_algorithms.c index 78ac6d91c89..0053c2f068e 100644 --- a/library/spdm_responder_lib/libspdm_rsp_algorithms.c +++ b/library/spdm_responder_lib/libspdm_rsp_algorithms.c @@ -579,8 +579,39 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context spdm_response->other_params_selection = (uint8_t)libspdm_prioritize_algorithm( other_params_support_priority_table, LIBSPDM_ARRAY_SIZE(other_params_support_priority_table), - spdm_context->local_context.algorithm.other_params_support, - spdm_context->connection_info.algorithm.other_params_support); + spdm_context->local_context.algorithm.other_params_support & + SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK, + spdm_context->connection_info.algorithm.other_params_support & + SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK); + } + + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + switch (spdm_context->connection_info.capability.flags & + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) { + case 0: + spdm_context->connection_info.multi_key_conn_req = false; + break; + case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY: + spdm_context->connection_info.multi_key_conn_req = true; + break; + case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_NEG: + if ((spdm_context->local_context.algorithm.other_params_support & + SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) { + spdm_context->connection_info.multi_key_conn_req = false; + } else { + spdm_context->connection_info.multi_key_conn_req = true; + } + break; + default: + return libspdm_generate_error_response( + spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, + 0, response_size, response); + } + if (spdm_context->connection_info.multi_key_conn_req) { + spdm_response->other_params_selection |= SPDM_ALGORITHMS_MULTI_KEY_CONN; + } else { + spdm_response->other_params_selection &= ~SPDM_ALGORITHMS_MULTI_KEY_CONN; + } } spdm_context->connection_info.algorithm.measurement_spec = @@ -760,6 +791,30 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context } } } + + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + if ((spdm_context->connection_info.algorithm.other_params_support & + SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) { + if ((spdm_context->local_context.capability.flags & + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) == + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_ONLY) { + return libspdm_generate_error_response( + spdm_context, + SPDM_ERROR_CODE_INVALID_REQUEST, 0, + response_size, response); + } + spdm_context->connection_info.multi_key_conn_rsp = false; + } else { + if ((spdm_context->local_context.capability.flags & + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) == 0) { + return libspdm_generate_error_response( + spdm_context, + SPDM_ERROR_CODE_INVALID_REQUEST, 0, + response_size, response); + } + spdm_context->connection_info.multi_key_conn_rsp = true; + } + } } else { spdm_context->connection_info.algorithm.dhe_named_group = 0; spdm_context->connection_info.algorithm.aead_cipher_suite = 0;