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

1.3 CAPABILITIES/ALGORITHMS: Add more capability #2431

Merged
merged 5 commits into from
Nov 21, 2023
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
44 changes: 42 additions & 2 deletions include/industry_standard/spdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,20 @@ typedef struct {
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_11_MASK | \
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP)

/* SPDM GET_CAPABILITIES request flags (1.3) */
#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP (0x00400000 | 0x00800000)
jyao1 marked this conversation as resolved.
Show resolved Hide resolved
#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_NO_SIG 0x00400000
#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_SIG 0x00800000
#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EVENT_CAP 0x02000000
#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP (0x04000000 | 0x08000000)
#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY 0x04000000
#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_NEG 0x08000000
#define SPDM_GET_CAPABILITIES_REQUEST_FLAGS_13_MASK ( \
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_12_MASK | \
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP | \
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EVENT_CAP | \
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP)

/* SPDM GET_CAPABILITIES response flags (1.0) */
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CACHE_CAP 0x00000001
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP 0x00000002
Expand Down Expand Up @@ -247,6 +261,26 @@ typedef struct {
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP | \
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP)

/* SPDM GET_CAPABILITIES response flags (1.3) */
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP (0x00400000 | 0x00800000)
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_NO_SIG 0x00400000
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG 0x00800000
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP 0x01000000
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EVENT_CAP 0x02000000
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP (0x04000000 | 0x08000000)
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_ONLY 0x04000000
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_NEG 0x08000000
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_GET_KEY_PAIR_INFO_CAP 0x10000000
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_KEY_PAIR_INFO_CAP 0x20000000
#define SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_13_MASK ( \
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_12_MASK | \
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP | \
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP | \
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EVENT_CAP | \
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP | \
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_GET_KEY_PAIR_INFO_CAP | \
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_KEY_PAIR_INFO_CAP)

