Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check key exchange MAC_CAP when message is sent #2933

Merged
merged 1 commit into from
Dec 20, 2024
Merged
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
16 changes: 8 additions & 8 deletions library/spdm_requester_lib/libspdm_req_get_capabilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,7 @@ static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t ve
}

/* Checks that originate from key exchange capabilities. */
if ((key_ex_cap == 1) || (psk_cap != 0)) {
/* While clearing MAC_CAP and setting ENCRYPT_CAP is legal according to DSP0274, libspdm
* also implements DSP0277 secure messages, which requires at least MAC_CAP to be set.
*/
if (mac_cap == 0) {
return false;
}
} else {
if ((key_ex_cap == 0) && (psk_cap == 0)) {
if ((mac_cap == 1) || (encrypt_cap == 1) || (handshake_in_the_clear_cap == 1) ||
(hbeat_cap == 1) || (key_upd_cap == 1)) {
return false;
Expand Down Expand Up @@ -172,6 +165,13 @@ static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t ve
}
}

/* Checks that are deferred to when a message is sent.
*
* If the Responder supports key exchange then MAC_CAP must be set. In addition, if the
* negotiated SPDM version is greater than 1.1 then the negotiated opaque data format must be
* OpaqueDataFmt1.
*/

return true;
}

Expand Down
12 changes: 12 additions & 0 deletions library/spdm_requester_lib/libspdm_req_key_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,21 @@ static libspdm_return_t libspdm_try_send_receive_key_exchange(
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

/* While clearing MAC_CAP and setting ENCRYPT_CAP is legal according to DSP0274, libspdm
* also implements DSP0277 secure messages, which requires at least MAC_CAP to be set.
*/
if (!libspdm_is_capabilities_flag_supported(
spdm_context, true,
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

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) {
Expand Down
11 changes: 11 additions & 0 deletions library/spdm_requester_lib/libspdm_req_psk_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,17 @@ static libspdm_return_t libspdm_try_send_receive_psk_exchange(
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

/* While clearing MAC_CAP and setting ENCRYPT_CAP is legal according to DSP0274, libspdm
* also implements DSP0277 secure messages, which requires at least MAC_CAP to be set.
*/
if (!libspdm_is_capabilities_flag_supported(
spdm_context, true,
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
}
Expand Down
16 changes: 8 additions & 8 deletions library/spdm_responder_lib/libspdm_rsp_capabilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,7 @@ static bool libspdm_check_request_flag_compatibility(uint32_t capabilities_flag,
}

/* Checks that originate from key exchange capabilities. */
if ((key_ex_cap == 1) || (psk_cap == 1)) {
/* While clearing MAC_CAP and setting ENCRYPT_CAP is legal according to DSP0274, libspdm
* also implements DSP0277 secure messages, which requires at least MAC_CAP to be set.
*/
if (mac_cap == 0) {
return false;
}
} else {
if ((key_ex_cap == 0) && (psk_cap == 0)) {
if ((mac_cap == 1) || (encrypt_cap == 1) || (handshake_in_the_clear_cap == 1) ||
(hbeat_cap == 1) || (key_upd_cap == 1)) {
return false;
Expand Down Expand Up @@ -144,6 +137,13 @@ static bool libspdm_check_request_flag_compatibility(uint32_t capabilities_flag,
}
}

/* Checks that are deferred to when a message is received.
*
* If the Requester supports key exchange then MAC_CAP must be set. In addition, if the
* negotiated SPDM version is greater than 1.1 then the negotiated opaque data format must be
* OpaqueDataFmt1.
*/

return true;
}

Expand Down
13 changes: 13 additions & 0 deletions library/spdm_responder_lib/libspdm_rsp_key_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,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);
}

/* While clearing MAC_CAP and setting ENCRYPT_CAP is legal according to DSP0274, libspdm
* also implements DSP0277 secure messages, which requires at least MAC_CAP to be set.
*/
if (!libspdm_is_capabilities_flag_supported(
spdm_context, false,
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
SPDM_KEY_EXCHANGE, response_size, response);
}

if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
Expand Down
13 changes: 13 additions & 0 deletions library/spdm_responder_lib/libspdm_rsp_psk_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,19 @@ libspdm_return_t libspdm_get_response_psk_exchange(libspdm_context_t *spdm_conte
spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
SPDM_PSK_EXCHANGE, response_size, response);
}

/* While clearing MAC_CAP and setting ENCRYPT_CAP is legal according to DSP0274, libspdm
* also implements DSP0277 secure messages, which requires at least MAC_CAP to be set.
*/
if (!libspdm_is_capabilities_flag_supported(
spdm_context, false,
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
SPDM_KEY_EXCHANGE, response_size, response);
}

if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
Expand Down
186 changes: 4 additions & 182 deletions unit_test/test_spdm_requester/error_test/get_capabilities_err.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,93 +592,13 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
}
return LIBSPDM_STATUS_SUCCESS;

case 0x14: {
spdm_capabilities_response_t *spdm_response;
size_t spdm_response_size;
size_t transport_header_size;

spdm_response_size = sizeof(spdm_capabilities_response_t);
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
spdm_response = (void *)((uint8_t *)*response + transport_header_size);

libspdm_zero_mem(spdm_response, spdm_response_size);
spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
spdm_response->header.request_response_code = SPDM_CAPABILITIES;
spdm_response->header.param1 = 0;
spdm_response->header.param2 = 0;
spdm_response->ct_exponent = 0;
spdm_response->flags =
LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11 &
(0xFFFFFFFF ^
(SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP |
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP |
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP));

libspdm_transport_test_encode_message(spdm_context, NULL, false,
false, spdm_response_size,
spdm_response,
response_size, response);
}
case 0x14:
return LIBSPDM_STATUS_SUCCESS;

case 0x15: {
spdm_capabilities_response_t *spdm_response;
size_t spdm_response_size;
size_t transport_header_size;

spdm_response_size = sizeof(spdm_capabilities_response_t);
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
spdm_response = (void *)((uint8_t *)*response + transport_header_size);

libspdm_zero_mem(spdm_response, spdm_response_size);
spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
spdm_response->header.request_response_code = SPDM_CAPABILITIES;
spdm_response->header.param1 = 0;
spdm_response->header.param2 = 0;
spdm_response->ct_exponent = 0;
spdm_response->flags =
LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11 &
(0xFFFFFFFF ^
(SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP |
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP |
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP |
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP));

libspdm_transport_test_encode_message(spdm_context, NULL, false,
false, spdm_response_size,
spdm_response,
response_size, response);
}
case 0x15:
return LIBSPDM_STATUS_SUCCESS;

case 0x16: {
spdm_capabilities_response_t *spdm_response;
size_t spdm_response_size;
size_t transport_header_size;

spdm_response_size = sizeof(spdm_capabilities_response_t);
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
spdm_response = (void *)((uint8_t *)*response + transport_header_size);

libspdm_zero_mem(spdm_response, spdm_response_size);
spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
spdm_response->header.request_response_code = SPDM_CAPABILITIES;
spdm_response->header.param1 = 0;
spdm_response->header.param2 = 0;
spdm_response->ct_exponent = 0;
spdm_response->flags =
LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11 &
(0xFFFFFFFF ^
(SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP |
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP |
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP |
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP));

libspdm_transport_test_encode_message(spdm_context, NULL, false,
false, spdm_response_size,
spdm_response,
response_size, response);
}
case 0x16:
return LIBSPDM_STATUS_SUCCESS;

case 0x17: {
Expand Down Expand Up @@ -735,33 +655,7 @@ static libspdm_return_t libspdm_requester_get_capabilities_test_receive_message(
}
return LIBSPDM_STATUS_SUCCESS;

case 0x19: {
spdm_capabilities_response_t *spdm_response;
size_t spdm_response_size;
size_t transport_header_size;

spdm_response_size = sizeof(spdm_capabilities_response_t);
transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
spdm_response = (void *)((uint8_t *)*response + transport_header_size);

libspdm_zero_mem(spdm_response, spdm_response_size);
spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
spdm_response->header.request_response_code = SPDM_CAPABILITIES;
spdm_response->header.param1 = 0;
spdm_response->header.param2 = 0;
spdm_response->ct_exponent = 0;
spdm_response->flags =
LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11 &
(0xFFFFFFFF ^
(SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP |
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP |
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP));

libspdm_transport_test_encode_message(spdm_context, NULL, false,
false, spdm_response_size,
spdm_response,
response_size, response);
}
case 0x19:
return LIBSPDM_STATUS_SUCCESS;

case 0x1a: {
Expand Down Expand Up @@ -1500,68 +1394,14 @@ static void libspdm_test_requester_get_capabilities_err_case19(void **state)

static void libspdm_test_requester_get_capabilities_err_case20(void **state)
{
libspdm_return_t status;
libspdm_test_context_t *spdm_test_context;
libspdm_context_t *spdm_context;

spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 0x14;
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
SPDM_VERSION_NUMBER_SHIFT_BIT;
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION;
libspdm_reset_message_a(spdm_context);

spdm_context->local_context.capability.ct_exponent = 0;
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG_VERSION_11;
status = libspdm_get_capabilities(spdm_context);
assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
/*assert_int_equal (spdm_context->connection_info.capability.ct_exponent, 0);
* assert_int_equal (spdm_context->connection_info.capability.flags, LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11 & (0xFFFFFFFF^(SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)));*/
}

static void libspdm_test_requester_get_capabilities_err_case21(void **state)
{
libspdm_return_t status;
libspdm_test_context_t *spdm_test_context;
libspdm_context_t *spdm_context;

spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 0x15;
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
SPDM_VERSION_NUMBER_SHIFT_BIT;
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION;
libspdm_reset_message_a(spdm_context);

spdm_context->local_context.capability.ct_exponent = 0;
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG_VERSION_11;
status = libspdm_get_capabilities(spdm_context);
assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
/*assert_int_equal (spdm_context->connection_info.capability.ct_exponent, 0);
* assert_int_equal (spdm_context->connection_info.capability.flags, LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11 & (0xFFFFFFFF^(SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)));*/
}

static void libspdm_test_requester_get_capabilities_err_case22(void **state)
{
libspdm_return_t status;
libspdm_test_context_t *spdm_test_context;
libspdm_context_t *spdm_context;

spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 0x16;
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
SPDM_VERSION_NUMBER_SHIFT_BIT;
spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_VERSION;
libspdm_reset_message_a(spdm_context);

spdm_context->local_context.capability.ct_exponent = 0;
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG_VERSION_11;
status = libspdm_get_capabilities(spdm_context);
assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
/*assert_int_equal (spdm_context->connection_info.capability.ct_exponent, 0);
* assert_int_equal (spdm_context->connection_info.capability.flags, LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11 & (0xFFFFFFFF^(SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)));*/
}

static void libspdm_test_requester_get_capabilities_err_case23(void **state)
Expand Down Expand Up @@ -1610,24 +1450,6 @@ static void libspdm_test_requester_get_capabilities_err_case24(void **state)

static void libspdm_test_requester_get_capabilities_err_case25(void **state)
{
libspdm_return_t status;
libspdm_test_context_t *spdm_test_context;
libspdm_context_t *spdm_context;

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_AFTER_VERSION;
libspdm_reset_message_a(spdm_context);

spdm_context->local_context.capability.ct_exponent = 0;
spdm_context->local_context.capability.flags = LIBSPDM_DEFAULT_CAPABILITY_FLAG_VERSION_11;
status = libspdm_get_capabilities(spdm_context);
assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
/*assert_int_equal (spdm_context->connection_info.capability.ct_exponent, 0);
* assert_int_equal (spdm_context->connection_info.capability.flags, LIBSPDM_DEFAULT_CAPABILITY_RESPONSE_FLAG_VERSION_11 & (0xFFFFFFFF^(SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)));*/
}

static void libspdm_test_requester_get_capabilities_err_case26(void **state)
Expand Down
Loading
Loading