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 : :
9 : 357 : uint32_t libspdm_get_dhe_pub_key_size(uint16_t dhe_named_group)
10 : : {
11 [ - - - + : 357 : 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 : 351 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
31 : : #if LIBSPDM_ECDHE_P256_SUPPORT
32 : 351 : 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 : 2 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1:
43 : : #if LIBSPDM_ECDHE_P521_SUPPORT
44 : 2 : 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 : 3 : default:
55 : 3 : return 0;
56 : : }
57 : : }
58 : :
59 : 1270 : uint32_t libspdm_get_dhe_shared_secret_size(uint16_t dhe_named_group)
60 : : {
61 [ - - - + : 1270 : 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 : 807 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
81 : : #if LIBSPDM_ECDHE_P256_SUPPORT
82 : 807 : 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 : 463 : default:
105 : 463 : 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 : 208 : static size_t libspdm_get_dhe_nid(uint16_t dhe_named_group)
117 : : {
118 [ - - - + : 208 : 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 : 208 : case SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1:
126 : 208 : 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 : 208 : 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 : 208 : nid = libspdm_get_dhe_nid(dhe_named_group);
152 [ - + ]: 208 : if (nid == 0) {
153 : 0 : return NULL;
154 : : }
155 : :
156 [ - + - - ]: 208 : 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 : 208 : 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 : 208 : 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 : 208 : void libspdm_dhe_free(uint16_t dhe_named_group, void *context)
236 : : {
237 [ - + ]: 208 : if (context == NULL) {
238 : 0 : return;
239 : : }
240 [ - + - - ]: 208 : 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 : 208 : 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 : 208 : libspdm_ec_free(context);
255 : : #else
256 : : LIBSPDM_ASSERT(false);
257 : : #endif
258 : 208 : 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 : 208 : 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 [ - + - - ]: 208 : 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 : 208 : 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 : 208 : 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 : 85 : 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 [ - + - - ]: 85 : 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 : 85 : 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 : 85 : 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 : : }
|