LCOV - code coverage report
Current view: top level - library/spdm_responder_lib - libspdm_rsp_algorithms.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.2 % 324 302
Test Date: 2025-06-29 08:09:00 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2025 DMTF. All rights reserved.
       4              :  *  License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
       5              :  **/
       6              : 
       7              : #include "internal/libspdm_responder_lib.h"
       8              : 
       9              : /* current version libspdm does not support any ext algo.
      10              :  * the responder will ignore the ext algo in request.
      11              :  * the responder will not build ext algo in response.*/
      12              : #pragma pack(1)
      13              : typedef struct {
      14              :     spdm_message_header_t header;
      15              :     uint16_t length;
      16              :     uint8_t measurement_specification_sel;
      17              :     uint8_t other_params_selection;
      18              :     uint32_t measurement_hash_algo;
      19              :     uint32_t base_asym_sel;
      20              :     uint32_t base_hash_sel;
      21              :     uint8_t reserved2[11];
      22              :     uint8_t mel_specification_sel;
      23              :     uint8_t ext_asym_sel_count;
      24              :     uint8_t ext_hash_sel_count;
      25              :     uint16_t reserved3;
      26              :     spdm_negotiate_algorithms_common_struct_table_t struct_table[
      27              :         SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG];
      28              : } libspdm_algorithms_response_mine_t;
      29              : #pragma pack()
      30              : 
      31              : /**
      32              :  * Select the preferred supported algorithm according to the priority_table.
      33              :  *
      34              :  * @param  priority_table        The priority table.
      35              :  * @param  priority_table_count  The count of the priority table entry.
      36              :  * @param  local_algo            Local supported algorithm.
      37              :  * @param  peer_algo             Peer supported algorithm.
      38              :  *
      39              :  * @return   Preferred supported algorithm
      40              :  **/
      41          162 : static uint32_t libspdm_prioritize_algorithm(const uint32_t *priority_table,
      42              :                                              size_t priority_table_count,
      43              :                                              uint32_t local_algo, uint32_t peer_algo)
      44              : {
      45              :     uint32_t common_algo;
      46              :     size_t index;
      47              : 
      48          162 :     common_algo = (local_algo & peer_algo);
      49          763 :     for (index = 0; index < priority_table_count; index++) {
      50          706 :         if ((common_algo & priority_table[index]) != 0) {
      51          105 :             return priority_table[index];
      52              :         }
      53              :     }
      54              : 
      55           57 :     return 0;
      56              : }
      57              : 
      58           41 : libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context,
      59              :                                                  size_t request_size,
      60              :                                                  const void *request,
      61              :                                                  size_t *response_size,
      62              :                                                  void *response)
      63              : {
      64              :     const spdm_negotiate_algorithms_request_t *spdm_request;
      65              :     size_t spdm_request_size;
      66              :     libspdm_algorithms_response_mine_t *spdm_response;
      67              :     spdm_negotiate_algorithms_common_struct_table_t *struct_table;
      68              :     size_t index;
      69              :     libspdm_return_t status;
      70              :     uint32_t algo_size;
      71              :     uint8_t fixed_alg_size;
      72              :     uint8_t ext_alg_count;
      73              :     uint16_t ext_alg_total_count;
      74              :     uint8_t alg_type_pre;
      75              : 
      76           41 :     uint32_t hash_priority_table[] = {
      77              :     #if LIBSPDM_SHA512_SUPPORT
      78              :         SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512,
      79              :     #endif
      80              :     #if LIBSPDM_SHA384_SUPPORT
      81              :         SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384,
      82              :     #endif
      83              :     #if LIBSPDM_SHA256_SUPPORT
      84              :         SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256,
      85              :     #endif
      86              :     #if LIBSPDM_SHA3_512_SUPPORT
      87              :         SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512,
      88              :     #endif
      89              :     #if LIBSPDM_SHA3_384_SUPPORT
      90              :         SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384,
      91              :     #endif
      92              :     #if LIBSPDM_SHA3_256_SUPPORT
      93              :         SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256,
      94              :     #endif
      95              :     #if LIBSPDM_SM3_256_SUPPORT
      96              :         SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256,
      97              :     #endif
      98              :         0,
      99              :     };
     100              : 
     101           41 :     uint32_t asym_priority_table[] = {
     102              :     #if LIBSPDM_ECDSA_P521_SUPPORT
     103              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521,
     104              :     #endif
     105              :     #if LIBSPDM_ECDSA_P384_SUPPORT
     106              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384,
     107              :     #endif
     108              :     #if LIBSPDM_ECDSA_P256_SUPPORT
     109              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256,
     110              :     #endif
     111              :     #if LIBSPDM_RSA_PSS_4096_SUPPORT
     112              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096,
     113              :     #endif
     114              :     #if LIBSPDM_RSA_PSS_3072_SUPPORT
     115              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072,
     116              :     #endif
     117              :     #if LIBSPDM_RSA_PSS_2048_SUPPORT
     118              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048,
     119              :     #endif
     120              :     #if LIBSPDM_RSA_SSA_4096_SUPPORT
     121              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096,
     122              :     #endif
     123              :     #if LIBSPDM_RSA_SSA_3072_SUPPORT
     124              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072,
     125              :     #endif
     126              :     #if LIBSPDM_RSA_SSA_2048_SUPPORT
     127              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
     128              :     #endif
     129              :     #if LIBSPDM_EDDSA_ED448_SUPPORT
     130              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448,
     131              :     #endif
     132              :     #if LIBSPDM_EDDSA_ED25519_SUPPORT
     133              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519,
     134              :     #endif
     135              :     #if LIBSPDM_SM2_DSA_P256_SUPPORT
     136              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256,
     137              :     #endif
     138              :         0,
     139              :     };
     140              : 
     141           41 :     uint32_t req_asym_priority_table[] = {
     142              :     #if LIBSPDM_ECDSA_P521_SUPPORT
     143              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521,
     144              :     #endif
     145              :     #if LIBSPDM_ECDSA_P384_SUPPORT
     146              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384,
     147              :     #endif
     148              :     #if LIBSPDM_ECDSA_P256_SUPPORT
     149              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256,
     150              :     #endif
     151              :     #if LIBSPDM_RSA_PSS_4096_SUPPORT
     152              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096,
     153              :     #endif
     154              :     #if LIBSPDM_RSA_PSS_3072_SUPPORT
     155              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072,
     156              :     #endif
     157              :     #if LIBSPDM_RSA_PSS_2048_SUPPORT
     158              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048,
     159              :     #endif
     160              :     #if LIBSPDM_RSA_SSA_4096_SUPPORT
     161              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096,
     162              :     #endif
     163              :     #if LIBSPDM_RSA_SSA_3072_SUPPORT
     164              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072,
     165              :     #endif
     166              :     #if LIBSPDM_RSA_SSA_2048_SUPPORT
     167              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
     168              :     #endif
     169              :     #if LIBSPDM_EDDSA_ED448_SUPPORT
     170              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448,
     171              :     #endif
     172              :     #if LIBSPDM_EDDSA_ED25519_SUPPORT
     173              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519,
     174              :     #endif
     175              :     #if LIBSPDM_SM2_DSA_P256_SUPPORT
     176              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256,
     177              :     #endif
     178              :         0,
     179              :     };
     180              : 
     181           41 :     uint32_t dhe_priority_table[] = {
     182              :     #if LIBSPDM_ECDHE_P521_SUPPORT
     183              :         SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1,
     184              :     #endif
     185              :     #if LIBSPDM_ECDHE_P384_SUPPORT
     186              :         SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1,
     187              :     #endif
     188              :     #if LIBSPDM_ECDHE_P256_SUPPORT
     189              :         SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1,
     190              :     #endif
     191              :     #if LIBSPDM_FFDHE_4096_SUPPORT
     192              :         SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096,
     193              :     #endif
     194              :     #if LIBSPDM_FFDHE_3072_SUPPORT
     195              :         SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072,
     196              :     #endif
     197              :     #if LIBSPDM_FFDHE_2048_SUPPORT
     198              :         SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048,
     199              :     #endif
     200              :     #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
     201              :         SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256,
     202              :     #endif
     203              :         0,
     204              :     };
     205              : 
     206           41 :     uint32_t aead_priority_table[] = {
     207              :     #if LIBSPDM_AEAD_AES_256_GCM_SUPPORT
     208              :         SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM,
     209              :     #endif
     210              :     #if LIBSPDM_AEAD_AES_128_GCM_SUPPORT
     211              :         SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM,
     212              :     #endif
     213              :     #if LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT
     214              :         SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305,
     215              :     #endif
     216              :     #if LIBSPDM_AEAD_SM4_128_GCM_SUPPORT
     217              :         SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM,
     218              :     #endif
     219              :         0,
     220              :     };
     221              : 
     222           41 :     uint32_t key_schedule_priority_table[] = {
     223              :         SPDM_ALGORITHMS_KEY_SCHEDULE_SPDM,
     224              :     };
     225              : 
     226           41 :     uint32_t measurement_hash_priority_table[] = {
     227              :     #if LIBSPDM_SHA512_SUPPORT
     228              :         SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_512,
     229              :     #endif
     230              :     #if LIBSPDM_SHA384_SUPPORT
     231              :         SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_384,
     232              :     #endif
     233              :     #if LIBSPDM_SHA256_SUPPORT
     234              :         SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_256,
     235              :     #endif
     236              :     #if LIBSPDM_SHA3_512_SUPPORT
     237              :         SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_512,
     238              :     #endif
     239              :     #if LIBSPDM_SHA3_384_SUPPORT
     240              :         SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_384,
     241              :     #endif
     242              :     #if LIBSPDM_SHA3_256_SUPPORT
     243              :         SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_256,
     244              :     #endif
     245              :     #if LIBSPDM_SM3_256_SUPPORT
     246              :         SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SM3_256,
     247              :     #endif
     248              :         SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_RAW_BIT_STREAM_ONLY,
     249              :     };
     250              : 
     251           41 :     uint32_t measurement_spec_priority_table[] = {
     252              :         SPDM_MEASUREMENT_SPECIFICATION_DMTF,
     253              :     };
     254              : 
     255           41 :     uint32_t other_params_support_priority_table[] = {
     256              :         SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1,
     257              :         SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0,
     258              :         SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE
     259              :     };
     260              : 
     261           41 :     uint32_t mel_spec_priority_table[] = {
     262              :         SPDM_MEL_SPECIFICATION_DMTF,
     263              :     };
     264              : 
     265           41 :     spdm_request = request;
     266              : 
     267           41 :     ext_alg_total_count = 0;
     268              : 
     269              :     /* -=[Check Parameters Phase]=- */
     270           41 :     LIBSPDM_ASSERT(spdm_request->header.request_response_code == SPDM_NEGOTIATE_ALGORITHMS);
     271           41 :     LIBSPDM_ASSERT(!(((spdm_context->local_context.capability.flags &
     272              :                        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0) ^
     273              :                      (spdm_context->local_context.algorithm.measurement_spec == 0)));
     274           41 :     LIBSPDM_ASSERT(!(((spdm_context->local_context.capability.flags &
     275              :                        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0) ^
     276              :                      (spdm_context->local_context.algorithm.measurement_hash_algo == 0)));
     277              : 
     278              :     /* -=[Verify State Phase]=- */
     279           41 :     if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
     280            2 :         return libspdm_responder_handle_response_state(
     281              :             spdm_context,
     282            2 :             spdm_request->header.request_response_code,
     283              :             response_size, response);
     284              :     }
     285           39 :     if (spdm_context->connection_info.connection_state !=
     286              :         LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES) {
     287            1 :         return libspdm_generate_error_response(spdm_context,
     288              :                                                SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
     289              :                                                0, response_size, response);
     290              :     }
     291              : 
     292              :     /* -=[Validate Request Phase]=- */
     293           38 :     if (spdm_request->header.spdm_version != libspdm_get_connection_version(spdm_context)) {
     294            0 :         return libspdm_generate_error_response(spdm_context,
     295              :                                                SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
     296              :                                                response_size, response);
     297              :     }
     298           38 :     if (request_size < sizeof(spdm_negotiate_algorithms_request_t)) {
     299            1 :         return libspdm_generate_error_response(spdm_context,
     300              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     301              :                                                response_size, response);
     302              :     }
     303           37 :     if (request_size <
     304              :         sizeof(spdm_negotiate_algorithms_request_t) +
     305           37 :         sizeof(uint32_t) * spdm_request->ext_asym_count +
     306           37 :         sizeof(uint32_t) * spdm_request->ext_hash_count +
     307           37 :         sizeof(spdm_negotiate_algorithms_common_struct_table_t) * spdm_request->header.param1) {
     308            1 :         return libspdm_generate_error_response(spdm_context,
     309              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     310              :                                                response_size, response);
     311              :     }
     312           36 :     struct_table = (void *)((size_t)spdm_request +
     313           36 :                             sizeof(spdm_negotiate_algorithms_request_t) +
     314           36 :                             sizeof(uint32_t) * spdm_request->ext_asym_count +
     315           36 :                             sizeof(uint32_t) * spdm_request->ext_hash_count);
     316           36 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     317           32 :         alg_type_pre = struct_table->alg_type;
     318          119 :         for (index = 0; index < spdm_request->header.param1; index++) {
     319           93 :             if ((size_t)spdm_request + request_size < (size_t)struct_table) {
     320            0 :                 return libspdm_generate_error_response(
     321              :                     spdm_context,
     322              :                     SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     323              :                     response_size, response);
     324              :             }
     325           93 :             if ((size_t)spdm_request + request_size - (size_t)struct_table <
     326              :                 sizeof(spdm_negotiate_algorithms_common_struct_table_t)) {
     327            0 :                 return libspdm_generate_error_response(
     328              :                     spdm_context,
     329              :                     SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     330              :                     response_size, response);
     331              :             }
     332           93 :             if ((struct_table->alg_type < SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE) ||
     333           92 :                 (struct_table->alg_type >
     334              :                  SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE)) {
     335            3 :                 return libspdm_generate_error_response(
     336              :                     spdm_context,
     337              :                     SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     338              :                     response_size, response);
     339              :             }
     340              :             /* AlgType shall monotonically increase for subsequent entries. */
     341           90 :             if ((index != 0) && (struct_table->alg_type <= alg_type_pre)) {
     342            3 :                 return libspdm_generate_error_response(
     343              :                     spdm_context,
     344              :                     SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     345              :                     response_size, response);
     346              :             }
     347           87 :             alg_type_pre = struct_table->alg_type;
     348           87 :             fixed_alg_size = (struct_table->alg_count >> 4) & 0xF;
     349           87 :             ext_alg_count = struct_table->alg_count & 0xF;
     350           87 :             ext_alg_total_count += ext_alg_count;
     351           87 :             if (fixed_alg_size != 2) {
     352            0 :                 return libspdm_generate_error_response(
     353              :                     spdm_context,
     354              :                     SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     355              :                     response_size, response);
     356              :             }
     357           87 :             if ((size_t)spdm_request + request_size - (size_t)struct_table -
     358              :                 sizeof(spdm_negotiate_algorithms_common_struct_table_t) <
     359           87 :                 sizeof(uint32_t) * ext_alg_count) {
     360            0 :                 return libspdm_generate_error_response(
     361              :                     spdm_context,
     362              :                     SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     363              :                     response_size, response);
     364              :             }
     365           87 :             struct_table =
     366           87 :                 (void *)((size_t)struct_table +
     367           87 :                          sizeof(spdm_negotiate_algorithms_common_struct_table_t) +
     368           87 :                          sizeof(uint32_t) * ext_alg_count);
     369              :         }
     370              :     }
     371           30 :     ext_alg_total_count += (spdm_request->ext_asym_count + spdm_request->ext_hash_count);
     372              :     /* Algorithm count check and message size check*/
     373           30 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     374           26 :         if (ext_alg_total_count > SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_EXT_ALG_COUNT_VERSION_11) {
     375            1 :             return libspdm_generate_error_response(
     376              :                 spdm_context,
     377              :                 SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     378              :                 response_size, response);
     379              :         }
     380           25 :         if (spdm_request->length > SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_LENGTH_VERSION_11) {
     381            0 :             return libspdm_generate_error_response(
     382              :                 spdm_context,
     383              :                 SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     384              :                 response_size, response);
     385              :         }
     386              :     } else {
     387            4 :         if (ext_alg_total_count > SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_EXT_ALG_COUNT_VERSION_10) {
     388            1 :             return libspdm_generate_error_response(
     389              :                 spdm_context,
     390              :                 SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     391              :                 response_size, response);
     392              :         }
     393            3 :         if (spdm_request->length > SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_LENGTH_VERSION_10) {
     394            0 :             return libspdm_generate_error_response(
     395              :                 spdm_context,
     396              :                 SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     397              :                 response_size, response);
     398              :         }
     399              :     }
     400              : 
     401           28 :     request_size = (size_t)struct_table - (size_t)spdm_request;
     402           28 :     if (request_size != spdm_request->length) {
     403            0 :         return libspdm_generate_error_response(
     404              :             spdm_context,
     405              :             SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     406              :             response_size, response);
     407              :     }
     408           28 :     spdm_request_size = request_size;
     409              : 
     410           28 :     libspdm_reset_message_buffer_via_request_code(spdm_context, NULL,
     411           28 :                                                   spdm_request->header.request_response_code);
     412              : 
     413              :     /* -=[Construct Response Phase]=- */
     414           28 :     LIBSPDM_ASSERT(*response_size >= sizeof(libspdm_algorithms_response_mine_t));
     415           28 :     *response_size = sizeof(libspdm_algorithms_response_mine_t);
     416           28 :     libspdm_zero_mem(response, *response_size);
     417           28 :     spdm_response = response;
     418              : 
     419           28 :     spdm_response->header.spdm_version = spdm_request->header.spdm_version;
     420           28 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     421              :         /* Number of Algorithms Structure Tables */
     422           25 :         spdm_response->header.param1 = spdm_request->header.param1;
     423              :         /* Respond with only the same amount of Algorithms Structure Tables as requested */
     424           25 :         *response_size = sizeof(libspdm_algorithms_response_mine_t) -
     425           25 :                          ((SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG  -
     426           25 :                            spdm_request->header.param1) *
     427              :                           sizeof(spdm_negotiate_algorithms_common_struct_table_t));
     428              :     } else {
     429            3 :         spdm_response->header.param1 = 0;
     430            3 :         *response_size =
     431              :             sizeof(libspdm_algorithms_response_mine_t) -
     432              :             (sizeof(spdm_negotiate_algorithms_common_struct_table_t) *
     433              :              SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG);
     434              :     }
     435           28 :     spdm_response->header.request_response_code = SPDM_ALGORITHMS;
     436           28 :     spdm_response->header.param2 = 0;
     437           28 :     spdm_response->length = (uint16_t)*response_size;
     438              : 
     439           28 :     spdm_context->connection_info.algorithm.measurement_spec =
     440           28 :         spdm_request->measurement_specification;
     441           28 :     if (spdm_request->measurement_specification != 0) {
     442           26 :         spdm_context->connection_info.algorithm.measurement_hash_algo =
     443           26 :             spdm_context->local_context.algorithm.measurement_hash_algo;
     444              :     } else {
     445            2 :         spdm_context->connection_info.algorithm.measurement_hash_algo = 0;
     446              :     }
     447           28 :     spdm_context->connection_info.algorithm.base_asym_algo = spdm_request->base_asym_algo;
     448           28 :     spdm_context->connection_info.algorithm.base_hash_algo = spdm_request->base_hash_algo;
     449           28 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     450           25 :         struct_table =
     451           25 :             (void *)((size_t)spdm_request +
     452           25 :                      sizeof(spdm_negotiate_algorithms_request_t) +
     453           25 :                      sizeof(uint32_t) * spdm_request->ext_asym_count +
     454           25 :                      sizeof(uint32_t) * spdm_request->ext_hash_count);
     455           89 :         for (index = 0; index < spdm_request->header.param1; index++) {
     456           65 :             switch (struct_table->alg_type) {
     457           17 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE:
     458           17 :                 if (struct_table->alg_supported == 0) {
     459            0 :                     return libspdm_generate_error_response(
     460              :                         spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     461              :                         0, response_size, response);
     462              :                 }
     463              : 
     464           17 :                 spdm_context->connection_info.algorithm.dhe_named_group =
     465           17 :                     struct_table->alg_supported;
     466           17 :                 spdm_response->struct_table[index].alg_type =
     467              :                     SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
     468           17 :                 spdm_response->struct_table[index].alg_count = 0x20;
     469           17 :                 spdm_response->struct_table[index].alg_supported =
     470           34 :                     (uint16_t)libspdm_prioritize_algorithm(
     471              :                         dhe_priority_table, LIBSPDM_ARRAY_SIZE(dhe_priority_table),
     472           17 :                         spdm_context->local_context.algorithm.dhe_named_group,
     473           17 :                         spdm_context->connection_info.algorithm.dhe_named_group);
     474           17 :                 break;
     475           17 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD:
     476           17 :                 if (struct_table->alg_supported == 0) {
     477            1 :                     return libspdm_generate_error_response(
     478              :                         spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     479              :                         0, response_size, response);
     480              :                 }
     481              : 
     482           16 :                 spdm_context->connection_info.algorithm.aead_cipher_suite =
     483           16 :                     struct_table->alg_supported;
     484           16 :                 spdm_response->struct_table[index].alg_type =
     485              :                     SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
     486           16 :                 spdm_response->struct_table[index].alg_count = 0x20;
     487           16 :                 spdm_response->struct_table[index].alg_supported =
     488           32 :                     (uint16_t)libspdm_prioritize_algorithm(
     489              :                         aead_priority_table, LIBSPDM_ARRAY_SIZE(aead_priority_table),
     490           16 :                         spdm_context->local_context.algorithm.aead_cipher_suite,
     491           16 :                         spdm_context->connection_info.algorithm.aead_cipher_suite);
     492           16 :                 break;
     493           16 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG:
     494           16 :                 if (struct_table->alg_supported == 0) {
     495            0 :                     return libspdm_generate_error_response(
     496              :                         spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     497              :                         0, response_size, response);
     498              :                 }
     499              : 
     500           16 :                 spdm_context->connection_info.algorithm.req_base_asym_alg =
     501           16 :                     struct_table->alg_supported;
     502           16 :                 spdm_response->struct_table[index].alg_type =
     503              :                     SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
     504           16 :                 spdm_response->struct_table[index].alg_count = 0x20;
     505           16 :                 spdm_response->struct_table[index].alg_supported =
     506           32 :                     (uint16_t)libspdm_prioritize_algorithm(
     507              :                         req_asym_priority_table,
     508              :                         LIBSPDM_ARRAY_SIZE(req_asym_priority_table),
     509           16 :                         spdm_context->local_context.algorithm.req_base_asym_alg,
     510           16 :                         spdm_context->connection_info.algorithm.req_base_asym_alg);
     511           16 :                 break;
     512           15 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE:
     513           15 :                 if (struct_table->alg_supported == 0) {
     514            0 :                     return libspdm_generate_error_response(
     515              :                         spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     516              :                         0, response_size, response);
     517              :                 }
     518              : 
     519           15 :                 spdm_context->connection_info.algorithm.key_schedule =
     520           15 :                     struct_table->alg_supported;
     521           15 :                 spdm_response->struct_table[index].alg_type =
     522              :                     SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
     523           15 :                 spdm_response->struct_table[index].alg_count = 0x20;
     524           15 :                 spdm_response->struct_table[index].alg_supported =
     525           30 :                     (uint16_t)libspdm_prioritize_algorithm(
     526              :                         key_schedule_priority_table,
     527              :                         LIBSPDM_ARRAY_SIZE(key_schedule_priority_table),
     528           15 :                         spdm_context->local_context.algorithm.key_schedule,
     529           15 :                         spdm_context->connection_info.algorithm.key_schedule);
     530           15 :                 break;
     531            0 :             default:
     532              :                 /* Unknown algorithm types do not need to be processed */
     533            0 :                 break;
     534              :             }
     535           64 :             ext_alg_count = struct_table->alg_count & 0xF;
     536           64 :             struct_table =
     537           64 :                 (void *)((size_t)struct_table +
     538           64 :                          sizeof(spdm_negotiate_algorithms_common_struct_table_t) +
     539           64 :                          sizeof(uint32_t) * ext_alg_count);
     540              :         }
     541              :     }
     542           27 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     543           14 :         spdm_context->connection_info.algorithm.other_params_support =
     544           14 :             spdm_request->other_params_support & SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK;
     545           14 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     546            8 :             spdm_context->connection_info.algorithm.other_params_support =
     547            8 :                 spdm_request->other_params_support;
     548            8 :             spdm_context->connection_info.algorithm.mel_spec =
     549            8 :                 spdm_request->mel_specification;
     550              :         }
     551              :     }
     552              : 
     553           27 :     if (libspdm_is_capabilities_flag_supported(
     554              :             spdm_context, false, 0,
     555              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP)) {
     556            2 :         spdm_response->measurement_specification_sel = (uint8_t)libspdm_prioritize_algorithm(
     557              :             measurement_spec_priority_table,
     558              :             LIBSPDM_ARRAY_SIZE(measurement_spec_priority_table),
     559            2 :             spdm_context->local_context.algorithm.measurement_spec,
     560            2 :             spdm_context->connection_info.algorithm.measurement_spec);
     561              :     } else {
     562           25 :         spdm_response->measurement_specification_sel = 0;
     563              :     }
     564              : 
     565           27 :     spdm_response->measurement_hash_algo = libspdm_prioritize_algorithm(
     566              :         measurement_hash_priority_table,
     567              :         LIBSPDM_ARRAY_SIZE(measurement_hash_priority_table),
     568              :         spdm_context->local_context.algorithm.measurement_hash_algo,
     569              :         spdm_context->connection_info.algorithm.measurement_hash_algo);
     570              : 
     571           27 :     spdm_response->base_asym_sel = libspdm_prioritize_algorithm(
     572              :         asym_priority_table, LIBSPDM_ARRAY_SIZE(asym_priority_table),
     573              :         spdm_context->local_context.algorithm.base_asym_algo,
     574              :         spdm_context->connection_info.algorithm.base_asym_algo);
     575              : 
     576           27 :     spdm_response->base_hash_sel = libspdm_prioritize_algorithm(
     577              :         hash_priority_table, LIBSPDM_ARRAY_SIZE(hash_priority_table),
     578              :         spdm_context->local_context.algorithm.base_hash_algo,
     579              :         spdm_context->connection_info.algorithm.base_hash_algo);
     580              : 
     581              : 
     582           27 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     583           28 :         spdm_response->other_params_selection = (uint8_t)libspdm_prioritize_algorithm(
     584              :             other_params_support_priority_table,
     585              :             LIBSPDM_ARRAY_SIZE(other_params_support_priority_table),
     586           14 :             spdm_context->local_context.algorithm.other_params_support &
     587              :             SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK,
     588           14 :             spdm_context->connection_info.algorithm.other_params_support &
     589              :             SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK);
     590           14 :         if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     591            8 :             if (libspdm_is_capabilities_flag_supported(
     592              :                     spdm_context, false, 0,
     593              :                     SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP)) {
     594            1 :                 spdm_response->mel_specification_sel = (uint8_t)libspdm_prioritize_algorithm(
     595              :                     mel_spec_priority_table,
     596              :                     LIBSPDM_ARRAY_SIZE(mel_spec_priority_table),
     597            1 :                     spdm_context->local_context.algorithm.mel_spec,
     598            1 :                     spdm_context->connection_info.algorithm.mel_spec);
     599              :             } else {
     600            7 :                 spdm_response->mel_specification_sel = 0;
     601              :             }
     602              :         }
     603              :     }
     604              : 
     605           27 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     606            8 :         switch (spdm_context->connection_info.capability.flags &
     607              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) {
     608            2 :         case 0:
     609            2 :             spdm_context->connection_info.multi_key_conn_req = false;
     610            2 :             break;
     611            2 :         case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY:
     612            2 :             spdm_context->connection_info.multi_key_conn_req = true;
     613            2 :             break;
     614            4 :         case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_NEG:
     615            4 :             if ((spdm_context->local_context.algorithm.other_params_support &
     616              :                  SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
     617            3 :                 spdm_context->connection_info.multi_key_conn_req = false;
     618              :             } else {
     619            1 :                 spdm_context->connection_info.multi_key_conn_req = true;
     620              :             }
     621            4 :             break;
     622            0 :         default:
     623            0 :             return libspdm_generate_error_response(
     624              :                 spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     625              :                 0, response_size, response);
     626              :         }
     627            8 :         if (spdm_context->connection_info.multi_key_conn_req) {
     628            3 :             spdm_response->other_params_selection |= SPDM_ALGORITHMS_MULTI_KEY_CONN;
     629              :         } else {
     630            5 :             spdm_response->other_params_selection &= ~SPDM_ALGORITHMS_MULTI_KEY_CONN;
     631              :         }
     632              :     }
     633              : 
     634           27 :     spdm_context->connection_info.algorithm.measurement_spec =
     635           27 :         spdm_response->measurement_specification_sel;
     636           27 :     spdm_context->connection_info.algorithm.measurement_hash_algo =
     637           27 :         spdm_response->measurement_hash_algo;
     638           27 :     spdm_context->connection_info.algorithm.base_asym_algo = spdm_response->base_asym_sel;
     639           27 :     spdm_context->connection_info.algorithm.base_hash_algo = spdm_response->base_hash_sel;
     640              : 
     641           27 :     if (libspdm_is_capabilities_flag_supported(
     642              :             spdm_context, false, 0,
     643            2 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) &&
     644            2 :         (spdm_request->measurement_specification != 0)) {
     645            1 :         if (spdm_context->connection_info.algorithm.measurement_spec !=
     646              :             SPDM_MEASUREMENT_SPECIFICATION_DMTF) {
     647            0 :             return libspdm_generate_error_response(
     648              :                 spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     649              :                 0, response_size, response);
     650              :         }
     651            1 :         algo_size = libspdm_get_measurement_hash_size(
     652              :             spdm_context->connection_info.algorithm.measurement_hash_algo);
     653            1 :         if (algo_size == 0) {
     654            0 :             return libspdm_generate_error_response(
     655              :                 spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     656              :                 0, response_size, response);
     657              :         }
     658              :     }
     659              : 
     660           27 :     if (libspdm_is_capabilities_flag_supported(
     661              :             spdm_context, false, 0,
     662           27 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) ||
     663           27 :         libspdm_is_capabilities_flag_supported(
     664              :             spdm_context, false, 0,
     665           18 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) ||
     666           18 :         libspdm_is_capabilities_flag_supported(
     667              :             spdm_context, false, 0,
     668           16 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) ||
     669           16 :         libspdm_is_capabilities_flag_supported(
     670              :             spdm_context, false,
     671              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     672           10 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) ||
     673           10 :         libspdm_is_capabilities_flag_supported(
     674              :             spdm_context, false,
     675              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
     676              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
     677           17 :         algo_size = libspdm_get_hash_size(
     678              :             spdm_context->connection_info.algorithm.base_hash_algo);
     679           17 :         if (algo_size == 0) {
     680            1 :             return libspdm_generate_error_response(
     681              :                 spdm_context,
     682              :                 SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     683              :                 response_size, response);
     684              :         }
     685              :     }
     686              : 
     687           26 :     if (libspdm_is_capabilities_flag_supported(
     688              :             spdm_context, false, 0,
     689           26 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) ||
     690           26 :         libspdm_is_capabilities_flag_supported(
     691              :             spdm_context, false, 0,
     692           18 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) ||
     693           18 :         libspdm_is_capabilities_flag_supported(
     694              :             spdm_context, false, 0,
     695           16 :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) ||
     696           16 :         libspdm_is_capabilities_flag_supported(
     697              :             spdm_context, false,
     698              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     699              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
     700           16 :         algo_size = libspdm_get_asym_signature_size(
     701              :             spdm_context->connection_info.algorithm.base_asym_algo);
     702           16 :         if (algo_size == 0) {
     703            1 :             return libspdm_generate_error_response(
     704              :                 spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     705              :                 0, response_size, response);
     706              :         }
     707              :     }
     708              : 
     709              :     /* -=[Process Request Phase]=- */
     710           25 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
     711           77 :         for (index = 0; index < spdm_response->header.param1; ++index) {
     712           55 :             switch(spdm_response->struct_table[index].alg_type) {
     713           14 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE:
     714           14 :                 spdm_context->connection_info.algorithm.dhe_named_group =
     715           14 :                     spdm_response->struct_table[index].alg_supported;
     716           14 :                 break;
     717           14 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD:
     718           14 :                 spdm_context->connection_info.algorithm.aead_cipher_suite =
     719           14 :                     spdm_response->struct_table[index].alg_supported;
     720           14 :                 break;
     721           14 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG:
     722           14 :                 spdm_context->connection_info.algorithm.req_base_asym_alg =
     723           14 :                     spdm_response->struct_table[index].alg_supported;
     724           14 :                 break;
     725           13 :             case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE:
     726           13 :                 spdm_context->connection_info.algorithm.key_schedule =
     727           13 :                     spdm_response->struct_table[index].alg_supported;
     728           13 :                 break;
     729            0 :             default:
     730              :                 /* Unreachable */
     731            0 :                 LIBSPDM_ASSERT(false);
     732            0 :                 break;
     733              :             }
     734              :         }
     735           22 :         if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     736           14 :             if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     737            8 :                 spdm_context->connection_info.algorithm.other_params_support =
     738            8 :                     (spdm_context->connection_info.algorithm.other_params_support &
     739            8 :                      SPDM_ALGORITHMS_MULTI_KEY_CONN) |
     740            8 :                     (spdm_response->other_params_selection &
     741              :                      SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK);
     742            8 :                 spdm_context->connection_info.algorithm.mel_spec =
     743            8 :                     spdm_response->mel_specification_sel;
     744              :             } else {
     745            6 :                 spdm_context->connection_info.algorithm.other_params_support =
     746            6 :                     (spdm_response->other_params_selection &
     747              :                      SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK);
     748            6 :                 spdm_context->connection_info.algorithm.mel_spec = 0;
     749              :             }
     750              :         } else {
     751            8 :             spdm_context->connection_info.algorithm.other_params_support = 0;
     752              :         }
     753              : 
     754           22 :         if (libspdm_is_capabilities_flag_supported(
     755              :                 spdm_context, false,
     756              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     757              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
     758           14 :             algo_size = libspdm_get_dhe_pub_key_size(
     759           14 :                 spdm_context->connection_info.algorithm.dhe_named_group);
     760           14 :             if (algo_size == 0) {
     761            1 :                 return libspdm_generate_error_response(
     762              :                     spdm_context,
     763              :                     SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     764              :                     response_size, response);
     765              :             }
     766              :         }
     767           21 :         if (libspdm_is_capabilities_flag_supported(
     768              :                 spdm_context, false,
     769              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP,
     770            8 :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) ||
     771            8 :             libspdm_is_capabilities_flag_supported(
     772              :                 spdm_context, false,
     773              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
     774              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
     775           13 :             algo_size = libspdm_get_aead_key_size(
     776           13 :                 spdm_context->connection_info.algorithm.aead_cipher_suite);
     777           13 :             if (algo_size == 0) {
     778            1 :                 return libspdm_generate_error_response(
     779              :                     spdm_context,
     780              :                     SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     781              :                     response_size, response);
     782              :             }
     783              :         }
     784           20 :         if (libspdm_is_capabilities_flag_supported(
     785              :                 spdm_context, false,
     786              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP,
     787              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP)) {
     788           12 :             algo_size = libspdm_get_req_asym_signature_size(
     789           12 :                 spdm_context->connection_info.algorithm.req_base_asym_alg);
     790           12 :             if (algo_size == 0) {
     791            1 :                 return libspdm_generate_error_response(
     792              :                     spdm_context,
     793              :                     SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     794              :                     response_size, response);
     795              :             }
     796              :         }
     797           19 :         if (libspdm_is_capabilities_flag_supported(
     798              :                 spdm_context, false,
     799              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     800            8 :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) ||
     801            8 :             libspdm_is_capabilities_flag_supported(
     802              :                 spdm_context, false,
     803              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
     804              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
     805           11 :             if (spdm_context->connection_info.algorithm.key_schedule !=
     806              :                 SPDM_ALGORITHMS_KEY_SCHEDULE_SPDM) {
     807            2 :                 return libspdm_generate_error_response(
     808              :                     spdm_context,
     809              :                     SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     810              :                     response_size, response);
     811              :             }
     812              :         }
     813              : 
     814           17 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     815            8 :             if ((spdm_context->connection_info.algorithm.other_params_support &
     816              :                  SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
     817            5 :                 if ((spdm_context->local_context.capability.flags &
     818              :                      SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) ==
     819              :                     SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_ONLY) {
     820            1 :                     return libspdm_generate_error_response(
     821              :                         spdm_context,
     822              :                         SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     823              :                         response_size, response);
     824              :                 }
     825            4 :                 spdm_context->connection_info.multi_key_conn_rsp = false;
     826              :             } else {
     827            3 :                 if ((spdm_context->local_context.capability.flags &
     828              :                      SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) == 0) {
     829            1 :                     return libspdm_generate_error_response(
     830              :                         spdm_context,
     831              :                         SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     832              :                         response_size, response);
     833              :                 }
     834            2 :                 spdm_context->connection_info.multi_key_conn_rsp = true;
     835              :             }
     836              :         }
     837              :     } else {
     838            3 :         spdm_context->connection_info.algorithm.dhe_named_group = 0;
     839            3 :         spdm_context->connection_info.algorithm.aead_cipher_suite = 0;
     840            3 :         spdm_context->connection_info.algorithm.req_base_asym_alg = 0;
     841            3 :         spdm_context->connection_info.algorithm.key_schedule = 0;
     842            3 :         spdm_context->connection_info.algorithm.other_params_support = 0;
     843              :     }
     844              : 
     845           18 :     status = libspdm_append_message_a(spdm_context, spdm_request, spdm_request_size);
     846           18 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     847            0 :         return libspdm_generate_error_response(spdm_context,
     848              :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     849              :                                                response_size, response);
     850              :     }
     851              : 
     852           18 :     status = libspdm_append_message_a(spdm_context, spdm_response, *response_size);
     853           18 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     854            0 :         return libspdm_generate_error_response(spdm_context,
     855              :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     856              :                                                response_size, response);
     857              :     }
     858              : 
     859              :     /* -=[Update State Phase]=- */
     860           18 :     libspdm_set_connection_state(spdm_context, LIBSPDM_CONNECTION_STATE_NEGOTIATED);
     861              : 
     862           18 :     return LIBSPDM_STATUS_SUCCESS;
     863              : }
        

Generated by: LCOV version 2.0-1