LCOV - code coverage report
Current view: top level - os_stub/spdm_device_secret_lib_sample - key_pair.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.3 % 232 198
Test Date: 2026-07-05 09:06:49 Functions: 100.0 % 8 8

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2024-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 <stdarg.h>
       8              : #include <stddef.h>
       9              : #include <setjmp.h>
      10              : #include <stdint.h>
      11              : #include <stdlib.h>
      12              : #include <stdio.h>
      13              : #include <assert.h>
      14              : #include <string.h>
      15              : 
      16              : #include <base.h>
      17              : #include "library/memlib.h"
      18              : #include "internal/libspdm_device_secret_lib.h"
      19              : #include "internal/libspdm_common_lib.h"
      20              : 
      21              : #if LIBSPDM_ENABLE_CAPABILITY_GET_KEY_PAIR_INFO_CAP
      22              : 
      23              : #define LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK SPDM_KEY_PAIR_ASYM_ALGO_CAP_MASK
      24              : 
      25              : #define LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK ( \
      26              :         SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_ML_DSA_44 | \
      27              :         SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_ML_DSA_65 | \
      28              :         SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_ML_DSA_87)
      29              : 
      30              : typedef struct {
      31              :     uint16_t capabilities;
      32              :     uint16_t key_usage_capabilities;
      33              :     uint16_t current_key_usage;
      34              :     uint32_t asym_algo_capabilities;
      35              :     uint32_t current_asym_algo;
      36              :     uint32_t pqc_asym_algo_capabilities;
      37              :     uint32_t current_pqc_asym_algo;
      38              :     uint16_t public_key_info_len;
      39              :     uint8_t assoc_cert_slot_mask;
      40              :     uint8_t public_key_info[SPDM_MAX_PUBLIC_KEY_INFO_LEN];
      41              : } libspdm_key_pair_info_t;
      42              : 
      43              : /* Up to (9 traditional + 3 ML-DSA) PRIMARY key pairs, each backing slots 0 and 1, plus one
      44              :  * SECONDARY key pair per algorithm backing slot 4 (the multi-key example) -- hence x2. */
      45              : #define LIBSPDM_MAX_KEY_PAIR_COUNT ((9 + 3) * 2)
      46              : 
      47              : libspdm_key_pair_info_t m_key_pair_info[LIBSPDM_MAX_KEY_PAIR_COUNT];
      48              : 
      49              : uint8_t m_total_key_pair_count = 0;
      50              : 
      51            2 : void libspdm_init_key_pair_info() {
      52              : #if (LIBSPDM_RSA_SSA_SUPPORT || LIBSPDM_RSA_PSS_SUPPORT)
      53            2 :     uint8_t public_key_info_rsa[] = {0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7,
      54              :                                      0x0D, 0x01, 0x01, 0x01, 0x05, 0x00};
      55              : #endif
      56              : #if LIBSPDM_ECDSA_P256_SUPPORT
      57            2 :     uint8_t public_key_info_ecp256[] = {0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
      58              :                                         0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
      59              :                                         0x03, 0x01, 0x07};
      60              : #endif
      61              : #if LIBSPDM_ECDSA_P384_SUPPORT
      62            2 :     uint8_t public_key_info_ecp384[] = {0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
      63              :                                         0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22};
      64              : #endif
      65              : #if LIBSPDM_ECDSA_P521_SUPPORT
      66            2 :     uint8_t public_key_info_ecp521[] = {0x30, 0x10, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
      67              :                                         0x02, 0x01, 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23};
      68              : #endif
      69              : #if LIBSPDM_SM2_DSA_P256_SUPPORT
      70              :     uint8_t public_key_info_sm2[] = {0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, 0xCE, 0x3D,
      71              :                                      0x02, 0x01, 0x06, 0x08, 0x2A, 0x81, 0x1C, 0xCF, 0x55,
      72              :                                      0x01, 0x82, 0x2D};
      73              : #endif
      74              : #if LIBSPDM_EDDSA_ED25519_SUPPORT
      75              :     uint8_t public_key_info_ed25519[] = {0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70};
      76              : #endif
      77              : #if LIBSPDM_EDDSA_ED448_SUPPORT
      78              :     uint8_t public_key_info_ed448[] = {0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x71};
      79              : #endif
      80              : #if LIBSPDM_ML_DSA_44_SUPPORT
      81              :     uint8_t public_key_info_mldsa44[] = {0x30, 0x0A, 0x06, 0x09,
      82              :                                          /* 2.16.840.1.101.3.4.3.17 */
      83              :                                          0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x11};
      84              : #endif
      85              : #if LIBSPDM_ML_DSA_65_SUPPORT
      86              :     uint8_t public_key_info_mldsa65[] = {0x30, 0x0A, 0x06, 0x09,
      87              :                                          /* 2.16.840.1.101.3.4.3.18 */
      88              :                                          0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x12};
      89              : #endif
      90              : #if LIBSPDM_ML_DSA_87_SUPPORT
      91              :     uint8_t public_key_info_mldsa87[] = {0x30, 0x0A, 0x06, 0x09,
      92              :                                          /* 2.16.840.1.101.3.4.3.19 */
      93              :                                          0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x13};
      94              : #endif
      95            2 :     uint8_t index = 0;
      96              :     /*provisioned key pair info*/
      97              : 
      98              : #if (LIBSPDM_RSA_SSA_2048_SUPPORT || LIBSPDM_RSA_PSS_2048_SUPPORT)
      99              :     /*key_pair_id 1*/
     100            2 :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     101            2 :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     102            2 :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     103            2 :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     104            2 :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     105            2 :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     106            2 :     m_key_pair_info[index].current_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_RSA2048;
     107            2 :     m_key_pair_info[index].current_pqc_asym_algo = 0;
     108            2 :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_rsa);
     109            2 :     libspdm_copy_mem(m_key_pair_info[index].public_key_info,
     110            2 :                      m_key_pair_info[index].public_key_info_len,
     111            2 :                      public_key_info_rsa, m_key_pair_info[index].public_key_info_len);
     112            2 :     index++;
     113              : #endif
     114              : 
     115              : #if (LIBSPDM_RSA_SSA_3072_SUPPORT || LIBSPDM_RSA_PSS_3072_SUPPORT)
     116              :     /*key_pair_id 2*/
     117            2 :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     118            2 :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     119            2 :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     120            2 :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     121            2 :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     122            2 :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     123            2 :     m_key_pair_info[index].current_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_RSA3072;
     124            2 :     m_key_pair_info[index].current_pqc_asym_algo = 0;
     125            2 :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_rsa);
     126            2 :     libspdm_copy_mem(m_key_pair_info[index].public_key_info,
     127            2 :                      m_key_pair_info[index].public_key_info_len,
     128            2 :                      public_key_info_rsa, m_key_pair_info[index].public_key_info_len);
     129            2 :     index++;
     130              : #endif
     131              : 
     132              : #if (LIBSPDM_RSA_SSA_4096_SUPPORT || LIBSPDM_RSA_PSS_4096_SUPPORT)
     133              :     /*key_pair_id 3*/
     134            2 :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     135            2 :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     136            2 :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     137            2 :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     138            2 :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     139            2 :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     140            2 :     m_key_pair_info[index].current_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_RSA4096;
     141            2 :     m_key_pair_info[index].current_pqc_asym_algo = 0;
     142            2 :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_rsa);
     143            2 :     libspdm_copy_mem(m_key_pair_info[index].public_key_info,
     144            2 :                      m_key_pair_info[index].public_key_info_len,
     145            2 :                      public_key_info_rsa, m_key_pair_info[index].public_key_info_len);
     146            2 :     index++;
     147              : #endif
     148              : 
     149              : #if LIBSPDM_ECDSA_P256_SUPPORT
     150              :     /*key_pair_id 4*/
     151            2 :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     152            2 :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     153            2 :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     154            2 :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     155            2 :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     156            2 :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     157            2 :     m_key_pair_info[index].current_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC256;
     158            2 :     m_key_pair_info[index].current_pqc_asym_algo = 0;
     159            2 :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_ecp256);
     160            2 :     libspdm_copy_mem(m_key_pair_info[index].public_key_info,
     161            2 :                      m_key_pair_info[index].public_key_info_len,
     162            2 :                      public_key_info_ecp256, m_key_pair_info[index].public_key_info_len);
     163            2 :     index++;
     164              : #endif
     165              : 
     166              : #if LIBSPDM_ECDSA_P384_SUPPORT
     167              :     /*key_pair_id 5*/
     168            2 :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     169            2 :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     170            2 :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     171            2 :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     172            2 :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     173            2 :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     174            2 :     m_key_pair_info[index].current_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC384;
     175            2 :     m_key_pair_info[index].current_pqc_asym_algo = 0;
     176            2 :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_ecp384);
     177            2 :     libspdm_copy_mem(m_key_pair_info[index].public_key_info,
     178            2 :                      m_key_pair_info[index].public_key_info_len,
     179            2 :                      public_key_info_ecp384, m_key_pair_info[index].public_key_info_len);
     180            2 :     index++;
     181              : #endif
     182              : 
     183              : #if LIBSPDM_ECDSA_P521_SUPPORT
     184              :     /*key_pair_id 6*/
     185            2 :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     186            2 :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     187            2 :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     188            2 :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     189            2 :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     190            2 :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     191            2 :     m_key_pair_info[index].current_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC521;
     192            2 :     m_key_pair_info[index].current_pqc_asym_algo = 0;
     193            2 :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_ecp521);
     194            2 :     libspdm_copy_mem(m_key_pair_info[index].public_key_info,
     195            2 :                      m_key_pair_info[index].public_key_info_len,
     196            2 :                      public_key_info_ecp521, m_key_pair_info[index].public_key_info_len);
     197            2 :     index++;
     198              : #endif
     199              : 
     200              : #if LIBSPDM_SM2_DSA_P256_SUPPORT
     201              :     /*key_pair_id 7*/
     202              :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     203              :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     204              :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     205              :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     206              :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     207              :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     208              :     m_key_pair_info[index].current_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_SM2;
     209              :     m_key_pair_info[index].current_pqc_asym_algo = 0;
     210              :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_sm2);
     211              :     libspdm_copy_mem(m_key_pair_info[index].public_key_info,
     212              :                      m_key_pair_info[index].public_key_info_len,
     213              :                      public_key_info_sm2, m_key_pair_info[index].public_key_info_len);
     214              :     index++;
     215              : #endif
     216              : 
     217              : #if LIBSPDM_EDDSA_ED25519_SUPPORT
     218              :     /*key_pair_id 8*/
     219              :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     220              :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     221              :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     222              :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     223              :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     224              :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     225              :     m_key_pair_info[index].current_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_ED25519;
     226              :     m_key_pair_info[index].current_pqc_asym_algo = 0;
     227              :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_ed25519);
     228              :     libspdm_copy_mem(m_key_pair_info[index].public_key_info,
     229              :                      m_key_pair_info[index].public_key_info_len,
     230              :                      public_key_info_ed25519, m_key_pair_info[index].public_key_info_len);
     231              :     index++;
     232              : #endif
     233              : 
     234              : #if LIBSPDM_EDDSA_ED448_SUPPORT
     235              :     /*key_pair_id 9*/
     236              :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     237              :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     238              :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     239              :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     240              :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     241              :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     242              :     m_key_pair_info[index].current_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_ED448;
     243              :     m_key_pair_info[index].current_pqc_asym_algo = 0;
     244              :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_ed448);
     245              :     libspdm_copy_mem(m_key_pair_info[index].public_key_info,
     246              :                      m_key_pair_info[index].public_key_info_len,
     247              :                      public_key_info_ed448, m_key_pair_info[index].public_key_info_len);
     248              :     index++;
     249              : #endif
     250              : 
     251              : #if LIBSPDM_ML_DSA_44_SUPPORT
     252              :     /*key_pair_id 10 (PQC)*/
     253              :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     254              :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     255              :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     256              :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     257              :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     258              :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     259              :     m_key_pair_info[index].current_asym_algo = 0;
     260              :     m_key_pair_info[index].current_pqc_asym_algo = SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_ML_DSA_44;
     261              :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_mldsa44);
     262              :     libspdm_copy_mem(m_key_pair_info[index].public_key_info, m_key_pair_info[index].public_key_info_len,
     263              :                      public_key_info_mldsa44, sizeof(public_key_info_mldsa44));
     264              :     index++;
     265              : #endif
     266              : 
     267              : #if LIBSPDM_ML_DSA_65_SUPPORT
     268              :     /*key_pair_id 11 (PQC)*/
     269              :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     270              :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     271              :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     272              :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     273              :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     274              :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     275              :     m_key_pair_info[index].current_asym_algo = 0;
     276              :     m_key_pair_info[index].current_pqc_asym_algo = SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_ML_DSA_65;
     277              :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_mldsa65);
     278              :     libspdm_copy_mem(m_key_pair_info[index].public_key_info, m_key_pair_info[index].public_key_info_len,
     279              :                      public_key_info_mldsa65, sizeof(public_key_info_mldsa65));
     280              :     index++;
     281              : #endif
     282              : 
     283              : #if LIBSPDM_ML_DSA_87_SUPPORT
     284              :     /*key_pair_id 12 (PQC)*/
     285              :     m_key_pair_info[index].capabilities = SPDM_KEY_PAIR_CAP_MASK;
     286              :     m_key_pair_info[index].key_usage_capabilities = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     287              :     m_key_pair_info[index].current_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     288              :     m_key_pair_info[index].asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_ASYM_ALGO_CAP_MASK;
     289              :     m_key_pair_info[index].pqc_asym_algo_capabilities = LIBSPDM_SUPPORTED_KEY_PAIR_PQC_ASYM_ALGO_CAP_MASK;
     290              :     m_key_pair_info[index].assoc_cert_slot_mask = 0x03;
     291              :     m_key_pair_info[index].current_asym_algo = 0;
     292              :     m_key_pair_info[index].current_pqc_asym_algo = SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_ML_DSA_87;
     293              :     m_key_pair_info[index].public_key_info_len = (uint16_t)sizeof(public_key_info_mldsa87);
     294              :     libspdm_copy_mem(m_key_pair_info[index].public_key_info, m_key_pair_info[index].public_key_info_len,
     295              :                      public_key_info_mldsa87, sizeof(public_key_info_mldsa87));
     296              :     index++;
     297              : #endif
     298              : 
     299              :     /* Multi-key example: for EACH primary key pair above (one per supported algorithm, backing
     300              :      * slots 0 and 1), append a SECONDARY key pair of the SAME algorithm that backs slot 4
     301              :      * (bundle_responder.certchain4.der / end_responder4.key). This shows two key pairs of one
     302              :      * algorithm backing different slots. KeyPairIDs stay contiguous 1..TotalKeyPairs: the primaries
     303              :      * are 1..num_primary and their secondaries are num_primary+1..2*num_primary. (SlotID 4 is a
     304              :      * NON-CONTIGUOUS slot, since slots 2 and 3 are left empty.) */
     305              :     {
     306            2 :         uint8_t num_primary = index;
     307              :         uint8_t i;
     308           14 :         for (i = 0; i < num_primary; i++) {
     309           12 :             m_key_pair_info[index] = m_key_pair_info[i];
     310           12 :             m_key_pair_info[index].assoc_cert_slot_mask = 0x10;
     311           12 :             index++;
     312              :         }
     313              :     }
     314              : 
     315            2 :     m_total_key_pair_count = index;
     316            2 : }
     317              : 
     318           36 : static uint8_t libspdm_get_total_key_pairs (void)
     319              : {
     320           36 :     if (m_total_key_pair_count == 0) {
     321            0 :         libspdm_init_key_pair_info();
     322              :     }
     323           36 :     return m_total_key_pair_count;
     324              : }
     325              : 
     326              : /* Convert a NEGOTIATE_ALGORITHMS base asymmetric algorithm (Table 113 wire bit, the encoding used
     327              :  * by connection_info.algorithm.base_asym_algo) to the key-pair capability encoding (Table 112,
     328              :  * the encoding stored in m_key_pair_info[].current_asym_algo). They are different bit layouts. */
     329          140 : static uint32_t libspdm_base_asym_algo_to_key_pair_cap(uint32_t base_asym_algo)
     330              : {
     331          140 :     switch (base_asym_algo) {
     332            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
     333              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
     334            0 :         return SPDM_KEY_PAIR_ASYM_ALGO_CAP_RSA2048;
     335            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
     336              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
     337            0 :         return SPDM_KEY_PAIR_ASYM_ALGO_CAP_RSA3072;
     338            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
     339              :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
     340            0 :         return SPDM_KEY_PAIR_ASYM_ALGO_CAP_RSA4096;
     341          140 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
     342          140 :         return SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC256;
     343            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
     344            0 :         return SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC384;
     345            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
     346            0 :         return SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC521;
     347            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
     348            0 :         return SPDM_KEY_PAIR_ASYM_ALGO_CAP_SM2;
     349            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
     350            0 :         return SPDM_KEY_PAIR_ASYM_ALGO_CAP_ED25519;
     351            0 :     case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
     352            0 :         return SPDM_KEY_PAIR_ASYM_ALGO_CAP_ED448;
     353            0 :     default:
     354            0 :         return 0;
     355              :     }
     356              : }
     357              : 
     358              : /* Return the device-global KeyPairID (1..TotalKeyPairs) for the key pair that backs (slot_id) under
     359              :  * the connection's negotiated algorithm. The PQC bitmap (Table 114) uses the same encoding for both
     360              :  * NEGOTIATE_ALGORITHMS and KEY_PAIR_INFO, so it is matched directly; the traditional algorithm is
     361              :  * converted to the key-pair capability encoding first.
     362              :  *
     363              :  * This is how the emu and the signing path obtain a REAL, algorithm-matched, contiguous KeyPairID
     364              :  * (per DSP0274, KeyPairIDs are 1..TotalKeyPairs without gaps and each has one fixed algorithm) --
     365              :  * the primary key pair of the negotiated algorithm backs slots 0/1 and its secondary backs slot 4.
     366              :  * Returns 0 if no matching key pair exists. */
     367          140 : uint8_t libspdm_get_key_pair_id_by_slot(uint32_t base_asym_algo, uint32_t pqc_asym_algo,
     368              :                                         uint8_t slot_id)
     369              : {
     370              :     uint8_t index;
     371              :     uint32_t key_pair_asym_algo;
     372              : 
     373          140 :     if (m_total_key_pair_count == 0) {
     374            2 :         libspdm_init_key_pair_info();
     375              :     }
     376              : 
     377          140 :     key_pair_asym_algo = libspdm_base_asym_algo_to_key_pair_cap(base_asym_algo);
     378              : 
     379         1400 :     for (index = 0; index < m_total_key_pair_count; index++) {
     380         1400 :         if ((m_key_pair_info[index].assoc_cert_slot_mask & (1 << slot_id)) == 0) {
     381          840 :             continue;
     382              :         }
     383          560 :         if ((pqc_asym_algo != 0) &&
     384            0 :             (m_key_pair_info[index].current_pqc_asym_algo == pqc_asym_algo)) {
     385            0 :             return (uint8_t)(index + 1);
     386              :         }
     387          560 :         if ((base_asym_algo != 0) &&
     388          560 :             (m_key_pair_info[index].current_asym_algo == key_pair_asym_algo)) {
     389          140 :             return (uint8_t)(index + 1);
     390              :         }
     391              :     }
     392            0 :     return 0;
     393              : }
     394              : 
     395              : /**
     396              :  * read the key pair info of the key_pair_id.
     397              :  *
     398              :  * @param  spdm_context               A pointer to the SPDM context.
     399              :  * @param  key_pair_id                Indicate which key pair ID's information to retrieve.
     400              :  *
     401              :  * @param  total_key_pairs            Indicate the total number of key pairs on the Responder.
     402              :  * @param  capabilities               Indicate the capabilities of the requested key pairs.
     403              :  * @param  key_usage_capabilities     Indicate the key usages the responder allows.
     404              :  * @param  current_key_usage          Indicate the currently configured key usage for the requested key pairs ID.
     405              :  * @param  asym_algo_capabilities     Indicate the asymmetric algorithms the Responder supports for this key pair ID.
     406              :  * @param  current_asym_algo          Indicate the currently configured asymmetric algorithm for this key pair ID.
     407              :  * @param  assoc_cert_slot_mask       This field is a bit mask representing the currently associated certificate slots.
     408              :  * @param  public_key_info_len        On input, indicate the size in bytes of the destination buffer to store.
     409              :  *                                    On output, indicate the size in bytes of the public_key_info.
     410              :  *                                    It can be NULL, if public_key_info is not required.
     411              :  * @param  public_key_info            A pointer to a destination buffer to store the public_key_info.
     412              :  *                                    It can be NULL, if public_key_info is not required.
     413              :  *
     414              :  * @retval true  get key pair info successfully.
     415              :  * @retval false get key pair info failed.
     416              :  **/
     417           22 : bool libspdm_read_key_pair_info(
     418              :     void *spdm_context,
     419              :     uint8_t key_pair_id,
     420              :     uint8_t *total_key_pairs,
     421              :     uint16_t *capabilities,
     422              :     uint16_t *key_usage_capabilities,
     423              :     uint16_t *current_key_usage,
     424              :     uint32_t *asym_algo_capabilities,
     425              :     uint32_t *current_asym_algo,
     426              :     uint32_t *pqc_asym_algo_capabilities,
     427              :     uint32_t *current_pqc_asym_algo,
     428              :     uint8_t *assoc_cert_slot_mask,
     429              :     uint16_t *public_key_info_len,
     430              :     uint8_t *public_key_info)
     431              : {
     432           22 :     *total_key_pairs = libspdm_get_total_key_pairs();
     433              : 
     434              :     /*check: KeyPairID is 1-based and indexes m_key_pair_info[key_pair_id - 1]*/
     435           22 :     if ((key_pair_id == 0) || (key_pair_id > *total_key_pairs)) {
     436            3 :         return false;
     437              :     }
     438              : 
     439           19 :     if (public_key_info_len != NULL) {
     440            2 :         if (*public_key_info_len < m_key_pair_info[key_pair_id - 1].public_key_info_len) {
     441            0 :             return false;
     442              :         }
     443              :     }
     444              : 
     445              :     /*output*/
     446           19 :     *capabilities = m_key_pair_info[key_pair_id - 1].capabilities;
     447           19 :     *key_usage_capabilities = m_key_pair_info[key_pair_id - 1].key_usage_capabilities;
     448           19 :     *current_key_usage = m_key_pair_info[key_pair_id - 1].current_key_usage;
     449           19 :     *asym_algo_capabilities = m_key_pair_info[key_pair_id - 1].asym_algo_capabilities;
     450           19 :     *current_asym_algo = m_key_pair_info[key_pair_id - 1].current_asym_algo;
     451           19 :     if (pqc_asym_algo_capabilities != NULL) {
     452           19 :         *pqc_asym_algo_capabilities = m_key_pair_info[key_pair_id - 1].pqc_asym_algo_capabilities;
     453              :     }
     454           19 :     if (current_pqc_asym_algo != NULL) {
     455           19 :         *current_pqc_asym_algo = m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo;
     456              :     }
     457           19 :     *assoc_cert_slot_mask = m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask;
     458              : 
     459           19 :     if (public_key_info_len != NULL) {
     460            2 :         *public_key_info_len = m_key_pair_info[key_pair_id - 1].public_key_info_len;
     461            2 :         if (public_key_info != NULL) {
     462            2 :             libspdm_copy_mem(public_key_info, *public_key_info_len,
     463            2 :                              m_key_pair_info[key_pair_id - 1].public_key_info, *public_key_info_len);
     464              :         }
     465              :     }
     466              : 
     467           19 :     return true;
     468              : }
     469              : #endif /* LIBSPDM_ENABLE_CAPABILITY_GET_KEY_PAIR_INFO_CAP */
     470              : 
     471              : #if LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP
     472              : 
     473              : typedef struct
     474              : {
     475              :     uint8_t key_pair_id;
     476              :     uint8_t operation;
     477              :     uint16_t desired_key_usage;
     478              :     uint32_t desired_asym_algo;
     479              :     uint32_t desired_pqc_asym_algo;
     480              :     uint8_t desired_assoc_cert_slot_mask;
     481              : } libspdm_cached_key_pair_info_data_t;
     482              : 
     483              : 
     484           11 : bool libspdm_read_cached_last_set_key_pair_info_request(uint8_t **last_set_key_pair_info_request,
     485              :                                                         size_t *last_set_key_pair_info_request_len)
     486              : {
     487              :     bool res;
     488           11 :     char file[] = "cached_last_set_key_pair_info_request";
     489              : 
     490           11 :     res = libspdm_read_input_file(file, (void **)last_set_key_pair_info_request,
     491              :                                   last_set_key_pair_info_request_len);
     492              : 
     493           11 :     return res;
     494              : }
     495              : 
     496            7 : bool libspdm_cache_last_set_key_pair_info_request(const uint8_t *last_set_key_pair_info_request,
     497              :                                                   size_t last_set_key_pair_info_request_len)
     498              : {
     499              :     bool res;
     500            7 :     char file[] = "cached_last_set_key_pair_info_request";
     501              : 
     502            7 :     res = libspdm_write_output_file(file, last_set_key_pair_info_request,
     503              :                                     last_set_key_pair_info_request_len);
     504              : 
     505            7 :     return res;
     506              : }
     507              : 
     508           14 : bool libspdm_write_key_pair_info(
     509              :     void *spdm_context,
     510              :     uint8_t key_pair_id,
     511              :     uint8_t operation,
     512              :     uint16_t desired_key_usage,
     513              :     uint32_t desired_asym_algo,
     514              :     uint32_t desired_pqc_asym_algo,
     515              :     uint8_t desired_assoc_cert_slot_mask,
     516              :     bool *need_reset)
     517              : {
     518              :     bool result;
     519              :     libspdm_cached_key_pair_info_data_t *cached_key_pair_info;
     520              :     libspdm_cached_key_pair_info_data_t current_key_pair_info;
     521              :     size_t cached_key_pair_info_len;
     522              : 
     523              :     /*check: KeyPairID is 1-based and indexes m_key_pair_info[key_pair_id - 1]*/
     524           14 :     if ((key_pair_id == 0) || (key_pair_id > libspdm_get_total_key_pairs())) {
     525            0 :         return false;
     526              :     }
     527              : 
     528           14 :     cached_key_pair_info_len = 0;
     529           14 :     if (*need_reset) {
     530           11 :         result = libspdm_read_cached_last_set_key_pair_info_request(
     531              :             (uint8_t **)&cached_key_pair_info,
     532              :             &cached_key_pair_info_len);
     533              : 
     534           11 :         if ((result) &&
     535           10 :             (cached_key_pair_info_len == sizeof(libspdm_cached_key_pair_info_data_t)) &&
     536           10 :             (cached_key_pair_info->operation == operation) &&
     537            7 :             (cached_key_pair_info->key_pair_id == key_pair_id) &&
     538            5 :             (cached_key_pair_info->desired_key_usage == desired_key_usage) &&
     539            5 :             (cached_key_pair_info->desired_asym_algo == desired_asym_algo) &&
     540            5 :             (cached_key_pair_info->desired_pqc_asym_algo == desired_pqc_asym_algo) &&
     541            4 :             (cached_key_pair_info->desired_assoc_cert_slot_mask == desired_assoc_cert_slot_mask)) {
     542            4 :             if (operation == SPDM_SET_KEY_PAIR_INFO_ERASE_OPERATION) {
     543            1 :                 m_key_pair_info[key_pair_id - 1].current_key_usage = 0;
     544            1 :                 m_key_pair_info[key_pair_id - 1].current_asym_algo = 0;
     545            1 :                 m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = 0;
     546            1 :                 m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask = 0;
     547            3 :             } else if (operation == SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION) {
     548            1 :                 m_key_pair_info[key_pair_id - 1].current_key_usage = desired_key_usage;
     549            1 :                 m_key_pair_info[key_pair_id - 1].current_asym_algo = desired_asym_algo;
     550            1 :                 m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = desired_pqc_asym_algo;
     551            1 :                 m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask =
     552              :                     desired_assoc_cert_slot_mask;
     553            2 :             } else if (operation == SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION) {
     554            2 :                 if (desired_key_usage != 0) {
     555            1 :                     m_key_pair_info[key_pair_id - 1].current_key_usage = desired_key_usage;
     556              :                 }
     557            2 :                 if (desired_asym_algo != 0) {
     558            1 :                     m_key_pair_info[key_pair_id - 1].current_asym_algo = desired_asym_algo;
     559              :                 }
     560            2 :                 if (desired_pqc_asym_algo != 0) {
     561            0 :                     m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = desired_pqc_asym_algo;
     562              :                 }
     563            2 :                 m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask =
     564              :                     desired_assoc_cert_slot_mask;
     565              :             } else {
     566            0 :                 free(cached_key_pair_info);
     567            0 :                 return false;
     568              :             }
     569              : 
     570              :             /*device don't need reset this time*/
     571            4 :             *need_reset = false;
     572            4 :             free(cached_key_pair_info);
     573            4 :             return true;
     574              :         } else {
     575            7 :             if (cached_key_pair_info != NULL) {
     576            6 :                 free(cached_key_pair_info);
     577              :             }
     578              : 
     579            7 :             current_key_pair_info.operation = operation;
     580            7 :             current_key_pair_info.key_pair_id = key_pair_id;
     581            7 :             current_key_pair_info.desired_key_usage = desired_key_usage;
     582            7 :             current_key_pair_info.desired_asym_algo = desired_asym_algo;
     583            7 :             current_key_pair_info.desired_pqc_asym_algo = desired_pqc_asym_algo;
     584            7 :             current_key_pair_info.desired_assoc_cert_slot_mask = desired_assoc_cert_slot_mask;
     585              :             /*device need reset this time: cache the last_set_key_pair_info_request */
     586            7 :             result = libspdm_cache_last_set_key_pair_info_request(
     587              :                 (const uint8_t *)&current_key_pair_info,
     588              :                 sizeof(libspdm_cached_key_pair_info_data_t));
     589            7 :             if (!result) {
     590            0 :                 return result;
     591              :             }
     592              : 
     593              :             /*device need reset this time*/
     594            7 :             *need_reset = true;
     595            7 :             return true;
     596              :         }
     597              :     } else {
     598            3 :         if (operation == SPDM_SET_KEY_PAIR_INFO_ERASE_OPERATION) {
     599            1 :             m_key_pair_info[key_pair_id - 1].current_key_usage = 0;
     600            1 :             m_key_pair_info[key_pair_id - 1].current_asym_algo = 0;
     601            1 :             m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = 0;
     602            1 :             m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask = 0;
     603            2 :         } else if (operation == SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION) {
     604            0 :             m_key_pair_info[key_pair_id - 1].current_key_usage = desired_key_usage;
     605            0 :             m_key_pair_info[key_pair_id - 1].current_asym_algo = desired_asym_algo;
     606            0 :             m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = desired_pqc_asym_algo;
     607            0 :             m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask = desired_assoc_cert_slot_mask;
     608            2 :         } else if (operation == SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION) {
     609            2 :             if (desired_key_usage != 0) {
     610            1 :                 m_key_pair_info[key_pair_id - 1].current_key_usage = desired_key_usage;
     611              :             }
     612            2 :             if (desired_asym_algo != 0) {
     613            1 :                 m_key_pair_info[key_pair_id - 1].current_asym_algo = desired_asym_algo;
     614              :             }
     615            2 :             if (desired_pqc_asym_algo != 0) {
     616            0 :                 m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = desired_pqc_asym_algo;
     617              :             }
     618            2 :             m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask = desired_assoc_cert_slot_mask;
     619              :         } else {
     620            0 :             return false;
     621              :         }
     622              : 
     623            3 :         return true;
     624              :     }
     625              : }
     626              : #endif /* #if LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP */
        

Generated by: LCOV version 2.0-1