LCOV - code coverage report
Current view: top level - library/spdm_requester_lib - libspdm_req_get_capabilities.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.6 % 250 224
Test Date: 2025-10-12 08:10:56 Functions: 100.0 % 4 4

            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_requester_lib.h"
       8              : 
       9              : /**
      10              :  * This function validates the Responder's capabilities.
      11              :  *
      12              :  * @param  capabilities_flag The Responder's CAPABILITIES.Flags field.
      13              :  * @param  version           The SPDM message version.
      14              :  *
      15              :  * @retval true  The field is valid.
      16              :  * @retval false The field is invalid.
      17              :  **/
      18           36 : static bool validate_responder_capability(uint32_t capabilities_flag, uint8_t version)
      19              : {
      20              :     /*uint8_t cache_cap = (uint8_t)(capabilities_flag)&0x01;*/
      21           36 :     const uint8_t cert_cap = (uint8_t)(capabilities_flag >> 1) & 0x01;
      22           36 :     const uint8_t chal_cap = (uint8_t)(capabilities_flag >> 2) & 0x01;
      23           36 :     const uint8_t meas_cap = (uint8_t)(capabilities_flag >> 3) & 0x03;
      24           36 :     const uint8_t meas_fresh_cap = (uint8_t)(capabilities_flag >> 5) & 0x01;
      25           36 :     const uint8_t encrypt_cap = (uint8_t)(capabilities_flag >> 6) & 0x01;
      26           36 :     const uint8_t mac_cap = (uint8_t)(capabilities_flag >> 7) & 0x01;
      27           36 :     const uint8_t mut_auth_cap = (uint8_t)(capabilities_flag >> 8) & 0x01;
      28           36 :     const uint8_t key_ex_cap = (uint8_t)(capabilities_flag >> 9) & 0x01;
      29           36 :     const uint8_t psk_cap = (uint8_t)(capabilities_flag >> 10) & 0x03;
      30           36 :     const uint8_t encap_cap = (uint8_t)(capabilities_flag >> 12) & 0x01;
      31           36 :     const uint8_t hbeat_cap = (uint8_t)(capabilities_flag >> 13) & 0x01;
      32           36 :     const uint8_t key_upd_cap = (uint8_t)(capabilities_flag >> 14) & 0x01;
      33           36 :     const uint8_t handshake_in_the_clear_cap = (uint8_t)(capabilities_flag >> 15) & 0x01;
      34           36 :     const uint8_t pub_key_id_cap = (uint8_t)(capabilities_flag >> 16) & 0x01;
      35              :     /* uint8_t chunk_cap = (uint8_t)(capabilities_flag >> 17) & 0x01; */
      36           36 :     const uint8_t alias_cert_cap = (uint8_t)(capabilities_flag >> 18) & 0x01;
      37           36 :     const uint8_t set_cert_cap = (uint8_t)(capabilities_flag >> 19) & 0x01;
      38           36 :     const uint8_t csr_cap = (uint8_t)(capabilities_flag >> 20) & 0x01;
      39           36 :     const uint8_t cert_install_reset_cap = (uint8_t)(capabilities_flag >> 21) & 0x01;
      40           36 :     const uint8_t ep_info_cap = (uint8_t)(capabilities_flag >> 22) & 0x03;
      41              :     /* const uint8_t mel_cap = (uint8_t)(capabilities_flag >> 24) & 0x01; */
      42           36 :     const uint8_t event_cap = (uint8_t)(capabilities_flag >> 25) & 0x01;
      43           36 :     const uint8_t multi_key_cap = (uint8_t)(capabilities_flag >> 26) & 0x03;
      44           36 :     const uint8_t get_key_pair_info_cap = (uint8_t)(capabilities_flag >> 28) & 0x01;
      45           36 :     const uint8_t set_key_pair_info_cap = (uint8_t)(capabilities_flag >> 29) & 0x01;
      46           36 :     const uint8_t set_key_pair_reset_cap = (uint8_t)(capabilities_flag >> 30) & 0x01;
      47              :     /* const uint8_t large_resp_cap = (uint8_t)(capabilities_flag >> 31) & 0x01; */
      48              : 
      49              :     /* Checks common to all SPDM versions. */
      50              : 
      51              :     /* Illegal to return reserved value. */
      52           36 :     if (meas_cap == 3) {
      53            1 :         return false;
      54              :     }
      55              : 
      56              :     /* If MEAS_FRESH_CAP is set then MEAS_CAP must be set. */
      57           35 :     if ((meas_cap == 0) && (meas_fresh_cap == 1)) {
      58            1 :         return false;
      59              :     }
      60              : 
      61           34 :     if (version == SPDM_MESSAGE_VERSION_10) {
      62              :         /* If measurements are not signed then CERT_CAP must equal CHAL_CAP.
      63              :          * If measurements are signed then CERT_CAP must be set. */
      64            7 :         if ((meas_cap == 0) || (meas_cap == 1)) {
      65            5 :             if (cert_cap != chal_cap) {
      66            1 :                 return false;
      67              :             }
      68            2 :         } else if (meas_cap == 2) {
      69            2 :             if (cert_cap == 0) {
      70            1 :                 return false;
      71              :             }
      72              :         }
      73            5 :         return true;
      74              :     }
      75              : 
      76              :     /* Checks common to 1.1 and higher. */
      77           27 :     if (version >= SPDM_MESSAGE_VERSION_11) {
      78              :         /* Illegal to return reserved values. */
      79           27 :         if (psk_cap == 3) {
      80            1 :             return false;
      81              :         }
      82              : 
      83              :         /* Checks that originate from key exchange capabilities. */
      84           26 :         if ((key_ex_cap == 1) || (psk_cap != 0)) {
      85           12 :             if ((mac_cap == 0) && (encrypt_cap == 0)) {
      86            4 :                 return false;
      87              :             }
      88              :         } else {
      89           14 :             if ((mac_cap == 1) || (encrypt_cap == 1) || (handshake_in_the_clear_cap == 1) ||
      90           11 :                 (hbeat_cap == 1) || (key_upd_cap == 1)) {
      91            3 :                 return false;
      92              :             }
      93           11 :             if (version >= SPDM_MESSAGE_VERSION_13) {
      94            1 :                 if (event_cap == 1) {
      95            0 :                     return false;
      96              :                 }
      97              :             }
      98              :         }
      99           19 :         if ((key_ex_cap == 0) && (psk_cap != 0)) {
     100            1 :             if (handshake_in_the_clear_cap == 1) {
     101            1 :                 return false;
     102              :             }
     103              :         }
     104              : 
     105              :         /* Checks that originate from certificate or public key capabilities. */
     106           18 :         if ((cert_cap == 1) || (pub_key_id_cap == 1)) {
     107              :             /* Certificate capabilities and public key capabilities cannot both be set. */
     108           13 :             if ((cert_cap == 1) && (pub_key_id_cap == 1)) {
     109            1 :                 return false;
     110              :             }
     111              :             /* If certificates or public keys are enabled then at least one of these capabilities
     112              :              * must be enabled to use the key. */
     113           12 :             if ((chal_cap == 0) && (key_ex_cap == 0) && ((meas_cap == 0) || (meas_cap == 1))) {
     114            1 :                 if (version >= SPDM_MESSAGE_VERSION_13) {
     115            0 :                     if ((ep_info_cap == 0) || (ep_info_cap == 1)) {
     116            0 :                         return false;
     117              :                     }
     118              :                 } else {
     119            1 :                     return false;
     120              :                 }
     121              :             }
     122              :         } else {
     123              :             /* If certificates or public keys are not enabled then these capabilities
     124              :              * cannot be enabled. */
     125            5 :             if ((chal_cap == 1) || (key_ex_cap == 1) || (meas_cap == 2) || (mut_auth_cap == 1)) {
     126            1 :                 return false;
     127              :             }
     128            4 :             if (version >= SPDM_MESSAGE_VERSION_13) {
     129            1 :                 if (ep_info_cap == 2) {
     130            1 :                     return false;
     131              :                 }
     132              :             }
     133              :         }
     134              : 
     135              :         /* Checks that originate from mutual authentication capabilities. */
     136           14 :         if (mut_auth_cap == 1) {
     137              :             /* Mutual authentication with asymmetric keys can only occur through the basic mutual
     138              :              * authentication flow (CHAL_CAP == 1) or the session-based mutual authentication flow
     139              :              * (KEY_EX_CAP == 1). */
     140            5 :             if ((key_ex_cap == 0) && (chal_cap == 0)) {
     141            0 :                 return false;
     142              :             }
     143              :         }
     144              :     }
     145              : 
     146              :     /* Checks specific to 1.1. */
     147           14 :     if (version == SPDM_MESSAGE_VERSION_11) {
     148            3 :         if ((mut_auth_cap == 1) && (encap_cap == 0)) {
     149            1 :             return false;
     150              :         }
     151              :     }
     152              : 
     153              :     /* Checks common to 1.2 and higher. */
     154           13 :     if (version >= SPDM_MESSAGE_VERSION_12) {
     155           11 :         if ((cert_cap == 0) && ((alias_cert_cap == 1) || (set_cert_cap == 1))) {
     156            1 :             return false;
     157              :         }
     158           10 :         if ((csr_cap == 1) && (set_cert_cap == 0)) {
     159            1 :             return false;
     160              :         }
     161            9 :         if ((cert_install_reset_cap == 1) && (csr_cap == 0) && (set_cert_cap == 0)) {
     162            1 :             return false;
     163              :         }
     164              :     }
     165              : 
     166              :     /* Checks specific to 1.3 and higher. */
     167           10 :     if (version >= SPDM_MESSAGE_VERSION_13) {
     168              :         /* Illegal to return reserved values. */
     169            2 :         if ((ep_info_cap == 3) || (multi_key_cap == 3)) {
     170            0 :             return false;
     171              :         }
     172            2 :         if ((multi_key_cap != 0) && ((get_key_pair_info_cap == 0) || (cert_cap == 0))) {
     173            0 :             return false;
     174              :         }
     175            2 :         if (pub_key_id_cap == 1) {
     176            0 :             if ((multi_key_cap != 0) || (get_key_pair_info_cap == 1) ||
     177              :                 (set_key_pair_info_cap == 1)) {
     178            0 :                 return false;
     179              :             }
     180              :         }
     181              :     }
     182              : 
     183              :     /* Checks that are deferred to when a message is sent.
     184              :      *
     185              :      * If the Responder supports key exchange then MAC_CAP must be set. In addition, if the
     186              :      * negotiated SPDM version is greater than 1.1 then the negotiated opaque data format must be
     187              :      * OpaqueDataFmt1.
     188              :      */
     189              : 
     190              :     /* Checks specific to 1.4 and higher. */
     191           10 :     if (version >= SPDM_MESSAGE_VERSION_14) {
     192            0 :         if ((set_key_pair_reset_cap == 1) && (set_key_pair_info_cap == 0)) {
     193            0 :             return false;
     194              :         }
     195              :     }
     196              : 
     197           10 :     return true;
     198              : }
     199              : 
     200              : /**
     201              :  * This function sends GET_CAPABILITIES and receives CAPABILITIES.
     202              :  *
     203              :  * @param  spdm_context A pointer to the SPDM context.
     204              :  *
     205              :  * @retval LIBSPDM_STATUS_SUCCESS
     206              :  *         GET_CAPABILITIES was sent and CAPABILITIES was received.
     207              :  * @retval LIBSPDM_STATUS_INVALID_STATE_LOCAL
     208              :  *         Cannot send GET_CAPABILITIES due to Requester's state. Send GET_VERSION first.
     209              :  * @retval LIBSPDM_STATUS_INVALID_MSG_SIZE
     210              :  *         The size of the CAPABILITIES response is invalid.
     211              :  * @retval LIBSPDM_STATUS_INVALID_MSG_FIELD
     212              :  *         The CAPABILITIES response contains one or more invalid fields.
     213              :  * @retval LIBSPDM_STATUS_ERROR_PEER
     214              :  *         The Responder returned an unexpected error.
     215              :  * @retval LIBSPDM_STATUS_BUSY_PEER
     216              :  *         The Responder continually returned Busy error messages.
     217              :  * @retval LIBSPDM_STATUS_RESYNCH_PEER
     218              :  *         The Responder returned a RequestResynch error message.
     219              :  * @retval LIBSPDM_STATUS_BUFFER_FULL
     220              :  *         The buffer used to store transcripts is exhausted.
     221              :  **/
     222           69 : static libspdm_return_t libspdm_try_get_capabilities(libspdm_context_t *spdm_context,
     223              :                                                      size_t *supported_algs_length,
     224              :                                                      void *supported_algs)
     225              : {
     226              :     libspdm_return_t status;
     227              :     spdm_get_capabilities_request_t *spdm_request;
     228              :     size_t spdm_request_size;
     229              :     spdm_capabilities_response_t *spdm_response;
     230              :     size_t spdm_response_size;
     231              :     uint8_t *message;
     232              :     size_t message_size;
     233              :     size_t transport_header_size;
     234              : 
     235              :     /* -=[Verify State Phase]=- */
     236           69 :     if (spdm_context->connection_info.connection_state != LIBSPDM_CONNECTION_STATE_AFTER_VERSION) {
     237            1 :         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     238              :     }
     239           68 :     libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_GET_CAPABILITIES);
     240              : 
     241              :     /* -=[Construct Request Phase]=- */
     242           68 :     transport_header_size = spdm_context->local_context.capability.transport_header_size;
     243           68 :     status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
     244           68 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     245            1 :         return status;
     246              :     }
     247           67 :     LIBSPDM_ASSERT (message_size >= transport_header_size +
     248              :                     spdm_context->local_context.capability.transport_tail_size);
     249           67 :     spdm_request = (void *)(message + transport_header_size);
     250           67 :     spdm_request_size = message_size - transport_header_size -
     251           67 :                         spdm_context->local_context.capability.transport_tail_size;
     252              : 
     253           67 :     LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_request->header));
     254              : 
     255           67 :     libspdm_zero_mem(spdm_request, spdm_request_size);
     256           67 :     spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
     257           67 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     258           12 :         LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_get_capabilities_request_t));
     259           12 :         spdm_request_size = sizeof(spdm_get_capabilities_request_t);
     260           55 :     } else if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     261           35 :         LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_get_capabilities_request_t) -
     262              :                         sizeof(spdm_request->data_transfer_size) -
     263              :                         sizeof(spdm_request->max_spdm_msg_size));
     264           35 :         spdm_request_size = sizeof(spdm_get_capabilities_request_t) -
     265              :                             sizeof(spdm_request->data_transfer_size) -
     266              :                             sizeof(spdm_request->max_spdm_msg_size);
     267              :     } else {
     268           20 :         spdm_request_size = sizeof(spdm_request->header);
     269              :     }
     270           67 :     spdm_request->header.request_response_code = SPDM_GET_CAPABILITIES;
     271           67 :     spdm_request->header.param1 = 0;
     272           67 :     spdm_request->header.param2 = 0;
     273           67 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     274           47 :         spdm_request->ct_exponent = spdm_context->local_context.capability.ct_exponent;
     275           47 :         spdm_request->flags =
     276           47 :             libspdm_mask_capability_flags(spdm_context, true,
     277              :                                           spdm_context->local_context.capability.flags);
     278              :     }
     279              : 
     280           67 :     if (supported_algs != NULL) {
     281            1 :         LIBSPDM_ASSERT((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
     282              :                        ((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) != 0));
     283              : 
     284            1 :         spdm_request->header.param1 |= SPDM_GET_CAPABILITIES_REQUEST_PARAM1_SUPPORTED_ALGORITHMS;
     285              :     }
     286              : 
     287           67 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     288           12 :         spdm_request->data_transfer_size =
     289           12 :             spdm_context->local_context.capability.data_transfer_size;
     290           12 :         spdm_request->max_spdm_msg_size =
     291           12 :             spdm_context->local_context.capability.max_spdm_msg_size;
     292              :     }
     293           67 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     294            0 :         spdm_request->ext_flags =
     295            0 :             libspdm_mask_capability_ext_flags(spdm_context, true,
     296            0 :                                               spdm_context->local_context.capability.ext_flags);
     297              :     } else {
     298           67 :         spdm_request->ext_flags = 0;
     299              :     }
     300              : 
     301              :     /* -=[Send Request Phase]=- */
     302           67 :     status = libspdm_send_spdm_request(spdm_context, NULL, spdm_request_size, spdm_request);
     303           67 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     304            1 :         libspdm_release_sender_buffer (spdm_context);
     305            1 :         return status;
     306              :     }
     307           66 :     libspdm_release_sender_buffer (spdm_context);
     308           66 :     spdm_request = (void *)spdm_context->last_spdm_request;
     309              : 
     310              :     /* -=[Receive Response Phase]=- */
     311           66 :     status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
     312           66 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     313            1 :         return status;
     314              :     }
     315           65 :     LIBSPDM_ASSERT (message_size >= transport_header_size);
     316           65 :     spdm_response = (void *)(message);
     317           65 :     spdm_response_size = message_size;
     318              : 
     319           65 :     status = libspdm_receive_spdm_response(spdm_context, NULL, &spdm_response_size,
     320              :                                            (void **)&spdm_response);
     321           65 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     322            3 :         goto receive_done;
     323              :     }
     324              : 
     325              :     /* -=[Validate Response Phase]=- */
     326           62 :     if (spdm_response_size < sizeof(spdm_message_header_t)) {
     327            0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     328            0 :         goto receive_done;
     329              :     }
     330           62 :     if (spdm_response->header.request_response_code == SPDM_ERROR) {
     331           23 :         status = libspdm_handle_simple_error_response(
     332           23 :             spdm_context, spdm_response->header.param1);
     333           23 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     334           23 :             goto receive_done;
     335              :         }
     336           39 :     } else if (spdm_response->header.request_response_code != SPDM_CAPABILITIES) {
     337            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     338            1 :         goto receive_done;
     339              :     }
     340           38 :     if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
     341            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     342            1 :         goto receive_done;
     343              :     }
     344           37 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     345           12 :         if (spdm_response_size < sizeof(spdm_capabilities_response_t)) {
     346            0 :             status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     347            0 :             goto receive_done;
     348              :         }
     349              :     } else {
     350           25 :         if (spdm_response_size < sizeof(spdm_capabilities_response_t) -
     351              :             sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)) {
     352            1 :             status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     353            1 :             goto receive_done;
     354              :         }
     355              :     }
     356              : 
     357           36 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
     358            3 :         (spdm_request->header.param1 & SPDM_GET_CAPABILITIES_REQUEST_PARAM1_SUPPORTED_ALGORITHMS)) {
     359              : 
     360            1 :         spdm_supported_algorithms_block_t *supported_algorithms =
     361            1 :             (spdm_supported_algorithms_block_t*)((uint8_t*)spdm_response + sizeof(spdm_capabilities_response_t));
     362              : 
     363            1 :         spdm_response_size = sizeof(spdm_capabilities_response_t) + supported_algorithms->length;
     364              : 
     365           35 :     } else if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     366           11 :         spdm_response_size = sizeof(spdm_capabilities_response_t);
     367              :     } else {
     368           24 :         spdm_response_size = sizeof(spdm_capabilities_response_t) -
     369              :                              sizeof(spdm_response->data_transfer_size) -
     370              :                              sizeof(spdm_response->max_spdm_msg_size);
     371              :     }
     372              : 
     373           36 :     if (!validate_responder_capability(spdm_response->flags, spdm_response->header.spdm_version)) {
     374           21 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     375           21 :         goto receive_done;
     376              :     }
     377           15 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     378            8 :         if ((spdm_response->data_transfer_size < SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) ||
     379            7 :             (spdm_response->data_transfer_size > spdm_response->max_spdm_msg_size)) {
     380            2 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     381            2 :             goto receive_done;
     382              :         }
     383              : 
     384            6 :         if (((spdm_response->flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP) == 0) &&
     385            2 :             (spdm_response->data_transfer_size != spdm_response->max_spdm_msg_size)) {
     386            1 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     387            1 :             goto receive_done;
     388              :         }
     389              :     }
     390              : 
     391           12 :     if (spdm_response->ct_exponent > LIBSPDM_MAX_CT_EXPONENT) {
     392            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     393            1 :         goto receive_done;
     394              :     }
     395              : 
     396              :     /* -=[Process Response Phase]=- */
     397           11 :     status = libspdm_append_message_a(spdm_context, spdm_request, spdm_request_size);
     398           11 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     399            1 :         goto receive_done;
     400              :     }
     401              : 
     402           10 :     status = libspdm_append_message_a(spdm_context, spdm_response, spdm_response_size);
     403           10 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     404            0 :         goto receive_done;
     405              :     }
     406              : 
     407           10 :     spdm_context->connection_info.capability.ct_exponent = spdm_response->ct_exponent;
     408           10 :     spdm_context->connection_info.capability.flags =
     409           10 :         libspdm_mask_capability_flags(spdm_context, false, spdm_response->flags);
     410              : 
     411           10 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     412            0 :         spdm_context->connection_info.capability.ext_flags =
     413            0 :             libspdm_mask_capability_ext_flags(spdm_context, false, spdm_response->ext_flags);
     414              :     } else {
     415           10 :         spdm_context->connection_info.capability.ext_flags = 0;
     416              :     }
     417              : 
     418           10 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     419            3 :         spdm_context->connection_info.capability.data_transfer_size =
     420            3 :             spdm_response->data_transfer_size;
     421            3 :         spdm_context->connection_info.capability.max_spdm_msg_size =
     422            3 :             spdm_response->max_spdm_msg_size;
     423              :     } else {
     424            7 :         spdm_context->connection_info.capability.data_transfer_size = 0;
     425            7 :         spdm_context->connection_info.capability.max_spdm_msg_size = 0;
     426              :     }
     427              : 
     428              :     /* Copy algorithms if requested and received */
     429           10 :     if (supported_algs != NULL &&
     430            1 :         spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
     431            1 :         (spdm_request->header.param1 & SPDM_GET_CAPABILITIES_REQUEST_PARAM1_SUPPORTED_ALGORITHMS)) {
     432              : 
     433            1 :         spdm_supported_algorithms_block_t *supported_algorithms =
     434            1 :             (spdm_supported_algorithms_block_t*)((uint8_t*)spdm_response +
     435              :                                                  sizeof(spdm_capabilities_response_t));
     436              : 
     437            1 :         size_t algorithm_data_size = spdm_response_size - sizeof(spdm_capabilities_response_t);
     438              : 
     439            1 :         if (*supported_algs_length >= algorithm_data_size) {
     440            1 :             libspdm_copy_mem(supported_algs, *supported_algs_length,
     441              :                              supported_algorithms, algorithm_data_size);
     442            1 :             *supported_algs_length = algorithm_data_size;
     443              :         } else {
     444            0 :             *supported_algs_length = algorithm_data_size;
     445            0 :             status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     446            0 :             goto receive_done;
     447              :         }
     448              :     }
     449              : 
     450              :     /* -=[Update State Phase]=- */
     451           10 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
     452           10 :     status = LIBSPDM_STATUS_SUCCESS;
     453              : 
     454              :     /* -=[Log Message Phase]=- */
     455              :     #if LIBSPDM_ENABLE_MSG_LOG
     456           10 :     libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
     457              :     #endif /* LIBSPDM_ENABLE_MSG_LOG */
     458              : 
     459           65 : receive_done:
     460           65 :     libspdm_release_receiver_buffer (spdm_context);
     461           65 :     return status;
     462              : }
     463              : 
     464           67 : libspdm_return_t libspdm_get_capabilities(libspdm_context_t *spdm_context)
     465              : {
     466              :     size_t retry;
     467              :     uint64_t retry_delay_time;
     468              :     libspdm_return_t status;
     469              : 
     470           67 :     spdm_context->crypto_request = false;
     471           67 :     retry = spdm_context->retry_times;
     472           67 :     retry_delay_time = spdm_context->retry_delay_time;
     473              :     do {
     474           68 :         status = libspdm_try_get_capabilities(spdm_context, NULL, NULL);
     475           68 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     476           66 :             return status;
     477              :         }
     478              : 
     479            2 :         libspdm_sleep(retry_delay_time);
     480            2 :     } while (retry-- != 0);
     481              : 
     482            1 :     return status;
     483              : }
     484              : 
     485            1 : libspdm_return_t libspdm_get_capabilities_with_supported_algs(libspdm_context_t *spdm_context,
     486              :                                                               size_t *supported_algs_length,
     487              :                                                               void *supported_algs)
     488              : {
     489              :     size_t retry;
     490              :     uint64_t retry_delay_time;
     491              :     libspdm_return_t status;
     492              : 
     493            1 :     LIBSPDM_ASSERT((supported_algs == NULL) || (supported_algs_length != NULL));
     494              : 
     495            1 :     spdm_context->crypto_request = false;
     496            1 :     retry = spdm_context->retry_times;
     497            1 :     retry_delay_time = spdm_context->retry_delay_time;
     498              :     do {
     499              :         status =
     500            1 :             libspdm_try_get_capabilities(spdm_context, supported_algs_length, supported_algs);
     501            1 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     502            1 :             return status;
     503              :         }
     504              : 
     505            0 :         libspdm_sleep(retry_delay_time);
     506            0 :     } while (retry-- != 0);
     507              : 
     508            0 :     return status;
     509              : }
        

Generated by: LCOV version 2.0-1