Branch data Line data Source code
1 : : /**
2 : : * Copyright Notice:
3 : : * Copyright 2021-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 : 5 : libspdm_return_t libspdm_init_connection(void *spdm_context, bool get_version_only)
10 : : {
11 : : libspdm_return_t status;
12 : : libspdm_context_t *context;
13 : :
14 : 5 : context = spdm_context;
15 : :
16 : 5 : status = libspdm_get_version(context, NULL, NULL);
17 [ + + ]: 5 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
18 : 1 : return status;
19 : : }
20 : :
21 [ + + ]: 4 : if (!get_version_only) {
22 : 3 : status = libspdm_get_capabilities(context);
23 [ + + ]: 3 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
24 : 1 : return status;
25 : : }
26 : 2 : status = libspdm_negotiate_algorithms(context);
27 [ + + ]: 2 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
28 : 1 : return status;
29 : : }
30 : : }
31 : 2 : return LIBSPDM_STATUS_SUCCESS;
32 : : }
33 : :
34 : 5 : libspdm_return_t libspdm_get_supported_algorithms(void *spdm_context,
35 : : size_t *responder_supported_algorithms_length,
36 : : void *responder_supported_algorithms_buffer,
37 : : uint8_t *spdm_version)
38 : : {
39 : : libspdm_return_t status;
40 : : libspdm_context_t *context;
41 : : bool has_version_1_3_or_above;
42 : : size_t index;
43 : :
44 : 5 : context = spdm_context;
45 : 5 : has_version_1_3_or_above = false;
46 : :
47 : : /* Verify responder_supported_algorithms_buffer is not NULL */
48 [ - + ]: 5 : LIBSPDM_ASSERT(responder_supported_algorithms_buffer != NULL);
49 [ - + ]: 5 : LIBSPDM_ASSERT(responder_supported_algorithms_length != NULL);
50 : :
51 : : /* Pre-check: Verify requester supports at least one version >= 1.3 */
52 [ + + ]: 18 : for (index = 0; index < context->local_context.version.spdm_version_count; index++) {
53 [ + + ]: 17 : if (libspdm_get_version_from_version_number(context->local_context.version.spdm_version[index]) >=
54 : : SPDM_MESSAGE_VERSION_13) {
55 : 4 : has_version_1_3_or_above = true;
56 : 4 : break;
57 : : }
58 : : }
59 [ + + ]: 5 : if (!has_version_1_3_or_above) {
60 : 1 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
61 : : }
62 : :
63 [ - + ]: 4 : LIBSPDM_ASSERT((context->local_context.capability.flags &
64 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) != 0);
65 : :
66 : 4 : status = libspdm_get_version(context, NULL, NULL);
67 [ + + ]: 4 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
68 : 1 : return status;
69 : : }
70 : :
71 : 3 : *spdm_version = libspdm_get_connection_version(context);
72 : :
73 [ + + ]: 3 : if (*spdm_version < SPDM_MESSAGE_VERSION_13) {
74 : 1 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
75 : : }
76 : :
77 : 2 : status = libspdm_get_capabilities_with_supported_algs(context, responder_supported_algorithms_length,
78 : : responder_supported_algorithms_buffer);
79 [ + + ]: 2 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
80 : 1 : return status;
81 : : }
82 : :
83 : 1 : return LIBSPDM_STATUS_SUCCESS;
84 : : }
85 : :
86 : : #if (LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)
87 : 4 : libspdm_return_t libspdm_start_session(void *spdm_context, bool use_psk,
88 : : const void *psk_hint,
89 : : uint16_t psk_hint_size,
90 : : uint8_t measurement_hash_type,
91 : : uint8_t slot_id,
92 : : uint8_t session_policy,
93 : : uint32_t *session_id,
94 : : uint8_t *heartbeat_period,
95 : : void *measurement_hash)
96 : : {
97 : : libspdm_return_t status;
98 : : libspdm_context_t *context;
99 : :
100 : : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
101 : : libspdm_session_info_t *session_info;
102 : : uint8_t req_slot_id_param;
103 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
104 : :
105 : 4 : context = spdm_context;
106 : 4 : status = LIBSPDM_STATUS_UNSUPPORTED_CAP;
107 : :
108 [ + + ]: 4 : if (!use_psk) {
109 : : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
110 : 1 : status = libspdm_send_receive_key_exchange(
111 : : context, measurement_hash_type, slot_id, session_policy,
112 : : session_id, heartbeat_period, &req_slot_id_param,
113 : : measurement_hash);
114 [ + - ]: 1 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
115 : 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
116 : : "libspdm_start_session - libspdm_send_receive_key_exchange - %x\n",
117 : : status));
118 : 1 : return status;
119 : : }
120 : :
121 : 0 : session_info = libspdm_get_session_info_via_session_id(context, *session_id);
122 [ # # ]: 0 : if (session_info == NULL) {
123 : 0 : LIBSPDM_ASSERT(false);
124 : 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
125 : : }
126 : :
127 [ # # # # ]: 0 : switch (session_info->mut_auth_requested) {
128 : 0 : case 0:
129 : 0 : break;
130 : 0 : case SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED:
131 : : #if !(LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP)
132 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
133 : : "libspdm_start_session - unsupported mut_auth_requested - 0x%x\n",
134 : : session_info->mut_auth_requested));
135 : : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
136 : : #endif
137 : 0 : break;
138 : 0 : case SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST:
139 : : case SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS:
140 : : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP)
141 : 0 : status = libspdm_encapsulated_request(
142 : : context, session_id,
143 : 0 : session_info->mut_auth_requested,
144 : : &req_slot_id_param);
145 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
146 : : "libspdm_start_session - libspdm_encapsulated_request - %x\n", status));
147 [ # # ]: 0 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
148 : 0 : return status;
149 : : }
150 : : #else
151 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
152 : : "libspdm_start_session - unsupported mut_auth_requested - 0x%x\n",
153 : : session_info->mut_auth_requested));
154 : : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
155 : : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) */
156 : 0 : break;
157 : 0 : default:
158 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
159 : : "libspdm_start_session - unknown mut_auth_requested - 0x%x\n",
160 : : session_info->mut_auth_requested));
161 : 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
162 : : }
163 : :
164 [ # # ]: 0 : if (req_slot_id_param == 0xF) {
165 : 0 : req_slot_id_param = 0xFF;
166 : : }
167 : 0 : status = libspdm_send_receive_finish(context, *session_id, req_slot_id_param);
168 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
169 : : "libspdm_start_session - libspdm_send_receive_finish - %x\n", status));
170 : : #else /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
171 : : LIBSPDM_ASSERT(false);
172 : : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
173 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
174 : : } else {
175 : : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
176 : 3 : status = libspdm_send_receive_psk_exchange(
177 : : context, psk_hint, psk_hint_size,
178 : : measurement_hash_type, session_policy, session_id,
179 : : heartbeat_period, measurement_hash);
180 [ + + ]: 3 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
181 : 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
182 : : "libspdm_start_session - libspdm_send_receive_psk_exchange - %x\n",
183 : : status));
184 : 1 : return status;
185 : : }
186 : :
187 : : /* send PSK_FINISH only if Responder supports context.*/
188 [ + + ]: 2 : if (libspdm_is_capabilities_flag_supported(
189 : : context, true, 0,
190 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP_RESPONDER_WITH_CONTEXT)) {
191 : 1 : status = libspdm_send_receive_psk_finish(context, *session_id);
192 : 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
193 : : "libspdm_start_session - libspdm_send_receive_psk_finish - %x\n",
194 : : status));
195 : : }
196 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
197 : : }
198 : 2 : return status;
199 : : }
200 : :
201 : 3 : libspdm_return_t libspdm_start_session_exchange(void *spdm_context, bool use_psk,
202 : : const void *psk_hint,
203 : : uint16_t psk_hint_size,
204 : : uint8_t measurement_hash_type,
205 : : uint8_t slot_id,
206 : : uint8_t session_policy,
207 : : uint32_t *session_id,
208 : : uint8_t *heartbeat_period,
209 : : void *measurement_hash,
210 : : const void *requester_random_in,
211 : : size_t requester_random_in_size,
212 : : void *requester_random,
213 : : size_t *requester_random_size,
214 : : void *responder_random,
215 : : size_t *responder_random_size,
216 : : const void *requester_opaque_data,
217 : : size_t requester_opaque_data_size,
218 : : void *responder_opaque_data,
219 : : size_t *responder_opaque_data_size)
220 : : {
221 : : libspdm_return_t status;
222 : : libspdm_context_t *context;
223 : :
224 : : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
225 : : libspdm_session_info_t *session_info;
226 : : uint8_t req_slot_id_param;
227 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP */
228 : :
229 : 3 : context = spdm_context;
230 : 3 : status = LIBSPDM_STATUS_UNSUPPORTED_CAP;
231 : :
232 [ + + ]: 3 : if (!use_psk) {
233 : : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
234 [ - + - - ]: 1 : LIBSPDM_ASSERT (
235 : : requester_random_in_size == 0 || requester_random_in_size == SPDM_RANDOM_DATA_SIZE);
236 [ - + - - ]: 1 : LIBSPDM_ASSERT (
237 : : requester_random_size == NULL || *requester_random_size == SPDM_RANDOM_DATA_SIZE);
238 [ - + - - ]: 1 : LIBSPDM_ASSERT (
239 : : responder_random_size == NULL || *responder_random_size == SPDM_RANDOM_DATA_SIZE);
240 : 1 : status = libspdm_send_receive_key_exchange_ex(
241 : : context, measurement_hash_type, slot_id, session_policy,
242 : : session_id, heartbeat_period, &req_slot_id_param,
243 : : measurement_hash, requester_random_in,
244 : : requester_random, responder_random,
245 : : requester_opaque_data, requester_opaque_data_size,
246 : : responder_opaque_data, responder_opaque_data_size);
247 [ + - ]: 1 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
248 : 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
249 : : "libspdm_start_session - libspdm_send_receive_key_exchange - %x\n",
250 : : status));
251 : 1 : return status;
252 : : }
253 : :
254 : 0 : session_info = libspdm_get_session_info_via_session_id(context, *session_id);
255 [ # # ]: 0 : if (session_info == NULL) {
256 : 0 : LIBSPDM_ASSERT(false);
257 : 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
258 : : }
259 : :
260 [ # # # # ]: 0 : switch (session_info->mut_auth_requested) {
261 : 0 : case 0:
262 : 0 : break;
263 : 0 : case SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED:
264 : : #if !(LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP)
265 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
266 : : "libspdm_start_session - unsupported mut_auth_requested - 0x%x\n",
267 : : session_info->mut_auth_requested));
268 : : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
269 : : #endif
270 : 0 : break;
271 : 0 : case SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST:
272 : : case SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS:
273 : : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP)
274 : 0 : status = libspdm_encapsulated_request(
275 : : context, session_id,
276 : 0 : session_info->mut_auth_requested,
277 : : &req_slot_id_param);
278 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
279 : : "libspdm_start_session - libspdm_encapsulated_request - %x\n", status));
280 [ # # ]: 0 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
281 : 0 : return status;
282 : : }
283 : : #else
284 : : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
285 : : "libspdm_start_session - unsupported mut_auth_requested - 0x%x\n",
286 : : session_info->mut_auth_requested));
287 : : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
288 : : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) */
289 : 0 : break;
290 : 0 : default:
291 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
292 : : "libspdm_start_session - unknown mut_auth_requested - 0x%x\n",
293 : : session_info->mut_auth_requested));
294 : 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
295 : : }
296 : : #else /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
297 : : LIBSPDM_ASSERT(false);
298 : : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
299 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
300 : : } else {
301 : : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
302 : 2 : status = libspdm_send_receive_psk_exchange_ex(
303 : : context, psk_hint, psk_hint_size,
304 : : measurement_hash_type, session_policy, session_id,
305 : : heartbeat_period, measurement_hash,
306 : : requester_random_in, requester_random_in_size,
307 : : requester_random, requester_random_size,
308 : : responder_random, responder_random_size,
309 : : requester_opaque_data, requester_opaque_data_size,
310 : : responder_opaque_data, responder_opaque_data_size);
311 [ + + ]: 2 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
312 : 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
313 : : "libspdm_start_session - libspdm_send_receive_psk_exchange - %x\n",
314 : : status));
315 : 1 : return status;
316 : : }
317 : : #else /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
318 : : LIBSPDM_ASSERT(false);
319 : : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
320 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
321 : : }
322 : :
323 : 1 : return status;
324 : : }
325 : :
326 : 3 : libspdm_return_t libspdm_start_session_finish(void *spdm_context,
327 : : uint32_t session_id,
328 : : const void *requester_opaque_data,
329 : : size_t requester_opaque_data_size,
330 : : void *responder_opaque_data,
331 : : size_t *responder_opaque_data_size)
332 : : {
333 : : libspdm_return_t status;
334 : : libspdm_context_t *context;
335 : : libspdm_session_info_t *session_info;
336 : :
337 : : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
338 : : uint8_t req_slot_id_param;
339 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP */
340 : :
341 : 3 : context = spdm_context;
342 : 3 : status = LIBSPDM_STATUS_UNSUPPORTED_CAP;
343 : :
344 : 3 : session_info = libspdm_get_session_info_via_session_id(context, session_id);
345 [ - + ]: 3 : if (session_info == NULL) {
346 : 0 : LIBSPDM_ASSERT(false);
347 : 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
348 : : }
349 : :
350 [ + + ]: 3 : if (!session_info->use_psk) {
351 : : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
352 : 1 : req_slot_id_param = session_info->local_used_cert_chain_slot_id;
353 [ - + ]: 1 : if (req_slot_id_param == 0xF) {
354 : 0 : req_slot_id_param = 0xFF;
355 : : }
356 : 1 : status = libspdm_send_receive_finish_ex(
357 : : context, session_id, req_slot_id_param,
358 : : requester_opaque_data, requester_opaque_data_size,
359 : : responder_opaque_data, responder_opaque_data_size);
360 : 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
361 : : "libspdm_start_session - libspdm_send_receive_finish - %x\n", status));
362 : : #else /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
363 : : LIBSPDM_ASSERT(false);
364 : : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
365 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
366 : : } else {
367 : : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
368 : : /* send PSK_FINISH only if Responder supports context.*/
369 [ + - ]: 2 : if (libspdm_is_capabilities_flag_supported(
370 : : context, true, 0,
371 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP_RESPONDER_WITH_CONTEXT)) {
372 : 2 : status = libspdm_send_receive_psk_finish_ex(
373 : : context, session_id,
374 : : requester_opaque_data, requester_opaque_data_size,
375 : : responder_opaque_data, responder_opaque_data_size);
376 : 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
377 : : "libspdm_start_session - libspdm_send_receive_psk_finish - %x\n",
378 : : status));
379 : : }
380 : : #else /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
381 : : LIBSPDM_ASSERT(false);
382 : : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
383 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
384 : : }
385 : :
386 : 3 : return status;
387 : : }
388 : :
389 : 1 : libspdm_return_t libspdm_stop_session(void *spdm_context, uint32_t session_id,
390 : : uint8_t end_session_attributes)
391 : : {
392 : : libspdm_return_t status;
393 : : libspdm_context_t *context;
394 : :
395 : 1 : context = spdm_context;
396 : :
397 : 1 : status = libspdm_send_receive_end_session(context, session_id, end_session_attributes);
398 : 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_stop_session - %x\n", status));
399 : :
400 : 1 : return status;
401 : : }
402 : : #endif /* (LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP) */
403 : :
404 : 5 : libspdm_return_t libspdm_send_data(void *spdm_context, const uint32_t *session_id,
405 : : bool is_app_message,
406 : : const void *request, size_t request_size)
407 : : {
408 : : libspdm_return_t status;
409 : : libspdm_context_t *context;
410 : : spdm_message_header_t *spdm_request;
411 : : size_t spdm_request_size;
412 : : uint8_t *message;
413 : : size_t message_size;
414 : : size_t transport_header_size;
415 : :
416 : 5 : context = spdm_context;
417 : 5 : transport_header_size = context->local_context.capability.transport_header_size;
418 : :
419 : 5 : status = libspdm_acquire_sender_buffer(context, &message_size, (void **)&message);
420 [ + + ]: 5 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
421 : 1 : return status;
422 : : }
423 [ - + ]: 4 : LIBSPDM_ASSERT (message_size >= transport_header_size +
424 : : context->local_context.capability.transport_tail_size);
425 : 4 : spdm_request = (void *)(message + transport_header_size);
426 : 4 : spdm_request_size = message_size - transport_header_size -
427 : 4 : context->local_context.capability.transport_tail_size;
428 : :
429 [ - + ]: 4 : LIBSPDM_ASSERT (spdm_request_size >= request_size);
430 : 4 : libspdm_copy_mem (spdm_request, spdm_request_size, request, request_size);
431 : 4 : spdm_request_size = request_size;
432 : :
433 : 4 : status = libspdm_send_request(context, session_id, is_app_message,
434 : : spdm_request_size, spdm_request);
435 : :
436 : 4 : libspdm_release_sender_buffer(context);
437 : :
438 : 4 : return status;
439 : : }
440 : :
441 : 4 : libspdm_return_t libspdm_receive_data(void *spdm_context, const uint32_t *session_id,
442 : : bool is_app_message,
443 : : void *response, size_t *response_size)
444 : : {
445 : : libspdm_return_t status;
446 : : libspdm_context_t *context;
447 : : spdm_error_response_t *spdm_response;
448 : : size_t spdm_response_size;
449 : : uint8_t *message;
450 : : size_t message_size;
451 : :
452 : 4 : context = spdm_context;
453 : :
454 : 4 : status = libspdm_acquire_receiver_buffer(context, &message_size, (void **)&message);
455 [ + + ]: 4 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
456 : 1 : return status;
457 : : }
458 : :
459 : 3 : spdm_response = (void *)(message);
460 : 3 : spdm_response_size = message_size;
461 : :
462 : 3 : status = libspdm_receive_response(context, session_id, is_app_message,
463 : : &spdm_response_size, (void **)&spdm_response);
464 [ + + ]: 3 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
465 : 1 : libspdm_release_receiver_buffer (context);
466 : 1 : return status;
467 : : }
468 : :
469 [ - + ]: 2 : if (spdm_response->header.request_response_code == SPDM_ERROR) {
470 [ # # # # ]: 0 : if ((spdm_response->header.param1 == SPDM_ERROR_CODE_DECRYPT_ERROR) &&
471 : : (session_id != NULL)) {
472 : 0 : libspdm_free_session_id(context, *session_id);
473 : 0 : libspdm_release_receiver_buffer (context);
474 : 0 : return LIBSPDM_STATUS_SESSION_MSG_ERROR;
475 : : }
476 : : }
477 : :
478 [ + + ]: 2 : if (*response_size >= spdm_response_size) {
479 : 1 : libspdm_copy_mem (response, *response_size, spdm_response, spdm_response_size);
480 : 1 : *response_size = spdm_response_size;
481 : : } else {
482 : 1 : *response_size = spdm_response_size;
483 : 1 : libspdm_release_receiver_buffer (context);
484 : 1 : return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
485 : : }
486 : :
487 : 1 : libspdm_release_receiver_buffer(context);
488 : :
489 : 1 : return LIBSPDM_STATUS_SUCCESS;
490 : : }
491 : :
492 : 11 : libspdm_return_t libspdm_send_receive_data(void *spdm_context, const uint32_t *session_id,
493 : : bool is_app_message,
494 : : const void *request, size_t request_size,
495 : : void *response, size_t *response_size)
496 : : {
497 : : libspdm_return_t status;
498 : :
499 [ + + ]: 11 : if (!is_app_message) {
500 : 6 : return libspdm_send_receive_spdm_data(spdm_context, session_id,
501 : : request, request_size,
502 : : response, response_size);
503 : : } else {
504 : 5 : status = libspdm_send_data(spdm_context, session_id, is_app_message, request, request_size);
505 : :
506 [ + + ]: 5 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
507 : 1 : return status;
508 : : }
509 : :
510 : 4 : return libspdm_receive_data(spdm_context, session_id, is_app_message, response, response_size);
511 : : }
512 : : }
513 : :
514 : :
515 : 6 : static libspdm_return_t libspdm_send_spdm_data(void *spdm_context, const uint32_t *session_id,
516 : : const void *request, size_t request_size)
517 : : {
518 : : libspdm_return_t status;
519 : : libspdm_context_t *context;
520 : : spdm_message_header_t *spdm_request;
521 : : size_t spdm_request_size;
522 : : uint8_t *message;
523 : : size_t message_size;
524 : : size_t transport_header_size;
525 : :
526 : 6 : context = spdm_context;
527 : 6 : transport_header_size = context->local_context.capability.transport_header_size;
528 : :
529 : 6 : status = libspdm_acquire_sender_buffer(context, &message_size, (void **)&message);
530 [ + + ]: 6 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
531 : 1 : return status;
532 : : }
533 [ - + ]: 5 : LIBSPDM_ASSERT (message_size >= transport_header_size +
534 : : context->local_context.capability.transport_tail_size);
535 : 5 : spdm_request = (void *)(message + transport_header_size);
536 : 5 : spdm_request_size = message_size - transport_header_size -
537 : 5 : context->local_context.capability.transport_tail_size;
538 : :
539 [ - + ]: 5 : LIBSPDM_ASSERT (spdm_request_size >= request_size);
540 : 5 : libspdm_copy_mem (spdm_request, spdm_request_size, request, request_size);
541 : 5 : spdm_request_size = request_size;
542 : :
543 : 5 : status = libspdm_send_spdm_request(context, session_id,
544 : : spdm_request_size, spdm_request);
545 : :
546 : 5 : libspdm_release_sender_buffer(context);
547 : :
548 : 5 : return status;
549 : : }
550 : :
551 : 5 : static libspdm_return_t libspdm_receive_spdm_data(void *spdm_context, const uint32_t *session_id,
552 : : void *response, size_t *response_size)
553 : : {
554 : : libspdm_return_t status;
555 : : libspdm_context_t *context;
556 : : spdm_error_response_t *spdm_response;
557 : : size_t spdm_response_size;
558 : : uint8_t *message;
559 : : size_t message_size;
560 : :
561 : 5 : context = spdm_context;
562 : :
563 : 5 : status = libspdm_acquire_receiver_buffer(context, &message_size, (void **)&message);
564 [ + + ]: 5 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
565 : 1 : return status;
566 : : }
567 : :
568 : 4 : spdm_response = (void *)(message);
569 : 4 : spdm_response_size = message_size;
570 : :
571 : 4 : status = libspdm_receive_spdm_response(context, session_id,
572 : : &spdm_response_size, (void **)&spdm_response);
573 [ + + ]: 4 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
574 : 1 : libspdm_release_receiver_buffer (context);
575 : 1 : return status;
576 : : }
577 : :
578 [ + + ]: 3 : if (spdm_response->header.request_response_code == SPDM_ERROR) {
579 [ + - + - ]: 1 : if ((spdm_response->header.param1 == SPDM_ERROR_CODE_DECRYPT_ERROR) &&
580 : : (session_id != NULL)) {
581 : 1 : libspdm_free_session_id(context, *session_id);
582 : 1 : libspdm_release_receiver_buffer (context);
583 : 1 : return LIBSPDM_STATUS_SESSION_MSG_ERROR;
584 : : }
585 : : }
586 : :
587 [ + + ]: 2 : if (*response_size >= spdm_response_size) {
588 : 1 : libspdm_copy_mem (response, *response_size, spdm_response, spdm_response_size);
589 : 1 : *response_size = spdm_response_size;
590 : : } else {
591 : 1 : *response_size = spdm_response_size;
592 : 1 : libspdm_release_receiver_buffer (context);
593 : 1 : return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
594 : : }
595 : :
596 : 1 : libspdm_release_receiver_buffer(context);
597 : :
598 : 1 : return LIBSPDM_STATUS_SUCCESS;
599 : : }
600 : :
601 : :
602 : 6 : libspdm_return_t libspdm_send_receive_spdm_data(void *spdm_context, const uint32_t *session_id,
603 : : const void *request, size_t request_size,
604 : : void *response, size_t *response_size)
605 : : {
606 : : libspdm_return_t status;
607 : :
608 : 6 : status = libspdm_send_spdm_data(spdm_context, session_id, request, request_size);
609 : :
610 [ + + ]: 6 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
611 : 1 : return status;
612 : : }
613 : :
614 : 5 : return libspdm_receive_spdm_data(spdm_context, session_id, response, response_size);
615 : : }
|