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: 83.0 % 230 191
Test Date: 2026-06-14 09:11:02 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           47 : uint8_t libspdm_read_total_key_pairs (void *spdm_context)
     319              : {
     320           47 :     if (m_total_key_pair_count == 0) {
     321            0 :         libspdm_init_key_pair_info();
     322              :     }
     323           47 :     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  capabilities               Indicate the capabilities of the requested key pairs.
     402              :  * @param  key_usage_capabilities     Indicate the key usages the responder allows.
     403              :  * @param  current_key_usage          Indicate the currently configured key usage for the requested key pairs ID.
     404              :  * @param  asym_algo_capabilities     Indicate the asymmetric algorithms the Responder supports for this key pair ID.
     405              :  * @param  current_asym_algo          Indicate the currently configured asymmetric algorithm for this key pair ID.
     406              :  * @param  assoc_cert_slot_mask       This field is a bit mask representing the currently associated certificate slots.
     407              :  * @param  public_key_info_len        On input, indicate the size in bytes of the destination buffer to store.
     408              :  *                                    On output, indicate the size in bytes of the public_key_info.
     409              :  *                                    It can be NULL, if public_key_info is not required.
     410              :  * @param  public_key_info            A pointer to a destination buffer to store the public_key_info.
     411              :  *                                    It can be NULL, if public_key_info is not required.
     412              :  *
     413              :  * @retval true  get key pair info successfully.
     414              :  * @retval false get key pair info failed.
     415              :  **/
     416           16 : bool libspdm_read_key_pair_info(
     417              :     void *spdm_context,
     418              :     uint8_t key_pair_id,
     419              :     uint16_t *capabilities,
     420              :     uint16_t *key_usage_capabilities,
     421              :     uint16_t *current_key_usage,
     422              :     uint32_t *asym_algo_capabilities,
     423              :     uint32_t *current_asym_algo,
     424              :     uint32_t *pqc_asym_algo_capabilities,
     425              :     uint32_t *current_pqc_asym_algo,
     426              :     uint8_t *assoc_cert_slot_mask,
     427              :     uint16_t *public_key_info_len,
     428              :     uint8_t *public_key_info)
     429              : {
     430              :     /*check*/
     431           16 :     if (key_pair_id > libspdm_read_total_key_pairs(spdm_context)) {
     432            0 :         return false;
     433              :     }
     434              : 
     435           16 :     if (public_key_info_len != NULL) {
     436            1 :         if (*public_key_info_len < m_key_pair_info[key_pair_id - 1].public_key_info_len) {
     437            0 :             return false;
     438              :         }
     439              :     }
     440              : 
     441              :     /*output*/
     442           16 :     *capabilities = m_key_pair_info[key_pair_id - 1].capabilities;
     443           16 :     *key_usage_capabilities = m_key_pair_info[key_pair_id - 1].key_usage_capabilities;
     444           16 :     *current_key_usage = m_key_pair_info[key_pair_id - 1].current_key_usage;
     445           16 :     *asym_algo_capabilities = m_key_pair_info[key_pair_id - 1].asym_algo_capabilities;
     446           16 :     *current_asym_algo = m_key_pair_info[key_pair_id - 1].current_asym_algo;
     447           16 :     if (pqc_asym_algo_capabilities != NULL) {
     448           16 :         *pqc_asym_algo_capabilities = m_key_pair_info[key_pair_id - 1].pqc_asym_algo_capabilities;
     449              :     }
     450           16 :     if (current_pqc_asym_algo != NULL) {
     451           16 :         *current_pqc_asym_algo = m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo;
     452              :     }
     453           16 :     *assoc_cert_slot_mask = m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask;
     454              : 
     455           16 :     if (public_key_info_len != NULL) {
     456            1 :         *public_key_info_len = m_key_pair_info[key_pair_id - 1].public_key_info_len;
     457            1 :         if (public_key_info != NULL) {
     458            1 :             libspdm_copy_mem(public_key_info, *public_key_info_len,
     459            1 :                              m_key_pair_info[key_pair_id - 1].public_key_info, *public_key_info_len);
     460              :         }
     461              :     }
     462              : 
     463           16 :     return true;
     464              : }
     465              : #endif /* LIBSPDM_ENABLE_CAPABILITY_GET_KEY_PAIR_INFO_CAP */
     466              : 
     467              : #if LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP
     468              : 
     469              : typedef struct
     470              : {
     471              :     uint8_t key_pair_id;
     472              :     uint8_t operation;
     473              :     uint16_t desired_key_usage;
     474              :     uint32_t desired_asym_algo;
     475              :     uint32_t desired_pqc_asym_algo;
     476              :     uint8_t desired_assoc_cert_slot_mask;
     477              : } libspdm_cached_key_pair_info_data_t;
     478              : 
     479              : 
     480            8 : bool libspdm_read_cached_last_set_key_pair_info_request(uint8_t **last_set_key_pair_info_request,
     481              :                                                         size_t *last_set_key_pair_info_request_len)
     482              : {
     483              :     bool res;
     484            8 :     char file[] = "cached_last_set_key_pair_info_request";
     485              : 
     486            8 :     res = libspdm_read_input_file(file, (void **)last_set_key_pair_info_request,
     487              :                                   last_set_key_pair_info_request_len);
     488              : 
     489            8 :     return res;
     490              : }
     491              : 
     492            5 : bool libspdm_cache_last_set_key_pair_info_request(const uint8_t *last_set_key_pair_info_request,
     493              :                                                   size_t last_set_key_pair_info_request_len)
     494              : {
     495              :     bool res;
     496            5 :     char file[] = "cached_last_set_key_pair_info_request";
     497              : 
     498            5 :     res = libspdm_write_output_file(file, last_set_key_pair_info_request,
     499              :                                     last_set_key_pair_info_request_len);
     500              : 
     501            5 :     return res;
     502              : }
     503              : 
     504           11 : bool libspdm_write_key_pair_info(
     505              :     void *spdm_context,
     506              :     uint8_t key_pair_id,
     507              :     uint8_t operation,
     508              :     uint16_t desired_key_usage,
     509              :     uint32_t desired_asym_algo,
     510              :     uint32_t desired_pqc_asym_algo,
     511              :     uint8_t desired_assoc_cert_slot_mask,
     512              :     bool *need_reset)
     513              : {
     514              :     bool result;
     515              :     libspdm_cached_key_pair_info_data_t *cached_key_pair_info;
     516              :     libspdm_cached_key_pair_info_data_t current_key_pair_info;
     517              :     size_t cached_key_pair_info_len;
     518              : 
     519              :     /*check*/
     520           11 :     if (key_pair_id > libspdm_read_total_key_pairs(spdm_context)) {
     521            0 :         return false;
     522              :     }
     523              : 
     524           11 :     cached_key_pair_info_len = 0;
     525           11 :     if (*need_reset) {
     526            8 :         result = libspdm_read_cached_last_set_key_pair_info_request(
     527              :             (uint8_t **)&cached_key_pair_info,
     528              :             &cached_key_pair_info_len);
     529              : 
     530            8 :         if ((result) &&
     531            7 :             (cached_key_pair_info_len == sizeof(libspdm_cached_key_pair_info_data_t)) &&
     532            7 :             (cached_key_pair_info->operation == operation) &&
     533            5 :             (cached_key_pair_info->key_pair_id == key_pair_id) &&
     534            3 :             (cached_key_pair_info->desired_key_usage == desired_key_usage) &&
     535            3 :             (cached_key_pair_info->desired_asym_algo == desired_asym_algo) &&
     536            3 :             (cached_key_pair_info->desired_assoc_cert_slot_mask == desired_assoc_cert_slot_mask)) {
     537            3 :             if (operation == SPDM_SET_KEY_PAIR_INFO_ERASE_OPERATION) {
     538            1 :                 m_key_pair_info[key_pair_id - 1].current_key_usage = 0;
     539            1 :                 m_key_pair_info[key_pair_id - 1].current_asym_algo = 0;
     540            1 :                 m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = 0;
     541            1 :                 m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask = 0;
     542            2 :             } else if (operation == SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION) {
     543            0 :                 m_key_pair_info[key_pair_id - 1].current_key_usage = desired_key_usage;
     544            0 :                 m_key_pair_info[key_pair_id - 1].current_asym_algo = desired_asym_algo;
     545            0 :                 m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = desired_pqc_asym_algo;
     546            0 :                 m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask =
     547              :                     desired_assoc_cert_slot_mask;
     548            2 :             } else if (operation == SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION) {
     549            2 :                 if (desired_key_usage != 0) {
     550            1 :                     m_key_pair_info[key_pair_id - 1].current_key_usage = desired_key_usage;
     551              :                 }
     552            2 :                 if (desired_asym_algo != 0) {
     553            1 :                     m_key_pair_info[key_pair_id - 1].current_asym_algo = desired_asym_algo;
     554              :                 }
     555            2 :                 if (desired_pqc_asym_algo != 0) {
     556            0 :                     m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = desired_pqc_asym_algo;
     557              :                 }
     558            2 :                 m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask =
     559              :                     desired_assoc_cert_slot_mask;
     560              :             } else {
     561            0 :                 free(cached_key_pair_info);
     562            0 :                 return false;
     563              :             }
     564              : 
     565              :             /*device don't need reset this time*/
     566            3 :             *need_reset = false;
     567            3 :             free(cached_key_pair_info);
     568            3 :             return true;
     569              :         } else {
     570            5 :             if (cached_key_pair_info != NULL) {
     571            4 :                 free(cached_key_pair_info);
     572              :             }
     573              : 
     574            5 :             current_key_pair_info.operation = operation;
     575            5 :             current_key_pair_info.key_pair_id = key_pair_id;
     576            5 :             current_key_pair_info.desired_key_usage = desired_key_usage;
     577            5 :             current_key_pair_info.desired_asym_algo = desired_asym_algo;
     578            5 :             current_key_pair_info.desired_pqc_asym_algo = desired_pqc_asym_algo;
     579            5 :             current_key_pair_info.desired_assoc_cert_slot_mask = desired_assoc_cert_slot_mask;
     580              :             /*device need reset this time: cache the last_set_key_pair_info_request */
     581            5 :             result = libspdm_cache_last_set_key_pair_info_request(
     582              :                 (const uint8_t *)&current_key_pair_info,
     583              :                 sizeof(libspdm_cached_key_pair_info_data_t));
     584            5 :             if (!result) {
     585            0 :                 return result;
     586              :             }
     587              : 
     588              :             /*device need reset this time*/
     589            5 :             *need_reset = true;
     590            5 :             return true;
     591              :         }
     592              :     } else {
     593            3 :         if (operation == SPDM_SET_KEY_PAIR_INFO_ERASE_OPERATION) {
     594            1 :             m_key_pair_info[key_pair_id - 1].current_key_usage = 0;
     595            1 :             m_key_pair_info[key_pair_id - 1].current_asym_algo = 0;
     596            1 :             m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = 0;
     597            1 :             m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask = 0;
     598            2 :         } else if (operation == SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION) {
     599            0 :             m_key_pair_info[key_pair_id - 1].current_key_usage = desired_key_usage;
     600            0 :             m_key_pair_info[key_pair_id - 1].current_asym_algo = desired_asym_algo;
     601            0 :             m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = desired_pqc_asym_algo;
     602            0 :             m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask = desired_assoc_cert_slot_mask;
     603            2 :         } else if (operation == SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION) {
     604            2 :             if (desired_key_usage != 0) {
     605            1 :                 m_key_pair_info[key_pair_id - 1].current_key_usage = desired_key_usage;
     606              :             }
     607            2 :             if (desired_asym_algo != 0) {
     608            1 :                 m_key_pair_info[key_pair_id - 1].current_asym_algo = desired_asym_algo;
     609              :             }
     610            2 :             if (desired_pqc_asym_algo != 0) {
     611            0 :                 m_key_pair_info[key_pair_id - 1].current_pqc_asym_algo = desired_pqc_asym_algo;
     612              :             }
     613            2 :             m_key_pair_info[key_pair_id - 1].assoc_cert_slot_mask = desired_assoc_cert_slot_mask;
     614              :         } else {
     615            0 :             return false;
     616              :         }
     617              : 
     618            3 :         return true;
     619              :     }
     620              : }
     621              : #endif /* #if LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP */
        

Generated by: LCOV version 2.0-1