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: 52.1 % 242 126
Test Date: 2025-06-29 08:09:00 Functions: 54.5 % 11 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_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 */
        

Generated by: LCOV version 2.0-1