Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2025 DMTF. All rights reserved.
4 : * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5 : **/
6 :
7 : #include "internal/libspdm_crypt_lib.h"
8 :
9 : /**
10 : * This function returns the SPDM DHE algorithm key size.
11 : *
12 : * @param dhe_named_group SPDM dhe_named_group
13 : *
14 : * @return SPDM DHE algorithm key size.
15 : **/
16 292 : uint32_t libspdm_get_dhe_pub_key_size(uint16_t dhe_named_group)
17 : {
18 292 : switch (dhe_named_group) {
19 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
20 : #if LIBSPDM_FFDHE_2048_SUPPORT
21 0 : return 256;
22 : #else
23 : return 0;
24 : #endif
25 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
26 : #if LIBSPDM_FFDHE_3072_SUPPORT
27 0 : return 384;
28 : #else
29 : return 0;
30 : #endif
31 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
32 : #if LIBSPDM_FFDHE_4096_SUPPORT
33 0 : return 512;
34 : #else
35 : return 0;
36 : #endif
37 289 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
38 : #if LIBSPDM_ECDHE_P256_SUPPORT
39 289 : return 32 * 2;
40 : #else
41 : return 0;
42 : #endif
43 1 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
44 : #if LIBSPDM_ECDHE_P384_SUPPORT
45 1 : return 48 * 2;
46 : #else
47 : return 0;
48 : #endif
49 1 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
50 : #if LIBSPDM_ECDHE_P521_SUPPORT
51 1 : return 66 * 2;
52 : #else
53 : return 0;
54 : #endif
55 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
56 : #if LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT
57 : return 32 * 2;
58 : #else
59 0 : return 0;
60 : #endif
61 1 : default:
62 1 : return 0;
63 : }
64 : }
65 :
66 : /**
67 : * This function returns the SPDM DHE shared secret size.
68 : *
69 : * @param dhe_named_group SPDM dhe_named_group
70 : *
71 : * @return SPDM DHE shared secret size.
72 : **/
73 740 : uint32_t libspdm_get_dhe_shared_secret_size(uint16_t dhe_named_group)
74 : {
75 740 : switch (dhe_named_group) {
76 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
77 : #if LIBSPDM_FFDHE_2048_SUPPORT
78 0 : return 256;
79 : #else
80 : return 0;
81 : #endif
82 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
83 : #if LIBSPDM_FFDHE_3072_SUPPORT
84 0 : return 384;
85 : #else
86 : return 0;
87 : #endif
88 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
89 : #if LIBSPDM_FFDHE_4096_SUPPORT
90 0 : return 512;
91 : #else
92 : return 0;
93 : #endif
94 554 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
95 : #if LIBSPDM_ECDHE_P256_SUPPORT
96 554 : return 32;
97 : #else
98 : return 0;
99 : #endif
100 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
101 : #if LIBSPDM_ECDHE_P384_SUPPORT
102 0 : return 48;
103 : #else
104 : return 0;
105 : #endif
106 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
107 : #if LIBSPDM_ECDHE_P521_SUPPORT
108 0 : return 66;
109 : #else
110 : return 0;
111 : #endif
112 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
113 : #if LIBSPDM_SM2_KEY_EXCHANGE_P256_SUPPORT
114 : return 32;
115 : #else
116 0 : return 0;
117 : #endif
118 186 : default:
119 186 : return 0;
120 : }
121 : }
122 :
123 : /**
124 : * Return cipher ID, based upon the negotiated DHE algorithm.
125 : *
126 : * @param dhe_named_group SPDM dhe_named_group
127 : *
128 : * @return DHE cipher ID
129 : **/
130 168 : static size_t libspdm_get_dhe_nid(uint16_t dhe_named_group)
131 : {
132 168 : switch (dhe_named_group) {
133 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
134 0 : return LIBSPDM_CRYPTO_NID_FFDHE2048;
135 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
136 0 : return LIBSPDM_CRYPTO_NID_FFDHE3072;
137 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
138 0 : return LIBSPDM_CRYPTO_NID_FFDHE4096;
139 168 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
140 168 : return LIBSPDM_CRYPTO_NID_SECP256R1;
141 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
142 0 : return LIBSPDM_CRYPTO_NID_SECP384R1;
143 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
144 0 : return LIBSPDM_CRYPTO_NID_SECP521R1;
145 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
146 0 : return LIBSPDM_CRYPTO_NID_SM2_KEY_EXCHANGE_P256;
147 0 : default:
148 0 : return LIBSPDM_CRYPTO_NID_NULL;
149 : }
150 : }
151 :
152 168 : void *libspdm_dhe_new(spdm_version_number_t spdm_version,
153 : uint16_t dhe_named_group, bool is_initiator)
154 : {
155 : size_t nid;
156 : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
157 : void *context;
158 : bool result;
159 : uint8_t spdm12_key_change_requester_context[
160 : SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT_SIZE];
161 : uint8_t spdm12_key_change_responder_context[
162 : SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT_SIZE];
163 : #endif /* LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT */
164 :
165 168 : nid = libspdm_get_dhe_nid(dhe_named_group);
166 168 : if (nid == 0) {
167 0 : return NULL;
168 : }
169 :
170 168 : switch (dhe_named_group) {
171 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
172 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
173 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
174 : #if LIBSPDM_FFDHE_SUPPORT
175 : #if !LIBSPDM_FFDHE_2048_SUPPORT
176 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048);
177 : #endif
178 : #if !LIBSPDM_FFDHE_3072_SUPPORT
179 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072);
180 : #endif
181 : #if !LIBSPDM_FFDHE_4096_SUPPORT
182 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096);
183 : #endif
184 0 : return libspdm_dh_new_by_nid(nid);
185 : #else
186 : LIBSPDM_ASSERT(false);
187 : return NULL;
188 : #endif
189 : break;
190 168 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
191 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
192 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
193 : #if LIBSPDM_ECDHE_SUPPORT
194 : #if !LIBSPDM_ECDHE_P256_SUPPORT
195 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1);
196 : #endif
197 : #if !LIBSPDM_ECDHE_P384_SUPPORT
198 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1);
199 : #endif
200 : #if !LIBSPDM_ECDHE_P521_SUPPORT
201 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1);
202 : #endif
203 168 : return libspdm_ec_new_by_nid(nid);
204 : #else
205 : LIBSPDM_ASSERT(false);
206 : return NULL;
207 : #endif
208 : break;
209 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
210 : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
211 : context = libspdm_sm2_key_exchange_new_by_nid(nid);
212 :
213 : libspdm_copy_mem(spdm12_key_change_requester_context,
214 : sizeof(spdm12_key_change_requester_context),
215 : SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT,
216 : SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT_SIZE);
217 : libspdm_copy_mem(spdm12_key_change_responder_context,
218 : sizeof(spdm12_key_change_responder_context),
219 : SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT,
220 : SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT_SIZE);
221 : /* patch the version*/
222 : spdm12_key_change_requester_context[25] = (char)('0' + ((spdm_version >> 12) & 0xF));
223 : spdm12_key_change_requester_context[27] = (char)('0' + ((spdm_version >> 8) & 0xF));
224 : spdm12_key_change_responder_context[25] = (char)('0' + ((spdm_version >> 12) & 0xF));
225 : spdm12_key_change_responder_context[27] = (char)('0' + ((spdm_version >> 8) & 0xF));
226 :
227 : result = libspdm_sm2_key_exchange_init (context, LIBSPDM_CRYPTO_NID_SM3_256,
228 : spdm12_key_change_requester_context,
229 : SPDM_VERSION_1_2_KEY_EXCHANGE_REQUESTER_CONTEXT_SIZE,
230 : spdm12_key_change_responder_context,
231 : SPDM_VERSION_1_2_KEY_EXCHANGE_RESPONDER_CONTEXT_SIZE,
232 : is_initiator);
233 : if (!result) {
234 : libspdm_sm2_key_exchange_free (context);
235 : return NULL;
236 : }
237 : return context;
238 : #else
239 0 : LIBSPDM_ASSERT(false);
240 0 : return NULL;
241 : #endif
242 : break;
243 0 : default:
244 0 : LIBSPDM_ASSERT(false);
245 0 : return NULL;
246 : }
247 : }
248 :
249 168 : void libspdm_dhe_free(uint16_t dhe_named_group, void *context)
250 : {
251 168 : if (context == NULL) {
252 0 : return;
253 : }
254 168 : switch (dhe_named_group) {
255 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
256 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
257 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
258 : #if LIBSPDM_FFDHE_SUPPORT
259 0 : libspdm_dh_free(context);
260 : #else
261 : LIBSPDM_ASSERT(false);
262 : #endif
263 0 : break;
264 168 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
265 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
266 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
267 : #if LIBSPDM_ECDHE_SUPPORT
268 168 : libspdm_ec_free(context);
269 : #else
270 : LIBSPDM_ASSERT(false);
271 : #endif
272 168 : break;
273 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
274 : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
275 : libspdm_sm2_key_exchange_free(context);
276 : #else
277 0 : LIBSPDM_ASSERT(false);
278 : #endif
279 0 : break;
280 0 : default:
281 0 : LIBSPDM_ASSERT(false);
282 0 : break;
283 : }
284 : }
285 :
286 168 : bool libspdm_dhe_generate_key(uint16_t dhe_named_group, void *context,
287 : uint8_t *public_key,
288 : size_t *public_key_size)
289 : {
290 168 : switch (dhe_named_group) {
291 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
292 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
293 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
294 : #if LIBSPDM_FFDHE_SUPPORT
295 : #if !LIBSPDM_FFDHE_2048_SUPPORT
296 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048);
297 : #endif
298 : #if !LIBSPDM_FFDHE_3072_SUPPORT
299 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072);
300 : #endif
301 : #if !LIBSPDM_FFDHE_4096_SUPPORT
302 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096);
303 : #endif
304 0 : return libspdm_dh_generate_key(context, public_key, public_key_size);
305 : #else
306 : LIBSPDM_ASSERT(false);
307 : return false;
308 : #endif
309 168 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
310 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
311 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
312 : #if LIBSPDM_ECDHE_SUPPORT
313 : #if !LIBSPDM_ECDHE_P256_SUPPORT
314 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1);
315 : #endif
316 : #if !LIBSPDM_ECDHE_P384_SUPPORT
317 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1);
318 : #endif
319 : #if !LIBSPDM_ECDHE_P521_SUPPORT
320 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1);
321 : #endif
322 168 : return libspdm_ec_generate_key(context, public_key, public_key_size);
323 : #else
324 : LIBSPDM_ASSERT(false);
325 : return false;
326 : #endif
327 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
328 : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
329 : return libspdm_sm2_key_exchange_generate_key(context, public_key, public_key_size);
330 : #else
331 0 : LIBSPDM_ASSERT(false);
332 0 : return false;
333 : #endif
334 0 : default:
335 0 : LIBSPDM_ASSERT(false);
336 0 : return false;
337 : }
338 : }
339 :
340 74 : bool libspdm_dhe_compute_key(uint16_t dhe_named_group, void *context,
341 : const uint8_t *peer_public,
342 : size_t peer_public_size, uint8_t *key,
343 : size_t *key_size)
344 : {
345 : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
346 : bool ret;
347 : #endif
348 :
349 74 : switch (dhe_named_group) {
350 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048:
351 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072:
352 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096:
353 : #if LIBSPDM_FFDHE_SUPPORT
354 : #if !LIBSPDM_FFDHE_2048_SUPPORT
355 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048);
356 : #endif
357 : #if !LIBSPDM_FFDHE_3072_SUPPORT
358 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072);
359 : #endif
360 : #if !LIBSPDM_FFDHE_4096_SUPPORT
361 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096);
362 : #endif
363 0 : return libspdm_dh_compute_key(context, peer_public, peer_public_size, key, key_size);
364 : #else
365 : LIBSPDM_ASSERT(false);
366 : return false;
367 : #endif
368 74 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
369 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1:
370 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
371 : #if LIBSPDM_ECDHE_SUPPORT
372 : #if !LIBSPDM_ECDHE_P256_SUPPORT
373 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1);
374 : #endif
375 : #if !LIBSPDM_ECDHE_P384_SUPPORT
376 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1);
377 : #endif
378 : #if !LIBSPDM_ECDHE_P521_SUPPORT
379 : LIBSPDM_ASSERT(dhe_named_group != SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1);
380 : #endif
381 74 : return libspdm_ec_compute_key(context, peer_public, peer_public_size, key, key_size);
382 : #else
383 : LIBSPDM_ASSERT(false);
384 : return false;
385 : #endif
386 0 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256:
387 : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
388 : ret = libspdm_sm2_key_exchange_compute_key(context, peer_public,
389 : peer_public_size, key, key_size);
390 : if (!ret) {
391 : return false;
392 : } else {
393 : /* SM2 key exchange can generate arbitrary length key_size.
394 : * SPDM requires SM2 key_size to be 16. */
395 : LIBSPDM_ASSERT (*key_size >= 16);
396 : *key_size = 16;
397 :
398 : return true;
399 : }
400 : #else
401 0 : LIBSPDM_ASSERT(false);
402 0 : return false;
403 : #endif
404 0 : default:
405 0 : LIBSPDM_ASSERT(false);
406 0 : return false;
407 : }
408 : }
|