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 *)¤t_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 */
|