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_requester_lib.h"
8 : :
9 : : #pragma pack(1)
10 : : typedef struct {
11 : : spdm_message_header_t header;
12 : : uint16_t length;
13 : : uint8_t measurement_specification;
14 : : uint8_t other_params_support;
15 : : uint32_t base_asym_algo;
16 : : uint32_t base_hash_algo;
17 : : uint32_t pqc_asym_algo;
18 : : uint8_t reserved2[8];
19 : : uint8_t ext_asym_count;
20 : : uint8_t ext_hash_count;
21 : : uint8_t reserved3;
22 : : uint8_t mel_specification;
23 : : spdm_negotiate_algorithms_common_struct_table_t struct_table[
24 : : SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG_14];
25 : : } libspdm_negotiate_algorithms_request_mine_t;
26 : :
27 : : typedef struct {
28 : : spdm_message_header_t header;
29 : : uint16_t length;
30 : : uint8_t measurement_specification_sel;
31 : : uint8_t other_params_selection;
32 : : uint32_t measurement_hash_algo;
33 : : uint32_t base_asym_sel;
34 : : uint32_t base_hash_sel;
35 : : uint32_t pqc_asym_sel;
36 : : uint8_t reserved2[7];
37 : : uint8_t mel_specification_sel;
38 : : uint8_t ext_asym_sel_count;
39 : : uint8_t ext_hash_sel_count;
40 : : uint16_t reserved3;
41 : : uint32_t ext_asym_sel;
42 : : uint32_t ext_hash_sel;
43 : : spdm_negotiate_algorithms_common_struct_table_t struct_table[
44 : : SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG_14];
45 : : } libspdm_algorithms_response_max_t;
46 : : #pragma pack()
47 : :
48 : : /**
49 : : * This function sends NEGOTIATE_ALGORITHMS and receives ALGORITHMS.
50 : : *
51 : : * @param spdm_context A pointer to the SPDM context.
52 : : *
53 : : * @retval LIBSPDM_STATUS_SUCCESS
54 : : * NEGOTIATE_ALGORITHMS was sent and ALGORITHMS was received.
55 : : * @retval LIBSPDM_STATUS_INVALID_STATE_LOCAL
56 : : * Cannot send NEGOTIATE_ALGORITHMS due to Requester's state.
57 : : * @retval LIBSPDM_STATUS_INVALID_MSG_SIZE
58 : : * The size of the ALGORITHMS response is invalid.
59 : : * @retval LIBSPDM_STATUS_INVALID_MSG_FIELD
60 : : * The ALGORITHMS response contains one or more invalid fields.
61 : : * @retval LIBSPDM_STATUS_ERROR_PEER
62 : : * The Responder returned an unexpected error.
63 : : * @retval LIBSPDM_STATUS_BUSY_PEER
64 : : * The Responder continually returned Busy error messages.
65 : : * @retval LIBSPDM_STATUS_RESYNCH_PEER
66 : : * The Responder returned a RequestResynch error message.
67 : : * @retval LIBSPDM_STATUS_BUFFER_FULL
68 : : * The buffer used to store transcripts is exhausted.
69 : : * @retval LIBSPDM_STATUS_NEGOTIATION_FAIL
70 : : * The Requester and Responder could not agree on mutual algorithms.
71 : : * Note: This return value may be removed in the future.
72 : : **/
73 : 134 : static libspdm_return_t libspdm_try_negotiate_algorithms(libspdm_context_t *spdm_context)
74 : : {
75 : : libspdm_return_t status;
76 : : libspdm_negotiate_algorithms_request_mine_t *spdm_request;
77 : : size_t spdm_request_size;
78 : : libspdm_algorithms_response_max_t *spdm_response;
79 : : size_t spdm_response_size;
80 : : uint32_t algo_size;
81 : : uint32_t pqc_algo_size;
82 : 134 : size_t index = 0;
83 : : spdm_negotiate_algorithms_common_struct_table_t *struct_table;
84 : : uint8_t fixed_alg_size;
85 : : uint8_t ext_alg_count;
86 : : uint8_t *message;
87 : : size_t message_size;
88 : : size_t transport_header_size;
89 : : uint8_t alg_type_pre;
90 : 134 : uint8_t req_param1 = 0;
91 : :
92 : : /* -=[Verify State Phase]=- */
93 [ + + ]: 134 : if (spdm_context->connection_info.connection_state !=
94 : : LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES) {
95 : 3 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
96 : : }
97 : :
98 : 131 : libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_NEGOTIATE_ALGORITHMS);
99 : :
100 : : /* -=[Construct Request Phase]=- */
101 : 131 : transport_header_size = spdm_context->local_context.capability.transport_header_size;
102 : 131 : status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
103 [ + + ]: 131 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
104 : 1 : return status;
105 : : }
106 [ - + ]: 130 : LIBSPDM_ASSERT (message_size >= transport_header_size +
107 : : spdm_context->local_context.capability.transport_tail_size);
108 : 130 : spdm_request = (void *)(message + transport_header_size);
109 : 130 : spdm_request_size = message_size - transport_header_size -
110 : 130 : spdm_context->local_context.capability.transport_tail_size;
111 : :
112 [ - + ]: 130 : LIBSPDM_ASSERT(spdm_request_size >= sizeof(spdm_negotiate_algorithms_request_t));
113 : 130 : libspdm_zero_mem(spdm_request, spdm_request_size);
114 : 130 : spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
115 [ + + ]: 130 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
116 : : /* Number of Algorithms Structure Tables based on supported algorithms */
117 [ + + ]: 76 : if (spdm_context->local_context.algorithm.dhe_named_group != 0) {
118 : 74 : req_param1++;
119 : : }
120 [ + + ]: 76 : if (spdm_context->local_context.algorithm.aead_cipher_suite != 0) {
121 : 74 : req_param1++;
122 : : }
123 [ + + ]: 76 : if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
124 : 74 : req_param1++;
125 : : }
126 [ + + ]: 76 : if (spdm_context->local_context.algorithm.key_schedule != 0) {
127 : 74 : req_param1++;
128 : : }
129 [ - + ]: 76 : LIBSPDM_ASSERT(req_param1 <=
130 : : SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG);
131 [ + + ]: 76 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
132 [ - + ]: 2 : if (spdm_context->local_context.algorithm.req_pqc_asym_alg != 0) {
133 : 0 : req_param1++;
134 : : }
135 [ - + ]: 2 : if (spdm_context->local_context.algorithm.kem_alg != 0) {
136 : 0 : req_param1++;
137 : : }
138 [ - + ]: 2 : LIBSPDM_ASSERT(req_param1 <=
139 : : SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG_14);
140 : : }
141 : 76 : spdm_request->header.param1 = req_param1;
142 : 76 : spdm_request->length =
143 : 76 : offsetof(libspdm_negotiate_algorithms_request_mine_t, struct_table) +
144 : : req_param1 * sizeof(spdm_negotiate_algorithms_common_struct_table_t);
145 : : } else {
146 : 54 : spdm_request->length = offsetof(libspdm_negotiate_algorithms_request_mine_t, struct_table);
147 : 54 : spdm_request->header.param1 = 0;
148 : : }
149 : :
150 [ - + ]: 130 : LIBSPDM_ASSERT(spdm_request_size >= spdm_request->length);
151 : 130 : spdm_request->header.request_response_code = SPDM_NEGOTIATE_ALGORITHMS;
152 : 130 : spdm_request->header.param2 = 0;
153 : 130 : spdm_request->measurement_specification =
154 : 130 : spdm_context->local_context.algorithm.measurement_spec;
155 [ + + ]: 130 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
156 : 45 : spdm_request->other_params_support =
157 : 45 : spdm_context->local_context.algorithm.other_params_support &
158 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK;
159 [ + + ]: 45 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
160 : 25 : spdm_request->other_params_support =
161 : 25 : spdm_context->local_context.algorithm.other_params_support;
162 : 25 : spdm_request->mel_specification =
163 : 25 : spdm_context->local_context.algorithm.mel_spec;
164 : : }
165 : : }
166 [ + + ]: 130 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
167 [ + + + - ]: 25 : switch (spdm_context->connection_info.capability.flags &
168 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP) {
169 : 19 : case 0:
170 : 19 : spdm_context->connection_info.multi_key_conn_rsp = false;
171 : 19 : break;
172 : 3 : case SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_ONLY:
173 : 3 : spdm_context->connection_info.multi_key_conn_rsp = true;
174 : 3 : break;
175 : 3 : case SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP_NEG:
176 [ + + ]: 3 : if ((spdm_context->local_context.algorithm.other_params_support &
177 : : SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
178 : 1 : spdm_context->connection_info.multi_key_conn_rsp = false;
179 : : } else {
180 : 2 : spdm_context->connection_info.multi_key_conn_rsp = true;
181 : : }
182 : 3 : break;
183 : 0 : default:
184 : 0 : LIBSPDM_ASSERT(false);
185 : 0 : libspdm_release_sender_buffer(spdm_context);
186 : 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
187 : : }
188 [ + + ]: 25 : if (spdm_context->connection_info.multi_key_conn_rsp) {
189 : 5 : spdm_request->other_params_support |= SPDM_ALGORITHMS_MULTI_KEY_CONN;
190 : : } else {
191 : 20 : spdm_request->other_params_support &= ~SPDM_ALGORITHMS_MULTI_KEY_CONN;
192 : : }
193 : : }
194 : 130 : spdm_request->base_asym_algo = spdm_context->local_context.algorithm.base_asym_algo;
195 : 130 : spdm_request->base_hash_algo = spdm_context->local_context.algorithm.base_hash_algo;
196 [ + + ]: 130 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
197 : 2 : spdm_request->pqc_asym_algo = spdm_context->local_context.algorithm.pqc_asym_algo;
198 : : }
199 : 130 : spdm_request->ext_asym_count = 0;
200 : 130 : spdm_request->ext_hash_count = 0;
201 [ + + ]: 130 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
202 : : /* ReqAlgStruct order based on by AlgType */
203 [ + + ]: 76 : if (spdm_context->local_context.algorithm.dhe_named_group != 0) {
204 : 74 : spdm_request->struct_table[index].alg_type =
205 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE;
206 : 74 : spdm_request->struct_table[index].alg_count = 0x20;
207 : 74 : spdm_request->struct_table[index].alg_supported =
208 : 74 : spdm_context->local_context.algorithm.dhe_named_group;
209 : 74 : index++;
210 : : }
211 [ + + ]: 76 : if (spdm_context->local_context.algorithm.aead_cipher_suite != 0) {
212 : 74 : spdm_request->struct_table[index].alg_type =
213 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD;
214 : 74 : spdm_request->struct_table[index].alg_count = 0x20;
215 : 74 : spdm_request->struct_table[index].alg_supported =
216 : 74 : spdm_context->local_context.algorithm.aead_cipher_suite;
217 : 74 : index++;
218 : : }
219 [ + + ]: 76 : if (spdm_context->local_context.algorithm.req_base_asym_alg != 0) {
220 : 74 : spdm_request->struct_table[index].alg_type =
221 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG;
222 : 74 : spdm_request->struct_table[index].alg_count = 0x20;
223 : 74 : spdm_request->struct_table[index].alg_supported =
224 : 74 : spdm_context->local_context.algorithm.req_base_asym_alg;
225 : 74 : index++;
226 : : }
227 [ + + ]: 76 : if (spdm_context->local_context.algorithm.key_schedule != 0) {
228 : 74 : spdm_request->struct_table[index].alg_type =
229 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE;
230 : 74 : spdm_request->struct_table[index].alg_count = 0x20;
231 : 74 : spdm_request->struct_table[index].alg_supported =
232 : 74 : spdm_context->local_context.algorithm.key_schedule;
233 : 74 : index++;
234 : : }
235 [ + + ]: 76 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
236 [ - + ]: 2 : if (spdm_context->local_context.algorithm.req_pqc_asym_alg != 0) {
237 : : /* Add assert to ensure it can be cast to uint16_t.
238 : : * It is enough now and can be enlarged later. */
239 [ # # ]: 0 : LIBSPDM_ASSERT(spdm_context->local_context.algorithm.req_pqc_asym_alg <= UINT16_MAX);
240 : 0 : spdm_request->struct_table[index].alg_type =
241 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG;
242 : 0 : spdm_request->struct_table[index].alg_count = 0x20;
243 : 0 : spdm_request->struct_table[index].alg_supported =
244 : 0 : (uint16_t)spdm_context->local_context.algorithm.req_pqc_asym_alg;
245 : 0 : index++;
246 : : }
247 [ - + ]: 2 : if (spdm_context->local_context.algorithm.kem_alg != 0) {
248 : : /* Add assert to ensure it can be cast to uint16_t.
249 : : * It is enough now and can be enlarged later. */
250 [ # # ]: 0 : LIBSPDM_ASSERT(spdm_context->local_context.algorithm.kem_alg <= UINT16_MAX);
251 : 0 : spdm_request->struct_table[index].alg_type =
252 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG;
253 : 0 : spdm_request->struct_table[index].alg_count = 0x20;
254 : 0 : spdm_request->struct_table[index].alg_supported =
255 : 0 : (uint16_t)spdm_context->local_context.algorithm.kem_alg;
256 : 0 : index++;
257 : : }
258 : : }
259 [ - + ]: 76 : LIBSPDM_ASSERT(index == spdm_request->header.param1);
260 : : }
261 : 130 : spdm_request_size = spdm_request->length;
262 : :
263 : : /* -=[Send Request Phase]=- */
264 : 130 : status = libspdm_send_spdm_request(spdm_context, NULL, spdm_request_size, spdm_request);
265 [ + + ]: 130 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
266 : 13 : libspdm_release_sender_buffer (spdm_context);
267 : 13 : return status;
268 : : }
269 : 117 : libspdm_release_sender_buffer (spdm_context);
270 : 117 : spdm_request = (void *)spdm_context->last_spdm_request;
271 : :
272 : : /* -=[Receive Response Phase]=- */
273 : 117 : status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
274 [ + + ]: 117 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
275 : 1 : return status;
276 : : }
277 [ - + ]: 116 : LIBSPDM_ASSERT (message_size >= transport_header_size);
278 : 116 : spdm_response = (void *)(message);
279 : 116 : spdm_response_size = message_size;
280 : :
281 : 116 : status = libspdm_receive_spdm_response(spdm_context, NULL, &spdm_response_size,
282 : : (void **)&spdm_response);
283 [ + + ]: 116 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
284 : 2 : goto receive_done;
285 : : }
286 : :
287 : : /* -=[Validate Response Phase]=- */
288 [ - + ]: 114 : if (spdm_response_size < sizeof(spdm_message_header_t)) {
289 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
290 : 0 : goto receive_done;
291 : : }
292 [ + + ]: 114 : if (spdm_response->header.request_response_code == SPDM_ERROR) {
293 : 10 : status = libspdm_handle_simple_error_response(spdm_context, spdm_response->header.param1);
294 [ + - ]: 10 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
295 : 10 : goto receive_done;
296 : : }
297 [ + + ]: 104 : } else if (spdm_response->header.request_response_code != SPDM_ALGORITHMS) {
298 : 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
299 : 1 : goto receive_done;
300 : : }
301 [ + + ]: 103 : if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
302 : 9 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
303 : 9 : goto receive_done;
304 : : }
305 [ + + ]: 94 : if (spdm_response_size < sizeof(spdm_algorithms_response_t)) {
306 : 4 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
307 : 4 : goto receive_done;
308 : : }
309 [ + + ]: 90 : if (!libspdm_onehot0(spdm_response->measurement_specification_sel)) {
310 : 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
311 : 1 : goto receive_done;
312 : : }
313 [ + + ]: 89 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
314 [ + + ]: 27 : if (!libspdm_onehot0(spdm_response->other_params_selection &
315 : : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK)) {
316 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
317 : 2 : goto receive_done;
318 : : }
319 : : }
320 [ + + ]: 87 : if (!libspdm_onehot0(spdm_response->measurement_hash_algo)) {
321 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
322 : 2 : goto receive_done;
323 : : }
324 [ + + ]: 85 : if (!libspdm_onehot0(spdm_response->base_asym_sel)) {
325 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
326 : 2 : goto receive_done;
327 : : }
328 [ + + ]: 83 : if (!libspdm_onehot0(spdm_response->base_hash_sel)) {
329 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
330 : 2 : goto receive_done;
331 : : }
332 [ + + ]: 81 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
333 [ - + ]: 2 : if (!libspdm_onehot0(spdm_response->pqc_asym_sel)) {
334 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
335 : 0 : goto receive_done;
336 : : }
337 : : }
338 [ + + ]: 81 : if (spdm_response->ext_asym_sel_count > 0) {
339 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
340 : 2 : goto receive_done;
341 : : }
342 [ + + ]: 79 : if (spdm_response->ext_hash_sel_count > 0) {
343 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
344 : 2 : goto receive_done;
345 : : }
346 : 77 : if (spdm_response_size <
347 : : sizeof(spdm_algorithms_response_t) +
348 : 77 : sizeof(uint32_t) * spdm_response->ext_asym_sel_count +
349 : 77 : sizeof(uint32_t) * spdm_response->ext_hash_sel_count +
350 [ - + ]: 77 : sizeof(spdm_negotiate_algorithms_common_struct_table_t) * spdm_response->header.param1) {
351 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
352 : 0 : goto receive_done;
353 : : }
354 : 77 : struct_table =
355 : 77 : (void *)((size_t)spdm_response +
356 : 77 : sizeof(spdm_algorithms_response_t) +
357 : 77 : sizeof(uint32_t) * spdm_response->ext_asym_sel_count +
358 : 77 : sizeof(uint32_t) * spdm_response->ext_hash_sel_count);
359 [ + + ]: 77 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
360 : 55 : alg_type_pre = 0;
361 : : /* header.param1 is implicitly checked through spdm_response_size. */
362 [ + + ]: 183 : for (index = 0; index < spdm_response->header.param1; index++) {
363 [ - + ]: 143 : if ((size_t)spdm_response + spdm_response_size < (size_t)struct_table) {
364 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
365 : 0 : goto receive_done;
366 : : }
367 [ - + ]: 143 : if ((size_t)spdm_response + spdm_response_size - (size_t)struct_table <
368 : : sizeof(spdm_negotiate_algorithms_common_struct_table_t)) {
369 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
370 : 0 : goto receive_done;
371 : : }
372 [ + + ]: 143 : if ((struct_table->alg_type < SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE) ||
373 [ - + ]: 141 : (struct_table->alg_type >
374 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG)) {
375 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
376 : 2 : goto receive_done;
377 : : }
378 [ + - ]: 141 : if ((spdm_response->header.spdm_version < SPDM_MESSAGE_VERSION_14) &&
379 [ + + ]: 141 : (struct_table->alg_type >
380 : : SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE)) {
381 : 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
382 : 1 : goto receive_done;
383 : : }
384 : : /* AlgType shall monotonically increase for subsequent entries. */
385 [ + + + + ]: 140 : if ((index != 0) && (struct_table->alg_type <= alg_type_pre)) {
386 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
387 : 2 : goto receive_done;
388 : : }
389 : 138 : alg_type_pre = struct_table->alg_type;
390 : 138 : fixed_alg_size = (struct_table->alg_count >> 4) & 0xF;
391 : 138 : ext_alg_count = struct_table->alg_count & 0xF;
392 [ + + ]: 138 : if (fixed_alg_size != 2) {
393 : 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
394 : 1 : goto receive_done;
395 : : }
396 [ + + ]: 137 : if (ext_alg_count > 0) {
397 : 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
398 : 1 : goto receive_done;
399 : : }
400 [ + + ]: 136 : if (!libspdm_onehot0(struct_table->alg_supported)) {
401 : 8 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
402 : 8 : goto receive_done;
403 : : }
404 : 128 : if ((size_t)spdm_response + spdm_response_size -
405 : 128 : (size_t)struct_table - sizeof(spdm_negotiate_algorithms_common_struct_table_t) <
406 [ - + ]: 128 : sizeof(uint32_t) * ext_alg_count) {
407 : 0 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
408 : 0 : goto receive_done;
409 : : }
410 : 128 : struct_table =
411 : 128 : (void *)((size_t)struct_table +
412 : 128 : sizeof(spdm_negotiate_algorithms_common_struct_table_t) +
413 : 128 : sizeof(uint32_t) * ext_alg_count);
414 : : }
415 : : }
416 : :
417 : 62 : spdm_response_size = (size_t)struct_table - (size_t)spdm_response;
418 [ + + ]: 62 : if (spdm_response_size != spdm_response->length) {
419 : 1 : status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
420 : 1 : goto receive_done;
421 : : }
422 : :
423 : : /* -=[Process Response Phase]=- */
424 : 61 : status = libspdm_append_message_a(spdm_context, spdm_request, spdm_request_size);
425 [ - + ]: 61 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
426 : 0 : goto receive_done;
427 : : }
428 : :
429 : 61 : status = libspdm_append_message_a(spdm_context, spdm_response, spdm_response_size);
430 [ - + ]: 61 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
431 : 0 : goto receive_done;
432 : : }
433 : :
434 : 61 : spdm_context->connection_info.algorithm.measurement_spec =
435 : 61 : spdm_response->measurement_specification_sel;
436 [ + + ]: 61 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
437 : 24 : spdm_context->connection_info.algorithm.other_params_support =
438 : 24 : spdm_response->other_params_selection & SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK;
439 [ + + ]: 24 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
440 : 19 : spdm_context->connection_info.algorithm.other_params_support =
441 : 19 : spdm_response->other_params_selection;
442 : 19 : spdm_context->connection_info.algorithm.mel_spec =
443 : 19 : spdm_response->mel_specification_sel;
444 : : }
445 : : }
446 : 61 : spdm_context->connection_info.algorithm.measurement_hash_algo =
447 : 61 : spdm_response->measurement_hash_algo;
448 : 61 : spdm_context->connection_info.algorithm.base_asym_algo = spdm_response->base_asym_sel;
449 : 61 : spdm_context->connection_info.algorithm.base_hash_algo = spdm_response->base_hash_sel;
450 [ + + ]: 61 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
451 : 2 : spdm_context->connection_info.algorithm.pqc_asym_algo = spdm_response->pqc_asym_sel;
452 : : }
453 : :
454 [ + + ]: 61 : if (libspdm_is_capabilities_flag_supported(
455 : : spdm_context, true, 0,
456 : 53 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) &&
457 [ + + ]: 53 : (spdm_request->measurement_specification != 0)) {
458 [ + + ]: 51 : if (spdm_context->connection_info.algorithm.measurement_spec !=
459 : : SPDM_MEASUREMENT_SPECIFICATION_DMTF) {
460 : 2 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
461 : 2 : goto receive_done;
462 : : }
463 : 49 : algo_size = libspdm_get_measurement_hash_size(
464 : : spdm_context->connection_info.algorithm.measurement_hash_algo);
465 [ + + ]: 49 : if (algo_size == 0) {
466 : 2 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
467 : 2 : goto receive_done;
468 : : }
469 : : } else {
470 [ + + ]: 10 : if (spdm_context->connection_info.algorithm.measurement_spec != 0) {
471 : 4 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
472 : 4 : goto receive_done;
473 : : }
474 : : }
475 : :
476 [ + + ]: 53 : if (libspdm_is_capabilities_flag_supported(
477 : : spdm_context, true, 0,
478 [ + + ]: 48 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) ||
479 : 48 : libspdm_is_capabilities_flag_supported(
480 : : spdm_context, true, 0,
481 [ + + ]: 25 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) ||
482 : 25 : libspdm_is_capabilities_flag_supported(
483 : : spdm_context, true, 0,
484 [ + + ]: 5 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) ||
485 : 5 : libspdm_is_capabilities_flag_supported(
486 : : spdm_context, true, 0,
487 [ + - ]: 2 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG) ||
488 : 2 : libspdm_is_capabilities_flag_supported(
489 : : spdm_context, true,
490 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
491 [ - + ]: 2 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) ||
492 : 2 : libspdm_is_capabilities_flag_supported(
493 : : spdm_context, true,
494 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
495 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
496 : 51 : algo_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
497 [ + + ]: 51 : if (algo_size == 0) {
498 : 3 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
499 : 3 : goto receive_done;
500 : : }
501 : 48 : if ((spdm_context->connection_info.algorithm.base_hash_algo &
502 [ + + ]: 48 : spdm_context->local_context.algorithm.base_hash_algo) == 0) {
503 : 2 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
504 : 2 : goto receive_done;
505 : : }
506 : : }
507 : :
508 [ + + ]: 48 : if (libspdm_is_capabilities_flag_supported(
509 : : spdm_context, true, 0,
510 [ + + ]: 43 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) ||
511 : 43 : libspdm_is_capabilities_flag_supported(
512 : : spdm_context, true, 0,
513 [ + + ]: 24 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) ||
514 : 24 : libspdm_is_capabilities_flag_supported(
515 : : spdm_context, true, 0,
516 [ + + ]: 4 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) ||
517 : 4 : libspdm_is_capabilities_flag_supported(
518 : : spdm_context, true, 0,
519 [ - + ]: 2 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG) ||
520 : 2 : libspdm_is_capabilities_flag_supported(
521 : : spdm_context, true,
522 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
523 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
524 : 46 : algo_size = libspdm_get_asym_signature_size(
525 : : spdm_context->connection_info.algorithm.base_asym_algo);
526 [ + + ]: 46 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
527 : 2 : pqc_algo_size = libspdm_get_pqc_asym_signature_size(
528 : : spdm_context->connection_info.algorithm.pqc_asym_algo);
529 : : } else {
530 : 44 : pqc_algo_size = 0;
531 : : }
532 [ + + - + : 46 : if (((algo_size == 0) && (pqc_algo_size == 0)) ||
+ - ]
533 [ - + ]: 43 : ((algo_size != 0) && (pqc_algo_size != 0))) {
534 : 3 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
535 : 3 : goto receive_done;
536 : : }
537 [ + - ]: 43 : if ((algo_size != 0) &&
538 : 43 : ((spdm_context->connection_info.algorithm.base_asym_algo &
539 [ + + ]: 43 : spdm_context->local_context.algorithm.base_asym_algo) == 0)) {
540 : 2 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
541 : 2 : goto receive_done;
542 : : }
543 [ - + ]: 41 : if ((pqc_algo_size != 0) &&
544 : 0 : ((spdm_context->connection_info.algorithm.pqc_asym_algo &
545 [ # # ]: 0 : spdm_context->local_context.algorithm.pqc_asym_algo) == 0)) {
546 : 0 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
547 : 0 : goto receive_done;
548 : : }
549 : : }
550 : :
551 [ + + ]: 43 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11) {
552 : 36 : struct_table =
553 : 36 : (void *)((size_t)spdm_response +
554 : 36 : sizeof(spdm_algorithms_response_t) +
555 : 36 : sizeof(uint32_t) * spdm_response->ext_asym_sel_count +
556 : 36 : sizeof(uint32_t) * spdm_response->ext_hash_sel_count);
557 [ + + ]: 136 : for (index = 0; index < spdm_response->header.param1; index++) {
558 [ + + + + : 100 : switch (struct_table->alg_type) {
- - - ]
559 : 25 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE:
560 : 25 : spdm_context->connection_info.algorithm.dhe_named_group =
561 : 25 : struct_table->alg_supported;
562 : 25 : break;
563 : 25 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD:
564 : 25 : spdm_context->connection_info.algorithm.aead_cipher_suite =
565 : 25 : struct_table->alg_supported;
566 : 25 : break;
567 : 25 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG:
568 : 25 : spdm_context->connection_info.algorithm.req_base_asym_alg =
569 : 25 : struct_table->alg_supported;
570 : 25 : break;
571 : 25 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE:
572 : 25 : spdm_context->connection_info.algorithm.key_schedule =
573 : 25 : struct_table->alg_supported;
574 : 25 : break;
575 : 0 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_PQC_ASYM_ALG:
576 : 0 : spdm_context->connection_info.algorithm.req_pqc_asym_alg =
577 : 0 : struct_table->alg_supported;
578 : 0 : break;
579 : 0 : case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEM_ALG:
580 : 0 : spdm_context->connection_info.algorithm.kem_alg =
581 : 0 : struct_table->alg_supported;
582 : 0 : break;
583 : : }
584 : 100 : ext_alg_count = struct_table->alg_count & 0xF;
585 : 100 : struct_table =
586 : 100 : (void *)((size_t)struct_table +
587 : 100 : sizeof(spdm_negotiate_algorithms_common_struct_table_t) +
588 : 100 : sizeof(uint32_t) * ext_alg_count);
589 : : }
590 : :
591 [ + + ]: 36 : if (libspdm_is_capabilities_flag_supported(
592 : : spdm_context, true,
593 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
594 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
595 : 24 : algo_size = libspdm_get_dhe_pub_key_size(
596 : 24 : spdm_context->connection_info.algorithm.dhe_named_group);
597 [ - + ]: 24 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
598 : 0 : pqc_algo_size = libspdm_get_kem_encap_key_size(
599 : : spdm_context->connection_info.algorithm.kem_alg);
600 : : } else {
601 : 24 : pqc_algo_size = 0;
602 : : }
603 [ - + - - : 24 : if (((algo_size == 0) && (pqc_algo_size == 0)) ||
+ - ]
604 [ - + ]: 24 : ((algo_size != 0) && (pqc_algo_size != 0))) {
605 : 0 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
606 : 0 : goto receive_done;
607 : : }
608 [ + - ]: 24 : if ((algo_size != 0) &&
609 : 24 : ((spdm_context->connection_info.algorithm.dhe_named_group &
610 [ + + ]: 24 : spdm_context->local_context.algorithm.dhe_named_group) == 0)) {
611 : 2 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
612 : 2 : goto receive_done;
613 : : }
614 [ - + ]: 22 : if ((pqc_algo_size != 0) &&
615 : 0 : ((spdm_context->connection_info.algorithm.kem_alg &
616 [ # # ]: 0 : spdm_context->local_context.algorithm.kem_alg) == 0)) {
617 : 0 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
618 : 0 : goto receive_done;
619 : : }
620 : : }
621 [ + + ]: 34 : if (libspdm_is_capabilities_flag_supported(
622 : : spdm_context, true,
623 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP,
624 [ - + ]: 12 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) ||
625 : 12 : libspdm_is_capabilities_flag_supported(
626 : : spdm_context, true,
627 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
628 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
629 : 22 : algo_size = libspdm_get_aead_key_size(
630 : 22 : spdm_context->connection_info.algorithm.aead_cipher_suite);
631 [ + + ]: 22 : if (algo_size == 0) {
632 : 2 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
633 : 2 : goto receive_done;
634 : : }
635 : 20 : if ((spdm_context->connection_info.algorithm.aead_cipher_suite &
636 [ - + ]: 20 : spdm_context->local_context.algorithm.aead_cipher_suite) == 0) {
637 : 0 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
638 : 0 : goto receive_done;
639 : : }
640 : : }
641 [ + + ]: 32 : if (libspdm_is_capabilities_flag_supported(
642 : : spdm_context, true,
643 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP,
644 [ - + ]: 12 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP) ||
645 : 12 : libspdm_is_capabilities_flag_supported(
646 : : spdm_context, true,
647 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_SIG, 0)) {
648 : 20 : algo_size = libspdm_get_req_asym_signature_size(
649 : 20 : spdm_context->connection_info.algorithm.req_base_asym_alg);
650 [ - + ]: 20 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
651 : 0 : pqc_algo_size = libspdm_get_req_pqc_asym_signature_size(
652 : : spdm_context->connection_info.algorithm.req_pqc_asym_alg);
653 : : } else {
654 : 20 : pqc_algo_size = 0;
655 : : }
656 [ + + - + : 20 : if (((algo_size == 0) && (pqc_algo_size == 0)) ||
+ - ]
657 [ - + ]: 19 : ((algo_size != 0) && (pqc_algo_size != 0))) {
658 : 1 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
659 : 1 : goto receive_done;
660 : : }
661 [ + - ]: 19 : if ((algo_size != 0) &&
662 : 19 : ((spdm_context->connection_info.algorithm.req_base_asym_alg &
663 [ + + ]: 19 : spdm_context->local_context.algorithm.req_base_asym_alg) == 0)) {
664 : 2 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
665 : 2 : goto receive_done;
666 : : }
667 [ - + ]: 17 : if ((pqc_algo_size != 0) &&
668 : 0 : ((spdm_context->connection_info.algorithm.req_pqc_asym_alg &
669 [ # # ]: 0 : spdm_context->local_context.algorithm.req_pqc_asym_alg) == 0)) {
670 : 0 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
671 : 0 : goto receive_done;
672 : : }
673 : : }
674 [ + + ]: 29 : if (libspdm_is_capabilities_flag_supported(
675 : : spdm_context, true,
676 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
677 [ - + ]: 12 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) ||
678 : 12 : libspdm_is_capabilities_flag_supported(
679 : : spdm_context, true,
680 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
681 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
682 [ + + ]: 17 : if (spdm_context->connection_info.algorithm.key_schedule !=
683 : : SPDM_ALGORITHMS_KEY_SCHEDULE_SPDM) {
684 : 2 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
685 : 2 : goto receive_done;
686 : : }
687 : 15 : if ((spdm_context->connection_info.algorithm.key_schedule &
688 [ - + ]: 15 : spdm_context->local_context.algorithm.key_schedule) == 0) {
689 : 0 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
690 : 0 : goto receive_done;
691 : : }
692 [ + + ]: 15 : if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
693 [ + + ]: 8 : if (libspdm_is_capabilities_flag_supported(
694 : : spdm_context, true, 0,
695 : 4 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP) &&
696 [ + + ]: 4 : (spdm_request->mel_specification != 0)) {
697 [ + + ]: 2 : if (spdm_context->connection_info.algorithm.mel_spec !=
698 : : SPDM_MEL_SPECIFICATION_DMTF) {
699 : 1 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
700 : 1 : goto receive_done;
701 : : }
702 : : } else {
703 [ + + ]: 6 : if (spdm_context->connection_info.algorithm.mel_spec != 0) {
704 : 3 : status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
705 : 3 : goto receive_done;
706 : : }
707 : : }
708 : : }
709 : : }
710 : :
711 [ + + ]: 23 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
712 [ + + ]: 13 : if ((spdm_context->connection_info.algorithm.other_params_support &
713 : : SPDM_ALGORITHMS_MULTI_KEY_CONN) == 0) {
714 [ + + ]: 10 : if ((spdm_context->local_context.capability.flags &
715 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) ==
716 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP_ONLY) {
717 : 1 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
718 : 1 : goto receive_done;
719 : : }
720 : 9 : spdm_context->connection_info.multi_key_conn_req = false;
721 : : } else {
722 [ + + ]: 3 : if ((spdm_context->local_context.capability.flags &
723 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MULTI_KEY_CAP) == 0) {
724 : 1 : status = LIBSPDM_STATUS_NEGOTIATION_FAIL;
725 : 1 : goto receive_done;
726 : : }
727 : 2 : spdm_context->connection_info.multi_key_conn_req = true;
728 : : }
729 : : }
730 : : } else {
731 : 7 : spdm_context->connection_info.algorithm.dhe_named_group = 0;
732 : 7 : spdm_context->connection_info.algorithm.aead_cipher_suite = 0;
733 : 7 : spdm_context->connection_info.algorithm.req_base_asym_alg = 0;
734 : 7 : spdm_context->connection_info.algorithm.key_schedule = 0;
735 : 7 : spdm_context->connection_info.algorithm.other_params_support = 0;
736 : 7 : spdm_context->connection_info.algorithm.req_pqc_asym_alg = 0;
737 : 7 : spdm_context->connection_info.algorithm.kem_alg = 0;
738 : : }
739 : :
740 : 28 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "base_hash - 0x%08x\n",
741 : : spdm_context->connection_info.algorithm.base_hash_algo));
742 : 28 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "base_asym - 0x%08x\n",
743 : : spdm_context->connection_info.algorithm.base_asym_algo));
744 : 28 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "dhe - 0x%04x\n",
745 : : spdm_context->connection_info.algorithm.dhe_named_group));
746 : 28 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "aead - 0x%04x\n",
747 : : spdm_context->connection_info.algorithm.aead_cipher_suite));
748 : 28 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "req_asym - 0x%04x\n",
749 : : spdm_context->connection_info.algorithm.req_base_asym_alg));
750 : 28 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "pqc_asym - 0x%08x\n",
751 : : spdm_context->connection_info.algorithm.pqc_asym_algo));
752 : 28 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "req_pqc_asym - 0x%04x\n",
753 : : spdm_context->connection_info.algorithm.req_pqc_asym_alg));
754 : 28 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "kem - 0x%04x\n",
755 : : spdm_context->connection_info.algorithm.kem_alg));
756 : :
757 : : /* -=[Update State Phase]=- */
758 : 28 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
759 : :
760 : : /* -=[Log Message Phase]=- */
761 : : #if LIBSPDM_ENABLE_MSG_LOG
762 : 28 : libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
763 : : #endif /* LIBSPDM_ENABLE_MSG_LOG */
764 : :
765 : 28 : status = LIBSPDM_STATUS_SUCCESS;
766 : :
767 : 116 : receive_done:
768 : 116 : libspdm_release_receiver_buffer (spdm_context);
769 : 116 : return status;
770 : : }
771 : :
772 : 133 : libspdm_return_t libspdm_negotiate_algorithms(libspdm_context_t *spdm_context)
773 : : {
774 : : size_t retry;
775 : : uint64_t retry_delay_time;
776 : : libspdm_return_t status;
777 : :
778 : 133 : spdm_context->crypto_request = false;
779 : 133 : retry = spdm_context->retry_times;
780 : 133 : retry_delay_time = spdm_context->retry_delay_time;
781 : : do {
782 : 134 : status = libspdm_try_negotiate_algorithms(spdm_context);
783 [ + + ]: 134 : if (status != LIBSPDM_STATUS_BUSY_PEER) {
784 : 131 : return status;
785 : : }
786 : :
787 : 3 : libspdm_sleep(retry_delay_time);
788 [ + + ]: 3 : } while (retry-- != 0);
789 : :
790 : 2 : return status;
791 : : }
|