/* SPDM NEGOTIATE_ALGORITHMS request */
typedef struct {
spdm_message_header_t header;
Expand All @@ -255,7 +289,9 @@ typedef struct {
uint16_t length;
uint8_t measurement_specification;
/* other_params_support is added in 1.2.
* BIT[0:3]=opaque_data_format support, BIT[4:7]=reserved*/
* BIT[0:3]=opaque_data_format support
* BIT[4]=ResponderMultiKeyConn, added in 1.3
* BIT[5:7]=reserved*/
uint8_t other_params_support;
uint32_t base_asym_algo;
uint32_t base_hash_algo;
Expand Down Expand Up @@ -353,7 +389,9 @@ typedef struct {
uint16_t length;
uint8_t measurement_specification_sel;
/* other_params_selection is added in 1.2.
* BIT[0:3]=opaque_data_format select, BIT[4:7]=reserved*/
* BIT[0:3]=opaque_data_format select,
* BIT[4]=RequesterMultiKeyConnSel, added in 1.3
* BIT[5:7]=reserved*/
uint8_t other_params_selection;
uint32_t measurement_hash_algo;
uint32_t base_asym_sel;
Expand Down Expand Up @@ -385,6 +423,8 @@ typedef struct {
#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 Multi-Connection Selection (1.3) */
#define SPDM_ALGORITHMS_MULTI_KEY_CONN 0x10

/* SPDM Opaque Data Format 1 (1.2) */
typedef struct {
Expand Down
4 changes: 4 additions & 0 deletions include/internal/libspdm_common_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ typedef struct {
/* Specifies whether the cached negotiated state should be invalidated. (responder only)
* This is a "sticky" bit wherein if it is set to 1 then it cannot be set to 0. */
uint8_t end_session_attributes;

/* multi-key negotiated result */
bool multi_key_conn_req;
bool multi_key_conn_rsp;
} libspdm_connection_info_t;

typedef struct {
Expand Down
2 changes: 2 additions & 0 deletions library/spdm_common_lib/libspdm_com_context_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -2752,6 +2752,8 @@ void libspdm_reset_context(void *spdm_context)
libspdm_zero_mem(&context->encap_context, sizeof(libspdm_encap_context_t));
context->connection_info.local_used_cert_chain_buffer_size = 0;
context->connection_info.local_used_cert_chain_buffer = NULL;
context->connection_info.multi_key_conn_req = false;
context->connection_info.multi_key_conn_rsp = false;
#if LIBSPDM_RESPOND_IF_READY_SUPPORT
context->cache_spdm_request_size = 0;
#endif
Expand Down
4 changes: 2 additions & 2 deletions library/spdm_common_lib/libspdm_com_opaque_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ bool libspdm_process_general_opaque_data_check(libspdm_context_t *spdm_context,
LIBSPDM_ASSERT(data_in_size <= SPDM_MAX_OPAQUE_DATA_SIZE);

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_1) {
if ((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) == SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
/* Check byte alignment */
if ((data_in_size & 3) != 0) {
return false;
Expand Down
41 changes: 36 additions & 5 deletions library/spdm_requester_lib/libspdm_req_get_capabilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t ve
const uint8_t set_cert_cap = (uint8_t)(capabilities_flag >> 19) & 0x01;
const uint8_t csr_cap = (uint8_t)(capabilities_flag >> 20) & 0x01;
const uint8_t cert_install_reset_cap = (uint8_t)(capabilities_flag >> 21) & 0x01;
const uint8_t ep_info_cap = (uint8_t)(capabilities_flag >> 22) & 0x03;
/* const uint8_t mel_cap = (uint8_t)(capabilities_flag >> 24) & 0x01; */
const uint8_t event_cap = (uint8_t)(capabilities_flag >> 25) & 0x01;
const uint8_t multi_key_cap = (uint8_t)(capabilities_flag >> 26) & 0x03;
const uint8_t get_key_pair_info_cap = (uint8_t)(capabilities_flag >> 28) & 0x01;
/* const uint8_t set_key_pair_info_cap = (uint8_t)(capabilities_flag >> 29) & 0x01; */

/* Checks common to all SPDM versions. */

Expand Down Expand Up @@ -65,8 +71,8 @@ static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t ve
return true;
}

/* Checks common to 1.1 and 1.2. */
if ((version == SPDM_MESSAGE_VERSION_11) || (version == SPDM_MESSAGE_VERSION_12)) {
/* Checks common to 1.1 and higher. */
if (version >= SPDM_MESSAGE_VERSION_11) {
/* Illegal to return reserved values. */
if (psk_cap == 3) {
return false;
Expand All @@ -85,6 +91,11 @@ static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t ve
(hbeat_cap == 1) || (key_upd_cap == 1)) {
return false;
}
if (version == SPDM_MESSAGE_VERSION_13) {
steven-bellock marked this conversation as resolved.
Show resolved Hide resolved
if (event_cap == 1) {
return false;
}
}
}
if ((key_ex_cap == 0) && (psk_cap != 0)) {
if (handshake_in_the_clear_cap == 1) {
Expand All @@ -107,6 +118,11 @@ static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t ve
if ((chal_cap == 1) || (key_ex_cap == 1) || (meas_cap == 2) || (mut_auth_cap == 1)) {
return false;
}
if (version == SPDM_MESSAGE_VERSION_13) {
steven-bellock marked this conversation as resolved.
Show resolved Hide resolved
if (ep_info_cap == 2) {
return false;
}
}
}

/* Checks that originate from mutual authentication capabilities. */
Expand All @@ -124,8 +140,8 @@ static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t ve
}
}

/* Checks specific to 1.2. */
if (version == SPDM_MESSAGE_VERSION_12) {
/* Checks common to 1.2 and higher. */
if (version >= SPDM_MESSAGE_VERSION_12) {
if ((cert_cap == 0) && ((alias_cert_cap == 1) || (set_cert_cap == 1))) {
return false;
}
Expand All @@ -137,6 +153,18 @@ static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t ve
}
}

/* Checks specific to 1.3. */
steven-bellock marked this conversation as resolved.
Show resolved Hide resolved
if (version == SPDM_MESSAGE_VERSION_13) {
/* Illegal to return reserved values. */
if ((ep_info_cap == 3) || (multi_key_cap == 3)) {
return false;
}
/* check multi-key */
if ((multi_key_cap != 0) && (get_key_pair_info_cap == 0)) {
return false;
}
}

return true;
}

Expand Down Expand Up @@ -322,9 +350,12 @@ static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_con
} else if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_11) {
spdm_context->connection_info.capability.flags =
spdm_response->flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_11_MASK;
} else {
} else if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_12) {
spdm_context->connection_info.capability.flags =
spdm_response->flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_12_MASK;
} else {
spdm_context->connection_info.capability.flags =
spdm_response->flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_13_MASK;
}

if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
Expand Down
46 changes: 46 additions & 0 deletions library/spdm_requester_lib/libspdm_req_negotiate_algorithms.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,32 @@ static libspdm_return_t libspdm_try_negotiate_algorithms(libspdm_context_t *spdm
spdm_request->other_params_support =
spdm_context->local_context.algorithm.other_params_support;
}
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
switch (spdm_context->connection_info.capability.flags &
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) {
case 0:
spdm_context->connection_info.multi_key_conn_rsp = false;
break;
case SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_ONLY:
spdm_context->connection_info.multi_key_conn_rsp = true;
break;
case SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_NEG:
if ((spdm_context->local_context.algorithm.other_params_support &
SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
spdm_context->connection_info.multi_key_conn_rsp = false;
} else {
spdm_context->connection_info.multi_key_conn_rsp = true;
}
break;
default:
return LIBSPDM_STATUS_INVALID_MSG_FIELD;
}
if (spdm_context->connection_info.multi_key_conn_rsp) {
spdm_request->other_params_support |= SPDM_ALGORITHMS_MULTI_KEY_CONN;
} else {
spdm_request->other_params_support &= ~SPDM_ALGORITHMS_MULTI_KEY_CONN;
}
}
spdm_request->base_asym_algo = spdm_context->local_context.algorithm.base_asym_algo;
spdm_request->base_hash_algo = spdm_context->local_context.algorithm.base_hash_algo;
spdm_request->ext_asym_count = 0;
Expand Down Expand Up @@ -536,6 +562,26 @@ static libspdm_return_t libspdm_try_negotiate_algorithms(libspdm_context_t *spdm
}
}
}

if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
if ((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
if ((spdm_context->local_context.capability.flags &
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) ==
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY) {
status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
goto receive_done;
}
spdm_context->connection_info.multi_key_conn_req = false;
} else {
if ((spdm_context->local_context.capability.flags &
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) == 0) {
status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
goto receive_done;
}
spdm_context->connection_info.multi_key_conn_req = true;
}
}
} else {
spdm_context->connection_info.algorithm.dhe_named_group = 0;
spdm_context->connection_info.algorithm.aead_cipher_suite = 0;
Expand Down
59 changes: 57 additions & 2 deletions library/spdm_responder_lib/libspdm_rsp_algorithms.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,39 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context
spdm_response->other_params_selection = (uint8_t)libspdm_prioritize_algorithm(
other_params_support_priority_table,
LIBSPDM_ARRAY_SIZE(other_params_support_priority_table),
spdm_context->local_context.algorithm.other_params_support,
spdm_context->connection_info.algorithm.other_params_support);
spdm_context->local_context.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK,
spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK);
}

