Skip to content

Commit

Permalink
add unit test : Requester and Responder set HANDSHAKE_IN_THE_CLEAR_CA…
Browse files Browse the repository at this point in the history
…P to 0.

Signed-off-by: Xiao <[email protected]>
  • Loading branch information
Xiao authored and jyao1 committed Jul 25, 2024
1 parent 504fd45 commit 21d720c
Show file tree
Hide file tree
Showing 2 changed files with 269 additions and 0 deletions.
147 changes: 147 additions & 0 deletions unit_test/test_spdm_requester/finish.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ libspdm_return_t libspdm_requester_finish_test_send_message(void *spdm_context,
m_libspdm_local_buffer_size += (request_size - 1);
return LIBSPDM_STATUS_SUCCESS;
case 0x17:
case 0x18:
m_libspdm_local_buffer_size = 0;
libspdm_copy_mem(m_libspdm_local_buffer, sizeof(m_libspdm_local_buffer), &ptr[1],
request_size - 1);
Expand Down Expand Up @@ -1470,6 +1471,43 @@ libspdm_return_t libspdm_requester_finish_test_receive_message(
response);
}
return LIBSPDM_STATUS_SUCCESS;
case 0x18: {
spdm_finish_response_t *spdm_response;
libspdm_session_info_t *session_info;
size_t spdm_response_size;
size_t transport_header_size;
uint32_t session_id;
uint8_t *scratch_buffer;
size_t scratch_buffer_size;

transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;

/* The ResponderVerifyData field does absent.*/
spdm_response_size = sizeof(spdm_finish_response_t);

spdm_response = (void *)((uint8_t *)*response + transport_header_size);
spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
spdm_response->header.request_response_code = SPDM_FINISH_RSP;
spdm_response->header.param1 = 0;
spdm_response->header.param2 = 0;

session_id = 0xFFFFFFFF;
/* For secure message, message is in sender buffer, we need copy it to scratch buffer.
* transport_message is always in sender buffer. */
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);
((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 @@ -3682,6 +3720,113 @@ void libspdm_test_requester_finish_case23(void **state)
free(data);
}

/**
* Test 24: Set HANDSHAKE_IN_THE_CLEAR_CAP to 0 , The ResponderVerifyData field is absent.
* Expected behavior: client returns a Status of RETURN_SUCCESS and
* session is established.
**/
void libspdm_test_requester_finish_case24(void **state)
{
libspdm_return_t status;
libspdm_test_context_t *spdm_test_context;
libspdm_context_t *spdm_context;
uint32_t session_id;
uint8_t req_slot_id_param;
void *data;
size_t data_size;
void *hash;
size_t hash_size;
libspdm_session_info_t *session_info;
libspdm_secured_message_context_t *secured_message_context;

spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 0x18;
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
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_KEY_EX_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_KEY_EX_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;
libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
m_libspdm_use_asym_algo, &data,
&data_size, &hash, &hash_size);
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;

#if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
spdm_context->connection_info.peer_used_cert_chain[0].buffer_size =
data_size;
libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[0].buffer,
sizeof(spdm_context->connection_info.peer_used_cert_chain[0].buffer),
data, data_size);
#else
libspdm_hash_all(
m_libspdm_use_hash_algo,
data, data_size,
spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash);
spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size =
libspdm_get_hash_size(m_libspdm_use_hash_algo);
libspdm_get_leaf_cert_public_key_from_cert_chain(
m_libspdm_use_hash_algo,
spdm_context->connection_info.algorithm.base_asym_algo,
data, data_size,
&spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
#endif
spdm_context->connection_info.peer_used_cert_chain_slot_id = 0;

/* Set HANDSHAKE_IN_THE_CLEAR_CAP to 0*/
spdm_context->connection_info.capability.flags &=
~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP;
spdm_context->local_context.capability.flags &=
~SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP;

session_id = 0xFFFFFFFF;
session_info = &spdm_context->session_info[0];
spdm_context->last_spdm_request_session_id_valid = true;
spdm_context->last_spdm_request_session_id = session_id;
libspdm_session_info_init(spdm_context, session_info, session_id, false);
hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
libspdm_set_mem(m_libspdm_dummy_buffer, hash_size, (uint8_t)(0xFF));
libspdm_secured_message_set_response_finished_key(
session_info->secured_message_context, m_libspdm_dummy_buffer,
hash_size);
libspdm_secured_message_set_session_state(
session_info->secured_message_context,
LIBSPDM_SESSION_STATE_HANDSHAKING);

req_slot_id_param = 0;
status = libspdm_send_receive_finish(spdm_context, session_id, req_slot_id_param);
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
assert_int_equal(
libspdm_secured_message_get_session_state(
spdm_context->session_info[0].secured_message_context),
LIBSPDM_SESSION_STATE_ESTABLISHED);

secured_message_context = session_info->secured_message_context;

assert_memory_equal((const void *)secured_message_context->master_secret.master_secret,
(const void *)m_libspdm_zero_buffer, sizeof(m_libspdm_zero_buffer));
free(data);
}

libspdm_test_context_t m_libspdm_requester_finish_test_context = {
LIBSPDM_TEST_CONTEXT_VERSION,
true,
Expand Down Expand Up @@ -3733,6 +3878,8 @@ int libspdm_requester_finish_test_main(void)
cmocka_unit_test(libspdm_test_requester_finish_case22),
/* Successful response using provisioned public key (slot_id 0xFF) */
cmocka_unit_test(libspdm_test_requester_finish_case23),
/* Set HANDSHAKE_IN_THE_CLEAR_CAP to 0 , The ResponderVerifyData field is absent.*/
cmocka_unit_test(libspdm_test_requester_finish_case24),
};

