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

Add support for SUBSCRIBE_EVENT_TYPES #2799

Merged
merged 1 commit into from
Sep 11, 2024
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
24 changes: 24 additions & 0 deletions include/hal/library/eventlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,29 @@ extern bool libspdm_event_get_types(
void *supported_event_groups_list,
uint32_t *supported_event_groups_list_len,
uint8_t *event_group_count);

/**
* Subscribe to the events given in SubscribeList.
*
* 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
* SPDM_SUBSCRIBE_EVENT_TYPES_REQUEST_ATTRIBUTE_ALL is set in the Attributes field then the event
* recipient subscribes to all events in that group.
*
* @param spdm_context A pointer to the SPDM context.
* @param spdm_version Indicates the negotiated version.
* @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 false An error occurred when processing the event group list.
**/
extern bool libspdm_event_subscribe(
void *spdm_context,
spdm_version_number_t spdm_version,
uint8_t subscribe_event_group_count,
uint32_t subscribe_list_len,
const void *subscribe_list);
#endif /* LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP */
#endif /* EVENTLIB_H */
18 changes: 18 additions & 0 deletions include/industry_standard/spdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@

/* SPDM response code (1.3) */
#define SPDM_SUPPORTED_EVENT_TYPES 0x62
#define SPDM_SUBSCRIBE_EVENT_TYPES_ACK 0x70
#define SPDM_MEASUREMENT_EXTENSION_LOG 0x6F
#define SPDM_KEY_PAIR_INFO 0x7C

Expand Down Expand Up @@ -89,6 +90,7 @@

/* SPDM request code (1.3) */
#define SPDM_GET_SUPPORTED_EVENT_TYPES 0xE2
#define SPDM_SUBSCRIBE_EVENT_TYPES 0xF0
#define SPDM_GET_MEASUREMENT_EXTENSION_LOG 0xEF
#define SPDM_GET_KEY_PAIR_INFO 0xFC

Expand Down Expand Up @@ -1197,6 +1199,22 @@ typedef struct {
/* uint8_t supported_event_groups_list[supported_event_groups_list_len] */
} spdm_supported_event_types_response_t;

typedef struct {
spdm_message_header_t header;
/* param1 == SubscribeEventGroupCount
* param2 == RSVD */
uint32_t subscribe_list_len;
/* uint8_t subscribe_list[subscribe_list_len] */
} spdm_subscribe_event_types_request_t;

#define SPDM_SUBSCRIBE_EVENT_TYPES_REQUEST_ATTRIBUTE_ALL (1 << 0)

typedef struct {
spdm_message_header_t header;
/* param1 == RSVD
* param2 == RSVD */
} spdm_subscribe_event_types_ack_response_t;

