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