Skip to content
Open
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
1 change: 1 addition & 0 deletions include/industry_standard/spdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
/* Encompasses SPDM specification versions 1.0, 1.1, 1.2, 1.3, 1.4 */
#define SPDM_MAX_VERSION_COUNT 5
#define SPDM_MAX_SLOT_COUNT 8
#define SPDM_MAX_BANK_COUNT 240
#define SPDM_MAX_OPAQUE_DATA_SIZE 1024
#define SPDM_MAX_CSR_TRACKING_TAG 7
/* MeasurementRecordLength is 3 bytes. */
Expand Down
13 changes: 8 additions & 5 deletions include/internal/libspdm_common_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ typedef struct {
libspdm_secured_message_version_t secured_message_version;

/* My Certificate */
const void *local_cert_chain_provision[SPDM_MAX_SLOT_COUNT];
size_t local_cert_chain_provision_size[SPDM_MAX_SLOT_COUNT];
const void *local_cert_chain_provision[LIBSPDM_MAX_BANK_COUNT][SPDM_MAX_SLOT_COUNT];
size_t local_cert_chain_provision_size[LIBSPDM_MAX_BANK_COUNT][SPDM_MAX_SLOT_COUNT];
uint8_t local_supported_slot_mask;
uint8_t cert_slot_reset_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];
spdm_key_pair_id_t local_key_pair_id[LIBSPDM_MAX_BANK_COUNT][SPDM_MAX_SLOT_COUNT];
spdm_certificate_info_t local_cert_info[LIBSPDM_MAX_BANK_COUNT][SPDM_MAX_SLOT_COUNT];
spdm_key_usage_bit_mask_t local_key_usage_bit_mask[LIBSPDM_MAX_BANK_COUNT][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 @@ -148,6 +148,9 @@ typedef struct {
/* Peer CertificateChain */
libspdm_peer_used_cert_chain_t peer_used_cert_chain[SPDM_MAX_SLOT_COUNT];

/* The local certificate bank to use */
uint8_t current_bank;

/* 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;
Expand Down
1 change: 1 addition & 0 deletions include/library/spdm_common_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ typedef enum {
LIBSPDM_DATA_LOCAL_KEY_PAIR_ID,
LIBSPDM_DATA_LOCAL_CERT_INFO,
LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK,
LIBSPDM_DATA_LOCAL_CURRENT_BANK,

LIBSPDM_DATA_MUT_AUTH_REQUESTED,
LIBSPDM_DATA_HEARTBEAT_PERIOD,
Expand Down
8 changes: 8 additions & 0 deletions include/library/spdm_lib_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@
#define LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP 1
#endif

/* SPDM 1.4 capabilities. */
#ifndef LIBSPDM_MAX_BANK_COUNT
/* We support up to 240 (SPDM_MAX_BANK_COUNT) banks, deafult to 2 as that seems
* to be a reasonable starting point.
*/
#define LIBSPDM_MAX_BANK_COUNT 2
#endif

/* Includes SPDM 1.3 features for CSR messages. If enabled then LIBSPDM_ENABLE_CAPABILITY_CSR_CAP
* must also be enabled.
*/
Expand Down
37 changes: 28 additions & 9 deletions library/spdm_common_lib/libspdm_com_context_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ libspdm_return_t libspdm_set_data(void *spdm_context, libspdm_data_type_t data_t
uint8_t mut_auth_requested;
uint8_t root_cert_index;
uint16_t data16;
uint8_t data8;
#if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) && LIBSPDM_CERT_PARSE_SUPPORT
bool status;
const uint8_t *cert_buffer;
Expand Down Expand Up @@ -523,8 +524,22 @@ libspdm_return_t libspdm_set_data(void *spdm_context, libspdm_data_type_t data_t
if (slot_id >= SPDM_MAX_SLOT_COUNT) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
context->local_context.local_cert_chain_provision_size[slot_id] = data_size;
context->local_context.local_cert_chain_provision[slot_id] = data;
context->local_context.local_cert_chain_provision_size[context->connection_info.current_bank][slot_id] =
data_size;
context->local_context.local_cert_chain_provision[context->connection_info.current_bank][slot_id] = data;
break;
case LIBSPDM_DATA_LOCAL_CURRENT_BANK:
if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
if (data_size != sizeof(uint8_t)) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
data8 = *(const uint8_t *)data;
if (data8 >= LIBSPDM_MAX_BANK_COUNT || data8 >= SPDM_MAX_BANK_COUNT) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
context->connection_info.current_bank = data8;
break;
case LIBSPDM_DATA_LOCAL_SUPPORTED_SLOT_MASK:
if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
Expand All @@ -546,7 +561,8 @@ libspdm_return_t libspdm_set_data(void *spdm_context, libspdm_data_type_t data_t
if (data_size != sizeof(spdm_key_pair_id_t)) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
context->local_context.local_key_pair_id[slot_id] = *(const spdm_key_pair_id_t *)data;
context->local_context.local_key_pair_id[context->connection_info.current_bank][slot_id] =
*(const spdm_key_pair_id_t *)data;
break;
case LIBSPDM_DATA_LOCAL_CERT_INFO:
if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
Expand All @@ -559,7 +575,8 @@ libspdm_return_t libspdm_set_data(void *spdm_context, libspdm_data_type_t data_t
if (data_size != sizeof(spdm_certificate_info_t)) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
context->local_context.local_cert_info[slot_id] = *(const spdm_certificate_info_t *)data;
context->local_context.local_cert_info[context->connection_info.current_bank][slot_id] =
*(const spdm_certificate_info_t *)data;
break;
case LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK:
if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
Expand All @@ -572,7 +589,7 @@ libspdm_return_t libspdm_set_data(void *spdm_context, libspdm_data_type_t data_t
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] =
context->local_context.local_key_usage_bit_mask[context->connection_info.current_bank][slot_id] =
libspdm_read_uint16((const uint8_t *)data);
break;
case LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER:
Expand Down Expand Up @@ -1222,15 +1239,17 @@ bool libspdm_check_context (void *spdm_context)
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP) != 0) &&
(context->local_context.capability.max_spdm_msg_size != 0)) {
for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
if ((context->local_context.local_cert_chain_provision_size[index] != 0) &&
(context->local_context.local_cert_chain_provision_size[index] +
if ((context->local_context.local_cert_chain_provision_size[context->connection_info.current_bank][index] !=
0) &&
(context->local_context.local_cert_chain_provision_size[context->connection_info.current_bank][index] +
sizeof(spdm_certificate_response_t) >
context->local_context.capability.max_spdm_msg_size)) {
LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
"max_spdm_msg_size (%d) must be greater than or "
"equal to local_cert_chain_provision_size[%zu] (%zu).\n",
"equal to local_cert_chain_provision_size[context->connection_info.current_bank][%zu] (%zu).\n",
context->local_context.capability.max_spdm_msg_size, index,
context->local_context.local_cert_chain_provision_size[index]));
context->local_context.local_cert_chain_provision_size[context->connection_info.
current_bank][index]));
return false;
}
}
Expand Down
24 changes: 15 additions & 9 deletions library/spdm_common_lib/libspdm_com_crypto_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ uint8_t libspdm_slot_id_to_key_pair_id (
}
}
LIBSPDM_ASSERT(slot_id < SPDM_MAX_SLOT_COUNT);
return context->local_context.local_key_pair_id[slot_id];
return context->local_context.local_key_pair_id[context->connection_info.current_bank][slot_id];
}

