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