Skip to content

Commit

Permalink
Add EventAllPolicy to key exchange
Browse files Browse the repository at this point in the history
Fix DMTF#2566

Signed-off-by: Steven Bellock <sbellock@nvidia.com>
  • Loading branch information
steven-bellock committed Sep 17, 2024
1 parent f36ceda commit f72e3a6
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 28 deletions.
21 changes: 17 additions & 4 deletions include/hal/library/eventlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,26 +39,39 @@ extern bool libspdm_event_get_types(
uint32_t *supported_event_groups_list_len,
uint8_t *event_group_count);

#define LIBSPDM_EVENT_SUBSCRIBE_ALL 0
#define LIBSPDM_EVENT_SUBSCRIBE_NONE 1
#define LIBSPDM_EVENT_SUBSCRIBE_LIST 2

/**
* Subscribe to the events given in SubscribeList.
* Subscribe or unsubscribe to events.
*
* If subscribe_event_group_count is 0 then the event recipient unsubscribes from all events and
* subscribe_list_len is 0 and subscribe_list is NULL. For a given event group, if
* If subscribe_type is LIBSPDM_EVENT_SUBSCRIBE_ALL then the Event Recipient subscribes to all
* events, and subsequent parameters are ignored. If subscribe_type is LIBSPDM_EVENT_SUBSCRIBE_NONE
* then the Event Recipient unsubscribes from all events and subsequent parameters are ignored. If
* subscribe_type is LIBSPDM_EVENT_SUBSCRIBE_LIST then the Event Recipient subscribes to the events
* given in subscribe_list. For a given event group, if
* SPDM_SUBSCRIBE_EVENT_TYPES_REQUEST_ATTRIBUTE_ALL is set in the Attributes field then the event
* recipient subscribes to all events in that group.
*
* Events can only be sent when the session state is LIBSPDM_SESSION_STATE_ESTABLISHED.
*
* @param spdm_context A pointer to the SPDM context.
* @param spdm_version Indicates the negotiated version.
* @param session_id Secure session identifier.
* @param subscribe_type One of the LIBSPDM_EVENT_SUBSCRIBE_* macros.
* @param subscribe_event_group_count Number of event groups in subscribe_list.
* @param subscribe_list_len Size, in bytes, of subscribe_list.
* @param subscribe_list Buffer that contains the event groups to be subscribed.
*
* @retval true All events were successfully subscribed or unsubscribed to.
* @retval true All events were successfully subscribed to or unsubscribed from.
* @retval false An error occurred when processing the event group list.
**/
extern bool libspdm_event_subscribe(
void *spdm_context,
spdm_version_number_t spdm_version,
uint32_t session_id,
uint8_t subscribe_type,
uint8_t subscribe_event_group_count,
uint32_t subscribe_list_len,
const void *subscribe_list);
Expand Down
3 changes: 2 additions & 1 deletion include/industry_standard/spdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,8 @@ typedef struct {
} spdm_key_exchange_request_t;

/* SPDM KEY_EXCHANGE request session_policy */
#define SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_TERMINATION_POLICY_RUNTIME_UPDATE 0x00000001
#define SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_TERMINATION_POLICY_RUNTIME_UPDATE 0x01
#define SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_EVENT_ALL_POLICY 0x02

/* SPDM KEY_EXCHANGE request measurement summary HashType */
#define SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH \
Expand Down
4 changes: 4 additions & 0 deletions library/spdm_requester_lib/libspdm_req_key_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,10 @@ static libspdm_return_t libspdm_try_send_receive_key_exchange(
LIBSPDM_ASSERT(measurement_hash_type == SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH ||
measurement_hash_type == SPDM_KEY_EXCHANGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH ||
measurement_hash_type == SPDM_KEY_EXCHANGE_REQUEST_ALL_MEASUREMENTS_HASH);
LIBSPDM_ASSERT(((session_policy & SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_EVENT_ALL_POLICY)
== 0) ||
libspdm_is_capabilities_flag_supported(
spdm_context, true, 0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EVENT_CAP));

/* -=[Verify State Phase]=- */
if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
Expand Down
41 changes: 32 additions & 9 deletions library/spdm_responder_lib/libspdm_rsp_key_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,17 +291,25 @@ libspdm_return_t libspdm_get_response_key_exchange(libspdm_context_t *spdm_conte
}
}

