Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2025 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 : #include "internal/libspdm_secured_message_lib.h"
9 :
10 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
11 :
12 : /**
13 : * This function generates the PSK exchange HMAC based upon TH.
14 : *
15 : * @param spdm_context A pointer to the SPDM context.
16 : * @param session_info The session info of an SPDM session.
17 : * @param hmac The buffer to store the PSK exchange HMAC.
18 : *
19 : * @retval true PSK exchange HMAC is generated.
20 : * @retval false PSK exchange HMAC is not generated.
21 : **/
22 11 : static bool libspdm_generate_psk_exchange_rsp_hmac(libspdm_context_t *spdm_context,
23 : libspdm_session_info_t *session_info,
24 : uint8_t *hmac)
25 : {
26 : uint8_t hmac_data[LIBSPDM_MAX_HASH_SIZE];
27 : size_t hash_size;
28 : bool result;
29 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
30 : uint8_t *th_curr_data;
31 : size_t th_curr_data_size;
32 : libspdm_th_managed_buffer_t th_curr;
33 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
34 : #endif
35 :
36 11 : hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
37 :
38 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
39 : result = libspdm_calculate_th_for_exchange(spdm_context, session_info,
40 : NULL, 0, &th_curr);
41 : if (!result) {
42 : return false;
43 : }
44 : th_curr_data = libspdm_get_managed_buffer(&th_curr);
45 : th_curr_data_size = libspdm_get_managed_buffer_size(&th_curr);
46 :
47 : result = libspdm_hash_all (spdm_context->connection_info.algorithm.base_hash_algo,
48 : th_curr_data, th_curr_data_size, hash_data);
49 : if (!result) {
50 : return false;
51 : }
52 :
53 : result = libspdm_hmac_all_with_response_finished_key(
54 : session_info->secured_message_context, hash_data,
55 : hash_size, hmac_data);
56 : if (!result) {
57 : return false;
58 : }
59 : #else
60 11 : result = libspdm_calculate_th_hmac_for_exchange_rsp(
61 : spdm_context, session_info, false, &hash_size, hmac_data);
62 11 : if (!result) {
63 0 : return false;
64 : }
65 : #endif
66 11 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_curr hmac - "));
67 11 : LIBSPDM_INTERNAL_DUMP_DATA(hmac_data, hash_size);
68 11 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
69 :
70 11 : libspdm_copy_mem(hmac, hash_size, hmac_data, hash_size);
71 :
72 11 : return true;
73 : }
74 :
75 18 : libspdm_return_t libspdm_get_response_psk_exchange(libspdm_context_t *spdm_context,
76 : size_t request_size,
77 : const void *request,
78 : size_t *response_size,
79 : void *response)
80 : {
81 : const spdm_psk_exchange_request_t *spdm_request;
82 : spdm_psk_exchange_response_t *spdm_response;
83 : bool result;
84 : uint32_t session_id;
85 : uint32_t measurement_summary_hash_size;
86 : uint32_t hmac_size;
87 : const uint8_t *cptr;
88 : uint8_t *ptr;
89 : libspdm_session_info_t *session_info;
90 : size_t total_size;
91 : uint16_t req_session_id;
92 : uint16_t rsp_session_id;
93 : libspdm_return_t status;
94 : size_t opaque_psk_exchange_rsp_size;
95 : uint8_t th1_hash_data[LIBSPDM_MAX_HASH_SIZE];
96 : uint8_t th2_hash_data[LIBSPDM_MAX_HASH_SIZE];
97 : uint32_t algo_size;
98 : uint16_t context_length;
99 : const void *psk_hint;
100 : size_t psk_hint_size;
101 :
102 18 : spdm_request = request;
103 :
104 : /* -=[Check Parameters Phase]=- */
105 18 : LIBSPDM_ASSERT(spdm_request->header.request_response_code == SPDM_PSK_EXCHANGE);
106 :
107 18 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
108 0 : return libspdm_generate_error_response(spdm_context,
109 : SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
110 : SPDM_PSK_EXCHANGE,
111 : response_size, response);
112 : }
113 :
114 18 : if (spdm_request->header.spdm_version != libspdm_get_connection_version(spdm_context)) {
115 0 : return libspdm_generate_error_response(spdm_context,
116 : SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
117 : response_size, response);
118 : }
119 18 : if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
120 3 : return libspdm_responder_handle_response_state(
121 : spdm_context,
122 3 : spdm_request->header.request_response_code,
123 : response_size, response);
124 : }
125 : /* Check capabilities even if GET_CAPABILITIES is not sent.
126 : * Assuming capabilities are provisioned.*/
127 15 : if (!libspdm_is_capabilities_flag_supported(
128 : spdm_context, false,
129 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
130 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
131 0 : return libspdm_generate_error_response(
132 : spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
133 : SPDM_PSK_EXCHANGE, response_size, response);
134 : }
135 :
136 : /* While clearing MAC_CAP and setting ENCRYPT_CAP is legal according to DSP0274, libspdm
137 : * also implements DSP0277 secure messages, which requires at least MAC_CAP to be set.
138 : */
139 15 : if (!libspdm_is_capabilities_flag_supported(
140 : spdm_context, false,
141 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
142 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
143 0 : return libspdm_generate_error_response(
144 : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
145 : SPDM_KEY_EXCHANGE, response_size, response);
146 : }
147 :
148 15 : if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
149 1 : return libspdm_generate_error_response(spdm_context,
150 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
151 : 0, response_size, response);
152 : }
153 14 : if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) {
154 2 : if ((spdm_context->connection_info.algorithm.other_params_support &
155 : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) != SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
156 0 : return libspdm_generate_error_response(
157 : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
158 : 0, response_size, response);
159 : }
160 : }
161 14 : if (spdm_context->last_spdm_request_session_id_valid) {
162 0 : return libspdm_generate_error_response(spdm_context,
163 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
164 : 0, response_size, response);
165 : }
166 :
167 : {
168 : /* Double check if algorithm has been provisioned, because ALGORITHM might be skipped.*/
169 14 : if (libspdm_is_capabilities_flag_supported(
170 : spdm_context, true, 0,
171 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP)) {
172 0 : if (spdm_context->connection_info.algorithm
173 0 : .measurement_spec != SPDM_MEASUREMENT_SPECIFICATION_DMTF) {
174 0 : return libspdm_generate_error_response(
175 : spdm_context,
176 : SPDM_ERROR_CODE_INVALID_REQUEST,
177 : 0, response_size,
178 : response);
179 : }
180 0 : algo_size = libspdm_get_measurement_hash_size(
181 : spdm_context->connection_info.algorithm
182 : .measurement_hash_algo);
183 0 : if (algo_size == 0) {
184 0 : return libspdm_generate_error_response(
185 : spdm_context,
186 : SPDM_ERROR_CODE_INVALID_REQUEST,
187 : 0, response_size,
188 : response);
189 : }
190 : }
191 14 : algo_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
192 14 : if (algo_size == 0) {
193 0 : return libspdm_generate_error_response(
194 : spdm_context,
195 : SPDM_ERROR_CODE_INVALID_REQUEST,
196 : 0, response_size, response);
197 : }
198 14 : if (spdm_context->connection_info.algorithm.key_schedule !=
199 : SPDM_ALGORITHMS_KEY_SCHEDULE_SPDM) {
200 0 : return libspdm_generate_error_response(
201 : spdm_context,
202 : SPDM_ERROR_CODE_INVALID_REQUEST,
203 : 0, response_size, response);
204 : }
205 : }
206 :
207 14 : if (spdm_request->header.param1 > 0) {
208 4 : if (!libspdm_is_capabilities_flag_supported(
209 : spdm_context, false,
210 3 : 0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) ||
211 3 : (spdm_context->connection_info.algorithm.measurement_spec == 0) ||
212 3 : (spdm_context->connection_info.algorithm.measurement_hash_algo == 0) ) {
213 1 : return libspdm_generate_error_response(
214 : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
215 : 0, response_size, response);
216 : }
217 : }
218 :
219 13 : measurement_summary_hash_size = libspdm_get_measurement_summary_hash_size(
220 13 : spdm_context, false, spdm_request->header.param1);
221 13 : if ((measurement_summary_hash_size == 0) &&
222 11 : (spdm_request->header.param1 != SPDM_PSK_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH)) {
223 1 : return libspdm_generate_error_response(spdm_context,
224 : SPDM_ERROR_CODE_INVALID_REQUEST,
225 : 0, response_size, response);
226 : }
227 :
228 12 : hmac_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
229 :
230 12 : if (request_size < sizeof(spdm_psk_exchange_request_t)) {
231 0 : return libspdm_generate_error_response(spdm_context,
232 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
233 : response_size, response);
234 : }
235 12 : if (request_size < sizeof(spdm_psk_exchange_request_t) +
236 12 : spdm_request->psk_hint_length +
237 12 : spdm_request->context_length +
238 12 : spdm_request->opaque_length) {
239 1 : return libspdm_generate_error_response(spdm_context,
240 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
241 : response_size, response);
242 : }
243 11 : request_size = sizeof(spdm_psk_exchange_request_t) +
244 11 : spdm_request->psk_hint_length +
245 11 : spdm_request->context_length +
246 11 : spdm_request->opaque_length;
247 :
248 11 : if (spdm_request->opaque_length != 0) {
249 9 : cptr = (const uint8_t *)request + sizeof(spdm_psk_exchange_request_t) +
250 9 : spdm_request->psk_hint_length + spdm_request->context_length;
251 9 : result = libspdm_process_general_opaque_data_check(spdm_context,
252 9 : spdm_request->opaque_length, cptr);
253 9 : if (!result) {
254 0 : return libspdm_generate_error_response(spdm_context,
255 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
256 : response_size, response);
257 : }
258 9 : status = libspdm_process_opaque_data_supported_version_data(
259 9 : spdm_context, spdm_request->opaque_length, cptr);
260 9 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
261 0 : return libspdm_generate_error_response(spdm_context,
262 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
263 : response_size, response);
264 : }
265 : }
266 :
267 11 : opaque_psk_exchange_rsp_size =
268 11 : libspdm_get_opaque_data_version_selection_data_size(spdm_context);
269 11 : if (libspdm_is_capabilities_flag_supported(
270 : spdm_context, false, 0,
271 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP_RESPONDER_WITH_CONTEXT)) {
272 11 : context_length = LIBSPDM_PSK_CONTEXT_LENGTH;
273 : } else {
274 0 : context_length = 0;
275 : }
276 11 : total_size = sizeof(spdm_psk_exchange_response_t) +
277 11 : measurement_summary_hash_size + context_length +
278 11 : opaque_psk_exchange_rsp_size + hmac_size;
279 :
280 11 : LIBSPDM_ASSERT(*response_size >= total_size);
281 11 : *response_size = total_size;
282 11 : libspdm_zero_mem(response, *response_size);
283 11 : spdm_response = response;
284 :
285 11 : spdm_response->header.spdm_version = spdm_request->header.spdm_version;
286 11 : spdm_response->header.request_response_code = SPDM_PSK_EXCHANGE_RSP;
287 11 : if (libspdm_is_capabilities_flag_supported(
288 : spdm_context, false,
289 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
290 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
291 0 : spdm_response->header.param1 = spdm_context->local_context.heartbeat_period;
292 : } else {
293 11 : spdm_response->header.param1 = 0x00;
294 : }
295 :
296 11 : req_session_id = spdm_request->req_session_id;
297 11 : rsp_session_id = libspdm_allocate_rsp_session_id(spdm_context, true);
298 11 : if (rsp_session_id == ((INVALID_SESSION_ID & 0xFFFF0000) >> 16)) {
299 0 : return libspdm_generate_error_response(
300 : spdm_context, SPDM_ERROR_CODE_SESSION_LIMIT_EXCEEDED, 0,
301 : response_size, response);
302 : }
303 11 : if (spdm_request->psk_hint_length == 0) {
304 2 : psk_hint_size = 0;
305 2 : psk_hint = NULL;
306 9 : } else if(spdm_request->psk_hint_length <= LIBSPDM_PSK_MAX_HINT_LENGTH ) {
307 9 : psk_hint_size = spdm_request->psk_hint_length;
308 9 : psk_hint = (const uint8_t *)request +
309 : sizeof(spdm_psk_exchange_request_t);
310 : } else {
311 0 : return libspdm_generate_error_response(
312 : spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
313 : response_size, response);
314 : }
315 11 : session_id = libspdm_generate_session_id(req_session_id, rsp_session_id);
316 11 : session_info = libspdm_assign_session_id(spdm_context, session_id, true);
317 11 : if (session_info == NULL) {
318 0 : return libspdm_generate_error_response(
319 : spdm_context, SPDM_ERROR_CODE_SESSION_LIMIT_EXCEEDED, 0,
320 : response_size, response);
321 : }
322 11 : libspdm_session_info_set_psk_hint(session_info, psk_hint, psk_hint_size);
323 :
324 11 : libspdm_reset_message_buffer_via_request_code(spdm_context, NULL,
325 11 : spdm_request->header.request_response_code);
326 :
327 11 : spdm_response->rsp_session_id = rsp_session_id;
328 11 : spdm_response->reserved = 0;
329 :
330 11 : spdm_response->context_length = context_length;
331 11 : spdm_response->opaque_length = (uint16_t)opaque_psk_exchange_rsp_size;
332 :
333 11 : ptr = (void *)(spdm_response + 1);
334 :
335 : #if LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
336 11 : if (libspdm_is_capabilities_flag_supported(
337 2 : spdm_context, false, 0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) &&
338 2 : ((spdm_request->header.param1 == SPDM_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH) ||
339 1 : (spdm_request->header.param1 == SPDM_REQUEST_ALL_MEASUREMENTS_HASH))) {
340 2 : result = libspdm_generate_measurement_summary_hash(
341 : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
342 : spdm_context,
343 : #endif
344 2 : spdm_context->connection_info.version,
345 : spdm_context->connection_info.algorithm.base_hash_algo,
346 2 : spdm_context->connection_info.algorithm.measurement_spec,
347 : spdm_context->connection_info.algorithm.measurement_hash_algo,
348 2 : spdm_request->header.param1,
349 : ptr,
350 : measurement_summary_hash_size);
351 :
352 2 : if (!result) {
353 0 : libspdm_free_session_id(spdm_context, session_id);
354 0 : return libspdm_generate_error_response(spdm_context,
355 : SPDM_ERROR_CODE_UNSPECIFIED, 0,
356 : response_size, response);
357 : }
358 : }
359 : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP */
360 :
361 11 : ptr += measurement_summary_hash_size;
362 :
363 11 : if (context_length != 0) {
364 11 : if(!libspdm_get_random_number(context_length, ptr)) {
365 0 : libspdm_free_session_id(spdm_context, session_id);
366 0 : return libspdm_generate_error_response(spdm_context,
367 : SPDM_ERROR_CODE_UNSPECIFIED, 0,
368 : response_size, response);
369 : }
370 11 : ptr += context_length;
371 : }
372 :
373 11 : libspdm_build_opaque_data_version_selection_data(
374 : spdm_context, &opaque_psk_exchange_rsp_size, ptr);
375 :
376 11 : ptr += opaque_psk_exchange_rsp_size;
377 :
378 11 : status = libspdm_append_message_k(spdm_context, session_info, false, request, request_size);
379 11 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
380 0 : libspdm_free_session_id(spdm_context, session_id);
381 0 : return libspdm_generate_error_response(spdm_context,
382 : SPDM_ERROR_CODE_UNSPECIFIED, 0,
383 : response_size, response);
384 : }
385 :
386 11 : status = libspdm_append_message_k(spdm_context, session_info, false, spdm_response,
387 11 : (size_t)ptr - (size_t)spdm_response);
388 11 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
389 0 : libspdm_free_session_id(spdm_context, session_id);
390 0 : return libspdm_generate_error_response(spdm_context,
391 : SPDM_ERROR_CODE_UNSPECIFIED, 0,
392 : response_size, response);
393 : }
394 :
395 11 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_generate_session_handshake_key[%x]\n",
396 : session_id));
397 11 : result = libspdm_calculate_th1_hash(spdm_context, session_info, false,
398 : th1_hash_data);
399 11 : if (!result) {
400 0 : libspdm_free_session_id(spdm_context, session_id);
401 0 : return libspdm_generate_error_response(spdm_context,
402 : SPDM_ERROR_CODE_UNSPECIFIED, 0,
403 : response_size, response);
404 : }
405 11 : result = libspdm_generate_session_handshake_key(
406 : session_info->secured_message_context, th1_hash_data);
407 11 : if (!result) {
408 0 : libspdm_free_session_id(spdm_context, session_id);
409 0 : return libspdm_generate_error_response(spdm_context,
410 : SPDM_ERROR_CODE_UNSPECIFIED, 0,
411 : response_size, response);
412 : }
413 :
414 11 : result = libspdm_generate_psk_exchange_rsp_hmac(spdm_context, session_info,
415 : ptr);
416 11 : if (!result) {
417 0 : libspdm_free_session_id(spdm_context, session_id);
418 0 : return libspdm_generate_error_response(
419 : spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
420 : 0, response_size, response);
421 : }
422 11 : status = libspdm_append_message_k(spdm_context, session_info, false, ptr, hmac_size);
423 11 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
424 0 : libspdm_free_session_id(spdm_context, session_id);
425 0 : return libspdm_generate_error_response(spdm_context,
426 : SPDM_ERROR_CODE_UNSPECIFIED, 0,
427 : response_size, response);
428 : }
429 11 : ptr += hmac_size;
430 :
431 11 : if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
432 2 : session_info->session_policy = spdm_request->header.param2;
433 : }
434 11 : libspdm_set_session_state(spdm_context, session_id, LIBSPDM_SESSION_STATE_HANDSHAKING);
435 :
436 11 : if (!libspdm_is_capabilities_flag_supported(
437 : spdm_context, false, 0,
438 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP_RESPONDER_WITH_CONTEXT)) {
439 : /* No need to receive PSK_FINISH, enter application phase directly.*/
440 :
441 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_generate_session_data_key[%x]\n",
442 : session_id));
443 0 : result = libspdm_calculate_th2_hash(spdm_context, session_info,
444 : false, th2_hash_data);
445 0 : if (!result) {
446 0 : libspdm_free_session_id(spdm_context, session_id);
447 0 : return libspdm_generate_error_response(
448 : spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
449 : 0, response_size, response);
450 : }
451 0 : result = libspdm_generate_session_data_key(
452 : session_info->secured_message_context, th2_hash_data);
453 0 : if (!result) {
454 0 : libspdm_free_session_id(spdm_context, session_id);
455 0 : return libspdm_generate_error_response(
456 : spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
457 : 0, response_size, response);
458 : }
459 :
460 : #if LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP
461 0 : if (libspdm_is_capabilities_flag_supported(
462 : spdm_context, false,
463 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
464 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
465 0 : result = libspdm_start_watchdog(
466 0 : session_id, spdm_context->local_context.heartbeat_period * 2);
467 0 : if (!result) {
468 0 : libspdm_free_session_id(spdm_context, session_id);
469 0 : return libspdm_generate_error_response(
470 : spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
471 : 0, response_size, response);
472 : }
473 : }
474 : #endif /* LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP */
475 :
476 0 : libspdm_set_session_state(spdm_context, session_id, LIBSPDM_SESSION_STATE_ESTABLISHED);
477 : }
478 :
479 11 : if (libspdm_is_capabilities_flag_supported(
480 : spdm_context, false,
481 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
482 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
483 0 : session_info->heartbeat_period = spdm_context->local_context.heartbeat_period;
484 : } else {
485 11 : session_info->heartbeat_period = 0x00;
486 : }
487 :
488 11 : return LIBSPDM_STATUS_SUCCESS;
489 : }
490 :
491 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
|