LCOV - code coverage report
Current view: top level - library/spdm_requester_lib - libspdm_req_negotiate_algorithms.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.9 % 457 388
Test Date: 2025-08-24 08:11:14 Functions: 100.0 % 2 2

            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              : #pragma pack(1)
      10              : typedef struct {
      11              :     spdm_message_header_t header;
      12              :     uint16_t length;
      13              :     uint8_t measurement_specification;
      14              :     uint8_t other_params_support;
      15              :     uint32_t base_asym_algo;
      16              :     uint32_t base_hash_algo;
      17              :     uint32_t pqc_asym_algo;
      18              :     uint8_t reserved2[8];
      19              :     uint8_t ext_asym_count;
      20              :     uint8_t ext_hash_count;
      21              :     uint8_t reserved3;
      22              :     uint8_t mel_specification;
      23              :     spdm_negotiate_algorithms_common_struct_table_t struct_table[
      24              :         SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG_14];
      25              : } libspdm_negotiate_algorithms_request_mine_t;
      26              : 
      27              : typedef struct {
      28              :     spdm_message_header_t header;
      29              :     uint16_t length;
      30              :     uint8_t measurement_specification_sel;
      31              :     uint8_t other_params_selection;
      32              :     uint32_t measurement_hash_algo;
      33              :     uint32_t base_asym_sel;
      34              :     uint32_t base_hash_sel;
      35              :     uint32_t pqc_asym_sel;
      36              :     uint8_t reserved2[7];
      37              :     uint8_t mel_specification_sel;
      38              :     uint8_t ext_asym_sel_count;
      39              :     uint8_t ext_hash_sel_count;
      40              :     uint16_t reserved3;
      41              :     uint32_t ext_asym_sel;
      42              :     uint32_t ext_hash_sel;
      43              :     spdm_negotiate_algorithms_common_struct_table_t struct_table[
      44              :         SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG_14];
      45              : } libspdm_algorithms_response_max_t;
      46              : #pragma pack()
      47              : 
      48              : /**
      49              :  * This function sends NEGOTIATE_ALGORITHMS and receives ALGORITHMS.
      50              :  *
      51              :  * @param  spdm_context A pointer to the SPDM context.
      52              :  *
      53              :  * @retval LIBSPDM_STATUS_SUCCESS
      54              :  *         NEGOTIATE_ALGORITHMS was sent and ALGORITHMS was received.
      55              :  * @retval LIBSPDM_STATUS_INVALID_STATE_LOCAL
      56              :  *         Cannot send NEGOTIATE_ALGORITHMS due to Requester's state.
      57              :  * @retval LIBSPDM_STATUS_INVALID_MSG_SIZE
      58              :  *         The size of the ALGORITHMS response is invalid.
      59              :  * @retval LIBSPDM_STATUS_INVALID_MSG_FIELD
      60              :  *         The ALGORITHMS response contains one or more invalid fields.
      61              :  * @retval LIBSPDM_STATUS_ERROR_PEER
      62              :  *         The Responder returned an unexpected error.
      63              :  * @retval LIBSPDM_STATUS_BUSY_PEER
      64              :  *         The Responder continually returned Busy error messages.
      65              :  * @retval LIBSPDM_STATUS_RESYNCH_PEER
      66              :  *         The Responder returned a RequestResynch error message.
      67              :  * @retval LIBSPDM_STATUS_BUFFER_FULL
      68              :  *         The buffer used to store transcripts is exhausted.
      69              :  * @retval LIBSPDM_STATUS_NEGOTIATION_FAIL
      70              :  *         The Requester and Responder could not agree on mutual algorithms.
      71              :  *         Note: This return value may be removed in the future.
      72              :  **/
      73           88 : static libspdm_return_t libspdm_try_negotiate_algorithms(libspdm_context_t *spdm_context)
      74              : {
      75              :     libspdm_return_t status;
      76              :     libspdm_negotiate_algorithms_request_mine_t *spdm_request;
      77              :     size_t spdm_request_size;
      78              :     libspdm_algorithms_response_max_t *spdm_response;
      79              :     size_t spdm_response_size;
      80              :     uint32_t algo_size;
      81              :     uint32_t pqc_algo_size;
      82           88 :     size_t index = 0;
      83              :     spdm_negotiate_algorithms_common_struct_table_t *struct_table;
      84              :     uint8_t fixed_alg_size;
      85              :     uint8_t ext_alg_count;
      86              :     uint8_t *message;
      87              :     size_t message_size;
      88              :     size_t transport_header_size;
      89              :     uint8_t alg_type_pre;
      90           88 :     uint8_t req_param1 = 0;
      91              : 
      92              :     /* -=[Verify State Phase]=- */
      93           88 :     if (spdm_context->connection_info.connection_state !=
      94              :         LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES) {
      95            1 :         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
      96              :     }
      97              : 
      98           87 :     libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_NEGOTIATE_ALGORITHMS);
      99              : 
     100              :     /* -=[Construct Request Phase]=- */
     101           87 :     transport_header_size = spdm_context->local_context.capability.transport_header_size;
     102           87 :     status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
     103           87 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     104            1 :         return status;
     105              :     }
     106           86 :     LIBSPDM_ASSERT (message_size >= transport_header_size +
     107              :                     spdm_context->local_context.capability.transport_tail_size);
     108           86 :     spdm_request = (void *)(message + transport_header_size);
     109           86 :     spdm_request_size = message_size - transport_header_size -
     110           86 :                         spdm_context->local_context.capability.transport_tail_size;
     111              : 
     112           86 :     LIBSPDM_ASSERT(spdm_request_size >= sizeof(spdm_negotiate_algorithms_request_t));
     113           86 :     libspdm_zero_mem(spdm_request, spdm_request_size);
     114           86 :     spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
     115           86 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     116              :         /* Number of Algorithms Structure Tables based on supported algorithms */
     117           51 :         if (spdm_context->local_context.algorithm.dhe_named_group != 0) {
     118           50 :             req_param1++;
     119              :         }
     120           51 :         if (spdm_context->local_context.algorithm.aead_cipher_suite != 0) {
     121           50 :             req_param1++;
     122              :         }
     123           51 :         if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
     124           50 :             req_param1++;
     125              :         }
     126           51 :         if (spdm_context->local_context.algorithm.key_schedule != 0) {
     127           50 :             req_param1++;
     128              :         }
     129           51 :         LIBSPDM_ASSERT(req_param1 <=
     130              :                        SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG);
     131           51 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     132            0 :             if (spdm_context->local_context.algorithm.req_pqc_asym_alg != 0) {
     133            0 :                 req_param1++;
     134              :             }
     135            0 :             if (spdm_context->local_context.algorithm.kem_alg != 0) {
     136            0 :                 req_param1++;
     137              :             }
     138            0 :             LIBSPDM_ASSERT(req_param1 <=
     139              :                            SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG_14);
     140              :         }
     141           51 :         spdm_request->header.param1 = req_param1;
     142           51 :         spdm_request->length =
     143           51 :             offsetof(libspdm_negotiate_algorithms_request_mine_t, struct_table) +
     144              :             req_param1 * sizeof(spdm_negotiate_algorithms_common_struct_table_t);
     145              :     } else {
     146           35 :         spdm_request->length = offsetof(libspdm_negotiate_algorithms_request_mine_t, struct_table);
     147           35 :         spdm_request->header.param1 = 0;
     148              :     }
     149              : 
     150           86 :     LIBSPDM_ASSERT(spdm_request_size >= spdm_request->length);
     151           86 :     spdm_request->header.request_response_code = SPDM_NEGOTIATE_ALGORITHMS;
     152           86 :     spdm_request->header.param2 = 0;
     153           86 :     spdm_request->measurement_specification =
     154           86 :         spdm_context->local_context.algorithm.measurement_spec;
     155           86 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     156           33 :         spdm_request->other_params_support =
     157           33 :             spdm_context->local_context.algorithm.other_params_support &
     158              :             SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK;
     159           33 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     160           14 :             spdm_request->other_params_support =
     161           14 :                 spdm_context->local_context.algorithm.other_params_support;
     162           14 :             spdm_request->mel_specification =
     163           14 :                 spdm_context->local_context.algorithm.mel_spec;
     164              :         }
     165              :     }
     166           86 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     167           14 :         switch (spdm_context->connection_info.capability.flags &
     168              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) {
     169           10 :         case 0:
     170           10 :             spdm_context->connection_info.multi_key_conn_rsp = false;
     171           10 :             break;
     172            2 :         case SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_ONLY:
     173            2 :             spdm_context->connection_info.multi_key_conn_rsp = true;
     174            2 :             break;
     175            2 :         case SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_NEG:
     176            2 :             if ((spdm_context->local_context.algorithm.other_params_support &
     177              :                  SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
     178            1 :                 spdm_context->connection_info.multi_key_conn_rsp = false;
     179              :             } else {
     180            1 :                 spdm_context->connection_info.multi_key_conn_rsp = true;
     181              :             }
     182            2 :             break;
     183            0 :         default:
     184            0 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     185              :         }
     186           14 :         if (spdm_context->connection_info.multi_key_conn_rsp) {
     187            3 :             spdm_request->other_params_support |= SPDM_ALGORITHMS_MULTI_KEY_CONN;
     188              :         } else {
     189           11 :             spdm_request->other_params_support &= ~SPDM_ALGORITHMS_MULTI_KEY_CONN;
     190              :         }
     191              :     }
     192           86 :     spdm_request->base_asym_algo = spdm_context->local_context.algorithm.base_asym_algo;
     193           86 :     spdm_request->base_hash_algo = spdm_context->local_context.algorithm.base_hash_algo;
     194           86 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     195            0 :         spdm_request->pqc_asym_algo = spdm_context->local_context.algorithm.pqc_asym_algo;
     196              :     }
     197           86 :     spdm_request->ext_asym_count = 0;
     198           86 :     spdm_request->ext_hash_count = 0;
     199           86 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     200              :         /* ReqAlgStruct order based on by AlgType */
     201           51 :         if (spdm_context->local_context.algorithm.dhe_named_group != 0) {
     202           50 :             spdm_request->struct_table[index].alg_type =
     203              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
     204           50 :             spdm_request->struct_table[index].alg_count = 0x20;
     205           50 :             spdm_request->struct_table[index].alg_supported =
     206           50 :                 spdm_context->local_context.algorithm.dhe_named_group;
     207           50 :             index++;
     208              :         }
     209           51 :         if (spdm_context->local_context.algorithm.aead_cipher_suite != 0) {
     210           50 :             spdm_request->struct_table[index].alg_type =
     211              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
     212           50 :             spdm_request->struct_table[index].alg_count = 0x20;
     213           50 :             spdm_request->struct_table[index].alg_supported =
     214           50 :                 spdm_context->local_context.algorithm.aead_cipher_suite;
     215           50 :             index++;
     216              :         }
     217           51 :         if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
     218           50 :             spdm_request->struct_table[index].alg_type =
     219              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
     220           50 :             spdm_request->struct_table[index].alg_count = 0x20;
     221           50 :             spdm_request->struct_table[index].alg_supported =
     222           50 :                 spdm_context->local_context.algorithm.req_base_asym_alg;
     223           50 :             index++;
     224              :         }
     225           51 :         if (spdm_context->local_context.algorithm.key_schedule != 0) {
     226           50 :             spdm_request->struct_table[index].alg_type =
     227              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
     228           50 :             spdm_request->struct_table[index].alg_count = 0x20;
     229           50 :             spdm_request->struct_table[index].alg_supported =
     230           50 :                 spdm_context->local_context.algorithm.key_schedule;
     231           50 :             index++;
     232              :         }
     233           51 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     234            0 :             if (spdm_context->local_context.algorithm.req_pqc_asym_alg != 0) {
     235              :                 /* Add assert to ensure it can be cast to uint16_t.
     236              :                  * It is enough now and can be enlarged later. */
     237            0 :                 LIBSPDM_ASSERT(spdm_context->local_context.algorithm.req_pqc_asym_alg <= UINT16_MAX);
     238            0 :                 spdm_request->struct_table[index].alg_type =
     239              :                     SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG;
     240            0 :                 spdm_request->struct_table[index].alg_count = 0x20;
     241            0 :                 spdm_request->struct_table[index].alg_supported =
     242            0 :                     (uint16_t)spdm_context->local_context.algorithm.req_pqc_asym_alg;
     243            0 :                 index++;
     244              :             }
     245            0 :             if (spdm_context->local_context.algorithm.kem_alg != 0) {
     246              :                 /* Add assert to ensure it can be cast to uint16_t.
     247              :                  * It is enough now and can be enlarged later. */
     248            0 :                 LIBSPDM_ASSERT(spdm_context->local_context.algorithm.kem_alg <= UINT16_MAX);
     249            0 :                 spdm_request->struct_table[index].alg_type =
     250              :                     SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG;
     251            0 :                 spdm_request->struct_table[index].alg_count = 0x20;
     252            0 :                 spdm_request->struct_table[index].alg_supported =
     253            0 :                     (uint16_t)spdm_context->local_context.algorithm.kem_alg;
     254            0 :                 index++;
     255              :             }
     256              :         }
     257           51 :         LIBSPDM_ASSERT(index == spdm_request->header.param1);
     258              :     }
     259           86 :     spdm_request_size = spdm_request->length;
     260              : 
     261              :     /* -=[Send Request Phase]=- */
     262           86 :     status = libspdm_send_spdm_request(spdm_context, NULL, spdm_request_size, spdm_request);
     263           86 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     264           11 :         libspdm_release_sender_buffer (spdm_context);
     265           11 :         return status;
     266              :     }
     267           75 :     libspdm_release_sender_buffer (spdm_context);
     268           75 :     spdm_request = (void *)spdm_context->last_spdm_request;
     269              : 
     270              :     /* -=[Receive Response Phase]=- */
     271           75 :     status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
     272           75 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     273            1 :         return status;
     274              :     }
     275           74 :     LIBSPDM_ASSERT (message_size >= transport_header_size);
     276           74 :     spdm_response = (void *)(message);
     277           74 :     spdm_response_size = message_size;
     278              : 
     279           74 :     status = libspdm_receive_spdm_response(spdm_context, NULL, &spdm_response_size,
     280              :                                            (void **)&spdm_response);
     281           74 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     282            1 :         goto receive_done;
     283              :     }
     284              : 
     285              :     /* -=[Validate Response Phase]=- */
     286           73 :     if (spdm_response_size < sizeof(spdm_message_header_t)) {
     287            0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     288            0 :         goto receive_done;
     289              :     }
     290           73 :     if (spdm_response->header.request_response_code == SPDM_ERROR) {
     291            6 :         status = libspdm_handle_simple_error_response(spdm_context, spdm_response->header.param1);
     292            6 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     293            6 :             goto receive_done;
     294              :         }
     295           67 :     } else if (spdm_response->header.request_response_code != SPDM_ALGORITHMS) {
     296            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     297            1 :         goto receive_done;
     298              :     }
     299           66 :     if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
     300            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     301            1 :         goto receive_done;
     302              :     }
     303           65 :     if (spdm_response_size < sizeof(spdm_algorithms_response_t)) {
     304            2 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     305            2 :         goto receive_done;
     306              :     }
     307           63 :     if (!libspdm_onehot0(spdm_response->measurement_specification_sel)) {
     308            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     309            1 :         goto receive_done;
     310              :     }
     311           62 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     312           22 :         if (!libspdm_onehot0(spdm_response->other_params_selection &
     313              :                              SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK)) {
     314            2 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     315            2 :             goto receive_done;
     316              :         }
     317              :     }
     318           60 :     if (!libspdm_onehot0(spdm_response->measurement_hash_algo)) {
     319            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     320            1 :         goto receive_done;
     321              :     }
     322           59 :     if (!libspdm_onehot0(spdm_response->base_asym_sel)) {
     323            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     324            1 :         goto receive_done;
     325              :     }
     326           58 :     if (!libspdm_onehot0(spdm_response->base_hash_sel)) {
     327            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     328            1 :         goto receive_done;
     329              :     }
     330           57 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     331            0 :         if (!libspdm_onehot0(spdm_response->pqc_asym_sel)) {
     332            0 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     333            0 :             goto receive_done;
     334              :         }
     335              :     }
     336           57 :     if (spdm_response->ext_asym_sel_count > 0) {
     337            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     338            1 :         goto receive_done;
     339              :     }
     340           56 :     if (spdm_response->ext_hash_sel_count > 0) {
     341            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     342            1 :         goto receive_done;
     343              :     }
     344           55 :     if (spdm_response_size <
     345              :         sizeof(spdm_algorithms_response_t) +
     346           55 :         sizeof(uint32_t) * spdm_response->ext_asym_sel_count +
     347           55 :         sizeof(uint32_t) * spdm_response->ext_hash_sel_count +
     348           55 :         sizeof(spdm_negotiate_algorithms_common_struct_table_t) * spdm_response->header.param1) {
     349            0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     350            0 :         goto receive_done;
     351              :     }
     352           55 :     struct_table =
     353           55 :         (void *)((size_t)spdm_response +
     354           55 :                  sizeof(spdm_algorithms_response_t) +
     355           55 :                  sizeof(uint32_t) * spdm_response->ext_asym_sel_count +
     356           55 :                  sizeof(uint32_t) * spdm_response->ext_hash_sel_count);
     357           55 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     358           37 :         alg_type_pre = struct_table->alg_type;
     359              :         /* header.param1 is implicitly checked through spdm_response_size. */
     360          119 :         for (index = 0; index < spdm_response->header.param1; index++) {
     361           94 :             if ((size_t)spdm_response + spdm_response_size < (size_t)struct_table) {
     362            0 :                 status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     363            0 :                 goto receive_done;
     364              :             }
     365           94 :             if ((size_t)spdm_response + spdm_response_size - (size_t)struct_table <
     366              :                 sizeof(spdm_negotiate_algorithms_common_struct_table_t)) {
     367            0 :                 status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     368            0 :                 goto receive_done;
     369              :             }
     370           94 :             if ((struct_table->alg_type < SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE) ||
     371           92 :                 (struct_table->alg_type >
     372              :                  SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG)) {
     373            2 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     374            2 :                 goto receive_done;
     375              :             }
     376           92 :             if ((spdm_response->header.spdm_version < SPDM_MESSAGE_VERSION_14) &&
     377           92 :                 (struct_table->alg_type >
     378              :                  SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE)) {
     379            1 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     380            1 :                 goto receive_done;
     381              :             }
     382              :             /* AlgType shall monotonically increase for subsequent entries. */
     383           91 :             if ((index != 0) && (struct_table->alg_type <= alg_type_pre)) {
     384            2 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     385            2 :                 goto receive_done;
     386              :             }
     387           89 :             alg_type_pre = struct_table->alg_type;
     388           89 :             fixed_alg_size = (struct_table->alg_count >> 4) & 0xF;
     389           89 :             ext_alg_count = struct_table->alg_count & 0xF;
     390           89 :             if (fixed_alg_size != 2) {
     391            1 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     392            1 :                 goto receive_done;
     393              :             }
     394           88 :             if (ext_alg_count > 0) {
     395            2 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     396            2 :                 goto receive_done;
     397              :             }
     398           86 :             if (!libspdm_onehot0(struct_table->alg_supported)) {
     399            4 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     400            4 :                 goto receive_done;
     401              :             }
     402           82 :             if ((size_t)spdm_response + spdm_response_size -
     403           82 :                 (size_t)struct_table - sizeof(spdm_negotiate_algorithms_common_struct_table_t) <
     404           82 :                 sizeof(uint32_t) * ext_alg_count) {
     405            0 :                 status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     406            0 :                 goto receive_done;
     407              :             }
     408           82 :             struct_table =
     409           82 :                 (void *)((size_t)struct_table +
     410           82 :                          sizeof(spdm_negotiate_algorithms_common_struct_table_t) +
     411           82 :                          sizeof(uint32_t) * ext_alg_count);
     412              :         }
     413              :     }
     414              : 
     415           43 :     spdm_response_size = (size_t)struct_table - (size_t)spdm_response;
     416           43 :     if (spdm_response_size != spdm_response->length) {
     417            3 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     418            3 :         goto receive_done;
     419              :     }
     420              : 
     421              :     /* -=[Process Response Phase]=- */
     422           40 :     status = libspdm_append_message_a(spdm_context, spdm_request, spdm_request_size);
     423           40 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     424            0 :         goto receive_done;
     425              :     }
     426              : 
     427           40 :     status = libspdm_append_message_a(spdm_context, spdm_response, spdm_response_size);
     428           40 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     429            0 :         goto receive_done;
     430              :     }
     431              : 
     432           40 :     spdm_context->connection_info.algorithm.measurement_spec =
     433           40 :         spdm_response->measurement_specification_sel;
     434           40 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     435           18 :         spdm_context->connection_info.algorithm.other_params_support =
     436           18 :             spdm_response->other_params_selection & SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK;
     437           18 :         if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     438           14 :             spdm_context->connection_info.algorithm.other_params_support =
     439           14 :                 spdm_response->other_params_selection;
     440           14 :             spdm_context->connection_info.algorithm.mel_spec =
     441           14 :                 spdm_response->mel_specification_sel;
     442              :         }
     443              :     }
     444           40 :     spdm_context->connection_info.algorithm.measurement_hash_algo =
     445           40 :         spdm_response->measurement_hash_algo;
     446           40 :     spdm_context->connection_info.algorithm.base_asym_algo = spdm_response->base_asym_sel;
     447           40 :     spdm_context->connection_info.algorithm.base_hash_algo = spdm_response->base_hash_sel;
     448           40 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     449            0 :         spdm_context->connection_info.algorithm.pqc_asym_algo = spdm_response->pqc_asym_sel;
     450              :     }
     451              : 
     452           40 :     if (libspdm_is_capabilities_flag_supported(
     453              :             spdm_context, true, 0,
     454           36 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) &&
     455           36 :         (spdm_request->measurement_specification != 0)) {
     456           34 :         if (spdm_context->connection_info.algorithm.measurement_spec !=
     457              :             SPDM_MEASUREMENT_SPECIFICATION_DMTF) {
     458            2 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     459            2 :             goto receive_done;
     460              :         }
     461           32 :         algo_size = libspdm_get_measurement_hash_size(
     462              :             spdm_context->connection_info.algorithm.measurement_hash_algo);
     463           32 :         if (algo_size == 0) {
     464            1 :             status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     465            1 :             goto receive_done;
     466              :         }
     467              :     } else {
     468            6 :         if (spdm_context->connection_info.algorithm.measurement_spec != 0) {
     469            3 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     470            3 :             goto receive_done;
     471              :         }
     472              :     }
     473              : 
     474           34 :     if (libspdm_is_capabilities_flag_supported(
     475              :             spdm_context, true, 0,
     476           32 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) ||
     477           32 :         libspdm_is_capabilities_flag_supported(
     478              :             spdm_context, true, 0,
     479           24 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) ||
     480           24 :         libspdm_is_capabilities_flag_supported(
     481              :             spdm_context, true, 0,
     482            2 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) ||
     483            2 :         libspdm_is_capabilities_flag_supported(
     484              :             spdm_context, true,
     485              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     486            2 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) ||
     487            2 :         libspdm_is_capabilities_flag_supported(
     488              :             spdm_context, true,
     489              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
     490              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
     491           32 :         algo_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     492           32 :         if (algo_size == 0) {
     493            1 :             status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     494            1 :             goto receive_done;
     495              :         }
     496           31 :         if ((spdm_context->connection_info.algorithm.base_hash_algo &
     497           31 :              spdm_context->local_context.algorithm.base_hash_algo) == 0) {
     498            1 :             status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     499            1 :             goto receive_done;
     500              :         }
     501              :     }
     502              : 
     503           32 :     if (libspdm_is_capabilities_flag_supported(
     504              :             spdm_context, true, 0,
     505           30 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) ||
     506           30 :         libspdm_is_capabilities_flag_supported(
     507              :             spdm_context, true, 0,
     508           24 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) ||
     509           24 :         libspdm_is_capabilities_flag_supported(
     510              :             spdm_context, true, 0,
     511            2 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) ||
     512            2 :         libspdm_is_capabilities_flag_supported(
     513              :             spdm_context, true,
     514              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     515              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
     516           30 :         algo_size = libspdm_get_asym_signature_size(
     517              :             spdm_context->connection_info.algorithm.base_asym_algo);
     518           30 :         if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     519            0 :             pqc_algo_size = libspdm_get_pqc_asym_signature_size(
     520              :                 spdm_context->connection_info.algorithm.pqc_asym_algo);
     521              :         } else {
     522           30 :             pqc_algo_size = 0;
     523              :         }
     524           30 :         if (((algo_size == 0) && (pqc_algo_size == 0)) ||
     525           29 :             ((algo_size != 0) && (pqc_algo_size != 0))) {
     526            1 :             status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     527            1 :             goto receive_done;
     528              :         }
     529           29 :         if ((algo_size != 0) &&
     530           29 :             ((spdm_context->connection_info.algorithm.base_asym_algo &
     531           29 :               spdm_context->local_context.algorithm.base_asym_algo) == 0)) {
     532            1 :             status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     533            1 :             goto receive_done;
     534              :         }
     535           28 :         if ((pqc_algo_size != 0) &&
     536            0 :             ((spdm_context->connection_info.algorithm.pqc_asym_algo &
     537            0 :               spdm_context->local_context.algorithm.pqc_asym_algo) == 0)) {
     538            0 :             status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     539            0 :             goto receive_done;
     540              :         }
     541              :     }
     542              : 
     543           30 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     544           24 :         struct_table =
     545           24 :             (void *)((size_t)spdm_response +
     546           24 :                      sizeof(spdm_algorithms_response_t) +
     547           24 :                      sizeof(uint32_t) * spdm_response->ext_asym_sel_count +
     548           24 :                      sizeof(uint32_t) * spdm_response->ext_hash_sel_count);
     549           88 :         for (index = 0; index < spdm_response->header.param1; index++) {
     550           64 :             switch (struct_table->alg_type) {
     551           16 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE:
     552           16 :                 spdm_context->connection_info.algorithm.dhe_named_group =
     553           16 :                     struct_table->alg_supported;
     554           16 :                 break;
     555           16 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD:
     556           16 :                 spdm_context->connection_info.algorithm.aead_cipher_suite =
     557           16 :                     struct_table->alg_supported;
     558           16 :                 break;
     559           16 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG:
     560           16 :                 spdm_context->connection_info.algorithm.req_base_asym_alg =
     561           16 :                     struct_table->alg_supported;
     562           16 :                 break;
     563           16 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE:
     564           16 :                 spdm_context->connection_info.algorithm.key_schedule =
     565           16 :                     struct_table->alg_supported;
     566           16 :                 break;
     567            0 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG:
     568            0 :                 spdm_context->connection_info.algorithm.req_pqc_asym_alg =
     569            0 :                     struct_table->alg_supported;
     570            0 :                 break;
     571            0 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG:
     572            0 :                 spdm_context->connection_info.algorithm.kem_alg =
     573            0 :                     struct_table->alg_supported;
     574            0 :                 break;
     575              :             }
     576           64 :             ext_alg_count = struct_table->alg_count & 0xF;
     577           64 :             struct_table =
     578           64 :                 (void *)((size_t)struct_table +
     579           64 :                          sizeof(spdm_negotiate_algorithms_common_struct_table_t) +
     580           64 :                          sizeof(uint32_t) * ext_alg_count);
     581              :         }
     582              : 
     583           24 :         if (libspdm_is_capabilities_flag_supported(
     584              :                 spdm_context, true,
     585              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     586              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
     587           16 :             algo_size = libspdm_get_dhe_pub_key_size(
     588           16 :                 spdm_context->connection_info.algorithm.dhe_named_group);
     589           16 :             if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     590            0 :                 pqc_algo_size = libspdm_get_kem_encap_key_size(
     591              :                     spdm_context->connection_info.algorithm.kem_alg);
     592              :             } else {
     593           16 :                 pqc_algo_size = 0;
     594              :             }
     595           16 :             if (((algo_size == 0) && (pqc_algo_size == 0)) ||
     596           16 :                 ((algo_size != 0) && (pqc_algo_size != 0))) {
     597            0 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     598            0 :                 goto receive_done;
     599              :             }
     600           16 :             if ((algo_size != 0) &&
     601           16 :                 ((spdm_context->connection_info.algorithm.dhe_named_group &
     602           16 :                   spdm_context->local_context.algorithm.dhe_named_group) == 0)) {
     603            1 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     604            1 :                 goto receive_done;
     605              :             }
     606           15 :             if ((pqc_algo_size != 0) &&
     607            0 :                 ((spdm_context->connection_info.algorithm.kem_alg &
     608            0 :                   spdm_context->local_context.algorithm.kem_alg) == 0)) {
     609            0 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     610            0 :                 goto receive_done;
     611              :             }
     612              :         }
     613           23 :         if (libspdm_is_capabilities_flag_supported(
     614              :                 spdm_context, true,
     615              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP,
     616            8 :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) ||
     617            8 :             libspdm_is_capabilities_flag_supported(
     618              :                 spdm_context, true,
     619              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
     620              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
     621           15 :             algo_size = libspdm_get_aead_key_size(
     622           15 :                 spdm_context->connection_info.algorithm.aead_cipher_suite);
     623           15 :             if (algo_size == 0) {
     624            1 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     625            1 :                 goto receive_done;
     626              :             }
     627           14 :             if ((spdm_context->connection_info.algorithm.aead_cipher_suite &
     628           14 :                  spdm_context->local_context.algorithm.aead_cipher_suite) == 0) {
     629            0 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     630            0 :                 goto receive_done;
     631              :             }
     632              :         }
     633           22 :         if (libspdm_is_capabilities_flag_supported(
     634              :                 spdm_context, true,
     635              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP,
     636              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP)) {
     637           14 :             algo_size = libspdm_get_req_asym_signature_size(
     638           14 :                 spdm_context->connection_info.algorithm.req_base_asym_alg);
     639           14 :             if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     640            0 :                 pqc_algo_size = libspdm_get_req_pqc_asym_signature_size(
     641              :                     spdm_context->connection_info.algorithm.req_pqc_asym_alg);
     642              :             } else {
     643           14 :                 pqc_algo_size = 0;
     644              :             }
     645           14 :             if (((algo_size == 0) && (pqc_algo_size == 0)) ||
     646           14 :                 ((algo_size != 0) && (pqc_algo_size != 0))) {
     647            0 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     648            0 :                 goto receive_done;
     649              :             }
     650           14 :             if ((algo_size != 0) &&
     651           14 :                 ((spdm_context->connection_info.algorithm.req_base_asym_alg &
     652           14 :                   spdm_context->local_context.algorithm.req_base_asym_alg) == 0)) {
     653            1 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     654            1 :                 goto receive_done;
     655              :             }
     656           13 :             if ((pqc_algo_size != 0) &&
     657            0 :                 ((spdm_context->connection_info.algorithm.req_pqc_asym_alg &
     658            0 :                   spdm_context->local_context.algorithm.req_pqc_asym_alg) == 0)) {
     659            0 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     660            0 :                 goto receive_done;
     661              :             }
     662              :         }
     663           21 :         if (libspdm_is_capabilities_flag_supported(
     664              :                 spdm_context, true,
     665              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     666            8 :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) ||
     667            8 :             libspdm_is_capabilities_flag_supported(
     668              :                 spdm_context, true,
     669              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
     670              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
     671           13 :             if (spdm_context->connection_info.algorithm.key_schedule !=
     672              :                 SPDM_ALGORITHMS_KEY_SCHEDULE_SPDM) {
     673            1 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     674            1 :                 goto receive_done;
     675              :             }
     676           12 :             if ((spdm_context->connection_info.algorithm.key_schedule &
     677           12 :                  spdm_context->local_context.algorithm.key_schedule) == 0) {
     678            0 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     679            0 :                 goto receive_done;
     680              :             }
     681           12 :             if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     682            8 :                 if (libspdm_is_capabilities_flag_supported(
     683              :                         spdm_context, true, 0,
     684            4 :                         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP) &&
     685            4 :                     (spdm_request->mel_specification != 0)) {
     686            2 :                     if (spdm_context->connection_info.algorithm.mel_spec !=
     687              :                         SPDM_MEL_SPECIFICATION_DMTF) {
     688            1 :                         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     689            1 :                         goto receive_done;
     690              :                     }
     691              :                 } else {
     692            6 :                     if (spdm_context->connection_info.algorithm.mel_spec != 0) {
     693            3 :                         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     694            3 :                         goto receive_done;
     695              :                     }
     696              :                 }
     697              :             }
     698              :         }
     699              : 
     700           16 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     701           10 :             if ((spdm_context->connection_info.algorithm.other_params_support &
     702              :                  SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
     703            7 :                 if ((spdm_context->local_context.capability.flags &
     704              :                      SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) ==
     705              :                     SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY) {
     706            1 :                     status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     707            1 :                     goto receive_done;
     708              :                 }
     709            6 :                 spdm_context->connection_info.multi_key_conn_req = false;
     710              :             } else {
     711            3 :                 if ((spdm_context->local_context.capability.flags &
     712              :                      SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) == 0) {
     713            1 :                     status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     714            1 :                     goto receive_done;
     715              :                 }
     716            2 :                 spdm_context->connection_info.multi_key_conn_req = true;
     717              :             }
     718              :         }
     719              :     } else {
     720            6 :         spdm_context->connection_info.algorithm.dhe_named_group = 0;
     721            6 :         spdm_context->connection_info.algorithm.aead_cipher_suite = 0;
     722            6 :         spdm_context->connection_info.algorithm.req_base_asym_alg = 0;
     723            6 :         spdm_context->connection_info.algorithm.key_schedule = 0;
     724            6 :         spdm_context->connection_info.algorithm.other_params_support = 0;
     725            6 :         spdm_context->connection_info.algorithm.req_pqc_asym_alg = 0;
     726            6 :         spdm_context->connection_info.algorithm.kem_alg = 0;
     727              :     }
     728              : 
     729           20 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "base_hash - 0x%08x\n",
     730              :                    spdm_context->connection_info.algorithm.base_hash_algo));
     731           20 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "base_asym - 0x%08x\n",
     732              :                    spdm_context->connection_info.algorithm.base_asym_algo));
     733           20 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "dhe - 0x%04x\n",
     734              :                    spdm_context->connection_info.algorithm.dhe_named_group));
     735           20 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aead - 0x%04x\n",
     736              :                    spdm_context->connection_info.algorithm.aead_cipher_suite));
     737           20 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "req_asym - 0x%04x\n",
     738              :                    spdm_context->connection_info.algorithm.req_base_asym_alg));
     739           20 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "pqc_asym - 0x%08x\n",
     740              :                    spdm_context->connection_info.algorithm.pqc_asym_algo));
     741           20 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "req_pqc_asym - 0x%04x\n",
     742              :                    spdm_context->connection_info.algorithm.req_pqc_asym_alg));
     743           20 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "kem - 0x%04x\n",
     744              :                    spdm_context->connection_info.algorithm.kem_alg));
     745              : 
     746              :     /* -=[Update State Phase]=- */
     747           20 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     748              : 
     749              :     /* -=[Log Message Phase]=- */
     750              :     #if LIBSPDM_ENABLE_MSG_LOG
     751           20 :     libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
     752              :     #endif /* LIBSPDM_ENABLE_MSG_LOG */
     753              : 
     754           20 :     status = LIBSPDM_STATUS_SUCCESS;
     755              : 
     756           74 : receive_done:
     757           74 :     libspdm_release_receiver_buffer (spdm_context);
     758           74 :     return status;
     759              : }
     760              : 
     761           87 : libspdm_return_t libspdm_negotiate_algorithms(libspdm_context_t *spdm_context)
     762              : {
     763              :     size_t retry;
     764              :     uint64_t retry_delay_time;
     765              :     libspdm_return_t status;
     766              : 
     767           87 :     spdm_context->crypto_request = false;
     768           87 :     retry = spdm_context->retry_times;
     769           87 :     retry_delay_time = spdm_context->retry_delay_time;
     770              :     do {
     771           88 :         status = libspdm_try_negotiate_algorithms(spdm_context);
     772           88 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     773           86 :             return status;
     774              :         }
     775              : 
     776            2 :         libspdm_sleep(retry_delay_time);
     777            2 :     } while (retry-- != 0);
     778              : 
     779            1 :     return status;
     780              : }
        

Generated by: LCOV version 2.0-1