LCOV - code coverage report
Current view: top level - spdm_requester_lib - libspdm_req_negotiate_algorithms.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.1 % 465 405
Test Date: 2026-10-01 20:56:25 Functions: 100.0 % 2 2
Branches: 78.6 % 295 232

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

Generated by: LCOV version 2.0-1