Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2023-2026 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 "spdm_unit_test.h"
8 : #include "internal/libspdm_secured_message_lib.h"
9 :
10 : #if LIBSPDM_AEAD_AES_256_GCM_SUPPORT
11 :
12 : static uint8_t m_secured_message[0x1000];
13 : static uint8_t m_app_message[0x1000];
14 : static libspdm_secured_message_context_t m_secured_message_context;
15 : static libspdm_secured_message_callbacks_t m_secured_message_callbacks;
16 :
17 : #define PARTIAL_SEQ_NUM_SIZE 8
18 :
19 22 : static uint8_t get_sequence_number(uint64_t sequence_number,
20 : uint8_t *sequence_number_buffer)
21 : {
22 22 : libspdm_copy_mem(sequence_number_buffer, (size_t)8,
23 : &sequence_number, (size_t)PARTIAL_SEQ_NUM_SIZE);
24 :
25 22 : return PARTIAL_SEQ_NUM_SIZE;
26 : }
27 :
28 8 : static uint32_t get_max_random_number_count(void)
29 : {
30 8 : return 0;
31 : }
32 :
33 24 : static spdm_version_number_t get_secured_spdm_version(spdm_version_number_t secured_message_version)
34 : {
35 24 : return secured_message_version;
36 : }
37 :
38 18 : static void initialize_secured_message_context(void)
39 : {
40 18 : m_secured_message_context.secured_message_version =
41 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
42 18 : m_secured_message_context.aead_cipher_suite = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM;
43 18 : m_secured_message_context.session_type = LIBSPDM_SESSION_TYPE_ENC_MAC;
44 18 : m_secured_message_context.session_state = LIBSPDM_SESSION_STATE_ESTABLISHED;
45 18 : m_secured_message_context.aead_tag_size = 16;
46 18 : m_secured_message_context.aead_key_size = 32;
47 18 : m_secured_message_context.aead_iv_size = 12;
48 594 : for (uint8_t index = 0; index < 32; index++) {
49 576 : m_secured_message_context.application_secret.request_data_encryption_key[index] = index;
50 576 : m_secured_message_context.application_secret.response_data_encryption_key[index] =
51 576 : 32 - index;
52 : }
53 234 : for (uint8_t index = 0; index < 12; index++) {
54 216 : m_secured_message_context.application_secret.request_data_salt[index] = index * 2;
55 216 : m_secured_message_context.application_secret.response_data_salt[index] = index * 4;
56 : }
57 18 : m_secured_message_context.application_secret.request_data_sequence_number = 0;
58 18 : m_secured_message_context.application_secret.response_data_sequence_number = 0;
59 18 : m_secured_message_context.max_spdm_session_sequence_number = UINT64_MAX;
60 18 : m_secured_message_context.sequence_number_endian =
61 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_BOTH;
62 18 : m_secured_message_callbacks.get_secured_spdm_version = get_secured_spdm_version;
63 18 : m_secured_message_callbacks.get_max_random_number_count = get_max_random_number_count;
64 18 : m_secured_message_callbacks.get_sequence_number = get_sequence_number;
65 18 : }
66 :
67 : /**
68 : * Test 1: Test basic encryption with sequence number set to all zeroes and little endianness.
69 : **/
70 1 : static void libspdm_test_secured_message_encode_case1(void **state)
71 : {
72 : libspdm_return_t status;
73 : uint8_t app_message_buffer[sizeof(spdm_secured_message_cipher_header_t) + 16];
74 1 : uint8_t *app_message = app_message_buffer + sizeof(spdm_secured_message_cipher_header_t);
75 1 : size_t secured_message_size = sizeof(m_secured_message);
76 1 : const uint32_t session_id = 0x00112233;
77 : uint8_t *ptr;
78 :
79 1 : initialize_secured_message_context();
80 :
81 17 : for (uint8_t index = 0; index < 16; index++) {
82 16 : app_message[index] = index;
83 : }
84 :
85 1 : status = libspdm_encode_secured_message(
86 : &m_secured_message_context, session_id, true,
87 : sizeof(app_message_buffer) - sizeof(spdm_secured_message_cipher_header_t),
88 : app_message, &secured_message_size, &m_secured_message,
89 : &m_secured_message_callbacks);
90 :
91 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
92 1 : assert_memory_equal(&session_id, &m_secured_message, 4);
93 :
94 : /* Sequence number is all zeroes. */
95 9 : for (int index = 4; index < 4 + PARTIAL_SEQ_NUM_SIZE; index++) {
96 8 : assert_int_equal(0, m_secured_message[index]);
97 : }
98 :
99 1 : assert_int_equal(0x0022, libspdm_read_uint16(&m_secured_message[4 + PARTIAL_SEQ_NUM_SIZE]));
100 :
101 1 : ptr = (uint8_t *)&m_secured_message + 6 + PARTIAL_SEQ_NUM_SIZE;
102 :
103 : /* Expected values generated from https://tinyurl.com/yrx9w78w */
104 1 : uint8_t expected_cipher_text[] = {0x9b, 0xfe, 0xd3, 0xb7, 0x04, 0x3d, 0x32, 0x86, 0x60, 0x3d,
105 : 0x86, 0x17, 0x33, 0xd6, 0x7f, 0x95, 0x9a, 0x20};
106 1 : uint8_t expected_mac[] = {0x3d, 0x4f, 0xac, 0x58, 0xcb, 0x70, 0x6c, 0xf5, 0xa0, 0x27, 0x0a,
107 : 0xf6, 0x73, 0xf0, 0xfe, 0x36};
108 :
109 1 : assert_memory_equal(expected_cipher_text, ptr, sizeof(expected_cipher_text));
110 1 : ptr += sizeof(expected_cipher_text);
111 1 : assert_memory_equal(expected_mac, ptr, sizeof(expected_mac));
112 :
113 : /* Sequence number is incremented by one after operation. */
114 1 : assert_int_equal(1, m_secured_message_context.application_secret.request_data_sequence_number);
115 1 : }
116 :
117 : /**
118 : * Test 2: Test basic encryption with sequence number set to alternating zeroes and ones and
119 : * little endianness.
120 : **/
121 1 : static void libspdm_test_secured_message_encode_case2(void **state)
122 : {
123 : libspdm_return_t status;
124 : uint8_t app_message_buffer[sizeof(spdm_secured_message_cipher_header_t) + 16];
125 1 : uint8_t *app_message = app_message_buffer + sizeof(spdm_secured_message_cipher_header_t);
126 1 : size_t secured_message_size = sizeof(m_secured_message);
127 1 : const uint32_t session_id = 0x00112233;
128 : uint8_t *ptr;
129 :
130 1 : initialize_secured_message_context();
131 1 : m_secured_message_context.application_secret.request_data_sequence_number = 0xaa55aa55aa55aa55;
132 :
133 17 : for (uint8_t index = 0; index < 16; index++) {
134 16 : app_message[index] = index;
135 : }
136 :
137 1 : status = libspdm_encode_secured_message(
138 : &m_secured_message_context, session_id, true,
139 : sizeof(app_message_buffer) - sizeof(spdm_secured_message_cipher_header_t),
140 : app_message, &secured_message_size, &m_secured_message,
141 : &m_secured_message_callbacks);
142 :
143 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
144 1 : assert_memory_equal(&session_id, &m_secured_message, 4);
145 :
146 : /* Sequence number is alternating 0x55 and 0xaa. */
147 9 : for (int index = 4; index < 4 + PARTIAL_SEQ_NUM_SIZE; index++) {
148 8 : if (index % 2 == 0) {
149 4 : assert_int_equal(0x55, m_secured_message[index]);
150 : } else {
151 4 : assert_int_equal(0xaa, m_secured_message[index]);
152 : }
153 : }
154 :
155 1 : assert_int_equal(0x0022, libspdm_read_uint16(&m_secured_message[4 + PARTIAL_SEQ_NUM_SIZE]));
156 :
157 1 : ptr = (uint8_t *)&m_secured_message + 6 + PARTIAL_SEQ_NUM_SIZE;
158 :
159 : /* Expected values generated from https://tinyurl.com/2amhw53e */
160 1 : uint8_t expected_cipher_text[] = {0x0d, 0xea, 0x75, 0xea, 0xc6, 0x91, 0x37, 0x49, 0x94, 0x97,
161 : 0x52, 0x63, 0xf8, 0xc0, 0x8f, 0x6c, 0x1a, 0xa4};
162 1 : uint8_t expected_mac[] = {0x0d, 0xcd, 0xb4, 0x8a, 0xd6, 0xfa, 0x24, 0x04, 0x79, 0xd5, 0xd8,
163 : 0xd2, 0xfe, 0x28, 0x19, 0x14};
164 :
165 1 : assert_memory_equal(expected_cipher_text, ptr, sizeof(expected_cipher_text));
166 1 : ptr += sizeof(expected_cipher_text);
167 1 : assert_memory_equal(expected_mac, ptr, sizeof(expected_mac));
168 :
169 : /* Sequence number is incremented by one after operation. */
170 1 : assert_int_equal(0xaa55aa55aa55aa56,
171 : m_secured_message_context.application_secret.request_data_sequence_number);
172 1 : }
173 :
174 : /**
175 : * Test 3: Test basic encryption with sequence number set to all zeroes and big endianness.
176 : * This has the same result as test 1 since the sequence number is all zeroes.
177 : **/
178 1 : static void libspdm_test_secured_message_encode_case3(void **state)
179 : {
180 : libspdm_return_t status;
181 : uint8_t app_message_buffer[sizeof(spdm_secured_message_cipher_header_t) + 16];
182 1 : uint8_t *app_message = app_message_buffer + sizeof(spdm_secured_message_cipher_header_t);
183 1 : size_t secured_message_size = sizeof(m_secured_message);
184 1 : const uint32_t session_id = 0x00112233;
185 : uint8_t *ptr;
186 :
187 1 : initialize_secured_message_context();
188 1 : m_secured_message_context.sequence_number_endian =
189 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_BIG_DEC_BOTH;
190 :
191 17 : for (uint8_t index = 0; index < 16; index++) {
192 16 : app_message[index] = index;
193 : }
194 :
195 1 : status = libspdm_encode_secured_message(
196 : &m_secured_message_context, session_id, true,
197 : sizeof(app_message_buffer) - sizeof(spdm_secured_message_cipher_header_t),
198 : app_message, &secured_message_size, &m_secured_message,
199 : &m_secured_message_callbacks);
200 :
201 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
202 1 : assert_memory_equal(&session_id, &m_secured_message, 4);
203 :
204 : /* Sequence number is all zeroes. */
205 9 : for (int index = 4; index < 4 + PARTIAL_SEQ_NUM_SIZE; index++) {
206 8 : assert_int_equal(0, m_secured_message[index]);
207 : }
208 :
209 1 : assert_int_equal(0x0022, libspdm_read_uint16(&m_secured_message[4 + PARTIAL_SEQ_NUM_SIZE]));
210 :
211 1 : ptr = (uint8_t *)&m_secured_message + 6 + PARTIAL_SEQ_NUM_SIZE;
212 :
213 : /* Expected values generated from https://tinyurl.com/yrx9w78w */
214 1 : uint8_t expected_cipher_text[] = {0x9b, 0xfe, 0xd3, 0xb7, 0x04, 0x3d, 0x32, 0x86, 0x60, 0x3d,
215 : 0x86, 0x17, 0x33, 0xd6, 0x7f, 0x95, 0x9a, 0x20};
216 1 : uint8_t expected_mac[] = {0x3d, 0x4f, 0xac, 0x58, 0xcb, 0x70, 0x6c, 0xf5, 0xa0, 0x27, 0x0a,
217 : 0xf6, 0x73, 0xf0, 0xfe, 0x36};
218 :
219 1 : assert_memory_equal(expected_cipher_text, ptr, sizeof(expected_cipher_text));
220 1 : ptr += sizeof(expected_cipher_text);
221 1 : assert_memory_equal(expected_mac, ptr, sizeof(expected_mac));
222 :
223 : /* Sequence number is incremented by one after operation. */
224 1 : assert_int_equal(1, m_secured_message_context.application_secret.request_data_sequence_number);
225 1 : }
226 :
227 : /**
228 : * Test 4: Test basic encryption with sequence number set to alternating zeroes and ones and
229 : * big endianness.
230 : **/
231 1 : static void libspdm_test_secured_message_encode_case4(void **state)
232 : {
233 : libspdm_return_t status;
234 : uint8_t app_message_buffer[sizeof(spdm_secured_message_cipher_header_t) + 16];
235 1 : uint8_t *app_message = app_message_buffer + sizeof(spdm_secured_message_cipher_header_t);
236 1 : size_t secured_message_size = sizeof(m_secured_message);
237 1 : const uint32_t session_id = 0x00112233;
238 : uint8_t *ptr;
239 :
240 1 : initialize_secured_message_context();
241 1 : m_secured_message_context.application_secret.request_data_sequence_number = 0xaa55aa55aa55aa55;
242 1 : m_secured_message_context.sequence_number_endian =
243 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_BIG_DEC_BOTH;
244 :
245 17 : for (uint8_t index = 0; index < 16; index++) {
246 16 : app_message[index] = index;
247 : }
248 :
249 1 : status = libspdm_encode_secured_message(
250 : &m_secured_message_context, session_id, true,
251 : sizeof(app_message_buffer) - sizeof(spdm_secured_message_cipher_header_t),
252 : app_message, &secured_message_size, &m_secured_message,
253 : &m_secured_message_callbacks);
254 :
255 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
256 1 : assert_memory_equal(&session_id, &m_secured_message, 4);
257 :
258 : /* Sequence number is alternating 0x55 and 0xaa. */
259 9 : for (int index = 4; index < 4 + PARTIAL_SEQ_NUM_SIZE; index++) {
260 8 : if (index % 2 == 0) {
261 4 : assert_int_equal(0x55, m_secured_message[index]);
262 : } else {
263 4 : assert_int_equal(0xaa, m_secured_message[index]);
264 : }
265 : }
266 :
267 1 : assert_int_equal(0x0022, libspdm_read_uint16(&m_secured_message[4 + PARTIAL_SEQ_NUM_SIZE]));
268 :
269 1 : ptr = (uint8_t *)&m_secured_message + 6 + PARTIAL_SEQ_NUM_SIZE;
270 :
271 : /* Expected values generated from https://tinyurl.com/azaw5bab */
272 1 : uint8_t expected_cipher_text[] = {0xf6, 0x4d, 0x6b, 0x94, 0x37, 0x7a, 0x18, 0x61, 0x01, 0xce,
273 : 0xfe, 0xa0, 0x8d, 0x91, 0x79, 0x8a, 0x89, 0x88};
274 1 : uint8_t expected_mac[] = {0xb6, 0x8e, 0xd3, 0x06, 0x4a, 0x95, 0x70, 0x89, 0xd4, 0xd8, 0xb9,
275 : 0x02, 0x9e, 0x9d, 0x72, 0x0b};
276 :
277 1 : assert_memory_equal(expected_cipher_text, ptr, sizeof(expected_cipher_text));
278 1 : ptr += sizeof(expected_cipher_text);
279 1 : assert_memory_equal(expected_mac, ptr, sizeof(expected_mac));
280 :
281 : /* Sequence number is incremented by one after operation. */
282 1 : assert_int_equal(0xaa55aa55aa55aa56,
283 : m_secured_message_context.application_secret.request_data_sequence_number);
284 1 : }
285 :
286 : /**
287 : * Test 5: Test basic decryption with sequence number set to all zeroes and little endianness.
288 : * This uses the same plaintext as test 1.
289 : **/
290 1 : static void libspdm_test_secured_message_encode_case5(void **state)
291 : {
292 : libspdm_return_t status;
293 1 : size_t app_message_size = sizeof(m_app_message);
294 1 : void *app_message = m_app_message;
295 1 : const uint32_t session_id = 0x00112233;
296 :
297 1 : uint8_t secured_message[] = {
298 : /* Session id. */
299 : 0x33, 0x22, 0x11, 0x00,
300 : /* Sequence number. */
301 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302 : /* Total length. */
303 : 0x22, 0x00,
304 : /* Encrypted application data length. */
305 : 0x9b, 0xfe,
306 : /* Encrypted application data. */
307 : 0xd3, 0xb7, 0x04, 0x3d, 0x32, 0x86, 0x60, 0x3d,
308 : 0x86, 0x17, 0x33, 0xd6, 0x7f, 0x95, 0x9a, 0x20,
309 : /* MAC. */
310 : 0x3d, 0x4f, 0xac, 0x58, 0xcb, 0x70, 0x6c, 0xf5,
311 : 0xa0, 0x27, 0x0a, 0xf6, 0x73, 0xf0, 0xfe, 0x36
312 : };
313 :
314 1 : initialize_secured_message_context();
315 1 : m_secured_message_context.sequence_number_endian =
316 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_LITTLE;
317 :
318 1 : libspdm_copy_mem(m_secured_message, sizeof(m_secured_message),
319 : secured_message, sizeof(secured_message));
320 :
321 1 : status = libspdm_decode_secured_message(
322 : &m_secured_message_context, session_id, true,
323 : sizeof(m_secured_message), m_secured_message, &app_message_size, &app_message,
324 : &m_secured_message_callbacks);
325 :
326 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
327 :
328 17 : for (int index = 0; index < 16; index++) {
329 16 : assert_int_equal(index, ((uint8_t *)app_message)[index]);
330 : }
331 :
332 : /* Sequence number is incremented by one after operation. */
333 1 : assert_int_equal(1, m_secured_message_context.application_secret.request_data_sequence_number);
334 1 : }
335 :
336 : /**
337 : * Test 6: Test basic decryption with sequence number set to all zeroes and big endianness.
338 : * This uses the same plaintext as test 1.
339 : **/
340 1 : static void libspdm_test_secured_message_encode_case6(void **state)
341 : {
342 : libspdm_return_t status;
343 1 : size_t app_message_size = sizeof(m_app_message);
344 1 : void *app_message = m_app_message;
345 1 : const uint32_t session_id = 0x00112233;
346 :
347 1 : uint8_t secured_message[] = {
348 : /* Session id. */
349 : 0x33, 0x22, 0x11, 0x00,
350 : /* Sequence number. */
351 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 : /* Total length. */
353 : 0x22, 0x00,
354 : /* Encrypted application data length. */
355 : 0x9b, 0xfe,
356 : /* Encrypted application data. */
357 : 0xd3, 0xb7, 0x04, 0x3d, 0x32, 0x86, 0x60, 0x3d,
358 : 0x86, 0x17, 0x33, 0xd6, 0x7f, 0x95, 0x9a, 0x20,
359 : /* MAC. */
360 : 0x3d, 0x4f, 0xac, 0x58, 0xcb, 0x70, 0x6c, 0xf5,
361 : 0xa0, 0x27, 0x0a, 0xf6, 0x73, 0xf0, 0xfe, 0x36
362 : };
363 :
364 1 : initialize_secured_message_context();
365 1 : m_secured_message_context.sequence_number_endian =
366 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_BIG_DEC_BIG;
367 :
368 1 : libspdm_copy_mem(m_secured_message, sizeof(m_secured_message),
369 : secured_message, sizeof(secured_message));
370 :
371 1 : status = libspdm_decode_secured_message(
372 : &m_secured_message_context, session_id, true,
373 : sizeof(m_secured_message), m_secured_message, &app_message_size, &app_message,
374 : &m_secured_message_callbacks);
375 :
376 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
377 :
378 17 : for (int index = 0; index < 16; index++) {
379 16 : assert_int_equal(index, ((uint8_t *)app_message)[index]);
380 : }
381 :
382 : /* Sequence number is incremented by one after operation. */
383 1 : assert_int_equal(1, m_secured_message_context.application_secret.request_data_sequence_number);
384 1 : }
385 :
386 : /**
387 : * Test 7: Test try-fail decryption.
388 : * The message is encrypted with big-endian sequence number but decoder is set to try
389 : * little-endian first. The first decryption with sequence number == 0 will pass regardless
390 : * of endianness. Endianness will be detected when sequence number == 1.
391 : * This uses the same plaintext as test 1.
392 : **/
393 1 : static void libspdm_test_secured_message_encode_case7(void **state)
394 : {
395 : libspdm_return_t status;
396 1 : size_t app_message_size = sizeof(m_app_message);
397 1 : void *app_message = m_app_message;
398 1 : const uint32_t session_id = 0x00112233;
399 :
400 1 : uint8_t secured_message_0[] = {
401 : /* Session id. */
402 : 0x33, 0x22, 0x11, 0x00,
403 : /* Sequence number. */
404 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 : /* Total length. */
406 : 0x22, 0x00,
407 : /* Encrypted application data length. */
408 : 0x9b, 0xfe,
409 : /* Encrypted application data. */
410 : 0xd3, 0xb7, 0x04, 0x3d, 0x32, 0x86, 0x60, 0x3d,
411 : 0x86, 0x17, 0x33, 0xd6, 0x7f, 0x95, 0x9a, 0x20,
412 : /* MAC. */
413 : 0x3d, 0x4f, 0xac, 0x58, 0xcb, 0x70, 0x6c, 0xf5,
414 : 0xa0, 0x27, 0x0a, 0xf6, 0x73, 0xf0, 0xfe, 0x36
415 : };
416 :
417 1 : initialize_secured_message_context();
418 1 : m_secured_message_context.sequence_number_endian =
419 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_BOTH;
420 :
421 1 : libspdm_copy_mem(m_secured_message, sizeof(m_secured_message),
422 : secured_message_0, sizeof(secured_message_0));
423 :
424 1 : status = libspdm_decode_secured_message(
425 : &m_secured_message_context, session_id, true,
426 : sizeof(m_secured_message), m_secured_message, &app_message_size, &app_message,
427 : &m_secured_message_callbacks);
428 :
429 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
430 :
431 17 : for (int index = 0; index < 16; index++) {
432 16 : assert_int_equal(index, ((uint8_t *)app_message)[index]);
433 : }
434 :
435 : /* Sequence number is incremented by one after operation. */
436 1 : assert_int_equal(0x1,
437 : m_secured_message_context.application_secret.request_data_sequence_number);
438 :
439 : /* Context should stay undetermined. */
440 1 : assert_int_equal(LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_BOTH,
441 : m_secured_message_context.sequence_number_endian);
442 :
443 : /* Increment sequence number to 1. The endianness can now be determined.
444 : * Generated from https://tinyurl.com/yztzj7f4 */
445 1 : uint8_t secured_message_1[] = {
446 : /* Session id. */
447 : 0x33, 0x22, 0x11, 0x00,
448 : /* Sequence number. */
449 : 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 : /* Total length. */
451 : 0x22, 0x00,
452 : /* Encrypted application data length. */
453 : 0x07, 0x82,
454 : /* Encrypted application data. */
455 : 0x8a, 0x2d, 0xb9, 0xbf, 0x37, 0x87, 0x0f, 0xc5,
456 : 0xb1, 0xe9, 0xb7, 0x03, 0xee, 0x1d, 0x14, 0xb4,
457 : /* MAC. */
458 : 0x50, 0xa1, 0x5c, 0x3e, 0xee, 0x27, 0x8f, 0xed,
459 : 0xed, 0xa6, 0x86, 0xaf, 0x31, 0x07, 0xd8, 0x6f
460 : };
461 :
462 1 : libspdm_copy_mem(m_secured_message, sizeof(m_secured_message),
463 : secured_message_1, sizeof(secured_message_1));
464 :
465 1 : app_message_size = sizeof(m_app_message);
466 1 : app_message = m_app_message;
467 :
468 1 : status = libspdm_decode_secured_message(
469 : &m_secured_message_context, session_id, true,
470 : sizeof(m_secured_message), m_secured_message, &app_message_size, &app_message,
471 : &m_secured_message_callbacks);
472 :
473 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
474 :
475 17 : for (int index = 0; index < 16; index++) {
476 16 : assert_int_equal(index, ((uint8_t *)app_message)[index]);
477 : }
478 :
479 : /* Sequence number is incremented by one after operation. */
480 1 : assert_int_equal(0x2,
481 : m_secured_message_context.application_secret.request_data_sequence_number);
482 :
483 : /* Context should change to big-endian only. */
484 1 : assert_int_equal(LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_BIG_DEC_BIG,
485 : m_secured_message_context.sequence_number_endian);
486 1 : }
487 :
488 : /**
489 : * Test 8: Test try-fail decryption.
490 : * The message is encrypted with little-endian sequence number but decoder is set to try
491 : * big-endian first. The first decryption with sequence number == 0 will pass regardless
492 : * of endianness. Endianness will be detected when sequence number == 1.
493 : * This uses the same plaintext as test 1.
494 : **/
495 1 : static void libspdm_test_secured_message_encode_case8(void **state)
496 : {
497 : libspdm_return_t status;
498 1 : size_t app_message_size = sizeof(m_app_message);
499 1 : void *app_message = m_app_message;
500 1 : const uint32_t session_id = 0x00112233;
501 :
502 1 : uint8_t secured_message_0[] = {
503 : /* Session id. */
504 : 0x33, 0x22, 0x11, 0x00,
505 : /* Sequence number. */
506 : 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 : /* Total length. */
508 : 0x22, 0x00,
509 : /* Encrypted application data length. */
510 : 0x9b, 0xfe,
511 : /* Encrypted application data. */
512 : 0xd3, 0xb7, 0x04, 0x3d, 0x32, 0x86, 0x60, 0x3d,
513 : 0x86, 0x17, 0x33, 0xd6, 0x7f, 0x95, 0x9a, 0x20,
514 : /* MAC. */
515 : 0x3d, 0x4f, 0xac, 0x58, 0xcb, 0x70, 0x6c, 0xf5,
516 : 0xa0, 0x27, 0x0a, 0xf6, 0x73, 0xf0, 0xfe, 0x36
517 : };
518 :
519 1 : initialize_secured_message_context();
520 1 : m_secured_message_context.sequence_number_endian =
521 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_BIG_DEC_BOTH;
522 :
523 1 : libspdm_copy_mem(m_secured_message, sizeof(m_secured_message),
524 : secured_message_0, sizeof(secured_message_0));
525 :
526 1 : status = libspdm_decode_secured_message(
527 : &m_secured_message_context, session_id, true,
528 : sizeof(m_secured_message), m_secured_message, &app_message_size, &app_message,
529 : &m_secured_message_callbacks);
530 :
531 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
532 :
533 17 : for (int index = 0; index < 16; index++) {
534 16 : assert_int_equal(index, ((uint8_t *)app_message)[index]);
535 : }
536 :
537 : /* Sequence number is incremented by one after operation. */
538 1 : assert_int_equal(0x1,
539 : m_secured_message_context.application_secret.request_data_sequence_number);
540 :
541 : /* Context should stay undetermined. */
542 1 : assert_int_equal(LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_BIG_DEC_BOTH,
543 : m_secured_message_context.sequence_number_endian);
544 :
545 : /* Increment sequence number to 1. The endianness can now be determined. */
546 1 : uint8_t secured_message_1[] = {
547 : /* Session id. */
548 : 0x33, 0x22, 0x11, 0x00,
549 : /* Sequence number. */
550 : 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551 : /* Total length. */
552 : 0x22, 0x00,
553 : /* Encrypted application data length. */
554 : 0xf4, 0x19,
555 : /* Encrypted application data. */
556 : 0x96, 0xdc, 0xc6, 0x78, 0x5e, 0x8c, 0x74, 0x72,
557 : 0x59, 0xf4, 0x27, 0x22, 0xb9, 0x1b, 0x1f, 0x56,
558 : /* MAC. */
559 : 0x1d, 0xca, 0x9f, 0x09, 0xd8, 0x80, 0x3a, 0x9a,
560 : 0x54, 0x8e, 0xf0, 0x9b, 0x53, 0xb9, 0xab, 0x1f
561 : };
562 :
563 1 : libspdm_copy_mem(m_secured_message, sizeof(m_secured_message),
564 : secured_message_1, sizeof(secured_message_1));
565 :
566 1 : app_message_size = sizeof(m_app_message);
567 1 : app_message = m_app_message;
568 :
569 1 : status = libspdm_decode_secured_message(
570 : &m_secured_message_context, session_id, true,
571 : sizeof(m_secured_message), m_secured_message, &app_message_size, &app_message,
572 : &m_secured_message_callbacks);
573 :
574 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
575 :
576 17 : for (int index = 0; index < 16; index++) {
577 16 : assert_int_equal(index, ((uint8_t *)app_message)[index]);
578 : }
579 :
580 : /* Sequence number is incremented by one after operation. */
581 1 : assert_int_equal(0x2,
582 : m_secured_message_context.application_secret.request_data_sequence_number);
583 :
584 : /* Context should change to little-endian only. */
585 1 : assert_int_equal(LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_LITTLE,
586 : m_secured_message_context.sequence_number_endian);
587 1 : }
588 :
589 : /**
590 : * Test 9: Test basic encryption with sequence number set to alternating zeroes and ones
591 : * encode : little endianness.
592 : * decode : little endianness.
593 : **/
594 1 : static void libspdm_test_secured_message_encode_case9(void **state) {
595 : libspdm_return_t status;
596 : uint8_t encode_buffer[sizeof(spdm_secured_message_cipher_header_t) + 16];
597 1 : uint8_t *encode_app_message = encode_buffer + sizeof(spdm_secured_message_cipher_header_t);
598 1 : size_t secured_message_size = sizeof(m_secured_message);
599 : libspdm_secured_message_context_t encode_secured_message_context;
600 :
601 1 : const uint32_t session_id = 0x00112233;
602 :
603 1 : initialize_secured_message_context();
604 1 : libspdm_copy_mem(&encode_secured_message_context, sizeof(encode_secured_message_context),
605 : &m_secured_message_context, sizeof(m_secured_message_context));
606 1 : m_secured_message_context.sequence_number_endian =
607 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_BOTH;
608 1 : encode_secured_message_context.application_secret.request_data_sequence_number =
609 : 0xaa55aa55aa55aa55;
610 :
611 17 : for (uint8_t index = 0; index < 16; index++) {
612 16 : encode_app_message[index] = index;
613 : }
614 :
615 1 : libspdm_zero_mem(m_secured_message, sizeof(m_secured_message));
616 1 : status = libspdm_encode_secured_message(
617 : &encode_secured_message_context, session_id, true,
618 : sizeof(encode_buffer) - sizeof(spdm_secured_message_cipher_header_t),
619 : encode_app_message, &secured_message_size, m_secured_message,
620 : &m_secured_message_callbacks);
621 :
622 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
623 1 : assert_memory_equal(&session_id, m_secured_message, 4);
624 :
625 : /* Sequence number is alternating 0x55 and 0xaa. */
626 9 : for (int index = 4; index < 4 + PARTIAL_SEQ_NUM_SIZE; index++) {
627 8 : if (index % 2 == 0) {
628 4 : assert_int_equal(0x55, m_secured_message[index]);
629 : } else {
630 4 : assert_int_equal(0xaa, m_secured_message[index]);
631 : }
632 : }
633 :
634 1 : assert_int_equal(0x0022, libspdm_read_uint16(&m_secured_message[4 + PARTIAL_SEQ_NUM_SIZE]));
635 1 : assert_int_equal(0xaa55aa55aa55aa56,
636 : encode_secured_message_context.application_secret.request_data_sequence_number);
637 :
638 1 : void *decode_app_message = m_app_message;
639 1 : size_t decode_app_message_size = sizeof(m_app_message);
640 : libspdm_secured_message_context_t decode_secured_message_context;
641 :
642 1 : initialize_secured_message_context();
643 1 : libspdm_copy_mem(&decode_secured_message_context, sizeof(decode_secured_message_context),
644 : &m_secured_message_context, sizeof(m_secured_message_context));
645 1 : decode_secured_message_context.sequence_number_endian =
646 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_LITTLE;
647 1 : decode_secured_message_context.application_secret.request_data_sequence_number =
648 : 0xaa55aa55aa55aa55;
649 :
650 1 : status = libspdm_decode_secured_message(
651 : &decode_secured_message_context, session_id, true,
652 : sizeof(m_secured_message), m_secured_message, &decode_app_message_size, &decode_app_message,
653 : &m_secured_message_callbacks);
654 :
655 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
656 :
657 17 : for (int index = 0; index < 16; index++) {
658 16 : assert_int_equal(index, ((uint8_t *)decode_app_message)[index]);
659 : }
660 :
661 : /* Sequence number is incremented by one after operation. */
662 1 : assert_int_equal(0xaa55aa55aa55aa56,
663 : decode_secured_message_context.application_secret.request_data_sequence_number);
664 1 : }
665 :
666 : /**
667 : * Test 10: Test basic encryption with sequence number one and little endianness.
668 : * encode : big endianness.
669 : * decode : little endianness.
670 : **/
671 1 : static void libspdm_test_secured_message_encode_case10(void **state)
672 : {
673 : libspdm_return_t status;
674 : uint8_t encode_buffer[sizeof(spdm_secured_message_cipher_header_t) + 16];
675 1 : uint8_t *encode_app_message = encode_buffer + sizeof(spdm_secured_message_cipher_header_t);
676 1 : size_t secured_message_size = sizeof(m_secured_message);
677 : libspdm_secured_message_context_t encode_secured_message_context;
678 :
679 1 : const uint32_t session_id = 0x00112233;
680 :
681 1 : initialize_secured_message_context();
682 1 : libspdm_copy_mem(&encode_secured_message_context, sizeof(encode_secured_message_context),
683 : &m_secured_message_context, sizeof(m_secured_message_context));
684 :
685 1 : encode_secured_message_context.sequence_number_endian =
686 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_BIG_DEC_BOTH;
687 1 : encode_secured_message_context.application_secret.request_data_sequence_number =
688 : 0x0000000000000001;
689 :
690 17 : for (uint8_t index = 0; index < 16; index++) {
691 16 : encode_app_message[index] = index;
692 : }
693 :
694 1 : libspdm_zero_mem(m_secured_message, sizeof(m_secured_message));
695 1 : status = libspdm_encode_secured_message(
696 : &encode_secured_message_context, session_id, true,
697 : sizeof(encode_buffer) - sizeof(spdm_secured_message_cipher_header_t),
698 : encode_app_message, &secured_message_size, m_secured_message,
699 : &m_secured_message_callbacks);
700 :
701 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
702 1 : assert_memory_equal(&session_id, m_secured_message, 4);
703 :
704 9 : for (int index = 4; index < 4 + PARTIAL_SEQ_NUM_SIZE; index++) {
705 8 : if (index == 4) {
706 1 : assert_int_equal(0x01, m_secured_message[index]);
707 : } else {
708 7 : assert_int_equal(0x00, m_secured_message[index]);
709 : }
710 : }
711 :
712 1 : assert_int_equal(0x0022, libspdm_read_uint16(&m_secured_message[4 + PARTIAL_SEQ_NUM_SIZE]));
713 1 : assert_int_equal(0x000000000000002,
714 : encode_secured_message_context.application_secret.request_data_sequence_number);
715 :
716 1 : void *decode_app_message = m_app_message;
717 1 : size_t decode_app_message_size = sizeof(m_app_message);
718 : libspdm_secured_message_context_t decode_secured_message_context;
719 :
720 1 : libspdm_copy_mem(&decode_secured_message_context, sizeof(decode_secured_message_context),
721 : &m_secured_message_context, sizeof(m_secured_message_context));
722 1 : decode_secured_message_context.application_secret.request_data_sequence_number =
723 : 0x0000000000000001;
724 1 : decode_secured_message_context.sequence_number_endian =
725 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_BOTH;
726 :
727 1 : status = libspdm_decode_secured_message(
728 : &decode_secured_message_context, session_id, true,
729 : sizeof(m_secured_message), m_secured_message, &decode_app_message_size, &decode_app_message,
730 : &m_secured_message_callbacks);
731 :
732 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
733 :
734 17 : for (int index = 0; index < 16; index++) {
735 16 : assert_int_equal(index, ((uint8_t *)decode_app_message)[index]);
736 : }
737 :
738 : /* Sequence number is incremented by one after operation. */
739 1 : assert_int_equal(0x0000000000000002,
740 : decode_secured_message_context.application_secret.request_data_sequence_number);
741 1 : }
742 :
743 : /**
744 : * Test 11: Test a message authentication only session with the sequence number set to zeroes and ones.
745 : * encode : big endianness.
746 : * decode : big endianness.
747 : **/
748 1 : static void libspdm_test_secured_message_encode_case11(void **state)
749 : {
750 : libspdm_return_t status;
751 : uint8_t encode_app_message[16];
752 1 : size_t secured_message_size = sizeof(m_secured_message);
753 : libspdm_secured_message_context_t encode_secured_message_context;
754 :
755 1 : const uint32_t session_id = 0x00112233;
756 : uint8_t *ptr;
757 :
758 1 : initialize_secured_message_context();
759 1 : libspdm_copy_mem(&encode_secured_message_context, sizeof(encode_secured_message_context),
760 : &m_secured_message_context, sizeof(encode_secured_message_context));
761 :
762 1 : encode_secured_message_context.sequence_number_endian =
763 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_BIG_DEC_BOTH;
764 1 : encode_secured_message_context.session_type = LIBSPDM_SESSION_TYPE_MAC_ONLY;
765 1 : encode_secured_message_context.application_secret.request_data_sequence_number =
766 : 0xaa55aa55aa55aa55;
767 :
768 17 : for (uint8_t index = 0; index < 16; index++) {
769 16 : encode_app_message[index] = index;
770 : }
771 :
772 1 : libspdm_zero_mem(m_secured_message, sizeof(m_secured_message));
773 1 : status = libspdm_encode_secured_message(
774 : &encode_secured_message_context, session_id, true,
775 : sizeof(encode_app_message), encode_app_message, &secured_message_size, m_secured_message,
776 : &m_secured_message_callbacks);
777 :
778 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
779 1 : assert_memory_equal(&session_id, m_secured_message, 4);
780 :
781 : /* Sequence number is alternating 0x55 and 0xaa. */
782 9 : for (int index = 4; index < 4 + PARTIAL_SEQ_NUM_SIZE; index++) {
783 8 : if (index % 2 == 0) {
784 4 : assert_int_equal(0x55, m_secured_message[index]);
785 : } else {
786 4 : assert_int_equal(0xaa, m_secured_message[index]);
787 : }
788 : }
789 :
790 1 : assert_int_equal(0x0020, libspdm_read_uint16(&m_secured_message[4 + PARTIAL_SEQ_NUM_SIZE]));
791 1 : assert_int_equal(0xaa55aa55aa55aa56,
792 : encode_secured_message_context.application_secret.request_data_sequence_number);
793 :
794 1 : ptr = (uint8_t *)&m_secured_message + 6 + PARTIAL_SEQ_NUM_SIZE;
795 17 : for (int index = 0; index < 16; index++) {
796 16 : assert_int_equal(index, ((uint8_t *)ptr)[index]);
797 : }
798 :
799 1 : void *decode_app_message = m_app_message;
800 1 : size_t decode_app_message_size = sizeof(m_app_message);
801 : libspdm_secured_message_context_t decode_secured_message_context;
802 1 : libspdm_copy_mem(
803 : &decode_secured_message_context, sizeof(encode_secured_message_context),
804 : &m_secured_message_context, sizeof(m_secured_message_context));
805 :
806 1 : decode_secured_message_context.sequence_number_endian =
807 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_BIG_DEC_BOTH;
808 1 : decode_secured_message_context.session_type = LIBSPDM_SESSION_TYPE_MAC_ONLY;
809 1 : decode_secured_message_context.application_secret.request_data_sequence_number =
810 : 0xaa55aa55aa55aa55;
811 :
812 1 : status = libspdm_decode_secured_message(
813 : &decode_secured_message_context, session_id, true,
814 : sizeof(m_secured_message), m_secured_message, &decode_app_message_size, &decode_app_message,
815 : &m_secured_message_callbacks);
816 :
817 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
818 :
819 17 : for (int index = 0; index < 16; index++) {
820 16 : assert_int_equal(index, ((uint8_t *)decode_app_message)[index]);
821 : }
822 :
823 : /* Sequence number is incremented by one after operation. */
824 1 : assert_int_equal(0xaa55aa55aa55aa56,
825 : decode_secured_message_context.application_secret.request_data_sequence_number);
826 1 : }
827 :
828 : /**
829 : * Test 12: Test a message authentication only session with the sequence number one.
830 : * encode : little endianness.
831 : * decode : big endianness.
832 : **/
833 1 : static void libspdm_test_secured_message_encode_case12(void **state)
834 : {
835 : libspdm_return_t status;
836 : uint8_t encode_app_message[16];
837 1 : size_t secured_message_size = sizeof(m_secured_message);
838 : libspdm_secured_message_context_t encode_secured_message_context;
839 :
840 1 : const uint32_t session_id = 0x00112233;
841 : uint8_t *ptr;
842 :
843 1 : initialize_secured_message_context();
844 1 : libspdm_copy_mem(&encode_secured_message_context, sizeof(encode_secured_message_context),
845 : &m_secured_message_context, sizeof(encode_secured_message_context));
846 :
847 1 : encode_secured_message_context.sequence_number_endian =
848 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_BOTH;
849 1 : encode_secured_message_context.session_type = LIBSPDM_SESSION_TYPE_MAC_ONLY;
850 1 : encode_secured_message_context.application_secret.request_data_sequence_number =
851 : 0x0000000000000001;
852 :
853 17 : for (uint8_t index = 0; index < 16; index++) {
854 16 : encode_app_message[index] = index;
855 : }
856 :
857 1 : libspdm_zero_mem(m_secured_message, sizeof(m_secured_message));
858 1 : status = libspdm_encode_secured_message(
859 : &encode_secured_message_context, session_id, true,
860 : sizeof(encode_app_message), encode_app_message, &secured_message_size, m_secured_message,
861 : &m_secured_message_callbacks);
862 :
863 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
864 1 : assert_memory_equal(&session_id, m_secured_message, 4);
865 :
866 : /* Sequence number is alternating 0x55 and 0xaa. */
867 9 : for (int index = 4; index < 4 + PARTIAL_SEQ_NUM_SIZE; index++) {
868 8 : if (index == 4) {
869 1 : assert_int_equal(0x01, m_secured_message[index]);
870 : } else {
871 7 : assert_int_equal(0x00, m_secured_message[index]);
872 : }
873 : }
874 :
875 1 : assert_int_equal(0x0020, libspdm_read_uint16(&m_secured_message[4 + PARTIAL_SEQ_NUM_SIZE]));
876 1 : assert_int_equal(0x0000000000000002,
877 : encode_secured_message_context.application_secret.request_data_sequence_number);
878 :
879 1 : ptr = (uint8_t *)&m_secured_message + 6 + PARTIAL_SEQ_NUM_SIZE;
880 17 : for (int index = 0; index < 16; index++) {
881 16 : assert_int_equal(index, ((uint8_t *)ptr)[index]);
882 : }
883 :
884 1 : void *decode_app_message = m_app_message;
885 1 : size_t decode_app_message_size = sizeof(m_app_message);
886 : libspdm_secured_message_context_t decode_secured_message_context;
887 1 : libspdm_copy_mem(
888 : &decode_secured_message_context, sizeof(encode_secured_message_context),
889 : &m_secured_message_context, sizeof(m_secured_message_context));
890 :
891 1 : decode_secured_message_context.sequence_number_endian =
892 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_BIG_DEC_BOTH;
893 1 : decode_secured_message_context.session_type = LIBSPDM_SESSION_TYPE_MAC_ONLY;
894 1 : decode_secured_message_context.application_secret.request_data_sequence_number =
895 : 0x0000000000000001;
896 :
897 1 : status = libspdm_decode_secured_message(
898 : &decode_secured_message_context, session_id, true,
899 : sizeof(m_secured_message), m_secured_message, &decode_app_message_size, &decode_app_message,
900 : &m_secured_message_callbacks);
901 :
902 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
903 :
904 17 : for (int index = 0; index < 16; index++) {
905 16 : assert_int_equal(index, ((uint8_t *)decode_app_message)[index]);
906 : }
907 :
908 : /* Sequence number is incremented by one after operation. */
909 1 : assert_int_equal(0x0000000000000002,
910 : decode_secured_message_context.application_secret.request_data_sequence_number);
911 1 : }
912 :
913 : /**
914 : * Test 13: A peer-crafted ENC_MAC record whose decrypted application_data_length equals
915 : * cipher_text_size leaves no room for the 2-byte cipher header, so the reported
916 : * payload would run past the decrypted plaintext. Decoding must reject it.
917 : **/
918 1 : static void libspdm_test_secured_message_encode_case13(void **state)
919 : {
920 : libspdm_return_t status;
921 : bool result;
922 1 : size_t app_message_size = sizeof(m_app_message);
923 1 : void *app_message = m_app_message;
924 1 : const uint32_t session_id = 0x00112233;
925 1 : const size_t record_header_size = 4 + PARTIAL_SEQ_NUM_SIZE + 2;
926 1 : const size_t cipher_text_size = 48;
927 1 : const size_t tag_size = 16;
928 : uint8_t plain_text[48];
929 : uint8_t iv[LIBSPDM_MAX_AEAD_IV_SIZE];
930 1 : size_t cipher_out_size = cipher_text_size;
931 :
932 1 : initialize_secured_message_context();
933 1 : m_secured_message_context.sequence_number_endian =
934 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_LITTLE;
935 :
936 : /* Forge a plaintext whose length field claims the entire ciphertext as payload,
937 : * leaving no room for the cipher header. */
938 1 : libspdm_zero_mem(plain_text, sizeof(plain_text));
939 1 : libspdm_write_uint16(plain_text, (uint16_t)cipher_text_size);
940 :
941 : /* Build the record header, which also serves as the AEAD additional data. */
942 1 : libspdm_zero_mem(m_secured_message, sizeof(m_secured_message));
943 1 : libspdm_write_uint32(m_secured_message, session_id);
944 1 : libspdm_write_uint16(m_secured_message + record_header_size - 2,
945 1 : (uint16_t)(cipher_text_size + tag_size));
946 :
947 : /* Sequence number zero means the IV is just the salt. */
948 1 : libspdm_zero_mem(iv, sizeof(iv));
949 1 : libspdm_copy_mem(iv, sizeof(iv),
950 : m_secured_message_context.application_secret.request_data_salt,
951 : m_secured_message_context.aead_iv_size);
952 :
953 1 : result = libspdm_aead_encryption(
954 1 : m_secured_message_context.secured_message_version,
955 1 : m_secured_message_context.aead_cipher_suite,
956 : m_secured_message_context.application_secret.request_data_encryption_key,
957 : m_secured_message_context.aead_key_size, iv,
958 : m_secured_message_context.aead_iv_size, m_secured_message, record_header_size,
959 : plain_text, cipher_text_size,
960 1 : m_secured_message + record_header_size + cipher_text_size, tag_size,
961 : m_secured_message + record_header_size, &cipher_out_size);
962 1 : assert_true(result);
963 :
964 1 : status = libspdm_decode_secured_message(
965 : &m_secured_message_context, session_id, true,
966 1 : record_header_size + cipher_text_size + tag_size, m_secured_message,
967 : &app_message_size, &app_message, &m_secured_message_callbacks);
968 :
969 1 : assert_int_equal(LIBSPDM_STATUS_INVALID_MSG_SIZE, status);
970 1 : }
971 :
972 : /**
973 : * Test 14: A higher minor version with the same major version is accepted.
974 : **/
975 1 : static void libspdm_test_secured_message_encode_case14(void **state)
976 : {
977 : libspdm_return_t status;
978 : uint8_t app_message_buffer[sizeof(spdm_secured_message_cipher_header_t) + 16];
979 1 : uint8_t *app_message = app_message_buffer + sizeof(spdm_secured_message_cipher_header_t);
980 1 : size_t secured_message_size = sizeof(m_secured_message);
981 1 : const uint32_t session_id = 0x00112233;
982 :
983 1 : initialize_secured_message_context();
984 : /* Major version 1, minor version 15. */
985 1 : m_secured_message_context.secured_message_version = 0x1f << SPDM_VERSION_NUMBER_SHIFT_BIT;
986 :
987 17 : for (uint8_t index = 0; index < 16; index++) {
988 16 : app_message[index] = index;
989 : }
990 :
991 1 : status = libspdm_encode_secured_message(
992 : &m_secured_message_context, session_id, true,
993 : sizeof(app_message_buffer) - sizeof(spdm_secured_message_cipher_header_t),
994 : app_message, &secured_message_size, &m_secured_message,
995 : &m_secured_message_callbacks);
996 :
997 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
998 1 : }
999 :
1000 : /**
1001 : * Test 15: A higher major version is rejected.
1002 : **/
1003 1 : static void libspdm_test_secured_message_encode_case15(void **state)
1004 : {
1005 : libspdm_return_t status;
1006 : uint8_t app_message[16];
1007 1 : size_t secured_message_size = sizeof(m_secured_message);
1008 1 : const uint32_t session_id = 0x00112233;
1009 :
1010 1 : initialize_secured_message_context();
1011 : /* Major version 2, minor version 0. */
1012 1 : m_secured_message_context.secured_message_version = 0x20 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1013 :
1014 17 : for (uint8_t index = 0; index < 16; index++) {
1015 16 : app_message[index] = index;
1016 : }
1017 :
1018 1 : status = libspdm_encode_secured_message(
1019 : &m_secured_message_context, session_id, true,
1020 : sizeof(app_message), app_message, &secured_message_size, &m_secured_message,
1021 : &m_secured_message_callbacks);
1022 :
1023 1 : assert_int_equal(LIBSPDM_STATUS_UNSUPPORTED_CAP, status);
1024 1 : }
1025 :
1026 : /**
1027 : * Test 16: A higher minor version with the same major version is accepted on decode.
1028 : **/
1029 1 : static void libspdm_test_secured_message_decode_case16(void **state)
1030 : {
1031 : libspdm_return_t status;
1032 : uint8_t encode_buffer[sizeof(spdm_secured_message_cipher_header_t) + 16];
1033 1 : uint8_t *encode_app_message = encode_buffer + sizeof(spdm_secured_message_cipher_header_t);
1034 1 : size_t secured_message_size = sizeof(m_secured_message);
1035 : libspdm_secured_message_context_t encode_secured_message_context;
1036 1 : void *decode_app_message = m_app_message;
1037 1 : size_t decode_app_message_size = sizeof(m_app_message);
1038 : libspdm_secured_message_context_t decode_secured_message_context;
1039 1 : const uint32_t session_id = 0x00112233;
1040 :
1041 1 : initialize_secured_message_context();
1042 : /* Major version 1, minor version 15. */
1043 1 : m_secured_message_context.secured_message_version = 0x1f << SPDM_VERSION_NUMBER_SHIFT_BIT;
1044 :
1045 1 : libspdm_copy_mem(&encode_secured_message_context, sizeof(encode_secured_message_context),
1046 : &m_secured_message_context, sizeof(m_secured_message_context));
1047 1 : encode_secured_message_context.sequence_number_endian =
1048 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_LITTLE;
1049 :
1050 17 : for (uint8_t index = 0; index < 16; index++) {
1051 16 : encode_app_message[index] = index;
1052 : }
1053 :
1054 1 : libspdm_zero_mem(m_secured_message, sizeof(m_secured_message));
1055 1 : status = libspdm_encode_secured_message(
1056 : &encode_secured_message_context, session_id, true,
1057 : sizeof(encode_buffer) - sizeof(spdm_secured_message_cipher_header_t),
1058 : encode_app_message, &secured_message_size, m_secured_message,
1059 : &m_secured_message_callbacks);
1060 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
1061 :
1062 1 : libspdm_copy_mem(&decode_secured_message_context, sizeof(decode_secured_message_context),
1063 : &m_secured_message_context, sizeof(m_secured_message_context));
1064 1 : decode_secured_message_context.sequence_number_endian =
1065 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_LITTLE;
1066 :
1067 1 : status = libspdm_decode_secured_message(
1068 : &decode_secured_message_context, session_id, true,
1069 : sizeof(m_secured_message), m_secured_message, &decode_app_message_size, &decode_app_message,
1070 : &m_secured_message_callbacks);
1071 :
1072 1 : assert_int_equal(LIBSPDM_STATUS_SUCCESS, status);
1073 :
1074 17 : for (int index = 0; index < 16; index++) {
1075 16 : assert_int_equal(index, ((uint8_t *)decode_app_message)[index]);
1076 : }
1077 1 : }
1078 :
1079 : /**
1080 : * Test 17: A higher major version is rejected on decode.
1081 : **/
1082 1 : static void libspdm_test_secured_message_decode_case17(void **state)
1083 : {
1084 : libspdm_return_t status;
1085 1 : size_t app_message_size = sizeof(m_app_message);
1086 1 : void *app_message = m_app_message;
1087 1 : const uint32_t session_id = 0x00112233;
1088 :
1089 1 : initialize_secured_message_context();
1090 : /* Major version 2, minor version 0. */
1091 1 : m_secured_message_context.secured_message_version = 0x20 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1092 :
1093 1 : libspdm_zero_mem(m_secured_message, sizeof(m_secured_message));
1094 1 : status = libspdm_decode_secured_message(
1095 : &m_secured_message_context, session_id, true,
1096 : sizeof(m_secured_message), m_secured_message, &app_message_size, &app_message,
1097 : &m_secured_message_callbacks);
1098 :
1099 1 : assert_int_equal(LIBSPDM_STATUS_UNSUPPORTED_CAP, status);
1100 1 : }
1101 :
1102 : libspdm_test_context_t m_libspdm_common_context_data_test_context = {
1103 : LIBSPDM_TEST_CONTEXT_VERSION,
1104 : true,
1105 : NULL,
1106 : NULL,
1107 : };
1108 :
1109 1 : int libspdm_secured_message_encode_decode_test_main(void)
1110 : {
1111 1 : const struct CMUnitTest spdm_secured_message_encode_decode_tests[] = {
1112 : cmocka_unit_test(libspdm_test_secured_message_encode_case1),
1113 : cmocka_unit_test(libspdm_test_secured_message_encode_case2),
1114 : cmocka_unit_test(libspdm_test_secured_message_encode_case3),
1115 : cmocka_unit_test(libspdm_test_secured_message_encode_case4),
1116 : cmocka_unit_test(libspdm_test_secured_message_encode_case5),
1117 : cmocka_unit_test(libspdm_test_secured_message_encode_case6),
1118 : cmocka_unit_test(libspdm_test_secured_message_encode_case7),
1119 : cmocka_unit_test(libspdm_test_secured_message_encode_case8),
1120 : cmocka_unit_test(libspdm_test_secured_message_encode_case9),
1121 : cmocka_unit_test(libspdm_test_secured_message_encode_case10),
1122 : cmocka_unit_test(libspdm_test_secured_message_encode_case11),
1123 : cmocka_unit_test(libspdm_test_secured_message_encode_case12),
1124 : cmocka_unit_test(libspdm_test_secured_message_encode_case13),
1125 : cmocka_unit_test(libspdm_test_secured_message_encode_case14),
1126 : cmocka_unit_test(libspdm_test_secured_message_encode_case15),
1127 : cmocka_unit_test(libspdm_test_secured_message_decode_case16),
1128 : cmocka_unit_test(libspdm_test_secured_message_decode_case17),
1129 : };
1130 :
1131 1 : libspdm_setup_test_context(&m_libspdm_common_context_data_test_context);
1132 :
1133 1 : return cmocka_run_group_tests(spdm_secured_message_encode_decode_tests,
1134 : libspdm_unit_test_group_setup,
1135 : libspdm_unit_test_group_teardown);
1136 : }
1137 :
1138 : #endif /* LIBSPDM_AEAD_AES_256_GCM_SUPPORT */
|