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