Skip to content

Commit

Permalink
Allow no selected OpaqueDataFmt
Browse files Browse the repository at this point in the history
Fix #1389.

Signed-off-by: Steven Bellock <sbellock@nvidia.com>
  • Loading branch information
steven-bellock committed Jul 23, 2023
1 parent 3f21568 commit 2aabafa
Show file tree
Hide file tree
Showing 22 changed files with 208 additions and 145 deletions.
5 changes: 3 additions & 2 deletions include/industry_standard/spdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,9 @@ typedef struct {
#define SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SM3_256 0x00000080

/* SPDM Opaque Data Format (1.2) */
#define SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0 0x00000001
#define SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1 0x00000002
#define SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE 0x0
#define SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0 0x1
#define SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1 0x2
#define SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK 0xF

/* SPDM Opaque Data Format 1 (1.2) */
Expand Down
4 changes: 4 additions & 0 deletions include/library/spdm_return_status.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ typedef uint32_t libspdm_return_t;
#define LIBSPDM_STATUS_PEER_BUFFER_TOO_SMALL \
LIBSPDM_STATUS_CONSTRUCT(LIBSPDM_SEVERITY_ERROR, LIBSPDM_SOURCE_CORE, 0x0013)

/* A parameter passed by the Integrator was overridden. */
#define LIBSPDM_STATUS_OVERRIDDEN_PARAMETER \
LIBSPDM_STATUS_CONSTRUCT(LIBSPDM_SEVERITY_WARNING, LIBSPDM_SOURCE_CORE, 0x0014)

/* - Cryptography Errors - */

/* Generic failure originating from the cryptography module. */
Expand Down
9 changes: 9 additions & 0 deletions library/spdm_requester_lib/libspdm_req_challenge.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,15 @@ static libspdm_return_t libspdm_try_challenge(libspdm_context_t *spdm_context,
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
if (((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) ==
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE) &&
(opaque_length != 0)) {
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}
}
ptr += sizeof(uint16_t);
if (opaque_length != 0) {
result = libspdm_process_general_opaque_data_check(spdm_context, opaque_length, ptr);
Expand Down
16 changes: 16 additions & 0 deletions library/spdm_requester_lib/libspdm_req_get_csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ static libspdm_return_t libspdm_try_get_csr(libspdm_context_t *spdm_context,
void *csr, size_t *csr_len)
{
libspdm_return_t status;
libspdm_return_t warning;
spdm_get_csr_request_t *spdm_request;
size_t spdm_request_size;
spdm_csr_response_t *spdm_response;
Expand Down Expand Up @@ -101,6 +102,17 @@ static libspdm_return_t libspdm_try_get_csr(libspdm_context_t *spdm_context,
(uint8_t *)requester_info, requester_info_length);
}

warning = LIBSPDM_STATUS_SUCCESS;
if (((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) == SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE) &&
(opaque_data_length != 0)) {
LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
"Overriding opaque_data_length to 0 since there is \
no negotiated opaque data format."));
opaque_data_length = 0;
warning = LIBSPDM_STATUS_OVERRIDDEN_PARAMETER;
}

if (opaque_data_length != 0) {
libspdm_copy_mem((uint8_t *)(spdm_request + 1) + requester_info_length,
spdm_request_size - sizeof(spdm_get_csr_request_t) - requester_info_length,
Expand Down Expand Up @@ -175,6 +187,10 @@ static libspdm_return_t libspdm_try_get_csr(libspdm_context_t *spdm_context,

receive_done:
libspdm_release_receiver_buffer (spdm_context);

if ((status == LIBSPDM_STATUS_SUCCESS) && (LIBSPDM_STATUS_IS_WARNING(warning))) {
status = warning;
}
return status;
}

Expand Down
9 changes: 9 additions & 0 deletions library/spdm_requester_lib/libspdm_req_get_measurements.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,15 @@ static libspdm_return_t libspdm_try_get_measurement(libspdm_context_t *spdm_cont
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
if (((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) ==
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE)
&& (opaque_length != 0)) {
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}
}
ptr += sizeof(uint16_t);
if (opaque_length != 0) {
result = libspdm_process_general_opaque_data_check(spdm_context, opaque_length, ptr);
Expand Down
6 changes: 6 additions & 0 deletions library/spdm_requester_lib/libspdm_req_key_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,12 @@ static libspdm_return_t libspdm_try_send_receive_key_exchange(
if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
}
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_MASK) != SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
return LIBSPDM_STATUS_INVALID_STATE_PEER;
}
}

