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 : : /**
10 : : * This function checks the compatibility of the received SPDM version,
11 : : * if received version is valid, subsequent spdm communication will follow this version.
12 : : *
13 : : * @param spdm_context A pointer to the SPDM context.
14 : : * @param version The SPDM message version.
15 : : *
16 : : *
17 : : * @retval true The received SPDM version is valid.
18 : : * @retval false The received SPDM version is invalid.
19 : : **/
20 : 42 : static bool libspdm_check_request_version_compatibility(libspdm_context_t *spdm_context,
21 : : uint8_t version)
22 : : {
23 : : uint8_t local_ver;
24 : : size_t index;
25 : :
26 [ + + ]: 108 : for (index = 0; index < spdm_context->local_context.version.spdm_version_count; index++) {
27 : 107 : local_ver = libspdm_get_version_from_version_number(
28 : 107 : spdm_context->local_context.version.spdm_version[index]);
29 [ + + ]: 107 : if (local_ver == version) {
30 : 41 : spdm_context->connection_info.version = version << SPDM_VERSION_NUMBER_SHIFT_BIT;
31 : 41 : return true;
32 : : }
33 : : }
34 : 1 : return false;
35 : : }
36 : :
37 : : /**
38 : : * This function checks the compatibility of the received GET_CAPABILITIES flag.
39 : : * Some flags are mutually inclusive/exclusive.
40 : : *
41 : : * @param capabilities_flag The received CAPABILITIES Flag.
42 : : * @param version The SPDM message version.
43 : : *
44 : : *
45 : : * @retval true The received Capabilities flag is valid.
46 : : * @retval false The received Capabilities flag is invalid.
47 : : **/
48 : 32 : static bool libspdm_check_request_flag_compatibility(uint32_t capabilities_flag, uint8_t version)
49 : : {
50 : 32 : const uint8_t cert_cap = (uint8_t)(capabilities_flag >> 1) & 0x01;
51 : 32 : const uint8_t chal_cap = (uint8_t)(capabilities_flag >> 2) & 0x01;
52 : 32 : const uint8_t encrypt_cap = (uint8_t)(capabilities_flag >> 6) & 0x01;
53 : 32 : const uint8_t mac_cap = (uint8_t)(capabilities_flag >> 7) & 0x01;
54 : 32 : const uint8_t mut_auth_cap = (uint8_t)(capabilities_flag >> 8) & 0x01;
55 : 32 : const uint8_t key_ex_cap = (uint8_t)(capabilities_flag >> 9) & 0x01;
56 : 32 : const uint8_t psk_cap = (uint8_t)(capabilities_flag >> 10) & 0x03;
57 : 32 : const uint8_t encap_cap = (uint8_t)(capabilities_flag >> 12) & 0x01;
58 : 32 : const uint8_t hbeat_cap = (uint8_t)(capabilities_flag >> 13) & 0x01;
59 : 32 : const uint8_t key_upd_cap = (uint8_t)(capabilities_flag >> 14) & 0x01;
60 : 32 : const uint8_t handshake_in_the_clear_cap = (uint8_t)(capabilities_flag >> 15) & 0x01;
61 : 32 : const uint8_t pub_key_id_cap = (uint8_t)(capabilities_flag >> 16) & 0x01;
62 : 32 : const uint8_t ep_info_cap = (uint8_t)(capabilities_flag >> 22) & 0x03;
63 : 32 : const uint8_t event_cap = (uint8_t)(capabilities_flag >> 25) & 0x01;
64 : 32 : const uint8_t multi_key_cap = (uint8_t)(capabilities_flag >> 26) & 0x03;
65 : :
66 [ - + ]: 32 : LIBSPDM_ASSERT(version >= SPDM_MESSAGE_VERSION_11);
67 : :
68 : : /* Checks common to 1.1 and higher */
69 [ + - ]: 32 : if (version >= SPDM_MESSAGE_VERSION_11) {
70 : : /* Illegal to return reserved values. */
71 [ + + - + ]: 32 : if ((psk_cap == 2) || (psk_cap == 3)) {
72 : 1 : return false;
73 : : }
74 : :
75 : : /* Checks that originate from key exchange capabilities. */
76 [ + + + + ]: 31 : if ((key_ex_cap == 1) || (psk_cap != 0)) {
77 [ + + + - ]: 14 : if ((mac_cap == 0) && (encrypt_cap == 0)) {
78 : 2 : return false;
79 : : }
80 : : } else {
81 [ + + + + : 17 : if ((mac_cap == 1) || (encrypt_cap == 1) || (handshake_in_the_clear_cap == 1) ||
+ - + - ]
82 [ - + ]: 15 : (hbeat_cap == 1) || (key_upd_cap == 1)) {
83 : 2 : return false;
84 : : }
85 [ + + ]: 15 : if (version >= SPDM_MESSAGE_VERSION_13) {
86 [ + + ]: 11 : if (event_cap == 1) {
87 : 1 : return false;
88 : : }
89 : : }
90 : : }
91 [ + + + + ]: 26 : if ((key_ex_cap == 0) && (psk_cap == 1)) {
92 [ + - ]: 1 : if (handshake_in_the_clear_cap == 1) {
93 : 1 : return false;
94 : : }
95 : : }
96 : :
97 : : /* Checks that originate from certificate or public key capabilities. */
98 [ + + + + ]: 25 : if ((cert_cap == 1) || (pub_key_id_cap == 1)) {
99 : : /* Certificate capabilities and public key capabilities cannot both be set. */
100 [ + + + + ]: 19 : if ((cert_cap == 1) && (pub_key_id_cap == 1)) {
101 : 2 : return false;
102 : : }
103 : : /* If certificates or public keys are enabled then at least one of these capabilities
104 : : * must be enabled to use the key. */
105 [ + + + - ]: 17 : if ((chal_cap == 0) && (key_ex_cap == 0)) {
106 [ + + ]: 8 : if (version >= SPDM_MESSAGE_VERSION_13) {
107 [ + + - + ]: 7 : if ((ep_info_cap == 0) || (ep_info_cap == 1)) {
108 : 2 : return false;
109 : : }
110 : : } else {
111 : 1 : return false;
112 : : }
113 : : }
114 : : } else {
115 : : /* If certificates or public keys are not enabled then these capabilities
116 : : * cannot be enabled. */
117 [ + + - + ]: 6 : if ((chal_cap == 1) || (mut_auth_cap == 1)) {
118 : 1 : return false;
119 : : }
120 [ + + ]: 5 : if (version >= SPDM_MESSAGE_VERSION_13) {
121 [ + + ]: 2 : if (ep_info_cap == 2) {
122 : 1 : return false;
123 : : }
124 : : }
125 : : }
126 : :
127 : : /* Checks that originate from mutual authentication capabilities. */
128 [ + + ]: 18 : if (mut_auth_cap == 1) {
129 : : /* Mutual authentication with asymmetric keys can only occur through the basic mutual
130 : : * authentication flow (CHAL_CAP == 1) or the session-based mutual authentication flow
131 : : * (KEY_EX_CAP == 1). */
132 [ + + + - ]: 10 : if ((key_ex_cap == 0) && (chal_cap == 0)) {
133 : 1 : return false;
134 : : }
135 : : }
136 : : }
137 : :
138 : : /* Checks specific to 1.1. */
139 [ + + ]: 17 : if (version == SPDM_MESSAGE_VERSION_11) {
140 [ + - + + ]: 9 : if ((mut_auth_cap == 1) && (encap_cap == 0)) {
141 : 1 : return false;
142 : : }
143 : : }
144 : :
145 : : /* Checks specific to 1.3 and higher. */
146 [ + + ]: 16 : if (version >= SPDM_MESSAGE_VERSION_13) {
147 : : /* Illegal to return reserved values. */
148 [ + + - + ]: 5 : if ((ep_info_cap == 3) || (multi_key_cap == 3)) {
149 : 1 : return false;
150 : : }
151 [ + - + - : 4 : if ((multi_key_cap != 0) && ((pub_key_id_cap == 1) || (cert_cap == 0))) {
+ + ]
152 : 1 : return false;
153 : : }
154 : : }
155 : :
156 : : /* Checks that are deferred to when a message is received.
157 : : *
158 : : * If the Requester supports key exchange then MAC_CAP must be set. In addition, if the
159 : : * negotiated SPDM version is greater than 1.1 then the negotiated opaque data format must be
160 : : * OpaqueDataFmt1.
161 : : */
162 : :
163 : 14 : return true;
164 : : }
165 : :
166 : 45 : libspdm_return_t libspdm_get_response_capabilities(libspdm_context_t *spdm_context,
167 : : size_t request_size,
168 : : const void *request,
169 : : size_t *response_size,
170 : : void *response)
171 : : {
172 : : const spdm_get_capabilities_request_t *spdm_request;
173 : : spdm_capabilities_response_t *spdm_response;
174 : : libspdm_return_t status;
175 : :
176 : 45 : spdm_request = request;
177 : :
178 : : /* -=[Check Parameters Phase]=- */
179 [ - + ]: 45 : LIBSPDM_ASSERT(spdm_request->header.request_response_code == SPDM_GET_CAPABILITIES);
180 : :
181 : : /* -=[Verify State Phase]=- */
182 [ + + ]: 45 : if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
183 : 2 : return libspdm_responder_handle_response_state(
184 : 2 : spdm_context, spdm_request->header.request_response_code, response_size, response);
185 : : }
186 [ + + ]: 43 : if (spdm_context->connection_info.connection_state != LIBSPDM_CONNECTION_STATE_AFTER_VERSION) {
187 : 1 : return libspdm_generate_error_response(spdm_context,
188 : : SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
189 : : 0, response_size, response);
190 : : }
191 : :
192 : : /* -=[Validate Request Phase]=- */
193 [ + + ]: 42 : if (!libspdm_check_request_version_compatibility(
194 : 42 : spdm_context, spdm_request->header.spdm_version)) {
195 : 1 : return libspdm_generate_error_response(spdm_context,
196 : : SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
197 : : response_size, response);
198 : : }
199 [ + + ]: 41 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
200 [ + + ]: 15 : if (request_size < sizeof(spdm_get_capabilities_request_t)) {
201 : 1 : return libspdm_generate_error_response(
202 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
203 : : } else {
204 : 14 : request_size = sizeof(spdm_get_capabilities_request_t);
205 : : }
206 [ + + ]: 26 : } else if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
207 [ + + ]: 19 : if (request_size < sizeof(spdm_get_capabilities_request_t) -
208 : : sizeof(spdm_request->data_transfer_size) - sizeof(spdm_request->max_spdm_msg_size)) {
209 : 1 : return libspdm_generate_error_response(
210 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
211 : : } else {
212 : 18 : request_size = sizeof(spdm_get_capabilities_request_t) -
213 : : sizeof(spdm_request->data_transfer_size) -
214 : : sizeof(spdm_request->max_spdm_msg_size);
215 : : }
216 : : } else {
217 [ + + ]: 7 : if (request_size < sizeof(spdm_message_header_t)) {
218 : 1 : return libspdm_generate_error_response(
219 : : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
220 : : } else {
221 : 6 : request_size = sizeof(spdm_message_header_t);
222 : : }
223 : : }
224 [ + + ]: 38 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
225 [ + + ]: 32 : if (!libspdm_check_request_flag_compatibility(
226 : 32 : spdm_request->flags, spdm_request->header.spdm_version)) {
227 : 18 : return libspdm_generate_error_response(spdm_context,
228 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
229 : : response_size, response);
230 : : }
231 : : }
232 [ + + ]: 20 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
233 [ + - ]: 6 : if ((spdm_request->data_transfer_size < SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) ||
234 [ + + ]: 6 : (spdm_request->data_transfer_size > spdm_request->max_spdm_msg_size)) {
235 : 1 : return libspdm_generate_error_response(spdm_context,
236 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
237 : : response_size, response);
238 : : }
239 [ + + ]: 5 : if (((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) == 0) &&
240 [ + + ]: 2 : (spdm_request->data_transfer_size != spdm_request->max_spdm_msg_size)) {
241 : 1 : return libspdm_generate_error_response(spdm_context,
242 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
243 : : response_size, response);
244 : : }
245 : : }
246 [ + + ]: 18 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
247 [ + + ]: 12 : if (spdm_request->ct_exponent > LIBSPDM_MAX_CT_EXPONENT) {
248 : 1 : return libspdm_generate_error_response(spdm_context,
249 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
250 : : response_size, response);
251 : : }
252 : : }
253 : :
254 : : /* Check that if Param1[0] is set, Requester must have CHUNK_CAP */
255 [ + + ]: 17 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13 &&
256 [ + + ]: 3 : (spdm_request->header.param1 & SPDM_GET_CAPABILITIES_REQUEST_PARAM1_SUPPORTED_ALGORITHMS) &&
257 [ - + ]: 2 : ((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) == 0)) {
258 : 0 : return libspdm_generate_error_response(spdm_context,
259 : : SPDM_ERROR_CODE_INVALID_REQUEST,
260 : : 0,
261 : : response_size,
262 : : response);
263 : : }
264 : :
265 : 17 : libspdm_reset_message_buffer_via_request_code(spdm_context, NULL,
266 : 17 : spdm_request->header.request_response_code);
267 : :
268 : : size_t required_size;
269 : :
270 [ + + ]: 17 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
271 : 4 : required_size = sizeof(spdm_capabilities_response_t);
272 : : } else {
273 : 13 : required_size = offsetof(spdm_capabilities_response_t, data_transfer_size);
274 : : }
275 : :
276 : 17 : uint32_t response_flags = libspdm_mask_capability_flags(
277 : : spdm_context, false, spdm_context->local_context.capability.flags);
278 : :
279 : 17 : bool supported_algs_requested =
280 : 20 : (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
281 [ + + ]: 3 : ((spdm_request->header.param1 & SPDM_GET_CAPABILITIES_REQUEST_PARAM1_SUPPORTED_ALGORITHMS) != 0) &&
282 [ + + + - ]: 22 : ((spdm_request->flags & SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) != 0) &&
283 [ + - ]: 2 : ((response_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP) != 0);
284 : :
285 [ + + ]: 17 : if (supported_algs_requested) {
286 : 2 : uint8_t table_count = 0;
287 [ + - ]: 2 : if (spdm_context->local_context.algorithm.dhe_named_group != 0) {
288 : 2 : table_count++;
289 : : }
290 [ + - ]: 2 : if (spdm_context->local_context.algorithm.aead_cipher_suite != 0) {
291 : 2 : table_count++;
292 : : }
293 [ + - ]: 2 : if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
294 : 2 : table_count++;
295 : : }
296 [ + - ]: 2 : if (spdm_context->local_context.algorithm.key_schedule != 0) {
297 : 2 : table_count++;
298 : : }
299 : :
300 [ + + ]: 2 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
301 [ + - ]: 1 : if (spdm_context->local_context.algorithm.req_pqc_asym_alg != 0) {
302 : 1 : table_count++;
303 : : }
304 [ + - ]: 1 : if (spdm_context->local_context.algorithm.kem_alg != 0) {
305 : 1 : table_count++;
306 : : }
307 : : }
308 : :
309 : 2 : required_size += sizeof(spdm_supported_algorithms_block_t) +
310 : 2 : (table_count * sizeof(spdm_negotiate_algorithms_common_struct_table_t));
311 : : }
312 : :
313 [ - + ]: 17 : LIBSPDM_ASSERT(*response_size >= required_size);
314 : 17 : *response_size = required_size;
315 : :
316 : 17 : libspdm_zero_mem(response, *response_size);
317 : 17 : spdm_response = response;
318 : :
319 : 17 : spdm_response->header.spdm_version = spdm_request->header.spdm_version;
320 : 17 : spdm_response->header.request_response_code = SPDM_CAPABILITIES;
321 : 17 : spdm_response->header.param1 = supported_algs_requested ?
322 : 17 : SPDM_CAPABILITIES_RESPONSE_PARAM1_SUPPORTED_ALGORITHMS : 0;
323 : 17 : spdm_response->header.param2 = 0;
324 : 17 : spdm_response->ct_exponent = spdm_context->local_context.capability.ct_exponent;
325 : 17 : spdm_response->flags = response_flags;
326 [ + + ]: 17 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
327 : 4 : spdm_response->data_transfer_size =
328 : 4 : spdm_context->local_context.capability.data_transfer_size;
329 : 4 : spdm_response->max_spdm_msg_size =
330 : 4 : spdm_context->local_context.capability.max_spdm_msg_size;
331 : : }
332 : :
333 [ + + ]: 17 : if (supported_algs_requested) {
334 : 2 : uint8_t index = 0;
335 : :
336 : : /* Allocate space for the supported_algorithms block at the end of the response */
337 : 2 : spdm_supported_algorithms_block_t *supported_algorithms =
338 : : (spdm_supported_algorithms_block_t*)((uint8_t*)spdm_response + sizeof(spdm_capabilities_response_t));
339 : :
340 : 2 : supported_algorithms->param2 = 0;
341 : 2 : supported_algorithms->length = sizeof(spdm_supported_algorithms_block_t);
342 : 2 : supported_algorithms->measurement_specification =
343 : 2 : spdm_context->local_context.algorithm.measurement_spec;
344 : 2 : supported_algorithms->other_params_support =
345 : 2 : spdm_context->local_context.algorithm.other_params_support;
346 : 2 : supported_algorithms->base_asym_algo=
347 : 2 : spdm_context->local_context.algorithm.base_asym_algo;
348 : 2 : supported_algorithms->base_hash_algo=
349 : 2 : spdm_context->local_context.algorithm.base_hash_algo;
350 : :
351 [ + + ]: 2 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
352 : 1 : supported_algorithms->pqc_asym_algo =
353 : 1 : spdm_context->local_context.algorithm.pqc_asym_algo;
354 : : } else {
355 : 1 : supported_algorithms->pqc_asym_algo = 0;
356 : : }
357 : :
358 : 2 : libspdm_zero_mem(supported_algorithms->reserved2, sizeof(supported_algorithms->reserved2));
359 : 2 : supported_algorithms->ext_asym_count = 0;
360 : 2 : supported_algorithms->ext_hash_count = 0;
361 : 2 : supported_algorithms->reserved3 = 0;
362 : 2 : supported_algorithms->mel_specification =
363 : 2 : spdm_context->local_context.algorithm.mel_spec;
364 : :
365 : 2 : spdm_negotiate_algorithms_common_struct_table_t *struct_table =
366 : : (spdm_negotiate_algorithms_common_struct_table_t*)(
367 : : (uint8_t*)supported_algorithms +
368 : : sizeof(spdm_supported_algorithms_block_t)
369 : : );
370 : :
371 [ + - ]: 2 : if (spdm_context->local_context.algorithm.dhe_named_group != 0) {
372 : 2 : struct_table[index].alg_type =
373 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
374 : 2 : struct_table[index].alg_count = 0x20;
375 : 2 : struct_table[index].alg_supported =
376 : 2 : spdm_context->local_context.algorithm.dhe_named_group;
377 : 2 : index++;
378 : : }
379 : :
380 [ + - ]: 2 : if (spdm_context->local_context.algorithm.aead_cipher_suite != 0) {
381 : 2 : struct_table[index].alg_type =
382 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
383 : 2 : struct_table[index].alg_count = 0x20;
384 : 2 : struct_table[index].alg_supported =
385 : 2 : spdm_context->local_context.algorithm.aead_cipher_suite;
386 : 2 : index++;
387 : : }
388 : :
389 [ + - ]: 2 : if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
390 : 2 : struct_table[index].alg_type =
391 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
392 : 2 : struct_table[index].alg_count = 0x20;
393 : 2 : struct_table[index].alg_supported =
394 : 2 : spdm_context->local_context.algorithm.req_base_asym_alg;
395 : 2 : index++;
396 : : }
397 : :
398 [ + - ]: 2 : if (spdm_context->local_context.algorithm.key_schedule != 0) {
399 : 2 : struct_table[index].alg_type =
400 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
401 : 2 : struct_table[index].alg_count = 0x20;
402 : 2 : struct_table[index].alg_supported =
403 : 2 : spdm_context->local_context.algorithm.key_schedule;
404 : 2 : index++;
405 : : }
406 : :
407 [ + + ]: 2 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
408 [ + - ]: 1 : if (spdm_context->local_context.algorithm.req_pqc_asym_alg != 0) {
409 : 1 : struct_table[index].alg_type =
410 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG;
411 : 1 : struct_table[index].alg_count = 0x20;
412 : 1 : struct_table[index].alg_supported =
413 : 1 : (uint16_t)spdm_context->local_context.algorithm.req_pqc_asym_alg;
414 : 1 : index++;
415 : : }
416 [ + - ]: 1 : if (spdm_context->local_context.algorithm.kem_alg != 0) {
417 : 1 : struct_table[index].alg_type =
418 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG;
419 : 1 : struct_table[index].alg_count = 0x20;
420 : 1 : struct_table[index].alg_supported =
421 : 1 : (uint16_t)spdm_context->local_context.algorithm.kem_alg;
422 : 1 : index++;
423 : : }
424 : : }
425 : :
426 : 2 : supported_algorithms->param1 = index;
427 : 2 : supported_algorithms->length +=
428 : 2 : supported_algorithms->param1*
429 : : sizeof(spdm_negotiate_algorithms_common_struct_table_t);
430 : :
431 [ + + ]: 15 : } else if (spdm_response->header.spdm_version < SPDM_MESSAGE_VERSION_12) {
432 : 13 : *response_size = sizeof(spdm_capabilities_response_t) -
433 : : sizeof(spdm_response->data_transfer_size) -
434 : : sizeof(spdm_response->max_spdm_msg_size);
435 : : }
436 : :
437 [ + + ]: 17 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
438 : 1 : spdm_response->ext_flags =
439 : 1 : libspdm_mask_capability_ext_flags(spdm_context, false,
440 : 1 : spdm_context->local_context.capability.ext_flags);
441 : : } else {
442 : 16 : spdm_response->ext_flags = 0;
443 : : }
444 : :
445 : : /* -=[Process Request Phase]=- */
446 : 17 : status = libspdm_append_message_a(spdm_context, spdm_request, request_size);
447 [ + + ]: 17 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
448 : 1 : return libspdm_generate_error_response(spdm_context,
449 : : SPDM_ERROR_CODE_UNSPECIFIED, 0,
450 : : response_size, response);
451 : : }
452 : 16 : status = libspdm_append_message_a(spdm_context, spdm_response, *response_size);
453 : :
454 [ + + ]: 16 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
455 : 1 : return libspdm_generate_error_response(spdm_context,
456 : : SPDM_ERROR_CODE_UNSPECIFIED, 0,
457 : : response_size, response);
458 : : }
459 : :
460 [ + + ]: 15 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
461 : 11 : spdm_context->connection_info.capability.ct_exponent = spdm_request->ct_exponent;
462 : : } else {
463 : 4 : spdm_context->connection_info.capability.ct_exponent = 0;
464 : : }
465 : :
466 [ + + ]: 15 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
467 : 11 : spdm_context->connection_info.capability.flags =
468 : 11 : libspdm_mask_capability_flags(spdm_context, true, spdm_request->flags);
469 : : } else {
470 : 4 : spdm_context->connection_info.capability.flags = 0;
471 : : }
472 : :
473 [ + + ]: 15 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
474 : 4 : spdm_context->connection_info.capability.data_transfer_size =
475 : 4 : spdm_request->data_transfer_size;
476 : 4 : spdm_context->connection_info.capability.max_spdm_msg_size =
477 : 4 : spdm_request->max_spdm_msg_size;
478 : : } else {
479 : 11 : spdm_context->connection_info.capability.data_transfer_size = 0;
480 : 11 : spdm_context->connection_info.capability.max_spdm_msg_size = 0;
481 : : }
482 : :
483 [ + + ]: 15 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
484 : 1 : spdm_context->connection_info.capability.ext_flags =
485 : 1 : libspdm_mask_capability_ext_flags(spdm_context, true, spdm_request->ext_flags);
486 : : } else {
487 : 14 : spdm_context->connection_info.capability.ext_flags = 0;
488 : : }
489 : :
490 : : /* -=[Update State Phase]=- */
491 : 15 : libspdm_set_connection_state(spdm_context, LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES);
492 : :
493 : 15 : return LIBSPDM_STATUS_SUCCESS;
494 : : }
|