#if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
Expand Down Expand Up @@ -73,11 +73,14 @@ void libspdm_get_local_cert_chain_buffer(void *spdm_context,

context = spdm_context;

LIBSPDM_ASSERT(context->local_context.local_cert_chain_provision[slot_id] != NULL);
LIBSPDM_ASSERT(context->local_context.local_cert_chain_provision_size != 0);
LIBSPDM_ASSERT(context->local_context.local_cert_chain_provision[context->connection_info.current_bank][slot_id] !=
NULL);
LIBSPDM_ASSERT(context->local_context.local_cert_chain_provision_size[context->connection_info.current_bank] != 0);

*cert_chain_buffer = context->local_context.local_cert_chain_provision[slot_id];
*cert_chain_buffer_size = context->local_context.local_cert_chain_provision_size[slot_id];
*cert_chain_buffer =
context->local_context.local_cert_chain_provision[context->connection_info.current_bank][slot_id];
*cert_chain_buffer_size =
context->local_context.local_cert_chain_provision_size[context->connection_info.current_bank][slot_id];
}

bool libspdm_get_local_cert_chain_data(void *spdm_context,
Expand Down Expand Up @@ -591,8 +594,9 @@ bool libspdm_generate_cert_chain_hash(libspdm_context_t *spdm_context,
LIBSPDM_ASSERT(slot_id < SPDM_MAX_SLOT_COUNT);
return libspdm_hash_all(
spdm_context->connection_info.algorithm.base_hash_algo,
spdm_context->local_context.local_cert_chain_provision[slot_id],
spdm_context->local_context.local_cert_chain_provision_size[slot_id], hash);
spdm_context->local_context.local_cert_chain_provision[spdm_context->connection_info.current_bank][slot_id],
spdm_context->local_context.local_cert_chain_provision_size[spdm_context->connection_info.current_bank][slot_id],
hash);
}