req_session_id = libspdm_allocate_req_session_id(spdm_context, false);
if (req_session_id == (INVALID_SESSION_ID & 0xFFFF))
Expand Down
16 changes: 8 additions & 8 deletions library/spdm_requester_lib/libspdm_req_negotiate_algorithms.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ static libspdm_return_t libspdm_try_negotiate_algorithms(libspdm_context_t *spdm
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
if (!libspdm_onehot0(spdm_response->other_params_selection &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK)) {
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}
}
if (!libspdm_onehot0(spdm_response->measurement_hash_algo)) {
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
Expand Down Expand Up @@ -482,20 +489,13 @@ static libspdm_return_t libspdm_try_negotiate_algorithms(libspdm_context_t *spdm
status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
goto receive_done;
}
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
if ((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) !=
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
goto receive_done;
}
}
}
} else {
spdm_context->connection_info.algorithm.dhe_named_group = 0;
spdm_context->connection_info.algorithm.aead_cipher_suite = 0;
spdm_context->connection_info.algorithm.req_base_asym_alg = 0;
spdm_context->connection_info.algorithm.key_schedule = 0;
spdm_context->connection_info.algorithm.other_params_support = 0;
}

/* -=[Update State Phase]=- */
Expand Down
8 changes: 7 additions & 1 deletion library/spdm_requester_lib/libspdm_req_psk_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,23 @@ static libspdm_return_t libspdm_try_send_receive_psk_exchange(
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}
libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_PSK_EXCHANGE);
if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
}
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_MASK) != SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
return LIBSPDM_STATUS_INVALID_STATE_PEER;
}
}

req_session_id = libspdm_allocate_req_session_id(spdm_context, true);
if (req_session_id == (INVALID_SESSION_ID & 0xFFFF))
{
return LIBSPDM_STATUS_SESSION_NUMBER_EXCEED;
}

libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_PSK_EXCHANGE);
{
/* Double check if algorithm has been provisioned, because ALGORITHM might be skipped.*/
if (libspdm_is_capabilities_flag_supported(
Expand Down
26 changes: 16 additions & 10 deletions library/spdm_responder_lib/libspdm_rsp_algorithms.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,8 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context

uint32_t other_params_support_priority_table[] = {
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1,
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0,
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE
};

spdm_request = request;
Expand Down Expand Up @@ -389,6 +391,20 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context
response_size, response);
}
}
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
switch (spdm_request->other_params_support & SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) {
case SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE:
case SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0:
case SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1:
break;
default:
return libspdm_generate_error_response(
spdm_context,
SPDM_ERROR_CODE_INVALID_REQUEST, 0,
response_size, response);
}
}

request_size = (size_t)struct_table - (size_t)spdm_request;
if (request_size != spdm_request->length) {
return libspdm_generate_error_response(
Expand Down Expand Up @@ -683,16 +699,6 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context
SPDM_ERROR_CODE_INVALID_REQUEST, 0,
response_size, response);
}
if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
if ((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) !=
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
return libspdm_generate_error_response(
spdm_context,
SPDM_ERROR_CODE_INVALID_REQUEST, 0,
response_size, response);
}
}
}
} else {
spdm_context->connection_info.algorithm.dhe_named_group = 0;
Expand Down
25 changes: 15 additions & 10 deletions library/spdm_responder_lib/libspdm_rsp_challenge_auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,23 +221,28 @@ libspdm_return_t libspdm_get_response_challenge_auth(libspdm_context_t *spdm_con
}
ptr += measurement_summary_hash_size;


opaque_data_size = *response_size - (sizeof(spdm_challenge_auth_response_t) + hash_size +
SPDM_NONCE_SIZE + measurement_summary_hash_size +
sizeof(uint16_t) + signature_size);
opaque_data =
(uint8_t*)response + sizeof(spdm_challenge_auth_response_t) + hash_size + SPDM_NONCE_SIZE +
measurement_summary_hash_size + sizeof(uint16_t);

result = libspdm_challenge_opaque_data(
spdm_context->connection_info.version,
slot_id,
measurement_summary_hash, measurement_summary_hash_size,
opaque_data, &opaque_data_size);
if (!result) {
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
0, response_size, response);
if ((libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) &&
((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) == SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE)) {
opaque_data_size = 0;
} else {
result = libspdm_challenge_opaque_data(
spdm_context->connection_info.version,
slot_id,
measurement_summary_hash, measurement_summary_hash_size,
opaque_data, &opaque_data_size);
if (!result) {
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
0, response_size, response);
}
}

/*write opaque_data_size*/
Expand Down
9 changes: 9 additions & 0 deletions library/spdm_responder_lib/libspdm_rsp_csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ libspdm_return_t libspdm_get_response_csr(libspdm_context_t *spdm_context,
SPDM_ERROR_CODE_INVALID_REQUEST, 0,
response_size, response);
}
if (((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) == SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE)
&& (opaque_data_length != 0)) {
LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "It's %x, baah!",
spdm_context->connection_info.algorithm.other_params_support));
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_INVALID_REQUEST, 0,
response_size, response);
}

