Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions library/spdm_requester_lib/libspdm_req_psk_finish.c
Original file line number Diff line number Diff line change
@@ -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
**/

Expand Down Expand Up @@ -293,6 +293,7 @@ static libspdm_return_t libspdm_try_send_receive_psk_finish(
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}

/* this message can only be in secured session
* thus don't need to consider transport layer padding, just check its exact size */
if (spdm_response_size != sizeof(spdm_psk_finish_response_t) + sizeof(uint16_t) +
Expand All @@ -302,7 +303,7 @@ static libspdm_return_t libspdm_try_send_receive_psk_finish(
}

if ((responder_opaque_data != NULL) && (responder_opaque_data_size != NULL)) {
if (opaque_data_size >= *responder_opaque_data_size) {
if (opaque_data_size > *responder_opaque_data_size) {
Copy link
Copy Markdown
Member

@jyao1 jyao1 Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

I notice finish has same issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Do you think we better create separate follow-up issue or propose "finish" fix within this PR ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am OK to create another PR.
I just want to ensure 1) all issues are fixed, 2) the solution is consistent, especially the similar ones.
That is why I cross-check other commands.

Copy link
Copy Markdown
Contributor Author

@czwolak czwolak Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you :) can we confirm also another cases?

  1. FINISH - what you found

if (opaque_data_size >= *responder_opaque_data_size) {
status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
goto receive_done;
}

  1. KEY_EXCHANGE

if (opaque_length >= *responder_opaque_data_size) {
status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
goto receive_done;
}

  1. PSK_EXCHANGE

if (spdm_response->opaque_length >= *responder_opaque_data_size) {
status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
goto receive_done;
}

status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
goto receive_done;
}
Expand All @@ -325,7 +326,7 @@ static libspdm_return_t libspdm_try_send_receive_psk_finish(
}
opaque_data_entry_size = 0;
}
spdm_response_size = sizeof(spdm_finish_response_t) + opaque_data_entry_size;
spdm_response_size = sizeof(spdm_psk_finish_response_t) + opaque_data_entry_size;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!


status = libspdm_append_message_f(spdm_context, session_info, true, spdm_response,
spdm_response_size);
Expand Down
6 changes: 6 additions & 0 deletions library/spdm_responder_lib/libspdm_rsp_psk_finish_rsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,12 @@ libspdm_return_t libspdm_get_response_psk_finish(libspdm_context_t *spdm_context
SPDM_ERROR_CODE_UNSPECIFIED, 0,
response_size, response);
}

if (opaque_data_size > SPDM_MAX_OPAQUE_DATA_SIZE) {
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_UNSPECIFIED, 0,
response_size, response);
}
}
libspdm_write_uint16(ptr, (uint16_t)opaque_data_size);
opaque_data_entry_size = sizeof(uint16_t) + opaque_data_size;
Expand Down
127 changes: 127 additions & 0 deletions unit_test/test_spdm_requester/psk_finish.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ static libspdm_return_t send_message(
m_libspdm_local_buffer_size += decoded_message_size;
}
return LIBSPDM_STATUS_SUCCESS;
case 0x12:
return LIBSPDM_STATUS_SUCCESS;
default:
return LIBSPDM_STATUS_SEND_FAIL;
}
Expand Down Expand Up @@ -921,6 +923,49 @@ static libspdm_return_t receive_message(
}
return LIBSPDM_STATUS_SUCCESS;

case 0x12: {
spdm_psk_finish_response_t *spdm_response;
size_t spdm_response_size;
size_t transport_header_size;
uint32_t session_id;
libspdm_session_info_t *session_info;
uint8_t *scratch_buffer;
size_t scratch_buffer_size;
uint16_t opaque_data_size;
uint8_t *ptr;

session_id = 0xFFFFFFFF;
opaque_data_size = SPDM_MAX_OPAQUE_DATA_SIZE + 1;
spdm_response_size = sizeof(spdm_psk_finish_response_t) + sizeof(uint16_t);
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
spdm_response = (void *)((uint8_t *)*response + transport_header_size);

spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_14;
spdm_response->header.request_response_code = SPDM_PSK_FINISH_RSP;
spdm_response->header.param1 = 0;
spdm_response->header.param2 = 0;
ptr = (uint8_t *)spdm_response + sizeof(spdm_psk_finish_response_t);
libspdm_write_uint16(ptr, opaque_data_size);

libspdm_get_scratch_buffer (spdm_context, (void **)&scratch_buffer, &scratch_buffer_size);
libspdm_copy_mem (scratch_buffer + transport_header_size,
scratch_buffer_size - transport_header_size,
spdm_response, spdm_response_size);
spdm_response = (void *)(scratch_buffer + transport_header_size);

libspdm_transport_test_encode_message(spdm_context, &session_id,
false, false, spdm_response_size,
spdm_response, response_size,
response);
session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
if (session_info == NULL) {
return LIBSPDM_STATUS_RECEIVE_FAIL;
}
((libspdm_secured_message_context_t*)(session_info->secured_message_context))
->handshake_secret.response_handshake_sequence_number--;
}
return LIBSPDM_STATUS_SUCCESS;

