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 : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
10 :
11 : #pragma pack(1)
12 : typedef struct {
13 : spdm_message_header_t header;
14 : uint8_t cert_chain_hash[LIBSPDM_MAX_HASH_SIZE];
15 : uint8_t nonce[SPDM_NONCE_SIZE];
16 : uint8_t measurement_summary_hash[LIBSPDM_MAX_HASH_SIZE];
17 : uint16_t opaque_length;
18 : uint8_t opaque_data[SPDM_MAX_OPAQUE_DATA_SIZE];
19 : uint8_t requester_context[SPDM_REQ_CONTEXT_SIZE];
20 : uint8_t signature[LIBSPDM_RSP_SIGNATURE_DATA_MAX_SIZE];
21 : } libspdm_challenge_auth_response_max_t;
22 : #pragma pack()
23 :
24 : /**
25 : * This function sends CHALLENGE to authenticate the device based upon the key in one slot.
26 : *
27 : * This function verifies the signature in the challenge auth.
28 : *
29 : * If basic mutual authentication is requested from the responder,
30 : * this function also perform the basic mutual authentication.
31 : *
32 : * @param spdm_context A pointer to the SPDM context.
33 : * @param slot_id The number of slot for the challenge.
34 : * @param requester_context If not NULL, a buffer to hold the requester context (8 bytes).
35 : * It is used only if the negotiated version >= 1.3.
36 : * @param measurement_hash_type The type of the measurement hash.
37 : * @param measurement_hash A pointer to a destination buffer to store the measurement hash.
38 : * @param slot_mask A pointer to a destination to store the slot mask.
39 : * @param requester_nonce_in If not NULL, a buffer that holds the requester nonce (32 bytes)
40 : * @param requester_nonce If not NULL, a buffer to hold the requester nonce (32 bytes).
41 : * @param responder_nonce If not NULL, a buffer to hold the responder nonce (32 bytes).
42 : *
43 : * @retval RETURN_SUCCESS The challenge auth is got successfully.
44 : * @retval RETURN_DEVICE_ERROR A device error occurs when communicates with the device.
45 : * @retval RETURN_SECURITY_VIOLATION Any verification fails.
46 : **/
47 48 : static libspdm_return_t libspdm_try_challenge(libspdm_context_t *spdm_context,
48 : uint8_t slot_id,
49 : const void *requester_context,
50 : uint8_t measurement_hash_type,
51 : void *measurement_hash,
52 : uint8_t *slot_mask,
53 : const void *requester_nonce_in,
54 : void *requester_nonce,
55 : void *responder_nonce,
56 : void *opaque_data,
57 : size_t *opaque_data_size)
58 : {
59 : libspdm_return_t status;
60 : bool result;
61 : spdm_challenge_request_t *spdm_request;
62 : size_t spdm_request_size;
63 : libspdm_challenge_auth_response_max_t *spdm_response;
64 : size_t spdm_response_size;
65 : uint8_t *ptr;
66 : void *cert_chain_hash;
67 : size_t hash_size;
68 : uint32_t measurement_summary_hash_size;
69 : void *nonce;
70 : void *measurement_summary_hash;
71 : uint16_t opaque_length;
72 : void *signature;
73 : size_t signature_size;
74 : uint8_t auth_attribute;
75 : uint8_t *message;
76 : size_t message_size;
77 : size_t transport_header_size;
78 :
79 : /* -=[Check Parameters Phase]=- */
80 48 : LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xff));
81 48 : LIBSPDM_ASSERT((slot_id != 0xff) ||
82 : (spdm_context->local_context.peer_public_key_provision_size != 0));
83 48 : LIBSPDM_ASSERT(measurement_hash_type == SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH ||
84 : measurement_hash_type == SPDM_CHALLENGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH ||
85 : measurement_hash_type == SPDM_CHALLENGE_REQUEST_ALL_MEASUREMENTS_HASH);
86 :
87 : /* -=[Verify State Phase]=- */
88 48 : if (!libspdm_is_capabilities_flag_supported(
89 : spdm_context, true, 0,
90 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP)) {
91 1 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
92 : }
93 47 : if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
94 1 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
95 : }
96 :
97 46 : libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_CHALLENGE);
98 :
99 : /* -=[Construct Request Phase]=- */
100 46 : spdm_context->connection_info.peer_used_cert_chain_slot_id = slot_id;
101 46 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
102 46 : status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
103 46 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
104 0 : return status;
105 : }
106 46 : LIBSPDM_ASSERT (message_size >= transport_header_size +
107 : spdm_context->local_context.capability.transport_tail_size);
108 46 : spdm_request = (void *)(message + transport_header_size);
109 46 : spdm_request_size = message_size - transport_header_size -
110 46 : spdm_context->local_context.capability.transport_tail_size;
111 :
112 46 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_challenge_request_t));
113 46 : spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
114 46 : spdm_request->header.request_response_code = SPDM_CHALLENGE;
115 46 : spdm_request->header.param1 = slot_id;
116 46 : spdm_request->header.param2 = measurement_hash_type;
117 46 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
118 2 : LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_challenge_request_t) +
119 : SPDM_REQ_CONTEXT_SIZE);
120 2 : spdm_request_size = sizeof(spdm_challenge_request_t) + SPDM_REQ_CONTEXT_SIZE;
121 : } else {
122 44 : spdm_request_size = sizeof(spdm_challenge_request_t);
123 : }
124 46 : if (requester_nonce_in == NULL) {
125 46 : if (!libspdm_get_random_number(SPDM_NONCE_SIZE, spdm_request->nonce)) {
126 0 : libspdm_release_sender_buffer (spdm_context);
127 0 : return LIBSPDM_STATUS_LOW_ENTROPY;
128 : }
129 : } else {
130 0 : libspdm_copy_mem(spdm_request->nonce, sizeof(spdm_request->nonce),
131 : requester_nonce_in, SPDM_NONCE_SIZE);
132 : }
133 46 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterNonce - "));
134 46 : LIBSPDM_INTERNAL_DUMP_DATA(spdm_request->nonce, SPDM_NONCE_SIZE);
135 46 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
136 46 : if (requester_nonce != NULL) {
137 0 : libspdm_copy_mem(requester_nonce, SPDM_NONCE_SIZE, spdm_request->nonce, SPDM_NONCE_SIZE);
138 : }
139 46 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
140 2 : if (requester_context == NULL) {
141 0 : libspdm_zero_mem(spdm_request + 1, SPDM_REQ_CONTEXT_SIZE);
142 : } else {
143 2 : libspdm_copy_mem(spdm_request + 1, SPDM_REQ_CONTEXT_SIZE,
144 : requester_context, SPDM_REQ_CONTEXT_SIZE);
145 : }
146 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterContext - "));
147 2 : LIBSPDM_INTERNAL_DUMP_DATA((uint8_t *)(spdm_request + 1), SPDM_REQ_CONTEXT_SIZE);
148 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
149 : }
150 :
151 : /* -=[Send Request Phase]=- */
152 46 : status = libspdm_send_spdm_request(spdm_context, NULL, spdm_request_size, spdm_request);
153 46 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
154 1 : libspdm_release_sender_buffer (spdm_context);
155 1 : return status;
156 : }
157 45 : libspdm_release_sender_buffer (spdm_context);
158 45 : spdm_request = (void *)spdm_context->last_spdm_request;
159 :
160 : /* -=[Receive Response Phase]=- */
161 45 : status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
162 45 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
163 0 : return status;
164 : }
165 45 : LIBSPDM_ASSERT (message_size >= transport_header_size);
166 45 : spdm_response = (void *)(message);
167 45 : spdm_response_size = message_size;
168 :
169 45 : status = libspdm_receive_spdm_response(
170 : spdm_context, NULL, &spdm_response_size, (void **)&spdm_response);
171 45 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
172 0 : goto receive_done;
173 : }
174 :
175 : /* -=[Validate Response Phase]=- */
176 45 : if (spdm_response_size < sizeof(spdm_message_header_t)) {
177 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
178 0 : goto receive_done;
179 : }
180 45 : if (spdm_response->header.request_response_code == SPDM_ERROR) {
181 24 : status = libspdm_handle_error_response_main(
182 : spdm_context, NULL,
183 : &spdm_response_size,
184 : (void **)&spdm_response, SPDM_CHALLENGE, SPDM_CHALLENGE_AUTH);
185 24 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
186 23 : goto receive_done;
187 : }
188 21 : } else if (spdm_response->header.request_response_code != SPDM_CHALLENGE_AUTH) {
189 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
190 1 : goto receive_done;
191 : }
192 21 : if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
193 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
194 1 : goto receive_done;
195 : }
196 20 : if (spdm_response_size < sizeof(spdm_challenge_auth_response_t)) {
197 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
198 0 : goto receive_done;
199 : }
200 20 : auth_attribute = spdm_response->header.param1;
201 20 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11 && slot_id == 0xFF) {
202 1 : if ((auth_attribute & SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_SLOT_ID_MASK) != 0xF) {
203 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
204 0 : goto receive_done;
205 : }
206 : } else {
207 19 : if ((spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11 &&
208 19 : (auth_attribute & SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_SLOT_ID_MASK) != slot_id) ||
209 18 : (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_10 &&
210 : auth_attribute != slot_id)) {
211 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
212 1 : goto receive_done;
213 : }
214 18 : if ((spdm_response->header.param2 & (1 << slot_id)) == 0) {
215 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
216 1 : goto receive_done;
217 : }
218 : }
219 18 : if ((auth_attribute & SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_BASIC_MUT_AUTH_REQ) != 0) {
220 0 : if (!libspdm_is_capabilities_flag_supported(
221 : spdm_context, true,
222 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP,
223 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP)) {
224 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
225 0 : goto receive_done;
226 : }
227 : }
228 :
229 : /* -=[Process Response Phase]=- */
230 18 : hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
231 18 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
232 0 : signature_size = libspdm_get_pqc_asym_signature_size(
233 : spdm_context->connection_info.algorithm.pqc_asym_algo);
234 : } else {
235 18 : signature_size = libspdm_get_asym_signature_size(
236 : spdm_context->connection_info.algorithm.base_asym_algo);
237 : }
238 18 : measurement_summary_hash_size = libspdm_get_measurement_summary_hash_size(
239 : spdm_context, true, measurement_hash_type);
240 :
241 18 : if (spdm_response_size <= sizeof(spdm_challenge_auth_response_t) +
242 18 : hash_size + SPDM_NONCE_SIZE + measurement_summary_hash_size + sizeof(uint16_t)) {
243 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
244 0 : goto receive_done;
245 : }
246 :
247 18 : ptr = spdm_response->cert_chain_hash;
248 :
249 18 : cert_chain_hash = ptr;
250 18 : ptr += hash_size;
251 18 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "cert_chain_hash (0x%zx) - ", hash_size));
252 18 : LIBSPDM_INTERNAL_DUMP_DATA(cert_chain_hash, hash_size);
253 18 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
254 18 : if (slot_id == 0xFF) {
255 1 : result = libspdm_verify_public_key_hash(spdm_context, cert_chain_hash, hash_size);
256 : } else {
257 17 : result = libspdm_verify_certificate_chain_hash(spdm_context, cert_chain_hash, hash_size);
258 : }
259 18 : if (!result) {
260 0 : status = LIBSPDM_STATUS_VERIF_FAIL;
261 0 : goto receive_done;
262 : }
263 :
264 18 : nonce = ptr;
265 18 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "nonce (0x%x) - ", SPDM_NONCE_SIZE));
266 18 : LIBSPDM_INTERNAL_DUMP_DATA(nonce, SPDM_NONCE_SIZE);
267 18 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
268 18 : ptr += SPDM_NONCE_SIZE;
269 18 : if (responder_nonce != NULL) {
270 0 : libspdm_copy_mem(responder_nonce, SPDM_NONCE_SIZE, nonce, SPDM_NONCE_SIZE);
271 : }
272 :
273 18 : measurement_summary_hash = ptr;
274 18 : ptr += measurement_summary_hash_size;
275 18 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "measurement_summary_hash (0x%x) - ",
276 : measurement_summary_hash_size));
277 18 : LIBSPDM_INTERNAL_DUMP_DATA(measurement_summary_hash, measurement_summary_hash_size);
278 18 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
279 :
280 18 : opaque_length = libspdm_read_uint16((const uint8_t *)ptr);
281 18 : if (opaque_length > SPDM_MAX_OPAQUE_DATA_SIZE) {
282 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
283 1 : goto receive_done;
284 : }
285 17 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
286 4 : if (((spdm_context->connection_info.algorithm.other_params_support &
287 : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) ==
288 1 : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE) &&
289 : (opaque_length != 0)) {
290 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
291 0 : goto receive_done;
292 : }
293 : }
294 17 : ptr += sizeof(uint16_t);
295 17 : if (opaque_length != 0) {
296 2 : result = libspdm_process_general_opaque_data_check(spdm_context, opaque_length, ptr);
297 2 : if (!result) {
298 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
299 0 : goto receive_done;
300 : }
301 : }
302 :
303 17 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
304 2 : if (spdm_response_size <
305 : sizeof(spdm_challenge_auth_response_t) + hash_size +
306 2 : SPDM_NONCE_SIZE + measurement_summary_hash_size +
307 2 : sizeof(uint16_t) + opaque_length + SPDM_REQ_CONTEXT_SIZE +
308 : signature_size) {
309 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
310 0 : goto receive_done;
311 : }
312 2 : spdm_response_size = sizeof(spdm_challenge_auth_response_t) +
313 2 : hash_size + SPDM_NONCE_SIZE +
314 2 : measurement_summary_hash_size + sizeof(uint16_t) +
315 2 : opaque_length + SPDM_REQ_CONTEXT_SIZE + signature_size;
316 : } else {
317 15 : if (spdm_response_size <
318 : sizeof(spdm_challenge_auth_response_t) + hash_size +
319 15 : SPDM_NONCE_SIZE + measurement_summary_hash_size +
320 15 : sizeof(uint16_t) + opaque_length + signature_size) {
321 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
322 0 : goto receive_done;
323 : }
324 15 : spdm_response_size = sizeof(spdm_challenge_auth_response_t) +
325 15 : hash_size + SPDM_NONCE_SIZE +
326 15 : measurement_summary_hash_size + sizeof(uint16_t) +
327 15 : opaque_length + signature_size;
328 : }
329 :
330 17 : if ((opaque_data != NULL) && (opaque_data_size != NULL)) {
331 2 : if (opaque_length >= *opaque_data_size) {
332 0 : status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
333 0 : goto receive_done;
334 : }
335 2 : libspdm_copy_mem(opaque_data, *opaque_data_size, ptr, opaque_length);
336 2 : *opaque_data_size = opaque_length;
337 : }
338 :
339 17 : ptr += opaque_length;
340 17 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
341 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterContext - "));
342 2 : LIBSPDM_INTERNAL_DUMP_DATA(ptr, SPDM_REQ_CONTEXT_SIZE);
343 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
344 2 : if (!libspdm_consttime_is_mem_equal(spdm_request + 1, ptr, SPDM_REQ_CONTEXT_SIZE)) {
345 1 : libspdm_reset_message_c(spdm_context);
346 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
347 1 : goto receive_done;
348 : }
349 1 : ptr += SPDM_REQ_CONTEXT_SIZE;
350 : }
351 :
352 16 : status = libspdm_append_message_c(spdm_context, spdm_request, spdm_request_size);
353 16 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
354 0 : goto receive_done;
355 : }
356 16 : status = libspdm_append_message_c(spdm_context, spdm_response,
357 : spdm_response_size - signature_size);
358 16 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
359 0 : libspdm_reset_message_c(spdm_context);
360 0 : goto receive_done;
361 : }
362 :
363 16 : signature = ptr;
364 16 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "signature (0x%zx):\n", signature_size));
365 16 : LIBSPDM_INTERNAL_DUMP_HEX(signature, signature_size);
366 16 : result = libspdm_verify_challenge_auth_signature(spdm_context, true, signature, signature_size);
367 16 : if (!result) {
368 1 : libspdm_reset_message_c(spdm_context);
369 1 : status = LIBSPDM_STATUS_VERIF_FAIL;
370 1 : goto receive_done;
371 : }
372 :
373 15 : if (measurement_hash != NULL) {
374 15 : libspdm_copy_mem(measurement_hash, measurement_summary_hash_size,
375 : measurement_summary_hash, measurement_summary_hash_size);
376 : }
377 15 : if (slot_mask != NULL) {
378 0 : *slot_mask = spdm_response->header.param2;
379 : }
380 :
381 : /* At this point the Requester has successfully authenticated the Responder, even if the
382 : * the Responder intends to authenticate the Requester. */
383 15 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
384 :
385 : /* -=[Update State Phase]=- */
386 : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP)
387 15 : if ((auth_attribute & SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_BASIC_MUT_AUTH_REQ) != 0) {
388 : /* we must release it here, because libspdm_encapsulated_request() will acquire again. */
389 0 : libspdm_release_receiver_buffer (spdm_context);
390 :
391 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "BasicMutAuth :\n"));
392 0 : status = libspdm_encapsulated_request(spdm_context, NULL, 0, NULL);
393 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
394 : "libspdm_challenge - libspdm_encapsulated_request - %xu\n", status));
395 0 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
396 0 : libspdm_reset_message_c(spdm_context);
397 0 : return status;
398 : }
399 0 : return LIBSPDM_STATUS_SUCCESS;
400 : }
401 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) */
402 :
403 15 : status = LIBSPDM_STATUS_SUCCESS;
404 :
405 45 : receive_done:
406 45 : libspdm_release_receiver_buffer (spdm_context);
407 45 : return status;
408 : }
409 :
410 43 : libspdm_return_t libspdm_challenge(void *spdm_context, void *reserved,
411 : uint8_t slot_id,
412 : uint8_t measurement_hash_type,
413 : void *measurement_hash,
414 : uint8_t *slot_mask)
415 : {
416 : libspdm_context_t *context;
417 : size_t retry;
418 : uint64_t retry_delay_time;
419 : libspdm_return_t status;
420 :
421 43 : context = spdm_context;
422 43 : context->crypto_request = true;
423 43 : retry = context->retry_times;
424 43 : retry_delay_time = context->retry_delay_time;
425 : do {
426 44 : status = libspdm_try_challenge(context, slot_id, NULL,
427 : measurement_hash_type,
428 : measurement_hash, slot_mask,
429 : NULL, NULL, NULL, NULL, NULL);
430 44 : if (status != LIBSPDM_STATUS_BUSY_PEER) {
431 42 : return status;
432 : }
433 :
434 2 : libspdm_sleep(retry_delay_time);
435 2 : } while (retry-- != 0);
436 :
437 1 : return status;
438 : }
439 :
440 2 : libspdm_return_t libspdm_challenge_ex(void *spdm_context, void *reserved,
441 : uint8_t slot_id,
442 : uint8_t measurement_hash_type,
443 : void *measurement_hash,
444 : uint8_t *slot_mask,
445 : const void *requester_nonce_in,
446 : void *requester_nonce,
447 : void *responder_nonce,
448 : void *opaque_data,
449 : size_t *opaque_data_size)
450 : {
451 : libspdm_context_t *context;
452 : size_t retry;
453 : uint64_t retry_delay_time;
454 : libspdm_return_t status;
455 :
456 2 : context = spdm_context;
457 2 : context->crypto_request = true;
458 2 : retry = context->retry_times;
459 2 : retry_delay_time = context->retry_delay_time;
460 : do {
461 2 : status = libspdm_try_challenge(context, slot_id, NULL,
462 : measurement_hash_type,
463 : measurement_hash,
464 : slot_mask,
465 : requester_nonce_in,
466 : requester_nonce, responder_nonce,
467 : opaque_data,
468 : opaque_data_size);
469 2 : if (status != LIBSPDM_STATUS_BUSY_PEER) {
470 2 : return status;
471 : }
472 :
473 0 : libspdm_sleep(retry_delay_time);
474 0 : } while (retry-- != 0);
475 :
476 0 : return status;
477 : }
478 :
479 2 : libspdm_return_t libspdm_challenge_ex2(void *spdm_context, void *reserved,
480 : uint8_t slot_id,
481 : const void *requester_context,
482 : uint8_t measurement_hash_type,
483 : void *measurement_hash,
484 : uint8_t *slot_mask,
485 : const void *requester_nonce_in,
486 : void *requester_nonce,
487 : void *responder_nonce,
488 : void *opaque_data,
489 : size_t *opaque_data_size)
490 : {
491 : libspdm_context_t *context;
492 : size_t retry;
493 : uint64_t retry_delay_time;
494 : libspdm_return_t status;
495 :
496 2 : context = spdm_context;
497 2 : context->crypto_request = true;
498 2 : retry = context->retry_times;
499 2 : retry_delay_time = context->retry_delay_time;
500 : do {
501 2 : status = libspdm_try_challenge(context, slot_id, requester_context,
502 : measurement_hash_type,
503 : measurement_hash,
504 : slot_mask,
505 : requester_nonce_in,
506 : requester_nonce, responder_nonce,
507 : opaque_data,
508 : opaque_data_size);
509 2 : if (status != LIBSPDM_STATUS_BUSY_PEER) {
510 2 : return status;
511 : }
512 :
513 0 : libspdm_sleep(retry_delay_time);
514 0 : } while (retry-- != 0);
515 :
516 0 : return status;
517 : }
518 :
519 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP */
|