if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
switch (spdm_context->connection_info.capability.flags &
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) {
case 0:
spdm_context->connection_info.multi_key_conn_req = false;
break;
case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY:
spdm_context->connection_info.multi_key_conn_req = true;
break;
case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_NEG:
if ((spdm_context->local_context.algorithm.other_params_support &
SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
spdm_context->connection_info.multi_key_conn_req = false;
} else {
spdm_context->connection_info.multi_key_conn_req = true;
}
break;
default:
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
0, response_size, response);
}
if (spdm_context->connection_info.multi_key_conn_req) {
spdm_response->other_params_selection |= SPDM_ALGORITHMS_MULTI_KEY_CONN;
} else {
spdm_response->other_params_selection &= ~SPDM_ALGORITHMS_MULTI_KEY_CONN;
}
}

spdm_context->connection_info.algorithm.measurement_spec =
Expand Down Expand Up @@ -760,6 +791,30 @@ libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context
}
}
}

if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
if ((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
if ((spdm_context->local_context.capability.flags &
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) ==
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_ONLY) {
return libspdm_generate_error_response(
spdm_context,
SPDM_ERROR_CODE_INVALID_REQUEST, 0,
response_size, response);
}
spdm_context->connection_info.multi_key_conn_rsp = false;
} else {
if ((spdm_context->local_context.capability.flags &
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) == 0) {
return libspdm_generate_error_response(
spdm_context,
SPDM_ERROR_CODE_INVALID_REQUEST, 0,
response_size, response);
}
spdm_context->connection_info.multi_key_conn_rsp = true;
}
}
} else {
spdm_context->connection_info.algorithm.dhe_named_group = 0;
spdm_context->connection_info.algorithm.aead_cipher_suite = 0;
Expand Down
Loading