default:
return LIBSPDM_STATUS_RECEIVE_FAIL;
}
Expand Down Expand Up @@ -2414,6 +2459,8 @@ static void req_psk_finish_case17(void **state)
spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
spdm_context->connection_info.algorithm.other_params_support =
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1;

session_id = 0xFFFFFFFF;
session_info = &spdm_context->session_info[0];
Expand Down Expand Up @@ -2455,6 +2502,84 @@ static void req_psk_finish_case17(void **state)
free(data);
}

/**
* Test 18: SPDM version 1.4, response opaque length exceeds protocol max.
* Expected behavior: requester returns LIBSPDM_STATUS_INVALID_MSG_FIELD.
**/
static void req_psk_finish_case18(void **state)
{
libspdm_return_t status;
libspdm_test_context_t *spdm_test_context;
libspdm_context_t *spdm_context;
uint32_t session_id;
void *data;
size_t data_size;
void *hash;
size_t hash_size;
libspdm_session_info_t *session_info;

spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 0x12;
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
SPDM_VERSION_NUMBER_SHIFT_BIT;
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP;
spdm_context->connection_info.capability.flags |=
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP;
spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP;
spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
m_libspdm_use_asym_algo, &data,
&data_size, &hash, &hash_size)) {
assert(false);
}
libspdm_reset_message_a(spdm_context);
spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
spdm_context->connection_info.algorithm.other_params_support =
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1;

session_id = 0xFFFFFFFF;
session_info = &spdm_context->session_info[0];
libspdm_session_info_init(spdm_context, session_info, session_id,
SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
libspdm_session_info_set_psk_hint(session_info,
LIBSPDM_TEST_PSK_HINT_STRING,
sizeof(LIBSPDM_TEST_PSK_HINT_STRING));
libspdm_secured_message_set_session_state(
session_info->secured_message_context,
LIBSPDM_SESSION_STATE_HANDSHAKING);
libspdm_set_mem(m_libspdm_dummy_key_buffer,
((libspdm_secured_message_context_t*)(session_info->secured_message_context))
->aead_key_size, (uint8_t)(0xFF));
libspdm_secured_message_set_response_handshake_encryption_key(
session_info->secured_message_context, m_libspdm_dummy_key_buffer,
((libspdm_secured_message_context_t*)(session_info->secured_message_context))
->aead_key_size);
libspdm_set_mem(m_libspdm_dummy_salt_buffer,
((libspdm_secured_message_context_t*)(session_info->secured_message_context))
->aead_iv_size, (uint8_t)(0xFF));
libspdm_secured_message_set_response_handshake_salt(
session_info->secured_message_context, m_libspdm_dummy_salt_buffer,
((libspdm_secured_message_context_t*)(session_info->secured_message_context))
->aead_iv_size);
((libspdm_secured_message_context_t *)(session_info->secured_message_context))
->handshake_secret.response_handshake_sequence_number = 0;
((libspdm_secured_message_context_t *)(session_info->secured_message_context))
->handshake_secret.request_handshake_sequence_number = 0;
libspdm_secured_message_set_dummy_finished_key (session_info->secured_message_context);

status = libspdm_send_receive_psk_finish(spdm_context, session_id);
assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);

free(data);
}

int libspdm_req_psk_finish_test(void)
{
const struct CMUnitTest test_cases[] = {
Expand Down Expand Up @@ -2492,6 +2617,8 @@ int libspdm_req_psk_finish_test(void)
cmocka_unit_test(req_psk_finish_case16),
/* SPDM 1.4 with OpaqueData */
cmocka_unit_test(req_psk_finish_case17),
/* SPDM 1.4 response opaque length over protocol max */
cmocka_unit_test(req_psk_finish_case18),
};

libspdm_test_context_t test_context = {
Expand Down
Loading
Loading