LCOV - code coverage report
Current view: top level - library/spdm_responder_lib - libspdm_rsp_encap_response.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 49.4 % 255 126
Test Date: 2025-08-24 08:11:14 Functions: 50.0 % 12 6

            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 */
        

Generated by: LCOV version 2.0-1