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_responder_lib.h"
8 : :
9 : : /* current version libspdm does not support any ext algo.
10 : : * the responder will ignore the ext algo in request.
11 : : * the responder will not build ext algo in response.*/
12 : : #pragma pack(1)
13 : : typedef struct {
14 : : spdm_message_header_t header;
15 : : uint16_t length;
16 : : uint8_t measurement_specification_sel;
17 : : uint8_t other_params_selection;
18 : : uint32_t measurement_hash_algo;
19 : : uint32_t base_asym_sel;
20 : : uint32_t base_hash_sel;
21 : : uint32_t pqc_asym_sel;
22 : : uint8_t reserved2[7];
23 : : uint8_t mel_specification_sel;
24 : : uint8_t ext_asym_sel_count;
25 : : uint8_t ext_hash_sel_count;
26 : : uint16_t reserved3;
27 : : spdm_negotiate_algorithms_common_struct_table_t struct_table[
28 : : SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG_14];
29 : : } libspdm_algorithms_response_mine_t;
30 : : #pragma pack()
31 : :
32 : : /**
33 : : * Select the preferred supported algorithm according to the priority_table.
34 : : *
35 : : * @param priority_table The priority table.
36 : : * @param priority_table_count The count of the priority table entry.
37 : : * @param local_algo Local supported algorithm.
38 : : * @param peer_algo Peer supported algorithm.
39 : : *
40 : : * @return Preferred supported algorithm
41 : : **/
42 : 240 : static uint32_t libspdm_prioritize_algorithm(const uint32_t *priority_table,
43 : : size_t priority_table_count,
44 : : uint32_t local_algo, uint32_t peer_algo)
45 : : {
46 : : uint32_t common_algo;
47 : : size_t index;
48 : :
49 : 240 : common_algo = (local_algo & peer_algo);
50 [ + + ]: 1105 : for (index = 0; index < priority_table_count; index++) {
51 [ + + ]: 1020 : if ((common_algo & priority_table[index]) != 0) {
52 : 155 : return priority_table[index];
53 : : }
54 : : }
55 : :
56 : 85 : return 0;
57 : : }
58 : :
59 : 77 : libspdm_return_t libspdm_get_response_algorithms(libspdm_context_t *spdm_context,
60 : : size_t request_size,
61 : : const void *request,
62 : : size_t *response_size,
63 : : void *response)
64 : : {
65 : : const spdm_negotiate_algorithms_request_t *spdm_request;
66 : : size_t spdm_request_size;
67 : : libspdm_algorithms_response_mine_t *spdm_response;
68 : : spdm_negotiate_algorithms_common_struct_table_t *struct_table;
69 : : size_t index;
70 : : size_t sub_index;
71 : : libspdm_return_t status;
72 : : uint32_t algo_size;
73 : : uint32_t pqc_algo_size;
74 : : uint8_t fixed_alg_size;
75 : : uint8_t ext_alg_count;
76 : : uint16_t ext_alg_total_count;
77 : : uint8_t alg_type_pre;
78 : :
79 : 77 : uint32_t hash_priority_table[] = {
80 : : #if LIBSPDM_SHA512_SUPPORT
81 : : SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512,
82 : : #endif
83 : : #if LIBSPDM_SHA384_SUPPORT
84 : : SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384,
85 : : #endif
86 : : #if LIBSPDM_SHA256_SUPPORT
87 : : SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256,
88 : : #endif
89 : : #if LIBSPDM_SHA3_512_SUPPORT
90 : : SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512,
91 : : #endif
92 : : #if LIBSPDM_SHA3_384_SUPPORT
93 : : SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384,
94 : : #endif
95 : : #if LIBSPDM_SHA3_256_SUPPORT
96 : : SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256,
97 : : #endif
98 : : #if LIBSPDM_SM3_256_SUPPORT
99 : : SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256,
100 : : #endif
101 : : 0,
102 : : };
103 : :
104 : 77 : uint32_t asym_priority_table[] = {
105 : : #if LIBSPDM_ECDSA_P521_SUPPORT
106 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521,
107 : : #endif
108 : : #if LIBSPDM_ECDSA_P384_SUPPORT
109 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384,
110 : : #endif
111 : : #if LIBSPDM_ECDSA_P256_SUPPORT
112 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256,
113 : : #endif
114 : : #if LIBSPDM_RSA_PSS_4096_SUPPORT
115 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096,
116 : : #endif
117 : : #if LIBSPDM_RSA_PSS_3072_SUPPORT
118 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072,
119 : : #endif
120 : : #if LIBSPDM_RSA_PSS_2048_SUPPORT
121 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048,
122 : : #endif
123 : : #if LIBSPDM_RSA_SSA_4096_SUPPORT
124 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096,
125 : : #endif
126 : : #if LIBSPDM_RSA_SSA_3072_SUPPORT
127 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072,
128 : : #endif
129 : : #if LIBSPDM_RSA_SSA_2048_SUPPORT
130 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
131 : : #endif
132 : : #if LIBSPDM_EDDSA_ED448_SUPPORT
133 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448,
134 : : #endif
135 : : #if LIBSPDM_EDDSA_ED25519_SUPPORT
136 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519,
137 : : #endif
138 : : #if LIBSPDM_SM2_DSA_P256_SUPPORT
139 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256,
140 : : #endif
141 : : 0,
142 : : };
143 : :
144 : 77 : uint32_t req_asym_priority_table[] = {
145 : : #if LIBSPDM_ECDSA_P521_SUPPORT
146 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521,
147 : : #endif
148 : : #if LIBSPDM_ECDSA_P384_SUPPORT
149 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384,
150 : : #endif
151 : : #if LIBSPDM_ECDSA_P256_SUPPORT
152 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256,
153 : : #endif
154 : : #if LIBSPDM_RSA_PSS_4096_SUPPORT
155 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096,
156 : : #endif
157 : : #if LIBSPDM_RSA_PSS_3072_SUPPORT
158 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072,
159 : : #endif
160 : : #if LIBSPDM_RSA_PSS_2048_SUPPORT
161 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048,
162 : : #endif
163 : : #if LIBSPDM_RSA_SSA_4096_SUPPORT
164 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096,
165 : : #endif
166 : : #if LIBSPDM_RSA_SSA_3072_SUPPORT
167 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072,
168 : : #endif
169 : : #if LIBSPDM_RSA_SSA_2048_SUPPORT
170 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
171 : : #endif
172 : : #if LIBSPDM_EDDSA_ED448_SUPPORT
173 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448,
174 : : #endif
175 : : #if LIBSPDM_EDDSA_ED25519_SUPPORT
176 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519,
177 : : #endif
178 : : #if LIBSPDM_SM2_DSA_P256_SUPPORT
179 : : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256,
180 : : #endif
181 : : 0,
182 : : };
183 : :
184 : 77 : uint32_t dhe_priority_table[] = {
185 : : #if LIBSPDM_ECDHE_P521_SUPPORT
186 : : SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1,
187 : : #endif
188 : : #if LIBSPDM_ECDHE_P384_SUPPORT
189 : : SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1,
190 : : #endif
191 : : #if LIBSPDM_ECDHE_P256_SUPPORT
192 : : SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1,
193 : : #endif
194 : : #if LIBSPDM_FFDHE_4096_SUPPORT
195 : : SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096,
196 : : #endif
197 : : #if LIBSPDM_FFDHE_3072_SUPPORT
198 : : SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072,
199 : : #endif
200 : : #if LIBSPDM_FFDHE_2048_SUPPORT
201 : : SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048,
202 : : #endif
203 : : #if LIBSPDM_SM2_KEY_EXCHANGE_SUPPORT
204 : : SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256,
205 : : #endif
206 : : 0,
207 : : };
208 : :
209 : 77 : uint32_t aead_priority_table[] = {
210 : : #if LIBSPDM_AEAD_AES_256_GCM_SUPPORT
211 : : SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM,
212 : : #endif
213 : : #if LIBSPDM_AEAD_AES_128_GCM_SUPPORT
214 : : SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM,
215 : : #endif
216 : : #if LIBSPDM_AEAD_CHACHA20_POLY1305_SUPPORT
217 : : SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305,
218 : : #endif
219 : : #if LIBSPDM_AEAD_SM4_128_GCM_SUPPORT
220 : : SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM,
221 : : #endif
222 : : 0,
223 : : };
224 : :
225 : 77 : uint32_t key_schedule_priority_table[] = {
226 : : SPDM_ALGORITHMS_KEY_SCHEDULE_SPDM,
227 : : };
228 : :
229 : 77 : uint32_t measurement_hash_priority_table[] = {
230 : : #if LIBSPDM_SHA512_SUPPORT
231 : : SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_512,
232 : : #endif
233 : : #if LIBSPDM_SHA384_SUPPORT
234 : : SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_384,
235 : : #endif
236 : : #if LIBSPDM_SHA256_SUPPORT
237 : : SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_256,
238 : : #endif
239 : : #if LIBSPDM_SHA3_512_SUPPORT
240 : : SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_512,
241 : : #endif
242 : : #if LIBSPDM_SHA3_384_SUPPORT
243 : : SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_384,
244 : : #endif
245 : : #if LIBSPDM_SHA3_256_SUPPORT
246 : : SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_256,
247 : : #endif
248 : : #if LIBSPDM_SM3_256_SUPPORT
249 : : SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SM3_256,
250 : : #endif
251 : : SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_RAW_BIT_STREAM_ONLY,
252 : : };
253 : :
254 : 77 : uint32_t measurement_spec_priority_table[] = {
255 : : SPDM_MEASUREMENT_SPECIFICATION_DMTF,
256 : : };
257 : :
258 : 77 : uint32_t other_params_support_priority_table[] = {
259 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1,
260 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0,
261 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE
262 : : };
263 : :
264 : 77 : uint32_t mel_spec_priority_table[] = {
265 : : SPDM_MEL_SPECIFICATION_DMTF,
266 : : };
267 : :
268 : 77 : uint32_t pqc_asym_priority_table[] = {
269 : : #if LIBSPDM_ML_DSA_87_SUPPORT
270 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_87,
271 : : #endif
272 : : #if LIBSPDM_ML_DSA_65_SUPPORT
273 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_65,
274 : : #endif
275 : : #if LIBSPDM_ML_DSA_44_SUPPORT
276 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_44,
277 : : #endif
278 : : #if LIBSPDM_SLH_DSA_SHAKE_256F_SUPPORT
279 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_256F,
280 : : #endif
281 : : #if LIBSPDM_SLH_DSA_SHA2_256F_SUPPORT
282 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_256F,
283 : : #endif
284 : : #if LIBSPDM_SLH_DSA_SHAKE_256S_SUPPORT
285 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_256S,
286 : : #endif
287 : : #if LIBSPDM_SLH_DSA_SHA2_256S_SUPPORT
288 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_256S,
289 : : #endif
290 : : #if LIBSPDM_SLH_DSA_SHAKE_192F_SUPPORT
291 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_192F,
292 : : #endif
293 : : #if LIBSPDM_SLH_DSA_SHA2_192F_SUPPORT
294 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_192F,
295 : : #endif
296 : : #if LIBSPDM_SLH_DSA_SHAKE_192S_SUPPORT
297 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_192S,
298 : : #endif
299 : : #if LIBSPDM_SLH_DSA_SHA2_192S_SUPPORT
300 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_192S,
301 : : #endif
302 : : #if LIBSPDM_SLH_DSA_SHAKE_128F_SUPPORT
303 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_128F,
304 : : #endif
305 : : #if LIBSPDM_SLH_DSA_SHA2_128F_SUPPORT
306 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_128F,
307 : : #endif
308 : : #if LIBSPDM_SLH_DSA_SHAKE_128S_SUPPORT
309 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_128S,
310 : : #endif
311 : : #if LIBSPDM_SLH_DSA_SHA2_128S_SUPPORT
312 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_128S,
313 : : #endif
314 : : 0,
315 : : };
316 : :
317 : 77 : uint32_t req_pqc_asym_priority_table[] = {
318 : : #if LIBSPDM_ML_DSA_87_SUPPORT
319 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_87,
320 : : #endif
321 : : #if LIBSPDM_ML_DSA_65_SUPPORT
322 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_65,
323 : : #endif
324 : : #if LIBSPDM_ML_DSA_44_SUPPORT
325 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_ML_DSA_44,
326 : : #endif
327 : : #if LIBSPDM_SLH_DSA_SHAKE_256F_SUPPORT
328 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_256F,
329 : : #endif
330 : : #if LIBSPDM_SLH_DSA_SHA2_256F_SUPPORT
331 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_256F,
332 : : #endif
333 : : #if LIBSPDM_SLH_DSA_SHAKE_256S_SUPPORT
334 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_256S,
335 : : #endif
336 : : #if LIBSPDM_SLH_DSA_SHA2_256S_SUPPORT
337 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_256S,
338 : : #endif
339 : : #if LIBSPDM_SLH_DSA_SHAKE_192F_SUPPORT
340 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_192F,
341 : : #endif
342 : : #if LIBSPDM_SLH_DSA_SHA2_192F_SUPPORT
343 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_192F,
344 : : #endif
345 : : #if LIBSPDM_SLH_DSA_SHAKE_192S_SUPPORT
346 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_192S,
347 : : #endif
348 : : #if LIBSPDM_SLH_DSA_SHA2_192S_SUPPORT
349 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_192S,
350 : : #endif
351 : : #if LIBSPDM_SLH_DSA_SHAKE_128F_SUPPORT
352 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_128F,
353 : : #endif
354 : : #if LIBSPDM_SLH_DSA_SHA2_128F_SUPPORT
355 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_128F,
356 : : #endif
357 : : #if LIBSPDM_SLH_DSA_SHAKE_128S_SUPPORT
358 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHAKE_128S,
359 : : #endif
360 : : #if LIBSPDM_SLH_DSA_SHA2_128S_SUPPORT
361 : : SPDM_ALGORITHMS_PQC_ASYM_ALGO_SLH_DSA_SHA2_128S,
362 : : #endif
363 : : 0,
364 : : };
365 : :
366 : 77 : uint32_t pqc_kem_priority_table[] = {
367 : : #if LIBSPDM_ML_KEM_1024_SUPPORT
368 : : SPDM_ALGORITHMS_KEM_ALG_ML_KEM_1024,
369 : : #endif
370 : : #if LIBSPDM_ML_KEM_768_SUPPORT
371 : : SPDM_ALGORITHMS_KEM_ALG_ML_KEM_768,
372 : : #endif
373 : : #if LIBSPDM_ML_KEM_512_SUPPORT
374 : : SPDM_ALGORITHMS_KEM_ALG_ML_KEM_512,
375 : : #endif
376 : : 0,
377 : : };
378 : :
379 : 77 : spdm_request = request;
380 : :
381 : 77 : ext_alg_total_count = 0;
382 : :
383 : : /* -=[Check Parameters Phase]=- */
384 [ - + ]: 77 : LIBSPDM_ASSERT(spdm_request->header.request_response_code == SPDM_NEGOTIATE_ALGORITHMS);
385 [ - + ]: 77 : LIBSPDM_ASSERT(!(((spdm_context->local_context.capability.flags &
386 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0) ^
387 : : (spdm_context->local_context.algorithm.measurement_spec == 0)));
388 [ - + ]: 77 : LIBSPDM_ASSERT(!(((spdm_context->local_context.capability.flags &
389 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0) ^
390 : : (spdm_context->local_context.algorithm.measurement_hash_algo == 0)));
391 : :
392 : : /* -=[Verify State Phase]=- */
393 [ + + ]: 77 : if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
394 : 2 : return libspdm_responder_handle_response_state(
395 : : spdm_context,
396 : 2 : spdm_request->header.request_response_code,
397 : : response_size, response);
398 : : }
399 [ + + ]: 75 : if (spdm_context->connection_info.connection_state !=
400 : : LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES) {
401 : 1 : return libspdm_generate_error_response(spdm_context,
402 : : SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
403 : : 0, response_size, response);
404 : : }
405 : :
406 : : /* -=[Validate Request Phase]=- */
407 [ + + ]: 74 : if (spdm_request->header.spdm_version != libspdm_get_connection_version(spdm_context)) {
408 : 9 : return libspdm_generate_error_response(spdm_context,
409 : : SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
410 : : response_size, response);
411 : : }
412 [ + + ]: 65 : if (request_size < sizeof(spdm_negotiate_algorithms_request_t)) {
413 : 1 : return libspdm_generate_error_response(spdm_context,
414 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
415 : : response_size, response);
416 : : }
417 : 64 : if (request_size <
418 : : sizeof(spdm_negotiate_algorithms_request_t) +
419 : 64 : sizeof(uint32_t) * spdm_request->ext_asym_count +
420 : 64 : sizeof(uint32_t) * spdm_request->ext_hash_count +
421 [ + + ]: 64 : sizeof(spdm_negotiate_algorithms_common_struct_table_t) * spdm_request->header.param1) {
422 : 2 : return libspdm_generate_error_response(spdm_context,
423 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
424 : : response_size, response);
425 : : }
426 : 62 : struct_table = (void *)((size_t)spdm_request +
427 : 62 : sizeof(spdm_negotiate_algorithms_request_t) +
428 : 62 : sizeof(uint32_t) * spdm_request->ext_asym_count +
429 : 62 : sizeof(uint32_t) * spdm_request->ext_hash_count);
430 [ + + ]: 62 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
431 : 56 : alg_type_pre = 0;
432 [ + + ]: 182 : for (index = 0; index < spdm_request->header.param1; index++) {
433 [ - + ]: 134 : if ((size_t)spdm_request + request_size < (size_t)struct_table) {
434 : 0 : return libspdm_generate_error_response(
435 : : spdm_context,
436 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
437 : : response_size, response);
438 : : }
439 [ + + ]: 134 : if ((size_t)spdm_request + request_size - (size_t)struct_table <
440 : : sizeof(spdm_negotiate_algorithms_common_struct_table_t)) {
441 : 1 : return libspdm_generate_error_response(
442 : : spdm_context,
443 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
444 : : response_size, response);
445 : : }
446 [ + + ]: 133 : if ((struct_table->alg_type < SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE) ||
447 [ - + ]: 132 : (struct_table->alg_type >
448 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG)) {
449 : 1 : return libspdm_generate_error_response(
450 : : spdm_context,
451 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
452 : : response_size, response);
453 : : }
454 [ + + ]: 132 : if ((spdm_request->header.spdm_version < SPDM_MESSAGE_VERSION_14) &&
455 [ + + ]: 128 : (struct_table->alg_type >
456 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE)) {
457 : 2 : return libspdm_generate_error_response(
458 : : spdm_context,
459 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
460 : : response_size, response);
461 : : }
462 : : /* AlgType shall monotonically increase for subsequent entries. */
463 [ + + + + ]: 130 : if ((index != 0) && (struct_table->alg_type <= alg_type_pre)) {
464 : 3 : return libspdm_generate_error_response(
465 : : spdm_context,
466 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
467 : : response_size, response);
468 : : }
469 : 127 : alg_type_pre = struct_table->alg_type;
470 : 127 : fixed_alg_size = (struct_table->alg_count >> 4) & 0xF;
471 : 127 : ext_alg_count = struct_table->alg_count & 0xF;
472 : 127 : ext_alg_total_count += ext_alg_count;
473 [ + + ]: 127 : if (fixed_alg_size != 2) {
474 : 1 : return libspdm_generate_error_response(
475 : : spdm_context,
476 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
477 : : response_size, response);
478 : : }
479 : 126 : if ((size_t)spdm_request + request_size - (size_t)struct_table -
480 : : sizeof(spdm_negotiate_algorithms_common_struct_table_t) <
481 [ - + ]: 126 : sizeof(uint32_t) * ext_alg_count) {
482 : 0 : return libspdm_generate_error_response(
483 : : spdm_context,
484 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
485 : : response_size, response);
486 : : }
487 : 126 : struct_table =
488 : 126 : (void *)((size_t)struct_table +
489 : 126 : sizeof(spdm_negotiate_algorithms_common_struct_table_t) +
490 : 126 : sizeof(uint32_t) * ext_alg_count);
491 : : }
492 : : }
493 : 54 : ext_alg_total_count += (spdm_request->ext_asym_count + spdm_request->ext_hash_count);
494 : : /* Algorithm count check and message size check*/
495 [ + + ]: 54 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
496 [ + + ]: 48 : if (ext_alg_total_count > SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_EXT_ALG_COUNT_VERSION_11) {
497 : 1 : return libspdm_generate_error_response(
498 : : spdm_context,
499 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
500 : : response_size, response);
501 : : }
502 [ + + ]: 47 : if (spdm_request->length > SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_LENGTH_VERSION_11) {
503 : 1 : return libspdm_generate_error_response(
504 : : spdm_context,
505 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
506 : : response_size, response);
507 : : }
508 : : } else {
509 [ + + ]: 6 : if (ext_alg_total_count > SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_EXT_ALG_COUNT_VERSION_10) {
510 : 1 : return libspdm_generate_error_response(
511 : : spdm_context,
512 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
513 : : response_size, response);
514 : : }
515 [ + + ]: 5 : if (spdm_request->length > SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_LENGTH_VERSION_10) {
516 : 1 : return libspdm_generate_error_response(
517 : : spdm_context,
518 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
519 : : response_size, response);
520 : : }
521 : : }
522 : :
523 : 50 : request_size = (size_t)struct_table - (size_t)spdm_request;
524 [ + + ]: 50 : if (request_size != spdm_request->length) {
525 : 1 : return libspdm_generate_error_response(
526 : : spdm_context,
527 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
528 : : response_size, response);
529 : : }
530 : 49 : spdm_request_size = request_size;
531 : :
532 : 49 : libspdm_reset_message_buffer_via_request_code(spdm_context, NULL,
533 : 49 : spdm_request->header.request_response_code);
534 : :
535 : : /* -=[Construct Response Phase]=- */
536 [ - + ]: 49 : LIBSPDM_ASSERT(*response_size >= sizeof(libspdm_algorithms_response_mine_t));
537 : 49 : *response_size = sizeof(libspdm_algorithms_response_mine_t);
538 : 49 : libspdm_zero_mem(response, *response_size);
539 : 49 : spdm_response = response;
540 : :
541 : 49 : spdm_response->header.spdm_version = spdm_request->header.spdm_version;
542 [ + + ]: 49 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
543 : : /* Number of Algorithms Structure Tables */
544 : 45 : spdm_response->header.param1 = spdm_request->header.param1;
545 : : /* Respond with only the same amount of Algorithms Structure Tables as requested */
546 : 45 : *response_size =
547 : 45 : offsetof(libspdm_algorithms_response_mine_t, struct_table) +
548 : 45 : spdm_request->header.param1 * sizeof(spdm_negotiate_algorithms_common_struct_table_t);
549 : : } else {
550 : 4 : spdm_response->header.param1 = 0;
551 : 4 : *response_size = offsetof(libspdm_algorithms_response_mine_t, struct_table);
552 : : }
553 : 49 : spdm_response->header.request_response_code = SPDM_ALGORITHMS;
554 : 49 : spdm_response->header.param2 = 0;
555 : 49 : spdm_response->length = (uint16_t)*response_size;
556 : :
557 : 49 : spdm_context->connection_info.algorithm.measurement_spec =
558 : 49 : spdm_request->measurement_specification;
559 [ + + ]: 49 : if (spdm_request->measurement_specification != 0) {
560 : 40 : spdm_context->connection_info.algorithm.measurement_hash_algo =
561 : 40 : spdm_context->local_context.algorithm.measurement_hash_algo;
562 : : } else {
563 : 9 : spdm_context->connection_info.algorithm.measurement_hash_algo = 0;
564 : : }
565 : 49 : spdm_context->connection_info.algorithm.base_asym_algo = spdm_request->base_asym_algo;
566 : 49 : spdm_context->connection_info.algorithm.base_hash_algo = spdm_request->base_hash_algo;
567 [ + + ]: 49 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
568 : 1 : spdm_context->connection_info.algorithm.pqc_asym_algo = spdm_request->pqc_asym_algo;
569 : : }
570 [ + + ]: 49 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
571 : 45 : struct_table =
572 : 45 : (void *)((size_t)spdm_request +
573 : 45 : sizeof(spdm_negotiate_algorithms_request_t) +
574 : 45 : sizeof(uint32_t) * spdm_request->ext_asym_count +
575 : 45 : sizeof(uint32_t) * spdm_request->ext_hash_count);
576 [ + + ]: 127 : for (index = 0; index < spdm_request->header.param1; index++) {
577 [ + + + + : 87 : switch (struct_table->alg_type) {
- - - ]
578 : 24 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE:
579 [ + + ]: 24 : if (struct_table->alg_supported == 0) {
580 : 1 : return libspdm_generate_error_response(
581 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
582 : : 0, response_size, response);
583 : : }
584 : :
585 : 23 : spdm_context->connection_info.algorithm.dhe_named_group =
586 : 23 : struct_table->alg_supported;
587 : 23 : spdm_response->struct_table[index].alg_type =
588 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
589 : 23 : spdm_response->struct_table[index].alg_count = 0x20;
590 : 23 : spdm_response->struct_table[index].alg_supported =
591 : 46 : (uint16_t)libspdm_prioritize_algorithm(
592 : : dhe_priority_table, LIBSPDM_ARRAY_SIZE(dhe_priority_table),
593 : 23 : spdm_context->local_context.algorithm.dhe_named_group,
594 : 23 : spdm_context->connection_info.algorithm.dhe_named_group);
595 : 23 : break;
596 : 23 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD:
597 [ + + ]: 23 : if (struct_table->alg_supported == 0) {
598 : 2 : return libspdm_generate_error_response(
599 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
600 : : 0, response_size, response);
601 : : }
602 : :
603 : 21 : spdm_context->connection_info.algorithm.aead_cipher_suite =
604 : 21 : struct_table->alg_supported;
605 : 21 : spdm_response->struct_table[index].alg_type =
606 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
607 : 21 : spdm_response->struct_table[index].alg_count = 0x20;
608 : 21 : spdm_response->struct_table[index].alg_supported =
609 : 42 : (uint16_t)libspdm_prioritize_algorithm(
610 : : aead_priority_table, LIBSPDM_ARRAY_SIZE(aead_priority_table),
611 : 21 : spdm_context->local_context.algorithm.aead_cipher_suite,
612 : 21 : spdm_context->connection_info.algorithm.aead_cipher_suite);
613 : 21 : break;
614 : 21 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG:
615 [ + + ]: 21 : if (struct_table->alg_supported == 0) {
616 : 1 : return libspdm_generate_error_response(
617 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
618 : : 0, response_size, response);
619 : : }
620 : :
621 : 20 : spdm_context->connection_info.algorithm.req_base_asym_alg =
622 : 20 : struct_table->alg_supported;
623 : 20 : spdm_response->struct_table[index].alg_type =
624 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
625 : 20 : spdm_response->struct_table[index].alg_count = 0x20;
626 : 20 : spdm_response->struct_table[index].alg_supported =
627 : 40 : (uint16_t)libspdm_prioritize_algorithm(
628 : : req_asym_priority_table,
629 : : LIBSPDM_ARRAY_SIZE(req_asym_priority_table),
630 : 20 : spdm_context->local_context.algorithm.req_base_asym_alg,
631 : 20 : spdm_context->connection_info.algorithm.req_base_asym_alg);
632 : 20 : break;
633 : 19 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE:
634 [ + + ]: 19 : if (struct_table->alg_supported == 0) {
635 : 1 : return libspdm_generate_error_response(
636 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
637 : : 0, response_size, response);
638 : : }
639 : :
640 : 18 : spdm_context->connection_info.algorithm.key_schedule =
641 : 18 : struct_table->alg_supported;
642 : 18 : spdm_response->struct_table[index].alg_type =
643 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
644 : 18 : spdm_response->struct_table[index].alg_count = 0x20;
645 : 18 : spdm_response->struct_table[index].alg_supported =
646 : 36 : (uint16_t)libspdm_prioritize_algorithm(
647 : : key_schedule_priority_table,
648 : : LIBSPDM_ARRAY_SIZE(key_schedule_priority_table),
649 : 18 : spdm_context->local_context.algorithm.key_schedule,
650 : 18 : spdm_context->connection_info.algorithm.key_schedule);
651 : 18 : break;
652 : 0 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG:
653 [ # # ]: 0 : if (struct_table->alg_supported == 0) {
654 : 0 : return libspdm_generate_error_response(
655 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
656 : : 0, response_size, response);
657 : : }
658 : :
659 : : /* Add assert to ensure it can be cast to uint16_t.
660 : : * It is enough now and can be enlarged later. */
661 [ # # ]: 0 : LIBSPDM_ASSERT(spdm_context->local_context.algorithm.kem_alg <= UINT16_MAX);
662 : 0 : spdm_context->connection_info.algorithm.req_pqc_asym_alg =
663 : 0 : struct_table->alg_supported;
664 : 0 : spdm_response->struct_table[index].alg_type =
665 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG;
666 : 0 : spdm_response->struct_table[index].alg_count = 0x20;
667 : 0 : spdm_response->struct_table[index].alg_supported =
668 : 0 : (uint16_t)libspdm_prioritize_algorithm(
669 : : req_pqc_asym_priority_table,
670 : : LIBSPDM_ARRAY_SIZE(req_pqc_asym_priority_table),
671 : : spdm_context->local_context.algorithm.req_pqc_asym_alg,
672 : : spdm_context->connection_info.algorithm.req_pqc_asym_alg);
673 : 0 : break;
674 : 0 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG:
675 [ # # ]: 0 : if (struct_table->alg_supported == 0) {
676 : 0 : return libspdm_generate_error_response(
677 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
678 : : 0, response_size, response);
679 : : }
680 : :
681 : : /* Add assert to ensure it can be cast to uint16_t.
682 : : * It is enough now and can be enlarged later. */
683 [ # # ]: 0 : LIBSPDM_ASSERT(spdm_context->local_context.algorithm.kem_alg <= UINT16_MAX);
684 : 0 : spdm_context->connection_info.algorithm.kem_alg =
685 : 0 : struct_table->alg_supported;
686 : 0 : spdm_response->struct_table[index].alg_type =
687 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG;
688 : 0 : spdm_response->struct_table[index].alg_count = 0x20;
689 : 0 : spdm_response->struct_table[index].alg_supported =
690 : 0 : (uint16_t)libspdm_prioritize_algorithm(
691 : : pqc_kem_priority_table,
692 : : LIBSPDM_ARRAY_SIZE(pqc_kem_priority_table),
693 : : spdm_context->local_context.algorithm.kem_alg,
694 : : spdm_context->connection_info.algorithm.kem_alg);
695 : 0 : break;
696 : 0 : default:
697 : : /* Unknown algorithm types do not need to be processed */
698 : 0 : break;
699 : : }
700 : 82 : ext_alg_count = struct_table->alg_count & 0xF;
701 : 82 : struct_table =
702 : 82 : (void *)((size_t)struct_table +
703 : 82 : sizeof(spdm_negotiate_algorithms_common_struct_table_t) +
704 : 82 : sizeof(uint32_t) * ext_alg_count);
705 : : }
706 : : }
707 [ + + ]: 44 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
708 : 19 : spdm_context->connection_info.algorithm.other_params_support =
709 : 19 : spdm_request->other_params_support & SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK;
710 [ + + ]: 19 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
711 : 13 : spdm_context->connection_info.algorithm.other_params_support =
712 : 13 : spdm_request->other_params_support;
713 : 13 : spdm_context->connection_info.algorithm.mel_spec =
714 : 13 : spdm_request->mel_specification;
715 : : }
716 : : }
717 : :
718 [ + + ]: 44 : if (libspdm_is_capabilities_flag_supported(
719 : : spdm_context, false, 0,
720 [ + + ]: 40 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) ||
721 : 40 : libspdm_is_capabilities_flag_supported(
722 : : spdm_context, false, 0,
723 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP)) {
724 : 5 : spdm_response->measurement_specification_sel = (uint8_t)libspdm_prioritize_algorithm(
725 : : measurement_spec_priority_table,
726 : : LIBSPDM_ARRAY_SIZE(measurement_spec_priority_table),
727 : 5 : spdm_context->local_context.algorithm.measurement_spec,
728 : 5 : spdm_context->connection_info.algorithm.measurement_spec);
729 : : } else {
730 : 39 : spdm_response->measurement_specification_sel = 0;
731 : : }
732 : :
733 : 44 : spdm_response->measurement_hash_algo = libspdm_prioritize_algorithm(
734 : : measurement_hash_priority_table,
735 : : LIBSPDM_ARRAY_SIZE(measurement_hash_priority_table),
736 : : spdm_context->local_context.algorithm.measurement_hash_algo,
737 : : spdm_context->connection_info.algorithm.measurement_hash_algo);
738 : :
739 : 44 : spdm_response->base_asym_sel = libspdm_prioritize_algorithm(
740 : : asym_priority_table, LIBSPDM_ARRAY_SIZE(asym_priority_table),
741 : : spdm_context->local_context.algorithm.base_asym_algo,
742 : : spdm_context->connection_info.algorithm.base_asym_algo);
743 : :
744 : 44 : spdm_response->base_hash_sel = libspdm_prioritize_algorithm(
745 : : hash_priority_table, LIBSPDM_ARRAY_SIZE(hash_priority_table),
746 : : spdm_context->local_context.algorithm.base_hash_algo,
747 : : spdm_context->connection_info.algorithm.base_hash_algo);
748 : :
749 [ + + ]: 44 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
750 : 1 : spdm_response->pqc_asym_sel = libspdm_prioritize_algorithm(
751 : : pqc_asym_priority_table, LIBSPDM_ARRAY_SIZE(pqc_asym_priority_table),
752 : : spdm_context->local_context.algorithm.pqc_asym_algo,
753 : : spdm_context->connection_info.algorithm.pqc_asym_algo);
754 : : } else {
755 : 43 : spdm_response->pqc_asym_sel = 0;
756 : : }
757 : :
758 [ + + ]: 44 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
759 : 38 : spdm_response->other_params_selection = (uint8_t)libspdm_prioritize_algorithm(
760 : : other_params_support_priority_table,
761 : : LIBSPDM_ARRAY_SIZE(other_params_support_priority_table),
762 : 19 : spdm_context->local_context.algorithm.other_params_support &
763 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK,
764 : 19 : spdm_context->connection_info.algorithm.other_params_support &
765 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK);
766 [ + + ]: 19 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
767 [ + + ]: 13 : if (libspdm_is_capabilities_flag_supported(
768 : : spdm_context, false, 0,
769 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP)) {
770 : 1 : spdm_response->mel_specification_sel = (uint8_t)libspdm_prioritize_algorithm(
771 : : mel_spec_priority_table,
772 : : LIBSPDM_ARRAY_SIZE(mel_spec_priority_table),
773 : 1 : spdm_context->local_context.algorithm.mel_spec,
774 : 1 : spdm_context->connection_info.algorithm.mel_spec);
775 : : } else {
776 : 12 : spdm_response->mel_specification_sel = 0;
777 : : }
778 : : }
779 : : }
780 : :
781 [ + + ]: 44 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
782 [ + + + + ]: 13 : switch (spdm_context->connection_info.capability.flags &
783 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) {
784 : 6 : case 0:
785 : 6 : spdm_context->connection_info.multi_key_conn_req = false;
786 : 6 : break;
787 : 2 : case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY:
788 : 2 : spdm_context->connection_info.multi_key_conn_req = true;
789 : 2 : break;
790 : 4 : case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_NEG:
791 [ + + ]: 4 : if ((spdm_context->local_context.algorithm.other_params_support &
792 : : SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
793 : 3 : spdm_context->connection_info.multi_key_conn_req = false;
794 : : } else {
795 : 1 : spdm_context->connection_info.multi_key_conn_req = true;
796 : : }
797 : 4 : break;
798 : 1 : default:
799 : 1 : return libspdm_generate_error_response(
800 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
801 : : 0, response_size, response);
802 : : }
803 [ + + ]: 12 : if (spdm_context->connection_info.multi_key_conn_req) {
804 : 3 : spdm_response->other_params_selection |= SPDM_ALGORITHMS_MULTI_KEY_CONN;
805 : : } else {
806 : 9 : spdm_response->other_params_selection &= ~SPDM_ALGORITHMS_MULTI_KEY_CONN;
807 : : }
808 : : }
809 : :
810 : : /* if both PQC and traditional algo are enabled, disable based on LIBSPDM_DATA_ALGO_PRIORITY_PQC_FIRST */
811 [ + + ]: 43 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
812 [ - + ]: 1 : if (spdm_context->local_context.algorithm.pqc_first) {
813 [ # # ]: 0 : if (spdm_response->pqc_asym_sel != 0) {
814 : 0 : spdm_response->base_asym_sel = 0;
815 : : }
816 [ # # ]: 0 : for (index = 0; index < spdm_response->header.param1; ++index) {
817 [ # # ]: 0 : if (spdm_response->struct_table[index].alg_type ==
818 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG) {
819 [ # # ]: 0 : if (spdm_response->struct_table[index].alg_supported != 0) {
820 [ # # ]: 0 : for (sub_index = 0; sub_index < spdm_response->header.param1; ++sub_index) {
821 [ # # ]: 0 : if (spdm_response->struct_table[sub_index].alg_type ==
822 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG) {
823 : 0 : spdm_response->struct_table[sub_index].alg_supported = 0;
824 : : }
825 : : }
826 : : }
827 : : }
828 [ # # ]: 0 : if (spdm_response->struct_table[index].alg_type ==
829 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG) {
830 [ # # ]: 0 : if (spdm_response->struct_table[index].alg_supported != 0) {
831 [ # # ]: 0 : for (sub_index = 0; sub_index < spdm_response->header.param1; ++sub_index) {
832 [ # # ]: 0 : if (spdm_response->struct_table[sub_index].alg_type ==
833 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE) {
834 : 0 : spdm_response->struct_table[sub_index].alg_supported = 0;
835 : : }
836 : : }
837 : : }
838 : : }
839 : : }
840 : : } else {
841 [ + - ]: 1 : if (spdm_response->base_asym_sel != 0) {
842 : 1 : spdm_response->pqc_asym_sel = 0;
843 : : }
844 [ + + ]: 5 : for (index = 0; index < spdm_response->header.param1; ++index) {
845 [ + + ]: 4 : if (spdm_response->struct_table[index].alg_type ==
846 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG) {
847 [ + - ]: 1 : if (spdm_response->struct_table[index].alg_supported != 0) {
848 [ + + ]: 5 : for (sub_index = 0; sub_index < spdm_response->header.param1; ++sub_index) {
849 [ - + ]: 4 : if (spdm_response->struct_table[sub_index].alg_type ==
850 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG) {
851 : 0 : spdm_response->struct_table[sub_index].alg_supported = 0;
852 : : }
853 : : }
854 : : }
855 : : }
856 [ + + ]: 4 : if (spdm_response->struct_table[index].alg_type ==
857 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE) {
858 [ + - ]: 1 : if (spdm_response->struct_table[index].alg_supported != 0) {
859 [ + + ]: 5 : for (sub_index = 0; sub_index < spdm_response->header.param1; ++sub_index) {
860 [ - + ]: 4 : if (spdm_response->struct_table[sub_index].alg_type ==
861 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG) {
862 : 0 : spdm_response->struct_table[sub_index].alg_supported = 0;
863 : : }
864 : : }
865 : : }
866 : : }
867 : : }
868 : : }
869 : : }
870 : :
871 : 43 : spdm_context->connection_info.algorithm.measurement_spec =
872 : 43 : spdm_response->measurement_specification_sel;
873 : 43 : spdm_context->connection_info.algorithm.measurement_hash_algo =
874 : 43 : spdm_response->measurement_hash_algo;
875 : 43 : spdm_context->connection_info.algorithm.base_asym_algo = spdm_response->base_asym_sel;
876 : 43 : spdm_context->connection_info.algorithm.base_hash_algo = spdm_response->base_hash_sel;
877 [ + + ]: 43 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
878 : 1 : spdm_context->connection_info.algorithm.pqc_asym_algo = spdm_response->pqc_asym_sel;
879 : : }
880 : :
881 [ + + ]: 43 : if (libspdm_is_capabilities_flag_supported(
882 : : spdm_context, false, 0,
883 : 4 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) &&
884 [ + + ]: 4 : (spdm_request->measurement_specification != 0)) {
885 [ + + ]: 3 : if (spdm_context->connection_info.algorithm.measurement_spec !=
886 : : SPDM_MEASUREMENT_SPECIFICATION_DMTF) {
887 : 1 : return libspdm_generate_error_response(
888 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
889 : : 0, response_size, response);
890 : : }
891 : 2 : algo_size = libspdm_get_measurement_hash_size(
892 : : spdm_context->connection_info.algorithm.measurement_hash_algo);
893 [ - + ]: 2 : if (algo_size == 0) {
894 : 0 : return libspdm_generate_error_response(
895 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
896 : : 0, response_size, response);
897 : : }
898 : : }
899 : :
900 [ + - ]: 42 : if (libspdm_is_capabilities_flag_supported(
901 : : spdm_context, false, 0,
902 [ + + ]: 42 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) ||
903 : 42 : libspdm_is_capabilities_flag_supported(
904 : : spdm_context, false, 0,
905 [ + + ]: 32 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) ||
906 : 32 : libspdm_is_capabilities_flag_supported(
907 : : spdm_context, false, 0,
908 [ + + ]: 29 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) ||
909 : 29 : libspdm_is_capabilities_flag_supported(
910 : : spdm_context, false, 0,
911 [ + + ]: 26 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG) ||
912 : 26 : libspdm_is_capabilities_flag_supported(
913 : : spdm_context, false,
914 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
915 [ + + ]: 18 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) ||
916 : 18 : libspdm_is_capabilities_flag_supported(
917 : : spdm_context, false,
918 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
919 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
920 : 25 : algo_size = libspdm_get_hash_size(
921 : : spdm_context->connection_info.algorithm.base_hash_algo);
922 [ + + ]: 25 : if (algo_size == 0) {
923 : 2 : return libspdm_generate_error_response(
924 : : spdm_context,
925 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
926 : : response_size, response);
927 : : }
928 : : }
929 : :
930 [ + - ]: 40 : if (libspdm_is_capabilities_flag_supported(
931 : : spdm_context, false, 0,
932 [ + + ]: 40 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) ||
933 : 40 : libspdm_is_capabilities_flag_supported(
934 : : spdm_context, false, 0,
935 [ + + ]: 31 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) ||
936 : 31 : libspdm_is_capabilities_flag_supported(
937 : : spdm_context, false, 0,
938 [ + + ]: 28 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) ||
939 : 28 : libspdm_is_capabilities_flag_supported(
940 : : spdm_context, false, 0,
941 [ + + ]: 26 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG) ||
942 : 26 : libspdm_is_capabilities_flag_supported(
943 : : spdm_context, false,
944 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
945 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
946 : 22 : algo_size = libspdm_get_asym_signature_size(
947 : : spdm_context->connection_info.algorithm.base_asym_algo);
948 : 22 : pqc_algo_size = libspdm_get_pqc_asym_signature_size(
949 : : spdm_context->connection_info.algorithm.pqc_asym_algo);
950 [ + + - + : 22 : if (((algo_size == 0) && (pqc_algo_size == 0)) ||
+ - ]
951 [ - + ]: 20 : ((algo_size != 0) && (pqc_algo_size != 0))) {
952 : 2 : return libspdm_generate_error_response(
953 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
954 : : 0, response_size, response);
955 : : }
956 : : }
957 : :
958 : : /* -=[Process Request Phase]=- */
959 [ + + ]: 38 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
960 [ + + ]: 102 : for (index = 0; index < spdm_response->header.param1; ++index) {
961 [ + + + + : 67 : switch(spdm_response->struct_table[index].alg_type) {
- - - ]
962 : 17 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE:
963 : 17 : spdm_context->connection_info.algorithm.dhe_named_group =
964 : 17 : spdm_response->struct_table[index].alg_supported;
965 : 17 : break;
966 : 17 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD:
967 : 17 : spdm_context->connection_info.algorithm.aead_cipher_suite =
968 : 17 : spdm_response->struct_table[index].alg_supported;
969 : 17 : break;
970 : 17 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG:
971 : 17 : spdm_context->connection_info.algorithm.req_base_asym_alg =
972 : 17 : spdm_response->struct_table[index].alg_supported;
973 : 17 : break;
974 : 16 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE:
975 : 16 : spdm_context->connection_info.algorithm.key_schedule =
976 : 16 : spdm_response->struct_table[index].alg_supported;
977 : 16 : break;
978 : 0 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG:
979 : 0 : spdm_context->connection_info.algorithm.req_pqc_asym_alg =
980 : 0 : spdm_response->struct_table[index].alg_supported;
981 : 0 : break;
982 : 0 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG:
983 : 0 : spdm_context->connection_info.algorithm.kem_alg =
984 : 0 : spdm_response->struct_table[index].alg_supported;
985 : 0 : break;
986 : 0 : default:
987 : : /* Unreachable */
988 : 0 : LIBSPDM_ASSERT(false);
989 : 0 : break;
990 : : }
991 : : }
992 [ + + ]: 35 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
993 [ + + ]: 16 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
994 : 10 : spdm_context->connection_info.algorithm.other_params_support =
995 : 10 : (spdm_context->connection_info.algorithm.other_params_support &
996 : 10 : SPDM_ALGORITHMS_MULTI_KEY_CONN) |
997 : 10 : (spdm_response->other_params_selection &
998 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK);
999 : 10 : spdm_context->connection_info.algorithm.mel_spec =
1000 : 10 : spdm_response->mel_specification_sel;
1001 : : } else {
1002 : 6 : spdm_context->connection_info.algorithm.other_params_support =
1003 : 6 : (spdm_response->other_params_selection &
1004 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK);
1005 : 6 : spdm_context->connection_info.algorithm.mel_spec = 0;
1006 : : }
1007 : : } else {
1008 : 19 : spdm_context->connection_info.algorithm.other_params_support = 0;
1009 : : }
1010 : :
1011 [ + + ]: 35 : if (libspdm_is_capabilities_flag_supported(
1012 : : spdm_context, false,
1013 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
1014 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
1015 : 17 : algo_size = libspdm_get_dhe_pub_key_size(
1016 : 17 : spdm_context->connection_info.algorithm.dhe_named_group);
1017 : 17 : pqc_algo_size = libspdm_get_kem_encap_key_size(
1018 : : spdm_context->connection_info.algorithm.kem_alg);
1019 [ + + - + : 17 : if (((algo_size == 0) && (pqc_algo_size == 0)) ||
+ - ]
1020 [ - + ]: 14 : ((algo_size != 0) && (pqc_algo_size != 0))) {
1021 : 3 : return libspdm_generate_error_response(
1022 : : spdm_context,
1023 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
1024 : : response_size, response);
1025 : : }
1026 : : }
1027 [ + + ]: 32 : if (libspdm_is_capabilities_flag_supported(
1028 : : spdm_context, false,
1029 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP,
1030 [ + + ]: 18 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) ||
1031 : 18 : libspdm_is_capabilities_flag_supported(
1032 : : spdm_context, false,
1033 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
1034 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
1035 : 15 : algo_size = libspdm_get_aead_key_size(
1036 : 15 : spdm_context->connection_info.algorithm.aead_cipher_suite);
1037 [ + + ]: 15 : if (algo_size == 0) {
1038 : 2 : return libspdm_generate_error_response(
1039 : : spdm_context,
1040 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
1041 : : response_size, response);
1042 : : }
1043 : : }
1044 [ + + ]: 30 : if (libspdm_is_capabilities_flag_supported(
1045 : : spdm_context, false,
1046 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP,
1047 [ + + ]: 15 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP) ||
1048 : 15 : libspdm_is_capabilities_flag_supported(
1049 : : spdm_context, false,
1050 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_SIG, 0)) {
1051 : 17 : algo_size = libspdm_get_req_asym_signature_size(
1052 : 17 : spdm_context->connection_info.algorithm.req_base_asym_alg);
1053 : 17 : pqc_algo_size = libspdm_get_req_pqc_asym_signature_size(
1054 : : spdm_context->connection_info.algorithm.req_pqc_asym_alg);
1055 [ + + - + : 17 : if (((algo_size == 0) && (pqc_algo_size == 0)) ||
+ - ]
1056 [ - + ]: 13 : ((algo_size != 0) && (pqc_algo_size != 0))) {
1057 : 4 : return libspdm_generate_error_response(
1058 : : spdm_context,
1059 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
1060 : : response_size, response);
1061 : : }
1062 : : }
1063 [ + + ]: 26 : if (libspdm_is_capabilities_flag_supported(
1064 : : spdm_context, false,
1065 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
1066 [ + + ]: 14 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) ||
1067 : 14 : libspdm_is_capabilities_flag_supported(
1068 : : spdm_context, false,
1069 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
1070 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
1071 [ + + ]: 13 : if (spdm_context->connection_info.algorithm.key_schedule !=
1072 : : SPDM_ALGORITHMS_KEY_SCHEDULE_SPDM) {
1073 : 3 : return libspdm_generate_error_response(
1074 : : spdm_context,
1075 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
1076 : : response_size, response);
1077 : : }
1078 : : }
1079 : :
1080 [ + + ]: 23 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
1081 [ + + ]: 10 : if ((spdm_context->connection_info.algorithm.other_params_support &
1082 : : SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
1083 [ + + ]: 7 : if ((spdm_context->local_context.capability.flags &
1084 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) ==
1085 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_ONLY) {
1086 : 1 : return libspdm_generate_error_response(
1087 : : spdm_context,
1088 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
1089 : : response_size, response);
1090 : : }
1091 : 6 : spdm_context->connection_info.multi_key_conn_rsp = false;
1092 : : } else {
1093 [ + + ]: 3 : if ((spdm_context->local_context.capability.flags &
1094 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) == 0) {
1095 : 1 : return libspdm_generate_error_response(
1096 : : spdm_context,
1097 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
1098 : : response_size, response);
1099 : : }
1100 : 2 : spdm_context->connection_info.multi_key_conn_rsp = true;
1101 : : }
1102 : : }
1103 : : } else {
1104 : 3 : spdm_context->connection_info.algorithm.dhe_named_group = 0;
1105 : 3 : spdm_context->connection_info.algorithm.aead_cipher_suite = 0;
1106 : 3 : spdm_context->connection_info.algorithm.req_base_asym_alg = 0;
1107 : 3 : spdm_context->connection_info.algorithm.key_schedule = 0;
1108 : 3 : spdm_context->connection_info.algorithm.other_params_support = 0;
1109 : 3 : spdm_context->connection_info.algorithm.req_pqc_asym_alg = 0;
1110 : 3 : spdm_context->connection_info.algorithm.kem_alg = 0;
1111 : : }
1112 : :
1113 : 24 : status = libspdm_append_message_a(spdm_context, spdm_request, spdm_request_size);
1114 [ - + ]: 24 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
1115 : 0 : return libspdm_generate_error_response(spdm_context,
1116 : : SPDM_ERROR_CODE_UNSPECIFIED, 0,
1117 : : response_size, response);
1118 : : }
1119 : :
1120 : 24 : status = libspdm_append_message_a(spdm_context, spdm_response, *response_size);
1121 [ - + ]: 24 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
1122 : 0 : return libspdm_generate_error_response(spdm_context,
1123 : : SPDM_ERROR_CODE_UNSPECIFIED, 0,
1124 : : response_size, response);
1125 : : }
1126 : :
1127 : 24 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "base_hash - 0x%08x\n",
1128 : : spdm_context->connection_info.algorithm.base_hash_algo));
1129 : 24 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "base_asym - 0x%08x\n",
1130 : : spdm_context->connection_info.algorithm.base_asym_algo));
1131 : 24 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "dhe - 0x%04x\n",
1132 : : spdm_context->connection_info.algorithm.dhe_named_group));
1133 : 24 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aead - 0x%04x\n",
1134 : : spdm_context->connection_info.algorithm.aead_cipher_suite));
1135 : 24 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "req_asym - 0x%04x\n",
1136 : : spdm_context->connection_info.algorithm.req_base_asym_alg));
1137 : 24 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "pqc_asym - 0x%08x\n",
1138 : : spdm_context->connection_info.algorithm.pqc_asym_algo));
1139 : 24 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "req_pqc_asym - 0x%04x\n",
1140 : : spdm_context->connection_info.algorithm.req_pqc_asym_alg));
1141 : 24 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "kem - 0x%04x\n",
1142 : : spdm_context->connection_info.algorithm.kem_alg));
1143 : :
1144 : : /* -=[Update State Phase]=- */
1145 : 24 : libspdm_set_connection_state(spdm_context, LIBSPDM_CONNECTION_STATE_NEGOTIATED);
1146 : :
1147 : 24 : return LIBSPDM_STATUS_SUCCESS;
1148 : : }
|