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: 2025-10-12 08:10:56 Functions: 100.0 % 7 7

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

Generated by: LCOV version 2.0-1