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: 37.4 % 91 34
Test Date: 2025-06-29 08:09:00 Functions: 100.0 % 6 6

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

Generated by: LCOV version 2.0-1