Branch data Line data Source code
1 : : /**
2 : : * Copyright Notice:
3 : : * Copyright 2025-2026 DMTF. All rights reserved.
4 : : * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5 : : **/
6 : :
7 : : #include "internal/libspdm_requester_lib.h"
8 : :
9 : : #if LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP
10 : :
11 : 22 : static libspdm_return_t libspdm_try_send_event(
12 : : libspdm_context_t *spdm_context, uint32_t session_id,
13 : : uint32_t event_count, size_t events_list_size, void *events_list)
14 : : {
15 : : libspdm_return_t status;
16 : : libspdm_session_info_t *session_info;
17 : : spdm_send_event_request_t *spdm_request;
18 : : size_t spdm_request_size;
19 : : spdm_event_ack_response_t *spdm_response;
20 : : size_t spdm_response_size;
21 : : size_t transport_header_size;
22 : : uint8_t *message;
23 : : size_t message_size;
24 : :
25 : : /* -=[Check Parameters Phase]=- */
26 : 22 : LIBSPDM_ASSERT(event_count != 0);
27 : 22 : LIBSPDM_ASSERT(events_list_size != 0);
28 : 22 : LIBSPDM_ASSERT(events_list != NULL);
29 : :
30 : 22 : session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
31 : :
32 [ - + ]: 22 : if (session_info == NULL) {
33 : 0 : LIBSPDM_ASSERT(false);
34 : 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
35 : : }
36 [ - + ]: 22 : if (libspdm_secured_message_get_session_state(session_info->secured_message_context) !=
37 : : LIBSPDM_SESSION_STATE_ESTABLISHED) {
38 : 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
39 : : }
40 : :
41 : : /* -=[Verify State Phase]=- */
42 [ + + ]: 22 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_13) {
43 : 2 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
44 : : }
45 [ + + ]: 20 : if (!libspdm_is_capabilities_flag_supported(
46 : : spdm_context, true, SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EVENT_CAP, 0)) {
47 : 2 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
48 : : }
49 : :
50 : : /* -=[Construct Request Phase]=- */
51 : 18 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
52 : 18 : status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
53 [ + + ]: 18 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
54 : 2 : return status;
55 : : }
56 : 16 : LIBSPDM_ASSERT (message_size >= transport_header_size +
57 : : spdm_context->local_context.capability.transport_tail_size);
58 : 16 : spdm_request = (void *)(message + transport_header_size);
59 : 16 : spdm_request_size = message_size - transport_header_size -
60 : 16 : spdm_context->local_context.capability.transport_tail_size;
61 : :
62 [ - + ]: 16 : if (spdm_request_size < sizeof(spdm_send_event_request_t) + events_list_size) {
63 : 0 : libspdm_release_sender_buffer(spdm_context);
64 : 0 : return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
65 : : }
66 : :
67 : 16 : spdm_request->header.spdm_version = libspdm_get_connection_version(spdm_context);
68 : 16 : spdm_request->header.request_response_code = SPDM_SEND_EVENT;
69 : 16 : spdm_request->header.param1 = 0;
70 : 16 : spdm_request->header.param2 = 0;
71 : 16 : spdm_request->event_count = event_count;
72 : :
73 : 16 : libspdm_copy_mem(spdm_request + 1, spdm_request_size - sizeof(spdm_send_event_request_t),
74 : : events_list, events_list_size);
75 : :
76 : 16 : spdm_request_size = sizeof(spdm_send_event_request_t) + events_list_size;
77 : :
78 : : /* -=[Send Request Phase]=- */
79 : 16 : status = libspdm_send_spdm_request(spdm_context, &session_id, spdm_request_size, spdm_request);
80 [ + + ]: 16 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
81 : 2 : libspdm_release_sender_buffer (spdm_context);
82 : 2 : return status;
83 : : }
84 : :
85 : 14 : libspdm_release_sender_buffer(spdm_context);
86 : 14 : spdm_request = (void *)spdm_context->last_spdm_request;
87 : :
88 : : /* -=[Receive Response Phase]=- */
89 : 14 : status = libspdm_acquire_receiver_buffer(spdm_context, &message_size, (void **)&message);
90 [ + + ]: 14 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
91 : 2 : return status;
92 : : }
93 : 12 : LIBSPDM_ASSERT (message_size >= transport_header_size);
94 : 12 : spdm_response = (void *)(message);
95 : 12 : spdm_response_size = message_size;
96 : :
97 : 12 : status = libspdm_receive_spdm_response(
98 : : spdm_context, &session_id, &spdm_response_size, (void **)&spdm_response);
99 [ + + ]: 12 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
100 : 2 : goto receive_done;
101 : : }
102 : :
103 : : /* -=[Validate Response Phase]=- */
104 [ - + ]: 10 : if (spdm_response_size < sizeof(spdm_message_header_t)) {
105 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
106 : 0 : goto receive_done;
107 : : }
108 [ + + ]: 10 : if (spdm_response->header.request_response_code == SPDM_ERROR) {
109 : 2 : status = libspdm_handle_error_response_main(
110 : : spdm_context, &session_id,
111 : : &spdm_response_size, (void **)&spdm_response,
112 : : SPDM_SEND_EVENT, SPDM_EVENT_ACK);
113 [ - + ]: 2 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
114 : 0 : goto receive_done;
115 : : }
116 [ + + ]: 8 : } else if (spdm_response->header.request_response_code != SPDM_EVENT_ACK) {
117 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
118 : 2 : goto receive_done;
119 : : }
120 [ + + ]: 8 : if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
121 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
122 : 2 : goto receive_done;
123 : : }
124 [ + + ]: 6 : if (spdm_response_size != sizeof(spdm_event_ack_response_t)) {
125 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
126 : 2 : goto receive_done;
127 : : }
128 : :
129 : : /* -=[Log Message Phase]=- */
130 : : #if LIBSPDM_ENABLE_MSG_LOG
131 : 4 : libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
132 : : #endif /* LIBSPDM_ENABLE_MSG_LOG */
133 : :
134 : 12 : receive_done:
135 : 12 : libspdm_release_receiver_buffer(spdm_context);
136 : :
137 : 12 : return status;
138 : : }
139 : :
140 : 22 : libspdm_return_t libspdm_send_event(void *spdm_context, uint32_t session_id, uint32_t event_count,
141 : : size_t events_list_size, void *events_list)
142 : : {
143 : : size_t retry;
144 : : uint64_t retry_delay_time;
145 : : libspdm_return_t status;
146 : : libspdm_context_t *context;
147 : :
148 : 22 : context = spdm_context;
149 : 22 : context->crypto_request = false;
150 : 22 : retry = context->retry_times;
151 : 22 : retry_delay_time = context->retry_delay_time;
152 : :
153 : : do {
154 : 22 : status = libspdm_try_send_event(context, session_id, event_count, events_list_size,
155 : : events_list);
156 [ + - ]: 22 : if (status != LIBSPDM_STATUS_BUSY_PEER) {
157 : 22 : return status;
158 : : }
159 : :
160 : 0 : libspdm_sleep(retry_delay_time);
161 [ # # ]: 0 : } while (retry-- != 0);
162 : :
163 : 0 : return status;
164 : : }
165 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP */
|