/* SPDM GET_MEASUREMENT_EXTENSION_LOG request */
typedef struct {
spdm_message_header_t header;
Expand Down
11 changes: 8 additions & 3 deletions include/internal/libspdm_responder_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -778,14 +778,19 @@ libspdm_return_t libspdm_get_response_chunk_send(libspdm_context_t *spdm_context
#endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */

#if LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP
/**
* Process the SPDM GET_SUPPORTED_EVENT_TYPES request and return the response.
**/
/* Process the SPDM GET_SUPPORTED_EVENT_TYPES request and return the response. */
libspdm_return_t libspdm_get_response_supported_event_types(libspdm_context_t *spdm_context,
size_t request_size,
const void *request,
size_t *response_size,
void *response);

/* Process the SPDM SUBSCRIBE_EVENT_TYPES request and return the response. */
libspdm_return_t libspdm_get_response_subscribe_event_types_ack(libspdm_context_t *spdm_context,
size_t request_size,
const void *request,
size_t *response_size,
void *response);
#endif /* LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP */

#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
Expand Down
19 changes: 19 additions & 0 deletions include/library/spdm_requester_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,25 @@ libspdm_return_t libspdm_get_event_types(void *spdm_context,
uint8_t *event_group_count,
uint32_t *supported_event_groups_list_len,
void *supported_event_groups_list);

/** This function subscribes to the specified event types.
*
* This function can only be called after a secure session has been established with the device.
*
* @param spdm_context A pointer to the SPDM context.
* @param session_id The session ID of the session.
* @param subscribe_event_group_count The number of event groups in subscribe_list. If this value
* is 0 then subscription to all events will be cleared and
* subscribe_list_len must be 0 and subscribe_list must be
* NULL.
* @param subscribe_list_len The size, in bytes, of subscribe_list.
* @param subscribe_list List of event types and event groups.
**/
libspdm_return_t libspdm_subscribe_event_types(void *spdm_context,
uint32_t session_id,
uint8_t subscribe_event_group_count,
uint32_t subscribe_list_len,
void *subscribe_list);
#endif /* LIBSPDM_EVENT_RECIPIENT_SUPPORT */

#if LIBSPDM_ENABLE_MSG_LOG
Expand Down
1 change: 1 addition & 0 deletions library/spdm_requester_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ target_sources(spdm_requester_lib
libspdm_req_get_certificate.c
libspdm_req_get_digests.c
libspdm_req_get_event_types.c
libspdm_req_subscribe_event_types.c
libspdm_req_get_measurements.c
libspdm_req_get_version.c
libspdm_req_handle_error_response.c
Expand Down
182 changes: 182 additions & 0 deletions library/spdm_requester_lib/libspdm_req_subscribe_event_types.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
/**
* Copyright Notice:
* Copyright 2024 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

#include "internal/libspdm_requester_lib.h"

#if LIBSPDM_EVENT_RECIPIENT_SUPPORT

static libspdm_return_t try_libspdm_subscribe_event_types(libspdm_context_t *spdm_context,
uint32_t session_id,
uint8_t subscribe_event_group_count,
uint32_t subscribe_list_len,
void *subscribe_list)
{
libspdm_return_t status;
libspdm_session_info_t *session_info;
spdm_subscribe_event_types_request_t *spdm_request;
size_t spdm_request_size;
spdm_supported_event_types_response_t *spdm_response;
size_t spdm_response_size;
size_t transport_header_size;
uint8_t *message;
size_t message_size;

/* -=[Check Parameters Phase]=- */
if (subscribe_event_group_count == 0) {
if ((subscribe_list_len != 0) || (subscribe_list != NULL)) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
} else {
if ((subscribe_list_len == 0) || (subscribe_list == NULL)) {
return LIBSPDM_STATUS_INVALID_PARAMETER;
}
}

session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);

if (session_info == NULL) {
LIBSPDM_ASSERT(false);
return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
}
if (libspdm_secured_message_get_session_state(session_info->secured_message_context) !=
LIBSPDM_SESSION_STATE_ESTABLISHED) {
return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
}

/* -=[Verify State Phase]=- */
if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_13) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}
if (!libspdm_is_capabilities_flag_supported(
spdm_context, true, 0,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EVENT_CAP)) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

/* -=[Construct Request Phase]=- */
transport_header_size = spdm_context->local_context.capability.transport_header_size;
status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
return status;
}
LIBSPDM_ASSERT (message_size >= transport_header_size +
spdm_context->local_context.capability.transport_tail_size);
spdm_request = (void *)(message + transport_header_size);
spdm_request_size = message_size - transport_header_size -
spdm_context->local_context.capability.transport_tail_size;
LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_subscribe_event_types_request_t));

if (spdm_request_size < sizeof(spdm_request->header)) {
libspdm_release_sender_buffer(spdm_context);
return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
}

spdm_request->header.spdm_version = libspdm_get_connection_version(spdm_context);
spdm_request->header.request_response_code = SPDM_SUBSCRIBE_EVENT_TYPES;
spdm_request->header.param1 = subscribe_event_group_count;
spdm_request->header.param2 = 0;

