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