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