LCOV - code coverage report
Current view: top level - unit_test/test_spdm_requester/error_test - send_event_err.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.9 % 193 187
Test Date: 2025-10-12 08:10:56 Functions: 100.0 % 13 13

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2025 DMTF. All rights reserved.
       4              :  *  License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
       5              :  **/
       6              : 
       7              : #include "spdm_unit_test.h"
       8              : #include "internal/libspdm_requester_lib.h"
       9              : #include "internal/libspdm_secured_message_lib.h"
      10              : 
      11              : #if LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP
      12              : 
      13              : static uint32_t m_session_id = 0xffffffff;
      14              : 
      15              : static struct m_test_params {
      16              :     uint32_t event_count;
      17              :     size_t events_list_size;
      18              :     uint8_t events_list[0x1000];
      19              : } m_test_params;
      20              : 
      21            6 : static libspdm_return_t send_message(
      22              :     void *spdm_context, size_t request_size, const void *request, uint64_t timeout)
      23              : {
      24            6 :     libspdm_test_context_t *spdm_test_context = libspdm_get_test_context();
      25              : 
      26            6 :     switch (spdm_test_context->case_id) {
      27            5 :     case 0x4:
      28              :     case 0x6:
      29              :     case 0x7:
      30              :     case 0x8:
      31              :     case 0x9:
      32            5 :         return LIBSPDM_STATUS_SUCCESS;
      33            1 :     case 0x5:
      34            1 :         return LIBSPDM_STATUS_SEND_FAIL;
      35            0 :     default:
      36            0 :         assert_true(false);
      37            0 :         return LIBSPDM_STATUS_SEND_FAIL;
      38              :     }
      39              : }
      40              : 
      41            4 : static libspdm_return_t receive_message(
      42              :     void *spdm_context, size_t *response_size, void **response, uint64_t timeout)
      43              : {
      44            4 :     libspdm_test_context_t *spdm_test_context = libspdm_get_test_context();
      45              :     spdm_event_ack_response_t *spdm_response;
      46              :     size_t spdm_response_size;
      47              :     size_t transport_header_size;
      48              :     uint32_t session_id;
      49              :     libspdm_session_info_t *session_info;
      50              :     uint8_t *scratch_buffer;
      51              :     size_t scratch_buffer_size;
      52              : 
      53            4 :     transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
      54            4 :     spdm_response = (void *)((uint8_t *)*response + transport_header_size);
      55              : 
      56            4 :     session_id = m_session_id;
      57            4 :     session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
      58            4 :     LIBSPDM_ASSERT((session_info != NULL));
      59              : 
      60            4 :     transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
      61            4 :     spdm_response = (void *)((uint8_t *)*response + transport_header_size);
      62              : 
      63            4 :     spdm_response_size = sizeof(spdm_event_ack_response_t);
      64            4 :     libspdm_zero_mem(spdm_response, spdm_response_size);
      65              : 
      66            4 :     spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
      67            4 :     spdm_response->header.request_response_code = SPDM_EVENT_ACK;
      68            4 :     spdm_response->header.param1 = 0;
      69            4 :     spdm_response->header.param2 = 0;
      70              : 
      71            4 :     switch (spdm_test_context->case_id) {
      72            1 :     case 0x7:
      73              :         /* Invalid response message size. */
      74            1 :         spdm_response_size++;
      75            1 :         break;
      76            1 :     case 0x8:
      77              :         /* Invalid RequestResponseCode to SEND_EVENT request. */
      78            1 :         spdm_response->header.request_response_code = SPDM_KEY_UPDATE_ACK;
      79            1 :         break;
      80            1 :     case 0x9:
      81              :         /* Invalid SPDMVersion field value. */
      82            1 :         spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_14;
      83            1 :         break;
      84            1 :     default:
      85            1 :         break;
      86              :     }
      87              : 
      88              :     /* For secure message, message is in sender buffer, we need copy it to scratch buffer.
      89              :      * transport_message is always in sender buffer. */
      90            4 :     libspdm_get_scratch_buffer(spdm_context, (void **)&scratch_buffer, &scratch_buffer_size);
      91            4 :     libspdm_copy_mem(scratch_buffer + transport_header_size,
      92              :                      scratch_buffer_size - transport_header_size,
      93              :                      spdm_response, spdm_response_size);
      94              : 
      95            4 :     spdm_response = (void *)(scratch_buffer + transport_header_size);
      96              : 
      97            4 :     libspdm_transport_test_encode_message(spdm_context, &session_id,
      98              :                                           false, false, spdm_response_size,
      99              :                                           spdm_response, response_size, response);
     100              : 
     101              :     /* Workaround: Use single context to encode message and then decode message. */
     102            4 :     ((libspdm_secured_message_context_t *)(session_info->secured_message_context))->
     103            4 :     application_secret.response_data_sequence_number--;
     104              : 
     105            4 :     switch (spdm_test_context->case_id) {
     106            1 :     case 0x6:
     107            1 :         return LIBSPDM_STATUS_RECEIVE_FAIL;
     108            3 :     case 0x7:
     109              :     case 0x8:
     110              :     case 0x9:
     111            3 :         return LIBSPDM_STATUS_SUCCESS;
     112            0 :     default:
     113            0 :         assert_true(false);
     114            0 :         return LIBSPDM_STATUS_RECEIVE_FAIL;
     115              :     }
     116              : }
     117              : 
     118            9 : static void set_standard_state(libspdm_context_t *spdm_context)
     119              : {
     120              :     libspdm_session_info_t *session_info;
     121              : 
     122            9 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
     123              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     124            9 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     125              : 
     126            9 :     spdm_context->connection_info.capability.flags |=
     127              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
     128            9 :     spdm_context->connection_info.capability.flags |=
     129              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
     130            9 :     spdm_context->connection_info.capability.flags |=
     131              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP;
     132            9 :     spdm_context->connection_info.capability.flags |=
     133              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP;
     134              : 
     135            9 :     spdm_context->local_context.capability.flags |=
     136              :         SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP;
     137            9 :     spdm_context->local_context.capability.flags |=
     138              :         SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
     139            9 :     spdm_context->local_context.capability.flags |=
     140              :         SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP;
     141            9 :     spdm_context->local_context.capability.flags |=
     142              :         SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP;
     143            9 :     spdm_context->local_context.capability.flags |=
     144              :         SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EVENT_CAP;
     145              : 
     146            9 :     spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
     147            9 :     spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
     148            9 :     spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
     149            9 :     spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
     150              : 
     151            9 :     spdm_context->latest_session_id = m_session_id;
     152            9 :     spdm_context->last_spdm_request_session_id_valid = true;
     153            9 :     spdm_context->last_spdm_request_session_id = m_session_id;
     154            9 :     session_info = &spdm_context->session_info[0];
     155            9 :     libspdm_session_info_init(spdm_context, session_info, m_session_id,
     156              :                               SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
     157            9 :     libspdm_secured_message_set_session_state(
     158              :         session_info->secured_message_context,
     159              :         LIBSPDM_SESSION_STATE_ESTABLISHED);
     160            9 : }
     161              : 
     162              : /**
     163              :  * Test 1: Requester has not set EVENT_CAP.
     164              :  * Expected behavior: returns with LIBSPDM_STATUS_UNSUPPORTED_CAP.
     165              :  **/
     166            1 : static void req_send_event_err_case1(void **state)
     167              : {
     168              :     libspdm_test_context_t *spdm_test_context;
     169              :     libspdm_context_t *spdm_context;
     170              :     libspdm_return_t status;
     171              : 
     172            1 :     spdm_test_context = *state;
     173            1 :     spdm_context = spdm_test_context->spdm_context;
     174            1 :     spdm_test_context->case_id = 0x1;
     175              : 
     176            1 :     set_standard_state(spdm_context);
     177              : 
     178              :     /* Clear EVENT_CAP. */
     179            1 :     spdm_context->local_context.capability.flags &=
     180              :         ~SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EVENT_CAP;
     181              : 
     182            1 :     m_test_params.event_count = 3;
     183            1 :     m_test_params.events_list_size = 100;
     184              : 
     185          101 :     for (int unsigned index = 0; index < m_test_params.events_list_size; index++) {
     186          100 :         m_test_params.events_list[index] = (uint8_t)index;
     187              :     }
     188              : 
     189            1 :     status = libspdm_send_event(spdm_context, m_session_id, m_test_params.event_count,
     190              :                                 m_test_params.events_list_size, m_test_params.events_list);
     191              : 
     192            1 :     assert_int_equal(status, LIBSPDM_STATUS_UNSUPPORTED_CAP);
     193            1 : }
     194              : 
     195              : /**
     196              :  * Test 2: Connection version does not support SEND_EVENT.
     197              :  * Expected behavior: returns with LIBSPDM_STATUS_UNSUPPORTED_CAP.
     198              :  **/
     199            1 : static void req_send_event_err_case2(void **state)
     200              : {
     201              :     libspdm_test_context_t *spdm_test_context;
     202              :     libspdm_context_t *spdm_context;
     203              :     libspdm_return_t status;
     204              : 
     205            1 :     spdm_test_context = *state;
     206            1 :     spdm_context = spdm_test_context->spdm_context;
     207            1 :     spdm_test_context->case_id = 0x2;
     208              : 
     209            1 :     set_standard_state(spdm_context);
     210              : 
     211              :     /* Set version to 1.2, which does not support SEND_EVENT. */
     212            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
     213              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     214              : 
     215            1 :     m_test_params.event_count = 3;
     216            1 :     m_test_params.events_list_size = 100;
     217              : 
     218          101 :     for (int unsigned index = 0; index < m_test_params.events_list_size; index++) {
     219          100 :         m_test_params.events_list[index] = (uint8_t)index;
     220              :     }
     221              : 
     222            1 :     status = libspdm_send_event(spdm_context, m_session_id, m_test_params.event_count,
     223              :                                 m_test_params.events_list_size, m_test_params.events_list);
     224              : 
     225            1 :     assert_int_equal(status, LIBSPDM_STATUS_UNSUPPORTED_CAP);
     226            1 : }
     227              : 
     228              : /**
     229              :  * Test 3: Unable to acquire send buffer.
     230              :  * Expected behavior: returns with LIBSPDM_STATUS_ACQUIRE_FAIL.
     231              :  **/
     232            1 : static void req_send_event_err_case3(void **state)
     233              : {
     234              :     libspdm_test_context_t *spdm_test_context;
     235              :     libspdm_context_t *spdm_context;
     236              :     libspdm_return_t status;
     237              : 
     238            1 :     spdm_test_context = *state;
     239            1 :     spdm_context = spdm_test_context->spdm_context;
     240            1 :     spdm_test_context->case_id = 0x3;
     241              : 
     242            1 :     set_standard_state(spdm_context);
     243              : 
     244            1 :     m_test_params.event_count = 3;
     245            1 :     m_test_params.events_list_size = 100;
     246              : 
     247          101 :     for (int unsigned index = 0; index < m_test_params.events_list_size; index++) {
     248          100 :         m_test_params.events_list[index] = (uint8_t)index;
     249              :     }
     250              : 
     251              :     /* Induce error when acquiring send buffer. */
     252            1 :     libspdm_force_error(LIBSPDM_ERR_ACQUIRE_SENDER_BUFFER);
     253              : 
     254            1 :     status = libspdm_send_event(spdm_context, m_session_id, m_test_params.event_count,
     255              :                                 m_test_params.events_list_size, m_test_params.events_list);
     256              : 
     257            1 :     libspdm_release_error(LIBSPDM_ERR_ACQUIRE_SENDER_BUFFER);
     258              : 
     259            1 :     assert_int_equal(status, LIBSPDM_STATUS_ACQUIRE_FAIL);
     260            1 : }
     261              : 
     262              : /**
     263              :  * Test 4: Unable to acquire receive buffer.
     264              :  * Expected behavior: returns with LIBSPDM_STATUS_ACQUIRE_FAIL.
     265              :  **/
     266            1 : static void req_send_event_err_case4(void **state)
     267              : {
     268              :     libspdm_test_context_t *spdm_test_context;
     269              :     libspdm_context_t *spdm_context;
     270              :     libspdm_return_t status;
     271              : 
     272            1 :     spdm_test_context = *state;
     273            1 :     spdm_context = spdm_test_context->spdm_context;
     274            1 :     spdm_test_context->case_id = 0x4;
     275              : 
     276            1 :     set_standard_state(spdm_context);
     277              : 
     278            1 :     m_test_params.event_count = 3;
     279            1 :     m_test_params.events_list_size = 100;
     280              : 
     281          101 :     for (int unsigned index = 0; index < m_test_params.events_list_size; index++) {
     282          100 :         m_test_params.events_list[index] = (uint8_t)index;
     283              :     }
     284              : 
     285              :     /* Induce error when acquiring receive buffer. */
     286            1 :     libspdm_force_error(LIBSPDM_ERR_ACQUIRE_RECEIVER_BUFFER);
     287              : 
     288            1 :     status = libspdm_send_event(spdm_context, m_session_id, m_test_params.event_count,
     289              :                                 m_test_params.events_list_size, m_test_params.events_list);
     290              : 
     291            1 :     libspdm_release_error(LIBSPDM_ERR_ACQUIRE_RECEIVER_BUFFER);
     292              : 
     293            1 :     assert_int_equal(status, LIBSPDM_STATUS_ACQUIRE_FAIL);
     294            1 : }
     295              : 
     296              : /**
     297              :  * Test 5: Unable to send message.
     298              :  * Expected behavior: returns with LIBSPDM_STATUS_SEND_FAIL.
     299              :  **/
     300            1 : static void req_send_event_err_case5(void **state)
     301              : {
     302              :     libspdm_test_context_t *spdm_test_context;
     303              :     libspdm_context_t *spdm_context;
     304              :     libspdm_return_t status;
     305              : 
     306            1 :     spdm_test_context = *state;
     307            1 :     spdm_context = spdm_test_context->spdm_context;
     308            1 :     spdm_test_context->case_id = 0x5;
     309              : 
     310            1 :     set_standard_state(spdm_context);
     311              : 
     312            1 :     m_test_params.event_count = 3;
     313            1 :     m_test_params.events_list_size = 100;
     314              : 
     315          101 :     for (int unsigned index = 0; index < m_test_params.events_list_size; index++) {
     316          100 :         m_test_params.events_list[index] = (uint8_t)index;
     317              :     }
     318              : 
     319            1 :     status = libspdm_send_event(spdm_context, m_session_id, m_test_params.event_count,
     320              :                                 m_test_params.events_list_size, m_test_params.events_list);
     321              : 
     322            1 :     assert_int_equal(status, LIBSPDM_STATUS_SEND_FAIL);
     323            1 : }
     324              : 
     325              : /**
     326              :  * Test 6: Unable to receive message.
     327              :  * Expected behavior: returns with LIBSPDM_STATUS_RECEIVE_FAIL.
     328              :  **/
     329            1 : static void req_send_event_err_case6(void **state)
     330              : {
     331              :     libspdm_test_context_t *spdm_test_context;
     332              :     libspdm_context_t *spdm_context;
     333              :     libspdm_return_t status;
     334              : 
     335            1 :     spdm_test_context = *state;
     336            1 :     spdm_context = spdm_test_context->spdm_context;
     337            1 :     spdm_test_context->case_id = 0x6;
     338              : 
     339            1 :     set_standard_state(spdm_context);
     340              : 
     341            1 :     m_test_params.event_count = 3;
     342            1 :     m_test_params.events_list_size = 100;
     343              : 
     344          101 :     for (int unsigned index = 0; index < m_test_params.events_list_size; index++) {
     345          100 :         m_test_params.events_list[index] = (uint8_t)index;
     346              :     }
     347              : 
     348            1 :     status = libspdm_send_event(spdm_context, m_session_id, m_test_params.event_count,
     349              :                                 m_test_params.events_list_size, m_test_params.events_list);
     350              : 
     351            1 :     assert_int_equal(status, LIBSPDM_STATUS_RECEIVE_FAIL);
     352            1 : }
     353              : 
     354              : /**
     355              :  * Test 7: Invalid size of EVENT_ACK response.
     356              :  * Expected behavior: returns with LIBSPDM_STATUS_INVALID_MSG_SIZE.
     357              :  **/
     358            1 : static void req_send_event_err_case7(void **state)
     359              : {
     360              :     libspdm_test_context_t *spdm_test_context;
     361              :     libspdm_context_t *spdm_context;
     362              :     libspdm_return_t status;
     363              : 
     364            1 :     spdm_test_context = *state;
     365            1 :     spdm_context = spdm_test_context->spdm_context;
     366            1 :     spdm_test_context->case_id = 0x7;
     367              : 
     368            1 :     set_standard_state(spdm_context);
     369              : 
     370            1 :     m_test_params.event_count = 3;
     371            1 :     m_test_params.events_list_size = 100;
     372              : 
     373          101 :     for (int unsigned index = 0; index < m_test_params.events_list_size; index++) {
     374          100 :         m_test_params.events_list[index] = (uint8_t)index;
     375              :     }
     376              : 
     377            1 :     status = libspdm_send_event(spdm_context, m_session_id, m_test_params.event_count,
     378              :                                 m_test_params.events_list_size, m_test_params.events_list);
     379              : 
     380            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_SIZE);
     381            1 : }
     382              : 
     383              : /**
     384              :  * Test 8: Invalid RequestResponseCode in response.
     385              :  * Expected behavior: returns with LIBSPDM_STATUS_INVALID_MSG_FIELD.
     386              :  **/
     387            1 : static void req_send_event_err_case8(void **state)
     388              : {
     389              :     libspdm_test_context_t *spdm_test_context;
     390              :     libspdm_context_t *spdm_context;
     391              :     libspdm_return_t status;
     392              : 
     393            1 :     spdm_test_context = *state;
     394            1 :     spdm_context = spdm_test_context->spdm_context;
     395            1 :     spdm_test_context->case_id = 0x8;
     396              : 
     397            1 :     set_standard_state(spdm_context);
     398              : 
     399            1 :     m_test_params.event_count = 3;
     400            1 :     m_test_params.events_list_size = 100;
     401              : 
     402          101 :     for (int unsigned index = 0; index < m_test_params.events_list_size; index++) {
     403          100 :         m_test_params.events_list[index] = (uint8_t)index;
     404              :     }
     405              : 
     406            1 :     status = libspdm_send_event(spdm_context, m_session_id, m_test_params.event_count,
     407              :                                 m_test_params.events_list_size, m_test_params.events_list);
     408              : 
     409            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
     410            1 : }
     411              : 
     412              : /**
     413              :  * Test 9: Invalid SPDMVersion in response.
     414              :  * Expected behavior: returns with LIBSPDM_STATUS_INVALID_MSG_FIELD.
     415              :  **/
     416            1 : static void req_send_event_err_case9(void **state)
     417              : {
     418              :     libspdm_test_context_t *spdm_test_context;
     419              :     libspdm_context_t *spdm_context;
     420              :     libspdm_return_t status;
     421              : 
     422            1 :     spdm_test_context = *state;
     423            1 :     spdm_context = spdm_test_context->spdm_context;
     424            1 :     spdm_test_context->case_id = 0x9;
     425              : 
     426            1 :     set_standard_state(spdm_context);
     427              : 
     428            1 :     m_test_params.event_count = 3;
     429            1 :     m_test_params.events_list_size = 100;
     430              : 
     431          101 :     for (int unsigned index = 0; index < m_test_params.events_list_size; index++) {
     432          100 :         m_test_params.events_list[index] = (uint8_t)index;
     433              :     }
     434              : 
     435            1 :     status = libspdm_send_event(spdm_context, m_session_id, m_test_params.event_count,
     436              :                                 m_test_params.events_list_size, m_test_params.events_list);
     437              : 
     438            1 :     assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
     439            1 : }
     440              : 
     441            1 : int libspdm_req_send_event_error_test(void)
     442              : {
     443            1 :     const struct CMUnitTest test_cases[] = {
     444              :         cmocka_unit_test(req_send_event_err_case1),
     445              :         cmocka_unit_test(req_send_event_err_case2),
     446              :         cmocka_unit_test(req_send_event_err_case3),
     447              :         cmocka_unit_test(req_send_event_err_case4),
     448              :         cmocka_unit_test(req_send_event_err_case5),
     449              :         cmocka_unit_test(req_send_event_err_case6),
     450              :         cmocka_unit_test(req_send_event_err_case7),
     451              :         cmocka_unit_test(req_send_event_err_case8),
     452              :         cmocka_unit_test(req_send_event_err_case9),
     453              :     };
     454              : 
     455            1 :     libspdm_test_context_t test_context = {
     456              :         LIBSPDM_TEST_CONTEXT_VERSION,
     457              :         true,
     458              :         send_message,
     459              :         receive_message,
     460              :     };
     461              : 
     462            1 :     libspdm_setup_test_context(&test_context);
     463              : 
     464            1 :     return cmocka_run_group_tests(test_cases,
     465              :                                   libspdm_unit_test_group_setup,
     466              :                                   libspdm_unit_test_group_teardown);
     467              : }
     468              : 
     469              : #endif /* LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP */
        

Generated by: LCOV version 2.0-1