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 220 : size_t libspdm_secured_message_get_context_size(void)
15 : {
16 220 : 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 1132 : void libspdm_secured_message_init_context(void *spdm_secured_message_context)
27 : {
28 : libspdm_secured_message_context_t *secured_message_context;
29 :
30 1132 : secured_message_context = spdm_secured_message_context;
31 1132 : libspdm_zero_mem(secured_message_context, sizeof(libspdm_secured_message_context_t));
32 1132 : }
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 696 : 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 696 : secured_message_context = spdm_secured_message_context;
45 696 : secured_message_context->use_psk = use_psk;
46 696 : }
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 404 : 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 404 : secured_message_context = spdm_secured_message_context;
61 404 : secured_message_context->session_state = session_state;
62 :
63 404 : if (session_state == LIBSPDM_SESSION_STATE_ESTABLISHED) {
64 : /* session handshake key should be zeroized after handshake phase. */
65 221 : libspdm_clear_handshake_secret(secured_message_context);
66 221 : libspdm_clear_master_secret(secured_message_context);
67 : }
68 404 : }
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 523 : libspdm_secured_message_get_session_state(void *spdm_secured_message_context)
79 : {
80 : libspdm_secured_message_context_t *secured_message_context;
81 :
82 523 : secured_message_context = spdm_secured_message_context;
83 523 : 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 696 : 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 696 : secured_message_context = spdm_secured_message_context;
98 696 : secured_message_context->session_type = session_type;
99 696 : }
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 696 : 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 696 : secured_message_context = spdm_secured_message_context;
122 696 : secured_message_context->version = version;
123 696 : secured_message_context->secured_message_version = secured_message_version;
124 696 : secured_message_context->base_hash_algo = base_hash_algo;
125 696 : secured_message_context->dhe_named_group = dhe_named_group;
126 696 : secured_message_context->kem_alg = kem_alg;
127 696 : secured_message_context->aead_cipher_suite = aead_cipher_suite;
128 696 : secured_message_context->key_schedule = key_schedule;
129 :
130 696 : secured_message_context->hash_size =
131 696 : libspdm_get_hash_size(secured_message_context->base_hash_algo);
132 696 : 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 696 : secured_message_context->shared_key_size = libspdm_get_dhe_pub_key_size(
137 696 : secured_message_context->dhe_named_group);
138 : }
139 1392 : secured_message_context->aead_key_size = libspdm_get_aead_key_size(
140 696 : secured_message_context->aead_cipher_suite);
141 1392 : secured_message_context->aead_iv_size = libspdm_get_aead_iv_size(
142 696 : secured_message_context->aead_cipher_suite);
143 1392 : secured_message_context->aead_tag_size = libspdm_get_aead_tag_size(
144 696 : secured_message_context->aead_cipher_suite);
145 696 : }
146 :
147 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
148 76 : 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 76 : secured_message_context = spdm_secured_message_context;
155 76 : if ((psk_hint != NULL) && (psk_hint_size > 0)) {
156 74 : secured_message_context->psk_hint_size = psk_hint_size;
157 74 : libspdm_copy_mem(secured_message_context->psk_hint,
158 : LIBSPDM_PSK_MAX_HINT_LENGTH,
159 : psk_hint,
160 : psk_hint_size);
161 : }
162 76 : }
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 696 : 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 696 : secured_message_context = spdm_secured_message_context;
178 696 : secured_message_context->max_spdm_session_sequence_number = max_spdm_session_sequence_number;
179 696 : }
180 :
181 696 : 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 696 : secured_message_context = spdm_secured_message_context;
188 696 : secured_message_context->sequence_number_endian = endian_value;
189 696 : }
190 :
191 : /**
192 : * Import the Shared Secret to an SPDM secured message context.
193 : *
194 : * @param spdm_secured_message_context A pointer to the SPDM secured message context.
195 : * @param shared_secret Indicate the shared secret.
196 : * @param shared_secret_size The size in bytes of the shared secret.
197 : *
198 : * @retval RETURN_SUCCESS Shared Secret is imported.
199 : */
200 0 : bool libspdm_secured_message_import_shared_secret(void *spdm_secured_message_context,
201 : const void *shared_secret,
202 : size_t shared_secret_size)
203 : {
204 : libspdm_secured_message_context_t *secured_message_context;
205 :
206 0 : secured_message_context = spdm_secured_message_context;
207 0 : if (shared_secret_size > secured_message_context->shared_key_size) {
208 0 : return false;
209 : }
210 0 : secured_message_context->shared_key_size = shared_secret_size;
211 0 : libspdm_copy_mem(secured_message_context->master_secret.shared_secret,
212 : sizeof(secured_message_context->master_secret.shared_secret),
213 : shared_secret, shared_secret_size);
214 0 : return true;
215 : }
216 :
217 3 : bool libspdm_secured_message_export_master_secret(
218 : void *spdm_secured_message_context, void *export_master_secret,
219 : size_t *export_master_secret_size)
220 : {
221 : libspdm_secured_message_context_t *secured_message_context;
222 :
223 3 : secured_message_context = spdm_secured_message_context;
224 :
225 3 : if (*export_master_secret_size > secured_message_context->hash_size) {
226 1 : *export_master_secret_size = secured_message_context->hash_size;
227 : }
228 :
229 3 : libspdm_copy_mem(export_master_secret, *export_master_secret_size,
230 3 : secured_message_context->export_master_secret,
231 : *export_master_secret_size);
232 :
233 3 : return true;
234 : }
235 :
236 1 : void libspdm_secured_message_clear_export_master_secret(void *spdm_secured_message_context)
237 : {
238 : libspdm_secured_message_context_t *secured_message_context;
239 :
240 1 : LIBSPDM_ASSERT(spdm_secured_message_context != NULL);
241 :
242 1 : secured_message_context = spdm_secured_message_context;
243 :
244 1 : libspdm_zero_mem(secured_message_context->export_master_secret,
245 : sizeof(secured_message_context->export_master_secret));
246 1 : }
247 :
248 : /**
249 : * Export the session_keys from an SPDM secured message context.
250 : *
251 : * @param spdm_secured_message_context A pointer to the SPDM secured message context.
252 : * @param session_keys Indicate the buffer to store the session_keys in libspdm_secure_session_keys_struct_t.
253 : * @param session_keys_size The size in bytes of the session_keys in libspdm_secure_session_keys_struct_t.
254 : *
255 : * @retval RETURN_SUCCESS session_keys are exported.
256 : */
257 0 : bool libspdm_secured_message_export_session_keys(void *spdm_secured_message_context,
258 : void *session_keys,
259 : size_t *session_keys_size)
260 : {
261 : libspdm_secured_message_context_t *secured_message_context;
262 : size_t struct_size;
263 : libspdm_secure_session_keys_struct_t *session_keys_struct;
264 : uint8_t *ptr;
265 :
266 0 : secured_message_context = spdm_secured_message_context;
267 0 : struct_size = sizeof(libspdm_secure_session_keys_struct_t) +
268 0 : (secured_message_context->aead_key_size +
269 0 : secured_message_context->aead_iv_size + sizeof(uint64_t)) * 2;
270 :
271 0 : if (*session_keys_size < struct_size) {
272 0 : *session_keys_size = struct_size;
273 0 : return false;
274 : }
275 :
276 0 : session_keys_struct = session_keys;
277 0 : session_keys_struct->version = LIBSPDM_SECURE_SESSION_KEYS_STRUCT_VERSION;
278 0 : session_keys_struct->aead_key_size = (uint32_t)secured_message_context->aead_key_size;
279 0 : session_keys_struct->aead_iv_size = (uint32_t)secured_message_context->aead_iv_size;
280 :
281 0 : ptr = (void *)(session_keys_struct + 1);
282 0 : libspdm_copy_mem(ptr,
283 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
284 0 : secured_message_context->application_secret.request_data_encryption_key,
285 : secured_message_context->aead_key_size);
286 0 : ptr += secured_message_context->aead_key_size;
287 0 : libspdm_copy_mem(ptr,
288 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
289 0 : secured_message_context->application_secret.request_data_salt,
290 : secured_message_context->aead_iv_size);
291 0 : ptr += secured_message_context->aead_iv_size;
292 0 : libspdm_copy_mem(ptr,
293 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
294 0 : &secured_message_context->application_secret.request_data_sequence_number,
295 : sizeof(uint64_t));
296 0 : ptr += sizeof(uint64_t);
297 0 : libspdm_copy_mem(ptr,
298 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
299 0 : secured_message_context->application_secret.response_data_encryption_key,
300 : secured_message_context->aead_key_size);
301 0 : ptr += secured_message_context->aead_key_size;
302 0 : libspdm_copy_mem(ptr,
303 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
304 0 : secured_message_context->application_secret.response_data_salt,
305 : secured_message_context->aead_iv_size);
306 0 : ptr += secured_message_context->aead_iv_size;
307 0 : libspdm_copy_mem(ptr,
308 0 : *session_keys_size - (ptr - (uint8_t*)session_keys),
309 0 : &secured_message_context->application_secret.response_data_sequence_number,
310 : sizeof(uint64_t));
311 0 : ptr += sizeof(uint64_t);
312 0 : return true;
313 : }
314 :
315 : /**
316 : * Import the session_keys from an SPDM secured message context.
317 : *
318 : * @param spdm_secured_message_context A pointer to the SPDM secured message context.
319 : * @param session_keys Indicate the buffer to store the session_keys in libspdm_secure_session_keys_struct_t.
320 : * @param session_keys_size The size in bytes of the session_keys in libspdm_secure_session_keys_struct_t.
321 : *
322 : * @retval RETURN_SUCCESS session_keys are imported.
323 : */
324 : bool
325 0 : libspdm_secured_message_import_session_keys(void *spdm_secured_message_context,
326 : const void *session_keys,
327 : size_t session_keys_size)
328 : {
329 : libspdm_secured_message_context_t *secured_message_context;
330 : size_t struct_size;
331 : const libspdm_secure_session_keys_struct_t *session_keys_struct;
332 : const uint8_t *ptr;
333 :
334 0 : secured_message_context = spdm_secured_message_context;
335 0 : struct_size = sizeof(libspdm_secure_session_keys_struct_t) +
336 0 : (secured_message_context->aead_key_size +
337 0 : secured_message_context->aead_iv_size + sizeof(uint64_t)) * 2;
338 :
339 0 : if (session_keys_size != struct_size) {
340 0 : return false;
341 : }
342 :
343 0 : session_keys_struct = session_keys;
344 0 : if ((session_keys_struct->version !=
345 0 : LIBSPDM_SECURE_SESSION_KEYS_STRUCT_VERSION) ||
346 0 : (session_keys_struct->aead_key_size !=
347 0 : secured_message_context->aead_key_size) ||
348 0 : (session_keys_struct->aead_iv_size !=
349 0 : secured_message_context->aead_iv_size)) {
350 0 : return false;
351 : }
352 :
353 0 : ptr = (const void *)(session_keys_struct + 1);
354 0 : libspdm_copy_mem(secured_message_context->application_secret.request_data_encryption_key,
355 : sizeof(secured_message_context->application_secret
356 : .request_data_encryption_key),
357 : ptr, secured_message_context->aead_key_size);
358 0 : ptr += secured_message_context->aead_key_size;
359 0 : libspdm_copy_mem(secured_message_context->application_secret.request_data_salt,
360 : sizeof(secured_message_context->application_secret
361 : .request_data_salt),
362 : ptr, secured_message_context->aead_iv_size);
363 0 : ptr += secured_message_context->aead_iv_size;
364 0 : libspdm_copy_mem(&secured_message_context->application_secret.request_data_sequence_number,
365 : sizeof(secured_message_context->application_secret
366 : .request_data_sequence_number),
367 : ptr, sizeof(uint64_t));
368 0 : ptr += sizeof(uint64_t);
369 0 : libspdm_copy_mem(secured_message_context->application_secret
370 0 : .response_data_encryption_key,
371 : sizeof(secured_message_context->application_secret
372 : .response_data_encryption_key),
373 : ptr, secured_message_context->aead_key_size);
374 0 : ptr += secured_message_context->aead_key_size;
375 0 : libspdm_copy_mem(secured_message_context->application_secret.response_data_salt,
376 : sizeof(secured_message_context->application_secret.response_data_salt),
377 : ptr, secured_message_context->aead_iv_size);
378 0 : ptr += secured_message_context->aead_iv_size;
379 0 : libspdm_copy_mem(&secured_message_context->application_secret.response_data_sequence_number,
380 : sizeof(secured_message_context->application_secret
381 : .response_data_sequence_number),
382 : ptr, sizeof(uint64_t));
383 0 : ptr += sizeof(uint64_t);
384 0 : return true;
385 : }
386 :
387 : /**
388 : * Get the last SPDM error struct of an SPDM context.
389 : *
390 : * @param spdm_context A pointer to the SPDM context.
391 : * @param last_spdm_error Last SPDM error struct of an SPDM context.
392 : */
393 28 : void libspdm_secured_message_get_last_spdm_error_struct(
394 : void *spdm_secured_message_context,
395 : libspdm_error_struct_t *last_spdm_error)
396 : {
397 : libspdm_secured_message_context_t *secured_message_context;
398 :
399 28 : secured_message_context = spdm_secured_message_context;
400 28 : libspdm_copy_mem(last_spdm_error, sizeof(libspdm_error_struct_t),
401 28 : &secured_message_context->last_spdm_error,
402 : sizeof(libspdm_error_struct_t));
403 28 : }
404 :
405 : /**
406 : * Set the last SPDM error struct of an SPDM context.
407 : *
408 : * @param spdm_context A pointer to the SPDM context.
409 : * @param last_spdm_error Last SPDM error struct of an SPDM context.
410 : */
411 332 : void libspdm_secured_message_set_last_spdm_error_struct(
412 : void *spdm_secured_message_context,
413 : const libspdm_error_struct_t *last_spdm_error)
414 : {
415 : libspdm_secured_message_context_t *secured_message_context;
416 :
417 332 : secured_message_context = spdm_secured_message_context;
418 332 : libspdm_copy_mem(&secured_message_context->last_spdm_error,
419 : sizeof(secured_message_context->last_spdm_error),
420 : last_spdm_error,
421 : sizeof(libspdm_error_struct_t));
422 332 : }
|