libspdm_setup_test_context(&m_libspdm_requester_finish_test_context);
Expand Down
122 changes: 122 additions & 0 deletions unit_test/test_spdm_responder/finish.c
Original file line number Diff line number Diff line change
Expand Up @@ -3713,6 +3713,126 @@ void libspdm_test_responder_finish_case28(void** state)
free(data2);
}

/**
* Test 29: Receive the correct FINISH from the requester, and
* the requester and responder have not set HANDSHAKE_IN_THE_CLEAR.
* Expected behavior: the responder accepts the request and produces a valid
* FINISH_RSP response message, and The ResponderVerifyData field is absent.
**/
void libspdm_test_responder_finish_case29(void **state)
{
libspdm_return_t status;
libspdm_test_context_t *spdm_test_context;
libspdm_context_t *spdm_context;
size_t response_size;
uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
spdm_finish_response_t *spdm_response;
void *data1;
size_t data_size1;
uint8_t *ptr;
uint8_t *cert_buffer;
size_t cert_buffer_size;
uint8_t cert_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
uint8_t request_finished_key[LIBSPDM_MAX_HASH_SIZE];
libspdm_session_info_t *session_info;
uint32_t session_id;
uint32_t hash_size;
uint32_t hmac_size;

spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 29;
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
SPDM_VERSION_NUMBER_SHIFT_BIT;
spdm_context->connection_info.connection_state =
LIBSPDM_CONNECTION_STATE_NEGOTIATED;
spdm_context->connection_info.capability.flags |=
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP;
spdm_context->local_context.capability.flags |=
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP;

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.measurement_spec =
m_libspdm_use_measurement_spec;
spdm_context->connection_info.algorithm.measurement_hash_algo =
m_libspdm_use_measurement_hash_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;
libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
m_libspdm_use_asym_algo, &data1,
&data_size1, NULL, NULL);
spdm_context->local_context.local_cert_chain_provision[0] = data1;
spdm_context->local_context.local_cert_chain_provision_size[0] =
data_size1;
spdm_context->connection_info.local_used_cert_chain_buffer = data1;
spdm_context->connection_info.local_used_cert_chain_buffer_size =
data_size1;

libspdm_reset_message_a(spdm_context);
spdm_context->local_context.mut_auth_requested = 0;

/* The requester and responder have not set HANDSHAKE_IN_THE_CLEAR*/
spdm_context->connection_info.capability.flags &=
~SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP;
spdm_context->local_context.capability.flags &=
~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP;

session_id = 0xFFFFFFFF;
spdm_context->latest_session_id = session_id;
spdm_context->last_spdm_request_session_id_valid = true;
spdm_context->last_spdm_request_session_id = session_id;
session_info = &spdm_context->session_info[0];
libspdm_session_info_init(spdm_context, session_info, session_id, false);

hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
hmac_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);

libspdm_set_mem(m_dummy_buffer, hash_size, (uint8_t)(0xFF));
libspdm_secured_message_set_request_finished_key(
session_info->secured_message_context, m_dummy_buffer,
hash_size);
libspdm_secured_message_set_session_state(
session_info->secured_message_context,
LIBSPDM_SESSION_STATE_HANDSHAKING);

hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
ptr = m_libspdm_finish_request1.signature;
libspdm_init_managed_buffer(&th_curr, sizeof(th_curr.buffer));
cert_buffer = (uint8_t *)data1;
cert_buffer_size = data_size1;
libspdm_hash_all(m_libspdm_use_hash_algo, cert_buffer, cert_buffer_size,
cert_buffer_hash);
/* transcript.message_a size is 0*/
libspdm_append_managed_buffer(&th_curr, cert_buffer_hash, hash_size);
/* session_transcript.message_k is 0*/
libspdm_append_managed_buffer(&th_curr, (uint8_t *)&m_libspdm_finish_request1,
sizeof(spdm_finish_request_t));
libspdm_set_mem(request_finished_key, LIBSPDM_MAX_HASH_SIZE, (uint8_t)(0xFF));
libspdm_hash_all(m_libspdm_use_hash_algo, libspdm_get_managed_buffer(&th_curr),
libspdm_get_managed_buffer_size(&th_curr), hash_data);
libspdm_hmac_all(m_libspdm_use_hash_algo, hash_data, hash_size,
request_finished_key, hash_size, ptr);
m_libspdm_finish_request1_size = sizeof(spdm_finish_request_t) + hmac_size;
response_size = sizeof(response);
status = libspdm_get_response_finish(spdm_context,
m_libspdm_finish_request1_size,
&m_libspdm_finish_request1,
&response_size, response);
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
/* The ResponderVerifyData field shall be absent.*/
assert_int_equal(response_size,
sizeof(spdm_finish_response_t));
spdm_response = (void *)response;
assert_int_equal(spdm_response->header.request_response_code,
SPDM_FINISH_RSP);
free(data1);
}

libspdm_test_context_t m_libspdm_responder_finish_test_context = {
LIBSPDM_TEST_CONTEXT_VERSION,
Expand Down Expand Up @@ -3776,6 +3896,8 @@ int libspdm_responder_finish_test_main(void)
cmocka_unit_test_setup(libspdm_test_responder_finish_case27, libspdm_unit_test_group_setup),
/* Little Endian Sign - Big or Little Endian Verify */
cmocka_unit_test_setup(libspdm_test_responder_finish_case28, libspdm_unit_test_group_setup),
/* The requester and responder have not set HANDSHAKE_IN_THE_CLEAR*/
cmocka_unit_test(libspdm_test_responder_finish_case29),
};

libspdm_setup_test_context(&m_libspdm_responder_finish_test_context);
Expand Down

0 comments on commit 21d720c

Please sign in to comment.