Branch data Line data Source code
1 : : /**
2 : : * Copyright Notice:
3 : : * Copyright 2021-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 "internal/libspdm_crypt_lib.h"
8 : : #include "library/spdm_common_lib.h"
9 : :
10 : : typedef struct {
11 : : bool is_requester;
12 : : uint8_t op_code;
13 : : const void *context;
14 : : size_t context_size;
15 : : size_t zero_pad_size;
16 : : } libspdm_signing_context_str_t;
17 : :
18 : : static const libspdm_signing_context_str_t m_libspdm_signing_context_str_table[] = {
19 : : {false, SPDM_CHALLENGE_AUTH, SPDM_CHALLENGE_AUTH_SIGN_CONTEXT,
20 : : SPDM_CHALLENGE_AUTH_SIGN_CONTEXT_SIZE, 36 - SPDM_CHALLENGE_AUTH_SIGN_CONTEXT_SIZE},
21 : : {true, SPDM_CHALLENGE_AUTH, SPDM_MUT_CHALLENGE_AUTH_SIGN_CONTEXT,
22 : : SPDM_MUT_CHALLENGE_AUTH_SIGN_CONTEXT_SIZE, 36 - SPDM_MUT_CHALLENGE_AUTH_SIGN_CONTEXT_SIZE},
23 : : {false, SPDM_MEASUREMENTS, SPDM_MEASUREMENTS_SIGN_CONTEXT, SPDM_MEASUREMENTS_SIGN_CONTEXT_SIZE,
24 : : 36 - SPDM_MEASUREMENTS_SIGN_CONTEXT_SIZE},
25 : : {false, SPDM_KEY_EXCHANGE_RSP, SPDM_KEY_EXCHANGE_RESPONSE_SIGN_CONTEXT,
26 : : SPDM_KEY_EXCHANGE_RESPONSE_SIGN_CONTEXT_SIZE,
27 : : 36 - SPDM_KEY_EXCHANGE_RESPONSE_SIGN_CONTEXT_SIZE},
28 : : {true, SPDM_FINISH, SPDM_FINISH_SIGN_CONTEXT, SPDM_FINISH_SIGN_CONTEXT_SIZE,
29 : : 36 - SPDM_FINISH_SIGN_CONTEXT_SIZE},
30 : : {false, SPDM_ENDPOINT_INFO, SPDM_ENDPOINT_INFO_SIGN_CONTEXT,
31 : : SPDM_ENDPOINT_INFO_SIGN_CONTEXT_SIZE,
32 : : 36 - SPDM_ENDPOINT_INFO_SIGN_CONTEXT_SIZE},
33 : : {true, SPDM_ENDPOINT_INFO, SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT,
34 : : SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT_SIZE, 36 - SPDM_MUT_ENDPOINT_INFO_SIGN_CONTEXT_SIZE},
35 : : };
36 : :
37 : : #if LIBSPDM_RSA_SSA_SUPPORT
38 : 41 : static bool libspdm_rsa_pkcs1_sign_with_nid_wrap (void *context, size_t hash_nid,
39 : : const uint8_t *message,
40 : : size_t message_size, uint8_t *signature,
41 : : size_t *sig_size)
42 : : {
43 : 41 : return libspdm_rsa_pkcs1_sign_with_nid (context, hash_nid,
44 : : message, message_size, signature, sig_size);
45 : : }
46 : : #endif
47 : :
48 : : #if LIBSPDM_RSA_PSS_SUPPORT
49 : 0 : static bool libspdm_rsa_pss_sign_wrap (void *context, size_t hash_nid,
50 : : const uint8_t *message,
51 : : size_t message_size, uint8_t *signature,
52 : : size_t *sig_size)
53 : : {
54 : 0 : return libspdm_rsa_pss_sign (context, hash_nid,
55 : : message, message_size, signature, sig_size);
56 : : }
57 : : #endif
58 : :
59 : : #if LIBSPDM_ECDSA_SUPPORT
60 : 157 : static bool libspdm_ecdsa_sign_wrap (void *context, size_t hash_nid,
61 : : const uint8_t *message,
62 : : size_t message_size, uint8_t *signature,
63 : : size_t *sig_size)
64 : : {
65 : 157 : return libspdm_ecdsa_sign (context, hash_nid,
66 : : message, message_size, signature, sig_size);
67 : : }
68 : : #endif
69 : :
70 : : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
71 : : static bool libspdm_eddsa_sign_wrap (void *context, size_t hash_nid,
72 : : const uint8_t *param, size_t param_size,
73 : : const uint8_t *message,
74 : : size_t message_size, uint8_t *signature,
75 : : size_t *sig_size)
76 : : {
77 : : return libspdm_eddsa_sign (context, hash_nid, param, param_size,
78 : : message, message_size, signature, sig_size);
79 : : }
80 : : #endif
81 : :
82 : : #if LIBSPDM_SM2_DSA_SUPPORT
83 : : static bool libspdm_sm2_dsa_sign_wrap (void *context, size_t hash_nid,
84 : : const uint8_t *param, size_t param_size,
85 : : const uint8_t *message,
86 : : size_t message_size, uint8_t *signature,
87 : : size_t *sig_size)
88 : : {
89 : : return libspdm_sm2_dsa_sign (context, hash_nid, param, param_size,
90 : : message, message_size, signature, sig_size);
91 : : }
92 : : #endif
93 : :
94 : 0 : const void *libspdm_get_signing_context_string (
95 : : spdm_version_number_t spdm_version,
96 : : uint8_t op_code,
97 : : bool is_requester,
98 : : size_t *context_size)
99 : : {
100 : : size_t index;
101 : :
102 : : /* It is introduced in SPDM 1.2*/
103 [ # # ]: 0 : LIBSPDM_ASSERT((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11);
104 : :
105 [ # # ]: 0 : for (index = 0; index < LIBSPDM_ARRAY_SIZE(m_libspdm_signing_context_str_table); index++) {
106 [ # # ]: 0 : if (m_libspdm_signing_context_str_table[index].is_requester == is_requester &&
107 [ # # ]: 0 : m_libspdm_signing_context_str_table[index].op_code == op_code) {
108 : 0 : *context_size = m_libspdm_signing_context_str_table[index].context_size;
109 : 0 : return m_libspdm_signing_context_str_table[index].context;
110 : : }
111 : : }
112 : 0 : LIBSPDM_ASSERT(false);
113 : 0 : return NULL;
114 : : }
115 : :
116 : 82 : void libspdm_create_signing_context (
117 : : spdm_version_number_t spdm_version,
118 : : uint8_t op_code,
119 : : bool is_requester,
120 : : void *spdm_signing_context)
121 : : {
122 : : size_t index;
123 : : char *context_str;
124 : :
125 : : /* It is introduced in SPDM 1.2*/
126 [ - + ]: 82 : LIBSPDM_ASSERT((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11);
127 : :
128 : : /* So far, it only leaves 1 bytes for version*/
129 [ + - - + ]: 82 : LIBSPDM_ASSERT((((spdm_version >> 12) & 0xF) < 10) &&
130 : : (((spdm_version >> 8) & 0xF) < 10));
131 : :
132 : 82 : context_str = spdm_signing_context;
133 [ + + ]: 410 : for (index = 0; index < 4; index++) {
134 : 328 : libspdm_copy_mem(context_str,
135 : : SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT_SIZE,
136 : : SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT,
137 : : SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT_SIZE);
138 : : /* patch the version*/
139 : 328 : context_str[11] = (char)('0' + ((spdm_version >> 12) & 0xF));
140 : 328 : context_str[13] = (char)('0' + ((spdm_version >> 8) & 0xF));
141 : 328 : context_str[15] = (char)('*');
142 : 328 : context_str += SPDM_VERSION_1_2_SIGNING_PREFIX_CONTEXT_SIZE;
143 : : }
144 [ + - ]: 404 : for (index = 0; index < LIBSPDM_ARRAY_SIZE(m_libspdm_signing_context_str_table); index++) {
145 [ + + ]: 404 : if (m_libspdm_signing_context_str_table[index].is_requester == is_requester &&
146 [ + + ]: 241 : m_libspdm_signing_context_str_table[index].op_code == op_code) {
147 : 82 : libspdm_zero_mem (
148 : : context_str,
149 : 82 : m_libspdm_signing_context_str_table[index].zero_pad_size);
150 : 82 : libspdm_copy_mem(context_str + m_libspdm_signing_context_str_table[index].zero_pad_size,
151 : 82 : m_libspdm_signing_context_str_table[index].context_size,
152 : 82 : m_libspdm_signing_context_str_table[index].context,
153 : 82 : m_libspdm_signing_context_str_table[index].context_size);
154 : 82 : return;
155 : : }
156 : : }
157 : 0 : LIBSPDM_ASSERT(false);
158 : : }
159 : :
160 : 714 : uint32_t libspdm_get_asym_signature_size(uint32_t base_asym_algo)
161 : : {
162 [ + - - + : 714 : switch (base_asym_algo) {
- - + - +
- - - + ]
163 : 123 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
164 : : #if LIBSPDM_RSA_SSA_2048_SUPPORT
165 : 123 : return 256;
166 : : #else
167 : : return 0;
168 : : #endif
169 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
170 : : #if LIBSPDM_RSA_PSS_2048_SUPPORT
171 : 0 : return 256;
172 : : #else
173 : : return 0;
174 : : #endif
175 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
176 : : #if LIBSPDM_RSA_SSA_3072_SUPPORT
177 : 0 : return 384;
178 : : #else
179 : : return 0;
180 : : #endif
181 : 1 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
182 : : #if LIBSPDM_RSA_PSS_3072_SUPPORT
183 : 1 : return 384;
184 : : #else
185 : : return 0;
186 : : #endif
187 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
188 : : #if LIBSPDM_RSA_SSA_4096_SUPPORT
189 : 0 : return 512;
190 : : #else
191 : : return 0;
192 : : #endif
193 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
194 : : #if LIBSPDM_RSA_PSS_4096_SUPPORT
195 : 0 : return 512;
196 : : #else
197 : : return 0;
198 : : #endif
199 : 571 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
200 : : #if LIBSPDM_ECDSA_P256_SUPPORT
201 : 571 : return 32 * 2;
202 : : #else
203 : : return 0;
204 : : #endif
205 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
206 : : #if LIBSPDM_ECDSA_P384_SUPPORT
207 : 0 : return 48 * 2;
208 : : #else
209 : : return 0;
210 : : #endif
211 : 4 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
212 : : #if LIBSPDM_ECDSA_P521_SUPPORT
213 : 4 : return 66 * 2;
214 : : #else
215 : : return 0;
216 : : #endif
217 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
218 : : #if LIBSPDM_SM2_DSA_P256_SUPPORT
219 : : return 32 * 2;
220 : : #else
221 : 0 : return 0;
222 : : #endif
223 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
224 : : #if LIBSPDM_EDDSA_ED25519_SUPPORT
225 : : return 32 * 2;
226 : : #else
227 : 0 : return 0;
228 : : #endif
229 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
230 : : #if LIBSPDM_EDDSA_ED448_SUPPORT
231 : : return 57 * 2;
232 : : #else
233 : 0 : return 0;
234 : : #endif
235 : 15 : default:
236 : 15 : return 0;
237 : : }
238 : : }
239 : :
240 : 198 : static bool libspdm_asym_sign_wrap (void *context, size_t hash_nid, uint32_t base_asym_algo,
241 : : const uint8_t *param, size_t param_size,
242 : : const uint8_t *message, size_t message_size,
243 : : uint8_t *signature, size_t *sig_size)
244 : : {
245 [ + - + - : 198 : switch (base_asym_algo) {
- - ]
246 : 41 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
247 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
248 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
249 : : #if LIBSPDM_RSA_SSA_SUPPORT
250 : : #if !LIBSPDM_RSA_SSA_2048_SUPPORT
251 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048);
252 : : #endif
253 : : #if !LIBSPDM_RSA_SSA_3072_SUPPORT
254 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072);
255 : : #endif
256 : : #if !LIBSPDM_RSA_SSA_4096_SUPPORT
257 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096);
258 : : #endif
259 : 41 : return libspdm_rsa_pkcs1_sign_with_nid_wrap(context, hash_nid,
260 : : message, message_size,
261 : : signature, sig_size);
262 : : #else
263 : : LIBSPDM_ASSERT(false);
264 : : return false;
265 : : #endif
266 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
267 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
268 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
269 : : #if LIBSPDM_RSA_PSS_SUPPORT
270 : : #if !LIBSPDM_RSA_PSS_2048_SUPPORT
271 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048);
272 : : #endif
273 : : #if !LIBSPDM_RSA_PSS_3072_SUPPORT
274 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072);
275 : : #endif
276 : : #if !LIBSPDM_RSA_PSS_4096_SUPPORT
277 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096);
278 : : #endif
279 : 0 : return libspdm_rsa_pss_sign_wrap(context, hash_nid,
280 : : message, message_size,
281 : : signature, sig_size);
282 : : #else
283 : : LIBSPDM_ASSERT(false);
284 : : return false;
285 : : #endif
286 : 157 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
287 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
288 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
289 : : #if LIBSPDM_ECDSA_SUPPORT
290 : : #if !LIBSPDM_ECDSA_P256_SUPPORT
291 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256);
292 : : #endif
293 : : #if !LIBSPDM_ECDSA_P384_SUPPORT
294 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384);
295 : : #endif
296 : : #if !LIBSPDM_ECDSA_P521_SUPPORT
297 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521);
298 : : #endif
299 : 157 : return libspdm_ecdsa_sign_wrap(context, hash_nid,
300 : : message, message_size,
301 : : signature, sig_size);
302 : : #else
303 : : LIBSPDM_ASSERT(false);
304 : : return false;
305 : : #endif
306 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
307 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
308 : : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
309 : : #if !LIBSPDM_EDDSA_ED25519_SUPPORT
310 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519);
311 : : #endif
312 : : #if !LIBSPDM_EDDSA_ED448_SUPPORT
313 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448);
314 : : #endif
315 : : return libspdm_eddsa_sign_wrap(context, hash_nid,
316 : : param, param_size,
317 : : message, message_size,
318 : : signature, sig_size);
319 : : #else
320 : 0 : LIBSPDM_ASSERT(false);
321 : 0 : return false;
322 : : #endif
323 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
324 : : #if LIBSPDM_SM2_DSA_SUPPORT
325 : : return libspdm_sm2_dsa_sign_wrap(context, hash_nid,
326 : : param, param_size,
327 : : message, message_size,
328 : : signature, sig_size);
329 : : #else
330 : 0 : LIBSPDM_ASSERT(false);
331 : 0 : return false;
332 : : #endif
333 : 0 : default:
334 : 0 : LIBSPDM_ASSERT(false);
335 : 0 : return false;
336 : : }
337 : : }
338 : :
339 : 1222 : void libspdm_asym_free(uint32_t base_asym_algo, void *context)
340 : : {
341 [ + + ]: 1222 : if (context == NULL) {
342 : 6 : return;
343 : : }
344 [ + + - - : 1216 : switch (base_asym_algo) {
- ]
345 : 143 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
346 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
347 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
348 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
349 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
350 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
351 : : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
352 : 143 : libspdm_rsa_free(context);
353 : : #else
354 : : LIBSPDM_ASSERT(false);
355 : : #endif
356 : 143 : break;
357 : 1073 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
358 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
359 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
360 : : #if LIBSPDM_ECDSA_SUPPORT
361 : 1073 : libspdm_ec_free(context);
362 : : #else
363 : : LIBSPDM_ASSERT(false);
364 : : #endif
365 : 1073 : break;
366 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
367 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
368 : : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
369 : : libspdm_ecd_free(context);
370 : : #else
371 : 0 : LIBSPDM_ASSERT(false);
372 : : #endif
373 : 0 : break;
374 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
375 : : #if LIBSPDM_SM2_DSA_SUPPORT
376 : : libspdm_sm2_dsa_free(context);
377 : : #else
378 : 0 : LIBSPDM_ASSERT(false);
379 : : #endif
380 : 0 : break;
381 : 0 : default:
382 : 0 : LIBSPDM_ASSERT(false);
383 : 0 : break;
384 : : }
385 : : }
386 : :
387 : 9 : static bool libspdm_asym_get_public_key_from_der_wrap(uint32_t base_asym_algo,
388 : : const uint8_t *der_data,
389 : : size_t der_size,
390 : : void **context)
391 : : {
392 [ + + - - : 9 : switch (base_asym_algo) {
- ]
393 : 4 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
394 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
395 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
396 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
397 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
398 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
399 : : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
400 : : #if !LIBSPDM_RSA_SSA_2048_SUPPORT
401 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048);
402 : : #endif
403 : : #if !LIBSPDM_RSA_SSA_3072_SUPPORT
404 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072);
405 : : #endif
406 : : #if !LIBSPDM_RSA_SSA_4096_SUPPORT
407 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096);
408 : : #endif
409 : : #if !LIBSPDM_RSA_PSS_2048_SUPPORT
410 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048);
411 : : #endif
412 : : #if !LIBSPDM_RSA_PSS_3072_SUPPORT
413 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072);
414 : : #endif
415 : : #if !LIBSPDM_RSA_PSS_4096_SUPPORT
416 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096);
417 : : #endif
418 : 4 : return libspdm_rsa_get_public_key_from_der(der_data, der_size, context);
419 : : #else
420 : : LIBSPDM_ASSERT(false);
421 : : return false;
422 : : #endif
423 : 5 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
424 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
425 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
426 : : #if LIBSPDM_ECDSA_SUPPORT
427 : : #if !LIBSPDM_ECDSA_P256_SUPPORT
428 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256);
429 : : #endif
430 : : #if !LIBSPDM_ECDSA_P384_SUPPORT
431 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384);
432 : : #endif
433 : : #if !LIBSPDM_ECDSA_P521_SUPPORT
434 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521);
435 : : #endif
436 : 5 : return libspdm_ec_get_public_key_from_der(der_data, der_size, context);
437 : : #else
438 : : LIBSPDM_ASSERT(false);
439 : : return false;
440 : : #endif
441 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
442 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
443 : : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
444 : : return libspdm_ecd_get_public_key_from_der(der_data, der_size, context);
445 : : #else
446 : 0 : LIBSPDM_ASSERT(false);
447 : 0 : return false;
448 : : #endif
449 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
450 : : #if LIBSPDM_SM2_DSA_SUPPORT
451 : : #if !LIBSPDM_EDDSA_ED25519_SUPPORT
452 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519);
453 : : #endif
454 : : #if !LIBSPDM_EDDSA_ED448_SUPPORT
455 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448);
456 : : #endif
457 : : return libspdm_sm2_get_public_key_from_der(der_data, der_size, context);
458 : : #else
459 : 0 : LIBSPDM_ASSERT(false);
460 : 0 : return false;
461 : : #endif
462 : 0 : default:
463 : 0 : LIBSPDM_ASSERT(false);
464 : 0 : return false;
465 : : }
466 : : }
467 : :
468 : 5 : bool libspdm_asym_get_public_key_from_der(uint32_t base_asym_algo,
469 : : const uint8_t *der_data,
470 : : size_t der_size,
471 : : void **context)
472 : : {
473 : 5 : return libspdm_asym_get_public_key_from_der_wrap(base_asym_algo,
474 : : der_data,
475 : : der_size,
476 : : context);
477 : : }
478 : :
479 : : /**
480 : : * Return if asymmetric function need message hash.
481 : : *
482 : : * @param base_asym_algo SPDM base_asym_algo
483 : : *
484 : : * @retval true asymmetric function need message hash
485 : : * @retval false asymmetric function need raw message
486 : : **/
487 : 315 : static bool libspdm_asym_func_need_hash(uint32_t base_asym_algo)
488 : : {
489 [ + + - - ]: 315 : switch (base_asym_algo) {
490 : 73 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
491 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
492 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
493 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
494 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
495 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
496 : 73 : return true;
497 : 242 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
498 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
499 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
500 : 242 : return true;
501 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
502 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
503 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
504 : 0 : return false;
505 : 0 : default:
506 : 0 : LIBSPDM_ASSERT(false);
507 : 0 : break;
508 : : }
509 : :
510 : 0 : return false;
511 : : }
512 : :
513 : : /**
514 : : * libspdm_copy_signature_swap_endian_rsa
515 : : * Swaps the endianness of a RSA signature buffer. The RSA signature buffer is
516 : : * actually single internal buffer and can be swapped as a single whole buffer.
517 : : *
518 : : * There are two known usage models for buffers for this function.
519 : : * 1) Source and dest are the same (and their sizes). This would be an in-place swap.
520 : : * 2) Source and dest are completely different (and dest size >= src size). No overlap.
521 : : *
522 : : * The case where source and dest are overlapped (and not the exact same buffer)
523 : : * is not allowed and guarded against with an assert.
524 : : **/
525 : 10 : static void libspdm_copy_signature_swap_endian_rsa(
526 : : uint8_t* dst,
527 : : size_t dst_size,
528 : : const uint8_t* src,
529 : : size_t src_size)
530 : : {
531 : : /* RSA signature is a single buffer to be swapped */
532 : : size_t i;
533 : :
534 [ + + ]: 10 : if (src == dst) {
535 [ - + ]: 4 : LIBSPDM_ASSERT(dst_size == src_size);
536 : :
537 : : /* src and dst are same buffer. Swap in place. */
538 : :
539 : : uint8_t byte;
540 [ + + ]: 516 : for (i = 0; i < dst_size / 2; i++) {
541 : 512 : byte = dst[i];
542 : 512 : dst[i] = dst[dst_size - i - 1];
543 : 512 : dst[dst_size - i - 1] = byte;
544 : : }
545 : : } else {
546 : : /* src and dst are different buffers.
547 : : * Guard against overlap case with assert.
548 : : * Overlap case is not an expected usage model. */
549 [ - + ]: 6 : LIBSPDM_ASSERT(dst_size >= src_size);
550 [ + + - + : 6 : LIBSPDM_ASSERT((src < dst && src + src_size <= dst) ||
+ - - + ]
551 : : (dst < src && dst + dst_size <= src));
552 : :
553 [ + + ]: 1542 : for (i = 0; i < src_size; i++) {
554 : 1536 : dst[i] = src[src_size - i - 1];
555 : : }
556 : : }
557 : 10 : }
558 : :
559 : : /**
560 : : * libspdm_copy_signature_swap_endian_ecdsa
561 : : * Swaps the endianness of a ECDSA signature buffer. The ECDSA signature buffer is
562 : : * actually two internal buffers, and each internal buffer must be swapped individually.
563 : : *
564 : : * There are two known usage models for buffers for this function.
565 : : * 1) Source and dest are the same (and their sizes). This would be an in-place swap.
566 : : * 2) Source and dest are completely different (and dest size >= src size). No overlap.
567 : : *
568 : : * The case where source and dest are overlapped (and not the exact same buffer)
569 : : * is not allowed and guarded against with an assert.
570 : : **/
571 : 10 : static void libspdm_copy_signature_swap_endian_ecdsa(
572 : : uint8_t* dst,
573 : : size_t dst_size,
574 : : const uint8_t* src,
575 : : size_t src_size)
576 : : {
577 : : /* ECDSA signature is actually 2 buffers (x & y)
578 : : * and each must be swapped individually */
579 : : size_t i;
580 : :
581 [ + + ]: 10 : if (src == dst) {
582 [ - + ]: 4 : LIBSPDM_ASSERT(dst_size == src_size);
583 : :
584 : : /* src and dst are same buffer. Swap ecdsa 2 internal buffers in place. */
585 : :
586 : : size_t x_size;
587 : : size_t y_size;
588 : : uint8_t* x;
589 : : uint8_t* y;
590 : : uint8_t byte;
591 : :
592 : 4 : x_size = dst_size / 2;
593 : 4 : y_size = x_size;
594 : :
595 : 4 : x = dst;
596 : 4 : y = x + x_size;
597 : :
598 [ + + ]: 68 : for (i = 0; i < x_size / 2; i++) {
599 : 64 : byte = x[i];
600 : 64 : x[i] = x[x_size - i - 1];
601 : 64 : x[x_size - i - 1] = byte;
602 : : }
603 : :
604 [ + + ]: 68 : for (i = 0; i < y_size / 2; i++) {
605 : 64 : byte = y[i];
606 : 64 : y[i] = y[y_size - i - 1];
607 : 64 : y[y_size - i - 1] = byte;
608 : : }
609 : : } else {
610 : : /* src and dst are different buffers.
611 : : * Guard against overlap case with assert.
612 : : * Overlap case is not an expected usage model. */
613 [ - + ]: 6 : LIBSPDM_ASSERT(dst_size >= src_size);
614 [ - + - - : 6 : LIBSPDM_ASSERT((src < dst && src + src_size <= dst) ||
+ - - + ]
615 : : (dst < src && dst + dst_size <= src));
616 : :
617 : : size_t x_size;
618 : : size_t y_size;
619 : :
620 : : const uint8_t* src_x;
621 : : const uint8_t* src_y;
622 : :
623 : : uint8_t* dst_x;
624 : : uint8_t* dst_y;
625 : :
626 : 6 : x_size = src_size / 2;
627 : 6 : y_size = x_size;
628 : :
629 : 6 : src_x = src;
630 : 6 : src_y = src_x + x_size;
631 : :
632 : 6 : dst_x = dst;
633 : 6 : dst_y = dst_x + x_size;
634 : :
635 [ + + ]: 198 : for (i = 0; i < x_size; i++) {
636 : 192 : dst_x[i] = src_x[x_size - i - 1];
637 : : }
638 : :
639 [ + + ]: 198 : for (i = 0; i < y_size; i++) {
640 : 192 : dst_y[i] = src_y[y_size - i - 1];
641 : : }
642 : : }
643 : 10 : }
644 : :
645 : 20 : void libspdm_copy_signature_swap_endian(
646 : : uint32_t base_asym_algo,
647 : : uint8_t* dst,
648 : : size_t dst_size,
649 : : const uint8_t* src,
650 : : size_t src_size)
651 : : {
652 : 20 : const uint32_t spdm_10_11_rsa_algos =
653 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 |
654 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 |
655 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 |
656 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 |
657 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 |
658 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096;
659 : :
660 : 20 : const uint32_t spdm_10_11_ecdsa_algos =
661 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 |
662 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 |
663 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521;
664 : :
665 [ + + ]: 20 : if (base_asym_algo & spdm_10_11_rsa_algos) {
666 : 10 : libspdm_copy_signature_swap_endian_rsa(dst, dst_size, src, src_size);
667 [ + - ]: 10 : } else if (base_asym_algo & spdm_10_11_ecdsa_algos) {
668 : 10 : libspdm_copy_signature_swap_endian_ecdsa(dst, dst_size, src, src_size);
669 : : } else {
670 : : /* Currently do not expect asymmetric algorithms other than RSA and ECDSA */
671 : 0 : LIBSPDM_ASSERT(0);
672 : : }
673 : 20 : }
674 : :
675 : : /**
676 : : * libspdm_is_palindrome
677 : : * Checks to see if a buffer is a palindrome.
678 : : * If the buffer is a palindrome, it is the same for both endians,
679 : : * and therefore endianness cannot be determined.
680 : : **/
681 : 69 : bool libspdm_is_palindrome(const uint8_t* buf, size_t buf_size)
682 : : {
683 : : size_t head;
684 : : size_t tail;
685 : :
686 : 69 : head = 0;
687 : 69 : tail = buf_size - 1;
688 : :
689 [ + + ]: 290 : while (head < tail) {
690 [ + + ]: 267 : if (buf[head] != buf[tail]) {
691 : 46 : return false;
692 : : }
693 : 221 : head++;
694 : 221 : tail--;
695 : : }
696 : :
697 : 23 : return true;
698 : : }
699 : :
700 : 52 : bool libspdm_is_signature_buffer_palindrome(
701 : : uint32_t base_asym_algo, const uint8_t *buf, size_t buf_size)
702 : : {
703 : 52 : const uint32_t spdm_10_11_rsa_algos =
704 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 |
705 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 |
706 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 |
707 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 |
708 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 |
709 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096;
710 : :
711 : 52 : const uint32_t spdm_10_11_ecdsa_algos =
712 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 |
713 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 |
714 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521;
715 : :
716 [ + + ]: 52 : if (base_asym_algo & spdm_10_11_rsa_algos) {
717 : 27 : return libspdm_is_palindrome(buf, buf_size);
718 [ + - ]: 25 : } else if (base_asym_algo & spdm_10_11_ecdsa_algos) {
719 : 25 : const size_t x_size = buf_size / 2;
720 : 25 : const size_t y_size = x_size;
721 : :
722 : 25 : const uint8_t *x = buf;
723 : 25 : const uint8_t *y = buf + x_size;
724 : :
725 [ + + + + ]: 25 : return libspdm_is_palindrome(x, x_size) && libspdm_is_palindrome(y, y_size);
726 : : } else {
727 : : /* Currently do not expect asymmetric algorithms other than RSA and ECDSA */
728 : 0 : LIBSPDM_ASSERT(0);
729 : 0 : return false;
730 : : }
731 : : }
732 : :
733 : : #if LIBSPDM_RSA_SSA_SUPPORT
734 : 33 : static bool libspdm_rsa_pkcs1_verify_with_nid_wrap (void *context, size_t hash_nid,
735 : : const uint8_t *message,
736 : : size_t message_size,
737 : : const uint8_t *signature,
738 : : size_t sig_size)
739 : : {
740 : 33 : return libspdm_rsa_pkcs1_verify_with_nid (context, hash_nid,
741 : : message, message_size, signature, sig_size);
742 : : }
743 : : #endif
744 : :
745 : : #if LIBSPDM_RSA_PSS_SUPPORT
746 : 0 : static bool libspdm_rsa_pss_verify_wrap (void *context, size_t hash_nid,
747 : : const uint8_t *message,
748 : : size_t message_size,
749 : : const uint8_t *signature,
750 : : size_t sig_size)
751 : : {
752 : 0 : return libspdm_rsa_pss_verify (context, hash_nid, message, message_size, signature, sig_size);
753 : : }
754 : : #endif
755 : :
756 : : #if LIBSPDM_ECDSA_SUPPORT
757 : 87 : static bool libspdm_ecdsa_verify_wrap (void *context, size_t hash_nid,
758 : : const uint8_t *message,
759 : : size_t message_size,
760 : : const uint8_t *signature,
761 : : size_t sig_size)
762 : : {
763 : 87 : return libspdm_ecdsa_verify (context, hash_nid, message, message_size, signature, sig_size);
764 : : }
765 : : #endif
766 : :
767 : : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
768 : : static bool libspdm_eddsa_verify_wrap (void *context, size_t hash_nid,
769 : : const uint8_t *param, size_t param_size,
770 : : const uint8_t *message,
771 : : size_t message_size,
772 : : const uint8_t *signature,
773 : : size_t sig_size)
774 : : {
775 : : return libspdm_eddsa_verify (context, hash_nid, param, param_size,
776 : : message, message_size, signature, sig_size);
777 : : }
778 : : #endif
779 : :
780 : : #if LIBSPDM_SM2_DSA_SUPPORT
781 : : static bool libspdm_sm2_dsa_verify_wrap (void *context, size_t hash_nid,
782 : : const uint8_t *param, size_t param_size,
783 : : const uint8_t *message,
784 : : size_t message_size,
785 : : const uint8_t *signature,
786 : : size_t sig_size)
787 : : {
788 : : return libspdm_sm2_dsa_verify (context, hash_nid, param, param_size,
789 : : message, message_size, signature, sig_size);
790 : : }
791 : : #endif
792 : :
793 : 120 : static bool libspdm_asym_verify_wrap(
794 : : void *context, size_t hash_nid, uint32_t base_asym_algo,
795 : : const uint8_t *param, size_t param_size,
796 : : const uint8_t *message, size_t message_size,
797 : : const uint8_t *signature, size_t sig_size)
798 : : {
799 [ + - + - : 120 : switch (base_asym_algo) {
- - ]
800 : 33 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048:
801 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072:
802 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096:
803 : : #if LIBSPDM_RSA_SSA_SUPPORT
804 : : #if !LIBSPDM_RSA_SSA_2048_SUPPORT
805 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048);
806 : : #endif
807 : : #if !LIBSPDM_RSA_SSA_3072_SUPPORT
808 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072);
809 : : #endif
810 : : #if !LIBSPDM_RSA_SSA_4096_SUPPORT
811 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096);
812 : : #endif
813 : 33 : return libspdm_rsa_pkcs1_verify_with_nid_wrap(context, hash_nid,
814 : : message, message_size,
815 : : signature, sig_size);
816 : : #else
817 : : LIBSPDM_ASSERT(false);
818 : : return false;
819 : : #endif
820 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048:
821 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072:
822 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096:
823 : : #if LIBSPDM_RSA_PSS_SUPPORT
824 : : #if !LIBSPDM_RSA_PSS_2048_SUPPORT
825 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048);
826 : : #endif
827 : : #if !LIBSPDM_RSA_PSS_3072_SUPPORT
828 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072);
829 : : #endif
830 : : #if !LIBSPDM_RSA_PSS_4096_SUPPORT
831 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096);
832 : : #endif
833 : 0 : return libspdm_rsa_pss_verify_wrap(context, hash_nid,
834 : : message, message_size,
835 : : signature, sig_size);
836 : : #else
837 : : LIBSPDM_ASSERT(false);
838 : : return false;
839 : : #endif
840 : 87 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256:
841 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384:
842 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521:
843 : : #if LIBSPDM_ECDSA_SUPPORT
844 : : #if !LIBSPDM_ECDSA_P256_SUPPORT
845 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256);
846 : : #endif
847 : : #if !LIBSPDM_ECDSA_P384_SUPPORT
848 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384);
849 : : #endif
850 : : #if !LIBSPDM_ECDSA_P521_SUPPORT
851 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521);
852 : : #endif
853 : 87 : return libspdm_ecdsa_verify_wrap(context, hash_nid,
854 : : message, message_size,
855 : : signature, sig_size);
856 : : #else
857 : : LIBSPDM_ASSERT(false);
858 : : return false;
859 : : #endif
860 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
861 : : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
862 : : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
863 : : #if !LIBSPDM_EDDSA_ED25519_SUPPORT
864 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519);
865 : : #endif
866 : : #if !LIBSPDM_EDDSA_ED448_SUPPORT
867 : : LIBSPDM_ASSERT(base_asym_algo!= SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448);
868 : : #endif
869 : : return libspdm_eddsa_verify_wrap(context, hash_nid,
870 : : param, param_size,
871 : : message, message_size,
872 : : signature, sig_size);
873 : : #else
874 : 0 : LIBSPDM_ASSERT(false);
875 : 0 : return false;
876 : : #endif
877 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
878 : : #if LIBSPDM_SM2_DSA_SUPPORT
879 : : return libspdm_sm2_dsa_verify_wrap(context, hash_nid,
880 : : param, param_size,
881 : : message, message_size,
882 : : signature, sig_size);
883 : : #else
884 : 0 : LIBSPDM_ASSERT(false);
885 : 0 : return false;
886 : : #endif
887 : 0 : default:
888 : 0 : LIBSPDM_ASSERT(false);
889 : 0 : return false;
890 : : }
891 : : }
892 : :
893 : 0 : bool libspdm_asym_verify_ex(
894 : : spdm_version_number_t spdm_version, uint8_t op_code,
895 : : uint32_t base_asym_algo, uint32_t base_hash_algo,
896 : : void *context,
897 : : const uint8_t *message, size_t message_size,
898 : : const uint8_t *signature, size_t sig_size,
899 : : uint8_t *endian)
900 : : {
901 : : bool need_hash;
902 : : uint8_t message_hash[LIBSPDM_MAX_HASH_SIZE];
903 : : size_t hash_size;
904 : : bool result;
905 : : size_t hash_nid;
906 : : uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
907 : : LIBSPDM_MAX_HASH_SIZE];
908 : : const void *param;
909 : : size_t param_size;
910 : :
911 : : bool try_big_endian;
912 : : bool try_little_endian;
913 : : bool little_endian_succeeded;
914 : : uint8_t endian_swapped_signature[LIBSPDM_MAX_ASYM_SIG_SIZE];
915 : :
916 : 0 : hash_nid = libspdm_get_hash_nid(base_hash_algo);
917 : 0 : need_hash = libspdm_asym_func_need_hash(base_asym_algo);
918 : :
919 : 0 : param = NULL;
920 : 0 : param_size = 0;
921 : :
922 [ # # ]: 0 : if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
923 : : /* Need use SPDM 1.2 signing. */
924 [ # # # # ]: 0 : switch (base_asym_algo) {
925 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
926 : 0 : param = "";
927 : 0 : param_size = 0;
928 : 0 : break;
929 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
930 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
931 : 0 : break;
932 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
933 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
934 : 0 : param = libspdm_get_signing_context_string (spdm_version, op_code, false, ¶m_size);
935 : 0 : break;
936 : 0 : default:
937 : : /* pass thru for rest algorithm */
938 : 0 : break;
939 : : }
940 : :
941 : 0 : libspdm_create_signing_context (spdm_version, op_code, false,
942 : : spdm12_signing_context_with_hash);
943 : 0 : hash_size = libspdm_get_hash_size(base_hash_algo);
944 : 0 : result = libspdm_hash_all(base_hash_algo, message, message_size,
945 : : &spdm12_signing_context_with_hash[
946 : : SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]);
947 [ # # ]: 0 : if (!result) {
948 : 0 : return false;
949 : : }
950 : :
951 : : /* re-assign message and message_size for signing */
952 : 0 : message = spdm12_signing_context_with_hash;
953 : 0 : message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
954 : 0 : try_big_endian = true;
955 : 0 : try_little_endian = false;
956 : 0 : little_endian_succeeded = false;
957 : : /* Passthru */
958 : : } else {
959 : 0 : try_big_endian =
960 : 0 : (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY
961 [ # # # # ]: 0 : || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
962 : :
963 : 0 : try_little_endian =
964 : 0 : (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY
965 [ # # # # ]: 0 : || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
966 : :
967 : 0 : little_endian_succeeded = false;
968 : : }
969 : :
970 [ # # ]: 0 : if (need_hash) {
971 : 0 : hash_size = libspdm_get_hash_size(base_hash_algo);
972 : 0 : result = libspdm_hash_all(base_hash_algo, message, message_size, message_hash);
973 [ # # ]: 0 : if (!result) {
974 : 0 : return false;
975 : : }
976 : 0 : result = false;
977 [ # # ]: 0 : if (try_big_endian) {
978 : 0 : result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
979 : : param, param_size,
980 : : message_hash, hash_size,
981 : : signature, sig_size);
982 : : }
983 [ # # # # ]: 0 : if (!result && try_little_endian) {
984 : 0 : libspdm_copy_signature_swap_endian(
985 : : base_asym_algo,
986 : : endian_swapped_signature, sizeof(endian_swapped_signature),
987 : : signature, sig_size);
988 : :
989 : 0 : result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
990 : : param, param_size,
991 : : message_hash, hash_size,
992 : : endian_swapped_signature, sig_size);
993 : 0 : little_endian_succeeded = result;
994 : : }
995 : : } else {
996 : 0 : result = false;
997 [ # # ]: 0 : if (try_big_endian) {
998 : 0 : result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
999 : : param, param_size,
1000 : : message, message_size,
1001 : : signature, sig_size);
1002 : : }
1003 [ # # # # ]: 0 : if (!result && try_little_endian) {
1004 : 0 : libspdm_copy_signature_swap_endian(
1005 : : base_asym_algo,
1006 : : endian_swapped_signature, sizeof(endian_swapped_signature),
1007 : : signature, sig_size);
1008 : :
1009 : 0 : result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
1010 : : param, param_size,
1011 : : message, message_size,
1012 : : endian_swapped_signature, sig_size);
1013 : 0 : little_endian_succeeded = result;
1014 : : }
1015 : : }
1016 [ # # # # : 0 : if (try_big_endian && try_little_endian && result) {
# # ]
1017 [ # # ]: 0 : if (!libspdm_is_signature_buffer_palindrome(base_asym_algo, signature, sig_size)) {
1018 [ # # ]: 0 : if (little_endian_succeeded) {
1019 : 0 : *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY;
1020 : : } else {
1021 : 0 : *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
1022 : : }
1023 : : }
1024 : : }
1025 : 0 : return result;
1026 : : }
1027 : :
1028 : :
1029 : 85 : bool libspdm_asym_verify_hash_ex(
1030 : : spdm_version_number_t spdm_version, uint8_t op_code,
1031 : : uint32_t base_asym_algo, uint32_t base_hash_algo,
1032 : : void *context, const uint8_t *message_hash,
1033 : : size_t hash_size, const uint8_t *signature,
1034 : : size_t sig_size, uint8_t *endian)
1035 : : {
1036 : : bool need_hash;
1037 : : uint8_t *message;
1038 : : size_t message_size;
1039 : : uint8_t full_message_hash[LIBSPDM_MAX_HASH_SIZE];
1040 : : bool result;
1041 : : size_t hash_nid;
1042 : : uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
1043 : : LIBSPDM_MAX_HASH_SIZE];
1044 : : const void *param;
1045 : : size_t param_size;
1046 : :
1047 : : bool try_big_endian;
1048 : : bool try_little_endian;
1049 : : bool little_endian_succeeded;
1050 : : uint8_t endian_swapped_signature[LIBSPDM_MAX_ASYM_SIG_SIZE];
1051 : :
1052 : 85 : hash_nid = libspdm_get_hash_nid(base_hash_algo);
1053 : 85 : need_hash = libspdm_asym_func_need_hash(base_asym_algo);
1054 [ - + ]: 85 : LIBSPDM_ASSERT (hash_size == libspdm_get_hash_size(base_hash_algo));
1055 : :
1056 : 85 : param = NULL;
1057 : 85 : param_size = 0;
1058 : 85 : try_big_endian = true;
1059 : 85 : try_little_endian = false;
1060 : 85 : little_endian_succeeded = false;
1061 : :
1062 [ + + ]: 85 : if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
1063 : : /* Need use SPDM 1.2 signing */
1064 [ - - - + ]: 22 : switch (base_asym_algo) {
1065 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
1066 : 0 : param = "";
1067 : 0 : param_size = 0;
1068 : 0 : break;
1069 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
1070 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1071 : 0 : break;
1072 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
1073 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1074 : 0 : param = libspdm_get_signing_context_string (spdm_version, op_code, false, ¶m_size);
1075 : 0 : break;
1076 : 22 : default:
1077 : : /* pass thru for rest algorithm */
1078 : 22 : break;
1079 : : }
1080 : :
1081 : 22 : libspdm_create_signing_context (spdm_version, op_code, false,
1082 : : spdm12_signing_context_with_hash);
1083 : 22 : libspdm_copy_mem(&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE],
1084 : : sizeof(spdm12_signing_context_with_hash)
1085 : : - (&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]
1086 : : - spdm12_signing_context_with_hash),
1087 : : message_hash, hash_size);
1088 : :
1089 : : /* assign message and message_size for signing */
1090 : 22 : message = spdm12_signing_context_with_hash;
1091 : 22 : message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
1092 : :
1093 [ + - ]: 22 : if (need_hash) {
1094 : 22 : result = libspdm_hash_all(base_hash_algo, message, message_size, full_message_hash);
1095 [ - + ]: 22 : if (!result) {
1096 : 0 : return false;
1097 : : }
1098 : 22 : return libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
1099 : : param, param_size,
1100 : : full_message_hash, hash_size,
1101 : : signature, sig_size);
1102 : : } else {
1103 : 0 : return libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
1104 : : param, param_size,
1105 : : message, message_size,
1106 : : signature, sig_size);
1107 : : }
1108 : : /* SPDM 1.2 signing done. */
1109 : : } else {
1110 : 63 : try_big_endian =
1111 : 63 : (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY
1112 [ + + + + ]: 63 : || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
1113 : :
1114 : 63 : try_little_endian =
1115 : 63 : (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY
1116 [ + + + + ]: 63 : || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
1117 : :
1118 : 63 : little_endian_succeeded = false;
1119 : : }
1120 : :
1121 [ + - ]: 63 : if (need_hash) {
1122 : 63 : result = false;
1123 [ + + ]: 63 : if (try_big_endian) {
1124 : 59 : result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
1125 : : param, param_size,
1126 : : message_hash, hash_size,
1127 : : signature, sig_size);
1128 : : }
1129 [ + + + + ]: 63 : if (!result && try_little_endian) {
1130 : 6 : libspdm_copy_signature_swap_endian(
1131 : : base_asym_algo,
1132 : : endian_swapped_signature, sizeof(endian_swapped_signature),
1133 : : signature, sig_size);
1134 : :
1135 : 6 : result = libspdm_asym_verify_wrap(context, hash_nid, base_asym_algo,
1136 : : param, param_size,
1137 : : message_hash, hash_size,
1138 : : endian_swapped_signature, sig_size);
1139 : 6 : little_endian_succeeded = result;
1140 : : }
1141 [ + + + + : 63 : if (try_big_endian && try_little_endian && result) {
+ - ]
1142 [ + - ]: 4 : if (!libspdm_is_signature_buffer_palindrome(base_asym_algo, signature, sig_size)) {
1143 [ + + ]: 4 : if (little_endian_succeeded) {
1144 : 2 : *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY;
1145 : : } else {
1146 : 2 : *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
1147 : : }
1148 : : }
1149 : : }
1150 : 63 : return result;
1151 : :
1152 : : } else {
1153 : 0 : LIBSPDM_ASSERT(false);
1154 : 0 : return false;
1155 : : }
1156 : : }
1157 : :
1158 : 0 : bool libspdm_asym_verify(
1159 : : spdm_version_number_t spdm_version, uint8_t op_code,
1160 : : uint32_t base_asym_algo, uint32_t base_hash_algo,
1161 : : void* context, const uint8_t* message,
1162 : : size_t message_size, const uint8_t* signature,
1163 : : size_t sig_size)
1164 : : {
1165 : 0 : uint8_t endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
1166 : 0 : return libspdm_asym_verify_ex(
1167 : : spdm_version, op_code, base_asym_algo, base_hash_algo,
1168 : : context, message, message_size, signature, sig_size, &endian);
1169 : : }
1170 : :
1171 : 0 : bool libspdm_asym_verify_hash(
1172 : : spdm_version_number_t spdm_version, uint8_t op_code,
1173 : : uint32_t base_asym_algo, uint32_t base_hash_algo,
1174 : : void* context, const uint8_t* message_hash,
1175 : : size_t hash_size, const uint8_t* signature,
1176 : : size_t sig_size)
1177 : : {
1178 : 0 : uint8_t endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
1179 : 0 : return libspdm_asym_verify_hash_ex(
1180 : : spdm_version, op_code, base_asym_algo, base_hash_algo,
1181 : : context, message_hash, hash_size, signature, sig_size, &endian);
1182 : : }
1183 : :
1184 : 103 : bool libspdm_asym_sign(
1185 : : spdm_version_number_t spdm_version, uint8_t op_code,
1186 : : uint32_t base_asym_algo, uint32_t base_hash_algo,
1187 : : void *context, const uint8_t *message,
1188 : : size_t message_size, uint8_t *signature,
1189 : : size_t *sig_size)
1190 : : {
1191 : : bool need_hash;
1192 : : uint8_t message_hash[LIBSPDM_MAX_HASH_SIZE];
1193 : : size_t hash_size;
1194 : : bool result;
1195 : : size_t hash_nid;
1196 : : uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
1197 : : LIBSPDM_MAX_HASH_SIZE];
1198 : : const void *param;
1199 : : size_t param_size;
1200 : :
1201 : 103 : hash_nid = libspdm_get_hash_nid(base_hash_algo);
1202 : 103 : need_hash = libspdm_asym_func_need_hash(base_asym_algo);
1203 : :
1204 : 103 : param = NULL;
1205 : 103 : param_size = 0;
1206 : :
1207 [ + + ]: 103 : if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
1208 : : /* Need use SPDM 1.2 signing */
1209 [ - - - + ]: 23 : switch (base_asym_algo) {
1210 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
1211 : 0 : param = "";
1212 : 0 : param_size = 0;
1213 : 0 : break;
1214 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
1215 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1216 : 0 : break;
1217 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
1218 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1219 : 0 : param = libspdm_get_signing_context_string (spdm_version, op_code, false, ¶m_size);
1220 : 0 : break;
1221 : 23 : default:
1222 : : /* pass thru for rest algorithm */
1223 : 23 : break;
1224 : : }
1225 : :
1226 : 23 : libspdm_create_signing_context (spdm_version, op_code, false,
1227 : : spdm12_signing_context_with_hash);
1228 : 23 : hash_size = libspdm_get_hash_size(base_hash_algo);
1229 : 23 : result = libspdm_hash_all(base_hash_algo, message, message_size,
1230 : : &spdm12_signing_context_with_hash[
1231 : : SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]);
1232 [ - + ]: 23 : if (!result) {
1233 : 0 : return false;
1234 : : }
1235 : :
1236 : : /* re-assign message and message_size for signing */
1237 : 23 : message = spdm12_signing_context_with_hash;
1238 : 23 : message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
1239 : :
1240 : : /* Passthru*/
1241 : : }
1242 : :
1243 [ + - ]: 103 : if (need_hash) {
1244 : 103 : hash_size = libspdm_get_hash_size(base_hash_algo);
1245 : 103 : result = libspdm_hash_all(base_hash_algo, message, message_size, message_hash);
1246 [ - + ]: 103 : if (!result) {
1247 : 0 : return false;
1248 : : }
1249 : 103 : return libspdm_asym_sign_wrap(context, hash_nid, base_asym_algo,
1250 : : param, param_size,
1251 : : message_hash, hash_size,
1252 : : signature, sig_size);
1253 : : } else {
1254 : 0 : return libspdm_asym_sign_wrap(context, hash_nid, base_asym_algo,
1255 : : param, param_size,
1256 : : message, message_size,
1257 : : signature, sig_size);
1258 : : }
1259 : : }
1260 : :
1261 : 54 : bool libspdm_asym_sign_hash(
1262 : : spdm_version_number_t spdm_version, uint8_t op_code,
1263 : : uint32_t base_asym_algo, uint32_t base_hash_algo,
1264 : : void *context, const uint8_t *message_hash,
1265 : : size_t hash_size, uint8_t *signature,
1266 : : size_t *sig_size)
1267 : : {
1268 : : bool need_hash;
1269 : : uint8_t *message;
1270 : : size_t message_size;
1271 : : uint8_t full_message_hash[LIBSPDM_MAX_HASH_SIZE];
1272 : : bool result;
1273 : : size_t hash_nid;
1274 : : uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
1275 : : LIBSPDM_MAX_HASH_SIZE];
1276 : : const void *param;
1277 : : size_t param_size;
1278 : :
1279 : 54 : hash_nid = libspdm_get_hash_nid(base_hash_algo);
1280 : 54 : need_hash = libspdm_asym_func_need_hash(base_asym_algo);
1281 [ - + ]: 54 : LIBSPDM_ASSERT (hash_size == libspdm_get_hash_size(base_hash_algo));
1282 : :
1283 : 54 : param = NULL;
1284 : 54 : param_size = 0;
1285 : :
1286 [ + + ]: 54 : if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
1287 : : /* Need use SPDM 1.2 signing */
1288 [ - - - + ]: 14 : switch (base_asym_algo) {
1289 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
1290 : 0 : param = "";
1291 : 0 : param_size = 0;
1292 : 0 : break;
1293 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
1294 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1295 : 0 : break;
1296 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
1297 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1298 : 0 : param = libspdm_get_signing_context_string (spdm_version, op_code, false, ¶m_size);
1299 : 0 : break;
1300 : 14 : default:
1301 : : /* pass thru for rest algorithm */
1302 : 14 : break;
1303 : : }
1304 : :
1305 : 14 : libspdm_create_signing_context (spdm_version, op_code, false,
1306 : : spdm12_signing_context_with_hash);
1307 : 14 : libspdm_copy_mem(&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE],
1308 : : sizeof(spdm12_signing_context_with_hash)
1309 : : - (&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]
1310 : : - spdm12_signing_context_with_hash),
1311 : : message_hash, hash_size);
1312 : :
1313 : : /* assign message and message_size for signing */
1314 : 14 : message = spdm12_signing_context_with_hash;
1315 : 14 : message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
1316 : :
1317 [ + - ]: 14 : if (need_hash) {
1318 : 14 : result = libspdm_hash_all(base_hash_algo, message, message_size, full_message_hash);
1319 [ - + ]: 14 : if (!result) {
1320 : 0 : return false;
1321 : : }
1322 : 14 : return libspdm_asym_sign_wrap(context, hash_nid, base_asym_algo,
1323 : : param, param_size,
1324 : : full_message_hash, hash_size,
1325 : : signature, sig_size);
1326 : : } else {
1327 : 0 : return libspdm_asym_sign_wrap(context, hash_nid, base_asym_algo,
1328 : : param, param_size,
1329 : : message, message_size,
1330 : : signature, sig_size);
1331 : : }
1332 : :
1333 : : /* SPDM 1.2 signing done. */
1334 : : }
1335 : :
1336 [ + - ]: 40 : if (need_hash) {
1337 : 40 : return libspdm_asym_sign_wrap(context, hash_nid, base_asym_algo,
1338 : : param, param_size,
1339 : : message_hash, hash_size,
1340 : : signature, sig_size);
1341 : : } else {
1342 : 0 : LIBSPDM_ASSERT (false);
1343 : 0 : return false;
1344 : : }
1345 : : }
1346 : :
1347 : 118 : uint32_t libspdm_get_req_asym_signature_size(uint16_t req_base_asym_alg)
1348 : : {
1349 : 118 : return libspdm_get_asym_signature_size(req_base_asym_alg);
1350 : : }
1351 : :
1352 : 74 : void libspdm_req_asym_free(uint16_t req_base_asym_alg, void *context)
1353 : : {
1354 : 74 : libspdm_asym_free(req_base_asym_alg, context);
1355 : 74 : }
1356 : :
1357 : 4 : bool libspdm_req_asym_get_public_key_from_der(uint16_t req_base_asym_alg,
1358 : : const uint8_t *der_data,
1359 : : size_t der_size,
1360 : : void **context)
1361 : : {
1362 : 4 : return libspdm_asym_get_public_key_from_der_wrap(req_base_asym_alg,
1363 : : der_data,
1364 : : der_size,
1365 : : context);
1366 : : }
1367 : :
1368 : 73 : static bool libspdm_req_asym_func_need_hash(uint16_t req_base_asym_alg)
1369 : : {
1370 : 73 : return libspdm_asym_func_need_hash(req_base_asym_alg);
1371 : : }
1372 : :
1373 : 0 : bool libspdm_req_asym_verify_ex(
1374 : : spdm_version_number_t spdm_version, uint8_t op_code,
1375 : : uint16_t req_base_asym_alg,
1376 : : uint32_t base_hash_algo, void *context,
1377 : : const uint8_t *message, size_t message_size,
1378 : : const uint8_t *signature, size_t sig_size, uint8_t *endian)
1379 : : {
1380 : : bool need_hash;
1381 : : uint8_t message_hash[LIBSPDM_MAX_HASH_SIZE];
1382 : : size_t hash_size;
1383 : : bool result;
1384 : : size_t hash_nid;
1385 : : uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
1386 : : LIBSPDM_MAX_HASH_SIZE];
1387 : : const void *param;
1388 : : size_t param_size;
1389 : :
1390 : : bool try_big_endian;
1391 : : bool try_little_endian;
1392 : : bool little_endian_succeeded;
1393 : : uint8_t endian_swapped_signature[LIBSPDM_MAX_ASYM_SIG_SIZE];
1394 : :
1395 : 0 : hash_nid = libspdm_get_hash_nid(base_hash_algo);
1396 : 0 : need_hash = libspdm_req_asym_func_need_hash(req_base_asym_alg);
1397 : :
1398 : 0 : param = NULL;
1399 : 0 : param_size = 0;
1400 : :
1401 [ # # ]: 0 : if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
1402 : : /* Need use SPDM 1.2 signing */
1403 [ # # # # ]: 0 : switch (req_base_asym_alg) {
1404 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
1405 : 0 : param = "";
1406 : 0 : param_size = 0;
1407 : 0 : break;
1408 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
1409 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1410 : 0 : break;
1411 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
1412 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1413 : 0 : param = libspdm_get_signing_context_string (spdm_version, op_code, true, ¶m_size);
1414 : 0 : break;
1415 : 0 : default:
1416 : : /* pass thru for rest algorithm */
1417 : 0 : break;
1418 : : }
1419 : :
1420 : 0 : libspdm_create_signing_context (spdm_version, op_code, true,
1421 : : spdm12_signing_context_with_hash);
1422 : 0 : hash_size = libspdm_get_hash_size(base_hash_algo);
1423 : 0 : result = libspdm_hash_all(base_hash_algo, message, message_size,
1424 : : &spdm12_signing_context_with_hash[
1425 : : SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]);
1426 [ # # ]: 0 : if (!result) {
1427 : 0 : return false;
1428 : : }
1429 : :
1430 : : /* re-assign message and message_size for signing */
1431 : 0 : message = spdm12_signing_context_with_hash;
1432 : 0 : message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
1433 : 0 : try_big_endian = true;
1434 : 0 : try_little_endian = false;
1435 : 0 : little_endian_succeeded = false;
1436 : : /* Passthru */
1437 : : } else {
1438 : 0 : try_big_endian =
1439 : 0 : (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY
1440 [ # # # # ]: 0 : || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
1441 : :
1442 : 0 : try_little_endian =
1443 : 0 : (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY
1444 [ # # # # ]: 0 : || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
1445 : :
1446 : 0 : little_endian_succeeded = false;
1447 : : }
1448 : :
1449 [ # # ]: 0 : if (need_hash) {
1450 : 0 : hash_size = libspdm_get_hash_size(base_hash_algo);
1451 : 0 : result = libspdm_hash_all(base_hash_algo, message, message_size, message_hash);
1452 [ # # ]: 0 : if (!result) {
1453 : 0 : return false;
1454 : : }
1455 : 0 : result = false;
1456 [ # # ]: 0 : if (try_big_endian) {
1457 : 0 : result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
1458 : : param, param_size,
1459 : : message_hash, hash_size,
1460 : : signature, sig_size);
1461 : : }
1462 [ # # # # ]: 0 : if (!result && try_little_endian) {
1463 : 0 : libspdm_copy_signature_swap_endian(
1464 : : req_base_asym_alg,
1465 : : endian_swapped_signature, sizeof(endian_swapped_signature),
1466 : : signature, sig_size);
1467 : :
1468 : 0 : result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
1469 : : param, param_size,
1470 : : message_hash, hash_size,
1471 : : endian_swapped_signature, sig_size);
1472 : 0 : little_endian_succeeded = result;
1473 : : }
1474 : : } else {
1475 : 0 : result = false;
1476 [ # # ]: 0 : if (try_big_endian) {
1477 : 0 : result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
1478 : : param, param_size,
1479 : : message, message_size,
1480 : : signature, sig_size);
1481 : : }
1482 [ # # # # ]: 0 : if (!result && try_little_endian) {
1483 : 0 : libspdm_copy_signature_swap_endian(
1484 : : req_base_asym_alg,
1485 : : endian_swapped_signature, sizeof(endian_swapped_signature),
1486 : : signature, sig_size);
1487 : :
1488 : 0 : result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
1489 : : param, param_size,
1490 : : message, message_size,
1491 : : endian_swapped_signature, sig_size);
1492 : 0 : little_endian_succeeded = result;
1493 : : }
1494 : : }
1495 [ # # # # : 0 : if (try_big_endian && try_little_endian && result) {
# # ]
1496 [ # # ]: 0 : if (!libspdm_is_signature_buffer_palindrome(req_base_asym_alg, signature, sig_size)) {
1497 [ # # ]: 0 : if (little_endian_succeeded) {
1498 : 0 : *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY;
1499 : : } else {
1500 : 0 : *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
1501 : : }
1502 : : }
1503 : : }
1504 : 0 : return result;
1505 : : }
1506 : :
1507 : 32 : bool libspdm_req_asym_verify_hash_ex(
1508 : : spdm_version_number_t spdm_version, uint8_t op_code,
1509 : : uint16_t req_base_asym_alg,
1510 : : uint32_t base_hash_algo, void *context,
1511 : : const uint8_t *message_hash, size_t hash_size,
1512 : : const uint8_t *signature, size_t sig_size, uint8_t *endian)
1513 : : {
1514 : : bool need_hash;
1515 : : uint8_t *message;
1516 : : size_t message_size;
1517 : : uint8_t full_message_hash[LIBSPDM_MAX_HASH_SIZE];
1518 : : bool result;
1519 : : size_t hash_nid;
1520 : : uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
1521 : : LIBSPDM_MAX_HASH_SIZE];
1522 : : const void *param;
1523 : : size_t param_size;
1524 : :
1525 : : bool try_big_endian;
1526 : : bool try_little_endian;
1527 : : bool little_endian_succeeded;
1528 : : uint8_t endian_swapped_signature[LIBSPDM_MAX_ASYM_SIG_SIZE];
1529 : :
1530 : 32 : hash_nid = libspdm_get_hash_nid(base_hash_algo);
1531 : 32 : need_hash = libspdm_req_asym_func_need_hash(req_base_asym_alg);
1532 [ - + ]: 32 : LIBSPDM_ASSERT (hash_size == libspdm_get_hash_size(base_hash_algo));
1533 : :
1534 : 32 : param = NULL;
1535 : 32 : param_size = 0;
1536 : :
1537 [ + + ]: 32 : if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
1538 : : /* Need use SPDM 1.2 signing */
1539 [ - - - + ]: 10 : switch (req_base_asym_alg) {
1540 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
1541 : 0 : param = "";
1542 : 0 : param_size = 0;
1543 : 0 : break;
1544 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
1545 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1546 : 0 : break;
1547 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
1548 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1549 : 0 : param = libspdm_get_signing_context_string (spdm_version, op_code, true, ¶m_size);
1550 : 0 : break;
1551 : 10 : default:
1552 : : /* pass thru for rest algorithm */
1553 : 10 : break;
1554 : : }
1555 : :
1556 : 10 : libspdm_create_signing_context (spdm_version, op_code, true,
1557 : : spdm12_signing_context_with_hash);
1558 : 10 : libspdm_copy_mem(&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE],
1559 : : sizeof(spdm12_signing_context_with_hash)
1560 : : - (&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]
1561 : : - spdm12_signing_context_with_hash),
1562 : : message_hash, hash_size);
1563 : :
1564 : : /* assign message and message_size for signing */
1565 : 10 : message = spdm12_signing_context_with_hash;
1566 : 10 : message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
1567 : :
1568 [ + - ]: 10 : if (need_hash) {
1569 : 10 : result = libspdm_hash_all(base_hash_algo, message, message_size,
1570 : : full_message_hash);
1571 [ - + ]: 10 : if (!result) {
1572 : 0 : return false;
1573 : : }
1574 : 10 : return libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
1575 : : param, param_size,
1576 : : full_message_hash, hash_size,
1577 : : signature, sig_size);
1578 : : } else {
1579 : 0 : return libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
1580 : : param, param_size,
1581 : : message, message_size,
1582 : : signature, sig_size);
1583 : : }
1584 : : /* SPDM 1.2 signing done. */
1585 : : } else {
1586 : 22 : try_big_endian =
1587 : 22 : (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY
1588 [ + + + + ]: 22 : || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
1589 : :
1590 : 22 : try_little_endian =
1591 : 22 : (*endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY
1592 [ + + + + ]: 22 : || *endian == LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE);
1593 : :
1594 : 22 : little_endian_succeeded = false;
1595 : : }
1596 : :
1597 [ + - ]: 22 : if (need_hash) {
1598 : 22 : result = false;
1599 [ + + ]: 22 : if (try_big_endian) {
1600 : 17 : result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
1601 : : param, param_size,
1602 : : message_hash, hash_size,
1603 : : signature, sig_size);
1604 : : }
1605 [ + + + + ]: 22 : if (!result && try_little_endian) {
1606 : 6 : libspdm_copy_signature_swap_endian(
1607 : : req_base_asym_alg,
1608 : : endian_swapped_signature, sizeof(endian_swapped_signature),
1609 : : signature, sig_size);
1610 : :
1611 : 6 : result = libspdm_asym_verify_wrap(context, hash_nid, req_base_asym_alg,
1612 : : param, param_size,
1613 : : message_hash, hash_size,
1614 : : endian_swapped_signature, sig_size);
1615 : 6 : little_endian_succeeded = result;
1616 : : }
1617 [ + + + + : 22 : if (try_big_endian && try_little_endian && result) {
+ - ]
1618 [ + - ]: 3 : if (!libspdm_is_signature_buffer_palindrome(req_base_asym_alg, signature, sig_size)) {
1619 [ + + ]: 3 : if (little_endian_succeeded) {
1620 : 1 : *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY;
1621 : : } else {
1622 : 2 : *endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
1623 : : }
1624 : : }
1625 : : }
1626 : 22 : return result;
1627 : : } else {
1628 : 0 : LIBSPDM_ASSERT (false);
1629 : 0 : return false;
1630 : : }
1631 : : }
1632 : :
1633 : 0 : bool libspdm_req_asym_verify(
1634 : : spdm_version_number_t spdm_version, uint8_t op_code,
1635 : : uint16_t req_base_asym_alg,
1636 : : uint32_t base_hash_algo, void* context,
1637 : : const uint8_t* message, size_t message_size,
1638 : : const uint8_t* signature, size_t sig_size)
1639 : : {
1640 : 0 : uint8_t endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
1641 : 0 : return libspdm_req_asym_verify_ex(
1642 : : spdm_version, op_code, req_base_asym_alg, base_hash_algo, context,
1643 : : message, message_size, signature, sig_size, &endian);
1644 : : }
1645 : :
1646 : 0 : bool libspdm_req_asym_verify_hash(
1647 : : spdm_version_number_t spdm_version, uint8_t op_code,
1648 : : uint16_t req_base_asym_alg,
1649 : : uint32_t base_hash_algo, void* context,
1650 : : const uint8_t* message_hash, size_t hash_size,
1651 : : const uint8_t* signature, size_t sig_size)
1652 : : {
1653 : 0 : uint8_t endian = LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY;
1654 : 0 : return libspdm_req_asym_verify_hash_ex(
1655 : : spdm_version, op_code, req_base_asym_alg, base_hash_algo, context,
1656 : : message_hash, hash_size, signature, sig_size, &endian);
1657 : : }
1658 : :
1659 : 25 : bool libspdm_req_asym_sign(
1660 : : spdm_version_number_t spdm_version, uint8_t op_code,
1661 : : uint16_t req_base_asym_alg,
1662 : : uint32_t base_hash_algo, void *context,
1663 : : const uint8_t *message, size_t message_size,
1664 : : uint8_t *signature, size_t *sig_size)
1665 : : {
1666 : : bool need_hash;
1667 : : uint8_t message_hash[LIBSPDM_MAX_HASH_SIZE];
1668 : : size_t hash_size;
1669 : : bool result;
1670 : : size_t hash_nid;
1671 : : uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
1672 : : LIBSPDM_MAX_HASH_SIZE];
1673 : : const void *param;
1674 : : size_t param_size;
1675 : :
1676 : 25 : hash_nid = libspdm_get_hash_nid(base_hash_algo);
1677 : 25 : need_hash = libspdm_req_asym_func_need_hash(req_base_asym_alg);
1678 : :
1679 : 25 : param = NULL;
1680 : 25 : param_size = 0;
1681 : :
1682 [ + + ]: 25 : if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
1683 : : /* Need use SPDM 1.2 signing */
1684 [ - - - + ]: 7 : switch (req_base_asym_alg) {
1685 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
1686 : 0 : param = "";
1687 : 0 : param_size = 0;
1688 : 0 : break;
1689 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
1690 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1691 : 0 : break;
1692 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
1693 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1694 : 0 : param = libspdm_get_signing_context_string (spdm_version, op_code, true, ¶m_size);
1695 : 0 : break;
1696 : 7 : default:
1697 : : /* pass thru for rest algorithm */
1698 : 7 : break;
1699 : : }
1700 : :
1701 : 7 : libspdm_create_signing_context (spdm_version, op_code, true,
1702 : : spdm12_signing_context_with_hash);
1703 : 7 : hash_size = libspdm_get_hash_size(base_hash_algo);
1704 : 7 : result = libspdm_hash_all(base_hash_algo, message, message_size,
1705 : : &spdm12_signing_context_with_hash[
1706 : : SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]);
1707 [ - + ]: 7 : if (!result) {
1708 : 0 : return false;
1709 : : }
1710 : :
1711 : : /* re-assign message and message_size for signing */
1712 : 7 : message = spdm12_signing_context_with_hash;
1713 : 7 : message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
1714 : :
1715 : : /* Passthru */
1716 : : }
1717 : :
1718 [ + - ]: 25 : if (need_hash) {
1719 : 25 : hash_size = libspdm_get_hash_size(base_hash_algo);
1720 : 25 : result = libspdm_hash_all(base_hash_algo, message, message_size,
1721 : : message_hash);
1722 [ - + ]: 25 : if (!result) {
1723 : 0 : return false;
1724 : : }
1725 : 25 : return libspdm_asym_sign_wrap(context, hash_nid, req_base_asym_alg,
1726 : : param, param_size,
1727 : : message_hash, hash_size,
1728 : : signature, sig_size);
1729 : : } else {
1730 : 0 : return libspdm_asym_sign_wrap(context, hash_nid, req_base_asym_alg,
1731 : : param, param_size,
1732 : : message, message_size,
1733 : : signature, sig_size);
1734 : : }
1735 : : }
1736 : :
1737 : 16 : bool libspdm_req_asym_sign_hash(
1738 : : spdm_version_number_t spdm_version, uint8_t op_code,
1739 : : uint16_t req_base_asym_alg,
1740 : : uint32_t base_hash_algo, void *context,
1741 : : const uint8_t *message_hash, size_t hash_size,
1742 : : uint8_t *signature, size_t *sig_size)
1743 : : {
1744 : : bool need_hash;
1745 : : uint8_t *message;
1746 : : size_t message_size;
1747 : : uint8_t full_message_hash[LIBSPDM_MAX_HASH_SIZE];
1748 : : bool result;
1749 : : size_t hash_nid;
1750 : : uint8_t spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE +
1751 : : LIBSPDM_MAX_HASH_SIZE];
1752 : : const void *param;
1753 : : size_t param_size;
1754 : :
1755 : 16 : hash_nid = libspdm_get_hash_nid(base_hash_algo);
1756 : 16 : need_hash = libspdm_req_asym_func_need_hash(req_base_asym_alg);
1757 [ - + ]: 16 : LIBSPDM_ASSERT (hash_size == libspdm_get_hash_size(base_hash_algo));
1758 : :
1759 : 16 : param = NULL;
1760 : 16 : param_size = 0;
1761 : :
1762 [ + + ]: 16 : if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) > SPDM_MESSAGE_VERSION_11) {
1763 : : /* Need use SPDM 1.2 signing */
1764 [ - - - + ]: 6 : switch (req_base_asym_alg) {
1765 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256:
1766 : 0 : param = "";
1767 : 0 : param_size = 0;
1768 : 0 : break;
1769 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519:
1770 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1771 : 0 : break;
1772 : 0 : case SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448:
1773 : 0 : hash_nid = LIBSPDM_CRYPTO_NID_NULL;
1774 : 0 : param = libspdm_get_signing_context_string (spdm_version, op_code, true, ¶m_size);
1775 : 0 : break;
1776 : 6 : default:
1777 : : /* pass thru for rest algorithm */
1778 : 6 : break;
1779 : : }
1780 : :
1781 : 6 : libspdm_create_signing_context (spdm_version, op_code, true,
1782 : : spdm12_signing_context_with_hash);
1783 : 6 : libspdm_copy_mem(&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE],
1784 : : sizeof(spdm12_signing_context_with_hash)
1785 : : - (&spdm12_signing_context_with_hash[SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE]
1786 : : - spdm12_signing_context_with_hash),
1787 : : message_hash, hash_size);
1788 : :
1789 : : /* assign message and message_size for signing */
1790 : 6 : message = spdm12_signing_context_with_hash;
1791 : 6 : message_size = SPDM_VERSION_1_2_SIGNING_CONTEXT_SIZE + hash_size;
1792 : :
1793 [ + - ]: 6 : if (need_hash) {
1794 : 6 : result = libspdm_hash_all(base_hash_algo, message, message_size,
1795 : : full_message_hash);
1796 [ - + ]: 6 : if (!result) {
1797 : 0 : return false;
1798 : : }
1799 : 6 : return libspdm_asym_sign_wrap(context, hash_nid, req_base_asym_alg,
1800 : : param, param_size,
1801 : : full_message_hash, hash_size,
1802 : : signature, sig_size);
1803 : : } else {
1804 : 0 : return libspdm_asym_sign_wrap(context, hash_nid, req_base_asym_alg,
1805 : : param, param_size,
1806 : : message, message_size,
1807 : : signature, sig_size);
1808 : : }
1809 : :
1810 : : /* SPDM 1.2 signing done. */
1811 : : }
1812 : :
1813 [ + - ]: 10 : if (need_hash) {
1814 : 10 : return libspdm_asym_sign_wrap(context, hash_nid, req_base_asym_alg,
1815 : : param, param_size,
1816 : : message_hash, hash_size,
1817 : : signature, sig_size);
1818 : : } else {
1819 : 0 : LIBSPDM_ASSERT (false);
1820 : 0 : return false;
1821 : : }
1822 : : }
|