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