LCOV - code coverage report
Current view: top level - unit_test/test_spdm_secured_message - encode_decode.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 417 417
Test Date: 2026-08-16 08:12:25 Functions: 100.0 % 22 22

            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 */
        

Generated by: LCOV version 2.0-1