LCOV - code coverage report
Current view: top level - library/spdm_crypt_lib - libspdm_crypt_dhe.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 36.7 % 109 40
Test Date: 2026-02-22 08:11:49 Functions: 100.0 % 7 7

            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              : 
       9          292 : uint32_t libspdm_get_dhe_pub_key_size(uint16_t dhe_named_group)
      10              : {
      11          292 :     switch (dhe_named_group) {
      12            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
      13              : #if LIBSPDM_FFDHE_2048_SUPPORT
      14            0 :         return 256;
      15              : #else
      16              :         return 0;
      17              : #endif
      18            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
      19              : #if LIBSPDM_FFDHE_3072_SUPPORT
      20            0 :         return 384;
      21              : #else
      22              :         return 0;
      23              : #endif
      24            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
      25              : #if LIBSPDM_FFDHE_4096_SUPPORT
      26            0 :         return 512;
      27              : #else
      28              :         return 0;
      29              : #endif
      30          289 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
      31              : #if LIBSPDM_ECDHE_P256_SUPPORT
      32          289 :         return 32 * 2;
      33              : #else
      34              :         return 0;
      35              : #endif
      36            1 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
      37              : #if LIBSPDM_ECDHE_P384_SUPPORT
      38            1 :         return 48 * 2;
      39              : #else
      40              :         return 0;
      41              : #endif
      42            1 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
      43              : #if LIBSPDM_ECDHE_P521_SUPPORT
      44            1 :         return 66 * 2;
      45              : #else
      46              :         return 0;
      47              : #endif
      48            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
      49              : #if LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT
      50              :         return 32 * 2;
      51              : #else
      52            0 :         return 0;
      53              : #endif
      54            1 :     default:
      55            1 :         return 0;
      56              :     }
      57              : }
      58              : 
      59          742 : uint32_t libspdm_get_dhe_shared_secret_size(uint16_t dhe_named_group)
      60              : {
      61          742 :     switch (dhe_named_group) {
      62            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
      63              : #if LIBSPDM_FFDHE_2048_SUPPORT
      64            0 :         return 256;
      65              : #else
      66              :         return 0;
      67              : #endif
      68            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
      69              : #if LIBSPDM_FFDHE_3072_SUPPORT
      70            0 :         return 384;
      71              : #else
      72              :         return 0;
      73              : #endif
      74            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
      75              : #if LIBSPDM_FFDHE_4096_SUPPORT
      76            0 :         return 512;
      77              : #else
      78              :         return 0;
      79              : #endif
      80          556 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
      81              : #if LIBSPDM_ECDHE_P256_SUPPORT
      82          556 :         return 32;
      83              : #else
      84              :         return 0;
      85              : #endif
      86            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
      87              : #if LIBSPDM_ECDHE_P384_SUPPORT
      88            0 :         return 48;
      89              : #else
      90              :         return 0;
      91              : #endif
      92            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
      93              : #if LIBSPDM_ECDHE_P521_SUPPORT
      94            0 :         return 66;
      95              : #else
      96              :         return 0;
      97              : #endif
      98            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
      99              : #if LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT
     100              :         return 32;
     101              : #else
     102            0 :         return 0;
     103              : #endif
     104          186 :     default:
     105          186 :         return 0;
     106              :     }
     107              : }
     108              : 
     109              : /**
     110              :  * Return cipher ID, based upon the negotiated DHE algorithm.
     111              :  *
     112              :  * @param  dhe_named_group                SPDM dhe_named_group
     113              :  *
     114              :  * @return DHE cipher ID
     115              :  **/
     116          168 : static size_t libspdm_get_dhe_nid(uint16_t dhe_named_group)
     117              : {
     118          168 :     switch (dhe_named_group) {
     119            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
     120            0 :         return LIBSPDM_CRYPTO_NID_FFDHE2048;
     121            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
     122            0 :         return LIBSPDM_CRYPTO_NID_FFDHE3072;
     123            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
     124            0 :         return LIBSPDM_CRYPTO_NID_FFDHE4096;
     125          168 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
     126          168 :         return LIBSPDM_CRYPTO_NID_SECP256R1;
     127            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
     128            0 :         return LIBSPDM_CRYPTO_NID_SECP384R1;
     129            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
     130            0 :         return LIBSPDM_CRYPTO_NID_SECP521R1;
     131            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
     132            0 :         return LIBSPDM_CRYPTO_NID_SM2_KEY_EXCHANGE_P256;
     133            0 :     default:
     134            0 :         return LIBSPDM_CRYPTO_NID_NULL;
     135              :     }
     136              : }
     137              : 
     138          168 : void *libspdm_dhe_new(spdm_version_number_t spdm_version,
     139              :                       uint16_t dhe_named_group, bool is_initiator)
     140              : {
     141              :     size_t nid;
     142              : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
     143              :     void *context;
     144              :     bool result;
     145              :     uint8_t spdm12_key_change_requester_context[
     146              :         SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT_SIZE];
     147              :     uint8_t spdm12_key_change_responder_context[
     148              :         SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT_SIZE];
     149              : #endif /* LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT */
     150              : 
     151          168 :     nid = libspdm_get_dhe_nid(dhe_named_group);
     152          168 :     if (nid == 0) {
     153            0 :         return NULL;
     154              :     }
     155              : 
     156          168 :     switch (dhe_named_group) {
     157            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
     158              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
     159              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
     160              : #if LIBSPDM_FFDHE_SUPPORT
     161              : #if !LIBSPDM_FFDHE_2048_SUPPORT
     162              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048);
     163              : #endif
     164              : #if !LIBSPDM_FFDHE_3072_SUPPORT
     165              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072);
     166              : #endif
     167              : #if !LIBSPDM_FFDHE_4096_SUPPORT
     168              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096);
     169              : #endif
     170            0 :         return libspdm_dh_new_by_nid(nid);
     171              : #else
     172              :         LIBSPDM_ASSERT(false);
     173              :         return NULL;
     174              : #endif
     175              :         break;
     176          168 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
     177              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
     178              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
     179              : #if LIBSPDM_ECDHE_SUPPORT
     180              : #if !LIBSPDM_ECDHE_P256_SUPPORT
     181              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1);
     182              : #endif
     183              : #if !LIBSPDM_ECDHE_P384_SUPPORT
     184              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1);
     185              : #endif
     186              : #if !LIBSPDM_ECDHE_P521_SUPPORT
     187              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1);
     188              : #endif
     189          168 :         return libspdm_ec_new_by_nid(nid);
     190              : #else
     191              :         LIBSPDM_ASSERT(false);
     192              :         return NULL;
     193              : #endif
     194              :         break;
     195            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
     196              : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
     197              :         context = libspdm_sm2_key_exchange_new_by_nid(nid);
     198              : 
     199              :         libspdm_copy_mem(spdm12_key_change_requester_context,
     200              :                          sizeof(spdm12_key_change_requester_context),
     201              :                          SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT,
     202              :                          SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT_SIZE);
     203              :         libspdm_copy_mem(spdm12_key_change_responder_context,
     204              :                          sizeof(spdm12_key_change_responder_context),
     205              :                          SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT,
     206              :                          SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT_SIZE);
     207              :         /* patch the version*/
     208              :         spdm12_key_change_requester_context[25] = (char)('0' + ((spdm_version >> 12) & 0xF));
     209              :         spdm12_key_change_requester_context[27] = (char)('0' + ((spdm_version >> 8) & 0xF));
     210              :         spdm12_key_change_responder_context[25] = (char)('0' + ((spdm_version >> 12) & 0xF));
     211              :         spdm12_key_change_responder_context[27] = (char)('0' + ((spdm_version >> 8) & 0xF));
     212              : 
     213              :         result = libspdm_sm2_key_exchange_init (context, LIBSPDM_CRYPTO_NID_SM3_256,
     214              :                                                 spdm12_key_change_requester_context,
     215              :                                                 SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT_SIZE,
     216              :                                                 spdm12_key_change_responder_context,
     217              :                                                 SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT_SIZE,
     218              :                                                 is_initiator);
     219              :         if (!result) {
     220              :             libspdm_sm2_key_exchange_free (context);
     221              :             return NULL;
     222              :         }
     223              :         return context;
     224              : #else
     225            0 :         LIBSPDM_ASSERT(false);
     226            0 :         return NULL;
     227              : #endif
     228              :         break;
     229            0 :     default:
     230            0 :         LIBSPDM_ASSERT(false);
     231            0 :         return NULL;
     232              :     }
     233              : }
     234              : 
     235          168 : void libspdm_dhe_free(uint16_t dhe_named_group, void *context)
     236              : {
     237          168 :     if (context == NULL) {
     238            0 :         return;
     239              :     }
     240          168 :     switch (dhe_named_group) {
     241            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
     242              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
     243              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
     244              : #if LIBSPDM_FFDHE_SUPPORT
     245            0 :         libspdm_dh_free(context);
     246              : #else
     247              :         LIBSPDM_ASSERT(false);
     248              : #endif
     249            0 :         break;
     250          168 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
     251              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
     252              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
     253              : #if LIBSPDM_ECDHE_SUPPORT
     254          168 :         libspdm_ec_free(context);
     255              : #else
     256              :         LIBSPDM_ASSERT(false);
     257              : #endif
     258          168 :         break;
     259            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
     260              : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
     261              :         libspdm_sm2_key_exchange_free(context);
     262              : #else
     263            0 :         LIBSPDM_ASSERT(false);
     264              : #endif
     265            0 :         break;
     266            0 :     default:
     267            0 :         LIBSPDM_ASSERT(false);
     268            0 :         break;
     269              :     }
     270              : }
     271              : 
     272          168 : bool libspdm_dhe_generate_key(uint16_t dhe_named_group, void *context,
     273              :                               uint8_t *public_key,
     274              :                               size_t *public_key_size)
     275              : {
     276          168 :     switch (dhe_named_group) {
     277            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
     278              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
     279              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
     280              : #if LIBSPDM_FFDHE_SUPPORT
     281              : #if !LIBSPDM_FFDHE_2048_SUPPORT
     282              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048);
     283              : #endif
     284              : #if !LIBSPDM_FFDHE_3072_SUPPORT
     285              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072);
     286              : #endif
     287              : #if !LIBSPDM_FFDHE_4096_SUPPORT
     288              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096);
     289              : #endif
     290            0 :         return libspdm_dh_generate_key(context, public_key, public_key_size);
     291              : #else
     292              :         LIBSPDM_ASSERT(false);
     293              :         return false;
     294              : #endif
     295          168 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
     296              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
     297              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
     298              : #if LIBSPDM_ECDHE_SUPPORT
     299              : #if !LIBSPDM_ECDHE_P256_SUPPORT
     300              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1);
     301              : #endif
     302              : #if !LIBSPDM_ECDHE_P384_SUPPORT
     303              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1);
     304              : #endif
     305              : #if !LIBSPDM_ECDHE_P521_SUPPORT
     306              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1);
     307              : #endif
     308          168 :         return libspdm_ec_generate_key(context, public_key, public_key_size);
     309              : #else
     310              :         LIBSPDM_ASSERT(false);
     311              :         return false;
     312              : #endif
     313            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
     314              : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
     315              :         return libspdm_sm2_key_exchange_generate_key(context, public_key, public_key_size);
     316              : #else
     317            0 :         LIBSPDM_ASSERT(false);
     318            0 :         return false;
     319              : #endif
     320            0 :     default:
     321            0 :         LIBSPDM_ASSERT(false);
     322            0 :         return false;
     323              :     }
     324              : }
     325              : 
     326           74 : bool libspdm_dhe_compute_key(uint16_t dhe_named_group, void *context,
     327              :                              const uint8_t *peer_public,
     328              :                              size_t peer_public_size, uint8_t *key,
     329              :                              size_t *key_size)
     330              : {
     331              : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
     332              :     bool ret;
     333              : #endif
     334              : 
     335           74 :     switch (dhe_named_group) {
     336            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
     337              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
     338              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
     339              : #if LIBSPDM_FFDHE_SUPPORT
     340              : #if !LIBSPDM_FFDHE_2048_SUPPORT
     341              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048);
     342              : #endif
     343              : #if !LIBSPDM_FFDHE_3072_SUPPORT
     344              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072);
     345              : #endif
     346              : #if !LIBSPDM_FFDHE_4096_SUPPORT
     347              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096);
     348              : #endif
     349            0 :         return libspdm_dh_compute_key(context, peer_public, peer_public_size, key, key_size);
     350              : #else
     351              :         LIBSPDM_ASSERT(false);
     352              :         return false;
     353              : #endif
     354           74 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
     355              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
     356              :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
     357              : #if LIBSPDM_ECDHE_SUPPORT
     358              : #if !LIBSPDM_ECDHE_P256_SUPPORT
     359              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1);
     360              : #endif
     361              : #if !LIBSPDM_ECDHE_P384_SUPPORT
     362              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1);
     363              : #endif
     364              : #if !LIBSPDM_ECDHE_P521_SUPPORT
     365              :         LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1);
     366              : #endif
     367           74 :         return libspdm_ec_compute_key(context, peer_public, peer_public_size, key, key_size);
     368              : #else
     369              :         LIBSPDM_ASSERT(false);
     370              :         return false;
     371              : #endif
     372            0 :     case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
     373              : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
     374              :         ret = libspdm_sm2_key_exchange_compute_key(context, peer_public,
     375              :                                                    peer_public_size, key, key_size);
     376              :         if (!ret) {
     377              :             return false;
     378              :         } else {
     379              :             /* SM2 key exchange can generate arbitrary length key_size.
     380              :              * SPDM requires SM2 key_size to be 16. */
     381              :             LIBSPDM_ASSERT (*key_size >= 16);
     382              :             *key_size = 16;
     383              : 
     384              :             return true;
     385              :         }
     386              : #else
     387            0 :         LIBSPDM_ASSERT(false);
     388            0 :         return false;
     389              : #endif
     390            0 :     default:
     391            0 :         LIBSPDM_ASSERT(false);
     392            0 :         return false;
     393              :     }
     394              : }
        

Generated by: LCOV version 2.0-1