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
Xiaohanjlll committed Jul 23, 2024
1 parent 504fd45 commit 8ebddb6
Show file tree
Hide file tree
Showing 2 changed files with 459 additions and 0 deletions.
337 changes: 337 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,8 @@ 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:
case 0x19:
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 +1472,134 @@ 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;

/* Set HANDSHAKE_IN_THE_CLEAR_CAP to 0 , The ResponderVerifyData field does not exist.*/
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;

case 0x19: {
spdm_finish_response_t *spdm_response;
uint32_t hash_size;
uint32_t hmac_size;
uint8_t *ptr;
void *data;
size_t data_size;
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 response_finished_key[LIBSPDM_MAX_HASH_SIZE];
size_t spdm_response_size;
size_t transport_header_size;
libspdm_session_info_t *session_info;
uint32_t session_id;
uint8_t *scratch_buffer;
size_t scratch_buffer_size;

((libspdm_context_t *)spdm_context)
->connection_info.algorithm.base_asym_algo =
m_libspdm_use_asym_algo;
((libspdm_context_t *)spdm_context)
->connection_info.algorithm.base_hash_algo =
m_libspdm_use_hash_algo;
((libspdm_context_t *)spdm_context)
->connection_info.algorithm.dhe_named_group =
m_libspdm_use_dhe_algo;
((libspdm_context_t *)spdm_context)
->connection_info.algorithm.measurement_hash_algo =
m_libspdm_use_measurement_hash_algo;

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_11;
spdm_response->header.request_response_code = SPDM_FINISH_RSP;
spdm_response->header.param1 = 0;
spdm_response->header.param2 = 0;

/* Set HANDSHAKE_IN_THE_CLEAR_CAP to 0 , The ResponderVerifyData field is present.*/
hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
hmac_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
spdm_response_size = sizeof(spdm_finish_response_t) + hmac_size;

ptr = (void *)(spdm_response + 1);
libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
sizeof(m_libspdm_local_buffer)
- (&m_libspdm_local_buffer[m_libspdm_local_buffer_size] -
m_libspdm_local_buffer),
spdm_response, sizeof(spdm_finish_response_t));
m_libspdm_local_buffer_size += sizeof(spdm_finish_response_t);
libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
m_libspdm_use_asym_algo, &data,
&data_size, NULL, NULL);
libspdm_init_managed_buffer(&th_curr, sizeof(th_curr.buffer));
cert_buffer = (uint8_t *)data;
cert_buffer_size = data_size;
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, m_libspdm_local_buffer,
m_libspdm_local_buffer_size);
libspdm_set_mem(response_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,
response_finished_key, hash_size, ptr);
ptr += hmac_size;
free(data);

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 +3812,209 @@ void libspdm_test_requester_finish_case23(void **state)
free(data);
}

/**
* Test 24: Set HANDSHAKE_IN_THE_CLEAR_CAP to 0 , The ResponderVerifyData field is present.
* 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);
}

/**
* Test 25: Set HANDSHAKE_IN_THE_CLEAR_CAP to 0 , The ResponderVerifyData field does not exist.
* Expected behavior: client returns a Status of RETURN_DEVICE_ERROR.
**/
void libspdm_test_requester_finish_case25(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;

spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 0x19;
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,
m_libspdm_use_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_BUSY_PEER);
free(data);
}

libspdm_test_context_t m_libspdm_requester_finish_test_context = {
LIBSPDM_TEST_CONTEXT_VERSION,
true,
Expand Down Expand Up @@ -3733,6 +4066,10 @@ 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 does not exist.*/
cmocka_unit_test(libspdm_test_requester_finish_case24),
/* Set HANDSHAKE_IN_THE_CLEAR_CAP to 0 , The ResponderVerifyData field is present.*/
cmocka_unit_test(libspdm_test_requester_finish_case25),
};

libspdm_setup_test_context(&m_libspdm_requester_finish_test_context);
Expand Down
Loading

0 comments on commit 8ebddb6

Please sign in to comment.