LCOV - code coverage report
Current view: top level - unit_test/test_spdm_responder - vendor_response.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.4 % 115 112
Test Date: 2025-09-14 08:11:04 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2023-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_responder_lib.h"
       9              : 
      10              : #if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
      11              : 
      12              : #define VENDOR_DEFINED_REQUEST_PAYLOAD_SIZE  16
      13              : #define VENDOR_DEFINED_RESPONSE_PAYLOAD_SIZE  64
      14              : 
      15              : #pragma pack(1)
      16              : typedef struct {
      17              :     spdm_message_header_t header;
      18              :     uint16_t standard_id;
      19              :     uint8_t vendor_id_len;
      20              :     uint8_t vendor_id[SPDM_MAX_VENDOR_ID_LENGTH];
      21              : } libspdm_vendor_request_test;
      22              : 
      23              : typedef struct {
      24              :     spdm_message_header_t header;
      25              :     uint16_t standard_id;
      26              :     uint8_t vendor_id_len;
      27              :     uint8_t vendor_id[SPDM_MAX_VENDOR_ID_LENGTH];
      28              : } libspdm_vendor_response_test;
      29              : #pragma pack()
      30              : 
      31              : static uint32_t m_session_id = 0xffffffff;
      32              : 
      33            1 : static libspdm_return_t libspdm_vendor_get_id_func_test(
      34              :     void *spdm_context,
      35              :     const uint32_t *session_id,
      36              :     uint16_t *resp_standard_id,
      37              :     uint8_t *resp_vendor_id_len,
      38              :     void *resp_vendor_id)
      39              : {
      40            1 :     assert_int_equal(*session_id, m_session_id);
      41              : 
      42            1 :     if (resp_standard_id == NULL ||
      43            1 :         resp_vendor_id_len == NULL ||
      44              :         resp_vendor_id == NULL)
      45            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
      46              : 
      47              :     /* vendor id length in bytes */
      48            1 :     if (*resp_vendor_id_len < 2)
      49            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
      50              : 
      51            1 :     *resp_standard_id = 6;
      52              :     /* vendor id length in bytes */
      53            1 :     *resp_vendor_id_len = 2;
      54            1 :     ((uint8_t*)resp_vendor_id)[0] = 0xAA;
      55            1 :     ((uint8_t*)resp_vendor_id)[1] = 0xAA;
      56              : 
      57            1 :     return LIBSPDM_STATUS_SUCCESS;
      58              : }
      59              : 
      60            1 : static libspdm_return_t libspdm_vendor_response_func_test(
      61              :     void *spdm_context,
      62              :     const uint32_t *session_id,
      63              :     uint16_t req_standard_id,
      64              :     uint8_t req_vendor_id_len,
      65              :     const void *req_vendor_id,
      66              :     uint32_t req_size,
      67              :     const void *req_data,
      68              :     uint32_t *resp_size,
      69              :     void *resp_data)
      70              : {
      71            1 :     if (req_data == NULL ||
      72            1 :         resp_size == NULL ||
      73              :         resp_data == NULL)
      74            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
      75              : 
      76            1 :     assert_int_equal(*session_id, m_session_id);
      77              : 
      78              :     /* get pointer to response data payload and populate */
      79            1 :     uint8_t *resp_payload = (uint8_t *)resp_data;
      80              :     /* get pointer to response length and populate */
      81            1 :     *resp_size = VENDOR_DEFINED_RESPONSE_PAYLOAD_SIZE;
      82              :     /* store length of response */
      83            1 :     libspdm_set_mem(resp_payload, *resp_size, 0xFF);
      84              : 
      85            1 :     printf("Got request 0x%x, sent response 0x%x\n",
      86            1 :            ((const uint8_t*)req_data)[0], ((uint8_t*)resp_data)[0]);
      87              : 
      88            1 :     return LIBSPDM_STATUS_SUCCESS;
      89              : }
      90              : 
      91              : /**
      92              :  * Test 1: Sending a vendor defined request using the internal response handler
      93              :  * Expected behavior: client returns a status of LIBSPDM_STATUS_SUCCESS and expected response
      94              :  **/
      95            1 : static void libspdm_test_responder_vendor_cmds_case1(void **state)
      96              : {
      97              :     libspdm_return_t status;
      98              :     libspdm_test_context_t *spdm_test_context;
      99              :     libspdm_context_t *spdm_context;
     100            1 :     uint8_t request_buffer[LIBSPDM_MAX_SPDM_MSG_SIZE] = {0};
     101            1 :     uint8_t response_buffer[LIBSPDM_MAX_SPDM_MSG_SIZE] = {0};
     102            1 :     libspdm_vendor_request_test request = {0};
     103            1 :     libspdm_vendor_response_test response = {0};
     104            1 :     size_t response_len = 0;
     105              :     libspdm_session_info_t *session_info;
     106              :     uint8_t *request_ptr;
     107              : 
     108            1 :     response.vendor_id_len = sizeof(response.vendor_id);
     109              : 
     110            1 :     spdm_test_context = *state;
     111            1 :     spdm_context = spdm_test_context->spdm_context;
     112            1 :     spdm_test_context->case_id = 0x1;
     113            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     114              :         SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256;
     115            1 :     request.header.spdm_version = SPDM_MESSAGE_VERSION_11;
     116            1 :     spdm_context->connection_info.version = request.header.spdm_version <<
     117              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     118            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     119            1 :     spdm_context->local_context.is_requester = true;
     120              : 
     121            1 :     spdm_context->latest_session_id = m_session_id;
     122            1 :     spdm_context->last_spdm_request_session_id_valid = true;
     123            1 :     spdm_context->last_spdm_request_session_id = m_session_id;
     124            1 :     session_info = &spdm_context->session_info[0];
     125            1 :     libspdm_session_info_init(spdm_context, session_info, m_session_id, true);
     126            1 :     libspdm_secured_message_set_session_state(
     127              :         session_info->secured_message_context,
     128              :         LIBSPDM_SESSION_STATE_ESTABLISHED);
     129              : 
     130            1 :     status = libspdm_register_vendor_get_id_callback_func(spdm_context,
     131              :                                                           libspdm_vendor_get_id_func_test);
     132            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     133            1 :     status = libspdm_register_vendor_callback_func(spdm_context,
     134              :                                                    libspdm_vendor_response_func_test);
     135            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     136              : 
     137            1 :     request.standard_id = 6;
     138            1 :     request.vendor_id_len = sizeof(request.vendor_id);
     139            1 :     libspdm_set_mem(request.vendor_id, sizeof(request.vendor_id), 0xAA);
     140              : 
     141            1 :     response_len = sizeof(response) + sizeof(uint16_t)
     142              :                    + VENDOR_DEFINED_RESPONSE_PAYLOAD_SIZE;
     143              : 
     144              :     /* copy header of request structure to buffer */
     145            1 :     libspdm_copy_mem(request_buffer, sizeof(request_buffer), &request,
     146            1 :                      sizeof(request.header) + 3 + request.vendor_id_len);
     147              :     /* write the request data len to the correct offset in the request_buffer */
     148            1 :     request_ptr = request_buffer + sizeof(request.header) + 3 + request.vendor_id_len;
     149            1 :     libspdm_write_uint16(request_ptr, VENDOR_DEFINED_REQUEST_PAYLOAD_SIZE);
     150              :     /* set the request data to the correct offset in the request_buffer */
     151            1 :     request_ptr += sizeof(uint16_t);
     152            1 :     libspdm_set_mem(request_ptr, VENDOR_DEFINED_REQUEST_PAYLOAD_SIZE, 0xAA);
     153              : 
     154              :     /* requires correctly encoded spdm vendor request message */
     155            1 :     status = libspdm_get_vendor_defined_response(spdm_context, sizeof(request),
     156              :                                                  request_buffer, &response_len, response_buffer);
     157              : 
     158            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     159            1 : }
     160              : 
     161              : /**
     162              :  * Test 2: Sending a vendor defined request using the internal response handler with Large VDM support
     163              :  * Expected behavior: client returns a status of LIBSPDM_STATUS_SUCCESS and expected response
     164              :  **/
     165            1 : static void libspdm_test_responder_vendor_cmds_case2(void **state)
     166              : {
     167              :     libspdm_return_t status;
     168              :     libspdm_test_context_t *spdm_test_context;
     169              :     libspdm_context_t *spdm_context;
     170            1 :     uint8_t request_buffer[LIBSPDM_MAX_SPDM_MSG_SIZE] = {0};
     171            1 :     uint8_t response_buffer[LIBSPDM_MAX_SPDM_MSG_SIZE] = {0};
     172            1 :     libspdm_vendor_request_test request = {0};
     173            1 :     libspdm_vendor_response_test response = {0};
     174            1 :     size_t response_len = 0;
     175            1 :     size_t request_len = 0;
     176              :     libspdm_session_info_t *session_info;
     177              :     uint8_t *request_ptr;
     178              : 
     179            1 :     spdm_test_context = *state;
     180            1 :     spdm_context = spdm_test_context->spdm_context;
     181            1 :     spdm_test_context->case_id = 0x2;
     182            1 :     spdm_context->connection_info.algorithm.base_hash_algo =
     183              :         SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256;
     184            1 :     request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
     185            1 :     spdm_context->connection_info.version = request.header.spdm_version <<
     186              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     187            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
     188            1 :     spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_LARGE_RESP_CAP;
     189            1 :     spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_LARGE_RESP_CAP;
     190            1 :     spdm_context->local_context.is_requester = false;
     191              : 
     192            1 :     spdm_context->latest_session_id = m_session_id;
     193            1 :     spdm_context->last_spdm_request_session_id_valid = true;
     194            1 :     spdm_context->last_spdm_request_session_id = m_session_id;
     195            1 :     session_info = &spdm_context->session_info[0];
     196            1 :     libspdm_session_info_init(spdm_context, session_info, m_session_id, true);
     197            1 :     libspdm_secured_message_set_session_state(
     198              :         session_info->secured_message_context,
     199              :         LIBSPDM_SESSION_STATE_ESTABLISHED);
     200              : 
     201            1 :     status = libspdm_register_vendor_get_id_callback_func(spdm_context,
     202              :                                                           libspdm_vendor_get_id_func_test);
     203            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     204            1 :     status = libspdm_register_vendor_callback_func(spdm_context,
     205              :                                                    libspdm_vendor_response_func_test);
     206            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     207              : 
     208            1 :     request.header.request_response_code = SPDM_VENDOR_DEFINED_REQUEST;
     209            1 :     request.header.param1 = SPDM_VENDOR_DEFINED_REQUEST_LARGE_REQ;
     210            1 :     request.standard_id = 6;
     211            1 :     request.vendor_id_len = sizeof(request.vendor_id);
     212            1 :     libspdm_set_mem(request.vendor_id, sizeof(request.vendor_id), 0xAA);
     213              : 
     214            1 :     response_len = sizeof(response) + sizeof(uint16_t) + sizeof(uint32_t)
     215              :                    + VENDOR_DEFINED_RESPONSE_PAYLOAD_SIZE;
     216              : 
     217              :     /* copy header of request structure to buffer */
     218            1 :     libspdm_copy_mem(request_buffer, sizeof(request_buffer),
     219            1 :                      &request, sizeof(spdm_vendor_defined_request_msg_t) + request.vendor_id_len);
     220              :     /* write the request data len to the correct offset in the request_buffer */
     221            1 :     request_ptr = request_buffer + sizeof(spdm_vendor_defined_request_msg_t) + request.vendor_id_len;
     222            1 :     libspdm_write_uint16(request_ptr, 0);
     223            1 :     request_ptr += sizeof(uint16_t);
     224            1 :     libspdm_write_uint32(request_ptr, VENDOR_DEFINED_REQUEST_PAYLOAD_SIZE);
     225              :     /* set the request data to the correct offset in the request_buffer */
     226            1 :     request_ptr += sizeof(uint32_t);
     227            1 :     libspdm_set_mem(request_ptr, VENDOR_DEFINED_REQUEST_PAYLOAD_SIZE, 0xAA);
     228            1 :     request_len = sizeof(spdm_vendor_defined_request_msg_t) + request.vendor_id_len + sizeof(uint16_t) +
     229              :                   sizeof(uint32_t) + VENDOR_DEFINED_REQUEST_PAYLOAD_SIZE;
     230              : 
     231              :     /* requires correctly encoded spdm vendor request message */
     232            1 :     status = libspdm_get_vendor_defined_response(spdm_context, request_len,
     233              :                                                  request_buffer, &response_len, response_buffer);
     234              : 
     235              :     /* copy to response data structure in the same way as for request */
     236            1 :     libspdm_copy_mem(&response, sizeof(response),
     237              :                      response_buffer, sizeof(spdm_vendor_defined_response_msg_t));
     238              : 
     239            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     240            1 :     assert_int_equal(response.header.spdm_version, SPDM_MESSAGE_VERSION_14);
     241            1 :     assert_int_equal(response.header.request_response_code, SPDM_VENDOR_DEFINED_RESPONSE);
     242            1 :     assert_int_equal(response.header.param1, SPDM_VENDOR_DEFINED_RESONSE_LARGE_RESP);
     243            1 : }
     244              : 
     245              : 
     246            1 : int libspdm_responder_vendor_cmds_test_main(void)
     247              : {
     248            1 :     const struct CMUnitTest spdm_responder_vendor_cmds_tests[] = {
     249              :         cmocka_unit_test(libspdm_test_responder_vendor_cmds_case1),
     250              :         cmocka_unit_test(libspdm_test_responder_vendor_cmds_case2),
     251              :     };
     252              : 
     253            1 :     libspdm_test_context_t test_context = {
     254              :         LIBSPDM_TEST_CONTEXT_VERSION,
     255              :         true,
     256              :     };
     257              : 
     258            1 :     libspdm_setup_test_context(&test_context);
     259              : 
     260            1 :     return cmocka_run_group_tests(spdm_responder_vendor_cmds_tests,
     261              :                                   libspdm_unit_test_group_setup,
     262              :                                   libspdm_unit_test_group_teardown);
     263              : }
     264              : 
     265              : #endif /* LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES */
        

Generated by: LCOV version 2.0-1