Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2025 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 : * This function validates the Responder's capabilities.
11 : *
12 : * @param capabilities_flag The Responder's CAPABILITIES.Flags field.
13 : * @param version The SPDM message version.
14 : *
15 : * @retval true The field is valid.
16 : * @retval false The field is invalid.
17 : **/
18 36 : static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t version)
19 : {
20 : /*uint8_t cache_cap = (uint8_t)(capabilities_flag)&0x01;*/
21 36 : const uint8_t cert_cap = (uint8_t)(capabilities_flag >> 1) & 0x01;
22 36 : const uint8_t chal_cap = (uint8_t)(capabilities_flag >> 2) & 0x01;
23 36 : const uint8_t meas_cap = (uint8_t)(capabilities_flag >> 3) & 0x03;
24 36 : const uint8_t meas_fresh_cap = (uint8_t)(capabilities_flag >> 5) & 0x01;
25 36 : const uint8_t encrypt_cap = (uint8_t)(capabilities_flag >> 6) & 0x01;
26 36 : const uint8_t mac_cap = (uint8_t)(capabilities_flag >> 7) & 0x01;
27 36 : const uint8_t mut_auth_cap = (uint8_t)(capabilities_flag >> 8) & 0x01;
28 36 : const uint8_t key_ex_cap = (uint8_t)(capabilities_flag >> 9) & 0x01;
29 36 : const uint8_t psk_cap = (uint8_t)(capabilities_flag >> 10) & 0x03;
30 36 : const uint8_t encap_cap = (uint8_t)(capabilities_flag >> 12) & 0x01;
31 36 : const uint8_t hbeat_cap = (uint8_t)(capabilities_flag >> 13) & 0x01;
32 36 : const uint8_t key_upd_cap = (uint8_t)(capabilities_flag >> 14) & 0x01;
33 36 : const uint8_t handshake_in_the_clear_cap = (uint8_t)(capabilities_flag >> 15) & 0x01;
34 36 : const uint8_t pub_key_id_cap = (uint8_t)(capabilities_flag >> 16) & 0x01;
35 : /* uint8_t chunk_cap = (uint8_t)(capabilities_flag >> 17) & 0x01; */
36 36 : const uint8_t alias_cert_cap = (uint8_t)(capabilities_flag >> 18) & 0x01;
37 36 : const uint8_t set_cert_cap = (uint8_t)(capabilities_flag >> 19) & 0x01;
38 36 : const uint8_t csr_cap = (uint8_t)(capabilities_flag >> 20) & 0x01;
39 36 : const uint8_t cert_install_reset_cap = (uint8_t)(capabilities_flag >> 21) & 0x01;
40 36 : const uint8_t ep_info_cap = (uint8_t)(capabilities_flag >> 22) & 0x03;
41 : /* const uint8_t mel_cap = (uint8_t)(capabilities_flag >> 24) & 0x01; */
42 36 : const uint8_t event_cap = (uint8_t)(capabilities_flag >> 25) & 0x01;
43 36 : const uint8_t multi_key_cap = (uint8_t)(capabilities_flag >> 26) & 0x03;
44 36 : const uint8_t get_key_pair_info_cap = (uint8_t)(capabilities_flag >> 28) & 0x01;
45 36 : const uint8_t set_key_pair_info_cap = (uint8_t)(capabilities_flag >> 29) & 0x01;
46 36 : const uint8_t set_key_pair_reset_cap = (uint8_t)(capabilities_flag >> 30) & 0x01;
47 : /* const uint8_t large_resp_cap = (uint8_t)(capabilities_flag >> 31) & 0x01; */
48 :
49 : /* Checks common to all SPDM versions. */
50 :
51 : /* Illegal to return reserved value. */
52 36 : if (meas_cap == 3) {
53 1 : return false;
54 : }
55 :
56 : /* If MEAS_FRESH_CAP is set then MEAS_CAP must be set. */
57 35 : if ((meas_cap == 0) && (meas_fresh_cap == 1)) {
58 1 : return false;
59 : }
60 :
61 34 : if (version == SPDM_MESSAGE_VERSION_10) {
62 : /* If measurements are not signed then CERT_CAP must equal CHAL_CAP.
63 : * If measurements are signed then CERT_CAP must be set. */
64 7 : if ((meas_cap == 0) || (meas_cap == 1)) {
65 5 : if (cert_cap != chal_cap) {
66 1 : return false;
67 : }
68 2 : } else if (meas_cap == 2) {
69 2 : if (cert_cap == 0) {
70 1 : return false;
71 : }
72 : }
73 5 : return true;
74 : }
75 :
76 : /* Checks common to 1.1 and higher. */
77 27 : if (version >= SPDM_MESSAGE_VERSION_11) {
78 : /* Illegal to return reserved values. */
79 27 : if (psk_cap == 3) {
80 1 : return false;
81 : }
82 :
83 : /* Checks that originate from key exchange capabilities. */
84 26 : if ((key_ex_cap == 1) || (psk_cap != 0)) {
85 12 : if ((mac_cap == 0) && (encrypt_cap == 0)) {
86 4 : return false;
87 : }
88 : } else {
89 14 : if ((mac_cap == 1) || (encrypt_cap == 1) || (handshake_in_the_clear_cap == 1) ||
90 11 : (hbeat_cap == 1) || (key_upd_cap == 1)) {
91 3 : return false;
92 : }
93 11 : if (version >= SPDM_MESSAGE_VERSION_13) {
94 1 : if (event_cap == 1) {
95 0 : return false;
96 : }
97 : }
98 : }
99 19 : if ((key_ex_cap == 0) && (psk_cap != 0)) {
100 1 : if (handshake_in_the_clear_cap == 1) {
101 1 : return false;
102 : }
103 : }
104 :
105 : /* Checks that originate from certificate or public key capabilities. */
106 18 : if ((cert_cap == 1) || (pub_key_id_cap == 1)) {
107 : /* Certificate capabilities and public key capabilities cannot both be set. */
108 13 : if ((cert_cap == 1) && (pub_key_id_cap == 1)) {
109 1 : return false;
110 : }
111 : /* If certificates or public keys are enabled then at least one of these capabilities
112 : * must be enabled to use the key. */
113 12 : if ((chal_cap == 0) && (key_ex_cap == 0) && ((meas_cap == 0) || (meas_cap == 1))) {
114 1 : if (version >= SPDM_MESSAGE_VERSION_13) {
115 0 : if ((ep_info_cap == 0) || (ep_info_cap == 1)) {
116 0 : return false;
117 : }
118 : } else {
119 1 : return false;
120 : }
121 : }
122 : } else {
123 : /* If certificates or public keys are not enabled then these capabilities
124 : * cannot be enabled. */
125 5 : if ((chal_cap == 1) || (key_ex_cap == 1) || (meas_cap == 2) || (mut_auth_cap == 1)) {
126 1 : return false;
127 : }
128 4 : if (version >= SPDM_MESSAGE_VERSION_13) {
129 1 : if (ep_info_cap == 2) {
130 1 : return false;
131 : }
132 : }
133 : }
134 :
135 : /* Checks that originate from mutual authentication capabilities. */
136 14 : if (mut_auth_cap == 1) {
137 : /* Mutual authentication with asymmetric keys can only occur through the basic mutual
138 : * authentication flow (CHAL_CAP == 1) or the session-based mutual authentication flow
139 : * (KEY_EX_CAP == 1). */
140 5 : if ((key_ex_cap == 0) && (chal_cap == 0)) {
141 0 : return false;
142 : }
143 : }
144 : }
145 :
146 : /* Checks specific to 1.1. */
147 14 : if (version == SPDM_MESSAGE_VERSION_11) {
148 3 : if ((mut_auth_cap == 1) && (encap_cap == 0)) {
149 1 : return false;
150 : }
151 : }
152 :
153 : /* Checks common to 1.2 and higher. */
154 13 : if (version >= SPDM_MESSAGE_VERSION_12) {
155 11 : if ((cert_cap == 0) && ((alias_cert_cap == 1) || (set_cert_cap == 1))) {
156 1 : return false;
157 : }
158 10 : if ((csr_cap == 1) && (set_cert_cap == 0)) {
159 1 : return false;
160 : }
161 9 : if ((cert_install_reset_cap == 1) && (csr_cap == 0) && (set_cert_cap == 0)) {
162 1 : return false;
163 : }
164 : }
165 :
166 : /* Checks specific to 1.3 and higher. */
167 10 : if (version >= SPDM_MESSAGE_VERSION_13) {
168 : /* Illegal to return reserved values. */
169 2 : if ((ep_info_cap == 3) || (multi_key_cap == 3)) {
170 0 : return false;
171 : }
172 2 : if ((multi_key_cap != 0) && ((get_key_pair_info_cap == 0) || (cert_cap == 0))) {
173 0 : return false;
174 : }
175 2 : if (pub_key_id_cap == 1) {
176 0 : if ((multi_key_cap != 0) || (get_key_pair_info_cap == 1) ||
177 : (set_key_pair_info_cap == 1)) {
178 0 : return false;
179 : }
180 : }
181 : }
182 :
183 : /* Checks that are deferred to when a message is sent.
184 : *
185 : * If the Responder supports key exchange then MAC_CAP must be set. In addition, if the
186 : * negotiated SPDM version is greater than 1.1 then the negotiated opaque data format must be
187 : * OpaqueDataFmt1.
188 : */
189 :
190 : /* Checks specific to 1.4 and higher. */
191 10 : if (version >= SPDM_MESSAGE_VERSION_14) {
192 0 : if ((set_key_pair_reset_cap == 1) && (set_key_pair_info_cap == 0)) {
193 0 : return false;
194 : }
195 : }
196 :
197 10 : return true;
198 : }
199 :
200 : /**
201 : * This function sends GET_CAPABILITIES and receives CAPABILITIES.
202 : *
203 : * @param spdm_context A pointer to the SPDM context.
204 : *
205 : * @retval LIBSPDM_STATUS_SUCCESS
206 : * GET_CAPABILITIES was sent and CAPABILITIES was received.
207 : * @retval LIBSPDM_STATUS_INVALID_STATE_LOCAL
208 : * Cannot send GET_CAPABILITIES due to Requester's state. Send GET_VERSION first.
209 : * @retval LIBSPDM_STATUS_INVALID_MSG_SIZE
210 : * The size of the CAPABILITIES response is invalid.
211 : * @retval LIBSPDM_STATUS_INVALID_MSG_FIELD
212 : * The CAPABILITIES response contains one or more invalid fields.
213 : * @retval LIBSPDM_STATUS_ERROR_PEER
214 : * The Responder returned an unexpected error.
215 : * @retval LIBSPDM_STATUS_BUSY_PEER
216 : * The Responder continually returned Busy error messages.
217 : * @retval LIBSPDM_STATUS_RESYNCH_PEER
218 : * The Responder returned a RequestResynch error message.
219 : * @retval LIBSPDM_STATUS_BUFFER_FULL
220 : * The buffer used to store transcripts is exhausted.
221 : **/
222 69 : static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_context,
223 : size_t *supported_algs_length,
224 : void *supported_algs)
225 : {
226 : libspdm_return_t status;
227 : spdm_get_capabilities_request_t *spdm_request;
228 : size_t spdm_request_size;
229 : spdm_capabilities_response_t *spdm_response;
230 : size_t spdm_response_size;
231 : uint8_t *message;
232 : size_t message_size;
233 : size_t transport_header_size;
234 :
235 : /* -=[Verify State Phase]=- */
236 69 : if (spdm_context->connection_info.connection_state != LIBSPDM_CONNECTION_STATE_AFTER_VERSION) {
237 1 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
238 : }
239 68 : libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_GET_CAPABILITIES);
240 :
241 : /* -=[Construct Request Phase]=- */
242 68 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
243 68 : status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
244 68 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
245 1 : return status;
246 : }
247 67 : LIBSPDM_ASSERT (message_size >= transport_header_size +
248 : spdm_context->local_context.capability.transport_tail_size);
249 67 : spdm_request = (void *)(message + transport_header_size);
250 67 : spdm_request_size = message_size - transport_header_size -
251 67 : spdm_context->local_context.capability.transport_tail_size;
252 :
253 67 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_request->header));
254 :
255 67 : libspdm_zero_mem(spdm_request, spdm_request_size);
256 67 : spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
257 67 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
258 12 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_get_capabilities_request_t));
259 12 : spdm_request_size = sizeof(spdm_get_capabilities_request_t);
260 55 : } else if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
261 35 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_get_capabilities_request_t) -
262 : sizeof(spdm_request->data_transfer_size) -
263 : sizeof(spdm_request->max_spdm_msg_size));
264 35 : spdm_request_size = sizeof(spdm_get_capabilities_request_t) -
265 : sizeof(spdm_request->data_transfer_size) -
266 : sizeof(spdm_request->max_spdm_msg_size);
267 : } else {
268 20 : spdm_request_size = sizeof(spdm_request->header);
269 : }
270 67 : spdm_request->header.request_response_code = SPDM_GET_CAPABILITIES;
271 67 : spdm_request->header.param1 = 0;
272 67 : spdm_request->header.param2 = 0;
273 67 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
274 47 : spdm_request->ct_exponent = spdm_context->local_context.capability.ct_exponent;
275 47 : spdm_request->flags =
276 47 : libspdm_mask_capability_flags(spdm_context, true,
277 : spdm_context->local_context.capability.flags);
278 : }
279 :
280 67 : if (supported_algs != NULL) {
281 1 : LIBSPDM_ASSERT((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
282 : ((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) != 0));
283 :
284 1 : spdm_request->header.param1 |= SPDM_GET_CAPABILITIES_REQUEST_PARAM1_SUPPORTED_ALGORITHMS;
285 : }
286 :
287 67 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
288 12 : spdm_request->data_transfer_size =
289 12 : spdm_context->local_context.capability.data_transfer_size;
290 12 : spdm_request->max_spdm_msg_size =
291 12 : spdm_context->local_context.capability.max_spdm_msg_size;
292 : }
293 67 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
294 0 : spdm_request->ext_flags =
295 0 : libspdm_mask_capability_ext_flags(spdm_context, true,
296 0 : spdm_context->local_context.capability.ext_flags);
297 : } else {
298 67 : spdm_request->ext_flags = 0;
299 : }
300 :
301 : /* -=[Send Request Phase]=- */
302 67 : status = libspdm_send_spdm_request(spdm_context, NULL, spdm_request_size, spdm_request);
303 67 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
304 1 : libspdm_release_sender_buffer (spdm_context);
305 1 : return status;
306 : }
307 66 : libspdm_release_sender_buffer (spdm_context);
308 66 : spdm_request = (void *)spdm_context->last_spdm_request;
309 :
310 : /* -=[Receive Response Phase]=- */
311 66 : status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
312 66 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
313 1 : return status;
314 : }
315 65 : LIBSPDM_ASSERT (message_size >= transport_header_size);
316 65 : spdm_response = (void *)(message);
317 65 : spdm_response_size = message_size;
318 :
319 65 : status = libspdm_receive_spdm_response(spdm_context, NULL, &spdm_response_size,
320 : (void **)&spdm_response);
321 65 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
322 3 : goto receive_done;
323 : }
324 :
325 : /* -=[Validate Response Phase]=- */
326 62 : if (spdm_response_size < sizeof(spdm_message_header_t)) {
327 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
328 0 : goto receive_done;
329 : }
330 62 : if (spdm_response->header.request_response_code == SPDM_ERROR) {
331 23 : status = libspdm_handle_simple_error_response(
332 23 : spdm_context, spdm_response->header.param1);
333 23 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
334 23 : goto receive_done;
335 : }
336 39 : } else if (spdm_response->header.request_response_code != SPDM_CAPABILITIES) {
337 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
338 1 : goto receive_done;
339 : }
340 38 : if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
341 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
342 1 : goto receive_done;
343 : }
344 37 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
345 12 : if (spdm_response_size < sizeof(spdm_capabilities_response_t)) {
346 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
347 0 : goto receive_done;
348 : }
349 : } else {
350 25 : if (spdm_response_size < sizeof(spdm_capabilities_response_t) -
351 : sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)) {
352 1 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
353 1 : goto receive_done;
354 : }
355 : }
356 :
357 36 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
358 3 : (spdm_request->header.param1 & SPDM_GET_CAPABILITIES_REQUEST_PARAM1_SUPPORTED_ALGORITHMS)) {
359 :
360 1 : spdm_supported_algorithms_block_t *supported_algorithms =
361 1 : (spdm_supported_algorithms_block_t*)((uint8_t*)spdm_response + sizeof(spdm_capabilities_response_t));
362 :
363 1 : spdm_response_size = sizeof(spdm_capabilities_response_t) + supported_algorithms->length;
364 :
365 35 : } else if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
366 11 : spdm_response_size = sizeof(spdm_capabilities_response_t);
367 : } else {
368 24 : spdm_response_size = sizeof(spdm_capabilities_response_t) -
369 : sizeof(spdm_response->data_transfer_size) -
370 : sizeof(spdm_response->max_spdm_msg_size);
371 : }
372 :
373 36 : if (!validate_responder_capability(spdm_response->flags, spdm_response->header.spdm_version)) {
374 21 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
375 21 : goto receive_done;
376 : }
377 15 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
378 8 : if ((spdm_response->data_transfer_size < SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) ||
379 7 : (spdm_response->data_transfer_size > spdm_response->max_spdm_msg_size)) {
380 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
381 2 : goto receive_done;
382 : }
383 :
384 6 : if (((spdm_response->flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP) == 0) &&
385 2 : (spdm_response->data_transfer_size != spdm_response->max_spdm_msg_size)) {
386 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
387 1 : goto receive_done;
388 : }
389 : }
390 :
391 12 : if (spdm_response->ct_exponent > LIBSPDM_MAX_CT_EXPONENT) {
392 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
393 1 : goto receive_done;
394 : }
395 :
396 : /* -=[Process Response Phase]=- */
397 11 : status = libspdm_append_message_a(spdm_context, spdm_request, spdm_request_size);
398 11 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
399 1 : goto receive_done;
400 : }
401 :
402 10 : status = libspdm_append_message_a(spdm_context, spdm_response, spdm_response_size);
403 10 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
404 0 : goto receive_done;
405 : }
406 :
407 10 : spdm_context->connection_info.capability.ct_exponent = spdm_response->ct_exponent;
408 10 : spdm_context->connection_info.capability.flags =
409 10 : libspdm_mask_capability_flags(spdm_context, false, spdm_response->flags);
410 :
411 10 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
412 0 : spdm_context->connection_info.capability.ext_flags =
413 0 : libspdm_mask_capability_ext_flags(spdm_context, false, spdm_response->ext_flags);
414 : } else {
415 10 : spdm_context->connection_info.capability.ext_flags = 0;
416 : }
417 :
418 10 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
419 3 : spdm_context->connection_info.capability.data_transfer_size =
420 3 : spdm_response->data_transfer_size;
421 3 : spdm_context->connection_info.capability.max_spdm_msg_size =
422 3 : spdm_response->max_spdm_msg_size;
423 : } else {
424 7 : spdm_context->connection_info.capability.data_transfer_size = 0;
425 7 : spdm_context->connection_info.capability.max_spdm_msg_size = 0;
426 : }
427 :
428 : /* Copy algorithms if requested and received */
429 10 : if (supported_algs != NULL &&
430 1 : spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
431 1 : (spdm_request->header.param1 & SPDM_GET_CAPABILITIES_REQUEST_PARAM1_SUPPORTED_ALGORITHMS)) {
432 :
433 1 : spdm_supported_algorithms_block_t *supported_algorithms =
434 1 : (spdm_supported_algorithms_block_t*)((uint8_t*)spdm_response +
435 : sizeof(spdm_capabilities_response_t));
436 :
437 1 : size_t algorithm_data_size = spdm_response_size - sizeof(spdm_capabilities_response_t);
438 :
439 1 : if (*supported_algs_length >= algorithm_data_size) {
440 1 : libspdm_copy_mem(supported_algs, *supported_algs_length,
441 : supported_algorithms, algorithm_data_size);
442 1 : *supported_algs_length = algorithm_data_size;
443 : } else {
444 0 : *supported_algs_length = algorithm_data_size;
445 0 : status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
446 0 : goto receive_done;
447 : }
448 : }
449 :
450 : /* -=[Update State Phase]=- */
451 10 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
452 10 : status = LIBSPDM_STATUS_SUCCESS;
453 :
454 : /* -=[Log Message Phase]=- */
455 : #if LIBSPDM_ENABLE_MSG_LOG
456 10 : libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
457 : #endif /* LIBSPDM_ENABLE_MSG_LOG */
458 :
459 65 : receive_done:
460 65 : libspdm_release_receiver_buffer (spdm_context);
461 65 : return status;
462 : }
463 :
464 67 : libspdm_return_t libspdm_get_capabilities(libspdm_context_t *spdm_context)
465 : {
466 : size_t retry;
467 : uint64_t retry_delay_time;
468 : libspdm_return_t status;
469 :
470 67 : spdm_context->crypto_request = false;
471 67 : retry = spdm_context->retry_times;
472 67 : retry_delay_time = spdm_context->retry_delay_time;
473 : do {
474 68 : status = libspdm_try_get_capabilities(spdm_context, NULL, NULL);
475 68 : if (status != LIBSPDM_STATUS_BUSY_PEER) {
476 66 : return status;
477 : }
478 :
479 2 : libspdm_sleep(retry_delay_time);
480 2 : } while (retry-- != 0);
481 :
482 1 : return status;
483 : }
484 :
485 1 : libspdm_return_t libspdm_get_capabilities_with_supported_algs(libspdm_context_t *spdm_context,
486 : size_t *supported_algs_length,
487 : void *supported_algs)
488 : {
489 : size_t retry;
490 : uint64_t retry_delay_time;
491 : libspdm_return_t status;
492 :
493 1 : LIBSPDM_ASSERT((supported_algs == NULL) || (supported_algs_length != NULL));
494 :
495 1 : spdm_context->crypto_request = false;
496 1 : retry = spdm_context->retry_times;
497 1 : retry_delay_time = spdm_context->retry_delay_time;
498 : do {
499 : status =
500 1 : libspdm_try_get_capabilities(spdm_context, supported_algs_length, supported_algs);
501 1 : if (status != LIBSPDM_STATUS_BUSY_PEER) {
502 1 : return status;
503 : }
504 :
505 0 : libspdm_sleep(retry_delay_time);
506 0 : } while (retry-- != 0);
507 :
508 0 : return status;
509 : }
|