Skip to content

Commit

Permalink
Add 1.3 DIGEST handling
Browse files Browse the repository at this point in the history
Signed-off-by: Jiewen Yao <[email protected]>
  • Loading branch information
jyao1 committed Nov 29, 2023
1 parent c2e91a9 commit d0260ce
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 9 deletions.
11 changes: 10 additions & 1 deletion include/internal/libspdm_common_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
9 changes: 9 additions & 0 deletions include/library/spdm_common_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down
97 changes: 94 additions & 3 deletions library/spdm_common_lib/libspdm_com_context_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 ||
Expand Down Expand Up @@ -949,27 +1000,67 @@ 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) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
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++;
}
}
digest_size = libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
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;
Expand Down
82 changes: 79 additions & 3 deletions library/spdm_requester_lib/libspdm_req_get_digests.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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)) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down
32 changes: 30 additions & 2 deletions library/spdm_responder_lib/libspdm_rsp_digests.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand All @@ -115,14 +125,32 @@ 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
.local_cert_chain_provision[index] != NULL) {
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(
Expand Down

0 comments on commit d0260ce

Please sign in to comment.