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_secured_message_lib.h"
8 :
9 : /**
10 : * Return the size in bytes of a single SPDM secured message context.
11 : *
12 : * @return the size in bytes of a single SPDM secured message context.
13 : **/
14 236 : size_t libspdm_secured_message_get_context_size(void)
15 : {
16 236 : return sizeof(libspdm_secured_message_context_t);
17 : }
18 :
19 : /**
20 : * Initialize an SPDM secured message context.
21 : *
22 : * The size in bytes of the spdm_secured_message_context can be returned by libspdm_secured_message_get_context_size.
23 : *
24 : * @param spdm_secured_message_context A pointer to the SPDM secured message context.
25 : */
26 1208 : void libspdm_secured_message_init_context(void *spdm_secured_message_context)
27 : {
28 : libspdm_secured_message_context_t *secured_message_context;
29 :
30 1208 : secured_message_context = spdm_secured_message_context;
31 1208 : libspdm_zero_mem(secured_message_context, sizeof(libspdm_secured_message_context_t));
32 1208 : }
33 :
34 : /**
35 : * Set use_psk to an SPDM secured message context.
36 : *
37 : * @param spdm_secured_message_context A pointer to the SPDM secured message context.
38 : * @param use_psk Indicate if the SPDM session use PSK.
39 : */
40 740 : void libspdm_secured_message_set_use_psk(void *spdm_secured_message_context, bool use_psk)
41 : {
42 : libspdm_secured_message_context_t *secured_message_context;
43 :
44 740 : secured_message_context = spdm_secured_message_context;
45 740 : secured_message_context->use_psk = use_psk;
46 740 : }
47 :
48 : /**
49 : * Set session_state to an SPDM secured message context.
50 : *
51 : * @param spdm_secured_message_context A pointer to the SPDM secured message context.
52 : * @param session_state Indicate the SPDM session state.
53 : */
54 448 : void libspdm_secured_message_set_session_state(
55 : void *spdm_secured_message_context,
56 : libspdm_session_state_t session_state)
57 : {
58 : libspdm_secured_message_context_t *secured_message_context;
59 :
60 448 : secured_message_context = spdm_secured_message_context;
61 448 : secured_message_context->session_state = session_state;
62 :
63 448 : if (session_state == LIBSPDM_SESSION_STATE_ESTABLISHED) {
64 : /* session handshake key should be zeroized after handshake phase. */
65 264 : libspdm_clear_handshake_secret(secured_message_context);
66 264 : libspdm_clear_master_secret(secured_message_context);
67 : }
68 448 : }
69 :
70 : /**
71 : * Return session_state of an SPDM secured message context.
72 : *
73 : * @param spdm_secured_message_context A pointer to the SPDM secured message context.
74 : *
75 : * @return the SPDM session state.
76 : */
77 : libspdm_session_state_t
78 558 : libspdm_secured_message_get_session_state(void *spdm_secured_message_context)
79 : {
80 : libspdm_secured_message_context_t *secured_message_context;
81 :
82 558 : secured_message_context = spdm_secured_message_context;
83 558 : return secured_message_context->session_state;
84 : }
85 :
86 : /**
87 : * Set session_type to an SPDM secured message context.
88 : *
89 : * @param spdm_secured_message_context A pointer to the SPDM secured message context.
90 : * @param session_type Indicate the SPDM session type.
91 : */
92 740 : void libspdm_secured_message_set_session_type(void *spdm_secured_message_context,
93 : libspdm_session_type_t session_type)
94 : {
95 : libspdm_secured_message_context_t *secured_message_context;
96 :
97 740 : secured_message_context = spdm_secured_message_context;
98 740 : secured_message_context->session_type = session_type;
99 740 : }
100 :
101 : /**
102 : * Set algorithm to an SPDM secured message context.
103 : *
104 : * @param spdm_secured_message_context A pointer to the SPDM secured message context.
105 : * @param base_hash_algo Indicate the negotiated base_hash_algo for the SPDM session.
106 : * @param dhe_named_group Indicate the negotiated dhe_named_group for the SPDM session.
107 : * @param aead_cipher_suite Indicate the negotiated aead_cipher_suite for the SPDM session.
108 : * @param key_schedule Indicate the negotiated key_schedule for the SPDM session.
109 : */
110 740 : void libspdm_secured_message_set_algorithms(void *spdm_secured_message_context,
111 : const spdm_version_number_t version,
112 : const spdm_version_number_t secured_message_version,
113 : uint32_t base_hash_algo,
114 : uint16_t dhe_named_group,
115 : uint32_t kem_alg,
116 : uint16_t aead_cipher_suite,
117 : uint16_t key_schedule)
118 : {
119 : libspdm_secured_message_context_t *secured_message_context;
120 :
121 740 : secured_message_context = spdm_secured_message_context;
122 740 : secured_message_context->version = version;
123 740 : secured_message_context->secured_message_version = secured_message_version;
124 740 : secured_message_context->base_hash_algo = base_hash_algo;
125 740 : secured_message_context->dhe_named_group = dhe_named_group;
126 740 : secured_message_context->kem_alg = kem_alg;
127 740 : secured_message_context->aead_cipher_suite = aead_cipher_suite;
128 740 : secured_message_context->key_schedule = key_schedule;
129 :
130 740 : secured_message_context->hash_size =
131 740 : libspdm_get_hash_size(secured_message_context->base_hash_algo);
132 740 : if (kem_alg != 0) {
133 0 : secured_message_context->shared_key_size = libspdm_get_kem_shared_secret_size(
134 : secured_message_context->kem_alg);
135 : } else {
136 740 : secured_message_context->shared_key_size = libspdm_get_dhe_shared_secret_size(
137 740 : secured_message_context->dhe_named_group);
138 : }
139 1480 : secured_message_context->aead_key_size = libspdm_get_aead_key_size(
140 740 : secured_message_context->aead_cipher_suite);
141 1480 : secured_message_context->aead_iv_size = libspdm_get_aead_iv_size(
142 740 : secured_message_context->aead_cipher_suite);
143 1480 : secured_message_context->aead_tag_size = libspdm_get_aead_tag_size(
144 740 : secured_message_context->aead_cipher_suite);
145 740 : }
146 :
147 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
148 77 : void libspdm_secured_message_set_psk_hint(void *spdm_secured_message_context,
149 : const void *psk_hint,
150 : size_t psk_hint_size)
151 : {
152 : libspdm_secured_message_context_t *secured_message_context;
153 :
154 77 : secured_message_context = spdm_secured_message_context;
155 77 : if ((psk_hint != NULL) && (psk_hint_size > 0)) {
156 75 : secured_message_context->psk_hint_size = psk_hint_size;
157 75 : libspdm_copy_mem(secured_message_context->psk_hint,
158 : LIBSPDM_PSK_MAX_HINT_LENGTH,
159 : psk_hint,
160 : psk_hint_size);
161 : }
162 77 : }
163 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */
164 :
165 : /**
166 : * Set the maximum sequence_number to an SPDM secured message context.
167 : *
168 : * @param spdm_secured_message_context A pointer to the SPDM secured message context.
169 : * @param max_spdm_session_sequence_number Indicate the maximum sequence_number in SPDM session.
170 : */
171 740 : void libspdm_secured_message_set_max_spdm_session_sequence_number(
172 : void *spdm_secured_message_context,
173 : uint64_t max_spdm_session_sequence_number)
174 : {
175 : libspdm_secured_message_context_t *secured_message_context;
176 :
177 740 : secured_message_context = spdm_secured_message_context;
178 740 : secured_message_context->max_spdm_session_sequence_number = max_spdm_session_sequence_number;
179 740 : }
180 :
181 740 : void libspdm_secured_message_set_sequence_number_endian (
182 : void *spdm_secured_message_context,
183 : uint8_t endian_value)
184 : {
185 : libspdm_secured_message_context_t *secured_message_context;
186 :
187 740 : secured_message_context = spdm_secured_message_context;
188 740 : secured_message_context->sequence_number_endian = endian_value;
189 740 : }
190 :
191 0 : bool libspdm_secured_message_import_shared_secret(void *spdm_secured_message_context,
192 : const void *shared_secret,
193 : size_t shared_secret_size)
194 : {
195 : libspdm_secured_message_context_t *secured_message_context;
196 :
197 0 : secured_message_context = spdm_secured_message_context;
198 0 : if (shared_secret_size > secured_message_context->shared_key_size) {
199 0 : return false;
200 : }
201 0 : secured_message_context->shared_key_size = shared_secret_size;
202 0 : libspdm_copy_mem(secured_message_context->master_secret.shared_secret,
203 : sizeof(secured_message_context->master_secret.shared_secret),
204 : shared_secret, shared_secret_size);
205 0 : return true;
206 : }
207 :
208 3 : bool libspdm_secured_message_export_master_secret(
209 : void *spdm_secured_message_context, void *export_master_secret,
210 : size_t *export_master_secret_size)
211 : {
212 : libspdm_secured_message_context_t *secured_message_context;
213 :
214 3 : secured_message_context = spdm_secured_message_context;
215 :
216 3 : if (*export_master_secret_size > secured_message_context->hash_size) {
217 1 : *export_master_secret_size = secured_message_context->hash_size;
218 : }
219 :
220 3 : libspdm_copy_mem(export_master_secret, *export_master_secret_size,
221 3 : secured_message_context->export_master_secret,
222 : *export_master_secret_size);
223 :
224 3 : return true;
225 : }
226 :
227 1 : void libspdm_secured_message_clear_export_master_secret(void *spdm_secured_message_context)
228 : {
229 : libspdm_secured_message_context_t *secured_message_context;
230 :
231 1 : LIBSPDM_ASSERT(spdm_secured_message_context != NULL);
232 :
233 1 : secured_message_context = spdm_secured_message_context;
234 :
235 1 : libspdm_zero_mem(secured_message_context->export_master_secret,
236 : sizeof(secured_message_context->export_master_secret));
237 1 : }
238 :
239 0 : bool libspdm_secured_message_export_session_keys(void *spdm_secured_message_context,
240 : void *session_keys,
241 : size_t *session_keys_size)
242 : {
243 : libspdm_secured_message_context_t *secured_message_context;
244 : size_t struct_size;
245 : libspdm_secure_session_keys_struct_t *session_keys_struct;
246 : uint8_t *ptr;
247 :
248 0 : secured_message_context = spdm_secured_message_context;
249 0 : struct_size = sizeof(libspdm_secure_session_keys_struct_t) +
250 0 : (secured_message_context->aead_key_size +
251 0 : secured_message_context->aead_iv_size + sizeof(uint64_t)) * 2;
252 :
253 0 : if (*session_keys_size < struct_size) {
254 0 : *session_keys_size = struct_size;
255 0 : return false;
256 : }
257 :
258 0 : session_keys_struct = session_keys;
259 0 : session_keys_struct->version = LIBSPDM_SECURE_SESSION_KEYS_STRUCT_VERSION;
260 0 : session_keys_struct->aead_key_size = (uint32_t)secured_message_context->aead_key_size;
261 0 : session_keys_struct->aead_iv_size = (uint32_t)secured_message_context->aead_iv_size;
262 :
263 0 : ptr = (void *)(session_keys_struct + 1);
264 0 : libspdm_copy_mem(ptr,
265 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
266 0 : secured_message_context->application_secret.request_data_encryption_key,
267 : secured_message_context->aead_key_size);
268 0 : ptr += secured_message_context->aead_key_size;
269 0 : libspdm_copy_mem(ptr,
270 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
271 0 : secured_message_context->application_secret.request_data_salt,
272 : secured_message_context->aead_iv_size);
273 0 : ptr += secured_message_context->aead_iv_size;
274 0 : libspdm_copy_mem(ptr,
275 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
276 0 : &secured_message_context->application_secret.request_data_sequence_number,
277 : sizeof(uint64_t));
278 0 : ptr += sizeof(uint64_t);
279 0 : libspdm_copy_mem(ptr,
280 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
281 0 : secured_message_context->application_secret.response_data_encryption_key,
282 : secured_message_context->aead_key_size);
283 0 : ptr += secured_message_context->aead_key_size;
284 0 : libspdm_copy_mem(ptr,
285 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
286 0 : secured_message_context->application_secret.response_data_salt,
287 : secured_message_context->aead_iv_size);
288 0 : ptr += secured_message_context->aead_iv_size;
289 0 : libspdm_copy_mem(ptr,
290 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
291 0 : &secured_message_context->application_secret.response_data_sequence_number,
292 : sizeof(uint64_t));
293 0 : ptr += sizeof(uint64_t);
294 0 : return true;
295 : }
296 :
297 0 : bool libspdm_secured_message_import_session_keys(void *spdm_secured_message_context,
298 : const void *session_keys,
299 : size_t session_keys_size)
300 : {
301 : libspdm_secured_message_context_t *secured_message_context;
302 : size_t struct_size;
303 : const libspdm_secure_session_keys_struct_t *session_keys_struct;
304 : const uint8_t *ptr;
305 :
306 0 : secured_message_context = spdm_secured_message_context;
307 0 : struct_size = sizeof(libspdm_secure_session_keys_struct_t) +
308 0 : (secured_message_context->aead_key_size +
309 0 : secured_message_context->aead_iv_size + sizeof(uint64_t)) * 2;
310 :
311 0 : if (session_keys_size != struct_size) {
312 0 : return false;
313 : }
314 :
315 0 : session_keys_struct = session_keys;
316 0 : if ((session_keys_struct->version !=
317 0 : LIBSPDM_SECURE_SESSION_KEYS_STRUCT_VERSION) ||
318 0 : (session_keys_struct->aead_key_size !=
319 0 : secured_message_context->aead_key_size) ||
320 0 : (session_keys_struct->aead_iv_size !=
321 0 : secured_message_context->aead_iv_size)) {
322 0 : return false;
323 : }
324 :
325 0 : ptr = (const void *)(session_keys_struct + 1);
326 0 : libspdm_copy_mem(secured_message_context->application_secret.request_data_encryption_key,
327 : sizeof(secured_message_context->application_secret
328 : .request_data_encryption_key),
329 : ptr, secured_message_context->aead_key_size);
330 0 : ptr += secured_message_context->aead_key_size;
331 0 : libspdm_copy_mem(secured_message_context->application_secret.request_data_salt,
332 : sizeof(secured_message_context->application_secret
333 : .request_data_salt),
334 : ptr, secured_message_context->aead_iv_size);
335 0 : ptr += secured_message_context->aead_iv_size;
336 0 : libspdm_copy_mem(&secured_message_context->application_secret.request_data_sequence_number,
337 : sizeof(secured_message_context->application_secret
338 : .request_data_sequence_number),
339 : ptr, sizeof(uint64_t));
340 0 : ptr += sizeof(uint64_t);
341 0 : libspdm_copy_mem(secured_message_context->application_secret
342 0 : .response_data_encryption_key,
343 : sizeof(secured_message_context->application_secret
344 : .response_data_encryption_key),
345 : ptr, secured_message_context->aead_key_size);
346 0 : ptr += secured_message_context->aead_key_size;
347 0 : libspdm_copy_mem(secured_message_context->application_secret.response_data_salt,
348 : sizeof(secured_message_context->application_secret.response_data_salt),
349 : ptr, secured_message_context->aead_iv_size);
350 0 : ptr += secured_message_context->aead_iv_size;
351 0 : libspdm_copy_mem(&secured_message_context->application_secret.response_data_sequence_number,
352 : sizeof(secured_message_context->application_secret
353 : .response_data_sequence_number),
354 : ptr, sizeof(uint64_t));
355 0 : ptr += sizeof(uint64_t);
356 0 : return true;
357 : }
358 :
359 : /**
360 : * Get the last SPDM error struct of an SPDM context.
361 : *
362 : * @param spdm_context A pointer to the SPDM context.
363 : * @param last_spdm_error Last SPDM error struct of an SPDM context.
364 : */
365 28 : void libspdm_secured_message_get_last_spdm_error_struct(
366 : void *spdm_secured_message_context,
367 : libspdm_error_struct_t *last_spdm_error)
368 : {
369 : libspdm_secured_message_context_t *secured_message_context;
370 :
371 28 : secured_message_context = spdm_secured_message_context;
372 28 : libspdm_copy_mem(last_spdm_error, sizeof(libspdm_error_struct_t),
373 28 : &secured_message_context->last_spdm_error,
374 : sizeof(libspdm_error_struct_t));
375 28 : }
376 :
377 : /**
378 : * Set the last SPDM error struct of an SPDM context.
379 : *
380 : * @param spdm_context A pointer to the SPDM context.
381 : * @param last_spdm_error Last SPDM error struct of an SPDM context.
382 : */
383 337 : void libspdm_secured_message_set_last_spdm_error_struct(
384 : void *spdm_secured_message_context,
385 : const libspdm_error_struct_t *last_spdm_error)
386 : {
387 : libspdm_secured_message_context_t *secured_message_context;
388 :
389 337 : secured_message_context = spdm_secured_message_context;
390 337 : libspdm_copy_mem(&secured_message_context->last_spdm_error,
391 : sizeof(secured_message_context->last_spdm_error),
392 : last_spdm_error,
393 : sizeof(libspdm_error_struct_t));
394 337 : }
|