bool libspdm_generate_public_key_hash(libspdm_context_t *spdm_context,
Expand All @@ -611,7 +615,8 @@ uint8_t libspdm_get_cert_slot_mask(libspdm_context_t *spdm_context)

slot_mask = 0;
for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
if (spdm_context->local_context.local_cert_chain_provision[index] != NULL) {
if (spdm_context->local_context.local_cert_chain_provision[spdm_context->connection_info.current_bank][index] !=
NULL) {
slot_mask |= (1 << index);
}
}
Expand All @@ -626,7 +631,8 @@ uint8_t libspdm_get_cert_slot_count(libspdm_context_t *spdm_context)

slot_count = 0;
for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
if (spdm_context->local_context.local_cert_chain_provision[index] != NULL) {
if (spdm_context->local_context.local_cert_chain_provision[spdm_context->connection_info.current_bank][index] !=
NULL) {
slot_count++;
}
}
Expand Down
10 changes: 6 additions & 4 deletions library/spdm_requester_lib/libspdm_req_encap_certificate.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,14 @@ libspdm_return_t libspdm_get_encap_response_certificate(void *spdm_context,
response_size, response);
}

if (context->local_context.local_cert_chain_provision[slot_id] == NULL) {
if (context->local_context.local_cert_chain_provision[context->connection_info.current_bank][slot_id] == NULL) {
return libspdm_generate_encap_error_response(
context, SPDM_ERROR_CODE_UNSPECIFIED,
0, response_size, response);
}

cert_chain_size = context->local_context.local_cert_chain_provision_size[slot_id];
cert_chain_size =
context->local_context.local_cert_chain_provision_size[context->connection_info.current_bank][slot_id];

if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) &&
(!use_large_cert_chain) && (cert_chain_size > SPDM_MAX_CERTIFICATE_CHAIN_SIZE)) {
Expand Down Expand Up @@ -160,7 +161,8 @@ libspdm_return_t libspdm_get_encap_response_certificate(void *spdm_context,
spdm_response->header.param2 = 0;
if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
context->connection_info.multi_key_conn_req) {
spdm_response->header.param2 = context->local_context.local_cert_info[slot_id];
spdm_response->header.param2 =
context->local_context.local_cert_info[context->connection_info.current_bank][slot_id];
}
if (use_large_cert_chain) {
spdm_response->header.param1 |= SPDM_CERTIFICATE_RESPONSE_LARGE_CERT_CHAIN;
Expand All @@ -179,7 +181,7 @@ libspdm_return_t libspdm_get_encap_response_certificate(void *spdm_context,
libspdm_copy_mem((uint8_t *)spdm_response + rsp_msg_header_size,
response_capacity - rsp_msg_header_size,
(const uint8_t *)context->local_context
.local_cert_chain_provision[slot_id] + offset, length);
.local_cert_chain_provision[context->connection_info.current_bank][slot_id] + offset, length);

/* Cache*/

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright Notice:
* Copyright 2021-2025 DMTF. All rights reserved.
* Copyright 2021-2026 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

Expand Down Expand Up @@ -86,7 +86,7 @@ libspdm_return_t libspdm_get_encap_response_challenge_auth(

if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
context->connection_info.multi_key_conn_req && (slot_id != 0xFF)) {
if ((context->local_context.local_key_usage_bit_mask[slot_id] &
if ((context->local_context.local_key_usage_bit_mask[context->connection_info.current_bank][slot_id] &
SPDM_KEY_USAGE_BIT_MASK_CHALLENGE_USE) == 0) {
return libspdm_generate_encap_error_response(
context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
Expand Down
10 changes: 6 additions & 4 deletions library/spdm_requester_lib/libspdm_req_encap_digests.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,16 +101,18 @@ libspdm_return_t libspdm_get_encap_response_digest(void *spdm_context,
slot_index = 0;
for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
if (context->local_context
.local_cert_chain_provision[index] != NULL) {
.local_cert_chain_provision[context->connection_info.current_bank][index] != NULL) {
spdm_response->header.param2 |= (1 << index);
result = libspdm_generate_cert_chain_hash(context, index,
&digest[hash_size * slot_index]);
if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
context->connection_info.multi_key_conn_req) {
key_pair_id[slot_index] = context->local_context.local_key_pair_id[index];
cert_info[slot_index] = context->local_context.local_cert_info[index];
key_pair_id[slot_index] =
context->local_context.local_key_pair_id[context->connection_info.current_bank][index];
cert_info[slot_index] =
context->local_context.local_cert_info[context->connection_info.current_bank][index];
key_usage_bit_mask[slot_index] =
context->local_context.local_key_usage_bit_mask[index];
context->local_context.local_key_usage_bit_mask[context->connection_info.current_bank][index];
}
slot_index++;
if (!result) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright Notice:
* Copyright 2025 DMTF. All rights reserved.
* Copyright 2025-2026 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

Expand Down Expand Up @@ -126,7 +126,8 @@ libspdm_return_t libspdm_get_encap_response_endpoint_info(void *spdm_context,
}

if (slot_id != 0xF) {
if (context->local_context.local_cert_chain_provision[slot_id] == NULL) {
if (context->local_context.local_cert_chain_provision[context->connection_info.current_bank][slot_id] ==
NULL) {
return libspdm_generate_encap_error_response(
context, SPDM_ERROR_CODE_INVALID_REQUEST,
0, response_size, response);
Expand All @@ -140,7 +141,7 @@ libspdm_return_t libspdm_get_encap_response_endpoint_info(void *spdm_context,
}

if (context->connection_info.multi_key_conn_req && slot_id != 0xF) {
if ((context->local_context.local_key_usage_bit_mask[slot_id] &
if ((context->local_context.local_key_usage_bit_mask[context->connection_info.current_bank][slot_id] &
SPDM_KEY_USAGE_BIT_MASK_ENDPOINT_INFO_USE) == 0) {
return libspdm_generate_encap_error_response(
context, SPDM_ERROR_CODE_INVALID_REQUEST,
Expand Down
5 changes: 3 additions & 2 deletions library/spdm_requester_lib/libspdm_req_encap_request.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright Notice:
* Copyright 2021-2025 DMTF. All rights reserved.
* Copyright 2021-2026 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

Expand Down Expand Up @@ -434,7 +434,8 @@ libspdm_return_t libspdm_encapsulated_request(libspdm_context_t *spdm_context,
if ((spdm_encapsulated_response_ack_response->header.spdm_version >=
SPDM_MESSAGE_VERSION_13) &&
spdm_context->connection_info.multi_key_conn_req) {
if ((spdm_context->local_context.local_key_usage_bit_mask[*req_slot_id_param
if ((spdm_context->local_context.local_key_usage_bit_mask[spdm_context->connection_info.
current_bank][*req_slot_id_param
] & SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE) == 0) {
libspdm_release_receiver_buffer (spdm_context);
return LIBSPDM_STATUS_INVALID_MSG_FIELD;
Expand Down
4 changes: 3 additions & 1 deletion library/spdm_requester_lib/libspdm_req_key_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,9 @@ static libspdm_return_t libspdm_try_send_receive_key_exchange(
if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
spdm_context->connection_info.multi_key_conn_req &&
(*req_slot_id_param != 0xf)) {
if ((spdm_context->local_context.local_key_usage_bit_mask[*req_slot_id_param] &
if ((spdm_context->local_context.local_key_usage_bit_mask[spdm_context->connection_info.current_bank][*
req_slot_id_param]
&
SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE) == 0) {
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
Expand Down
Loading
Loading