if (opaque_data_length >
request_size - sizeof(spdm_get_csr_request_t)) {
Expand Down
11 changes: 9 additions & 2 deletions library/spdm_responder_lib/libspdm_rsp_key_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,19 @@ libspdm_return_t libspdm_get_response_key_exchange(libspdm_context_t *spdm_conte
spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
SPDM_KEY_EXCHANGE, response_size, response);
}
if (spdm_context->connection_info.connection_state <
LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
0, response_size, response);
}
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_MASK) != SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
0, response_size, response);
}
}
if (spdm_context->last_spdm_request_session_id_valid) {
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
Expand Down
35 changes: 21 additions & 14 deletions library/spdm_responder_lib/libspdm_rsp_measurements.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,22 +256,29 @@ libspdm_return_t libspdm_get_response_measurements(libspdm_context_t *spdm_conte
opaque_data =
(uint8_t*)response + sizeof(spdm_measurements_response_t) +
SPDM_NONCE_SIZE + sizeof(uint16_t);
opaque_data_size = meas_opaque_buffer_size - measurements_size;

ret = libspdm_measurement_opaque_data(
spdm_context->connection_info.version,
spdm_context->connection_info.algorithm.measurement_spec,
spdm_context->connection_info.algorithm.measurement_hash_algo,
measurements_index,
spdm_request->header.param1,
opaque_data,
&opaque_data_size);
if ((libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) &&
((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) == SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE)) {
opaque_data_size = 0;
} else {
opaque_data_size = meas_opaque_buffer_size - measurements_size;

if (!ret) {
libspdm_reset_message_m(spdm_context, session_info);
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
0, response_size, response);
ret = libspdm_measurement_opaque_data(
spdm_context->connection_info.version,
spdm_context->connection_info.algorithm.measurement_spec,
spdm_context->connection_info.algorithm.measurement_hash_algo,
measurements_index,
spdm_request->header.param1,
opaque_data,
&opaque_data_size);

if (!ret) {
libspdm_reset_message_m(spdm_context, session_info);
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
0, response_size, response);
}
}

LIBSPDM_ASSERT(opaque_data_size <= (meas_opaque_buffer_size - measurements_size));
Expand Down
8 changes: 8 additions & 0 deletions library/spdm_responder_lib/libspdm_rsp_psk_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ libspdm_return_t libspdm_get_response_psk_exchange(libspdm_context_t *spdm_conte
SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
0, response_size, response);
}
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_MASK) != SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
0, response_size, response);
}
}
if (spdm_context->last_spdm_request_session_id_valid) {
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1284,9 +1284,9 @@ static libspdm_return_t libspdm_requester_negotiate_algorithm_test_receive_messa
spdm_response->header.param1 = 4;
spdm_response->header.param2 = 0;
spdm_response->length = sizeof(libspdm_algorithms_response_spdm11_t);
spdm_response->measurement_specification_sel =
SPDM_MEASUREMENT_SPECIFICATION_DMTF;
spdm_response->other_params_selection = 0;
spdm_response->measurement_specification_sel = SPDM_MEASUREMENT_SPECIFICATION_DMTF;
/* Return illegal value for OpaqueDataFmt. */
spdm_response->other_params_selection = 0x3;
spdm_response->measurement_hash_algo = m_libspdm_use_measurement_hash_algo;
spdm_response->base_asym_sel = m_libspdm_use_asym_algo;
spdm_response->base_hash_sel = m_libspdm_use_hash_algo;
Expand Down Expand Up @@ -1589,8 +1589,7 @@ static libspdm_return_t libspdm_requester_negotiate_algorithm_test_receive_messa
SPDM_MEASUREMENT_SPECIFICATION_DMTF;
/* Two bits set when only one should be set. */
spdm_response->other_params_selection =
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0 |
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1;
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0 | SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1;
spdm_response->measurement_hash_algo =
m_libspdm_use_measurement_hash_algo;
spdm_response->base_asym_sel = m_libspdm_use_asym_algo;
Expand Down Expand Up @@ -2753,7 +2752,7 @@ static void libspdm_test_requester_negotiate_algorithms_error_case34(void **stat
spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP;

status = libspdm_negotiate_algorithms (spdm_context);
assert_int_equal (status, LIBSPDM_STATUS_NEGOTIATION_FAIL);
assert_int_equal (status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
}

/**
Expand Down Expand Up @@ -3010,7 +3009,7 @@ static void libspdm_test_requester_negotiate_algorithms_error_case41(void **stat
libspdm_reset_message_a(spdm_context);

status = libspdm_negotiate_algorithms(spdm_context);
assert_int_equal(status, LIBSPDM_STATUS_NEGOTIATION_FAIL);
assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
}

/**
Expand Down
Loading

0 comments on commit 2aabafa

Please sign in to comment.