diff --git a/include/internal/libspdm_common_lib.h b/include/internal/libspdm_common_lib.h index 93d2e9cafe4..50de120b002 100644 --- a/include/internal/libspdm_common_lib.h +++ b/include/internal/libspdm_common_lib.h @@ -80,6 +80,10 @@ typedef struct { /* My Certificate */ const void *local_cert_chain_provision[SPDM_MAX_SLOT_COUNT]; size_t local_cert_chain_provision_size[SPDM_MAX_SLOT_COUNT]; + uint8_t local_supported_slot_mask; + spdm_key_pair_id_t local_key_pair_id[SPDM_MAX_SLOT_COUNT]; + spdm_certificate_info_t local_cert_info[SPDM_MAX_SLOT_COUNT]; + spdm_key_usage_bit_mask_t local_key_usage_bit_mask[SPDM_MAX_SLOT_COUNT]; /* My raw public key (slot_id - 0xFF) */ const void *local_public_key_provision; size_t local_public_key_provision_size; @@ -114,9 +118,14 @@ typedef struct { spdm_version_number_t secured_message_version; /* Peer digests buffer */ - uint8_t peer_digest_slot_mask; + uint8_t peer_provisioned_slot_mask; + uint8_t peer_supported_slot_mask; uint8_t peer_total_digest_buffer[LIBSPDM_MAX_HASH_SIZE * SPDM_MAX_SLOT_COUNT]; + spdm_key_pair_id_t peer_key_pair_id[SPDM_MAX_SLOT_COUNT]; + spdm_certificate_info_t peer_cert_info[SPDM_MAX_SLOT_COUNT]; + spdm_key_usage_bit_mask_t peer_key_usage_bit_mask[SPDM_MAX_SLOT_COUNT]; + /* Peer CertificateChain */ libspdm_peer_used_cert_chain_t peer_used_cert_chain[SPDM_MAX_SLOT_COUNT]; uint8_t peer_used_cert_chain_slot_id; diff --git a/include/library/spdm_common_lib.h b/include/library/spdm_common_lib.h index fe184ea1b42..da35a63cd05 100644 --- a/include/library/spdm_common_lib.h +++ b/include/library/spdm_common_lib.h @@ -64,6 +64,10 @@ typedef enum { LIBSPDM_DATA_PEER_PUBLIC_ROOT_CERT, LIBSPDM_DATA_PEER_PUBLIC_KEY, LIBSPDM_DATA_LOCAL_PUBLIC_KEY, + LIBSPDM_DATA_LOCAL_SUPPORTED_SLOT_MASK, + LIBSPDM_DATA_LOCAL_KEY_PAIR_ID, + LIBSPDM_DATA_LOCAL_CERT_INFO, + LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK, LIBSPDM_DATA_BASIC_MUT_AUTH_REQUESTED, LIBSPDM_DATA_MUT_AUTH_REQUESTED, @@ -72,7 +76,12 @@ typedef enum { /* Negotiated result */ LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER, LIBSPDM_DATA_PEER_SLOT_MASK, + LIBSPDM_DATA_PEER_PROVISIONED_SLOT_MASK = LIBSPDM_DATA_PEER_SLOT_MASK, + LIBSPDM_DATA_PEER_SUPPORTED_SLOT_MASK, LIBSPDM_DATA_PEER_TOTAL_DIGEST_BUFFER, + LIBSPDM_DATA_PEER_KEY_PAIR_ID, + LIBSPDM_DATA_PEER_CERT_INFO, + LIBSPDM_DATA_PEER_KEY_USAGE_BIT_MASK, /* SessionData */ LIBSPDM_DATA_SESSION_USE_PSK, diff --git a/library/spdm_common_lib/libspdm_com_context_data.c b/library/spdm_common_lib/libspdm_com_context_data.c index 10c860fa213..f5f66621c69 100644 --- a/library/spdm_common_lib/libspdm_com_context_data.c +++ b/library/spdm_common_lib/libspdm_com_context_data.c @@ -477,6 +477,56 @@ libspdm_return_t libspdm_set_data(void *spdm_context, libspdm_data_type_t data_t context->local_context.local_cert_chain_provision_size[slot_id] = data_size; context->local_context.local_cert_chain_provision[slot_id] = data; break; + case LIBSPDM_DATA_LOCAL_SUPPORTED_SLOT_MASK: + if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + slot_id = parameter->additional_data[0]; + if (data_size != sizeof(uint8_t)) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + context->local_context.local_supported_slot_mask = *(uint8_t *)data; + break; + case LIBSPDM_DATA_LOCAL_KEY_PAIR_ID: + if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + slot_id = parameter->additional_data[0]; + if (slot_id >= SPDM_MAX_SLOT_COUNT) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + if (data_size != sizeof(spdm_key_pair_id_t)) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + context->local_context.local_key_pair_id[slot_id] = *(spdm_key_pair_id_t *)data; + break; + case LIBSPDM_DATA_LOCAL_CERT_INFO: + if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + slot_id = parameter->additional_data[0]; + if (slot_id >= SPDM_MAX_SLOT_COUNT) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + if (data_size != sizeof(spdm_certificate_info_t)) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + context->local_context.local_cert_info[slot_id] = *(spdm_certificate_info_t *)data; + break; + case LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK: + if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + slot_id = parameter->additional_data[0]; + if (slot_id >= SPDM_MAX_SLOT_COUNT) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + if (data_size != sizeof(spdm_key_usage_bit_mask_t)) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + context->local_context.local_key_usage_bit_mask[slot_id] = + libspdm_read_uint16((const uint8_t *)data); + break; case LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER: if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { return LIBSPDM_STATUS_INVALID_PARAMETER; @@ -775,6 +825,7 @@ libspdm_return_t libspdm_get_data(void *spdm_context, libspdm_data_type_t data_t libspdm_session_info_t *session_info; size_t digest_size; size_t digest_count; + uint8_t slot_id; size_t index; if (spdm_context == NULL || data == NULL || data_size == NULL || @@ -949,12 +1000,19 @@ libspdm_return_t libspdm_get_data(void *spdm_context, libspdm_data_type_t data_t target_data_size = sizeof(libspdm_response_state_t); target_data = &context->response_state; break; - case LIBSPDM_DATA_PEER_SLOT_MASK: + case LIBSPDM_DATA_PEER_PROVISIONED_SLOT_MASK: if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { return LIBSPDM_STATUS_INVALID_PARAMETER; } target_data_size = sizeof(uint8_t); - target_data = &context->connection_info.peer_digest_slot_mask; + target_data = &context->connection_info.peer_provisioned_slot_mask; + break; + case LIBSPDM_DATA_PEER_SUPPORTED_SLOT_MASK: + if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + target_data_size = sizeof(uint8_t); + target_data = &context->connection_info.peer_supported_slot_mask; break; case LIBSPDM_DATA_PEER_TOTAL_DIGEST_BUFFER: if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { @@ -962,7 +1020,7 @@ libspdm_return_t libspdm_get_data(void *spdm_context, libspdm_data_type_t data_t } digest_count = 0; for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) { - if (context->connection_info.peer_digest_slot_mask & (1 << index)) { + if (context->connection_info.peer_provisioned_slot_mask & (1 << index)) { digest_count++; } } @@ -970,6 +1028,39 @@ libspdm_return_t libspdm_get_data(void *spdm_context, libspdm_data_type_t data_t target_data_size = digest_size * digest_count; target_data = context->connection_info.peer_total_digest_buffer; break; + case LIBSPDM_DATA_PEER_KEY_PAIR_ID: + if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + slot_id = parameter->additional_data[0]; + if (slot_id >= SPDM_MAX_SLOT_COUNT) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + target_data_size = sizeof(spdm_key_pair_id_t); + target_data = &context->connection_info.peer_key_pair_id[slot_id]; + break; + case LIBSPDM_DATA_PEER_CERT_INFO: + if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + slot_id = parameter->additional_data[0]; + if (slot_id >= SPDM_MAX_SLOT_COUNT) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + target_data_size = sizeof(spdm_certificate_info_t); + target_data = &context->connection_info.peer_cert_info[slot_id]; + break; + case LIBSPDM_DATA_PEER_KEY_USAGE_BIT_MASK: + if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + slot_id = parameter->additional_data[0]; + if (slot_id >= SPDM_MAX_SLOT_COUNT) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + target_data_size = sizeof(spdm_key_usage_bit_mask_t); + target_data = &context->connection_info.peer_key_usage_bit_mask[slot_id]; + break; case LIBSPDM_DATA_SESSION_USE_PSK: target_data_size = sizeof(bool); target_data = &session_info->use_psk; diff --git a/library/spdm_requester_lib/libspdm_req_get_digests.c b/library/spdm_requester_lib/libspdm_req_get_digests.c index c8b37387c15..4ca6b3e5757 100644 --- a/library/spdm_requester_lib/libspdm_req_get_digests.c +++ b/library/spdm_requester_lib/libspdm_req_get_digests.c @@ -12,6 +12,9 @@ typedef struct { spdm_message_header_t header; uint8_t digest[LIBSPDM_MAX_HASH_SIZE * SPDM_MAX_SLOT_COUNT]; + spdm_key_pair_id_t key_pair_id[SPDM_MAX_SLOT_COUNT]; + spdm_certificate_info_t cert_info[SPDM_MAX_SLOT_COUNT]; + spdm_key_usage_bit_mask_t key_usage_bit_mask[SPDM_MAX_SLOT_COUNT]; } libspdm_digests_response_max_t; #pragma pack() @@ -59,6 +62,11 @@ static libspdm_return_t libspdm_try_get_digest(libspdm_context_t *spdm_context, size_t transport_header_size; libspdm_session_info_t *session_info; libspdm_session_state_t session_state; + size_t additional_size; + spdm_key_pair_id_t *key_pair_id; + spdm_certificate_info_t *cert_info; + spdm_key_usage_bit_mask_t *key_usage_bit_mask; + size_t slot_index; /* -=[Verify State Phase]=- */ if (!libspdm_is_capabilities_flag_supported( @@ -159,6 +167,18 @@ static libspdm_return_t libspdm_try_get_digest(libspdm_context_t *spdm_context, *slot_mask = spdm_response->header.param2; } + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "provisioned_slot_mask - 0x%02x\n", + spdm_response->header.param2)); + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "supported_slot_mask - 0x%02x\n", + spdm_response->header.param1)); + if ((spdm_response->header.param1 & spdm_response->header.param2) != + spdm_response->header.param2) { + status = LIBSPDM_STATUS_INVALID_MSG_FIELD; + goto receive_done; + } + } + digest_count = 0; for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) { if (spdm_response->header.param2 & (1 << index)) { @@ -170,11 +190,19 @@ static libspdm_return_t libspdm_try_get_digest(libspdm_context_t *spdm_context, goto receive_done; } - if (spdm_response_size < sizeof(spdm_digest_response_t) + digest_count * digest_size) { + additional_size = 0; + if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) && + spdm_context->connection_info.multi_key_conn_rsp) { + additional_size = sizeof(spdm_key_pair_id_t) + sizeof(spdm_certificate_info_t) + + sizeof(spdm_key_usage_bit_mask_t); + } + if (spdm_response_size < + sizeof(spdm_digest_response_t) + digest_count * (digest_size + additional_size)) { status = LIBSPDM_STATUS_INVALID_MSG_SIZE; goto receive_done; } - spdm_response_size = sizeof(spdm_digest_response_t) + digest_count * digest_size; + spdm_response_size = + sizeof(spdm_digest_response_t) + digest_count * (digest_size + additional_size); /* -=[Process Response Phase]=- */ if (session_id == NULL) { @@ -196,22 +224,70 @@ static libspdm_return_t libspdm_try_get_digest(libspdm_context_t *spdm_context, } } + key_pair_id = + (spdm_key_pair_id_t *)((uint8_t *)spdm_response->digest + digest_size * digest_count); + cert_info = + (spdm_certificate_info_t *)((uint8_t *)key_pair_id + sizeof(spdm_key_pair_id_t) * + digest_count); + key_usage_bit_mask = + (spdm_key_usage_bit_mask_t *)((uint8_t *)cert_info + sizeof(spdm_certificate_info_t) * + digest_count); for (index = 0; index < digest_count; index++) { LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "digest (0x%x) - ", index)); LIBSPDM_INTERNAL_DUMP_DATA(&spdm_response->digest[digest_size * index], digest_size); LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n")); } + if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) && + spdm_context->connection_info.multi_key_conn_rsp) { + for (index = 0; index < digest_count; index++) { + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "key_pair_id (0x%x) - 0x%02x\n", index, + key_pair_id[index])); + } + for (index = 0; index < digest_count; index++) { + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "cert_info (0x%x) - 0x%02x\n", index, + cert_info[index])); + } + for (index = 0; index < digest_count; index++) { + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "key_usage_bit_mask (0x%x) - 0x%04x\n", index, + key_usage_bit_mask[index])); + } + } if (total_digest_buffer != NULL) { libspdm_copy_mem(total_digest_buffer, digest_size * digest_count, spdm_response->digest, digest_size * digest_count); } - spdm_context->connection_info.peer_digest_slot_mask = spdm_response->header.param2; + spdm_context->connection_info.peer_provisioned_slot_mask = spdm_response->header.param2; + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + spdm_context->connection_info.peer_supported_slot_mask = spdm_response->header.param1; + } else { + spdm_context->connection_info.peer_supported_slot_mask = spdm_response->header.param2; + } libspdm_copy_mem( spdm_context->connection_info.peer_total_digest_buffer, sizeof(spdm_context->connection_info.peer_total_digest_buffer), spdm_response->digest, digest_size * digest_count); + libspdm_zero_mem(spdm_context->connection_info.peer_key_pair_id, + sizeof(spdm_context->connection_info.peer_key_pair_id)); + libspdm_zero_mem(spdm_context->connection_info.peer_cert_info, + sizeof(spdm_context->connection_info.peer_cert_info)); + libspdm_zero_mem(spdm_context->connection_info.peer_key_usage_bit_mask, + sizeof(spdm_context->connection_info.peer_key_usage_bit_mask)); + if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) && + spdm_context->connection_info.multi_key_conn_rsp) { + slot_index = 0; + for (index = 0; index < digest_count; index++) { + if (spdm_response->header.param2 & (1 << index)) { + spdm_context->connection_info.peer_key_pair_id[index] = key_pair_id[slot_index]; + spdm_context->connection_info.peer_cert_info[index] = + cert_info[slot_index] & SPDM_CERTIFICATE_INFO_CERT_MODEL_MASK; + spdm_context->connection_info.peer_key_usage_bit_mask[index] = + key_usage_bit_mask[slot_index]; + slot_index++; + } + } + } /* -=[Update State Phase]=- */ if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS) { diff --git a/library/spdm_responder_lib/libspdm_rsp_digests.c b/library/spdm_responder_lib/libspdm_rsp_digests.c index eb086bb9c5e..62efb249604 100644 --- a/library/spdm_responder_lib/libspdm_rsp_digests.c +++ b/library/spdm_responder_lib/libspdm_rsp_digests.c @@ -27,6 +27,10 @@ libspdm_return_t libspdm_get_response_digests(libspdm_context_t *spdm_context, s uint8_t slot_count; /*populated slot index*/ uint8_t slot_index; + size_t additional_size; + spdm_key_pair_id_t *key_pair_id; + spdm_certificate_info_t *cert_info; + spdm_key_usage_bit_mask_t *key_usage_bit_mask; spdm_request = request; @@ -104,9 +108,15 @@ libspdm_return_t libspdm_get_response_digests(libspdm_context_t *spdm_context, s spdm_context->connection_info.algorithm.base_hash_algo); slot_count = libspdm_get_cert_slot_count(spdm_context); + additional_size = 0; + if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) && + spdm_context->connection_info.multi_key_conn_rsp) { + additional_size = sizeof(spdm_key_pair_id_t) + sizeof(spdm_certificate_info_t) + + sizeof(spdm_key_usage_bit_mask_t); + } LIBSPDM_ASSERT(*response_size >= - sizeof(spdm_digest_response_t) + hash_size * slot_count); - *response_size = sizeof(spdm_digest_response_t) + hash_size * slot_count; + sizeof(spdm_digest_response_t) + (hash_size + additional_size) * slot_count); + *response_size = sizeof(spdm_digest_response_t) + (hash_size + additional_size) * slot_count; libspdm_zero_mem(response, *response_size); spdm_response = response; @@ -115,7 +125,18 @@ libspdm_return_t libspdm_get_response_digests(libspdm_context_t *spdm_context, s spdm_response->header.param1 = 0; spdm_response->header.param2 = 0; + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + spdm_response->header.param1 = spdm_context->local_context.local_supported_slot_mask; + } + digest = (void *)(spdm_response + 1); + key_pair_id = (spdm_key_pair_id_t *)((uint8_t *)digest + hash_size * slot_count); + cert_info = (spdm_certificate_info_t *)((uint8_t *)key_pair_id + + sizeof(spdm_key_pair_id_t) * slot_count); + key_usage_bit_mask = (spdm_key_usage_bit_mask_t *)((uint8_t *)cert_info + + sizeof(spdm_certificate_info_t) * + slot_count); + slot_index = 0; for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) { if (spdm_context->local_context @@ -123,6 +144,13 @@ libspdm_return_t libspdm_get_response_digests(libspdm_context_t *spdm_context, s spdm_response->header.param2 |= (1 << index); result = libspdm_generate_cert_chain_hash(spdm_context, index, &digest[hash_size * slot_index]); + if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) && + spdm_context->connection_info.multi_key_conn_rsp) { + key_pair_id[slot_index] = spdm_context->local_context.local_key_pair_id[index]; + cert_info[slot_index] = spdm_context->local_context.local_cert_info[index]; + key_usage_bit_mask[slot_index] = + spdm_context->local_context.local_key_usage_bit_mask[index]; + } slot_index++; if (!result) { return libspdm_generate_error_response(