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