LCOV - code coverage report
Current view: top level - library/spdm_crypt_lib - libspdm_crypt_asym.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 50.9 % 617 314
Test Date: 2025-06-29 08:09:00 Functions: 75.0 % 36 27

            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_crypt_lib.h"
       8              : #include "library/spdm_common_lib.h"
       9              : 
      10              : typedef struct {
      11              :     bool is_requester;
      12              :     uint8_t op_code;
      13              :     const void *context;
      14              :     size_t context_size;
      15              :     size_t zero_pad_size;
      16              : } libspdm_signing_context_str_t;
      17              : 
      18              : static const libspdm_signing_context_str_t m_libspdm_signing_context_str_table[] = {
      19              :     {false, SPDM_CHALLENGE_AUTH, SPDM_CHALLENGE_AUTH_SIGN_CONTEXT,
      20              :      SPDM_CHALLENGE_AUTH_SIGN_CONTEXT_SIZE, 36 - SPDM_CHALLENGE_AUTH_SIGN_CONTEXT_SIZE},
      21              :     {true, SPDM_CHALLENGE_AUTH, SPDM_MUT_CHALLENGE_AUTH_SIGN_CONTEXT,
      22              :      SPDM_MUT_CHALLENGE_AUTH_SIGN_CONTEXT_SIZE, 36 - SPDM_MUT_CHALLENGE_AUTH_SIGN_CONTEXT_SIZE},
      23              :     {false, SPDM_MEASUREMENTS, SPDM_MEASUREMENTS_SIGN_CONTEXT, SPDM_MEASUREMENTS_SIGN_CONTEXT_SIZE,
      24              :      36 - SPDM_MEASUREMENTS_SIGN_CONTEXT_SIZE},
      25              :     {false, SPDM_KEY_EXCHANGE_RSP, SPDM_KEY_EXCHANGE_RESPONSE_SIGN_CONTEXT,
      26              :      SPDM_KEY_EXCHANGE_RESPONSE_SIGN_CONTEXT_SIZE,
      27              :      36 - SPDM_KEY_EXCHANGE_RESPONSE_SIGN_CONTEXT_SIZE},
      28              :     {true, SPDM_FINISH, SPDM_FINISH_SIGN_CONTEXT, SPDM_FINISH_SIGN_CONTEXT_SIZE,
      29              :      36 - SPDM_FINISH_SIGN_CONTEXT_SIZE},
      30              :     {false, SPDM_ENDPOINT_INFO, SPDM_ENDPOINT_INFO_SIGN_CONTEXT,
      31              :      SPDM_ENDPOINT_INFO_SIGN_CONTEXT_SIZE,
      32              :      36 - SPDM_ENDPOINT_INFO_SIGN_CONTEXT_SIZE},
      33              :     {true, SPDM_ENDPOINT_INFO, SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT,
      34              :      SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT_SIZE, 36 - SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT_SIZE},
      35              : };
      36              : 
      37              : #if LIBSPDM_RSA_SSA_SUPPORT
      38           36 : static bool libspdm_rsa_pkcs1_sign_with_nid_wrap (void *context, size_t hash_nid,
      39              :                                                   const uint8_t *param, size_t param_size,
      40              :                                                   const uint8_t *message,
      41              :                                                   size_t message_size, uint8_t *signature,
      42              :                                                   size_t *sig_size)
      43              : {
      44           36 :     return libspdm_rsa_pkcs1_sign_with_nid (context, hash_nid,
      45              :                                             message, message_size, signature, sig_size);
      46              : }
      47              : #endif
      48              : 
      49              : #if LIBSPDM_RSA_PSS_SUPPORT
      50            0 : static bool libspdm_rsa_pss_sign_wrap (void *context, size_t hash_nid,
      51              :                                        const uint8_t *param, size_t param_size,
      52              :                                        const uint8_t *message,
      53              :                                        size_t message_size, uint8_t *signature,
      54              :                                        size_t *sig_size)
      55              : {
      56            0 :     return libspdm_rsa_pss_sign (context, hash_nid,
      57              :                                  message, message_size, signature, sig_size);
      58              : }
      59              : #endif
      60              : 
      61              : #if LIBSPDM_ECDSA_SUPPORT
      62          140 : static bool libspdm_ecdsa_sign_wrap (void *context, size_t hash_nid,
      63              :                                      const uint8_t *param, size_t param_size,
      64              :                                      const uint8_t *message,
      65              :                                      size_t message_size, uint8_t *signature,
      66              :                                      size_t *sig_size)
      67              : {
      68          140 :     return libspdm_ecdsa_sign (context, hash_nid,
      69              :                                message, message_size, signature, sig_size);
      70              : }
      71              : #endif
      72              : 
      73              : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
      74              : static bool libspdm_eddsa_sign_wrap (void *context, size_t hash_nid,
      75              :                                      const uint8_t *param, size_t param_size,
      76              :                                      const uint8_t *message,
      77              :                                      size_t message_size, uint8_t *signature,
      78              :                                      size_t *sig_size)
      79              : {
      80              :     return libspdm_eddsa_sign (context, hash_nid, param, param_size,
      81              :                                message, message_size, signature, sig_size);
      82              : }
      83              : #endif
      84              : 
      85              : #if LIBSPDM_SM2_DSA_SUPPORT
      86              : static bool libspdm_sm2_dsa_sign_wrap (void *context, size_t hash_nid,
      87              :                                        const uint8_t *param, size_t param_size,
      88              :                                        const uint8_t *message,
      89              :                                        size_t message_size, uint8_t *signature,
      90              :                                        size_t *sig_size)
      91              : {
      92              :     return libspdm_sm2_dsa_sign (context, hash_nid, param, param_size,
      93              :                                  message, message_size, signature, sig_size);
      94              : }
      95              : #endif
      96              : 
      97              : /**
      98              :  * Get the SPDM signing context string, which is required since SPDM 1.2.
      99              :  *
     100              :  * @param  spdm_version                         negotiated SPDM version
     101              :  * @param  op_code                              the SPDM opcode which requires the signing
     102              :  * @param  is_requester                         indicate if the signing is from a requester
     103              :  * @param  context_size                         SPDM signing context size
     104              :  **/
     105            0 : static const void *libspdm_get_signing_context_string (
     106              :     spdm_version_number_t spdm_version,
     107              :     uint8_t op_code,
     108              :     bool is_requester,
     109              :     size_t *context_size)
     110              : {
     111              :     size_t index;
     112              : 
     113              :     /* It is introduced in SPDM 1.2*/
     114            0 :     LIBSPDM_ASSERT((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11);
     115              : 
     116            0 :     for (index = 0; index < LIBSPDM_ARRAY_SIZE(m_libspdm_signing_context_str_table); index++) {
     117            0 :         if (m_libspdm_signing_context_str_table[index].is_requester == is_requester &&
     118            0 :             m_libspdm_signing_context_str_table[index].op_code == op_code) {
     119            0 :             *context_size = m_libspdm_signing_context_str_table[index].context_size;
     120            0 :             return m_libspdm_signing_context_str_table[index].context;
     121              :         }
     122              :     }
     123            0 :     LIBSPDM_ASSERT(false);
     124            0 :     return NULL;
     125              : }
     126              : 
     127              : /**
     128              :  * Create SPDM signing context, which is required since SPDM 1.2.
     129              :  *
     130              :  * @param  spdm_version                         negotiated SPDM version
     131              :  * @param  op_code                              the SPDM opcode which requires the signing
     132              :  * @param  is_requester                         indicate if the signing is from a requester
     133              :  * @param  spdm_signing_context                 SPDM signing context
     134              :  **/
     135           81 : static void libspdm_create_signing_context (
     136              :     spdm_version_number_t spdm_version,
     137              :     uint8_t op_code,
     138              :     bool is_requester,
     139              :     void *spdm_signing_context)
     140              : {
     141              :     size_t index;
     142              :     char *context_str;
     143              : 
     144              :     /* It is introduced in SPDM 1.2*/
     145           81 :     LIBSPDM_ASSERT((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11);
     146              : 
     147              :     /* So far, it only leaves 1 bytes for version*/
     148           81 :     LIBSPDM_ASSERT((((spdm_version >> 12) & 0xF) < 10) &&
     149              :                    (((spdm_version >> 8) & 0xF) < 10));
     150              : 
     151           81 :     context_str = spdm_signing_context;
     152          405 :     for (index = 0; index < 4; index++) {
     153          324 :         libspdm_copy_mem(context_str,
     154              :                          SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT_SIZE,
     155              :                          SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT,
     156              :                          SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT_SIZE);
     157              :         /* patch the version*/
     158          324 :         context_str[11] = (char)('0' + ((spdm_version >> 12) & 0xF));
     159          324 :         context_str[13] = (char)('0' + ((spdm_version >> 8) & 0xF));
     160          324 :         context_str[15] = (char)('*');
     161          324 :         context_str += SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT_SIZE;
     162              :     }
     163          400 :     for (index = 0; index < LIBSPDM_ARRAY_SIZE(m_libspdm_signing_context_str_table); index++) {
     164          400 :         if (m_libspdm_signing_context_str_table[index].is_requester == is_requester &&
     165          238 :             m_libspdm_signing_context_str_table[index].op_code == op_code) {
     166           81 :             libspdm_zero_mem (
     167              :                 context_str,
     168           81 :                 m_libspdm_signing_context_str_table[index].zero_pad_size);
     169           81 :             libspdm_copy_mem(context_str + m_libspdm_signing_context_str_table[index].zero_pad_size,
     170           81 :                              m_libspdm_signing_context_str_table[index].context_size,
     171           81 :                              m_libspdm_signing_context_str_table[index].context,
     172           81 :                              m_libspdm_signing_context_str_table[index].context_size);
     173           81 :             return;
     174              :         }
     175              :     }
     176            0 :     LIBSPDM_ASSERT(false);
     177              : }
     178              : 
     179          615 : uint32_t libspdm_get_asym_signature_size(uint32_t base_asym_algo)
     180              : {
     181          615 :     switch (base_asym_algo) {
     182          106 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     183              : #if LIBSPDM_RSA_SSA_2048_SUPPORT
     184          106 :         return 256;
     185              : #else
     186              :         return 0;
     187              : #endif
     188            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
     189              : #if LIBSPDM_RSA_PSS_2048_SUPPORT
     190            0 :         return 256;
     191              : #else
     192              :         return 0;
     193              : #endif
     194            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     195              : #if LIBSPDM_RSA_SSA_3072_SUPPORT
     196            0 :         return 384;
     197              : #else
     198              :         return 0;
     199              : #endif
     200            1 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
     201              : #if LIBSPDM_RSA_PSS_3072_SUPPORT
     202            1 :         return 384;
     203              : #else
     204              :         return 0;
     205              : #endif
     206            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     207              : #if LIBSPDM_RSA_SSA_4096_SUPPORT
     208            0 :         return 512;
     209              : #else
     210              :         return 0;
     211              : #endif
     212            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
     213              : #if LIBSPDM_RSA_PSS_4096_SUPPORT
     214            0 :         return 512;
     215              : #else
     216              :         return 0;
     217              : #endif
     218          498 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
     219              : #if LIBSPDM_ECDSA_P256_SUPPORT
     220          498 :         return 32 * 2;
     221              : #else
     222              :         return 0;
     223              : #endif
     224            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
     225              : #if LIBSPDM_ECDSA_P384_SUPPORT
     226            0 :         return 48 * 2;
     227              : #else
     228              :         return 0;
     229              : #endif
     230            2 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
     231              : #if LIBSPDM_ECDSA_P521_SUPPORT
     232            2 :         return 66 * 2;
     233              : #else
     234              :         return 0;
     235              : #endif
     236            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
     237              : #if LIBSPDM_SM2_DSA_P256_SUPPORT
     238              :         return 32 * 2;
     239              : #else
     240            0 :         return 0;
     241              : #endif
     242            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     243              : #if LIBSPDM_EDDSA_ED25519_SUPPORT
     244              :         return 32 * 2;
     245              : #else
     246            0 :         return 0;
     247              : #endif
     248            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     249              : #if LIBSPDM_EDDSA_ED448_SUPPORT
     250              :         return 57 * 2;
     251              : #else
     252            0 :         return 0;
     253              : #endif
     254            8 :     default:
     255            8 :         return 0;
     256              :     }
     257              : }
     258              : 
     259          176 : static bool libspdm_asym_sign_wrap (void *context, size_t hash_nid, uint32_t base_asym_algo,
     260              :                                     const uint8_t *param, size_t param_size,
     261              :                                     const uint8_t *message, size_t message_size,
     262              :                                     uint8_t *signature, size_t *sig_size)
     263              : {
     264          176 :     switch (base_asym_algo) {
     265           36 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     266              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     267              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     268              : #if LIBSPDM_RSA_SSA_SUPPORT
     269              : #if !LIBSPDM_RSA_SSA_2048_SUPPORT
     270              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048);
     271              : #endif
     272              : #if !LIBSPDM_RSA_SSA_3072_SUPPORT
     273              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072);
     274              : #endif
     275              : #if !LIBSPDM_RSA_SSA_4096_SUPPORT
     276              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096);
     277              : #endif
     278           36 :         return libspdm_rsa_pkcs1_sign_with_nid_wrap(context, hash_nid,
     279              :                                                     param, param_size,
     280              :                                                     message, message_size,
     281              :                                                     signature, sig_size);
     282              : #else
     283              :         LIBSPDM_ASSERT(false);
     284              :         return false;
     285              : #endif
     286            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
     287              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
     288              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
     289              : #if LIBSPDM_RSA_PSS_SUPPORT
     290              : #if !LIBSPDM_RSA_PSS_2048_SUPPORT
     291              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048);
     292              : #endif
     293              : #if !LIBSPDM_RSA_PSS_3072_SUPPORT
     294              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072);
     295              : #endif
     296              : #if !LIBSPDM_RSA_PSS_4096_SUPPORT
     297              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096);
     298              : #endif
     299            0 :         return libspdm_rsa_pss_sign_wrap(context, hash_nid,
     300              :                                          param, param_size,
     301              :                                          message, message_size,
     302              :                                          signature, sig_size);
     303              : #else
     304              :         LIBSPDM_ASSERT(false);
     305              :         return false;
     306              : #endif
     307          140 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
     308              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
     309              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
     310              : #if LIBSPDM_ECDSA_SUPPORT
     311              : #if !LIBSPDM_ECDSA_P256_SUPPORT
     312              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256);
     313              : #endif
     314              : #if !LIBSPDM_ECDSA_P384_SUPPORT
     315              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384);
     316              : #endif
     317              : #if !LIBSPDM_ECDSA_P521_SUPPORT
     318              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521);
     319              : #endif
     320          140 :         return libspdm_ecdsa_sign_wrap(context, hash_nid,
     321              :                                        param, param_size,
     322              :                                        message, message_size,
     323              :                                        signature, sig_size);
     324              : #else
     325              :         LIBSPDM_ASSERT(false);
     326              :         return false;
     327              : #endif
     328            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     329              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     330              : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
     331              : #if !LIBSPDM_EDDSA_ED25519_SUPPORT
     332              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519);
     333              : #endif
     334              : #if !LIBSPDM_EDDSA_ED448_SUPPORT
     335              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448);
     336              : #endif
     337              :         return libspdm_eddsa_sign_wrap(context, hash_nid,
     338              :                                        param, param_size,
     339              :                                        message, message_size,
     340              :                                        signature, sig_size);
     341              : #else
     342            0 :         LIBSPDM_ASSERT(false);
     343            0 :         return false;
     344              : #endif
     345            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
     346              : #if LIBSPDM_SM2_DSA_SUPPORT
     347              :         return libspdm_sm2_dsa_sign_wrap(context, hash_nid,
     348              :                                          param, param_size,
     349              :                                          message, message_size,
     350              :                                          signature, sig_size);
     351              : #else
     352            0 :         LIBSPDM_ASSERT(false);
     353            0 :         return false;
     354              : #endif
     355            0 :     default:
     356            0 :         LIBSPDM_ASSERT(false);
     357            0 :         return false;
     358              :     }
     359              : }
     360              : 
     361          961 : void libspdm_asym_free(uint32_t base_asym_algo, void *context)
     362              : {
     363          961 :     if (context == NULL) {
     364            2 :         return;
     365              :     }
     366          959 :     switch (base_asym_algo) {
     367          102 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     368              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     369              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     370              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
     371              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
     372              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
     373              : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
     374          102 :         libspdm_rsa_free(context);
     375              : #else
     376              :         LIBSPDM_ASSERT(false);
     377              : #endif
     378          102 :         break;
     379          857 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
     380              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
     381              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
     382              : #if LIBSPDM_ECDSA_SUPPORT
     383          857 :         libspdm_ec_free(context);
     384              : #else
     385              :         LIBSPDM_ASSERT(false);
     386              : #endif
     387          857 :         break;
     388            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     389              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     390              : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
     391              :         libspdm_ecd_free(context);
     392              : #else
     393            0 :         LIBSPDM_ASSERT(false);
     394              : #endif
     395            0 :         break;
     396            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
     397              : #if LIBSPDM_SM2_DSA_SUPPORT
     398              :         libspdm_sm2_dsa_free(context);
     399              : #else
     400            0 :         LIBSPDM_ASSERT(false);
     401              : #endif
     402            0 :         break;
     403            0 :     default:
     404            0 :         LIBSPDM_ASSERT(false);
     405            0 :         break;
     406              :     }
     407              : }
     408              : 
     409           10 : static bool libspdm_asym_get_public_key_from_der_wrap(uint32_t base_asym_algo,
     410              :                                                       const uint8_t *der_data,
     411              :                                                       size_t der_size,
     412              :                                                       void **context)
     413              : {
     414           10 :     switch (base_asym_algo) {
     415            5 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     416              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     417              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     418              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
     419              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
     420              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
     421              : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
     422              : #if !LIBSPDM_RSA_SSA_2048_SUPPORT
     423              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048);
     424              : #endif
     425              : #if !LIBSPDM_RSA_SSA_3072_SUPPORT
     426              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072);
     427              : #endif
     428              : #if !LIBSPDM_RSA_SSA_4096_SUPPORT
     429              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096);
     430              : #endif
     431              : #if !LIBSPDM_RSA_PSS_2048_SUPPORT
     432              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048);
     433              : #endif
     434              : #if !LIBSPDM_RSA_PSS_3072_SUPPORT
     435              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072);
     436              : #endif
     437              : #if !LIBSPDM_RSA_PSS_4096_SUPPORT
     438              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096);
     439              : #endif
     440            5 :         return libspdm_rsa_get_public_key_from_der(der_data, der_size, context);
     441              : #else
     442              :         LIBSPDM_ASSERT(false);
     443              :         return false;
     444              : #endif
     445            5 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
     446              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
     447              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
     448              : #if LIBSPDM_ECDSA_SUPPORT
     449              : #if !LIBSPDM_ECDSA_P256_SUPPORT
     450              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256);
     451              : #endif
     452              : #if !LIBSPDM_ECDSA_P384_SUPPORT
     453              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384);
     454              : #endif
     455              : #if !LIBSPDM_ECDSA_P521_SUPPORT
     456              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521);
     457              : #endif
     458            5 :         return libspdm_ec_get_public_key_from_der(der_data, der_size, context);
     459              : #else
     460              :         LIBSPDM_ASSERT(false);
     461              :         return false;
     462              : #endif
     463            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     464              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     465              : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
     466              :         return libspdm_ecd_get_public_key_from_der(der_data, der_size, context);
     467              : #else
     468            0 :         LIBSPDM_ASSERT(false);
     469            0 :         return false;
     470              : #endif
     471            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
     472              : #if LIBSPDM_SM2_DSA_SUPPORT
     473              : #if !LIBSPDM_EDDSA_ED25519_SUPPORT
     474              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519);
     475              : #endif
     476              : #if !LIBSPDM_EDDSA_ED448_SUPPORT
     477              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448);
     478              : #endif
     479              :         return libspdm_sm2_get_public_key_from_der(der_data, der_size, context);
     480              : #else
     481            0 :         LIBSPDM_ASSERT(false);
     482            0 :         return false;
     483              : #endif
     484            0 :     default:
     485            0 :         LIBSPDM_ASSERT(false);
     486            0 :         return false;
     487              :     }
     488              : }
     489              : 
     490            5 : bool libspdm_asym_get_public_key_from_der(uint32_t base_asym_algo,
     491              :                                           const uint8_t *der_data,
     492              :                                           size_t der_size,
     493              :                                           void **context)
     494              : {
     495            5 :     return libspdm_asym_get_public_key_from_der_wrap(base_asym_algo,
     496              :                                                      der_data,
     497              :                                                      der_size,
     498              :                                                      context);
     499              : }
     500              : 
     501              : /**
     502              :  * Return if asymmetric function need message hash.
     503              :  *
     504              :  * @param  base_asym_algo               SPDM base_asym_algo
     505              :  *
     506              :  * @retval true  asymmetric function need message hash
     507              :  * @retval false asymmetric function need raw message
     508              :  **/
     509          285 : static bool libspdm_asym_func_need_hash(uint32_t base_asym_algo)
     510              : {
     511          285 :     switch (base_asym_algo) {
     512           65 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     513              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     514              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     515              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
     516              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
     517              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
     518           65 :         return true;
     519          220 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
     520              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
     521              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
     522          220 :         return true;
     523            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     524              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     525              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
     526            0 :         return false;
     527            0 :     default:
     528            0 :         LIBSPDM_ASSERT(false);
     529            0 :         break;
     530              :     }
     531              : 
     532            0 :     return false;
     533              : }
     534              : 
     535              : /**
     536              :  * libspdm_copy_signature_swap_endian_rsa
     537              :  * Swaps the endianness of a RSA signature buffer. The ECDSA signature buffer is
     538              :  * actually single internal buffer and can be swapped as a single whole buffer.
     539              :  *
     540              :  * There are two known usage models for buffers for this function.
     541              :  * 1) Source and dest are the same (and their sizes).  This would be an in-place swap.
     542              :  * 2) Source and dest are completely different (and dest size >= src size). No overlap.
     543              :  *
     544              :  * The case where source and dest are overlapped (and not the exact same buffer)
     545              :  * is not allowed and guarded against with an assert.
     546              :  **/
     547           10 : static void libspdm_copy_signature_swap_endian_rsa(
     548              :     uint8_t* dst,
     549              :     size_t dst_size,
     550              :     const uint8_t* src,
     551              :     size_t src_size)
     552              : {
     553              :     /* RSA signature is a single buffer to be swapped */
     554              :     size_t i;
     555              : 
     556           10 :     if (src == dst) {
     557            4 :         LIBSPDM_ASSERT(dst_size == src_size);
     558              : 
     559              :         /* src and dst are same buffer. Swap in place. */
     560              : 
     561              :         uint8_t byte;
     562          516 :         for (i = 0; i < dst_size / 2; i++) {
     563          512 :             byte = dst[i];
     564          512 :             dst[i] = dst[dst_size - i - 1];
     565          512 :             dst[dst_size - i - 1] = byte;
     566              :         }
     567              :     } else {
     568              :         /* src and dst are different buffers.
     569              :          * Guard against overlap case with assert.
     570              :          * Overlap case is not an expected usage model. */
     571            6 :         LIBSPDM_ASSERT(dst_size >= src_size);
     572            6 :         LIBSPDM_ASSERT((src < dst && src + src_size <= dst) ||
     573              :                        (dst < src && dst + dst_size <= src));
     574              : 
     575         1542 :         for (i = 0; i < src_size; i++) {
     576         1536 :             dst[i] = src[src_size - i - 1];
     577              :         }
     578              :     }
     579           10 : }
     580              : 
     581              : /**
     582              :  * libspdm_copy_signature_swap_endian_ecdsa
     583              :  * Swaps the endianness of a ECDSA signature buffer. The ECDSA signature buffer is
     584              :  * actually two internal buffers, and each internal buffer must be swapped individually.
     585              :  *
     586              :  * There are two known usage models for buffers for this function.
     587              :  * 1) Source and dest are the same (and their sizes).  This would be an in-place swap.
     588              :  * 2) Source and dest are completely different (and dest size >= src size). No overlap.
     589              :  *
     590              :  * The case where source and dest are overlapped (and not the exact same buffer)
     591              :  * is not allowed and guarded against with an assert.
     592              :  **/
     593           10 : static void libspdm_copy_signature_swap_endian_ecdsa(
     594              :     uint8_t* dst,
     595              :     size_t dst_size,
     596              :     const uint8_t* src,
     597              :     size_t src_size)
     598              : {
     599              :     /* ECDSA signature is actually 2 buffers (x & y)
     600              :      * and each must be swapped individually */
     601              :     size_t i;
     602              : 
     603           10 :     if (src == dst) {
     604            4 :         LIBSPDM_ASSERT(dst_size == src_size);
     605              : 
     606              :         /* src and dst are same buffer. Swap ecdsa 2 internal buffers in place. */
     607              : 
     608              :         size_t x_size;
     609              :         size_t y_size;
     610              :         uint8_t* x;
     611              :         uint8_t* y;
     612              :         uint8_t byte;
     613              : 
     614            4 :         x_size = dst_size / 2;
     615            4 :         y_size = x_size;
     616              : 
     617            4 :         x = dst;
     618            4 :         y = x + x_size;
     619              : 
     620           68 :         for (i = 0; i < x_size / 2; i++) {
     621           64 :             byte = x[i];
     622           64 :             x[i] = x[x_size - i - 1];
     623           64 :             x[x_size - i - 1] = byte;
     624              :         }
     625              : 
     626           68 :         for (i = 0; i < y_size / 2; i++) {
     627           64 :             byte = y[i];
     628           64 :             y[i] = y[y_size - i - 1];
     629           64 :             y[y_size - i - 1] = byte;
     630              :         }
     631              :     } else {
     632              :         /* src and dst are different buffers.
     633              :          * Guard against overlap case with assert.
     634              :          * Overlap case is not an expected usage model. */
     635            6 :         LIBSPDM_ASSERT(dst_size >= src_size);
     636            6 :         LIBSPDM_ASSERT((src < dst && src + src_size <= dst) ||
     637              :                        (dst < src && dst + dst_size <= src));
     638              : 
     639              :         size_t x_size;
     640              :         size_t y_size;
     641              : 
     642              :         const uint8_t* src_x;
     643              :         const uint8_t* src_y;
     644              : 
     645              :         uint8_t* dst_x;
     646              :         uint8_t* dst_y;
     647              : 
     648            6 :         x_size = src_size / 2;
     649            6 :         y_size = x_size;
     650              : 
     651            6 :         src_x = src;
     652            6 :         src_y = src_x + x_size;
     653              : 
     654            6 :         dst_x = dst;
     655            6 :         dst_y = dst_x + x_size;
     656              : 
     657          198 :         for (i = 0; i < x_size; i++) {
     658          192 :             dst_x[i] = src_x[x_size - i - 1];
     659              :         }
     660              : 
     661          198 :         for (i = 0; i < y_size; i++) {
     662          192 :             dst_y[i] = src_y[y_size - i - 1];
     663              :         }
     664              :     }
     665           10 : }
     666              : 
     667           20 : void libspdm_copy_signature_swap_endian(
     668              :     uint32_t base_asym_algo,
     669              :     uint8_t* dst,
     670              :     size_t dst_size,
     671              :     const uint8_t* src,
     672              :     size_t src_size)
     673              : {
     674           20 :     const uint32_t spdm_10_11_rsa_algos =
     675              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 |
     676              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 |
     677              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 |
     678              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 |
     679              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 |
     680              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096;
     681              : 
     682           20 :     const uint32_t spdm_10_11_ecdsa_algos =
     683              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 |
     684              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 |
     685              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521;
     686              : 
     687           20 :     if (base_asym_algo & spdm_10_11_rsa_algos) {
     688           10 :         libspdm_copy_signature_swap_endian_rsa(dst, dst_size, src, src_size);
     689           10 :     } else if (base_asym_algo & spdm_10_11_ecdsa_algos) {
     690           10 :         libspdm_copy_signature_swap_endian_ecdsa(dst, dst_size, src, src_size);
     691              :     } else {
     692              :         /* Currently do not expect asymmetric algorithms other than RSA and ECDSA */
     693            0 :         LIBSPDM_ASSERT(0);
     694              :     }
     695           20 : }
     696              : 
     697              : /**
     698              :  * libspdm_is_palindrome
     699              :  * Checks to see if a buffer is a palindrome.
     700              :  * If the buffer is a palindrone, it is the same for both endians,
     701              :  * and therefore endianness cannot be determined.
     702              :  **/
     703           69 : bool libspdm_is_palindrome(const uint8_t* buf, size_t buf_size)
     704              : {
     705              :     size_t head;
     706              :     size_t tail;
     707              : 
     708           69 :     head = 0;
     709           69 :     tail = buf_size - 1;
     710              : 
     711          290 :     while (head < tail) {
     712          267 :         if (buf[head] != buf[tail]) {
     713           46 :             return false;
     714              :         }
     715          221 :         head++;
     716          221 :         tail--;
     717              :     }
     718              : 
     719           23 :     return true;
     720              : }
     721              : 
     722           52 : bool libspdm_is_signature_buffer_palindrome(
     723              :     uint32_t base_asym_algo, const uint8_t *buf, size_t buf_size)
     724              : {
     725           52 :     const uint32_t spdm_10_11_rsa_algos =
     726              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 |
     727              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 |
     728              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 |
     729              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 |
     730              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 |
     731              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096;
     732              : 
     733           52 :     const uint32_t spdm_10_11_ecdsa_algos =
     734              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 |
     735              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 |
     736              :         SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521;
     737              : 
     738           52 :     if (base_asym_algo & spdm_10_11_rsa_algos) {
     739           27 :         return libspdm_is_palindrome(buf, buf_size);
     740           25 :     } else if (base_asym_algo & spdm_10_11_ecdsa_algos) {
     741           25 :         const size_t x_size = buf_size / 2;
     742           25 :         const size_t y_size = x_size;
     743              : 
     744           25 :         const uint8_t *x = buf;
     745           25 :         const uint8_t *y = buf + x_size;
     746              : 
     747           25 :         return libspdm_is_palindrome(x, x_size) && libspdm_is_palindrome(y, y_size);
     748              :     } else {
     749              :         /* Currently do not expect asymmetric algorithms other than RSA and ECDSA */
     750            0 :         LIBSPDM_ASSERT(0);
     751            0 :         return false;
     752              :     }
     753              : }
     754              : 
     755              : #if LIBSPDM_RSA_SSA_SUPPORT
     756           30 : static bool libspdm_rsa_pkcs1_verify_with_nid_wrap (void *context, size_t hash_nid,
     757              :                                                     const uint8_t *param, size_t param_size,
     758              :                                                     const uint8_t *message,
     759              :                                                     size_t message_size,
     760              :                                                     const uint8_t *signature,
     761              :                                                     size_t sig_size)
     762              : {
     763           30 :     return libspdm_rsa_pkcs1_verify_with_nid (context, hash_nid,
     764              :                                               message, message_size, signature, sig_size);
     765              : }
     766              : #endif
     767              : 
     768              : #if LIBSPDM_RSA_PSS_SUPPORT
     769            0 : static bool libspdm_rsa_pss_verify_wrap (void *context, size_t hash_nid,
     770              :                                          const uint8_t *param, size_t param_size,
     771              :                                          const uint8_t *message,
     772              :                                          size_t message_size,
     773              :                                          const uint8_t *signature,
     774              :                                          size_t sig_size)
     775              : {
     776            0 :     return libspdm_rsa_pss_verify (context, hash_nid, message, message_size, signature, sig_size);
     777              : }
     778              : #endif
     779              : 
     780              : #if LIBSPDM_ECDSA_SUPPORT
     781           82 : bool libspdm_ecdsa_verify_wrap (void *context, size_t hash_nid,
     782              :                                 const uint8_t *param, size_t param_size,
     783              :                                 const uint8_t *message,
     784              :                                 size_t message_size,
     785              :                                 const uint8_t *signature,
     786              :                                 size_t sig_size)
     787              : {
     788           82 :     return libspdm_ecdsa_verify (context, hash_nid, message, message_size, signature, sig_size);
     789              : }
     790              : #endif
     791              : 
     792              : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
     793              : bool libspdm_eddsa_verify_wrap (void *context, size_t hash_nid,
     794              :                                 const uint8_t *param, size_t param_size,
     795              :                                 const uint8_t *message,
     796              :                                 size_t message_size,
     797              :                                 const uint8_t *signature,
     798              :                                 size_t sig_size)
     799              : {
     800              :     return libspdm_eddsa_verify (context, hash_nid, param, param_size,
     801              :                                  message, message_size, signature, sig_size);
     802              : }
     803              : #endif
     804              : 
     805              : #if LIBSPDM_SM2_DSA_SUPPORT
     806              : bool libspdm_sm2_dsa_verify_wrap (void *context, size_t hash_nid,
     807              :                                   const uint8_t *param, size_t param_size,
     808              :                                   const uint8_t *message,
     809              :                                   size_t message_size,
     810              :                                   const uint8_t *signature,
     811              :                                   size_t sig_size)
     812              : {
     813              :     return libspdm_sm2_dsa_verify (context, hash_nid, param, param_size,
     814              :                                    message, message_size, signature, sig_size);
     815              : }
     816              : #endif
     817              : 
     818          112 : static bool libspdm_asym_verify_wrap(
     819              :     void *context, size_t hash_nid, uint32_t base_asym_algo,
     820              :     const uint8_t *param, size_t param_size,
     821              :     const uint8_t *message, size_t message_size,
     822              :     const uint8_t *signature, size_t sig_size)
     823              : {
     824          112 :     switch (base_asym_algo) {
     825           30 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     826              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     827              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     828              : #if LIBSPDM_RSA_SSA_SUPPORT
     829              : #if !LIBSPDM_RSA_SSA_2048_SUPPORT
     830              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048);
     831              : #endif
     832              : #if !LIBSPDM_RSA_SSA_3072_SUPPORT
     833              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072);
     834              : #endif
     835              : #if !LIBSPDM_RSA_SSA_4096_SUPPORT
     836              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096);
     837              : #endif
     838           30 :         return libspdm_rsa_pkcs1_verify_with_nid_wrap(context, hash_nid,
     839              :                                                       param, param_size,
     840              :                                                       message, message_size,
     841              :                                                       signature, sig_size);
     842              : #else
     843              :         LIBSPDM_ASSERT(false);
     844              :         return false;
     845              : #endif
     846            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
     847              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
     848              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
     849              : #if LIBSPDM_RSA_PSS_SUPPORT
     850              : #if !LIBSPDM_RSA_PSS_2048_SUPPORT
     851              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048);
     852              : #endif
     853              : #if !LIBSPDM_RSA_PSS_3072_SUPPORT
     854              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072);
     855              : #endif
     856              : #if !LIBSPDM_RSA_PSS_4096_SUPPORT
     857              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096);
     858              : #endif
     859            0 :         return libspdm_rsa_pss_verify_wrap(context, hash_nid,
     860              :                                            param, param_size,
     861              :                                            message, message_size,
     862              :                                            signature, sig_size);
     863              : #else
     864              :         LIBSPDM_ASSERT(false);
     865              :         return false;
     866              : #endif
     867           82 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
     868              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
     869              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
     870              : #if LIBSPDM_ECDSA_SUPPORT
     871              : #if !LIBSPDM_ECDSA_P256_SUPPORT
     872              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256);
     873              : #endif
     874              : #if !LIBSPDM_ECDSA_P384_SUPPORT
     875              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384);
     876              : #endif
     877              : #if !LIBSPDM_ECDSA_P521_SUPPORT
     878              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521);
     879              : #endif
     880           82 :         return libspdm_ecdsa_verify_wrap(context, hash_nid,
     881              :                                          param, param_size,
     882              :                                          message, message_size,
     883              :                                          signature, sig_size);
     884              : #else
     885              :         LIBSPDM_ASSERT(false);
     886              :         return false;
     887              : #endif
     888            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     889              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     890              : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
     891              : #if !LIBSPDM_EDDSA_ED25519_SUPPORT
     892              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519);
     893              : #endif
     894              : #if !LIBSPDM_EDDSA_ED448_SUPPORT
     895              :         LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448);
     896              : #endif
     897              :         return libspdm_eddsa_verify_wrap(context, hash_nid,
     898              :                                          param, param_size,
     899              :                                          message, message_size,
     900              :                                          signature, sig_size);
     901              : #else
     902            0 :         LIBSPDM_ASSERT(false);
     903            0 :         return false;
     904              : #endif
     905            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
     906              : #if LIBSPDM_SM2_DSA_SUPPORT
     907              :         return libspdm_sm2_dsa_verify_wrap(context, hash_nid,
     908              :                                            param, param_size,
     909              :                                            message, message_size,
     910              :                                            signature, sig_size);
     911              : #else
     912            0 :         LIBSPDM_ASSERT(false);
     913            0 :         return false;
     914              : #endif
     915            0 :     default:
     916            0 :         LIBSPDM_ASSERT(false);
     917            0 :         return false;
     918              :     }
     919              : }
     920              : 
     921            0 : bool libspdm_asym_verify_ex(
     922              :     spdm_version_number_t spdm_version, uint8_t op_code,
     923              :     uint32_t base_asym_algo, uint32_t base_hash_algo,
     924              :     void *context,
     925              :     const uint8_t *message, size_t message_size,
     926              :     const uint8_t *signature, size_t sig_size,
     927              :     uint8_t *endian)
     928              : {
     929              :     bool need_hash;
     930              :     uint8_t message_hash[LIBSPDM_MAX_HASH_SIZE];
     931              :     size_t hash_size;
     932              :     bool result;
     933              :     size_t hash_nid;
     934              :     uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
     935              :                                              LIBSPDM_MAX_HASH_SIZE];
     936              :     const void *param;
     937              :     size_t param_size;
     938              : 
     939              :     bool try_big_endian;
     940              :     bool try_little_endian;
     941              :     bool little_endian_succeeded;
     942              :     uint8_t endian_swapped_signature[LIBSPDM_MAX_ASYM_SIG_SIZE];
     943              : 
     944            0 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
     945            0 :     need_hash = libspdm_asym_func_need_hash(base_asym_algo);
     946              : 
     947            0 :     param = NULL;
     948            0 :     param_size = 0;
     949              : 
     950            0 :     if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
     951              :         /* Need use SPDM 1.2 signing. */
     952            0 :         switch (base_asym_algo) {
     953            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
     954            0 :             param = "";
     955            0 :             param_size = 0;
     956            0 :             break;
     957            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     958            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
     959            0 :             break;
     960            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     961            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
     962            0 :             param = libspdm_get_signing_context_string (spdm_version, op_code, false, &param_size);
     963            0 :             break;
     964            0 :         default:
     965              :             /* pass thru for rest algorithm */
     966            0 :             break;
     967              :         }
     968              : 
     969            0 :         libspdm_create_signing_context (spdm_version, op_code, false,
     970              :                                         spdm12_signing_context_with_hash);
     971            0 :         hash_size = libspdm_get_hash_size(base_hash_algo);
     972            0 :         result = libspdm_hash_all(base_hash_algo, message, message_size,
     973              :                                   &spdm12_signing_context_with_hash[
     974              :                                       SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]);
     975            0 :         if (!result) {
     976            0 :             return false;
     977              :         }
     978              : 
     979              :         /* re-assign message and message_size for signing */
     980            0 :         message = spdm12_signing_context_with_hash;
     981            0 :         message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
     982            0 :         try_big_endian = true;
     983            0 :         try_little_endian = false;
     984            0 :         little_endian_succeeded = false;
     985              :         /* Passthru */
     986              :     } else {
     987            0 :         try_big_endian =
     988            0 :             (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY
     989            0 :              || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
     990              : 
     991            0 :         try_little_endian =
     992            0 :             (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY
     993            0 :              || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
     994              : 
     995            0 :         little_endian_succeeded = false;
     996              :     }
     997              : 
     998            0 :     if (need_hash) {
     999            0 :         hash_size = libspdm_get_hash_size(base_hash_algo);
    1000            0 :         result = libspdm_hash_all(base_hash_algo, message, message_size, message_hash);
    1001            0 :         if (!result) {
    1002            0 :             return false;
    1003              :         }
    1004            0 :         result = false;
    1005            0 :         if (try_big_endian) {
    1006            0 :             result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
    1007              :                                               param, param_size,
    1008              :                                               message_hash, hash_size,
    1009              :                                               signature, sig_size);
    1010              :         }
    1011            0 :         if (!result && try_little_endian) {
    1012            0 :             libspdm_copy_signature_swap_endian(
    1013              :                 base_asym_algo,
    1014              :                 endian_swapped_signature, sizeof(endian_swapped_signature),
    1015              :                 signature, sig_size);
    1016              : 
    1017            0 :             result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
    1018              :                                               param, param_size,
    1019              :                                               message_hash, hash_size,
    1020              :                                               endian_swapped_signature, sig_size);
    1021            0 :             little_endian_succeeded = result;
    1022              :         }
    1023              :     } else {
    1024            0 :         result = false;
    1025            0 :         if (try_big_endian) {
    1026            0 :             result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
    1027              :                                               param, param_size,
    1028              :                                               message, message_size,
    1029              :                                               signature, sig_size);
    1030              :         }
    1031            0 :         if (!result && try_little_endian) {
    1032            0 :             libspdm_copy_signature_swap_endian(
    1033              :                 base_asym_algo,
    1034              :                 endian_swapped_signature, sizeof(endian_swapped_signature),
    1035              :                 signature, sig_size);
    1036              : 
    1037            0 :             result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
    1038              :                                               param, param_size,
    1039              :                                               message, message_size,
    1040              :                                               endian_swapped_signature, sig_size);
    1041            0 :             little_endian_succeeded = result;
    1042              :         }
    1043              :     }
    1044            0 :     if (try_big_endian && try_little_endian && result) {
    1045            0 :         if (!libspdm_is_signature_buffer_palindrome(base_asym_algo, signature, sig_size)) {
    1046            0 :             if (little_endian_succeeded) {
    1047            0 :                 *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY;
    1048              :             } else {
    1049            0 :                 *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
    1050              :             }
    1051              :         }
    1052              :     }
    1053            0 :     return result;
    1054              : }
    1055              : 
    1056              : 
    1057           80 : bool libspdm_asym_verify_hash_ex(
    1058              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1059              :     uint32_t base_asym_algo, uint32_t base_hash_algo,
    1060              :     void *context, const uint8_t *message_hash,
    1061              :     size_t hash_size, const uint8_t *signature,
    1062              :     size_t sig_size, uint8_t *endian)
    1063              : {
    1064              :     bool need_hash;
    1065              :     uint8_t *message;
    1066              :     size_t message_size;
    1067              :     uint8_t full_message_hash[LIBSPDM_MAX_HASH_SIZE];
    1068              :     bool result;
    1069              :     size_t hash_nid;
    1070              :     uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
    1071              :                                              LIBSPDM_MAX_HASH_SIZE];
    1072              :     const void *param;
    1073              :     size_t param_size;
    1074              : 
    1075              :     bool try_big_endian;
    1076              :     bool try_little_endian;
    1077              :     bool little_endian_succeeded;
    1078              :     uint8_t endian_swapped_signature[LIBSPDM_MAX_ASYM_SIG_SIZE];
    1079              : 
    1080           80 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
    1081           80 :     need_hash = libspdm_asym_func_need_hash(base_asym_algo);
    1082           80 :     LIBSPDM_ASSERT (hash_size == libspdm_get_hash_size(base_hash_algo));
    1083              : 
    1084           80 :     param = NULL;
    1085           80 :     param_size = 0;
    1086           80 :     try_big_endian = true;
    1087           80 :     try_little_endian = false;
    1088           80 :     little_endian_succeeded = false;
    1089              : 
    1090           80 :     if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
    1091              :         /* Need use SPDM 1.2 signing */
    1092           22 :         switch (base_asym_algo) {
    1093            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
    1094            0 :             param = "";
    1095            0 :             param_size = 0;
    1096            0 :             break;
    1097            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
    1098            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1099            0 :             break;
    1100            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
    1101            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1102            0 :             param = libspdm_get_signing_context_string (spdm_version, op_code, false, &param_size);
    1103            0 :             break;
    1104           22 :         default:
    1105              :             /* pass thru for rest algorithm */
    1106           22 :             break;
    1107              :         }
    1108              : 
    1109           22 :         libspdm_create_signing_context (spdm_version, op_code, false,
    1110              :                                         spdm12_signing_context_with_hash);
    1111           22 :         libspdm_copy_mem(&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE],
    1112              :                          sizeof(spdm12_signing_context_with_hash)
    1113              :                          - (&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]
    1114              :                             - spdm12_signing_context_with_hash),
    1115              :                          message_hash, hash_size);
    1116              : 
    1117              :         /* assign message and message_size for signing */
    1118           22 :         message = spdm12_signing_context_with_hash;
    1119           22 :         message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
    1120              : 
    1121           22 :         if (need_hash) {
    1122           22 :             result = libspdm_hash_all(base_hash_algo, message, message_size, full_message_hash);
    1123           22 :             if (!result) {
    1124            0 :                 return false;
    1125              :             }
    1126           22 :             return libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
    1127              :                                             param, param_size,
    1128              :                                             full_message_hash, hash_size,
    1129              :                                             signature, sig_size);
    1130              :         } else {
    1131            0 :             return libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
    1132              :                                             param, param_size,
    1133              :                                             message, message_size,
    1134              :                                             signature, sig_size);
    1135              :         }
    1136              :         /* SPDM 1.2 signing done. */
    1137              :     } else {
    1138           58 :         try_big_endian =
    1139           58 :             (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY
    1140           58 :              || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
    1141              : 
    1142           58 :         try_little_endian =
    1143           58 :             (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY
    1144           58 :              || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
    1145              : 
    1146           58 :         little_endian_succeeded = false;
    1147              :     }
    1148              : 
    1149           58 :     if (need_hash) {
    1150           58 :         result = false;
    1151           58 :         if (try_big_endian) {
    1152           54 :             result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
    1153              :                                               param, param_size,
    1154              :                                               message_hash, hash_size,
    1155              :                                               signature, sig_size);
    1156              :         }
    1157           58 :         if (!result && try_little_endian) {
    1158            6 :             libspdm_copy_signature_swap_endian(
    1159              :                 base_asym_algo,
    1160              :                 endian_swapped_signature, sizeof(endian_swapped_signature),
    1161              :                 signature, sig_size);
    1162              : 
    1163            6 :             result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
    1164              :                                               param, param_size,
    1165              :                                               message_hash, hash_size,
    1166              :                                               endian_swapped_signature, sig_size);
    1167            6 :             little_endian_succeeded = result;
    1168              :         }
    1169           58 :         if (try_big_endian && try_little_endian && result) {
    1170            4 :             if (!libspdm_is_signature_buffer_palindrome(base_asym_algo, signature, sig_size)) {
    1171            4 :                 if (little_endian_succeeded) {
    1172            2 :                     *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY;
    1173              :                 } else {
    1174            2 :                     *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
    1175              :                 }
    1176              :             }
    1177              :         }
    1178           58 :         return result;
    1179              : 
    1180              :     } else {
    1181            0 :         LIBSPDM_ASSERT(false);
    1182            0 :         return false;
    1183              :     }
    1184              : }
    1185              : 
    1186            0 : bool libspdm_asym_verify(
    1187              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1188              :     uint32_t base_asym_algo, uint32_t base_hash_algo,
    1189              :     void* context, const uint8_t* message,
    1190              :     size_t message_size, const uint8_t* signature,
    1191              :     size_t sig_size)
    1192              : {
    1193            0 :     uint8_t endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
    1194            0 :     return libspdm_asym_verify_ex(
    1195              :         spdm_version, op_code, base_asym_algo, base_hash_algo,
    1196              :         context, message, message_size, signature, sig_size, &endian);
    1197              : }
    1198              : 
    1199            0 : bool libspdm_asym_verify_hash(
    1200              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1201              :     uint32_t base_asym_algo, uint32_t base_hash_algo,
    1202              :     void* context, const uint8_t* message_hash,
    1203              :     size_t hash_size, const uint8_t* signature,
    1204              :     size_t sig_size)
    1205              : {
    1206            0 :     uint8_t endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
    1207            0 :     return libspdm_asym_verify_hash_ex(
    1208              :         spdm_version, op_code, base_asym_algo, base_hash_algo,
    1209              :         context, message_hash, hash_size, signature, sig_size, &endian);
    1210              : }
    1211              : 
    1212           99 : bool libspdm_asym_sign(
    1213              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1214              :     uint32_t base_asym_algo, uint32_t base_hash_algo,
    1215              :     void *context, const uint8_t *message,
    1216              :     size_t message_size, uint8_t *signature,
    1217              :     size_t *sig_size)
    1218              : {
    1219              :     bool need_hash;
    1220              :     uint8_t message_hash[LIBSPDM_MAX_HASH_SIZE];
    1221              :     size_t hash_size;
    1222              :     bool result;
    1223              :     size_t hash_nid;
    1224              :     uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
    1225              :                                              LIBSPDM_MAX_HASH_SIZE];
    1226              :     const void *param;
    1227              :     size_t param_size;
    1228              : 
    1229           99 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
    1230           99 :     need_hash = libspdm_asym_func_need_hash(base_asym_algo);
    1231              : 
    1232           99 :     param = NULL;
    1233           99 :     param_size = 0;
    1234              : 
    1235           99 :     if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
    1236              :         /* Need use SPDM 1.2 signing */
    1237           23 :         switch (base_asym_algo) {
    1238            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
    1239            0 :             param = "";
    1240            0 :             param_size = 0;
    1241            0 :             break;
    1242            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
    1243            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1244            0 :             break;
    1245            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
    1246            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1247            0 :             param = libspdm_get_signing_context_string (spdm_version, op_code, false, &param_size);
    1248            0 :             break;
    1249           23 :         default:
    1250              :             /* pass thru for rest algorithm */
    1251           23 :             break;
    1252              :         }
    1253              : 
    1254           23 :         libspdm_create_signing_context (spdm_version, op_code, false,
    1255              :                                         spdm12_signing_context_with_hash);
    1256           23 :         hash_size = libspdm_get_hash_size(base_hash_algo);
    1257           23 :         result = libspdm_hash_all(base_hash_algo, message, message_size,
    1258              :                                   &spdm12_signing_context_with_hash[
    1259              :                                       SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]);
    1260           23 :         if (!result) {
    1261            0 :             return false;
    1262              :         }
    1263              : 
    1264              :         /* re-assign message and message_size for signing */
    1265           23 :         message = spdm12_signing_context_with_hash;
    1266           23 :         message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
    1267              : 
    1268              :         /* Passthru*/
    1269              :     }
    1270              : 
    1271           99 :     if (need_hash) {
    1272           99 :         hash_size = libspdm_get_hash_size(base_hash_algo);
    1273           99 :         result = libspdm_hash_all(base_hash_algo, message, message_size, message_hash);
    1274           99 :         if (!result) {
    1275            0 :             return false;
    1276              :         }
    1277           99 :         return libspdm_asym_sign_wrap(context, hash_nid, base_asym_algo,
    1278              :                                       param, param_size,
    1279              :                                       message_hash, hash_size,
    1280              :                                       signature, sig_size);
    1281              :     } else {
    1282            0 :         return libspdm_asym_sign_wrap(context, hash_nid, base_asym_algo,
    1283              :                                       param, param_size,
    1284              :                                       message, message_size,
    1285              :                                       signature, sig_size);
    1286              :     }
    1287              : }
    1288              : 
    1289           41 : bool libspdm_asym_sign_hash(
    1290              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1291              :     uint32_t base_asym_algo, uint32_t base_hash_algo,
    1292              :     void *context, const uint8_t *message_hash,
    1293              :     size_t hash_size, uint8_t *signature,
    1294              :     size_t *sig_size)
    1295              : {
    1296              :     bool need_hash;
    1297              :     uint8_t *message;
    1298              :     size_t message_size;
    1299              :     uint8_t full_message_hash[LIBSPDM_MAX_HASH_SIZE];
    1300              :     bool result;
    1301              :     size_t hash_nid;
    1302              :     uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
    1303              :                                              LIBSPDM_MAX_HASH_SIZE];
    1304              :     const void *param;
    1305              :     size_t param_size;
    1306              : 
    1307           41 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
    1308           41 :     need_hash = libspdm_asym_func_need_hash(base_asym_algo);
    1309           41 :     LIBSPDM_ASSERT (hash_size == libspdm_get_hash_size(base_hash_algo));
    1310              : 
    1311           41 :     param = NULL;
    1312           41 :     param_size = 0;
    1313              : 
    1314           41 :     if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
    1315              :         /* Need use SPDM 1.2 signing */
    1316           13 :         switch (base_asym_algo) {
    1317            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
    1318            0 :             param = "";
    1319            0 :             param_size = 0;
    1320            0 :             break;
    1321            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
    1322            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1323            0 :             break;
    1324            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
    1325            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1326            0 :             param = libspdm_get_signing_context_string (spdm_version, op_code, false, &param_size);
    1327            0 :             break;
    1328           13 :         default:
    1329              :             /* pass thru for rest algorithm */
    1330           13 :             break;
    1331              :         }
    1332              : 
    1333           13 :         libspdm_create_signing_context (spdm_version, op_code, false,
    1334              :                                         spdm12_signing_context_with_hash);
    1335           13 :         libspdm_copy_mem(&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE],
    1336              :                          sizeof(spdm12_signing_context_with_hash)
    1337              :                          - (&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]
    1338              :                             - spdm12_signing_context_with_hash),
    1339              :                          message_hash, hash_size);
    1340              : 
    1341              :         /* assign message and message_size for signing */
    1342           13 :         message = spdm12_signing_context_with_hash;
    1343           13 :         message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
    1344              : 
    1345           13 :         if (need_hash) {
    1346           13 :             result = libspdm_hash_all(base_hash_algo, message, message_size, full_message_hash);
    1347           13 :             if (!result) {
    1348            0 :                 return false;
    1349              :             }
    1350           13 :             return libspdm_asym_sign_wrap(context, hash_nid, base_asym_algo,
    1351              :                                           param, param_size,
    1352              :                                           full_message_hash, hash_size,
    1353              :                                           signature, sig_size);
    1354              :         } else {
    1355            0 :             return libspdm_asym_sign_wrap(context, hash_nid, base_asym_algo,
    1356              :                                           param, param_size,
    1357              :                                           message, message_size,
    1358              :                                           signature, sig_size);
    1359              :         }
    1360              : 
    1361              :         /* SPDM 1.2 signing done. */
    1362              :     }
    1363              : 
    1364           28 :     if (need_hash) {
    1365           28 :         return libspdm_asym_sign_wrap(context, hash_nid, base_asym_algo,
    1366              :                                       param, param_size,
    1367              :                                       message_hash, hash_size,
    1368              :                                       signature, sig_size);
    1369              :     } else {
    1370            0 :         LIBSPDM_ASSERT (false);
    1371            0 :         return false;
    1372              :     }
    1373              : }
    1374              : 
    1375           97 : uint32_t libspdm_get_req_asym_signature_size(uint16_t req_base_asym_alg)
    1376              : {
    1377           97 :     return libspdm_get_asym_signature_size(req_base_asym_alg);
    1378              : }
    1379              : 
    1380           40 : void libspdm_req_asym_free(uint16_t req_base_asym_alg, void *context)
    1381              : {
    1382           40 :     libspdm_asym_free(req_base_asym_alg, context);
    1383           40 : }
    1384              : 
    1385            5 : bool libspdm_req_asym_get_public_key_from_der(uint16_t req_base_asym_alg,
    1386              :                                               const uint8_t *der_data,
    1387              :                                               size_t der_size,
    1388              :                                               void **context)
    1389              : {
    1390            5 :     return libspdm_asym_get_public_key_from_der_wrap(req_base_asym_alg,
    1391              :                                                      der_data,
    1392              :                                                      der_size,
    1393              :                                                      context);
    1394              : }
    1395              : 
    1396           65 : bool libspdm_req_asym_func_need_hash(uint16_t req_base_asym_alg)
    1397              : {
    1398           65 :     return libspdm_asym_func_need_hash(req_base_asym_alg);
    1399              : }
    1400              : 
    1401            0 : bool libspdm_req_asym_verify_ex(
    1402              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1403              :     uint16_t req_base_asym_alg,
    1404              :     uint32_t base_hash_algo, void *context,
    1405              :     const uint8_t *message, size_t message_size,
    1406              :     const uint8_t *signature, size_t sig_size, uint8_t *endian)
    1407              : {
    1408              :     bool need_hash;
    1409              :     uint8_t message_hash[LIBSPDM_MAX_HASH_SIZE];
    1410              :     size_t hash_size;
    1411              :     bool result;
    1412              :     size_t hash_nid;
    1413              :     uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
    1414              :                                              LIBSPDM_MAX_HASH_SIZE];
    1415              :     const void *param;
    1416              :     size_t param_size;
    1417              : 
    1418              :     bool try_big_endian;
    1419              :     bool try_little_endian;
    1420              :     bool little_endian_succeeded;
    1421              :     uint8_t endian_swapped_signature[LIBSPDM_MAX_ASYM_SIG_SIZE];
    1422              : 
    1423            0 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
    1424            0 :     need_hash = libspdm_req_asym_func_need_hash(req_base_asym_alg);
    1425              : 
    1426            0 :     param = NULL;
    1427            0 :     param_size = 0;
    1428              : 
    1429            0 :     if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
    1430              :         /* Need use SPDM 1.2 signing */
    1431            0 :         switch (req_base_asym_alg) {
    1432            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
    1433            0 :             param = "";
    1434            0 :             param_size = 0;
    1435            0 :             break;
    1436            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
    1437            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1438            0 :             break;
    1439            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
    1440            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1441            0 :             param = libspdm_get_signing_context_string (spdm_version, op_code, true, &param_size);
    1442            0 :             break;
    1443            0 :         default:
    1444              :             /* pass thru for rest algorithm */
    1445            0 :             break;
    1446              :         }
    1447              : 
    1448            0 :         libspdm_create_signing_context (spdm_version, op_code, true,
    1449              :                                         spdm12_signing_context_with_hash);
    1450            0 :         hash_size = libspdm_get_hash_size(base_hash_algo);
    1451            0 :         result = libspdm_hash_all(base_hash_algo, message, message_size,
    1452              :                                   &spdm12_signing_context_with_hash[
    1453              :                                       SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]);
    1454            0 :         if (!result) {
    1455            0 :             return false;
    1456              :         }
    1457              : 
    1458              :         /* re-assign message and message_size for signing */
    1459            0 :         message = spdm12_signing_context_with_hash;
    1460            0 :         message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
    1461            0 :         try_big_endian = true;
    1462            0 :         try_little_endian = false;
    1463            0 :         little_endian_succeeded = false;
    1464              :         /* Passthru */
    1465              :     } else {
    1466            0 :         try_big_endian =
    1467            0 :             (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY
    1468            0 :              || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
    1469              : 
    1470            0 :         try_little_endian =
    1471            0 :             (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY
    1472            0 :              || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
    1473              : 
    1474            0 :         little_endian_succeeded = false;
    1475              :     }
    1476              : 
    1477            0 :     if (need_hash) {
    1478            0 :         hash_size = libspdm_get_hash_size(base_hash_algo);
    1479            0 :         result = libspdm_hash_all(base_hash_algo, message, message_size, message_hash);
    1480            0 :         if (!result) {
    1481            0 :             return false;
    1482              :         }
    1483            0 :         result = false;
    1484            0 :         if (try_big_endian) {
    1485            0 :             result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
    1486              :                                               param, param_size,
    1487              :                                               message_hash, hash_size,
    1488              :                                               signature, sig_size);
    1489              :         }
    1490            0 :         if (!result && try_little_endian) {
    1491            0 :             libspdm_copy_signature_swap_endian(
    1492              :                 req_base_asym_alg,
    1493              :                 endian_swapped_signature, sizeof(endian_swapped_signature),
    1494              :                 signature, sig_size);
    1495              : 
    1496            0 :             result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
    1497              :                                               param, param_size,
    1498              :                                               message_hash, hash_size,
    1499              :                                               endian_swapped_signature, sig_size);
    1500            0 :             little_endian_succeeded = result;
    1501              :         }
    1502              :     } else {
    1503            0 :         result = false;
    1504            0 :         if (try_big_endian) {
    1505            0 :             result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
    1506              :                                               param, param_size,
    1507              :                                               message, message_size,
    1508              :                                               signature, sig_size);
    1509              :         }
    1510            0 :         if (!result && try_little_endian) {
    1511            0 :             libspdm_copy_signature_swap_endian(
    1512              :                 req_base_asym_alg,
    1513              :                 endian_swapped_signature, sizeof(endian_swapped_signature),
    1514              :                 signature, sig_size);
    1515              : 
    1516            0 :             result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
    1517              :                                               param, param_size,
    1518              :                                               message, message_size,
    1519              :                                               endian_swapped_signature, sig_size);
    1520            0 :             little_endian_succeeded = result;
    1521              :         }
    1522              :     }
    1523            0 :     if (try_big_endian && try_little_endian && result) {
    1524            0 :         if (!libspdm_is_signature_buffer_palindrome(req_base_asym_alg, signature, sig_size)) {
    1525            0 :             if (little_endian_succeeded) {
    1526            0 :                 *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY;
    1527              :             } else {
    1528            0 :                 *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
    1529              :             }
    1530              :         }
    1531              :     }
    1532            0 :     return result;
    1533              : }
    1534              : 
    1535           29 : bool libspdm_req_asym_verify_hash_ex(
    1536              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1537              :     uint16_t req_base_asym_alg,
    1538              :     uint32_t base_hash_algo, void *context,
    1539              :     const uint8_t *message_hash, size_t hash_size,
    1540              :     const uint8_t *signature, size_t sig_size, uint8_t *endian)
    1541              : {
    1542              :     bool need_hash;
    1543              :     uint8_t *message;
    1544              :     size_t message_size;
    1545              :     uint8_t full_message_hash[LIBSPDM_MAX_HASH_SIZE];
    1546              :     bool result;
    1547              :     size_t hash_nid;
    1548              :     uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
    1549              :                                              LIBSPDM_MAX_HASH_SIZE];
    1550              :     const void *param;
    1551              :     size_t param_size;
    1552              : 
    1553              :     bool try_big_endian;
    1554              :     bool try_little_endian;
    1555              :     bool little_endian_succeeded;
    1556              :     uint8_t endian_swapped_signature[LIBSPDM_MAX_ASYM_SIG_SIZE];
    1557              : 
    1558           29 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
    1559           29 :     need_hash = libspdm_req_asym_func_need_hash(req_base_asym_alg);
    1560           29 :     LIBSPDM_ASSERT (hash_size == libspdm_get_hash_size(base_hash_algo));
    1561              : 
    1562           29 :     param = NULL;
    1563           29 :     param_size = 0;
    1564              : 
    1565           29 :     if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
    1566              :         /* Need use SPDM 1.2 signing */
    1567           10 :         switch (req_base_asym_alg) {
    1568            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
    1569            0 :             param = "";
    1570            0 :             param_size = 0;
    1571            0 :             break;
    1572            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
    1573            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1574            0 :             break;
    1575            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
    1576            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1577            0 :             param = libspdm_get_signing_context_string (spdm_version, op_code, true, &param_size);
    1578            0 :             break;
    1579           10 :         default:
    1580              :             /* pass thru for rest algorithm */
    1581           10 :             break;
    1582              :         }
    1583              : 
    1584           10 :         libspdm_create_signing_context (spdm_version, op_code, true,
    1585              :                                         spdm12_signing_context_with_hash);
    1586           10 :         libspdm_copy_mem(&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE],
    1587              :                          sizeof(spdm12_signing_context_with_hash)
    1588              :                          - (&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]
    1589              :                             - spdm12_signing_context_with_hash),
    1590              :                          message_hash, hash_size);
    1591              : 
    1592              :         /* assign message and message_size for signing */
    1593           10 :         message = spdm12_signing_context_with_hash;
    1594           10 :         message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
    1595              : 
    1596           10 :         if (need_hash) {
    1597           10 :             result = libspdm_hash_all(base_hash_algo, message, message_size,
    1598              :                                       full_message_hash);
    1599           10 :             if (!result) {
    1600            0 :                 return false;
    1601              :             }
    1602           10 :             return libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
    1603              :                                             param, param_size,
    1604              :                                             full_message_hash, hash_size,
    1605              :                                             signature, sig_size);
    1606              :         } else {
    1607            0 :             return libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
    1608              :                                             param, param_size,
    1609              :                                             message, message_size,
    1610              :                                             signature, sig_size);
    1611              :         }
    1612              :         /* SPDM 1.2 signing done. */
    1613              :     } else {
    1614           19 :         try_big_endian =
    1615           19 :             (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY
    1616           19 :              || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
    1617              : 
    1618           19 :         try_little_endian =
    1619           19 :             (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY
    1620           19 :              || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
    1621              : 
    1622           19 :         little_endian_succeeded = false;
    1623              :     }
    1624              : 
    1625           19 :     if (need_hash) {
    1626           19 :         result = false;
    1627           19 :         if (try_big_endian) {
    1628           14 :             result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
    1629              :                                               param, param_size,
    1630              :                                               message_hash, hash_size,
    1631              :                                               signature, sig_size);
    1632              :         }
    1633           19 :         if (!result && try_little_endian) {
    1634            6 :             libspdm_copy_signature_swap_endian(
    1635              :                 req_base_asym_alg,
    1636              :                 endian_swapped_signature, sizeof(endian_swapped_signature),
    1637              :                 signature, sig_size);
    1638              : 
    1639            6 :             result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
    1640              :                                               param, param_size,
    1641              :                                               message_hash, hash_size,
    1642              :                                               endian_swapped_signature, sig_size);
    1643            6 :             little_endian_succeeded = result;
    1644              :         }
    1645           19 :         if (try_big_endian && try_little_endian && result) {
    1646            3 :             if (!libspdm_is_signature_buffer_palindrome(req_base_asym_alg, signature, sig_size)) {
    1647            3 :                 if (little_endian_succeeded) {
    1648            1 :                     *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY;
    1649              :                 } else {
    1650            2 :                     *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
    1651              :                 }
    1652              :             }
    1653              :         }
    1654           19 :         return result;
    1655              :     } else {
    1656            0 :         LIBSPDM_ASSERT (false);
    1657            0 :         return false;
    1658              :     }
    1659              : }
    1660              : 
    1661            0 : bool libspdm_req_asym_verify(
    1662              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1663              :     uint16_t req_base_asym_alg,
    1664              :     uint32_t base_hash_algo, void* context,
    1665              :     const uint8_t* message, size_t message_size,
    1666              :     const uint8_t* signature, size_t sig_size)
    1667              : {
    1668            0 :     uint8_t endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
    1669            0 :     return libspdm_req_asym_verify_ex(
    1670              :         spdm_version, op_code, req_base_asym_alg, base_hash_algo, context,
    1671              :         message, message_size, signature, sig_size, &endian);
    1672              : }
    1673              : 
    1674            0 : bool libspdm_req_asym_verify_hash(
    1675              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1676              :     uint16_t req_base_asym_alg,
    1677              :     uint32_t base_hash_algo, void* context,
    1678              :     const uint8_t* message_hash, size_t hash_size,
    1679              :     const uint8_t* signature, size_t sig_size)
    1680              : {
    1681            0 :     uint8_t endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
    1682            0 :     return libspdm_req_asym_verify_hash_ex(
    1683              :         spdm_version, op_code, req_base_asym_alg, base_hash_algo, context,
    1684              :         message_hash, hash_size, signature, sig_size, &endian);
    1685              : }
    1686              : 
    1687           22 : bool libspdm_req_asym_sign(
    1688              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1689              :     uint16_t req_base_asym_alg,
    1690              :     uint32_t base_hash_algo, void *context,
    1691              :     const uint8_t *message, size_t message_size,
    1692              :     uint8_t *signature, size_t *sig_size)
    1693              : {
    1694              :     bool need_hash;
    1695              :     uint8_t message_hash[LIBSPDM_MAX_HASH_SIZE];
    1696              :     size_t hash_size;
    1697              :     bool result;
    1698              :     size_t hash_nid;
    1699              :     uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
    1700              :                                              LIBSPDM_MAX_HASH_SIZE];
    1701              :     const void *param;
    1702              :     size_t param_size;
    1703              : 
    1704           22 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
    1705           22 :     need_hash = libspdm_req_asym_func_need_hash(req_base_asym_alg);
    1706              : 
    1707           22 :     param = NULL;
    1708           22 :     param_size = 0;
    1709              : 
    1710           22 :     if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
    1711              :         /* Need use SPDM 1.2 signing */
    1712            7 :         switch (req_base_asym_alg) {
    1713            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
    1714            0 :             param = "";
    1715            0 :             param_size = 0;
    1716            0 :             break;
    1717            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
    1718            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1719            0 :             break;
    1720            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
    1721            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1722            0 :             param = libspdm_get_signing_context_string (spdm_version, op_code, true, &param_size);
    1723            0 :             break;
    1724            7 :         default:
    1725              :             /* pass thru for rest algorithm */
    1726            7 :             break;
    1727              :         }
    1728              : 
    1729            7 :         libspdm_create_signing_context (spdm_version, op_code, true,
    1730              :                                         spdm12_signing_context_with_hash);
    1731            7 :         hash_size = libspdm_get_hash_size(base_hash_algo);
    1732            7 :         result = libspdm_hash_all(base_hash_algo, message, message_size,
    1733              :                                   &spdm12_signing_context_with_hash[
    1734              :                                       SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]);
    1735            7 :         if (!result) {
    1736            0 :             return false;
    1737              :         }
    1738              : 
    1739              :         /* re-assign message and message_size for signing */
    1740            7 :         message = spdm12_signing_context_with_hash;
    1741            7 :         message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
    1742              : 
    1743              :         /* Passthru */
    1744              :     }
    1745              : 
    1746           22 :     if (need_hash) {
    1747           22 :         hash_size = libspdm_get_hash_size(base_hash_algo);
    1748           22 :         result = libspdm_hash_all(base_hash_algo, message, message_size,
    1749              :                                   message_hash);
    1750           22 :         if (!result) {
    1751            0 :             return false;
    1752              :         }
    1753           22 :         return libspdm_asym_sign_wrap(context, hash_nid, req_base_asym_alg,
    1754              :                                       param, param_size,
    1755              :                                       message_hash, hash_size,
    1756              :                                       signature, sig_size);
    1757              :     } else {
    1758            0 :         return libspdm_asym_sign_wrap(context, hash_nid, req_base_asym_alg,
    1759              :                                       param, param_size,
    1760              :                                       message, message_size,
    1761              :                                       signature, sig_size);
    1762              :     }
    1763              : }
    1764              : 
    1765           14 : bool libspdm_req_asym_sign_hash(
    1766              :     spdm_version_number_t spdm_version, uint8_t op_code,
    1767              :     uint16_t req_base_asym_alg,
    1768              :     uint32_t base_hash_algo, void *context,
    1769              :     const uint8_t *message_hash, size_t hash_size,
    1770              :     uint8_t *signature, size_t *sig_size)
    1771              : {
    1772              :     bool need_hash;
    1773              :     uint8_t *message;
    1774              :     size_t message_size;
    1775              :     uint8_t full_message_hash[LIBSPDM_MAX_HASH_SIZE];
    1776              :     bool result;
    1777              :     size_t hash_nid;
    1778              :     uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
    1779              :                                              LIBSPDM_MAX_HASH_SIZE];
    1780              :     const void *param;
    1781              :     size_t param_size;
    1782              : 
    1783           14 :     hash_nid = libspdm_get_hash_nid(base_hash_algo);
    1784           14 :     need_hash = libspdm_req_asym_func_need_hash(req_base_asym_alg);
    1785           14 :     LIBSPDM_ASSERT (hash_size == libspdm_get_hash_size(base_hash_algo));
    1786              : 
    1787           14 :     param = NULL;
    1788           14 :     param_size = 0;
    1789              : 
    1790           14 :     if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
    1791              :         /* Need use SPDM 1.2 signing */
    1792            6 :         switch (req_base_asym_alg) {
    1793            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
    1794            0 :             param = "";
    1795            0 :             param_size = 0;
    1796            0 :             break;
    1797            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
    1798            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1799            0 :             break;
    1800            0 :         case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
    1801            0 :             hash_nid = LIBSPDM_CRYPTO_NID_NULL;
    1802            0 :             param = libspdm_get_signing_context_string (spdm_version, op_code, true, &param_size);
    1803            0 :             break;
    1804            6 :         default:
    1805              :             /* pass thru for rest algorithm */
    1806            6 :             break;
    1807              :         }
    1808              : 
    1809            6 :         libspdm_create_signing_context (spdm_version, op_code, true,
    1810              :                                         spdm12_signing_context_with_hash);
    1811            6 :         libspdm_copy_mem(&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE],
    1812              :                          sizeof(spdm12_signing_context_with_hash)
    1813              :                          - (&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]
    1814              :                             - spdm12_signing_context_with_hash),
    1815              :                          message_hash, hash_size);
    1816              : 
    1817              :         /* assign message and message_size for signing */
    1818            6 :         message = spdm12_signing_context_with_hash;
    1819            6 :         message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
    1820              : 
    1821            6 :         if (need_hash) {
    1822            6 :             result = libspdm_hash_all(base_hash_algo, message, message_size,
    1823              :                                       full_message_hash);
    1824            6 :             if (!result) {
    1825            0 :                 return false;
    1826              :             }
    1827            6 :             return libspdm_asym_sign_wrap(context, hash_nid, req_base_asym_alg,
    1828              :                                           param, param_size,
    1829              :                                           full_message_hash, hash_size,
    1830              :                                           signature, sig_size);
    1831              :         } else {
    1832            0 :             return libspdm_asym_sign_wrap(context, hash_nid, req_base_asym_alg,
    1833              :                                           param, param_size,
    1834              :                                           message, message_size,
    1835              :                                           signature, sig_size);
    1836              :         }
    1837              : 
    1838              :         /* SPDM 1.2 signing done. */
    1839              :     }
    1840              : 
    1841            8 :     if (need_hash) {
    1842            8 :         return libspdm_asym_sign_wrap(context, hash_nid, req_base_asym_alg,
    1843              :                                       param, param_size,
    1844              :                                       message_hash, hash_size,
    1845              :                                       signature, sig_size);
    1846              :     } else {
    1847            0 :         LIBSPDM_ASSERT (false);
    1848            0 :         return false;
    1849              :     }
    1850              : }
        

Generated by: LCOV version 2.0-1