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_responder_lib.h"
8 :
9 : #if LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
10 :
11 : /**
12 : * Get the SPDM encapsulated request.
13 : *
14 : * @param spdm_context A pointer to the SPDM context.
15 : * @param encap_request_size Size, in bytes, of the encapsulated request data.
16 : * On input, it means the size in bytes of encapsulated request data
17 : * buffer.
18 : * On output, it means the size, in bytes, of copied encapsulated
19 : * request data buffer if LIBSPDM_RETURN_SUCCESS is returned,
20 : * and means the size in bytes of desired encapsulated request data
21 : * buffer if LIBSPDM_STATUS_BUFFER_TOO_SMALL is returned.
22 : * @param encap_request A pointer to the encapsulated request data.
23 : **/
24 : typedef libspdm_return_t (*libspdm_get_encap_request_func)(
25 : libspdm_context_t *spdm_context, size_t *encap_request_size, void *encap_request);
26 :
27 : /**
28 : * Process the SPDM encapsulated response.
29 : *
30 : * @param spdm_context A pointer to the SPDM context.
31 : * @param encap_response_size Size, in bytes, of the encapsulated response data.
32 : * @param encap_response A pointer to the encapsulated response data.
33 : * @param need_continue Indicate if encapsulated communication needs to continue.
34 : **/
35 : typedef libspdm_return_t (*libspdm_process_encap_response_func)(
36 : libspdm_context_t *spdm_context, size_t encap_response_size,
37 : const void *encap_response, bool *need_continue);
38 :
39 : typedef struct {
40 : uint8_t request_op_code;
41 : libspdm_get_encap_request_func get_encap_request;
42 : libspdm_process_encap_response_func process_encap_response;
43 : } libspdm_encap_response_struct_t;
44 :
45 12 : static libspdm_return_t libspdm_get_encap_struct_via_op_code
46 : (uint8_t request_op_code, libspdm_encap_response_struct_t *encap_struct)
47 : {
48 : size_t index;
49 :
50 12 : libspdm_encap_response_struct_t encap_response_struct[] = {
51 : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT)
52 : { SPDM_GET_DIGESTS, libspdm_get_encap_request_get_digest,
53 : libspdm_process_encap_response_digest },
54 :
55 : { SPDM_GET_CERTIFICATE, libspdm_get_encap_request_get_certificate,
56 : libspdm_process_encap_response_certificate },
57 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (...) */
58 :
59 : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_SEND_CHALLENGE_SUPPORT)
60 : { SPDM_CHALLENGE, libspdm_get_encap_request_challenge,
61 : libspdm_process_encap_response_challenge_auth },
62 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_SEND_CHALLENGE_SUPPORT) */
63 :
64 : { SPDM_KEY_UPDATE, libspdm_get_encap_request_key_update,
65 : libspdm_process_encap_response_key_update },
66 :
67 : #if LIBSPDM_SEND_GET_ENDPOINT_INFO_SUPPORT
68 : { SPDM_GET_ENDPOINT_INFO, libspdm_get_encap_request_get_endpoint_info,
69 : libspdm_process_encap_response_endpoint_info }
70 : #endif /* LIBSPDM_SEND_GET_ENDPOINT_INFO_SUPPORT */
71 : };
72 :
73 30 : for (index = 0; index < LIBSPDM_ARRAY_SIZE(encap_response_struct); index++) {
74 30 : if (encap_response_struct[index].request_op_code == request_op_code) {
75 12 : libspdm_copy_mem(encap_struct, sizeof(libspdm_encap_response_struct_t),
76 12 : &encap_response_struct[index],
77 : sizeof(libspdm_encap_response_struct_t));
78 12 : return LIBSPDM_STATUS_SUCCESS;
79 : }
80 : }
81 0 : LIBSPDM_ASSERT(false);
82 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
83 : }
84 :
85 7 : static void libspdm_encap_move_to_next_op_code(libspdm_context_t *spdm_context)
86 : {
87 : uint8_t index;
88 :
89 7 : LIBSPDM_ASSERT(spdm_context->encap_context.request_op_code_count <=
90 : LIBSPDM_MAX_ENCAP_REQUEST_OP_CODE_SEQUENCE_COUNT);
91 7 : if (spdm_context->encap_context.current_request_op_code == 0) {
92 5 : spdm_context->encap_context.current_request_op_code =
93 5 : spdm_context->encap_context.request_op_code_sequence[0];
94 5 : return;
95 : }
96 2 : for (index = 0; index < spdm_context->encap_context.request_op_code_count; index++) {
97 2 : if (spdm_context->encap_context.current_request_op_code ==
98 2 : spdm_context->encap_context.request_op_code_sequence[index]) {
99 2 : spdm_context->encap_context.current_request_op_code =
100 2 : spdm_context->encap_context.request_op_code_sequence[index + 1];
101 2 : return;
102 : }
103 : }
104 0 : LIBSPDM_ASSERT(false);
105 : }
106 :
107 : /**
108 : * Process a SPDM encapsulated response.
109 : *
110 : * @param spdm_context The SPDM context for the device.
111 : * @param encap_response_size Size, in bytes, of the request data.
112 : * @param encap_response A pointer to the request data.
113 : * @param encap_request_size Size, in bytes, of the response data.
114 : * @param encap_request A pointer to the response data.
115 : **/
116 10 : static libspdm_return_t libspdm_process_encapsulated_response(
117 : libspdm_context_t *spdm_context, size_t encap_response_size,
118 : const void *encap_response, size_t *encap_request_size, void *encap_request)
119 : {
120 : libspdm_return_t status;
121 : bool need_continue;
122 : libspdm_encap_response_struct_t encap_response_struct;
123 :
124 : /* Process previous response. */
125 10 : need_continue = false;
126 :
127 10 : if (spdm_context->encap_context.current_request_op_code != 0) {
128 5 : status = libspdm_get_encap_struct_via_op_code(
129 5 : spdm_context->encap_context.current_request_op_code, &encap_response_struct);
130 5 : LIBSPDM_ASSERT(status == LIBSPDM_STATUS_SUCCESS);
131 5 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
132 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
133 : }
134 5 : LIBSPDM_ASSERT(encap_response_struct.process_encap_response != NULL);
135 5 : if (encap_response_struct.process_encap_response == NULL) {
136 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
137 : }
138 5 : status = encap_response_struct.process_encap_response(
139 : spdm_context, encap_response_size, encap_response, &need_continue);
140 5 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
141 : /* If the Requester delivers an encapsulated ERROR message with a ResponseNotReady error code,
142 : * the Responder shall terminate the encapsulated request flow by setting Param2 in
143 : * the corresponding ENCAPSULATED_RESPONSE_ACK response message to a value of zero. */
144 1 : if (status == LIBSPDM_STATUS_NOT_READY_PEER) {
145 1 : *encap_request_size = 0;
146 1 : spdm_context->encap_context.current_request_op_code = 0;
147 1 : return LIBSPDM_STATUS_SUCCESS;
148 : } else {
149 0 : return status;
150 : }
151 : }
152 : }
153 :
154 9 : spdm_context->encap_context.request_id += 1;
155 :
156 : /* Move to next request. */
157 9 : if (!need_continue) {
158 7 : libspdm_encap_move_to_next_op_code(spdm_context);
159 : }
160 :
161 9 : if (spdm_context->encap_context.current_request_op_code == 0) {
162 : /* No more work to do - stop. */
163 2 : *encap_request_size = 0;
164 2 : spdm_context->encap_context.current_request_op_code = 0;
165 2 : return LIBSPDM_STATUS_SUCCESS;
166 : }
167 :
168 : /* Process the next request. */
169 7 : status = libspdm_get_encap_struct_via_op_code(
170 7 : spdm_context->encap_context.current_request_op_code, &encap_response_struct);
171 7 : LIBSPDM_ASSERT(status == LIBSPDM_STATUS_SUCCESS);
172 7 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
173 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
174 : }
175 7 : LIBSPDM_ASSERT(encap_response_struct.get_encap_request != NULL);
176 7 : if (encap_response_struct.get_encap_request == NULL) {
177 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
178 : }
179 7 : status = encap_response_struct.get_encap_request(
180 : spdm_context, encap_request_size, encap_request);
181 7 : return status;
182 : }
183 :
184 0 : void libspdm_init_key_update_encap_state(void *spdm_context)
185 : {
186 : libspdm_context_t *context;
187 :
188 0 : context = spdm_context;
189 :
190 0 : context->encap_context.current_request_op_code = 0x00;
191 0 : context->encap_context.request_id = 0;
192 0 : context->encap_context.last_encap_request_size = 0;
193 0 : libspdm_zero_mem(&context->encap_context.last_encap_request_header,
194 : sizeof(context->encap_context.last_encap_request_header));
195 0 : context->response_state = LIBSPDM_RESPONSE_STATE_PROCESSING_ENCAP;
196 :
197 0 : libspdm_reset_message_mut_b(context);
198 0 : libspdm_reset_message_mut_c(context);
199 :
200 0 : libspdm_zero_mem(context->encap_context.request_op_code_sequence,
201 : sizeof(context->encap_context.request_op_code_sequence));
202 0 : context->encap_context.request_op_code_count = 1;
203 0 : context->encap_context.request_op_code_sequence[0] = SPDM_KEY_UPDATE;
204 0 : context->encap_context.session_id = INVALID_SESSION_ID;
205 0 : }
206 :
207 0 : void libspdm_init_key_update_encap_state_with_session(
208 : void *spdm_context, uint32_t session_id)
209 : {
210 : libspdm_context_t *context;
211 :
212 0 : libspdm_init_key_update_encap_state (spdm_context);
213 :
214 0 : context = spdm_context;
215 0 : context->encap_context.session_id = session_id;
216 0 : }
217 :
218 : #if LIBSPDM_SEND_GET_ENDPOINT_INFO_SUPPORT
219 0 : void libspdm_init_get_endpoint_info_encap_state(void *spdm_context, uint32_t session_id)
220 : {
221 : libspdm_context_t *context;
222 :
223 0 : context = spdm_context;
224 :
225 0 : context->encap_context.current_request_op_code = 0x00;
226 0 : context->encap_context.request_id = 0;
227 0 : context->encap_context.last_encap_request_size = 0;
228 0 : libspdm_zero_mem(&context->encap_context.last_encap_request_header,
229 : sizeof(context->encap_context.last_encap_request_header));
230 0 : context->response_state = LIBSPDM_RESPONSE_STATE_PROCESSING_ENCAP;
231 :
232 0 : libspdm_zero_mem(context->encap_context.request_op_code_sequence,
233 : sizeof(context->encap_context.request_op_code_sequence));
234 0 : context->encap_context.request_op_code_count = 1;
235 0 : context->encap_context.request_op_code_sequence[0] = SPDM_GET_ENDPOINT_INFO;
236 0 : context->encap_context.session_id = session_id;
237 0 : }
238 : #endif /* LIBSPDM_SEND_GET_ENDPOINT_INFO_SUPPORT */
239 :
240 8 : libspdm_return_t libspdm_get_response_encapsulated_request(
241 : libspdm_context_t *spdm_context, size_t request_size, const void *request,
242 : size_t *response_size, void *response)
243 : {
244 : spdm_encapsulated_request_response_t *spdm_response;
245 : void *encap_request;
246 : size_t encap_request_size;
247 : libspdm_return_t status;
248 : const spdm_get_encapsulated_request_request_t *spdm_request;
249 :
250 8 : spdm_request = request;
251 :
252 8 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
253 0 : return libspdm_generate_error_response(spdm_context,
254 : SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
255 : SPDM_GET_ENCAPSULATED_REQUEST,
256 : response_size, response);
257 : }
258 :
259 8 : if (!libspdm_is_encap_supported(spdm_context)) {
260 0 : return libspdm_generate_error_response(
261 : spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
262 : SPDM_GET_ENCAPSULATED_REQUEST, response_size, response);
263 : }
264 8 : if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_PROCESSING_ENCAP) {
265 3 : if (spdm_context->response_state == LIBSPDM_RESPONSE_STATE_NORMAL) {
266 2 : if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) {
267 1 : return libspdm_generate_error_response(
268 : spdm_context,
269 : SPDM_ERROR_CODE_NO_PENDING_REQUESTS, 0,
270 : response_size, response);
271 :
272 : } else {
273 1 : return libspdm_generate_error_response(
274 : spdm_context,
275 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
276 : response_size, response);
277 : }
278 : }
279 1 : return libspdm_responder_handle_response_state(
280 : spdm_context,
281 1 : spdm_request->header.request_response_code,
282 : response_size, response);
283 : }
284 :
285 5 : if ((spdm_context->encap_context.session_id != INVALID_SESSION_ID) &&
286 0 : ((!spdm_context->last_spdm_request_session_id_valid) ||
287 0 : (spdm_context->encap_context.session_id != spdm_context->last_spdm_request_session_id))) {
288 0 : if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) {
289 0 : return libspdm_generate_error_response(
290 : spdm_context,
291 : SPDM_ERROR_CODE_NO_PENDING_REQUESTS, 0,
292 : response_size, response);
293 : } else {
294 0 : return libspdm_generate_error_response(
295 : spdm_context,
296 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
297 : response_size, response);
298 : }
299 : }
300 :
301 5 : if (request_size < sizeof(spdm_get_encapsulated_request_request_t)) {
302 0 : return libspdm_generate_error_response(spdm_context,
303 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
304 : response_size, response);
305 : }
306 :
307 5 : libspdm_reset_message_buffer_via_request_code(spdm_context, NULL,
308 5 : spdm_request->header.request_response_code);
309 :
310 5 : LIBSPDM_ASSERT(*response_size > sizeof(spdm_encapsulated_request_response_t));
311 5 : libspdm_zero_mem(response, *response_size);
312 :
313 5 : spdm_response = response;
314 5 : spdm_response->header.spdm_version = spdm_request->header.spdm_version;
315 5 : spdm_response->header.request_response_code = SPDM_ENCAPSULATED_REQUEST;
316 5 : spdm_response->header.param1 = 0;
317 5 : spdm_response->header.param2 = 0;
318 :
319 5 : encap_request_size = *response_size - sizeof(spdm_encapsulated_request_response_t);
320 5 : encap_request = spdm_response + 1;
321 :
322 5 : status = libspdm_process_encapsulated_response(
323 : spdm_context, 0, NULL, &encap_request_size, encap_request);
324 5 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
325 0 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
326 0 : return libspdm_generate_error_response(
327 : spdm_context, SPDM_ERROR_CODE_INVALID_RESPONSE_CODE, 0,
328 : response_size, response);
329 : }
330 5 : *response_size = sizeof(spdm_encapsulated_request_response_t) + encap_request_size;
331 5 : spdm_response->header.param1 = spdm_context->encap_context.request_id;
332 :
333 5 : if (encap_request_size == 0) {
334 0 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
335 : }
336 :
337 5 : return LIBSPDM_STATUS_SUCCESS;
338 : }
339 :
340 9 : libspdm_return_t libspdm_get_response_encapsulated_response_ack(
341 : libspdm_context_t *spdm_context, size_t request_size, const void *request,
342 : size_t *response_size, void *response)
343 : {
344 : const spdm_deliver_encapsulated_response_request_t *spdm_request;
345 : size_t spdm_request_size;
346 : spdm_encapsulated_response_ack_response_t *spdm_response;
347 : const void *encap_response;
348 : size_t encap_response_size;
349 : void *encap_request;
350 : size_t encap_request_size;
351 : libspdm_return_t status;
352 : size_t ack_header_size;
353 :
354 9 : spdm_request = request;
355 :
356 9 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
357 0 : return libspdm_generate_error_response(spdm_context,
358 : SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
359 : SPDM_DELIVER_ENCAPSULATED_RESPONSE,
360 : response_size, response);
361 : }
362 :
363 9 : if (!libspdm_is_encap_supported(spdm_context)) {
364 0 : return libspdm_generate_error_response(
365 : spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
366 : SPDM_DELIVER_ENCAPSULATED_RESPONSE, response_size, response);
367 : }
368 9 : if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_PROCESSING_ENCAP) {
369 2 : if (spdm_context->response_state == LIBSPDM_RESPONSE_STATE_NORMAL) {
370 1 : return libspdm_generate_error_response(
371 : spdm_context,
372 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
373 : response_size, response);
374 : }
375 1 : return libspdm_responder_handle_response_state(spdm_context,
376 1 : spdm_request->header.request_response_code,
377 : response_size, response);
378 : }
379 :
380 7 : if (request_size <= sizeof(spdm_deliver_encapsulated_response_request_t)) {
381 1 : return libspdm_generate_error_response(spdm_context,
382 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
383 : response_size, response);
384 : }
385 :
386 6 : spdm_request_size = request_size;
387 :
388 6 : if (spdm_request->header.param1 != spdm_context->encap_context.request_id) {
389 1 : return libspdm_generate_error_response(spdm_context,
390 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
391 : response_size, response);
392 : }
393 :
394 5 : encap_response = (spdm_request + 1);
395 5 : encap_response_size = spdm_request_size - sizeof(spdm_deliver_encapsulated_response_request_t);
396 :
397 5 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
398 2 : ack_header_size = sizeof(spdm_encapsulated_response_ack_response_t);
399 : } else {
400 3 : ack_header_size = sizeof(spdm_message_header_t);
401 : }
402 :
403 5 : LIBSPDM_ASSERT(*response_size > ack_header_size);
404 5 : libspdm_zero_mem(response, *response_size);
405 :
406 5 : spdm_response = response;
407 5 : spdm_response->header.spdm_version = spdm_request->header.spdm_version;
408 5 : spdm_response->header.request_response_code = SPDM_ENCAPSULATED_RESPONSE_ACK;
409 5 : spdm_response->header.param1 = 0;
410 5 : spdm_response->header.param2 = SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_PRESENT;
411 :
412 5 : encap_request_size = *response_size - ack_header_size;
413 5 : encap_request = (uint8_t *)spdm_response + ack_header_size;
414 5 : if (encap_response_size < sizeof(spdm_message_header_t)) {
415 0 : return libspdm_generate_error_response(spdm_context,
416 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
417 : response_size, response);
418 : }
419 :
420 5 : libspdm_reset_message_buffer_via_request_code(spdm_context, NULL,
421 5 : spdm_request->header.request_response_code);
422 :
423 5 : status = libspdm_process_encapsulated_response(
424 : spdm_context, encap_response_size, encap_response,
425 : &encap_request_size, encap_request);
426 5 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
427 0 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
428 0 : return libspdm_generate_error_response(
429 : spdm_context, SPDM_ERROR_CODE_INVALID_RESPONSE_CODE, 0, response_size, response);
430 : }
431 :
432 5 : *response_size = ack_header_size + encap_request_size;
433 5 : spdm_response->header.param1 = spdm_context->encap_context.request_id;
434 :
435 5 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
436 2 : spdm_response->ack_request_id = spdm_request->header.param1;
437 : }
438 :
439 5 : if (encap_request_size == 0) {
440 3 : spdm_response->header.param1 = 0;
441 3 : spdm_response->header.param2 = SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_ABSENT;
442 3 : if ((spdm_context->encap_context.req_slot_id != 0) &&
443 0 : (spdm_context->encap_context.req_slot_id != 0xFF)) {
444 0 : spdm_response->header.param2 =
445 : SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_REQ_SLOT_NUMBER;
446 0 : *response_size = ack_header_size + 1;
447 0 : *(uint8_t *)(spdm_response + 1) = spdm_context->encap_context.req_slot_id;
448 : }
449 3 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
450 : }
451 :
452 5 : return LIBSPDM_STATUS_SUCCESS;
453 : }
454 :
455 7 : libspdm_return_t libspdm_handle_encap_error_response_main(
456 : libspdm_context_t *spdm_context, uint8_t error_code)
457 : {
458 7 : if (error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) {
459 1 : return LIBSPDM_STATUS_NOT_READY_PEER;
460 : }
461 :
462 6 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
463 : }
464 : #endif /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP */
465 :
466 : #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
467 : #if LIBSPDM_SEND_CHALLENGE_SUPPORT
468 0 : void libspdm_init_basic_mut_auth_encap_state(libspdm_context_t *spdm_context)
469 : {
470 0 : spdm_context->encap_context.session_id = INVALID_SESSION_ID;
471 0 : spdm_context->encap_context.current_request_op_code = 0x00;
472 0 : spdm_context->encap_context.request_id = 0;
473 0 : spdm_context->encap_context.last_encap_request_size = 0;
474 0 : libspdm_zero_mem(&spdm_context->encap_context.last_encap_request_header,
475 : sizeof(spdm_context->encap_context.last_encap_request_header));
476 0 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
477 :
478 : /* Clear Cache. */
479 0 : libspdm_reset_message_mut_b(spdm_context);
480 0 : libspdm_reset_message_mut_c(spdm_context);
481 :
482 : /* Possible Sequence:
483 : * 1. Basic Mutual Auth:
484 : * 1.1 GET_DIGEST/GET_CERTIFICATE/CHALLENGE (encap_context.req_slot_id must not be 0xFF)
485 : * 1.2 CHALLENGE (REQUEST_FLAGS_PUB_KEY_ID_CAP, encap_context req_slot_id must be 0xFF) */
486 0 : libspdm_zero_mem(spdm_context->encap_context.request_op_code_sequence,
487 : sizeof(spdm_context->encap_context.request_op_code_sequence));
488 : /* Basic Mutual Auth*/
489 0 : if (libspdm_is_capabilities_flag_supported(
490 : spdm_context, false,
491 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PUB_KEY_ID_CAP, 0)) {
492 0 : LIBSPDM_ASSERT (spdm_context->encap_context.req_slot_id == 0xFF);
493 :
494 0 : spdm_context->encap_context.request_op_code_count = 1;
495 0 : spdm_context->encap_context.request_op_code_sequence[0] = SPDM_CHALLENGE;
496 : } else {
497 0 : LIBSPDM_ASSERT (spdm_context->encap_context.req_slot_id != 0xFF);
498 0 : LIBSPDM_ASSERT(spdm_context->mut_auth_cert_chain_buffer != NULL);
499 0 : LIBSPDM_ASSERT(spdm_context->mut_auth_cert_chain_buffer_max_size != 0);
500 :
501 0 : spdm_context->encap_context.request_op_code_count = 3;
502 0 : spdm_context->encap_context.request_op_code_sequence[0] = SPDM_GET_DIGESTS;
503 0 : spdm_context->encap_context.request_op_code_sequence[1] = SPDM_GET_CERTIFICATE;
504 0 : spdm_context->encap_context.request_op_code_sequence[2] = SPDM_CHALLENGE;
505 : }
506 :
507 0 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_PROCESSING_ENCAP;
508 0 : }
509 : #endif /* LIBSPDM_SEND_CHALLENGE_SUPPORT */
510 :
511 0 : void libspdm_init_mut_auth_encap_state(libspdm_context_t *spdm_context, uint8_t mut_auth_requested)
512 : {
513 0 : spdm_context->encap_context.session_id = INVALID_SESSION_ID;
514 0 : spdm_context->encap_context.current_request_op_code = 0x00;
515 0 : if (mut_auth_requested == SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS) {
516 0 : spdm_context->encap_context.current_request_op_code = SPDM_GET_DIGESTS;
517 : }
518 0 : spdm_context->encap_context.request_id = 0;
519 0 : spdm_context->encap_context.last_encap_request_size = 0;
520 0 : libspdm_zero_mem(&spdm_context->encap_context.last_encap_request_header,
521 : sizeof(spdm_context->encap_context.last_encap_request_header));
522 0 : spdm_context->mut_auth_cert_chain_buffer_size = 0;
523 :
524 : /* Clear cache. */
525 0 : libspdm_reset_message_mut_b(spdm_context);
526 0 : libspdm_reset_message_mut_c(spdm_context);
527 :
528 : /* Possible Sequence:
529 : * 2. Session Mutual Auth: (spdm_context->last_spdm_request_session_id_valid)
530 : * 2.1 GET_DIGEST/GET_CERTIFICATE
531 : * (MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST or MUT_AUTH_REQUESTED_WITH_GET_DIGESTS,
532 : * encap_context.req_slot_id must not be 0xFF)
533 : * 2.2 N/A (REQUEST_FLAGS_PUB_KEY_ID_CAP, MUT_AUTH_REQUESTED, encap_context.req_slot_id may
534 : * or may not be 0xFF)*/
535 :
536 0 : libspdm_zero_mem(spdm_context->encap_context.request_op_code_sequence,
537 : sizeof(spdm_context->encap_context.request_op_code_sequence));
538 :
539 : /* Session mutual authentication. */
540 0 : if (libspdm_is_capabilities_flag_supported(
541 : spdm_context, false,
542 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PUB_KEY_ID_CAP, 0)) {
543 0 : LIBSPDM_ASSERT(spdm_context->encap_context.req_slot_id == 0xFF);
544 0 : LIBSPDM_ASSERT(mut_auth_requested == SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED);
545 : } else {
546 0 : LIBSPDM_ASSERT(spdm_context->mut_auth_cert_chain_buffer != NULL);
547 0 : LIBSPDM_ASSERT(spdm_context->mut_auth_cert_chain_buffer_max_size != 0);
548 : }
549 :
550 0 : switch (mut_auth_requested) {
551 0 : case SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED:
552 : /* No encapsulation is required. */
553 0 : spdm_context->encap_context.request_op_code_count = 0;
554 0 : break;
555 0 : case SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST:
556 : case SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS:
557 0 : LIBSPDM_ASSERT (spdm_context->encap_context.req_slot_id != 0xFF);
558 0 : spdm_context->encap_context.request_op_code_count = 2;
559 0 : spdm_context->encap_context.request_op_code_sequence[0] = SPDM_GET_DIGESTS;
560 0 : spdm_context->encap_context.request_op_code_sequence[1] = SPDM_GET_CERTIFICATE;
561 0 : break;
562 0 : default:
563 0 : LIBSPDM_ASSERT (false);
564 0 : spdm_context->encap_context.request_op_code_count = 0;
565 0 : break;
566 : }
567 :
568 0 : if (spdm_context->encap_context.request_op_code_count != 0) {
569 : /* Change state only if encapsulation is required. */
570 0 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_PROCESSING_ENCAP;
571 : }
572 0 : }
573 : #endif /* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP */
|