if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
spdm_context->connection_info.multi_key_conn_rsp &&
(slot_id != 0xff)) {
if ((spdm_context->local_context.local_key_usage_bit_mask[slot_id] &
SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE) == 0) {
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
0, response_size, response);
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
if (spdm_context->connection_info.multi_key_conn_rsp && (slot_id != 0xff)) {
if ((spdm_context->local_context.local_key_usage_bit_mask[slot_id] &
SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE) == 0) {
return libspdm_generate_error_response(
spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
}
}
}

if ((spdm_request->session_policy &
SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_EVENT_ALL_POLICY) != 0) {
if (!libspdm_is_capabilities_flag_supported(
spdm_context, false, 0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EVENT_CAP)) {
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_INVALID_REQUEST, 0,
response_size, response);
}
}
}
spdm_context->connection_info.local_used_cert_chain_slot_id = slot_id;

signature_size = libspdm_get_asym_signature_size(
Expand Down Expand Up @@ -620,6 +628,21 @@ libspdm_return_t libspdm_get_response_key_exchange(libspdm_context_t *spdm_conte
ptr += hmac_size;
}

#if LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
if ((spdm_request->session_policy &
SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_EVENT_ALL_POLICY) != 0) {
if (!libspdm_event_subscribe(spdm_context, spdm_context->connection_info.version,
session_id, LIBSPDM_EVENT_SUBSCRIBE_ALL, 0, 0, NULL)) {
libspdm_free_session_id(spdm_context, session_id);
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_UNSPECIFIED, 0,
response_size, response);
}
}
}
#endif /* LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP */

session_info->mut_auth_requested = spdm_response->mut_auth_requested;
if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
session_info->session_policy = spdm_request->session_policy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ libspdm_return_t libspdm_get_response_subscribe_event_types_ack(libspdm_context_
uint32_t session_id;
libspdm_session_info_t *session_info;
libspdm_session_state_t session_state;
uint8_t subscribe_type;
uint8_t subscribe_event_group_count;
uint32_t subscribe_list_len;
const void *subscribe_list;
Expand Down Expand Up @@ -118,15 +119,18 @@ libspdm_return_t libspdm_get_response_subscribe_event_types_ack(libspdm_context_
}

if (subscribe_event_group_count == 0) {
subscribe_type = LIBSPDM_EVENT_SUBSCRIBE_NONE;
subscribe_list_len = 0;
subscribe_list = NULL;
} else {
subscribe_type = LIBSPDM_EVENT_SUBSCRIBE_LIST;
subscribe_list_len = spdm_request->subscribe_list_len;
subscribe_list = (const void *)(spdm_request + 1);
}

if (!libspdm_event_subscribe(spdm_context, spdm_context->connection_info.version,
subscribe_event_group_count, subscribe_list_len, subscribe_list)) {
if (!libspdm_event_subscribe(spdm_context, spdm_context->connection_info.version, session_id,
subscribe_type, subscribe_event_group_count,
subscribe_list_len, subscribe_list)) {
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_INVALID_REQUEST, 0,
response_size, response);
Expand Down
2 changes: 2 additions & 0 deletions os_stub/spdm_device_secret_lib_null/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ bool libspdm_event_get_types(
bool libspdm_event_subscribe(
void *spdm_context,
spdm_version_number_t spdm_version,
uint32_t session_id,
uint8_t subscribe_type,
uint8_t subscribe_event_group_count,
uint32_t subscribe_list_len,
const void *subscribe_list)
Expand Down
27 changes: 25 additions & 2 deletions os_stub/spdm_device_secret_lib_sample/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
bool g_in_trusted_environment = false;
uint32_t g_supported_event_groups_list_len = 8;
uint8_t g_event_group_count = 1;
bool g_event_all_subscribe = false;
bool g_event_all_unsubscribe = false;

#if LIBSPDM_ENABLE_CAPABILITY_GET_KEY_PAIR_INFO_CAP
typedef struct {
Expand Down Expand Up @@ -2253,20 +2255,41 @@ bool libspdm_event_get_types(
bool libspdm_event_subscribe(
void *spdm_context,
spdm_version_number_t spdm_version,
uint32_t session_id,
uint8_t subscribe_type,
uint8_t subscribe_event_group_count,
uint32_t subscribe_list_len,
const void *subscribe_list)
{
if (subscribe_event_group_count == 0) {
switch (subscribe_type) {
case LIBSPDM_EVENT_SUBSCRIBE_ALL:
if ((subscribe_list_len != 0) || (subscribe_list != NULL)) {
return false;
}
} else {
LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Subscribing to all events for session ID 0x.%x\n"));
g_event_all_subscribe = true;
g_event_all_unsubscribe = false;
return true;
case LIBSPDM_EVENT_SUBSCRIBE_NONE:
if ((subscribe_list_len != 0) || (subscribe_list != NULL)) {
return false;
}
LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Unsubscribing from all events for session ID 0x.%x\n"));
g_event_all_subscribe = false;
g_event_all_unsubscribe = true;
return true;
case LIBSPDM_EVENT_SUBSCRIBE_LIST:
if ((subscribe_list_len == 0) || (subscribe_list == NULL)) {
return false;
}
break;
default:
return false;
}

g_event_all_subscribe = false;
g_event_all_unsubscribe = false;

LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
"subscribe_event_group_count == %d, subscribe_list_len = %d\n",
subscribe_event_group_count, subscribe_list_len));
Expand Down
21 changes: 12 additions & 9 deletions unit_test/test_spdm_requester/key_exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -7783,7 +7783,8 @@ static void libspdm_test_requester_key_exchange_case30(void **state)
libspdm_zero_mem(measurement_hash, sizeof(measurement_hash));
status = libspdm_send_receive_key_exchange(
spdm_context,
SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, 0, 0xFF,
SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, 0,
SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_TERMINATION_POLICY_RUNTIME_UPDATE,
&session_id, &heartbeat_period, &slot_id_param,
measurement_hash);
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
Expand All @@ -7792,7 +7793,8 @@ static void libspdm_test_requester_key_exchange_case30(void **state)
libspdm_secured_message_get_session_state(
spdm_context->session_info[0].secured_message_context),
LIBSPDM_SESSION_STATE_HANDSHAKING);
assert_int_equal(spdm_context->session_info[0].session_policy, 0xFF);
assert_int_equal(spdm_context->session_info[0].session_policy,
SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_TERMINATION_POLICY_RUNTIME_UPDATE);
free(data);
}

Expand Down Expand Up @@ -7953,7 +7955,8 @@ void libspdm_test_requester_key_exchange_case32(void **state)
libspdm_zero_mem(measurement_hash, sizeof(measurement_hash));
status = libspdm_send_receive_key_exchange(
spdm_context,
SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, 0xFF, 0xFF,
SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, 0xFF,
SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_TERMINATION_POLICY_RUNTIME_UPDATE,
&session_id, &heartbeat_period, &slot_id_param,
measurement_hash);
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
Expand All @@ -7962,9 +7965,8 @@ void libspdm_test_requester_key_exchange_case32(void **state)
libspdm_secured_message_get_session_state(
spdm_context->session_info[0].secured_message_context),
LIBSPDM_SESSION_STATE_HANDSHAKING);
assert_int_equal(
spdm_context->session_info[0].session_policy,
0xFF);
assert_int_equal(spdm_context->session_info[0].session_policy,
SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_TERMINATION_POLICY_RUNTIME_UPDATE);
free(data);
}

Expand Down Expand Up @@ -8037,7 +8039,8 @@ static void libspdm_test_requester_key_exchange_case33(void **state)
libspdm_zero_mem(measurement_hash, sizeof(measurement_hash));
status = libspdm_send_receive_key_exchange(
spdm_context,
SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, 0, 0xFF,
SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, 0,
SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_TERMINATION_POLICY_RUNTIME_UPDATE,
&session_id, &heartbeat_period, &slot_id_param,
measurement_hash);
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
Expand All @@ -8046,8 +8049,8 @@ static void libspdm_test_requester_key_exchange_case33(void **state)
libspdm_secured_message_get_session_state(
spdm_context->session_info[0].secured_message_context),
LIBSPDM_SESSION_STATE_HANDSHAKING);
assert_int_equal(
spdm_context->session_info[0].session_policy, 0xFF);
assert_int_equal(spdm_context->session_info[0].session_policy,
SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_TERMINATION_POLICY_RUNTIME_UPDATE);
free(data);
}

Expand Down
Loading

0 comments on commit f72e3a6

Please sign in to comment.