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: 2026-02-22 08:11:49 Functions: 75.0 % 36 27

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

Generated by: LCOV version 2.0-1