LCOV - code coverage report
Current view: top level - library/spdm_responder_lib - libspdm_rsp_capabilities.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 83.0 % 241 200
Test Date: 2025-10-12 08:10:56 Functions: 100.0 % 3 3

            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              : #include <stddef.h>
       9              : 
      10              : /**
      11              :  * This function checks the compatibility of the received SPDM version,
      12              :  * if received version is valid, subsequent spdm communication will follow this version.
      13              :  *
      14              :  * @param  spdm_context  A pointer to the SPDM context.
      15              :  * @param  version       The SPDM message version.
      16              :  *
      17              :  *
      18              :  * @retval true   The received SPDM version is valid.
      19              :  * @retval false  The received SPDM version is invalid.
      20              :  **/
      21           20 : static bool libspdm_check_request_version_compatibility(libspdm_context_t *spdm_context,
      22              :                                                         uint8_t version)
      23              : {
      24              :     uint8_t local_ver;
      25              :     size_t index;
      26              : 
      27           45 :     for (index = 0; index < spdm_context->local_context.version.spdm_version_count; index++) {
      28           45 :         local_ver = libspdm_get_version_from_version_number(
      29           45 :             spdm_context->local_context.version.spdm_version[index]);
      30           45 :         if (local_ver == version) {
      31           20 :             spdm_context->connection_info.version = version << SPDM_VERSION_NUMBER_SHIFT_BIT;
      32           20 :             return true;
      33              :         }
      34              :     }
      35            0 :     return false;
      36              : }
      37              : 
      38              : /**
      39              :  * This function checks the compatibility of the received GET_CAPABILITES flag.
      40              :  * Some flags are mutually inclusive/exclusive.
      41              :  *
      42              :  * @param  capabilities_flag  The received CAPABILITIES Flag.
      43              :  * @param  version            The SPDM message version.
      44              :  *
      45              :  *
      46              :  * @retval true   The received Capabilities flag is valid.
      47              :  * @retval false  The received Capabilities flag is invalid.
      48              :  **/
      49           20 : static bool libspdm_check_request_flag_compatibility(uint32_t capabilities_flag, uint8_t version)
      50              : {
      51           20 :     const uint8_t cert_cap = (uint8_t)(capabilities_flag >> 1) & 0x01;
      52           20 :     const uint8_t chal_cap = (uint8_t)(capabilities_flag >> 2) & 0x01;
      53           20 :     const uint8_t encrypt_cap = (uint8_t)(capabilities_flag >> 6) & 0x01;
      54           20 :     const uint8_t mac_cap = (uint8_t)(capabilities_flag >> 7) & 0x01;
      55           20 :     const uint8_t mut_auth_cap = (uint8_t)(capabilities_flag >> 8) & 0x01;
      56           20 :     const uint8_t key_ex_cap = (uint8_t)(capabilities_flag >> 9) & 0x01;
      57           20 :     const uint8_t psk_cap = (uint8_t)(capabilities_flag >> 10) & 0x03;
      58           20 :     const uint8_t encap_cap = (uint8_t)(capabilities_flag >> 12) & 0x01;
      59           20 :     const uint8_t hbeat_cap = (uint8_t)(capabilities_flag >> 13) & 0x01;
      60           20 :     const uint8_t key_upd_cap = (uint8_t)(capabilities_flag >> 14) & 0x01;
      61           20 :     const uint8_t handshake_in_the_clear_cap = (uint8_t)(capabilities_flag >> 15) & 0x01;
      62           20 :     const uint8_t pub_key_id_cap = (uint8_t)(capabilities_flag >> 16) & 0x01;
      63           20 :     const uint8_t ep_info_cap = (uint8_t)(capabilities_flag >> 22) & 0x03;
      64           20 :     const uint8_t event_cap = (uint8_t)(capabilities_flag >> 25) & 0x01;
      65           20 :     const uint8_t multi_key_cap = (uint8_t)(capabilities_flag >> 26) & 0x03;
      66              : 
      67              :     /* Checks common to 1.1 and higher */
      68           20 :     if (version >= SPDM_MESSAGE_VERSION_11) {
      69              :         /* Illegal to return reserved values. */
      70           18 :         if ((psk_cap == 2) || (psk_cap == 3)) {
      71            0 :             return false;
      72              :         }
      73              : 
      74              :         /* Checks that originate from key exchange capabilities. */
      75           18 :         if ((key_ex_cap == 1) || (psk_cap != 0)) {
      76           11 :             if ((mac_cap == 0) && (encrypt_cap == 0)) {
      77            2 :                 return false;
      78              :             }
      79              :         } else {
      80            7 :             if ((mac_cap == 1) || (encrypt_cap == 1) || (handshake_in_the_clear_cap == 1) ||
      81            5 :                 (hbeat_cap == 1) || (key_upd_cap == 1)) {
      82            2 :                 return false;
      83              :             }
      84            5 :             if (version >= SPDM_MESSAGE_VERSION_13) {
      85            2 :                 if (event_cap == 1) {
      86            0 :                     return false;
      87              :                 }
      88              :             }
      89              :         }
      90           14 :         if ((key_ex_cap == 0) && (psk_cap == 1)) {
      91            1 :             if (handshake_in_the_clear_cap == 1) {
      92            1 :                 return false;
      93              :             }
      94              :         }
      95              : 
      96              :         /* Checks that originate from certificate or public key capabilities. */
      97           13 :         if ((cert_cap == 1) || (pub_key_id_cap == 1)) {
      98              :             /* Certificate capabilities and public key capabilities cannot both be set. */
      99           10 :             if ((cert_cap == 1) && (pub_key_id_cap == 1)) {
     100            2 :                 return false;
     101              :             }
     102              :             /* If certificates or public keys are enabled then at least one of these capabilities
     103              :              * must be enabled to use the key. */
     104            8 :             if ((chal_cap == 0) && (key_ex_cap == 0)) {
     105            2 :                 if (version >= SPDM_MESSAGE_VERSION_13) {
     106            2 :                     if ((ep_info_cap == 0) || (ep_info_cap == 1)) {
     107            0 :                         return false;
     108              :                     }
     109              :                 } else {
     110            0 :                     return false;
     111              :                 }
     112              :             }
     113              :         } else {
     114              :             /* If certificates or public keys are not enabled then these capabilities
     115              :              * cannot be enabled. */
     116            3 :             if ((chal_cap == 1) || (mut_auth_cap == 1)) {
     117            0 :                 return false;
     118              :             }
     119            3 :             if (version >= SPDM_MESSAGE_VERSION_13) {
     120            0 :                 if (ep_info_cap == 2) {
     121            0 :                     return false;
     122              :                 }
     123              :             }
     124              :         }
     125              : 
     126              :         /* Checks that originate from mutual authentication capabilities. */
     127           11 :         if (mut_auth_cap == 1) {
     128              :             /* Mutual authentication with asymmetric keys can only occur through the basic mutual
     129              :              * authentication flow (CHAL_CAP == 1) or the session-based mutual authentication flow
     130              :              * (KEY_EX_CAP == 1). */
     131            6 :             if ((key_ex_cap == 0) && (chal_cap == 0)) {
     132            0 :                 return false;
     133              :             }
     134              :         }
     135              :     }
     136              : 
     137              :     /* Checks specific to 1.1. */
     138           13 :     if (version == SPDM_MESSAGE_VERSION_11) {
     139            6 :         if ((mut_auth_cap == 1) && (encap_cap == 0)) {
     140            1 :             return false;
     141              :         }
     142              :     }
     143              : 
     144              :     /* Checks specific to 1.3 and higher. */
     145           12 :     if (version >= SPDM_MESSAGE_VERSION_13) {
     146              :         /* Illegal to return reserved values. */
     147            2 :         if ((ep_info_cap == 3) || (multi_key_cap == 3)) {
     148            0 :             return false;
     149              :         }
     150            2 :         if ((multi_key_cap != 0) && ((pub_key_id_cap == 1) || (cert_cap == 0))) {
     151            0 :             return false;
     152              :         }
     153              :     }
     154              : 
     155              :     /* Checks that are deferred to when a message is received.
     156              :      *
     157              :      * If the Requester supports key exchange then MAC_CAP must be set. In addition, if the
     158              :      * negotiated SPDM version is greater than 1.1 then the negotiated opaque data format must be
     159              :      * OpaqueDataFmt1.
     160              :      */
     161              : 
     162           12 :     return true;
     163              : }
     164              : 
     165           23 : libspdm_return_t libspdm_get_response_capabilities(libspdm_context_t *spdm_context,
     166              :                                                    size_t request_size,
     167              :                                                    const void *request,
     168              :                                                    size_t *response_size,
     169              :                                                    void *response)
     170              : {
     171              :     const spdm_get_capabilities_request_t *spdm_request;
     172              :     spdm_capabilities_response_t *spdm_response;
     173              :     libspdm_return_t status;
     174              : 
     175           23 :     spdm_request = request;
     176              : 
     177              :     /* -=[Check Parameters Phase]=- */
     178           23 :     LIBSPDM_ASSERT(spdm_request->header.request_response_code == SPDM_GET_CAPABILITIES);
     179              : 
     180              :     /* -=[Verify State Phase]=- */
     181           23 :     if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
     182            2 :         return libspdm_responder_handle_response_state(
     183            2 :             spdm_context, spdm_request->header.request_response_code,  response_size, response);
     184              :     }
     185           21 :     if (spdm_context->connection_info.connection_state != LIBSPDM_CONNECTION_STATE_AFTER_VERSION) {
     186            1 :         return libspdm_generate_error_response(spdm_context,
     187              :                                                SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
     188              :                                                0, response_size, response);
     189              :     }
     190              : 
     191              :     /* -=[Validate Request Phase]=- */
     192           20 :     if (!libspdm_check_request_version_compatibility(
     193           20 :             spdm_context, spdm_request->header.spdm_version)) {
     194            0 :         return libspdm_generate_error_response(spdm_context,
     195              :                                                SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
     196              :                                                response_size, response);
     197              :     }
     198           20 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     199            5 :         if (request_size < sizeof(spdm_get_capabilities_request_t)) {
     200            0 :             return libspdm_generate_error_response(
     201              :                 spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     202              :         } else {
     203            5 :             request_size = sizeof(spdm_get_capabilities_request_t);
     204              :         }
     205           15 :     } else if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     206           13 :         if (request_size < sizeof(spdm_get_capabilities_request_t) -
     207              :             sizeof(spdm_request->data_transfer_size) - sizeof(spdm_request->max_spdm_msg_size)) {
     208            0 :             return libspdm_generate_error_response(
     209              :                 spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     210              :         } else {
     211           13 :             request_size = sizeof(spdm_get_capabilities_request_t) -
     212              :                            sizeof(spdm_request->data_transfer_size) -
     213              :                            sizeof(spdm_request->max_spdm_msg_size);
     214              :         }
     215              :     } else {
     216            2 :         if (request_size < sizeof(spdm_message_header_t)) {
     217            0 :             return libspdm_generate_error_response(
     218              :                 spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     219              :         } else {
     220            2 :             request_size = sizeof(spdm_message_header_t);
     221              :         }
     222              :     }
     223           20 :     if (!libspdm_check_request_flag_compatibility(
     224           20 :             spdm_request->flags, spdm_request->header.spdm_version)) {
     225            8 :         return libspdm_generate_error_response(spdm_context,
     226              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     227              :                                                response_size, response);
     228              :     }
     229           12 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     230            5 :         if ((spdm_request->data_transfer_size < SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) ||
     231            5 :             (spdm_request->data_transfer_size > spdm_request->max_spdm_msg_size)) {
     232            1 :             return libspdm_generate_error_response(spdm_context,
     233              :                                                    SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     234              :                                                    response_size, response);
     235              :         }
     236            4 :         if (((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) == 0) &&
     237            2 :             (spdm_request->data_transfer_size != spdm_request->max_spdm_msg_size)) {
     238            1 :             return libspdm_generate_error_response(spdm_context,
     239              :                                                    SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     240              :                                                    response_size, response);
     241              :         }
     242              :     }
     243           10 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     244            8 :         if (spdm_request->ct_exponent > LIBSPDM_MAX_CT_EXPONENT) {
     245            1 :             return libspdm_generate_error_response(spdm_context,
     246              :                                                    SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     247              :                                                    response_size, response);
     248              :         }
     249              :     }
     250              : 
     251              :     /* Check that if Param1[0] is set, Requester must have CHUNK_CAP */
     252            9 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
     253            2 :         (spdm_request->header.param1 & SPDM_GET_CAPABILITIES_REQUEST_PARAM1_SUPPORTED_ALGORITHMS) &&
     254            1 :         ((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) == 0)) {
     255            0 :         return libspdm_generate_error_response(spdm_context,
     256              :                                                SPDM_ERROR_CODE_INVALID_REQUEST,
     257              :                                                0,
     258              :                                                response_size,
     259              :                                                response);
     260              :     }
     261              : 
     262            9 :     libspdm_reset_message_buffer_via_request_code(spdm_context, NULL,
     263            9 :                                                   spdm_request->header.request_response_code);
     264              : 
     265              :     size_t required_size;
     266              : 
     267            9 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     268            3 :         required_size = sizeof(spdm_capabilities_response_t);
     269              :     } else {
     270            6 :         required_size = offsetof(spdm_capabilities_response_t, data_transfer_size);
     271              :     }
     272              : 
     273            9 :     uint32_t response_flags = libspdm_mask_capability_flags(
     274              :         spdm_context, false, spdm_context->local_context.capability.flags);
     275              : 
     276            9 :     bool supported_algs_requested =
     277           11 :         (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
     278            2 :         ((spdm_request->header.param1 & SPDM_GET_CAPABILITIES_REQUEST_PARAM1_SUPPORTED_ALGORITHMS) != 0) &&
     279           12 :         ((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) != 0) &&
     280            1 :         ((response_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP) != 0);
     281              : 
     282            9 :     if (supported_algs_requested) {
     283            1 :         uint8_t table_count = 0;
     284            1 :         if (spdm_context->local_context.algorithm.dhe_named_group != 0) {
     285            1 :             table_count++;
     286              :         }
     287            1 :         if (spdm_context->local_context.algorithm.aead_cipher_suite != 0) {
     288            1 :             table_count++;
     289              :         }
     290            1 :         if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
     291            1 :             table_count++;
     292              :         }
     293            1 :         if (spdm_context->local_context.algorithm.key_schedule != 0) {
     294            1 :             table_count++;
     295              :         }
     296              : 
     297            1 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     298            0 :             if (spdm_context->local_context.algorithm.req_pqc_asym_alg != 0) {
     299            0 :                 table_count++;
     300              :             }
     301            0 :             if (spdm_context->local_context.algorithm.kem_alg != 0) {
     302            0 :                 table_count++;
     303              :             }
     304              :         }
     305              : 
     306            1 :         required_size += sizeof(spdm_supported_algorithms_block_t) +
     307            1 :                          (table_count * sizeof(spdm_negotiate_algorithms_common_struct_table_t));
     308              :     }
     309              : 
     310            9 :     LIBSPDM_ASSERT(*response_size >= required_size);
     311            9 :     *response_size = required_size;
     312              : 
     313            9 :     libspdm_zero_mem(response, *response_size);
     314            9 :     spdm_response = response;
     315              : 
     316            9 :     spdm_response->header.spdm_version = spdm_request->header.spdm_version;
     317            9 :     spdm_response->header.request_response_code = SPDM_CAPABILITIES;
     318            9 :     spdm_response->header.param1 = 0;
     319            9 :     spdm_response->header.param2 = 0;
     320            9 :     spdm_response->ct_exponent = spdm_context->local_context.capability.ct_exponent;
     321            9 :     spdm_response->flags = response_flags;
     322            9 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     323            3 :         spdm_response->data_transfer_size =
     324            3 :             spdm_context->local_context.capability.data_transfer_size;
     325            3 :         spdm_response->max_spdm_msg_size =
     326            3 :             spdm_context->local_context.capability.max_spdm_msg_size;
     327              :     }
     328              : 
     329            9 :     if (supported_algs_requested) {
     330            1 :         uint8_t index = 0;
     331              : 
     332              :         /* Allocate space for the supported_algorithms block at the end of the response */
     333            1 :         spdm_supported_algorithms_block_t *supported_algorithms =
     334              :             (spdm_supported_algorithms_block_t*)((uint8_t*)spdm_response + sizeof(spdm_capabilities_response_t));
     335              : 
     336            1 :         supported_algorithms->param2 = 0;
     337            1 :         supported_algorithms->length = sizeof(spdm_supported_algorithms_block_t);
     338            1 :         supported_algorithms->measurement_specification =
     339            1 :             spdm_context->local_context.algorithm.measurement_spec;
     340            1 :         supported_algorithms->other_params_support =
     341            1 :             spdm_context->local_context.algorithm.other_params_support;
     342            1 :         supported_algorithms->base_asym_algo=
     343            1 :             spdm_context->local_context.algorithm.base_asym_algo;
     344            1 :         supported_algorithms->base_hash_algo=
     345            1 :             spdm_context->local_context.algorithm.base_hash_algo;
     346              : 
     347            1 :         if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     348            0 :             supported_algorithms->pqc_asym_algo =
     349            0 :                 spdm_context->local_context.algorithm.pqc_asym_algo;
     350              :         } else {
     351            1 :             supported_algorithms->pqc_asym_algo = 0;
     352              :         }
     353              : 
     354            1 :         libspdm_zero_mem(supported_algorithms->reserved2, sizeof(supported_algorithms->reserved2));
     355            1 :         supported_algorithms->ext_asym_count = 0;
     356            1 :         supported_algorithms->ext_hash_count = 0;
     357            1 :         supported_algorithms->reserved3 = 0;
     358            1 :         supported_algorithms->mel_specification =
     359            1 :             spdm_context->local_context.algorithm.mel_spec;
     360              : 
     361            1 :         spdm_negotiate_algorithms_common_struct_table_t *struct_table =
     362              :             (spdm_negotiate_algorithms_common_struct_table_t*)(
     363              :                 (uint8_t*)supported_algorithms +
     364              :                 sizeof(spdm_supported_algorithms_block_t)
     365              :                 );
     366              : 
     367            1 :         if (spdm_context->local_context.algorithm.dhe_named_group != 0) {
     368            1 :             struct_table[index].alg_type =
     369              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
     370            1 :             struct_table[index].alg_count = 0x20;
     371            1 :             struct_table[index].alg_supported =
     372            1 :                 spdm_context->local_context.algorithm.dhe_named_group;
     373            1 :             index++;
     374              :         }
     375              : 
     376            1 :         if (spdm_context->local_context.algorithm.aead_cipher_suite != 0) {
     377            1 :             struct_table[index].alg_type =
     378              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
     379            1 :             struct_table[index].alg_count = 0x20;
     380            1 :             struct_table[index].alg_supported =
     381            1 :                 spdm_context->local_context.algorithm.aead_cipher_suite;
     382            1 :             index++;
     383              :         }
     384              : 
     385            1 :         if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
     386            1 :             struct_table[index].alg_type =
     387              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
     388            1 :             struct_table[index].alg_count = 0x20;
     389            1 :             struct_table[index].alg_supported =
     390            1 :                 spdm_context->local_context.algorithm.req_base_asym_alg;
     391            1 :             index++;
     392              :         }
     393              : 
     394            1 :         if (spdm_context->local_context.algorithm.key_schedule != 0) {
     395            1 :             struct_table[index].alg_type =
     396              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
     397            1 :             struct_table[index].alg_count = 0x20;
     398            1 :             struct_table[index].alg_supported =
     399            1 :                 spdm_context->local_context.algorithm.key_schedule;
     400            1 :             index++;
     401              :         }
     402              : 
     403            1 :         if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     404            0 :             if (spdm_context->local_context.algorithm.req_pqc_asym_alg != 0) {
     405            0 :                 struct_table[index].alg_type =
     406              :                     SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG;
     407            0 :                 struct_table[index].alg_count = 0x20;
     408            0 :                 struct_table[index].alg_supported =
     409            0 :                     (uint16_t)spdm_context->local_context.algorithm.req_pqc_asym_alg;
     410            0 :                 index++;
     411              :             }
     412            0 :             if (spdm_context->local_context.algorithm.kem_alg != 0) {
     413            0 :                 struct_table[index].alg_type =
     414              :                     SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG;
     415            0 :                 struct_table[index].alg_count = 0x20;
     416            0 :                 struct_table[index].alg_supported =
     417            0 :                     (uint16_t)spdm_context->local_context.algorithm.kem_alg;
     418            0 :                 index++;
     419              :             }
     420              :         }
     421              : 
     422            1 :         supported_algorithms->param1 = index;
     423            1 :         supported_algorithms->length +=
     424            1 :             supported_algorithms->param1*
     425              :             sizeof(spdm_negotiate_algorithms_common_struct_table_t);
     426              : 
     427            8 :     } else if (spdm_response->header.spdm_version < SPDM_MESSAGE_VERSION_12) {
     428            6 :         *response_size = sizeof(spdm_capabilities_response_t) -
     429              :                          sizeof(spdm_response->data_transfer_size) -
     430              :                          sizeof(spdm_response->max_spdm_msg_size);
     431              :     }
     432              : 
     433            9 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     434            0 :         spdm_response->ext_flags =
     435            0 :             libspdm_mask_capability_ext_flags(spdm_context, false,
     436            0 :                                               spdm_context->local_context.capability.ext_flags);
     437              :     } else {
     438            9 :         spdm_response->ext_flags = 0;
     439              :     }
     440              : 
     441              :     /* -=[Process Request Phase]=- */
     442            9 :     status = libspdm_append_message_a(spdm_context, spdm_request, request_size);
     443            9 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     444            0 :         return libspdm_generate_error_response(spdm_context,
     445              :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     446              :                                                response_size, response);
     447              :     }
     448            9 :     status = libspdm_append_message_a(spdm_context, spdm_response, *response_size);
     449              : 
     450            9 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     451            0 :         return libspdm_generate_error_response(spdm_context,
     452              :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     453              :                                                response_size, response);
     454              :     }
     455              : 
     456            9 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     457            7 :         spdm_context->connection_info.capability.ct_exponent = spdm_request->ct_exponent;
     458              :     } else {
     459            2 :         spdm_context->connection_info.capability.ct_exponent = 0;
     460              :     }
     461              : 
     462            9 :     spdm_context->connection_info.capability.flags =
     463            9 :         libspdm_mask_capability_flags(spdm_context, true, spdm_request->flags);
     464              : 
     465            9 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     466            3 :         spdm_context->connection_info.capability.data_transfer_size =
     467            3 :             spdm_request->data_transfer_size;
     468            3 :         spdm_context->connection_info.capability.max_spdm_msg_size =
     469            3 :             spdm_request->max_spdm_msg_size;
     470              :     } else {
     471            6 :         spdm_context->connection_info.capability.data_transfer_size = 0;
     472            6 :         spdm_context->connection_info.capability.max_spdm_msg_size = 0;
     473              :     }
     474              : 
     475            9 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     476            0 :         spdm_context->connection_info.capability.ext_flags =
     477            0 :             libspdm_mask_capability_ext_flags(spdm_context, true, spdm_request->ext_flags);
     478              :     } else {
     479            9 :         spdm_context->connection_info.capability.ext_flags = 0;
     480              :     }
     481              : 
     482              :     /* -=[Update State Phase]=- */
     483            9 :     libspdm_set_connection_state(spdm_context, LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES);
     484              : 
     485            9 :     return LIBSPDM_STATUS_SUCCESS;
     486              : }
        

Generated by: LCOV version 2.0-1