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: 87.4 % 459 401
Test Date: 2026-07-05 09:06:49 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2026 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           89 : 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           89 :     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           89 :     uint8_t req_param1 = 0;
      91              : 
      92              :     /* -=[Verify State Phase]=- */
      93           89 :     if (spdm_context->connection_info.connection_state !=
      94              :         LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES) {
      95            1 :         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
      96              :     }
      97              : 
      98           88 :     libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_NEGOTIATE_ALGORITHMS);
      99              : 
     100              :     /* -=[Construct Request Phase]=- */
     101           88 :     transport_header_size = spdm_context->local_context.capability.transport_header_size;
     102           88 :     status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
     103           88 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     104            1 :         return status;
     105              :     }
     106           87 :     LIBSPDM_ASSERT (message_size >= transport_header_size +
     107              :                     spdm_context->local_context.capability.transport_tail_size);
     108           87 :     spdm_request = (void *)(message + transport_header_size);
     109           87 :     spdm_request_size = message_size - transport_header_size -
     110           87 :                         spdm_context->local_context.capability.transport_tail_size;
     111              : 
     112           87 :     LIBSPDM_ASSERT(spdm_request_size >= sizeof(spdm_negotiate_algorithms_request_t));
     113           87 :     libspdm_zero_mem(spdm_request, spdm_request_size);
     114           87 :     spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
     115           87 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     116              :         /* Number of Algorithms Structure Tables based on supported algorithms */
     117           54 :         if (spdm_context->local_context.algorithm.dhe_named_group != 0) {
     118           53 :             req_param1++;
     119              :         }
     120           54 :         if (spdm_context->local_context.algorithm.aead_cipher_suite != 0) {
     121           53 :             req_param1++;
     122              :         }
     123           54 :         if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
     124           53 :             req_param1++;
     125              :         }
     126           54 :         if (spdm_context->local_context.algorithm.key_schedule != 0) {
     127           53 :             req_param1++;
     128              :         }
     129           54 :         LIBSPDM_ASSERT(req_param1 <=
     130              :                        SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG);
     131           54 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     132            2 :             if (spdm_context->local_context.algorithm.req_pqc_asym_alg != 0) {
     133            0 :                 req_param1++;
     134              :             }
     135            2 :             if (spdm_context->local_context.algorithm.kem_alg != 0) {
     136            0 :                 req_param1++;
     137              :             }
     138            2 :             LIBSPDM_ASSERT(req_param1 <=
     139              :                            SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG_14);
     140              :         }
     141           54 :         spdm_request->header.param1 = req_param1;
     142           54 :         spdm_request->length =
     143           54 :             offsetof(libspdm_negotiate_algorithms_request_mine_t, struct_table) +
     144              :             req_param1 * sizeof(spdm_negotiate_algorithms_common_struct_table_t);
     145              :     } else {
     146           33 :         spdm_request->length = offsetof(libspdm_negotiate_algorithms_request_mine_t, struct_table);
     147           33 :         spdm_request->header.param1 = 0;
     148              :     }
     149              : 
     150           87 :     LIBSPDM_ASSERT(spdm_request_size >= spdm_request->length);
     151           87 :     spdm_request->header.request_response_code = SPDM_NEGOTIATE_ALGORITHMS;
     152           87 :     spdm_request->header.param2 = 0;
     153           87 :     spdm_request->measurement_specification =
     154           87 :         spdm_context->local_context.algorithm.measurement_spec;
     155           87 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     156           34 :         spdm_request->other_params_support =
     157           34 :             spdm_context->local_context.algorithm.other_params_support &
     158              :             SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK;
     159           34 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     160           16 :             spdm_request->other_params_support =
     161           16 :                 spdm_context->local_context.algorithm.other_params_support;
     162           16 :             spdm_request->mel_specification =
     163           16 :                 spdm_context->local_context.algorithm.mel_spec;
     164              :         }
     165              :     }
     166           87 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     167           16 :         switch (spdm_context->connection_info.capability.flags &
     168              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) {
     169           12 :         case 0:
     170           12 :             spdm_context->connection_info.multi_key_conn_rsp = false;
     171           12 :             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           16 :         if (spdm_context->connection_info.multi_key_conn_rsp) {
     187            3 :             spdm_request->other_params_support |= SPDM_ALGORITHMS_MULTI_KEY_CONN;
     188              :         } else {
     189           13 :             spdm_request->other_params_support &= ~SPDM_ALGORITHMS_MULTI_KEY_CONN;
     190              :         }
     191              :     }
     192           87 :     spdm_request->base_asym_algo = spdm_context->local_context.algorithm.base_asym_algo;
     193           87 :     spdm_request->base_hash_algo = spdm_context->local_context.algorithm.base_hash_algo;
     194           87 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     195            2 :         spdm_request->pqc_asym_algo = spdm_context->local_context.algorithm.pqc_asym_algo;
     196              :     }
     197           87 :     spdm_request->ext_asym_count = 0;
     198           87 :     spdm_request->ext_hash_count = 0;
     199           87 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     200              :         /* ReqAlgStruct order based on by AlgType */
     201           54 :         if (spdm_context->local_context.algorithm.dhe_named_group != 0) {
     202           53 :             spdm_request->struct_table[index].alg_type =
     203              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
     204           53 :             spdm_request->struct_table[index].alg_count = 0x20;
     205           53 :             spdm_request->struct_table[index].alg_supported =
     206           53 :                 spdm_context->local_context.algorithm.dhe_named_group;
     207           53 :             index++;
     208              :         }
     209           54 :         if (spdm_context->local_context.algorithm.aead_cipher_suite != 0) {
     210           53 :             spdm_request->struct_table[index].alg_type =
     211              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
     212           53 :             spdm_request->struct_table[index].alg_count = 0x20;
     213           53 :             spdm_request->struct_table[index].alg_supported =
     214           53 :                 spdm_context->local_context.algorithm.aead_cipher_suite;
     215           53 :             index++;
     216              :         }
     217           54 :         if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
     218           53 :             spdm_request->struct_table[index].alg_type =
     219              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
     220           53 :             spdm_request->struct_table[index].alg_count = 0x20;
     221           53 :             spdm_request->struct_table[index].alg_supported =
     222           53 :                 spdm_context->local_context.algorithm.req_base_asym_alg;
     223           53 :             index++;
     224              :         }
     225           54 :         if (spdm_context->local_context.algorithm.key_schedule != 0) {
     226           53 :             spdm_request->struct_table[index].alg_type =
     227              :                 SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
     228           53 :             spdm_request->struct_table[index].alg_count = 0x20;
     229           53 :             spdm_request->struct_table[index].alg_supported =
     230           53 :                 spdm_context->local_context.algorithm.key_schedule;
     231           53 :             index++;
     232              :         }
     233           54 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     234            2 :             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            2 :             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           54 :         LIBSPDM_ASSERT(index == spdm_request->header.param1);
     258              :     }
     259           87 :     spdm_request_size = spdm_request->length;
     260              : 
     261              :     /* -=[Send Request Phase]=- */
     262           87 :     status = libspdm_send_spdm_request(spdm_context, NULL, spdm_request_size, spdm_request);
     263           87 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     264           11 :         libspdm_release_sender_buffer (spdm_context);
     265           11 :         return status;
     266              :     }
     267           76 :     libspdm_release_sender_buffer (spdm_context);
     268           76 :     spdm_request = (void *)spdm_context->last_spdm_request;
     269              : 
     270              :     /* -=[Receive Response Phase]=- */
     271           76 :     status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
     272           76 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     273            1 :         return status;
     274              :     }
     275           75 :     LIBSPDM_ASSERT (message_size >= transport_header_size);
     276           75 :     spdm_response = (void *)(message);
     277           75 :     spdm_response_size = message_size;
     278              : 
     279           75 :     status = libspdm_receive_spdm_response(spdm_context, NULL, &spdm_response_size,
     280              :                                            (void **)&spdm_response);
     281           75 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     282            1 :         goto receive_done;
     283              :     }
     284              : 
     285              :     /* -=[Validate Response Phase]=- */
     286           74 :     if (spdm_response_size < sizeof(spdm_message_header_t)) {
     287            0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     288            0 :         goto receive_done;
     289              :     }
     290           74 :     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           68 :     } 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           67 :     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           66 :     if (spdm_response_size < sizeof(spdm_algorithms_response_t)) {
     304            2 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     305            2 :         goto receive_done;
     306              :     }
     307           64 :     if (!libspdm_onehot0(spdm_response->measurement_specification_sel)) {
     308            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     309            1 :         goto receive_done;
     310              :     }
     311           63 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     312           23 :         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           61 :     if (!libspdm_onehot0(spdm_response->measurement_hash_algo)) {
     319            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     320            1 :         goto receive_done;
     321              :     }
     322           60 :     if (!libspdm_onehot0(spdm_response->base_asym_sel)) {
     323            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     324            1 :         goto receive_done;
     325              :     }
     326           59 :     if (!libspdm_onehot0(spdm_response->base_hash_sel)) {
     327            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     328            1 :         goto receive_done;
     329              :     }
     330           58 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     331            2 :         if (!libspdm_onehot0(spdm_response->pqc_asym_sel)) {
     332            0 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     333            0 :             goto receive_done;
     334              :         }
     335              :     }
     336           58 :     if (spdm_response->ext_asym_sel_count > 0) {
     337            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     338            1 :         goto receive_done;
     339              :     }
     340           57 :     if (spdm_response->ext_hash_sel_count > 0) {
     341            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     342            1 :         goto receive_done;
     343              :     }
     344           56 :     if (spdm_response_size <
     345              :         sizeof(spdm_algorithms_response_t) +
     346           56 :         sizeof(uint32_t) * spdm_response->ext_asym_sel_count +
     347           56 :         sizeof(uint32_t) * spdm_response->ext_hash_sel_count +
     348           56 :         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           56 :     struct_table =
     353           56 :         (void *)((size_t)spdm_response +
     354           56 :                  sizeof(spdm_algorithms_response_t) +
     355           56 :                  sizeof(uint32_t) * spdm_response->ext_asym_sel_count +
     356           56 :                  sizeof(uint32_t) * spdm_response->ext_hash_sel_count);
     357           56 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     358           40 :         alg_type_pre = struct_table->alg_type;
     359              :         /* header.param1 is implicitly checked through spdm_response_size. */
     360          130 :         for (index = 0; index < spdm_response->header.param1; index++) {
     361          101 :             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          101 :             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          101 :             if ((struct_table->alg_type < SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE) ||
     371           99 :                 (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           99 :             if ((spdm_response->header.spdm_version < SPDM_MESSAGE_VERSION_14) &&
     377           99 :                 (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           98 :             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           96 :             alg_type_pre = struct_table->alg_type;
     388           96 :             fixed_alg_size = (struct_table->alg_count >> 4) & 0xF;
     389           96 :             ext_alg_count = struct_table->alg_count & 0xF;
     390           96 :             if (fixed_alg_size != 2) {
     391            1 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     392            1 :                 goto receive_done;
     393              :             }
     394           95 :             if (ext_alg_count > 0) {
     395            1 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     396            1 :                 goto receive_done;
     397              :             }
     398           94 :             if (!libspdm_onehot0(struct_table->alg_supported)) {
     399            4 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     400            4 :                 goto receive_done;
     401              :             }
     402           90 :             if ((size_t)spdm_response + spdm_response_size -
     403           90 :                 (size_t)struct_table - sizeof(spdm_negotiate_algorithms_common_struct_table_t) <
     404           90 :                 sizeof(uint32_t) * ext_alg_count) {
     405            0 :                 status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     406            0 :                 goto receive_done;
     407              :             }
     408           90 :             struct_table =
     409           90 :                 (void *)((size_t)struct_table +
     410           90 :                          sizeof(spdm_negotiate_algorithms_common_struct_table_t) +
     411           90 :                          sizeof(uint32_t) * ext_alg_count);
     412              :         }
     413              :     }
     414              : 
     415           45 :     spdm_response_size = (size_t)struct_table - (size_t)spdm_response;
     416           45 :     if (spdm_response_size != spdm_response->length) {
     417            1 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     418            1 :         goto receive_done;
     419              :     }
     420              : 
     421              :     /* -=[Process Response Phase]=- */
     422           44 :     status = libspdm_append_message_a(spdm_context, spdm_request, spdm_request_size);
     423           44 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     424            0 :         goto receive_done;
     425              :     }
     426              : 
     427           44 :     status = libspdm_append_message_a(spdm_context, spdm_response, spdm_response_size);
     428           44 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     429            0 :         goto receive_done;
     430              :     }
     431              : 
     432           44 :     spdm_context->connection_info.algorithm.measurement_spec =
     433           44 :         spdm_response->measurement_specification_sel;
     434           44 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     435           20 :         spdm_context->connection_info.algorithm.other_params_support =
     436           20 :             spdm_response->other_params_selection & SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK;
     437           20 :         if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     438           16 :             spdm_context->connection_info.algorithm.other_params_support =
     439           16 :                 spdm_response->other_params_selection;
     440           16 :             spdm_context->connection_info.algorithm.mel_spec =
     441           16 :                 spdm_response->mel_specification_sel;
     442              :         }
     443              :     }
     444           44 :     spdm_context->connection_info.algorithm.measurement_hash_algo =
     445           44 :         spdm_response->measurement_hash_algo;
     446           44 :     spdm_context->connection_info.algorithm.base_asym_algo = spdm_response->base_asym_sel;
     447           44 :     spdm_context->connection_info.algorithm.base_hash_algo = spdm_response->base_hash_sel;
     448           44 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     449            2 :         spdm_context->connection_info.algorithm.pqc_asym_algo = spdm_response->pqc_asym_sel;
     450              :     }
     451              : 
     452           44 :     if (libspdm_is_capabilities_flag_supported(
     453              :             spdm_context, true, 0,
     454           40 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) &&
     455           40 :         (spdm_request->measurement_specification != 0)) {
     456           38 :         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           36 :         algo_size = libspdm_get_measurement_hash_size(
     462              :             spdm_context->connection_info.algorithm.measurement_hash_algo);
     463           36 :         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           38 :     if (libspdm_is_capabilities_flag_supported(
     475              :             spdm_context, true, 0,
     476           34 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) ||
     477           34 :         libspdm_is_capabilities_flag_supported(
     478              :             spdm_context, true, 0,
     479           25 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) ||
     480           25 :         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           36 :         algo_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     492           36 :         if (algo_size == 0) {
     493            1 :             status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     494            1 :             goto receive_done;
     495              :         }
     496           35 :         if ((spdm_context->connection_info.algorithm.base_hash_algo &
     497           35 :              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           36 :     if (libspdm_is_capabilities_flag_supported(
     504              :             spdm_context, true, 0,
     505           32 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) ||
     506           32 :         libspdm_is_capabilities_flag_supported(
     507              :             spdm_context, true, 0,
     508           25 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) ||
     509           25 :         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           34 :         algo_size = libspdm_get_asym_signature_size(
     517              :             spdm_context->connection_info.algorithm.base_asym_algo);
     518           34 :         if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     519            2 :             pqc_algo_size = libspdm_get_pqc_asym_signature_size(
     520              :                 spdm_context->connection_info.algorithm.pqc_asym_algo);
     521              :         } else {
     522           32 :             pqc_algo_size = 0;
     523              :         }
     524           34 :         if (((algo_size == 0) && (pqc_algo_size == 0)) ||
     525           33 :             ((algo_size != 0) && (pqc_algo_size != 0))) {
     526            1 :             status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     527            1 :             goto receive_done;
     528              :         }
     529           33 :         if ((algo_size != 0) &&
     530           33 :             ((spdm_context->connection_info.algorithm.base_asym_algo &
     531           33 :               spdm_context->local_context.algorithm.base_asym_algo) == 0)) {
     532            1 :             status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     533            1 :             goto receive_done;
     534              :         }
     535           32 :         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           34 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     544           28 :         struct_table =
     545           28 :             (void *)((size_t)spdm_response +
     546           28 :                      sizeof(spdm_algorithms_response_t) +
     547           28 :                      sizeof(uint32_t) * spdm_response->ext_asym_sel_count +
     548           28 :                      sizeof(uint32_t) * spdm_response->ext_hash_sel_count);
     549          100 :         for (index = 0; index < spdm_response->header.param1; index++) {
     550           72 :             switch (struct_table->alg_type) {
     551           18 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE:
     552           18 :                 spdm_context->connection_info.algorithm.dhe_named_group =
     553           18 :                     struct_table->alg_supported;
     554           18 :                 break;
     555           18 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD:
     556           18 :                 spdm_context->connection_info.algorithm.aead_cipher_suite =
     557           18 :                     struct_table->alg_supported;
     558           18 :                 break;
     559           18 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG:
     560           18 :                 spdm_context->connection_info.algorithm.req_base_asym_alg =
     561           18 :                     struct_table->alg_supported;
     562           18 :                 break;
     563           18 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE:
     564           18 :                 spdm_context->connection_info.algorithm.key_schedule =
     565           18 :                     struct_table->alg_supported;
     566           18 :                 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           72 :             ext_alg_count = struct_table->alg_count & 0xF;
     577           72 :             struct_table =
     578           72 :                 (void *)((size_t)struct_table +
     579           72 :                          sizeof(spdm_negotiate_algorithms_common_struct_table_t) +
     580           72 :                          sizeof(uint32_t) * ext_alg_count);
     581              :         }
     582              : 
     583           28 :         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           18 :             algo_size = libspdm_get_dhe_pub_key_size(
     588           18 :                 spdm_context->connection_info.algorithm.dhe_named_group);
     589           18 :             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           18 :                 pqc_algo_size = 0;
     594              :             }
     595           18 :             if (((algo_size == 0) && (pqc_algo_size == 0)) ||
     596           18 :                 ((algo_size != 0) && (pqc_algo_size != 0))) {
     597            0 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     598            0 :                 goto receive_done;
     599              :             }
     600           18 :             if ((algo_size != 0) &&
     601           18 :                 ((spdm_context->connection_info.algorithm.dhe_named_group &
     602           18 :                   spdm_context->local_context.algorithm.dhe_named_group) == 0)) {
     603            1 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     604            1 :                 goto receive_done;
     605              :             }
     606           17 :             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           27 :         if (libspdm_is_capabilities_flag_supported(
     614              :                 spdm_context, true,
     615              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP,
     616           10 :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) ||
     617           10 :             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           17 :             algo_size = libspdm_get_aead_key_size(
     622           17 :                 spdm_context->connection_info.algorithm.aead_cipher_suite);
     623           17 :             if (algo_size == 0) {
     624            1 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     625            1 :                 goto receive_done;
     626              :             }
     627           16 :             if ((spdm_context->connection_info.algorithm.aead_cipher_suite &
     628           16 :                  spdm_context->local_context.algorithm.aead_cipher_suite) == 0) {
     629            0 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     630            0 :                 goto receive_done;
     631              :             }
     632              :         }
     633           26 :         if (libspdm_is_capabilities_flag_supported(
     634              :                 spdm_context, true,
     635              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP,
     636           10 :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP) ||
     637           10 :             libspdm_is_capabilities_flag_supported(
     638              :                 spdm_context, true,
     639              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_SIG, 0)) {
     640           16 :             algo_size = libspdm_get_req_asym_signature_size(
     641           16 :                 spdm_context->connection_info.algorithm.req_base_asym_alg);
     642           16 :             if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     643            0 :                 pqc_algo_size = libspdm_get_req_pqc_asym_signature_size(
     644              :                     spdm_context->connection_info.algorithm.req_pqc_asym_alg);
     645              :             } else {
     646           16 :                 pqc_algo_size = 0;
     647              :             }
     648           16 :             if (((algo_size == 0) && (pqc_algo_size == 0)) ||
     649           15 :                 ((algo_size != 0) && (pqc_algo_size != 0))) {
     650            1 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     651            1 :                 goto receive_done;
     652              :             }
     653           15 :             if ((algo_size != 0) &&
     654           15 :                 ((spdm_context->connection_info.algorithm.req_base_asym_alg &
     655           15 :                   spdm_context->local_context.algorithm.req_base_asym_alg) == 0)) {
     656            1 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     657            1 :                 goto receive_done;
     658              :             }
     659           14 :             if ((pqc_algo_size != 0) &&
     660            0 :                 ((spdm_context->connection_info.algorithm.req_pqc_asym_alg &
     661            0 :                   spdm_context->local_context.algorithm.req_pqc_asym_alg) == 0)) {
     662            0 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     663            0 :                 goto receive_done;
     664              :             }
     665              :         }
     666           24 :         if (libspdm_is_capabilities_flag_supported(
     667              :                 spdm_context, true,
     668              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     669           10 :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) ||
     670           10 :             libspdm_is_capabilities_flag_supported(
     671              :                 spdm_context, true,
     672              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
     673              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
     674           14 :             if (spdm_context->connection_info.algorithm.key_schedule !=
     675              :                 SPDM_ALGORITHMS_KEY_SCHEDULE_SPDM) {
     676            1 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     677            1 :                 goto receive_done;
     678              :             }
     679           13 :             if ((spdm_context->connection_info.algorithm.key_schedule &
     680           13 :                  spdm_context->local_context.algorithm.key_schedule) == 0) {
     681            0 :                 status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     682            0 :                 goto receive_done;
     683              :             }
     684           13 :             if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     685            8 :                 if (libspdm_is_capabilities_flag_supported(
     686              :                         spdm_context, true, 0,
     687            4 :                         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP) &&
     688            4 :                     (spdm_request->mel_specification != 0)) {
     689            2 :                     if (spdm_context->connection_info.algorithm.mel_spec !=
     690              :                         SPDM_MEL_SPECIFICATION_DMTF) {
     691            1 :                         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     692            1 :                         goto receive_done;
     693              :                     }
     694              :                 } else {
     695            6 :                     if (spdm_context->connection_info.algorithm.mel_spec != 0) {
     696            3 :                         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     697            3 :                         goto receive_done;
     698              :                     }
     699              :                 }
     700              :             }
     701              :         }
     702              : 
     703           19 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     704           12 :             if ((spdm_context->connection_info.algorithm.other_params_support &
     705              :                  SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
     706            9 :                 if ((spdm_context->local_context.capability.flags &
     707              :                      SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) ==
     708              :                     SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY) {
     709            1 :                     status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     710            1 :                     goto receive_done;
     711              :                 }
     712            8 :                 spdm_context->connection_info.multi_key_conn_req = false;
     713              :             } else {
     714            3 :                 if ((spdm_context->local_context.capability.flags &
     715              :                      SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) == 0) {
     716            1 :                     status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
     717            1 :                     goto receive_done;
     718              :                 }
     719            2 :                 spdm_context->connection_info.multi_key_conn_req = true;
     720              :             }
     721              :         }
     722              :     } else {
     723            6 :         spdm_context->connection_info.algorithm.dhe_named_group = 0;
     724            6 :         spdm_context->connection_info.algorithm.aead_cipher_suite = 0;
     725            6 :         spdm_context->connection_info.algorithm.req_base_asym_alg = 0;
     726            6 :         spdm_context->connection_info.algorithm.key_schedule = 0;
     727            6 :         spdm_context->connection_info.algorithm.other_params_support = 0;
     728            6 :         spdm_context->connection_info.algorithm.req_pqc_asym_alg = 0;
     729            6 :         spdm_context->connection_info.algorithm.kem_alg = 0;
     730              :     }
     731              : 
     732           23 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "base_hash - 0x%08x\n",
     733              :                    spdm_context->connection_info.algorithm.base_hash_algo));
     734           23 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "base_asym - 0x%08x\n",
     735              :                    spdm_context->connection_info.algorithm.base_asym_algo));
     736           23 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "dhe - 0x%04x\n",
     737              :                    spdm_context->connection_info.algorithm.dhe_named_group));
     738           23 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aead - 0x%04x\n",
     739              :                    spdm_context->connection_info.algorithm.aead_cipher_suite));
     740           23 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "req_asym - 0x%04x\n",
     741              :                    spdm_context->connection_info.algorithm.req_base_asym_alg));
     742           23 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "pqc_asym - 0x%08x\n",
     743              :                    spdm_context->connection_info.algorithm.pqc_asym_algo));
     744           23 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "req_pqc_asym - 0x%04x\n",
     745              :                    spdm_context->connection_info.algorithm.req_pqc_asym_alg));
     746           23 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "kem - 0x%04x\n",
     747              :                    spdm_context->connection_info.algorithm.kem_alg));
     748              : 
     749              :     /* -=[Update State Phase]=- */
     750           23 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     751              : 
     752              :     /* -=[Log Message Phase]=- */
     753              :     #if LIBSPDM_ENABLE_MSG_LOG
     754           23 :     libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
     755              :     #endif /* LIBSPDM_ENABLE_MSG_LOG */
     756              : 
     757           23 :     status = LIBSPDM_STATUS_SUCCESS;
     758              : 
     759           75 : receive_done:
     760           75 :     libspdm_release_receiver_buffer (spdm_context);
     761           75 :     return status;
     762              : }
     763              : 
     764           88 : libspdm_return_t libspdm_negotiate_algorithms(libspdm_context_t *spdm_context)
     765              : {
     766              :     size_t retry;
     767              :     uint64_t retry_delay_time;
     768              :     libspdm_return_t status;
     769              : 
     770           88 :     spdm_context->crypto_request = false;
     771           88 :     retry = spdm_context->retry_times;
     772           88 :     retry_delay_time = spdm_context->retry_delay_time;
     773              :     do {
     774           89 :         status = libspdm_try_negotiate_algorithms(spdm_context);
     775           89 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     776           87 :             return status;
     777              :         }
     778              : 
     779            2 :         libspdm_sleep(retry_delay_time);
     780            2 :     } while (retry-- != 0);
     781              : 
     782            1 :     return status;
     783              : }
        

Generated by: LCOV version 2.0-1