if (subscribe_event_group_count == 0) {
spdm_request_size = sizeof(spdm_request->header);
} else {
if (spdm_request_size < sizeof(spdm_subscribe_event_types_request_t) + subscribe_list_len) {
libspdm_release_sender_buffer(spdm_context);
return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
}

spdm_request_size = sizeof(spdm_subscribe_event_types_request_t) + subscribe_list_len;
spdm_request->subscribe_list_len = subscribe_list_len;
libspdm_copy_mem(spdm_request + 1,
spdm_request_size - sizeof(spdm_subscribe_event_types_request_t),
subscribe_list,
subscribe_list_len);
}

/* -=[Send Request Phase]=- */
status = libspdm_send_spdm_request(spdm_context, &session_id, spdm_request_size, spdm_request);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
libspdm_release_sender_buffer (spdm_context);
return status;
}

libspdm_release_sender_buffer(spdm_context);
spdm_request = (void *)spdm_context->last_spdm_request;

/* -=[Receive Response Phase]=- */
status = libspdm_acquire_receiver_buffer(spdm_context, &message_size, (void **)&message);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
return status;
}
LIBSPDM_ASSERT (message_size >= transport_header_size);
spdm_response = (void *)(message);
spdm_response_size = message_size;

status = libspdm_receive_spdm_response(
spdm_context, &session_id, &spdm_response_size, (void **)&spdm_response);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
goto receive_done;
}

/* -=[Validate Response Phase]=- */
if (spdm_response_size != sizeof(spdm_subscribe_event_types_ack_response_t)) {
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
goto receive_done;
}
if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}
if (spdm_response->header.request_response_code == SPDM_ERROR) {
status = libspdm_handle_error_response_main(
spdm_context, &session_id,
&spdm_response_size, (void **)&spdm_response,
SPDM_SUBSCRIBE_EVENT_TYPES, SPDM_SUBSCRIBE_EVENT_TYPES_ACK);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
goto receive_done;
}
} else if (spdm_response->header.request_response_code != SPDM_SUBSCRIBE_EVENT_TYPES_ACK) {
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}

receive_done:
libspdm_release_receiver_buffer(spdm_context);

return status;
}

libspdm_return_t libspdm_subscribe_event_types(void *spdm_context,
uint32_t session_id,
uint8_t subscribe_event_group_count,
uint32_t subscribe_list_len,
void *subscribe_list)
{
size_t retry;
uint64_t retry_delay_time;
libspdm_return_t status;
libspdm_context_t *context;

context = spdm_context;
context->crypto_request = true;
retry = context->retry_times;
retry_delay_time = context->retry_delay_time;
do {
status = try_libspdm_subscribe_event_types(context,
session_id,
subscribe_event_group_count,
subscribe_list_len,
subscribe_list);
if (status != LIBSPDM_STATUS_BUSY_PEER) {
return status;
}

libspdm_sleep(retry_delay_time);
} while (retry-- != 0);

return status;
}

#endif /* LIBSPDM_EVENT_RECIPIENT_SUPPORT */
1 change: 1 addition & 0 deletions library/spdm_responder_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ target_sources(spdm_responder_lib
libspdm_rsp_version.c
libspdm_rsp_set_certificate.c
libspdm_rsp_supported_event_types.c
libspdm_rsp_subscribe_event_types_ack.c
libspdm_rsp_csr.c
libspdm_rsp_chunk_send_ack.c
libspdm_rsp_chunk_get.c
Expand Down
1 change: 1 addition & 0 deletions library/spdm_responder_lib/libspdm_rsp_receive_send.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ libspdm_get_spdm_response_func libspdm_get_response_func_via_request_code(uint8_

#if LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP
{ SPDM_SUPPORTED_EVENT_TYPES, libspdm_get_response_supported_event_types },
{ SPDM_SUBSCRIBE_EVENT_TYPES, libspdm_get_response_subscribe_event_types_ack },
#endif /* LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP */

#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
Expand Down
Loading
Loading