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 : #ifndef SPDM_COMMON_LIB_INTERNAL_H
8 : #define SPDM_COMMON_LIB_INTERNAL_H
9 :
10 : #include "library/spdm_common_lib.h"
11 : #include "library/spdm_secured_message_lib.h"
12 : #include "library/spdm_return_status.h"
13 : #include "library/spdm_crypt_lib.h"
14 : #include "hal/library/debuglib.h"
15 : #include "hal/library/memlib.h"
16 : #include "hal/library/requester/reqasymsignlib.h"
17 : #include "hal/library/requester/psklib.h"
18 : #include "hal/library/responder/asymsignlib.h"
19 : #include "hal/library/responder/csrlib.h"
20 : #include "hal/library/responder/measlib.h"
21 : #include "hal/library/responder/key_pair_info.h"
22 : #include "hal/library/responder/psklib.h"
23 : #include "hal/library/responder/setcertlib.h"
24 : #include "hal/library/endpointinfolib.h"
25 : #include "hal/library/eventlib.h"
26 : #include "hal/library/cryptlib.h"
27 :
28 : #define INVALID_SESSION_ID LIBSPDM_INVALID_SESSION_ID
29 : /* The SPDM specification does not limit the values of CTExponent and RDTExponent.
30 : * libspdm artificially limits their values to 31, which corresponds to approximately 35 minutes
31 : * for CT and RDT. If an endpoint takes longer than 35 minutes to generate an SPDM message then
32 : * libspdm assumes the Integrator would not want to interact with such an endpoint. A maximum value
33 : * of 31 also means that, when calculating CT and RDT, a left-shift will not result in C undefined
34 : * behavior.
35 : */
36 : #define LIBSPDM_MAX_CT_EXPONENT 31
37 : #define LIBSPDM_MAX_RDT_EXPONENT 31
38 :
39 : #define LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER 0xFFFFFFFFFFFFFFFFull
40 :
41 : typedef struct {
42 : uint8_t spdm_version_count;
43 : spdm_version_number_t spdm_version[SPDM_MAX_VERSION_COUNT];
44 : } libspdm_device_version_t;
45 :
46 : typedef struct {
47 : uint8_t secured_message_version_count;
48 : spdm_version_number_t secured_message_version[SECURED_SPDM_MAX_VERSION_COUNT];
49 : } libspdm_secured_message_version_t;
50 :
51 : typedef struct {
52 : uint8_t ct_exponent;
53 : uint64_t rtt;
54 : uint32_t st1;
55 : uint32_t flags;
56 : uint16_t ext_flags;
57 : uint32_t data_transfer_size;
58 : uint32_t sender_data_transfer_size;
59 : uint32_t max_spdm_msg_size;
60 : uint32_t transport_header_size;
61 : uint32_t transport_tail_size;
62 : } libspdm_device_capability_t;
63 :
64 : typedef struct {
65 : uint8_t measurement_spec;
66 : uint8_t other_params_support;
67 : uint8_t mel_spec;
68 : uint32_t measurement_hash_algo;
69 : uint32_t base_asym_algo;
70 : uint32_t base_hash_algo;
71 : uint16_t dhe_named_group;
72 : uint16_t aead_cipher_suite;
73 : uint16_t req_base_asym_alg;
74 : uint16_t key_schedule;
75 : uint32_t pqc_asym_algo;
76 : uint32_t req_pqc_asym_alg;
77 : uint32_t kem_alg;
78 : bool pqc_first;
79 : } libspdm_device_algorithm_t;
80 :
81 : typedef struct {
82 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
83 : uint8_t buffer[LIBSPDM_MAX_CERT_CHAIN_SIZE];
84 : size_t buffer_size;
85 : #else
86 : uint8_t buffer_hash[LIBSPDM_MAX_HASH_SIZE];
87 : uint32_t buffer_hash_size;
88 : /* leaf cert public key of the peer */
89 : void *leaf_cert_public_key;
90 : #endif
91 : } libspdm_peer_used_cert_chain_t;
92 :
93 : typedef struct {
94 : /* Local device info */
95 : libspdm_device_version_t version;
96 : libspdm_device_capability_t capability;
97 : libspdm_device_algorithm_t algorithm;
98 : libspdm_secured_message_version_t secured_message_version;
99 :
100 : /* My Certificate */
101 : const void *local_cert_chain_provision[SPDM_MAX_SLOT_COUNT];
102 : size_t local_cert_chain_provision_size[SPDM_MAX_SLOT_COUNT];
103 : uint8_t local_supported_slot_mask;
104 : uint8_t cert_slot_reset_mask;
105 : spdm_key_pair_id_t local_key_pair_id[SPDM_MAX_SLOT_COUNT];
106 : spdm_certificate_info_t local_cert_info[SPDM_MAX_SLOT_COUNT];
107 : spdm_key_usage_bit_mask_t local_key_usage_bit_mask[SPDM_MAX_SLOT_COUNT];
108 : /* My raw public key (slot_id - 0xFF) */
109 : const void *local_public_key_provision;
110 : size_t local_public_key_provision_size;
111 :
112 : /* Peer Root Certificate */
113 : const void *peer_root_cert_provision[LIBSPDM_MAX_ROOT_CERT_SUPPORT];
114 : size_t peer_root_cert_provision_size[LIBSPDM_MAX_ROOT_CERT_SUPPORT];
115 : /* Peer raw public key (slot_id - 0xFF) */
116 : const void *peer_public_key_provision;
117 : size_t peer_public_key_provision_size;
118 :
119 : /* Peer Cert verify*/
120 : libspdm_verify_spdm_cert_chain_func verify_peer_spdm_cert_chain;
121 :
122 : /* Responder policy*/
123 : bool basic_mut_auth_requested;
124 : uint8_t mut_auth_requested;
125 : bool mandatory_mut_auth;
126 : uint8_t heartbeat_period;
127 :
128 : /*The device role*/
129 : bool is_requester;
130 : } libspdm_local_context_t;
131 :
132 : typedef struct {
133 : /* Connection State */
134 : libspdm_connection_state_t connection_state;
135 :
136 : /* Peer device info (negotiated) */
137 : spdm_version_number_t version;
138 : libspdm_device_capability_t capability;
139 : libspdm_device_algorithm_t algorithm;
140 :
141 : /* Peer digests buffer */
142 : uint8_t peer_provisioned_slot_mask;
143 : uint8_t peer_supported_slot_mask;
144 : uint8_t peer_total_digest_buffer[LIBSPDM_MAX_HASH_SIZE * SPDM_MAX_SLOT_COUNT];
145 :
146 : spdm_key_pair_id_t peer_key_pair_id[SPDM_MAX_SLOT_COUNT];
147 : spdm_certificate_info_t peer_cert_info[SPDM_MAX_SLOT_COUNT];
148 : spdm_key_usage_bit_mask_t peer_key_usage_bit_mask[SPDM_MAX_SLOT_COUNT];
149 :
150 : /* Peer CertificateChain */
151 : libspdm_peer_used_cert_chain_t peer_used_cert_chain[SPDM_MAX_SLOT_COUNT];
152 : uint8_t peer_used_cert_chain_slot_id;
153 :
154 : /* Local Used CertificateChain (for responder, or requester in mut auth) */
155 : const uint8_t *local_used_cert_chain_buffer;
156 : size_t local_used_cert_chain_buffer_size;
157 : uint8_t local_used_cert_chain_slot_id;
158 :
159 : /* Specifies whether the cached negotiated state should be invalidated. (responder only)
160 : * This is a "sticky" bit wherein if it is set to 1 then it cannot be set to 0. */
161 : uint8_t end_session_attributes;
162 :
163 : /* multi-key negotiated result */
164 : bool multi_key_conn_req;
165 : bool multi_key_conn_rsp;
166 : } libspdm_connection_info_t;
167 :
168 : typedef struct {
169 : size_t max_buffer_size;
170 : size_t buffer_size;
171 : /*uint8_t buffer[max_buffer_size];*/
172 : } libspdm_managed_buffer_t;
173 :
174 : typedef struct {
175 : size_t max_buffer_size;
176 : size_t buffer_size;
177 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE];
178 : } libspdm_vca_managed_buffer_t;
179 :
180 : /*
181 : * +--------------------------+------------------------------------------+---------+
182 : * | DIGESTS 1.4 | 4 + (H [+ 4]) * SlotNum = [36, 548] | [1, 18] |
183 : * +--------------------------+------------------------------------------+---------+
184 : * It is for multi-key.
185 : */
186 : #define LIBSPDM_MAX_MESSAGE_D_BUFFER_SIZE (4 + \
187 : (LIBSPDM_MAX_HASH_SIZE + 4) * SPDM_MAX_SLOT_COUNT)
188 :
189 : typedef struct {
190 : size_t max_buffer_size;
191 : size_t buffer_size;
192 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_D_BUFFER_SIZE];
193 : } libspdm_message_d_managed_buffer_t;
194 :
195 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
196 :
197 : /*
198 : * +--------------------------+------------------------------------------+---------+
199 : * | GET_DIGESTS 1.4 | 4 | 1 |
200 : * | DIGESTS 1.4 | 4 + (H [+ 4]) * SlotNum = [36, 548] | [1, 18] |
201 : * +--------------------------+------------------------------------------+---------+
202 : * | GET_CERTIFICATE 1.4 | 16 | 1 |
203 : * | CERTIFICATE 1.4 | 16 + PortionLen | [1, ] |
204 : * +--------------------------+------------------------------------------+---------+
205 : */
206 : #define LIBSPDM_MAX_MESSAGE_B_BUFFER_SIZE (40 + \
207 : (LIBSPDM_MAX_HASH_SIZE + 4) * SPDM_MAX_SLOT_COUNT + \
208 : LIBSPDM_MAX_CERT_CHAIN_SIZE)
209 :
210 : /*
211 : * +--------------------------+------------------------------------------+---------+
212 : * | CHALLENGE 1.4 | 44 | 1 |
213 : * | CHALLENGE_AUTH 1.4 | 46 + H * 2 + S [+ O] = [166, 678] | [6, 23] |
214 : * +--------------------------+------------------------------------------+---------+
215 : */
216 : #define LIBSPDM_MAX_MESSAGE_C_BUFFER_SIZE (90 + \
217 : LIBSPDM_MAX_HASH_SIZE * 2 + \
218 : LIBSPDM_RSP_SIGNATURE_DATA_MAX_SIZE + \
219 : SPDM_MAX_OPAQUE_DATA_SIZE)
220 :
221 : /*
222 : * +--------------------------+------------------------------------------+---------+
223 : * | GET_MEASUREMENTS 1.4 | 13 + Nonce (0 or 32) | 1 |
224 : * | MEASUREMENTS 1.4 | 50 + MeasRecLen (+ S) [+ O] = [106, 554] | [4, 19] |
225 : * +--------------------------+------------------------------------------+---------+
226 : */
227 : #define LIBSPDM_MAX_MESSAGE_M_BUFFER_SIZE (63 + SPDM_NONCE_SIZE + \
228 : LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE + \
229 : LIBSPDM_RSP_SIGNATURE_DATA_MAX_SIZE + \
230 : SPDM_MAX_OPAQUE_DATA_SIZE)
231 :
232 : /*
233 : * +--------------------------+------------------------------------------+---------+
234 : * | KEY_EXCHANGE 1.4 | 42 + D [+ O] = [106, 554] | [4, 19] |
235 : * | KEY_EXCHANGE_RSP 1.4 | 42 + D + H + S (+ H) [+ O] = [234, 1194] | [8, 40] |
236 : * +--------------------------+------------------------------------------+---------+
237 : * | PSK_EXCHANGE 1.4 | 12 [+ PSKHint] + R [+ O] = 44 | 2 |
238 : * | PSK_EXCHANGE_RSP 1.4 | 12 + R + H (+ H) [+ O] = [108, 172] | [4, 6] |
239 : * +--------------------------+------------------------------------------+---------+
240 : */
241 : #define LIBSPDM_MAX_MESSAGE_K_BUFFER_SIZE (84 + LIBSPDM_REQ_EXCHANGE_DATA_MAX_SIZE + \
242 : LIBSPDM_RSP_EXCHANGE_DATA_MAX_SIZE + \
243 : LIBSPDM_MAX_HASH_SIZE * 2 + \
244 : LIBSPDM_RSP_SIGNATURE_DATA_MAX_SIZE + \
245 : SPDM_MAX_OPAQUE_DATA_SIZE * 2)
246 :
247 : /*
248 : * +--------------------------+------------------------------------------+---------+
249 : * | FINISH 1.4 | 6 (+ S) + H [+ O] = [100, 580] | [4, 20] |
250 : * | FINISH_RSP 1.4 | 6 (+ H) [+ O] = [36, 69] | [1, 3] |
251 : * +--------------------------+------------------------------------------+---------+
252 : * | PSK_FINISH 1.4 | 6 + H [+ O] = [36, 68] | [1, 3] |
253 : * | PSK_FINISH_RSP 1.4 | 6 [+ O] | 1 |
254 : * +--------------------------+------------------------------------------+---------+
255 : */
256 : #define LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE (12 + LIBSPDM_MAX_HASH_SIZE * 2 + \
257 : LIBSPDM_REQ_SIGNATURE_DATA_MAX_SIZE + \
258 : SPDM_MAX_OPAQUE_DATA_SIZE * 2)
259 :
260 : /*
261 : * +--------------------------+------------------------------------------+---------+
262 : * | GET_EP_INFO 1.4 | 8 + Nonce (0 or 32) = [8, 40] | 1 |
263 : * | EP_INFO 1.4 | 12 + Nonce + EPInfoLen (+ S) = [12, 1024]| [1, 25] |
264 : * +--------------------------+------------------------------------------+---------+
265 : */
266 : #define LIBSPDM_MAX_MESSAGE_E_BUFFER_SIZE (20 + SPDM_NONCE_SIZE * 2 + \
267 : LIBSPDM_MAX_ENDPOINT_INFO_LENGTH + \
268 : LIBSPDM_RSP_SIGNATURE_DATA_MAX_SIZE)
269 :
270 : #define LIBSPDM_MAX_MESSAGE_L1L2_BUFFER_SIZE \
271 : (LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE + LIBSPDM_MAX_MESSAGE_M_BUFFER_SIZE)
272 :
273 : #define LIBSPDM_MAX_MESSAGE_M1M2_BUFFER_SIZE \
274 : (LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE + \
275 : LIBSPDM_MAX_MESSAGE_B_BUFFER_SIZE + LIBSPDM_MAX_MESSAGE_C_BUFFER_SIZE)
276 :
277 : #define LIBSPDM_MAX_MESSAGE_TH_BUFFER_SIZE \
278 : (LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE + \
279 : LIBSPDM_MAX_MESSAGE_D_BUFFER_SIZE + \
280 : LIBSPDM_MAX_HASH_SIZE + LIBSPDM_MAX_MESSAGE_K_BUFFER_SIZE + \
281 : LIBSPDM_MAX_MESSAGE_D_BUFFER_SIZE + \
282 : LIBSPDM_MAX_HASH_SIZE + LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE)
283 :
284 : #define LIBSPDM_MAX_MESSAGE_IL1IL2_BUFFER_SIZE \
285 : (LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE + LIBSPDM_MAX_MESSAGE_E_BUFFER_SIZE)
286 :
287 : typedef struct {
288 : size_t max_buffer_size;
289 : size_t buffer_size;
290 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_B_BUFFER_SIZE];
291 : } libspdm_message_b_managed_buffer_t;
292 :
293 : typedef struct {
294 : size_t max_buffer_size;
295 : size_t buffer_size;
296 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_C_BUFFER_SIZE];
297 : } libspdm_message_c_managed_buffer_t;
298 :
299 : typedef struct {
300 : size_t max_buffer_size;
301 : size_t buffer_size;
302 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_M_BUFFER_SIZE];
303 : } libspdm_message_m_managed_buffer_t;
304 :
305 : typedef struct {
306 : size_t max_buffer_size;
307 : size_t buffer_size;
308 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_K_BUFFER_SIZE];
309 : } libspdm_message_k_managed_buffer_t;
310 :
311 : typedef struct {
312 : size_t max_buffer_size;
313 : size_t buffer_size;
314 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE];
315 : } libspdm_message_f_managed_buffer_t;
316 :
317 : typedef struct {
318 : size_t max_buffer_size;
319 : size_t buffer_size;
320 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_E_BUFFER_SIZE];
321 : } libspdm_message_e_managed_buffer_t;
322 :
323 : typedef struct {
324 : size_t max_buffer_size;
325 : size_t buffer_size;
326 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_L1L2_BUFFER_SIZE];
327 : } libspdm_l1l2_managed_buffer_t;
328 :
329 : typedef struct {
330 : size_t max_buffer_size;
331 : size_t buffer_size;
332 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_M1M2_BUFFER_SIZE];
333 : } libspdm_m1m2_managed_buffer_t;
334 :
335 : typedef struct {
336 : size_t max_buffer_size;
337 : size_t buffer_size;
338 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_IL1IL2_BUFFER_SIZE];
339 : } libspdm_il1il2_managed_buffer_t;
340 :
341 : typedef struct {
342 : size_t max_buffer_size;
343 : size_t buffer_size;
344 : uint8_t buffer[LIBSPDM_MAX_MESSAGE_TH_BUFFER_SIZE];
345 : } libspdm_th_managed_buffer_t;
346 :
347 : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
348 :
349 : /* signature = Sign(SK, hash(M1))
350 : * Verify(PK, hash(M2), signature)*/
351 :
352 : /* M1/M2 = Concatenate (A, B, C)
353 : * A = Concatenate (GET_VERSION, VERSION, GET_CAPABILITIES, CAPABILITIES, NEGOTIATE_ALGORITHMS, ALGORITHMS)
354 : * B = Concatenate (GET_DIGEST, DIGEST, GET_CERTIFICATE, CERTIFICATE)
355 : * C = Concatenate (CHALLENGE, CHALLENGE_AUTH\signature)*/
356 :
357 : /* Mut M1/M2 = Concatenate (MutB, MutC)
358 : * MutB = Concatenate (GET_DIGEST, DIGEST, GET_CERTIFICATE, CERTIFICATE)
359 : * MutC = Concatenate (CHALLENGE, CHALLENGE_AUTH\signature)*/
360 :
361 : /* signature = Sign(SK, hash(L1))
362 : * Verify(PK, hash(L2), signature)*/
363 :
364 : /* L1/L2 = Concatenate (M)
365 : * M = Concatenate (GET_MEASUREMENT, MEASUREMENT\signature)*/
366 :
367 : /* IL1/IL2 = Concatenate (A, E)
368 : * E = Concatenate (GET_ENDPOINT_INFO, ENDPOINT_INFO\signature)*/
369 :
370 : /* Encap IL1/IL2 = Concatenate (A, Encap E)
371 : * Encap E = Concatenate (GET_ENDPOINT_INFO, ENDPOINT_INFO\signature)*/
372 :
373 : typedef struct {
374 : /* the message_a must be plan text because we do not know the algorithm yet.*/
375 : libspdm_vca_managed_buffer_t message_a;
376 : libspdm_message_d_managed_buffer_t message_d;
377 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
378 : libspdm_message_b_managed_buffer_t message_b;
379 : libspdm_message_c_managed_buffer_t message_c;
380 : libspdm_message_b_managed_buffer_t message_mut_b;
381 : libspdm_message_c_managed_buffer_t message_mut_c;
382 : libspdm_message_m_managed_buffer_t message_m;
383 : libspdm_message_e_managed_buffer_t message_e;
384 : libspdm_message_e_managed_buffer_t message_encap_e;
385 : #else
386 : void *digest_context_m1m2;
387 : void *digest_context_mut_m1m2;
388 : void *digest_context_l1l2;
389 : void *digest_context_il1il2;
390 : void *digest_context_encap_il1il2;
391 : #endif
392 : } libspdm_transcript_t;
393 :
394 : /* TH for KEY_EXCHANGE response signature: Concatenate (A, D, Ct, K)
395 : * D = DIGEST, if MULTI_KEY_CONN_RSP
396 : * Ct = certificate chain
397 : * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response\signature+verify_data)*/
398 :
399 : /* TH for KEY_EXCHANGE response HMAC: Concatenate (A, D, Ct, K)
400 : * D = DIGEST, if MULTI_KEY_CONN_RSP
401 : * Ct = certificate chain
402 : * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response\verify_data)*/
403 :
404 : /* TH for FINISH request signature: Concatenate (A, D, Ct, K, EncapD, CM, F)
405 : * D = DIGEST, if MULTI_KEY_CONN_RSP
406 : * Ct = certificate chain
407 : * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response)
408 : * EncapD = Encap DIGEST, if MULTI_KEY_CONN_REQ
409 : * CM = mutual certificate chain
410 : * F = Concatenate (FINISH request\signature+verify_data)*/
411 :
412 : /* TH for FINISH response HMAC: Concatenate (A, D, Ct, K, EncapD, CM, F)
413 : * D = DIGEST, if MULTI_KEY_CONN_RSP
414 : * Ct = certificate chain
415 : * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response)
416 : * EncapD = Encap DIGEST, if MULTI_KEY_CONN_REQ
417 : * CM = mutual certificate chain, if MutAuth
418 : * F = Concatenate (FINISH request\verify_data)*/
419 :
420 : /* th1: Concatenate (A, D, Ct, K)
421 : * D = DIGEST, if MULTI_KEY_CONN_RSP
422 : * Ct = certificate chain
423 : * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response)*/
424 :
425 : /* th2: Concatenate (A, D, Ct, K, EncapD, CM, F)
426 : * D = DIGEST, if MULTI_KEY_CONN_RSP
427 : * Ct = certificate chain
428 : * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response)
429 : * EncapD = Encap DIGEST, if MULTI_KEY_CONN_REQ
430 : * CM = mutual certificate chain, if MutAuth
431 : * F = Concatenate (FINISH request, FINISH response)*/
432 :
433 : /* TH for PSK_EXCHANGE response HMAC: Concatenate (A, K)
434 : * K = Concatenate (PSK_EXCHANGE request, PSK_EXCHANGE response\verify_data)*/
435 :
436 : /* TH for PSK_FINISH response HMAC: Concatenate (A, K, F)
437 : * K = Concatenate (PSK_EXCHANGE request, PSK_EXCHANGE response)
438 : * F = Concatenate (PSK_FINISH request\verify_data)*/
439 :
440 : /* TH1_PSK1: Concatenate (A, K)
441 : * K = Concatenate (PSK_EXCHANGE request, PSK_EXCHANGE response\verify_data)*/
442 :
443 : /* TH1_PSK2: Concatenate (A, K, F)
444 : * K = Concatenate (PSK_EXCHANGE request, PSK_EXCHANGE response)
445 : * F = Concatenate (PSK_FINISH request\verify_data)*/
446 :
447 : /* TH2_PSK: Concatenate (A, K, F)
448 : * K = Concatenate (PSK_EXCHANGE request, PSK_EXCHANGE response)
449 : * F = Concatenate (PSK_FINISH request, PSK_FINISH response)*/
450 :
451 : typedef struct {
452 : libspdm_message_d_managed_buffer_t message_encap_d;
453 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
454 : libspdm_message_k_managed_buffer_t message_k;
455 : libspdm_message_f_managed_buffer_t message_f;
456 : libspdm_message_m_managed_buffer_t message_m;
457 : libspdm_message_e_managed_buffer_t message_e;
458 : libspdm_message_e_managed_buffer_t message_encap_e;
459 : #else
460 : bool message_f_initialized;
461 : void *digest_context_th;
462 : void *digest_context_l1l2;
463 : void *digest_context_il1il2;
464 : void *digest_context_encap_il1il2;
465 : /* this is back up for message F reset.*/
466 : void *digest_context_th_backup;
467 : #endif
468 : } libspdm_session_transcript_t;
469 :
470 : typedef struct {
471 : uint32_t session_id;
472 : bool use_psk;
473 : uint8_t mut_auth_requested;
474 : uint8_t end_session_attributes;
475 : uint8_t session_policy;
476 : uint8_t heartbeat_period;
477 : libspdm_session_transcript_t session_transcript;
478 : /* Register for the last KEY_UPDATE token and operation (responder only)*/
479 : spdm_key_update_request_t last_key_update_request;
480 : void *secured_message_context;
481 : } libspdm_session_info_t;
482 :
483 : #define LIBSPDM_MAX_ENCAP_REQUEST_OP_CODE_SEQUENCE_COUNT 3
484 : typedef struct {
485 : /* Valid OpCode: GET_DIGEST/GET_CERTIFICATE/CHALLENGE/KEY_UPDATE/GET_ENDPOINT_INFO/SEND_EVENT
486 : * The last one is 0x00, as a terminator. */
487 : uint8_t request_op_code_sequence[LIBSPDM_MAX_ENCAP_REQUEST_OP_CODE_SEQUENCE_COUNT + 1];
488 : uint8_t request_op_code_count;
489 : uint8_t current_request_op_code;
490 : uint8_t request_id;
491 : uint8_t req_slot_id;
492 : spdm_message_header_t last_encap_request_header;
493 : size_t last_encap_request_size;
494 : uint32_t cert_chain_total_len;
495 : uint8_t req_context[SPDM_REQ_CONTEXT_SIZE];
496 : uint32_t session_id;
497 : bool use_large_cert_chain;
498 : } libspdm_encap_context_t;
499 :
500 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
501 : typedef struct {
502 : bool chunk_in_use;
503 : uint8_t chunk_handle;
504 : uint32_t chunk_seq_no;
505 : size_t chunk_bytes_transferred;
506 :
507 : void* large_message;
508 : size_t large_message_size;
509 : size_t large_message_capacity;
510 : } libspdm_chunk_info_t;
511 :
512 : typedef struct {
513 : libspdm_chunk_info_t send;
514 : libspdm_chunk_info_t get;
515 : } libspdm_chunk_context_t;
516 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
517 :
518 : #if LIBSPDM_ENABLE_MSG_LOG
519 : typedef struct {
520 : void *buffer;
521 : size_t max_buffer_size;
522 : uint32_t mode;
523 : size_t buffer_size;
524 : uint32_t status;
525 : } libspdm_msg_log_t;
526 : #endif /* LIBSPDM_ENABLE_MSG_LOG */
527 :
528 : #if LIBSPDM_FIPS_MODE
529 : typedef struct {
530 : /**
531 : * Tested algo flag: 0 represents that the algo is not tested.
532 : * See LIBSPDM_FIPS_SELF_TEST_xxx;
533 : **/
534 : uint32_t tested_algo;
535 : /**
536 : * Flag for the result of run algo self_test, 0 represents the result is failed.
537 : * See LIBSPDM_FIPS_SELF_TEST_xxx;
538 : **/
539 : uint32_t self_test_result;
540 : /**
541 : * Buffer provided by integrator to hold large intermediate results.
542 : **/
543 : void *selftest_buffer;
544 : size_t selftest_buffer_size;
545 : } libspdm_fips_selftest_context_t;
546 : #endif /* LIBSPDM_FIPS_MODE */
547 :
548 : #define LIBSPDM_CONTEXT_STRUCT_VERSION 0x3
549 :
550 : typedef struct {
551 : uint32_t version;
552 :
553 : /* IO information */
554 : libspdm_device_send_message_func send_message;
555 : libspdm_device_receive_message_func receive_message;
556 :
557 : /*
558 : * reserved for request and response in the main dispatch function in SPDM responder.
559 : * this buffer is the transport message received from spdm_context->receive_message()
560 : * or sent to spdm_context->send_message().
561 : * This message may be SPDM transport message or secured SPDM transport message.
562 : **/
563 : libspdm_device_acquire_sender_buffer_func acquire_sender_buffer;
564 : libspdm_device_release_sender_buffer_func release_sender_buffer;
565 : libspdm_device_acquire_receiver_buffer_func acquire_receiver_buffer;
566 : libspdm_device_release_receiver_buffer_func release_receiver_buffer;
567 :
568 : /* Transport Layer information */
569 : libspdm_transport_encode_message_func transport_encode_message;
570 : libspdm_transport_decode_message_func transport_decode_message;
571 :
572 : /* Cached plain text command
573 : * If the command is cipher text, decrypt then cache it. */
574 : void *last_spdm_request;
575 : size_t last_spdm_request_size;
576 :
577 : /* Buffers used for data processing and transport. */
578 : void *scratch_buffer;
579 : size_t scratch_buffer_size;
580 : void *sender_buffer;
581 : size_t sender_buffer_size;
582 : void *receiver_buffer;
583 : size_t receiver_buffer_size;
584 :
585 : /* Cache session_id in this spdm_message, only valid for secured message. */
586 : uint32_t last_spdm_request_session_id;
587 : bool last_spdm_request_session_id_valid;
588 :
589 : /* Cache the error in libspdm_process_request. It is handled in libspdm_build_response. */
590 : libspdm_error_struct_t last_spdm_error;
591 :
592 : /* Register GetResponse function (responder only) */
593 : void *get_response_func;
594 :
595 : /* Register GetEncapResponse function (requester only) */
596 : void *get_encap_response_func;
597 : libspdm_encap_context_t encap_context;
598 :
599 : /* Register spdm_session_state_callback function (responder only)
600 : * Register can know the state after StartSession / EndSession. */
601 : void *spdm_session_state_callback;
602 :
603 : /* Register spdm_connection_state_callback function (responder only)
604 : * Register can know the connection state such as negotiated. */
605 : void *spdm_connection_state_callback;
606 :
607 : /* Register libspdm_key_update_callback function (responder only)
608 : * Register can know when session keys are updated during KEY_UPDATE operations. */
609 : void *spdm_key_update_callback;
610 :
611 : libspdm_local_context_t local_context;
612 :
613 : libspdm_connection_info_t connection_info;
614 : libspdm_transcript_t transcript;
615 :
616 : libspdm_session_info_t session_info[LIBSPDM_MAX_SESSION_COUNT];
617 :
618 : /* Buffer that the Responder uses to store the Requester's certificate chain for
619 : * mutual authentication. */
620 : void *mut_auth_cert_chain_buffer;
621 : size_t mut_auth_cert_chain_buffer_size;
622 : size_t mut_auth_cert_chain_buffer_max_size;
623 :
624 : /* Cache latest session ID for HANDSHAKE_IN_THE_CLEAR */
625 : uint32_t latest_session_id;
626 :
627 : /* Register for Responder state, be initial to Normal (responder only) */
628 : libspdm_response_state_t response_state;
629 :
630 : /* Cached data for SPDM_ERROR_CODE_RESPONSE_NOT_READY/SPDM_RESPOND_IF_READY */
631 : spdm_error_data_response_not_ready_t error_data;
632 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
633 : void *cache_spdm_request;
634 : size_t cache_spdm_request_size;
635 : #endif
636 : uint8_t current_token;
637 :
638 : /* Register for the retry times when receive "BUSY" Error response (requester only) */
639 : uint8_t retry_times;
640 : /* Register for the delay time in microseconds between retry requests
641 : * when receive "BUSY" Error response (requester only) */
642 : uint64_t retry_delay_time;
643 : bool crypto_request;
644 :
645 : /* App context data for use by application */
646 : void *app_context_data_ptr;
647 :
648 : /* See LIBSPDM_DATA_HANDLE_ERROR_RETURN_POLICY_*. */
649 : uint8_t handle_error_return_policy;
650 :
651 : /* Max session count for DHE session and PSK session
652 : * Set via LIBSPDM_DATA_MAX_DHE_SESSION_COUNT and LIBSPDM_DATA_MAX_PSK_SESSION_COUNT */
653 : uint32_t max_dhe_session_count;
654 : uint32_t max_psk_session_count;
655 :
656 : /* Current session count for DHE session and PSK session */
657 : uint32_t current_dhe_session_count;
658 : uint32_t current_psk_session_count;
659 :
660 : /* see LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER */
661 : uint64_t max_spdm_session_sequence_number;
662 :
663 : uint8_t sequence_number_endian;
664 :
665 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
666 : /* Chunk specific context */
667 : libspdm_chunk_context_t chunk_context;
668 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
669 :
670 : #if LIBSPDM_ENABLE_MSG_LOG
671 : libspdm_msg_log_t msg_log;
672 : #endif /* LIBSPDM_ENABLE_MSG_LOG */
673 :
674 : #if LIBSPDM_FIPS_MODE
675 : libspdm_fips_selftest_context_t fips_selftest_context;
676 : #endif /* LIBSPDM_FIPS_MODE */
677 :
678 : /* Endianness (BE/LE/Both) to use for signature verification on SPDM 1.0 and 1.1
679 : * This field is ignored for other SPDM versions */
680 : uint8_t spdm_10_11_verify_signature_endian;
681 :
682 : #if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
683 : libspdm_vendor_response_callback_func vendor_response_callback;
684 : libspdm_vendor_get_id_callback_func vendor_response_get_id;
685 : #endif /* LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES */
686 :
687 : #if LIBSPDM_EVENT_RECIPIENT_SUPPORT
688 : libspdm_process_event_func process_event;
689 : #endif /* LIBSPDM_EVENT_RECIPIENT_SUPPORT */
690 :
691 : #if (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && (LIBSPDM_SEND_GET_ENDPOINT_INFO_SUPPORT)
692 : libspdm_get_endpoint_info_callback_func get_endpoint_info_callback;
693 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && (LIBSPDM_SEND_GET_ENDPOINT_INFO_SUPPORT) */
694 : } libspdm_context_t;
695 :
696 : #define LIBSPDM_CONTEXT_SIZE_WITHOUT_SECURED_CONTEXT (sizeof(libspdm_context_t))
697 : #define LIBSPDM_CONTEXT_SIZE_ALL (LIBSPDM_CONTEXT_SIZE_WITHOUT_SECURED_CONTEXT + \
698 : LIBSPDM_SECURED_MESSAGE_CONTEXT_SIZE * LIBSPDM_MAX_SESSION_COUNT)
699 :
700 : #if LIBSPDM_DEBUG_PRINT_ENABLE
701 : /**
702 : * Return the request code name based on given request code.
703 : *
704 : * @param request_code The SPDM request code.
705 : *
706 : * @return request code name according to the request code.
707 : **/
708 : const char *libspdm_get_code_str(uint8_t request_code);
709 :
710 : #ifdef LIBSPDM_INTERNAL_DUMP_HEX_STR_OVERRIDE
711 : extern void LIBSPDM_INTERNAL_DUMP_HEX_STR_OVERRIDE(const uint8_t *data, size_t size);
712 : #define LIBSPDM_INTERNAL_DUMP_HEX_STR(data, size) LIBSPDM_INTERNAL_DUMP_HEX_STR_OVERRIDE(data, size)
713 : #else
714 : /**
715 : * This function dump raw data.
716 : *
717 : * @param data raw data
718 : * @param size raw data size
719 : **/
720 : void libspdm_internal_dump_hex_str(const uint8_t *data, size_t size);
721 : #define LIBSPDM_INTERNAL_DUMP_HEX_STR(data, size) libspdm_internal_dump_hex_str(data, size)
722 : #endif /* LIBSPDM_INTERNAL_DUMP_HEX_STR_OVERRIDE */
723 :
724 : #ifdef LIBSPDM_INTERNAL_DUMP_DATA_OVERRIDE
725 : extern void LIBSPDM_INTERNAL_DUMP_DATA_OVERRIDE(const uint8_t *data, size_t size);
726 : #define LIBSPDM_INTERNAL_DUMP_DATA(data, size) LIBSPDM_INTERNAL_DUMP_DATA_OVERRIDE(data, size)
727 : #else
728 : /**
729 : * This function dump raw data.
730 : *
731 : * @param data raw data
732 : * @param size raw data size
733 : **/
734 : void libspdm_internal_dump_data(const uint8_t *data, size_t size);
735 : #define LIBSPDM_INTERNAL_DUMP_DATA(data, size) libspdm_internal_dump_data(data, size)
736 : #endif /* LIBSPDM_INTERNAL_DUMP_DATA_OVERRIDE */
737 :
738 : #ifdef LIBSPDM_INTERNAL_DUMP_HEX_OVERRIDE
739 : extern void LIBSPDM_INTERNAL_DUMP_HEX_OVERRIDE(const uint8_t *data, size_t size);
740 : #define LIBSPDM_INTERNAL_DUMP_HEX(data, size) LIBSPDM_INTERNAL_DUMP_HEX_OVERRIDE(data, size)
741 : #else
742 : /**
743 : * This function dump raw data with column format.
744 : *
745 : * @param data raw data
746 : * @param size raw data size
747 : **/
748 : void libspdm_internal_dump_hex(const uint8_t *data, size_t size);
749 : #define LIBSPDM_INTERNAL_DUMP_HEX(data, size) libspdm_internal_dump_hex(data, size)
750 : #endif /* LIBSPDM_INTERNAL_DUMP_HEX_OVERRIDE */
751 :
752 : #else /* LIBSPDM_DEBUG_PRINT_ENABLE */
753 : #define LIBSPDM_INTERNAL_DUMP_HEX(data, size)
754 : #define LIBSPDM_INTERNAL_DUMP_HEX_STR(data, size)
755 : #define LIBSPDM_INTERNAL_DUMP_DATA(data, size)
756 : #endif /* LIBSPDM_DEBUG_PRINT_ENABLE */
757 :
758 : /* Required scratch buffer size for libspdm internal usage.
759 : * It may be used to hold the encrypted/decrypted message and/or last sent/received message.
760 : * It may be used to hold the large request/response and intermediate send/receive buffer
761 : * in case of chunking.
762 : *
763 : * If chunking is not supported, it should be at least below.
764 : * +--------------------------+-----------------+-----------------+
765 : * | SENDER_RECEIVER |MAX_SPDM_MSG_SIZE|MAX_SPDM_MSG_SIZE|
766 : * +--------------------------+-----------------+-----------------+
767 : * |<-Snd/Rcv buf for chunk ->|<-last request ->|<-cache request->|
768 : *
769 : *
770 : * If chunking is supported, it should be at least below.
771 : * +---------------+--------------+--------------------------+------------------------------+-----------------+-----------------+
772 : * |SECURE_MESSAGE |LARGE_MESSAGE | SENDER_RECEIVER | LARGE SENDER_RECEIVER |MAX_SPDM_MSG_SIZE|MAX_SPDM_MSG_SIZE|
773 : * +---------------+--------------+--------------------------+------------------------------+-----------------+-----------------+
774 : * |<-Secure msg ->|<-Large msg ->|<-Snd/Rcv buf for chunk ->|<-Snd/Rcv buf for large msg ->|<-last request ->|<-cache request->|
775 : *
776 : *
777 : * The value is configurable based on max_spdm_msg_size.
778 : * The value MAY be changed in different libspdm version.
779 : * It is exposed here, just in case the libspdm consumer wants to configure the setting at build time.
780 : */
781 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
782 : /* first section */
783 : uint32_t libspdm_get_scratch_buffer_secure_message_offset(libspdm_context_t *spdm_context);
784 : uint32_t libspdm_get_scratch_buffer_secure_message_capacity(libspdm_context_t *spdm_context);
785 :
786 : /* second section */
787 : uint32_t libspdm_get_scratch_buffer_large_message_offset(libspdm_context_t *spdm_context);
788 : uint32_t libspdm_get_scratch_buffer_large_message_capacity(libspdm_context_t *spdm_context);
789 : #endif
790 :
791 : /* third section */
792 : uint32_t libspdm_get_scratch_buffer_sender_receiver_offset(libspdm_context_t *spdm_context);
793 : uint32_t libspdm_get_scratch_buffer_sender_receiver_capacity(libspdm_context_t *spdm_context);
794 :
795 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
796 : /* fourth section */
797 : uint32_t libspdm_get_scratch_buffer_large_sender_receiver_offset(libspdm_context_t *spdm_context);
798 : uint32_t libspdm_get_scratch_buffer_large_sender_receiver_capacity(libspdm_context_t *spdm_context);
799 : #endif
800 :
801 : /* fifth section */
802 : uint32_t libspdm_get_scratch_buffer_last_spdm_request_offset(libspdm_context_t *spdm_context);
803 : uint32_t libspdm_get_scratch_buffer_last_spdm_request_capacity(libspdm_context_t *spdm_context);
804 :
805 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
806 : /* sixth section */
807 : uint32_t libspdm_get_scratch_buffer_cache_spdm_request_offset(libspdm_context_t *spdm_context);
808 : uint32_t libspdm_get_scratch_buffer_cache_spdm_request_capacity(libspdm_context_t *spdm_context);
809 : #endif
810 :
811 : /* combination */
812 : uint32_t libspdm_get_scratch_buffer_capacity(libspdm_context_t *spdm_context);
813 :
814 : /**
815 : * Append a new data buffer to the managed buffer.
816 : *
817 : * @param managed_buffer The managed buffer to be appended.
818 : * @param buffer The address of the data buffer to be appended to the managed buffer.
819 : * @param buffer_size The size in bytes of the data buffer to be appended to the managed buffer.
820 : *
821 : * @retval RETURN_SUCCESS The new data buffer is appended to the managed buffer.
822 : * @retval RETURN_BUFFER_TOO_SMALL The managed buffer is too small to be appended.
823 : **/
824 : libspdm_return_t libspdm_append_managed_buffer(void *managed_buffer,
825 : const void *buffer, size_t buffer_size);
826 :
827 : /**
828 : * Reset the managed buffer.
829 : * The buffer_size is reset to 0.
830 : * The max_buffer_size is unchanged.
831 : * The buffer is not freed.
832 : *
833 : * @param managed_buffer The managed buffer.
834 : **/
835 : void libspdm_reset_managed_buffer(void *managed_buffer);
836 :
837 : /**
838 : * Return the size of managed buffer.
839 : *
840 : * @param managed_buffer The managed buffer.
841 : *
842 : * @return the size of managed buffer.
843 : **/
844 : size_t libspdm_get_managed_buffer_size(void *managed_buffer);
845 :
846 : /**
847 : * Return the address of managed buffer.
848 : *
849 : * @param managed_buffer The managed buffer.
850 : *
851 : * @return the address of managed buffer.
852 : **/
853 : void *libspdm_get_managed_buffer(void *managed_buffer);
854 :
855 : /**
856 : * Init the managed buffer.
857 : *
858 : * @param managed_buffer The managed buffer.
859 : * @param max_buffer_size The maximum size in bytes of the managed buffer.
860 : **/
861 : void libspdm_init_managed_buffer(void *managed_buffer, size_t max_buffer_size);
862 :
863 : /**
864 : * Reset message buffer in SPDM context according to request code.
865 : *
866 : * @param spdm_context A pointer to the SPDM context.
867 : * @param spdm_session_info A pointer to the SPDM session context.
868 : * @param spdm_request The SPDM request code.
869 : */
870 : void libspdm_reset_message_buffer_via_request_code(void *context, void *session_info,
871 : uint8_t request_code);
872 :
873 : /**
874 : * This function initializes the session info.
875 : *
876 : * @param spdm_context A pointer to the SPDM context.
877 : * @param session_id The SPDM session ID.
878 : **/
879 : void libspdm_session_info_init(libspdm_context_t *spdm_context,
880 : libspdm_session_info_t *session_info,
881 : uint32_t session_id, spdm_version_number_t secured_message_version,
882 : bool use_psk);
883 :
884 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
885 : /**
886 : * Set the psk_hint to a session info.
887 : *
888 : * @param session_info A pointer to a session info.
889 : * @param psk_hint Indicate the PSK hint.
890 : * @param psk_hint_size The size in bytes of the PSK hint.
891 : */
892 : void libspdm_session_info_set_psk_hint(libspdm_session_info_t *session_info,
893 : const void *psk_hint,
894 : size_t psk_hint_size);
895 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */
896 :
897 : /**
898 : * This function returns if a given version is supported based upon the GET_VERSION/VERSION.
899 : *
900 : * @param spdm_context A pointer to the SPDM context.
901 : * @param version The SPDM version.
902 : *
903 : * @retval true the version is supported.
904 : * @retval false the version is not supported.
905 : **/
906 : bool libspdm_is_version_supported(const libspdm_context_t *spdm_context, uint8_t version);
907 :
908 : /**
909 : * This function returns connection version negotiated by GET_VERSION/VERSION.
910 : *
911 : * @param spdm_context A pointer to the SPDM context.
912 : *
913 : * @return the connection version.
914 : **/
915 : uint8_t libspdm_get_connection_version(const libspdm_context_t *spdm_context);
916 :
917 : /**
918 : * This function returns if a capabilities flag is supported in current SPDM connection.
919 : *
920 : * @param spdm_context A pointer to the SPDM context.
921 : * @param is_requester Is the function called from a requester.
922 : * @param requester_capabilities_flag The requester capabilities flag to be checked
923 : * @param responder_capabilities_flag The responder capabilities flag to be checked
924 : *
925 : * @retval true the capabilities flag is supported.
926 : * @retval false the capabilities flag is not supported.
927 : **/
928 : bool libspdm_is_capabilities_flag_supported(const libspdm_context_t *spdm_context,
929 : bool is_requester,
930 : uint32_t requester_capabilities_flag,
931 : uint32_t responder_capabilities_flag);
932 :
933 : /**
934 : * This function returns if a capabilities extended flag is supported in current SPDM connection.
935 : *
936 : * @param spdm_context A pointer to the SPDM context.
937 : * @param is_requester Is the function called from a requester.
938 : * @param requester_capabilities_ext_flag The requester capabilities extended flag to be checked
939 : * @param responder_capabilities_ext_flag The responder capabilities extended flag to be checked
940 : *
941 : * @retval true the capabilities extended flag is supported.
942 : * @retval false the capabilities extended flag is not supported.
943 : **/
944 : bool libspdm_is_capabilities_ext_flag_supported(const libspdm_context_t *spdm_context,
945 : bool is_requester,
946 : uint16_t requester_capabilities_ext_flag,
947 : uint16_t responder_capabilities_ext_flag);
948 :
949 : /**
950 : * Checks the negotiated SPDM version and endpoint capabilities to determine if encapsulated
951 : * messages are supported or not.
952 : *
953 : * @param spdm_context A pointer to the SPDM context.
954 : *
955 : * @retval true Both endpoints support encapsulated messages.
956 : * @retval false At least one endpoint does not support encapsulated messages.
957 : **/
958 : bool libspdm_is_encap_supported(const libspdm_context_t *spdm_context);
959 :
960 : /**
961 : * This function generates the certificate chain hash.
962 : *
963 : * @param spdm_context A pointer to the SPDM context.
964 : * @param slot_id The slot index of the certificate chain.
965 : * @param signature The buffer to store the certificate chain hash.
966 : *
967 : * @retval true certificate chain hash is generated.
968 : * @retval false certificate chain hash is not generated.
969 : **/
970 : bool libspdm_generate_cert_chain_hash(libspdm_context_t *spdm_context,
971 : size_t slot_id, uint8_t *hash);
972 :
973 : /**
974 : * This function generates the public key hash.
975 : *
976 : * @param spdm_context A pointer to the SPDM context.
977 : * @param hash The buffer to store the public key hash.
978 : *
979 : * @retval true public key hash is generated.
980 : * @retval false public key hash is not generated.
981 : **/
982 : bool libspdm_generate_public_key_hash(libspdm_context_t *spdm_context,
983 : uint8_t *hash);
984 :
985 : /**
986 : * This function verifies the integrity of peer certificate chain buffer including
987 : * spdm_cert_chain_t header.
988 : *
989 : * @param spdm_context A pointer to the SPDM context.
990 : * @param cert_chain_buffer Certificate chain buffer including spdm_cert_chain_t header.
991 : * @param cert_chain_buffer_size size in bytes of the certificate chain buffer.
992 : *
993 : * @retval true Peer certificate chain buffer integrity verification passed.
994 : * @retval false Peer certificate chain buffer integrity verification failed.
995 : **/
996 : bool libspdm_verify_peer_cert_chain_buffer_integrity(libspdm_context_t *spdm_context,
997 : const void *cert_chain_buffer,
998 : size_t cert_chain_buffer_size);
999 :
1000 : /**
1001 : * This function verifies peer certificate chain authority.
1002 : *
1003 : * @param spdm_context A pointer to the SPDM context.
1004 : * @param cert_chain_buffer Certificate chain buffer including spdm_cert_chain_t header.
1005 : * @param cert_chain_buffer_size size in bytes of the certificate chain buffer.
1006 : * @param trust_anchor A buffer to hold the trust_anchor which is used to validate the peer certificate, if not NULL.
1007 : * @param trust_anchor_size A buffer to hold the trust_anchor_size, if not NULL.
1008 : *
1009 : * @retval true Peer certificate chain buffer authority verification passed.
1010 : * Or there is no root_cert in local_context.
1011 : * @retval false Peer certificate chain buffer authority verification failed.
1012 : **/
1013 : bool libspdm_verify_peer_cert_chain_buffer_authority(libspdm_context_t *spdm_context,
1014 : const void *cert_chain_buffer,
1015 : size_t cert_chain_buffer_size,
1016 : const void **trust_anchor,
1017 : size_t *trust_anchor_size);
1018 : /**
1019 : * This function generates the challenge signature based upon m1m2 for authentication.
1020 : *
1021 : * @param spdm_context A pointer to the SPDM context.
1022 : * @param is_requester Indicate of the signature generation for a requester or a responder.
1023 : * @param signature The buffer to store the challenge signature.
1024 : *
1025 : * @retval true challenge signature is generated.
1026 : * @retval false challenge signature is not generated.
1027 : **/
1028 : bool libspdm_generate_challenge_auth_signature(libspdm_context_t *spdm_context,
1029 : bool is_requester,
1030 : uint8_t slot_id,
1031 : uint8_t *signature);
1032 :
1033 : /**
1034 : * This function verifies the certificate chain hash.
1035 : *
1036 : * @param spdm_context A pointer to the SPDM context.
1037 : * @param certificate_chain_hash The certificate chain hash data buffer.
1038 : * @param certificate_chain_hash_size size in bytes of the certificate chain hash data buffer.
1039 : *
1040 : * @retval true hash verification pass.
1041 : * @retval false hash verification fail.
1042 : **/
1043 : bool libspdm_verify_certificate_chain_hash(libspdm_context_t *spdm_context,
1044 : const void *certificate_chain_hash,
1045 : size_t certificate_chain_hash_size);
1046 :
1047 : /**
1048 : * This function verifies the public key hash.
1049 : *
1050 : * @param spdm_context A pointer to the SPDM context.
1051 : * @param public_key_hash The public key hash data buffer.
1052 : * @param public_key_hash_size size in bytes of the public key hash data buffer.
1053 : *
1054 : * @retval true hash verification pass.
1055 : * @retval false hash verification fail.
1056 : **/
1057 : bool libspdm_verify_public_key_hash(libspdm_context_t *spdm_context,
1058 : const void *public_key_hash,
1059 : size_t public_key_hash_size);
1060 :
1061 : /**
1062 : * This function verifies the challenge signature based upon m1m2.
1063 : *
1064 : * @param spdm_context A pointer to the SPDM context.
1065 : * @param is_requester Indicate of the signature verification for a requester or a responder.
1066 : * @param sign_data The signature data buffer.
1067 : * @param sign_data_size size in bytes of the signature data buffer.
1068 : *
1069 : * @retval true signature verification pass.
1070 : * @retval false signature verification fail.
1071 : **/
1072 : bool libspdm_verify_challenge_auth_signature(libspdm_context_t *spdm_context,
1073 : bool is_requester,
1074 : const void *sign_data,
1075 : size_t sign_data_size);
1076 :
1077 : /**
1078 : * This function calculate the measurement summary hash size.
1079 : *
1080 : * @param spdm_context A pointer to the SPDM context.
1081 : * @param is_requester Is the function called from a requester.
1082 : * @param measurement_summary_hash_type The type of the measurement summary hash.
1083 : *
1084 : * @return 0 measurement summary hash type is invalid, NO_MEAS hash type or no MEAS capabilities.
1085 : * @return measurement summary hash size according to type.
1086 : **/
1087 : uint32_t libspdm_get_measurement_summary_hash_size(libspdm_context_t *spdm_context,
1088 : bool is_requester,
1089 : uint8_t measurement_summary_hash_type);
1090 :
1091 : /**
1092 : * This function generates the endpoint info signature based upon il1il2 for authentication.
1093 : *
1094 : * @param spdm_context A pointer to the SPDM context.
1095 : * @param session_info A pointer to the SPDM session context.
1096 : * @param is_requester Indicate of the signature generation for a requester or a responder.
1097 : * @param signature The buffer to store the endpoint info signature.
1098 : *
1099 : * @retval true challenge signature is generated.
1100 : * @retval false challenge signature is not generated.
1101 : **/
1102 : bool libspdm_generate_endpoint_info_signature(libspdm_context_t *spdm_context,
1103 : libspdm_session_info_t *session_info,
1104 : bool is_requester,
1105 : uint8_t slot_id,
1106 : uint8_t *signature);
1107 :
1108 : /**
1109 : * This function verifies the challenge signature based upon m1m2.
1110 : *
1111 : * @param spdm_context A pointer to the SPDM context.
1112 : * @param session_info A pointer to the SPDM session context.
1113 : * @param is_requester Indicate of the signature verification for a requester or a responder.
1114 : * @param sign_data The signature data buffer.
1115 : * @param sign_data_size size in bytes of the signature data buffer.
1116 : *
1117 : * @retval true signature verification pass.
1118 : * @retval false signature verification fail.
1119 : **/
1120 : bool libspdm_verify_endpoint_info_signature(libspdm_context_t *spdm_context,
1121 : libspdm_session_info_t *session_info,
1122 : bool is_requester,
1123 : const void *sign_data,
1124 : size_t sign_data_size);
1125 :
1126 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1127 : /*
1128 : * This function calculates l1l2.
1129 : * If session_info is NULL, this function will use M cache of SPDM context,
1130 : * else will use M cache of SPDM session context.
1131 : *
1132 : * @param spdm_context A pointer to the SPDM context.
1133 : * @param session_info A pointer to the SPDM session context.
1134 : * @param l1l2 The buffer to store the l1l2.
1135 : *
1136 : * @retval RETURN_SUCCESS l1l2 is calculated.
1137 : */
1138 : bool libspdm_calculate_l1l2(libspdm_context_t *spdm_context,
1139 : void *session_info,
1140 : libspdm_l1l2_managed_buffer_t *l1l2);
1141 : #else
1142 : /*
1143 : * This function calculates l1l2 hash.
1144 : * If session_info is NULL, this function will use M cache of SPDM context,
1145 : * else will use M cache of SPDM session context.
1146 : *
1147 : * @param spdm_context A pointer to the SPDM context.
1148 : * @param session_info A pointer to the SPDM session context.
1149 : * @param l1l2_hash_size size in bytes of the l1l2 hash
1150 : * @param l1l2_hash The buffer to store the l1l2 hash
1151 : *
1152 : * @retval RETURN_SUCCESS l1l2 is calculated.
1153 : */
1154 : bool libspdm_calculate_l1l2_hash(libspdm_context_t *spdm_context,
1155 : void *session_info,
1156 : size_t *l1l2_hash_size, void *l1l2_hash);
1157 : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
1158 :
1159 : /**
1160 : * Get element from multi element opaque data by element id.
1161 : *
1162 : * This function should be called in
1163 : * libspdm_process_opaque_data_supported_version_data/libspdm_process_opaque_data_version_selection_data.
1164 : *
1165 : * @param[in] data_in_size Size of multi element opaque data.
1166 : * @param[in] data_in A pointer to the multi element opaque data.
1167 : * @param[in] element_id Element id.
1168 : * @param[in] sm_data_id ID for the Secured Message data type.
1169 : * @param[out] get_element_ptr Pointer to store found element.
1170 : *
1171 : * @retval true Get element successfully
1172 : * @retval false Get element failed
1173 : **/
1174 : bool libspdm_get_element_from_opaque_data(libspdm_context_t *spdm_context,
1175 : size_t data_in_size, const void *data_in,
1176 : uint8_t element_id, uint8_t sm_data_id,
1177 : const void **get_element_ptr, size_t *get_element_len);
1178 :
1179 : /**
1180 : * Process general opaque data check
1181 : *
1182 : * @param data_in_size size in bytes of the data_in.
1183 : * @param data_in A pointer to the buffer to store the opaque data version selection.
1184 : *
1185 : * @retval true check opaque data successfully
1186 : * @retval false check opaque data failed
1187 : **/
1188 : bool libspdm_process_general_opaque_data_check(libspdm_context_t *spdm_context,
1189 : size_t data_in_size,
1190 : const void *data_in);
1191 :
1192 : /**
1193 : * Return the size in bytes of opaque data supported version.
1194 : *
1195 : * This function should be called in libspdm_process_opaque_data_supported_version_data.
1196 : *
1197 : * @param version_count Secure version count.
1198 : *
1199 : * @return The size in bytes of opaque data supported version.
1200 : **/
1201 : size_t libspdm_get_untrusted_opaque_data_supported_version_data_size(
1202 : libspdm_context_t *spdm_context, uint8_t version_count);
1203 :
1204 : /**
1205 : * Return the size in bytes of opaque data supported version.
1206 : *
1207 : * This function should be called in KEY_EXCHANGE/PSK_EXCHANGE request generation.
1208 : *
1209 : * @return the size in bytes of opaque data supported version.
1210 : **/
1211 : size_t libspdm_get_opaque_data_supported_version_data_size(libspdm_context_t *spdm_context);
1212 :
1213 : /**
1214 : * Return the size in bytes of opaque data version selection.
1215 : *
1216 : * This function should be called in KEY_EXCHANGE/PSK_EXCHANGE response generation.
1217 : *
1218 : * @return the size in bytes of opaque data version selection.
1219 : **/
1220 : size_t libspdm_get_opaque_data_version_selection_data_size(const libspdm_context_t *spdm_context);
1221 :
1222 : /**
1223 : * Return the SPDMversion field of the version number struct.
1224 : *
1225 : * @param ver Spdm version number struct.
1226 : *
1227 : * @return the SPDMversion of the version number struct.
1228 : **/
1229 : uint8_t libspdm_get_version_from_version_number(const spdm_version_number_t ver);
1230 :
1231 : /**
1232 : * Sort SPDMversion in descending order.
1233 : *
1234 : * @param spdm_context A pointer to the SPDM context.
1235 : * @param ver_set A pointer to the version set.
1236 : * @param ver_num Version number.
1237 : */
1238 : void libspdm_version_number_sort(spdm_version_number_t *ver_set, size_t ver_num);
1239 :
1240 : /**
1241 : * Negotiate SPDMversion for connection.
1242 : * ver_set is the local version set of requester, res_ver_set is the version set of responder.
1243 : *
1244 : * @param common_version A pointer to store the common version.
1245 : * @param req_ver_set A pointer to the requester version set.
1246 : * @param req_ver_num Version number of requester.
1247 : * @param res_ver_set A pointer to the responder version set.
1248 : * @param res_ver_num Version number of responder.
1249 : *
1250 : * @retval true Negotiation successfully, connect version be saved to common_version.
1251 : * @retval false Negotiation failed.
1252 : */
1253 : bool libspdm_negotiate_connection_version(spdm_version_number_t *common_version,
1254 : spdm_version_number_t *req_ver_set,
1255 : size_t req_ver_num,
1256 : const spdm_version_number_t *res_ver_set,
1257 : size_t res_ver_num);
1258 :
1259 : /**
1260 : * Acquire a device sender buffer for transport layer message.
1261 : *
1262 : * @param context A pointer to the SPDM context.
1263 : * @param max_msg_size size in bytes of the maximum size of sender buffer.
1264 : * @param msg_buf_ptr A pointer to a sender buffer.
1265 : *
1266 : * @retval RETURN_SUCCESS The sender buffer is acquired.
1267 : **/
1268 : libspdm_return_t libspdm_acquire_sender_buffer (
1269 : libspdm_context_t *spdm_context, size_t *max_msg_size, void **msg_buf_ptr);
1270 :
1271 : /**
1272 : * Release a device sender buffer for transport layer message.
1273 : *
1274 : * @param context A pointer to the SPDM context.
1275 : *
1276 : * @retval RETURN_SUCCESS The sender buffer is Released.
1277 : **/
1278 : void libspdm_release_sender_buffer (libspdm_context_t *spdm_context);
1279 :
1280 : /**
1281 : * Get the sender buffer.
1282 : *
1283 : * @param context A pointer to the SPDM context.
1284 : * @param sender_buffer Buffer address of the sender buffer.
1285 : * @param sender_buffer_size Size of the sender buffer.
1286 : *
1287 : **/
1288 : void libspdm_get_sender_buffer (
1289 : libspdm_context_t *spdm_context,
1290 : void **sender_buffer,
1291 : size_t *sender_buffer_size);
1292 :
1293 : /**
1294 : * Acquire a device receiver buffer for transport layer message.
1295 : *
1296 : * @param context A pointer to the SPDM context.
1297 : * @param max_msg_size size in bytes of the maximum size of receiver buffer.
1298 : * @param msg_buf_pt A pointer to a receiver buffer.
1299 : *
1300 : * @retval RETURN_SUCCESS The receiver buffer is acquired.
1301 : **/
1302 : libspdm_return_t libspdm_acquire_receiver_buffer (
1303 : libspdm_context_t *spdm_context, size_t *max_msg_size, void **msg_buf_ptr);
1304 :
1305 : /**
1306 : * Release a device receiver buffer for transport layer message.
1307 : *
1308 : * @param context A pointer to the SPDM context.
1309 : *
1310 : * @retval RETURN_SUCCESS The receiver buffer is Released.
1311 : **/
1312 : void libspdm_release_receiver_buffer (libspdm_context_t *spdm_context);
1313 :
1314 : /**
1315 : * Get the receiver buffer.
1316 : *
1317 : * @param context A pointer to the SPDM context.
1318 : * @param receiver_buffer Buffer address of the receiver buffer.
1319 : * @param receiver_buffer_size Size of the receiver buffer.
1320 : *
1321 : **/
1322 : void libspdm_get_receiver_buffer (
1323 : libspdm_context_t *spdm_context,
1324 : void **receiver_buffer,
1325 : size_t *receiver_buffer_size);
1326 :
1327 : /**
1328 : * Get the certificate slot mask
1329 : *
1330 : * @param[in] context A pointer to the SPDM context.
1331 : *
1332 : * @retval slot_mask get slot mask
1333 : **/
1334 : uint8_t libspdm_get_cert_slot_mask (libspdm_context_t *spdm_context);
1335 :
1336 : /**
1337 : * Get the certificate slot count
1338 : *
1339 : * @param[in] context A pointer to the SPDM context.
1340 : *
1341 : * @retval slot_count get slot count
1342 : **/
1343 : uint8_t libspdm_get_cert_slot_count(libspdm_context_t *spdm_context);
1344 :
1345 : #if LIBSPDM_ENABLE_MSG_LOG
1346 : void libspdm_append_msg_log(libspdm_context_t *spdm_context, void *message, size_t message_size);
1347 : #endif
1348 :
1349 : /**
1350 : * Reset message A cache in SPDM context.
1351 : *
1352 : * @param spdm_context A pointer to the SPDM context.
1353 : **/
1354 : void libspdm_reset_message_a(libspdm_context_t *spdm_context);
1355 :
1356 : /**
1357 : * Reset message D cache in SPDM context.
1358 : *
1359 : * @param spdm_context A pointer to the SPDM context.
1360 : * @param spdm_session_info A pointer to the SPDM session context.
1361 : **/
1362 : void libspdm_reset_message_d(libspdm_context_t *spdm_context);
1363 :
1364 : /**
1365 : * Reset message B cache in SPDM context.
1366 : *
1367 : * @param spdm_context A pointer to the SPDM context.
1368 : **/
1369 : void libspdm_reset_message_b(libspdm_context_t *spdm_context);
1370 :
1371 : /**
1372 : * Reset message C cache in SPDM context.
1373 : *
1374 : * @param spdm_context A pointer to the SPDM context.
1375 : **/
1376 : void libspdm_reset_message_c(libspdm_context_t *spdm_context);
1377 :
1378 : /**
1379 : * Reset message MutB cache in SPDM context.
1380 : *
1381 : * @param spdm_context A pointer to the SPDM context.
1382 : **/
1383 : void libspdm_reset_message_mut_b(libspdm_context_t *spdm_context);
1384 :
1385 : /**
1386 : * Reset message MutC cache in SPDM context.
1387 : *
1388 : * @param spdm_context A pointer to the SPDM context.
1389 : **/
1390 : void libspdm_reset_message_mut_c(libspdm_context_t *spdm_context);
1391 :
1392 : /**
1393 : * Reset message M cache in SPDM context.
1394 : * If session_info is NULL, this function will use M cache of SPDM context,
1395 : * else will use M cache of SPDM session context.
1396 : *
1397 : * @param spdm_context A pointer to the SPDM context.
1398 : * @param session_info A pointer to the SPDM session context.
1399 : **/
1400 : void libspdm_reset_message_m(libspdm_context_t *spdm_context, void *session_info);
1401 :
1402 : /**
1403 : * Reset message K cache in SPDM context.
1404 : *
1405 : * @param spdm_context A pointer to the SPDM context.
1406 : * @param spdm_session_info A pointer to the SPDM session context.
1407 : **/
1408 : void libspdm_reset_message_k(libspdm_context_t *spdm_context, void *spdm_session_info);
1409 :
1410 : /**
1411 : * Reset message EncapD cache in SPDM context.
1412 : *
1413 : * @param spdm_context A pointer to the SPDM context.
1414 : * @param spdm_session_info A pointer to the SPDM session context.
1415 : **/
1416 : void libspdm_reset_message_encap_d(libspdm_context_t *spdm_context, void *spdm_session_info);
1417 :
1418 : /**
1419 : * Reset message F cache in SPDM context.
1420 : *
1421 : * @param spdm_context A pointer to the SPDM context.
1422 : * @param spdm_session_info A pointer to the SPDM session context.
1423 : **/
1424 : void libspdm_reset_message_f(libspdm_context_t *spdm_context, void *spdm_session_info);
1425 :
1426 : /**
1427 : * Reset message E cache in SPDM context.
1428 : * If session_info is NULL, this function will use E cache of SPDM context,
1429 : * else will use E cache of SPDM session context.
1430 : *
1431 : * @param spdm_context A pointer to the SPDM context.
1432 : * @param spdm_session_info A pointer to the SPDM session context.
1433 : **/
1434 : void libspdm_reset_message_e(libspdm_context_t *spdm_context, void *session_info);
1435 :
1436 : /**
1437 : * Reset message encap E cache in SPDM context.
1438 : * If session_info is NULL, this function will use encap E cache of SPDM context,
1439 : * else will use encap E cache of SPDM session context.
1440 : *
1441 : * @param spdm_context A pointer to the SPDM context.
1442 : * @param spdm_session_info A pointer to the SPDM session context.
1443 : **/
1444 : void libspdm_reset_message_encap_e(libspdm_context_t *spdm_context, void *session_info);
1445 :
1446 : /**
1447 : * Append message A cache in SPDM context.
1448 : *
1449 : * @param spdm_context A pointer to the SPDM context.
1450 : * @param message Message buffer.
1451 : * @param message_size Size in bytes of message buffer.
1452 : *
1453 : * @return RETURN_SUCCESS message is appended.
1454 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1455 : **/
1456 : libspdm_return_t libspdm_append_message_a(libspdm_context_t *spdm_context, const void *message,
1457 : size_t message_size);
1458 :
1459 : /**
1460 : * Append message D cache in SPDM context.
1461 : *
1462 : * @param spdm_context A pointer to the SPDM context.
1463 : * @param message Message buffer.
1464 : * @param message_size Size in bytes of message buffer.
1465 : *
1466 : * @return RETURN_SUCCESS message is appended.
1467 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1468 : **/
1469 : libspdm_return_t libspdm_append_message_d(libspdm_context_t *spdm_context, const void *message,
1470 : size_t message_size);
1471 :
1472 : /**
1473 : * Append message B cache in SPDM context.
1474 : *
1475 : * @param spdm_context A pointer to the SPDM context.
1476 : * @param message Message buffer.
1477 : * @param message_size Size in bytes of message buffer.
1478 : *
1479 : * @return RETURN_SUCCESS message is appended.
1480 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1481 : **/
1482 : libspdm_return_t libspdm_append_message_b(libspdm_context_t *spdm_context, const void *message,
1483 : size_t message_size);
1484 :
1485 : /**
1486 : * Append message C cache in SPDM context.
1487 : *
1488 : * @param spdm_context A pointer to the SPDM context.
1489 : * @param message Message buffer.
1490 : * @param message_size Size in bytes of message buffer.
1491 : *
1492 : * @return RETURN_SUCCESS message is appended.
1493 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1494 : **/
1495 : libspdm_return_t libspdm_append_message_c(libspdm_context_t *spdm_context, const void *message,
1496 : size_t message_size);
1497 :
1498 : /**
1499 : * Append message MutB cache in SPDM context.
1500 : *
1501 : * @param spdm_context A pointer to the SPDM context.
1502 : * @param message Message buffer.
1503 : * @param message_size Size in bytes of message buffer.
1504 : *
1505 : * @return RETURN_SUCCESS message is appended.
1506 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1507 : **/
1508 : libspdm_return_t libspdm_append_message_mut_b(libspdm_context_t *spdm_context, const void *message,
1509 : size_t message_size);
1510 :
1511 : /**
1512 : * Append message MutC cache in SPDM context.
1513 : *
1514 : * @param spdm_context A pointer to the SPDM context.
1515 : * @param message Message buffer.
1516 : * @param message_size Size in bytes of message buffer.
1517 : *
1518 : * @return RETURN_SUCCESS message is appended.
1519 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1520 : **/
1521 : libspdm_return_t libspdm_append_message_mut_c(libspdm_context_t *spdm_context, const void *message,
1522 : size_t message_size);
1523 :
1524 : /**
1525 : * Append message M cache in SPDM context.
1526 : * If session_info is NULL, this function will use M cache of SPDM context,
1527 : * else will use M cache of SPDM session context.
1528 : *
1529 : * @param spdm_context A pointer to the SPDM context.
1530 : * @param session_info A pointer to the SPDM session context.
1531 : * @param message Message buffer.
1532 : * @param message_size Size in bytes of message buffer.
1533 : *
1534 : * @return RETURN_SUCCESS message is appended.
1535 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1536 : **/
1537 : libspdm_return_t libspdm_append_message_m(libspdm_context_t *spdm_context,
1538 : void *session_info,
1539 : const void *message, size_t message_size);
1540 :
1541 : /**
1542 : * Append message K cache in SPDM context.
1543 : *
1544 : * @param spdm_context A pointer to the SPDM context.
1545 : * @param spdm_session_info A pointer to the SPDM session context.
1546 : * @param is_requester Indicate of the key generation for a requester or a responder.
1547 : * @param message Message buffer.
1548 : * @param message_size Size in bytes of message buffer.
1549 : *
1550 : * @return RETURN_SUCCESS message is appended.
1551 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1552 : **/
1553 : libspdm_return_t libspdm_append_message_k(libspdm_context_t *spdm_context,
1554 : void *spdm_session_info,
1555 : bool is_requester, const void *message,
1556 : size_t message_size);
1557 :
1558 : /**
1559 : * Append message EncapD cache in SPDM context.
1560 : *
1561 : * @param spdm_context A pointer to the SPDM context.
1562 : * @param spdm_session_info A pointer to the SPDM session context.
1563 : * @param is_requester Indicate of the key generation for a requester or a responder.
1564 : * @param message Message buffer.
1565 : * @param message_size Size in bytes of message buffer.
1566 : *
1567 : * @return RETURN_SUCCESS message is appended.
1568 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1569 : **/
1570 : libspdm_return_t libspdm_append_message_encap_d(libspdm_context_t *spdm_context,
1571 : void *spdm_session_info,
1572 : bool is_requester, const void *message,
1573 : size_t message_size);
1574 :
1575 : /**
1576 : * Append message F cache in SPDM context.
1577 : *
1578 : * @param spdm_context A pointer to the SPDM context.
1579 : * @param spdm_session_info A pointer to the SPDM session context.
1580 : * @param is_requester Indicate of the key generation for a requester or a responder.
1581 : * @param message Message buffer.
1582 : * @param message_size Size in bytes of message buffer.
1583 : *
1584 : * @return RETURN_SUCCESS message is appended.
1585 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1586 : **/
1587 : libspdm_return_t libspdm_append_message_f(libspdm_context_t *spdm_context,
1588 : void *spdm_session_info,
1589 : bool is_requester, const void *message,
1590 : size_t message_size);
1591 :
1592 : /**
1593 : * Append message E cache in SPDM context.
1594 : * If session_info is NULL, this function will use E cache of SPDM context,
1595 : * else will use E cache of SPDM session context.
1596 : *
1597 : * @param spdm_context A pointer to the SPDM context.
1598 : * @param session_info A pointer to the SPDM session context.
1599 : * @param message message buffer.
1600 : * @param message_size size in bytes of message buffer.
1601 : *
1602 : * @return RETURN_SUCCESS message is appended.
1603 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1604 : **/
1605 : libspdm_return_t libspdm_append_message_e(libspdm_context_t *spdm_context, void *session_info,
1606 : const void *message, size_t message_size);
1607 :
1608 : /**
1609 : * Append message encap E cache in SPDM context.
1610 : * If session_info is NULL, this function will use encap E cache of SPDM context,
1611 : * else will use encap E cache of SPDM session context.
1612 : *
1613 : * @param spdm_context A pointer to the SPDM context.
1614 : * @param session_info A pointer to the SPDM session context.
1615 : * @param message message buffer.
1616 : * @param message_size size in bytes of message buffer.
1617 : *
1618 : * @return RETURN_SUCCESS message is appended.
1619 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1620 : **/
1621 : libspdm_return_t libspdm_append_message_encap_e(libspdm_context_t *spdm_context, void *session_info,
1622 : const void *message, size_t message_size);
1623 :
1624 : /**
1625 : * This function generates a session ID by concatenating req_session_id and rsp_session_id.
1626 : *
1627 : * @param[in] req_session_id
1628 : * @param[in] rsp_session_id
1629 : *
1630 : * @return Session ID.
1631 : **/
1632 : uint32_t libspdm_generate_session_id(uint16_t req_session_id, uint16_t rsp_session_id);
1633 :
1634 : /**
1635 : * This function assigns a new session ID.
1636 : *
1637 : * @param spdm_context A pointer to the SPDM context.
1638 : * @param session_id The SPDM session ID.
1639 : *
1640 : * @return session info associated with this new session ID.
1641 : **/
1642 : libspdm_session_info_t *libspdm_assign_session_id(libspdm_context_t *spdm_context,
1643 : uint32_t session_id,
1644 : spdm_version_number_t secured_message_version,
1645 : bool use_psk);
1646 :
1647 : /**
1648 : * This function frees a session ID.
1649 : *
1650 : * @param spdm_context A pointer to the SPDM context.
1651 : * @param session_id The SPDM session ID.
1652 : **/
1653 : void libspdm_free_session_id(libspdm_context_t *spdm_context, uint32_t session_id);
1654 :
1655 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1656 : /*
1657 : * This function calculates current TH data with message A and message K.
1658 : *
1659 : * @param spdm_context A pointer to the SPDM context.
1660 : * @param session_info The SPDM session ID.
1661 : * @param cert_chain_buffer Certificate chain buffer with spdm_cert_chain_t header.
1662 : * @param cert_chain_buffer_size Size in bytes of the certificate chain buffer.
1663 : * @param th_data_buffer_size Size in bytes of the th_data_buffer
1664 : * @param th_data_buffer The buffer to store the th_data_buffer
1665 : *
1666 : * @retval RETURN_SUCCESS current TH data is calculated.
1667 : */
1668 : bool libspdm_calculate_th_for_exchange(
1669 : libspdm_context_t *spdm_context, void *spdm_session_info,
1670 : const uint8_t *cert_chain_buffer, size_t cert_chain_buffer_size,
1671 : libspdm_th_managed_buffer_t *th_curr);
1672 : #else
1673 : /*
1674 : * This function calculates current TH hash with message A and message K.
1675 : *
1676 : * @param spdm_context A pointer to the SPDM context.
1677 : * @param session_info The SPDM session ID.
1678 : * @param th_hash_buffer_size Size in bytes of the th_hash_buffer
1679 : * @param th_hash_buffer The buffer to store the th_hash_buffer
1680 : *
1681 : * @retval RETURN_SUCCESS current TH hash is calculated.
1682 : */
1683 : bool libspdm_calculate_th_hash_for_exchange(
1684 : libspdm_context_t *spdm_context, void *spdm_session_info,
1685 : size_t *th_hash_buffer_size, void *th_hash_buffer);
1686 :
1687 : /*
1688 : * This function calculates current TH hmac with message A and message K, with response finished_key.
1689 : *
1690 : * @param spdm_context A pointer to the SPDM context.
1691 : * @param session_info The SPDM session ID.
1692 : * @param th_hmac_buffer_size Size in bytes of the th_hmac_buffer
1693 : * @param th_hmac_buffer The buffer to store the th_hmac_buffer
1694 : *
1695 : * @retval RETURN_SUCCESS current TH hmac is calculated.
1696 : */
1697 : bool libspdm_calculate_th_hmac_for_exchange_rsp(
1698 : libspdm_context_t *spdm_context, void *spdm_session_info,
1699 : size_t *th_hmac_buffer_size, void *th_hmac_buffer);
1700 : #endif
1701 :
1702 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1703 : /*
1704 : * This function calculates current TH data with message A, message K and message F.
1705 : *
1706 : * @param spdm_context A pointer to the SPDM context.
1707 : * @param session_info The SPDM session ID.
1708 : * @param cert_chain_buffer Certificate chain buffer with spdm_cert_chain_t header.
1709 : * @param cert_chain_buffer_size Size in bytes of the certificate chain buffer.
1710 : * @param mut_cert_chain_buffer Certificate chain buffer with spdm_cert_chain_t header in mutual authentication.
1711 : * @param mut_cert_chain_buffer_size Size in bytes of the certificate chain buffer in mutual authentication.
1712 : * @param th_data_buffer_size Size in bytes of the th_data_buffer.
1713 : * @param th_data_buffer The buffer to store the th_data_buffer
1714 : *
1715 : * @retval RETURN_SUCCESS current TH data is calculated.
1716 : */
1717 : bool libspdm_calculate_th_for_finish(libspdm_context_t *spdm_context,
1718 : void *spdm_session_info,
1719 : const uint8_t *cert_chain_buffer,
1720 : size_t cert_chain_buffer_size,
1721 : const uint8_t *mut_cert_chain_buffer,
1722 : size_t mut_cert_chain_buffer_size,
1723 : libspdm_th_managed_buffer_t *th_curr);
1724 : #else
1725 : /*
1726 : * This function calculates current TH hash with message A, message K and message F.
1727 : *
1728 : * @param spdm_context A pointer to the SPDM context.
1729 : * @param session_info The SPDM session ID.
1730 : * @param th_hash_buffer_size Size in bytes of the th_hash_buffer
1731 : * @param th_hash_buffer The buffer to store the th_hash_buffer
1732 : *
1733 : * @retval RETURN_SUCCESS current TH hash is calculated.
1734 : */
1735 : bool libspdm_calculate_th_hash_for_finish(libspdm_context_t *spdm_context,
1736 : void *spdm_session_info,
1737 : size_t *th_hash_buffer_size,
1738 : void *th_hash_buffer);
1739 :
1740 : /*
1741 : * This function calculates current TH hmac with message A, message K and message F, with response finished_key.
1742 : *
1743 : * @param spdm_context A pointer to the SPDM context.
1744 : * @param session_info The SPDM session ID.
1745 : * @param th_hmac_buffer_size Size in bytes of the th_hmac_buffer
1746 : * @param th_hmac_buffer The buffer to store the th_hmac_buffer
1747 : *
1748 : * @retval RETURN_SUCCESS current TH hmac is calculated.
1749 : */
1750 : bool libspdm_calculate_th_hmac_for_finish_rsp(libspdm_context_t *spdm_context,
1751 : void *spdm_session_info,
1752 : size_t *th_hmac_buffer_size,
1753 : void *th_hmac_buffer);
1754 :
1755 : /*
1756 : * This function calculates current TH hmac with message A, message K and message F, with request finished_key.
1757 : *
1758 : * @param spdm_context A pointer to the SPDM context.
1759 : * @param session_info The SPDM session ID.
1760 : * @param th_hmac_buffer_size Size in bytes of the th_hmac_buffer
1761 : * @param th_hmac_buffer The buffer to store the th_hmac_buffer
1762 : *
1763 : * @retval RETURN_SUCCESS current TH hmac is calculated.
1764 : */
1765 : bool libspdm_calculate_th_hmac_for_finish_req(libspdm_context_t *spdm_context,
1766 : void *spdm_session_info,
1767 : size_t *th_hmac_buffer_size,
1768 : void *th_hmac_buffer);
1769 : #endif
1770 :
1771 : /*
1772 : * This function calculates th1 hash.
1773 : *
1774 : * @param spdm_context A pointer to the SPDM context.
1775 : * @param session_info The SPDM session ID.
1776 : * @param is_requester Indicate of the key generation for a requester or a responder.
1777 : * @param th1_hash_data Th1 hash.
1778 : *
1779 : * @retval RETURN_SUCCESS th1 hash is calculated.
1780 : */
1781 : bool libspdm_calculate_th1_hash(libspdm_context_t *spdm_context,
1782 : void *spdm_session_info,
1783 : bool is_requester,
1784 : uint8_t *th1_hash_data);
1785 :
1786 : /*
1787 : * This function calculates th2 hash.
1788 : *
1789 : * @param spdm_context A pointer to the SPDM context.
1790 : * @param session_info The SPDM session ID.
1791 : * @param is_requester Indicate of the key generation for a requester or a responder.
1792 : * @param th1_hash_data Th2 hash
1793 : *
1794 : * @retval RETURN_SUCCESS th2 hash is calculated.
1795 : */
1796 : bool libspdm_calculate_th2_hash(libspdm_context_t *spdm_context,
1797 : void *spdm_session_info,
1798 : bool is_requester,
1799 : uint8_t *th2_hash_data);
1800 :
1801 : /**
1802 : * Reads a 24-bit value from memory that may be unaligned.
1803 : *
1804 : * @param buffer The pointer to a 24-bit value that may be unaligned.
1805 : *
1806 : * @return The 24-bit value read from buffer.
1807 : **/
1808 : uint32_t libspdm_read_uint24(const uint8_t *buffer);
1809 :
1810 : /**
1811 : * Writes a 24-bit value to memory that may be unaligned.
1812 : *
1813 : * @param buffer The pointer to a 24-bit value that may be unaligned.
1814 : * @param value 24-bit value to write to buffer.
1815 : **/
1816 : void libspdm_write_uint24(uint8_t *buffer, uint32_t value);
1817 :
1818 : /**
1819 : * Reads a 16-bit value from memory that may be unaligned.
1820 : *
1821 : * @param buffer The pointer to a 16-bit value that may be unaligned.
1822 : *
1823 : * @return The 16-bit value read from buffer.
1824 : **/
1825 : uint16_t libspdm_read_uint16(const uint8_t *buffer);
1826 :
1827 : /**
1828 : * Writes a 16-bit value to memory that may be unaligned.
1829 : *
1830 : * @param buffer The pointer to a 16-bit value that may be unaligned.
1831 : * @param value 16-bit value to write to buffer.
1832 : **/
1833 : void libspdm_write_uint16(uint8_t *buffer, uint16_t value);
1834 :
1835 : /**
1836 : * Reads a 32-bit value from memory that may be unaligned.
1837 : *
1838 : * @param buffer The pointer to a 32-bit value that may be unaligned.
1839 : *
1840 : * @return The 32-bit value read from buffer.
1841 : **/
1842 : uint32_t libspdm_read_uint32(const uint8_t *buffer);
1843 :
1844 : /**
1845 : * Writes a 32-bit value to memory that may be unaligned.
1846 : *
1847 : * @param buffer The pointer to a 32-bit value that may be unaligned.
1848 : * @param value 32-bit value to write to buffer.
1849 : **/
1850 : void libspdm_write_uint32(uint8_t *buffer, uint32_t value);
1851 :
1852 : /**
1853 : * Reads a 64-bit value from memory that may be unaligned.
1854 : *
1855 : * @param buffer The pointer to a 64-bit value that may be unaligned.
1856 : *
1857 : * @return The 64-bit value read from buffer.
1858 : **/
1859 : uint64_t libspdm_read_uint64(const uint8_t *buffer);
1860 :
1861 : /**
1862 : * Writes a 64-bit value to memory that may be unaligned.
1863 : *
1864 : * @param buffer The pointer to a 64-bit value that may be unaligned.
1865 : * @param value 64-bit value to write to buffer.
1866 : **/
1867 : void libspdm_write_uint64(uint8_t *buffer, uint64_t value);
1868 :
1869 : /**
1870 : * Determine if bitmask has at most one bit set.
1871 : *
1872 : * @param mask The bitmask to be tested.
1873 : *
1874 : * @return true At most one bit is set.
1875 : * @return false More than one bit is set.
1876 : */
1877 402 : static inline bool libspdm_onehot0(uint32_t mask)
1878 : {
1879 402 : return !mask || !(mask & (mask - 1));
1880 : }
1881 :
1882 1 : static inline uint64_t libspdm_byte_swap_64(uint64_t value)
1883 : {
1884 1 : return (((value & 0x00000000000000ff) << 56) |
1885 1 : ((value & 0x000000000000ff00) << 40) |
1886 1 : ((value & 0x0000000000ff0000) << 24) |
1887 1 : ((value & 0x00000000ff000000) << 8) |
1888 1 : ((value & 0x000000ff00000000) >> 8) |
1889 1 : ((value & 0x0000ff0000000000) >> 24) |
1890 2 : ((value & 0x00ff000000000000) >> 40) |
1891 1 : ((value & 0xff00000000000000) >> 56));
1892 : }
1893 :
1894 : static inline uint32_t libspdm_byte_swap_32(uint32_t value)
1895 : {
1896 : return ((value & 0x000000FF) << 24) |
1897 : ((value & 0x0000FF00) << 8) |
1898 : ((value & 0x00FF0000) >> 8) |
1899 : ((value & 0xFF000000) >> 24);
1900 : }
1901 :
1902 : static inline uint16_t libspdm_byte_swap_16(uint16_t value)
1903 : {
1904 : return ((value & 0x00FF) << 8) |
1905 : ((value & 0xFF00) >> 8);
1906 : }
1907 :
1908 : /**
1909 : * Return capability flags that are masked by the negotiated SPDM version.
1910 : *
1911 : * @param spdm_context A pointer to the SPDM context.
1912 : * @param is_request_flags If true then flags are from a request message or Requester.
1913 : * If false then flags are from a response message or Responder.
1914 : * @param flags A bitmask of capability flags.
1915 : *
1916 : * @return The masked capability flags.
1917 : */
1918 : uint32_t libspdm_mask_capability_flags(libspdm_context_t *spdm_context,
1919 : bool is_request_flags, uint32_t flags);
1920 :
1921 : /**
1922 : * Return capability extended flags that are masked by the negotiated SPDM version.
1923 : *
1924 : * @param spdm_context A pointer to the SPDM context.
1925 : * @param is_request_flags If true then flags are from a request message or Requester.
1926 : * If false then flags are from a response message or Responder.
1927 : * @param ext_flags A bitmask of capability extended flags.
1928 : *
1929 : * @return The masked capability extended flags.
1930 : */
1931 : uint16_t libspdm_mask_capability_ext_flags(libspdm_context_t *spdm_context,
1932 : bool is_request_flags, uint16_t ext_flags);
1933 :
1934 : /**
1935 : * Return BaseHashAlgo that is masked by the negotiated SPDM version.
1936 : *
1937 : * @param spdm_context A pointer to the SPDM context.
1938 : * @param base_hash_algo Unmasked BaseHashAlgo.
1939 : *
1940 : * @return The masked BaseHashAlgo.
1941 : */
1942 : uint32_t libspdm_mask_base_hash_algo(libspdm_context_t *spdm_context, uint32_t base_hash_algo);
1943 :
1944 : /**
1945 : * Return MeasurementHashAlgo that is masked by the negotiated SPDM version.
1946 : *
1947 : * @param spdm_context A pointer to the SPDM context.
1948 : * @param measurement_hash_algo Unmasked MeasurementHashAlgo.
1949 : *
1950 : * @return The masked MeasurementHashAlgo.
1951 : */
1952 : uint32_t libspdm_mask_measurement_hash_algo(libspdm_context_t *spdm_context,
1953 : uint32_t measurement_hash_algo);
1954 :
1955 : /**
1956 : * Return MeasurementSpecification that is masked by the negotiated SPDM version.
1957 : *
1958 : * @param spdm_context A pointer to the SPDM context.
1959 : * @param measurement_specification Unmasked MeasurementSpecification.
1960 : *
1961 : * @return The masked MeasurementSpecification.
1962 : */
1963 : uint8_t libspdm_mask_measurement_specification(libspdm_context_t *spdm_context,
1964 : uint8_t measurement_specification);
1965 :
1966 : /**
1967 : * Return MELspecification that is masked by the negotiated SPDM version.
1968 : *
1969 : * @param spdm_context A pointer to the SPDM context.
1970 : * @param mel_specification Unmasked MELspecification.
1971 : *
1972 : * @return The masked MELspecification.
1973 : */
1974 : uint8_t libspdm_mask_mel_specification(libspdm_context_t *spdm_context, uint8_t mel_specification);
1975 :
1976 : /**
1977 : * Return BaseAsymAlgo that is masked by the negotiated SPDM version.
1978 : *
1979 : * @param spdm_context A pointer to the SPDM context.
1980 : * @param base_asym_algo Unmasked BaseAsymAlgo.
1981 : *
1982 : * @return The masked BaseAsymAlgo.
1983 : */
1984 : uint32_t libspdm_mask_base_asym_algo(libspdm_context_t *spdm_context, uint32_t base_asym_algo);
1985 :
1986 : /**
1987 : * Check if the combination of SVH ID and VendorIDLen are legal.
1988 : *
1989 : * @param id Registry or standards body identifier (SPDM_REGISTRY_ID_*).
1990 : * Its size is two bytes due to the vendor-defined messages.
1991 : * @param vendor_id_len Length, in bytes, of the VendorID field.
1992 : * @retval true The ID and VendorIDLen are legal.
1993 : * @retval false The ID and VendorIDLen are illegal.
1994 : */
1995 : bool libspdm_validate_svh_vendor_id_len(uint16_t id, uint8_t vendor_id_len);
1996 :
1997 : /**
1998 : * Map slot ID to key pair ID.
1999 : *
2000 : * @param spdm_context A pointer to the SPDM context.
2001 : * @param slot_id The slot ID.
2002 : * @param is_requester Indicate of the key generation for a requester or a responder.
2003 : *
2004 : * @return key pair ID.
2005 : */
2006 : uint8_t libspdm_slot_id_to_key_pair_id (
2007 : void *spdm_context,
2008 : uint8_t slot_id,
2009 : bool is_requester);
2010 :
2011 : #if LIBSPDM_EVENT_RECIPIENT_SUPPORT
2012 : /**
2013 : * Check if the combination of DMTF EventTypeId and EventDetailLen is legal in a SEND_EVENT message.
2014 : *
2015 : * @param event_type_id Value of the DMTF EventTypeId.
2016 : * @param event_detail_len Size, in bytes, of EventDetail.
2017 : *
2018 : * @retval true The EventTypeId and EventDetailLen are legal.
2019 : * @retval false The EventTypeId and EventDetailLen are illegal.
2020 : */
2021 : bool libspdm_validate_dmtf_event_type(uint16_t event_type_id, uint16_t event_detail_len);
2022 :
2023 : /**
2024 : * Given a list of events, finds the event identified by the target EventInstanceID.
2025 : *
2026 : * @param events_list_start Pointer to list of events.
2027 : * @param event_count Number of events in the list.
2028 : * @param target_event_instance_id EventInstanceID to be found.
2029 : *
2030 : * @retval NULL Could not find the EventInstanceID.
2031 : * @retval non-NULL Pointer to the event corresponding to the target EventInstanceID
2032 : */
2033 : const void *libspdm_find_event_instance_id(const void *events_list_start, uint32_t event_count,
2034 : uint32_t target_event_instance_id);
2035 : /**
2036 : * Parses and sends an event to the Integrator. This function shall not be called if the Integrator
2037 : * has not registered an event handler via libspdm_register_event_callback.
2038 : *
2039 : * @param context A pointer to the SPDM context.
2040 : * @param session_id Secure session identifier.
2041 : * @param event_data A pointer to the event do be parsed and sent to Integrator.
2042 : * @param next_event_data On output, returns a pointer to the next event in event_data.
2043 : *
2044 : * @retval true The event was successfully parsed and sent to the Integrator.
2045 : * @retval false Unable to parse the event or the Integrator returned an error for the event.
2046 : */
2047 : bool libspdm_parse_and_send_event(libspdm_context_t *context, uint32_t session_id,
2048 : const void *event_data, const void **next_event_data);
2049 : #endif /* LIBSPDM_EVENT_RECIPIENT_SUPPORT */
2050 :
2051 : /**
2052 : * Given a buffer that spans from ptr to end_ptr, check if ptr + increment is within the buffer.
2053 : *
2054 : * @retval true There is enough space in the buffer.
2055 : * @retval false There is not enough space in the buffer.
2056 : */
2057 : bool libspdm_check_for_space(const uint8_t *ptr, const uint8_t *end_ptr, size_t increment);
2058 :
2059 : #endif /* SPDM_COMMON_LIB_INTERNAL_H */
|