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