LCOV - code coverage report
Current view: top level - unit_test/test_spdm_responder - set_key_pair_info_ack.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 329 329
Test Date: 2026-07-05 09:06:49 Functions: 100.0 % 6 6

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2024-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_responder_lib.h"
       9              : #include "internal/libspdm_requester_lib.h"
      10              : 
      11              : #if LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP
      12              : 
      13              : /**
      14              :  * Test 1: Successful response to set key pair info with key pair id 4
      15              :  * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code, and correct response message size and fields
      16              :  **/
      17            1 : static void rsp_set_key_pair_info_ack_case1(void **state)
      18              : {
      19              :     libspdm_return_t status;
      20              :     libspdm_test_context_t *spdm_test_context;
      21              :     libspdm_context_t *spdm_context;
      22              :     size_t response_size;
      23              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
      24              :     spdm_set_key_pair_info_ack_response_t *spdm_response;
      25              : 
      26              :     uint8_t key_pair_id;
      27              :     size_t set_key_pair_info_request_size;
      28              :     spdm_set_key_pair_info_request_t *set_key_pair_info_request;
      29              :     uint8_t *ptr;
      30              :     uint16_t desired_key_usage;
      31              :     uint32_t desired_asym_algo;
      32              :     uint8_t desired_assoc_cert_slot_mask;
      33              : 
      34            1 :     set_key_pair_info_request = malloc(sizeof(spdm_set_key_pair_info_request_t) +
      35              :                                        sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) +
      36              :                                        sizeof(uint8_t));
      37              : 
      38            1 :     spdm_test_context = *state;
      39            1 :     spdm_context = spdm_test_context->spdm_context;
      40            1 :     spdm_test_context->case_id = 0x1;
      41            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
      42              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
      43            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
      44            1 :     spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
      45            1 :     spdm_context->local_context.capability.flags |=
      46              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_KEY_PAIR_INFO_CAP;
      47              : 
      48            1 :     key_pair_id = 4;
      49              : 
      50            1 :     response_size = sizeof(response);
      51              : 
      52              :     /*change: remove an association with slot*/
      53            1 :     set_key_pair_info_request_size =
      54              :         sizeof(spdm_set_key_pair_info_request_t) +
      55              :         sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t);
      56              : 
      57            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
      58            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_13;
      59            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
      60            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION;
      61            1 :     set_key_pair_info_request->header.param2 = 0;
      62            1 :     set_key_pair_info_request->key_pair_id = key_pair_id;
      63              : 
      64            1 :     status = libspdm_get_response_set_key_pair_info_ack(
      65              :         spdm_context, set_key_pair_info_request_size,
      66              :         set_key_pair_info_request, &response_size, response);
      67            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
      68            1 :     assert_int_equal(response_size, sizeof(spdm_set_key_pair_info_ack_response_t));
      69            1 :     spdm_response = (void *)response;
      70            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_SET_KEY_PAIR_INFO_ACK);
      71              : 
      72              :     /*erase: erase the keyusage and asymalgo*/
      73            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_ERASE_OPERATION;
      74            1 :     set_key_pair_info_request_size = sizeof(spdm_set_key_pair_info_request_t);
      75            1 :     status = libspdm_get_response_set_key_pair_info_ack(
      76              :         spdm_context, set_key_pair_info_request_size,
      77              :         set_key_pair_info_request, &response_size, response);
      78            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
      79            1 :     assert_int_equal(response_size, sizeof(spdm_set_key_pair_info_ack_response_t));
      80            1 :     spdm_response = (void *)response;
      81            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_SET_KEY_PAIR_INFO_ACK);
      82              : 
      83              :     /*generate: generate a new key pair*/
      84            1 :     desired_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
      85            1 :     desired_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC256;
      86            1 :     desired_assoc_cert_slot_mask = 0x08;
      87            1 :     set_key_pair_info_request_size =
      88              :         sizeof(spdm_set_key_pair_info_request_t) +
      89              :         sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t);
      90              : 
      91            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
      92            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_13;
      93            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
      94            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION;
      95            1 :     set_key_pair_info_request->header.param2 = 0;
      96            1 :     set_key_pair_info_request->key_pair_id = key_pair_id;
      97              : 
      98            1 :     ptr = (uint8_t*)(set_key_pair_info_request + 1);
      99            1 :     ptr += sizeof(uint8_t);
     100              : 
     101            1 :     libspdm_write_uint16(ptr, desired_key_usage);
     102            1 :     ptr += sizeof(uint16_t);
     103              : 
     104            1 :     libspdm_write_uint32(ptr, desired_asym_algo);
     105            1 :     ptr += sizeof(uint32_t);
     106              : 
     107            1 :     *ptr = desired_assoc_cert_slot_mask;
     108              : 
     109            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     110              :         spdm_context, set_key_pair_info_request_size,
     111              :         set_key_pair_info_request, &response_size, response);
     112            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     113            1 :     assert_int_equal(response_size, sizeof(spdm_set_key_pair_info_ack_response_t));
     114            1 :     spdm_response = (void *)response;
     115            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_SET_KEY_PAIR_INFO_ACK);
     116            1 :     free(set_key_pair_info_request);
     117            1 : }
     118              : 
     119              : /**
     120              :  * Test 2: Can be populated with new test.
     121              :  **/
     122            1 : static void rsp_set_key_pair_info_ack_case2(void **state)
     123              : {
     124            1 : }
     125              : 
     126              : /**
     127              :  * Test 3: The collection of multiple sub-cases.
     128              :  **/
     129            1 : static void rsp_set_key_pair_info_ack_case3(void **state)
     130              : {
     131              :     libspdm_return_t status;
     132              :     libspdm_test_context_t *spdm_test_context;
     133              :     libspdm_context_t *spdm_context;
     134              :     size_t response_size;
     135              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     136              :     spdm_set_key_pair_info_ack_response_t *spdm_response;
     137              : 
     138              :     uint8_t key_pair_id;
     139              :     size_t set_key_pair_info_request_size;
     140              :     spdm_set_key_pair_info_request_t *set_key_pair_info_request;
     141              :     uint8_t *ptr;
     142              :     uint16_t desired_key_usage;
     143              :     uint32_t desired_asym_algo;
     144              :     uint8_t desired_assoc_cert_slot_mask;
     145              :     uint8_t desired_pqc_asym_algo_len;
     146              :     uint32_t desired_pqc_asym_algo;
     147              : 
     148              :     uint8_t temp_buf[LIBSPDM_RECEIVER_BUFFER_SIZE];
     149            1 :     set_key_pair_info_request = (spdm_set_key_pair_info_request_t *)temp_buf;
     150              : 
     151            1 :     spdm_test_context = *state;
     152            1 :     spdm_context = spdm_test_context->spdm_context;
     153            1 :     spdm_test_context->case_id = 0x3;
     154            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
     155              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     156            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
     157            1 :     spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
     158            1 :     spdm_context->local_context.capability.flags |=
     159              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_KEY_PAIR_INFO_CAP;
     160              : 
     161            1 :     key_pair_id = 4;
     162              : 
     163              :     /*set responder need reset, spdm 1.4 */
     164            1 :     spdm_context->local_context.capability.flags |=
     165              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_KEY_PAIR_RESET_CAP;
     166              : 
     167              :     /*Before reset, change: remove an association with slot*/
     168            1 :     set_key_pair_info_request_size =
     169              :         sizeof(spdm_set_key_pair_info_request_t) +
     170              :         sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t) +
     171              :         sizeof(uint8_t);
     172              : 
     173            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
     174            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_14;
     175            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
     176            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION;
     177            1 :     set_key_pair_info_request->header.param2 = 0;
     178            1 :     set_key_pair_info_request->key_pair_id = key_pair_id;
     179              : 
     180            1 :     response_size = sizeof(response);
     181            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     182              :         spdm_context, set_key_pair_info_request_size,
     183              :         set_key_pair_info_request, &response_size, response);
     184            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     185            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     186            1 :     spdm_response = (void *)response;
     187            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     188            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESET_REQUIRED);
     189            1 :     assert_int_equal(spdm_response->header.param2, 0);
     190              : 
     191              :     /* Sub Case 1: If KeyPairErase is set, all fields after the KeyPairID field in this request should not exist. */
     192            1 :     desired_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     193            1 :     desired_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC256;
     194            1 :     desired_pqc_asym_algo_len = sizeof(desired_pqc_asym_algo);
     195            1 :     desired_pqc_asym_algo = 0;
     196            1 :     desired_assoc_cert_slot_mask = 0x08;
     197            1 :     set_key_pair_info_request_size =
     198              :         sizeof(spdm_set_key_pair_info_request_t) +
     199              :         sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t) +
     200              :         sizeof(uint8_t) + sizeof(uint32_t);
     201              : 
     202            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
     203            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_14;
     204            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
     205            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_ERASE_OPERATION;
     206            1 :     set_key_pair_info_request->header.param2 = 0;
     207            1 :     set_key_pair_info_request->key_pair_id = key_pair_id;
     208              : 
     209            1 :     ptr = (uint8_t*)(set_key_pair_info_request + 1);
     210            1 :     ptr += sizeof(uint8_t);
     211              : 
     212            1 :     libspdm_write_uint16(ptr, desired_key_usage);
     213            1 :     ptr += sizeof(uint16_t);
     214              : 
     215            1 :     libspdm_write_uint32(ptr, desired_asym_algo);
     216            1 :     ptr += sizeof(uint32_t);
     217              : 
     218            1 :     *ptr = desired_assoc_cert_slot_mask;
     219            1 :     ptr += sizeof(uint8_t);
     220              : 
     221            1 :     *ptr = desired_pqc_asym_algo_len;
     222            1 :     ptr += sizeof(uint8_t);
     223              : 
     224            1 :     libspdm_write_uint32(ptr, desired_pqc_asym_algo);
     225              : 
     226            1 :     response_size = sizeof(response);
     227            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     228              :         spdm_context, set_key_pair_info_request_size,
     229              :         set_key_pair_info_request, &response_size, response);
     230            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     231            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     232            1 :     spdm_response = (void *)response;
     233            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     234            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_OPERATION_FAILED);
     235            1 :     assert_int_equal(spdm_response->header.param2, 0);
     236              : 
     237              :     /*Sub Case 2: When GenerateKeyPair is set, the fields of DesiredKeyUsage, DesiredAsymAlgo and DesiredAssocCertSlotMask should exist. */
     238            1 :     set_key_pair_info_request_size = sizeof(spdm_set_key_pair_info_request_t);
     239              : 
     240            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
     241            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_14;
     242            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
     243            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION;
     244            1 :     set_key_pair_info_request->header.param2 = 0;
     245            1 :     set_key_pair_info_request->key_pair_id = key_pair_id;
     246              : 
     247            1 :     response_size = sizeof(response);
     248            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     249              :         spdm_context, set_key_pair_info_request_size,
     250              :         set_key_pair_info_request, &response_size, response);
     251            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     252            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     253            1 :     spdm_response = (void *)response;
     254            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     255            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
     256            1 :     assert_int_equal(spdm_response->header.param2, 0);
     257              : 
     258              :     /*Sub Case 3: key_pair_id = 0 */
     259            1 :     set_key_pair_info_request_size = sizeof(spdm_set_key_pair_info_request_t);
     260              : 
     261            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
     262            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_14;
     263            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
     264            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION;
     265            1 :     set_key_pair_info_request->header.param2 = 0;
     266            1 :     set_key_pair_info_request->key_pair_id = 0;
     267              : 
     268            1 :     response_size = sizeof(response);
     269            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     270              :         spdm_context, set_key_pair_info_request_size,
     271              :         set_key_pair_info_request, &response_size, response);
     272            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     273            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     274            1 :     spdm_response = (void *)response;
     275            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     276            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
     277            1 :     assert_int_equal(spdm_response->header.param2, 0);
     278              : 
     279              :     /* Sub Case 4: DesiredAsymAlgo must not have multiple bits set. */
     280            1 :     desired_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     281            1 :     desired_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC256 |
     282              :                         SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC384;
     283            1 :     desired_pqc_asym_algo_len = sizeof(desired_pqc_asym_algo);
     284            1 :     desired_pqc_asym_algo = 0;
     285            1 :     desired_assoc_cert_slot_mask = 0x08;
     286            1 :     set_key_pair_info_request_size =
     287              :         sizeof(spdm_set_key_pair_info_request_t) +
     288              :         sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t) +
     289              :         sizeof(uint8_t) + sizeof(uint32_t);
     290              : 
     291            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
     292            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_14;
     293            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
     294            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION;
     295            1 :     set_key_pair_info_request->header.param2 = 0;
     296            1 :     set_key_pair_info_request->key_pair_id = key_pair_id;
     297              : 
     298            1 :     ptr = (uint8_t*)(set_key_pair_info_request + 1);
     299            1 :     ptr += sizeof(uint8_t);
     300              : 
     301            1 :     libspdm_write_uint16(ptr, desired_key_usage);
     302            1 :     ptr += sizeof(uint16_t);
     303              : 
     304            1 :     libspdm_write_uint32(ptr, desired_asym_algo);
     305            1 :     ptr += sizeof(uint32_t);
     306              : 
     307            1 :     *ptr = desired_assoc_cert_slot_mask;
     308            1 :     ptr += sizeof(uint8_t);
     309              : 
     310            1 :     *ptr = desired_pqc_asym_algo_len;
     311            1 :     ptr += sizeof(uint8_t);
     312              : 
     313            1 :     libspdm_write_uint32(ptr, desired_pqc_asym_algo);
     314              : 
     315            1 :     response_size = sizeof(response);
     316            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     317              :         spdm_context, set_key_pair_info_request_size,
     318              :         set_key_pair_info_request, &response_size, response);
     319            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     320            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     321            1 :     spdm_response = (void *)response;
     322            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     323            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
     324            1 :     assert_int_equal(spdm_response->header.param2, 0);
     325              : 
     326              :     /* Sub Case 5: DesiredPqcAsymAlgo selects a bit outside PqcAsymAlgoCapabilities. Per
     327              :      * DSP0274 Table 115 this is the same class of malformed request as an out-of-capability
     328              :      * DesiredAsymAlgo, so the Responder shall answer with InvalidRequest (not
     329              :      * UnsupportedRequest). The sample HAL supports ML-DSA but not SLH-DSA for this key pair. */
     330            1 :     desired_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     331            1 :     desired_asym_algo = 0;
     332            1 :     desired_pqc_asym_algo_len = sizeof(desired_pqc_asym_algo);
     333            1 :     desired_pqc_asym_algo = SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_SLH_DSA_SHA2_128S;
     334            1 :     desired_assoc_cert_slot_mask = 0x08;
     335            1 :     set_key_pair_info_request_size =
     336              :         sizeof(spdm_set_key_pair_info_request_t) +
     337              :         sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t) +
     338              :         sizeof(uint8_t) + sizeof(uint32_t);
     339              : 
     340            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
     341            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_14;
     342            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
     343            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION;
     344            1 :     set_key_pair_info_request->header.param2 = 0;
     345            1 :     set_key_pair_info_request->key_pair_id = key_pair_id;
     346              : 
     347            1 :     ptr = (uint8_t*)(set_key_pair_info_request + 1);
     348            1 :     ptr += sizeof(uint8_t);
     349              : 
     350            1 :     libspdm_write_uint16(ptr, desired_key_usage);
     351            1 :     ptr += sizeof(uint16_t);
     352              : 
     353            1 :     libspdm_write_uint32(ptr, desired_asym_algo);
     354            1 :     ptr += sizeof(uint32_t);
     355              : 
     356            1 :     *ptr = desired_assoc_cert_slot_mask;
     357            1 :     ptr += sizeof(uint8_t);
     358              : 
     359            1 :     *ptr = desired_pqc_asym_algo_len;
     360            1 :     ptr += sizeof(uint8_t);
     361              : 
     362            1 :     libspdm_write_uint32(ptr, desired_pqc_asym_algo);
     363              : 
     364            1 :     response_size = sizeof(response);
     365            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     366              :         spdm_context, set_key_pair_info_request_size,
     367              :         set_key_pair_info_request, &response_size, response);
     368            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     369            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     370            1 :     spdm_response = (void *)response;
     371            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     372            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
     373            1 :     assert_int_equal(spdm_response->header.param2, 0);
     374              : 
     375              :     /*Before reset, change: remove an association with slot*/
     376            1 :     set_key_pair_info_request_size =
     377              :         sizeof(spdm_set_key_pair_info_request_t) +
     378              :         sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t) +
     379              :         sizeof(uint8_t);
     380              : 
     381            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
     382            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_14;
     383            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
     384            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION;
     385            1 :     set_key_pair_info_request->header.param2 = 0;
     386            1 :     set_key_pair_info_request->key_pair_id = 0x1;
     387              : 
     388            1 :     response_size = sizeof(response);
     389            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     390              :         spdm_context, set_key_pair_info_request_size,
     391              :         set_key_pair_info_request, &response_size, response);
     392            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     393            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     394            1 :     spdm_response = (void *)response;
     395            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     396            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESET_REQUIRED);
     397            1 :     assert_int_equal(spdm_response->header.param2, 0);
     398            1 : }
     399              : 
     400              : /**
     401              :  * Test 4: Successful response to set key pair info with key pair id 4: need reset, spdm 1.4
     402              :  * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code, and correct response message size and fields
     403              :  **/
     404            1 : static void rsp_set_key_pair_info_ack_case4(void **state)
     405              : {
     406              :     /* reference case 2 */
     407              :     libspdm_return_t status;
     408              :     libspdm_test_context_t *spdm_test_context;
     409              :     libspdm_context_t *spdm_context;
     410              :     size_t response_size;
     411              :     uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
     412              :     spdm_set_key_pair_info_ack_response_t *spdm_response;
     413              : 
     414              :     uint8_t key_pair_id;
     415              :     size_t set_key_pair_info_request_size;
     416              :     spdm_set_key_pair_info_request_t *set_key_pair_info_request;
     417              :     uint8_t *ptr;
     418              :     uint16_t desired_key_usage;
     419              :     uint32_t desired_asym_algo;
     420              :     uint8_t desired_assoc_cert_slot_mask;
     421              :     uint8_t desired_pqc_asym_algo_len;
     422              :     uint32_t desired_pqc_asym_algo;
     423              : 
     424            1 :     set_key_pair_info_request = malloc(sizeof(spdm_set_key_pair_info_request_t) +
     425              :                                        sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) +
     426              :                                        sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t));
     427              : 
     428            1 :     spdm_test_context = *state;
     429            1 :     spdm_context = spdm_test_context->spdm_context;
     430            1 :     spdm_test_context->case_id = 0x4;
     431            1 :     spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
     432              :                                             SPDM_VERSION_NUMBER_SHIFT_BIT;
     433            1 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
     434            1 :     spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
     435            1 :     spdm_context->local_context.capability.flags = 0; /* clear flags */
     436            1 :     spdm_context->local_context.capability.flags |=
     437              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_KEY_PAIR_INFO_CAP;
     438              : 
     439            1 :     key_pair_id = 4;
     440              : 
     441              :     /*set responder need reset, spdm 1.4 */
     442            1 :     spdm_context->local_context.capability.flags |=
     443              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_KEY_PAIR_RESET_CAP;
     444              : 
     445            1 :     response_size = sizeof(response);
     446              : 
     447              :     /*Before reset, change: remove an association with slot*/
     448            1 :     set_key_pair_info_request_size =
     449              :         sizeof(spdm_set_key_pair_info_request_t) +
     450              :         sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t) +
     451              :         sizeof(uint8_t);
     452              : 
     453            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
     454            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_14;
     455            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
     456            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION;
     457            1 :     set_key_pair_info_request->header.param2 = 0;
     458            1 :     set_key_pair_info_request->key_pair_id = key_pair_id;
     459              : 
     460            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     461              :         spdm_context, set_key_pair_info_request_size,
     462              :         set_key_pair_info_request, &response_size, response);
     463            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     464            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     465            1 :     spdm_response = (void *)response;
     466            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     467            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESET_REQUIRED);
     468            1 :     assert_int_equal(spdm_response->header.param2, 0);
     469              : 
     470              :     /*After reset, change: remove an association with slot*/
     471            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     472              :         spdm_context, set_key_pair_info_request_size,
     473              :         set_key_pair_info_request, &response_size, response);
     474            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     475            1 :     assert_int_equal(response_size, sizeof(spdm_set_key_pair_info_ack_response_t));
     476            1 :     spdm_response = (void *)response;
     477            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_SET_KEY_PAIR_INFO_ACK);
     478              : 
     479              :     /*Before reset, erase: erase the keyusage and asymalgo*/
     480            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_ERASE_OPERATION;
     481            1 :     set_key_pair_info_request_size = sizeof(spdm_set_key_pair_info_request_t);
     482            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     483              :         spdm_context, set_key_pair_info_request_size,
     484              :         set_key_pair_info_request, &response_size, response);
     485            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     486            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     487            1 :     spdm_response = (void *)response;
     488            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     489            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESET_REQUIRED);
     490            1 :     assert_int_equal(spdm_response->header.param2, 0);
     491              : 
     492              :     /*After reset, erase: erase the keyusage and asymalgo*/
     493            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     494              :         spdm_context, set_key_pair_info_request_size,
     495              :         set_key_pair_info_request, &response_size, response);
     496            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     497            1 :     assert_int_equal(response_size, sizeof(spdm_set_key_pair_info_ack_response_t));
     498            1 :     spdm_response = (void *)response;
     499            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_SET_KEY_PAIR_INFO_ACK);
     500              : 
     501              : 
     502              :     /*Before reset, generate: generate a new key pair*/
     503            1 :     desired_key_usage = SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE;
     504            1 :     desired_asym_algo = SPDM_KEY_PAIR_ASYM_ALGO_CAP_ECC256;
     505            1 :     desired_pqc_asym_algo_len = sizeof(desired_pqc_asym_algo);
     506            1 :     desired_pqc_asym_algo = 0;
     507            1 :     desired_assoc_cert_slot_mask = 0x08;
     508            1 :     set_key_pair_info_request_size =
     509              :         sizeof(spdm_set_key_pair_info_request_t) +
     510              :         sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t) +
     511              :         sizeof(uint8_t) + sizeof(uint32_t);
     512              : 
     513            1 :     libspdm_zero_mem(set_key_pair_info_request, set_key_pair_info_request_size);
     514            1 :     set_key_pair_info_request->header.spdm_version = SPDM_MESSAGE_VERSION_14;
     515            1 :     set_key_pair_info_request->header.request_response_code = SPDM_SET_KEY_PAIR_INFO;
     516            1 :     set_key_pair_info_request->header.param1 = SPDM_SET_KEY_PAIR_INFO_CHANGE_OPERATION;
     517            1 :     set_key_pair_info_request->header.param2 = 0;
     518            1 :     set_key_pair_info_request->key_pair_id = key_pair_id;
     519              : 
     520            1 :     ptr = (uint8_t*)(set_key_pair_info_request + 1);
     521            1 :     ptr += sizeof(uint8_t);
     522              : 
     523            1 :     libspdm_write_uint16(ptr, desired_key_usage);
     524            1 :     ptr += sizeof(uint16_t);
     525              : 
     526            1 :     libspdm_write_uint32(ptr, desired_asym_algo);
     527            1 :     ptr += sizeof(uint32_t);
     528              : 
     529            1 :     *ptr = desired_assoc_cert_slot_mask;
     530            1 :     ptr += sizeof(uint8_t);
     531              : 
     532            1 :     *ptr = desired_pqc_asym_algo_len;
     533            1 :     ptr += sizeof(uint8_t);
     534              : 
     535            1 :     libspdm_write_uint32(ptr, desired_pqc_asym_algo);
     536              : 
     537            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     538              :         spdm_context, set_key_pair_info_request_size,
     539              :         set_key_pair_info_request, &response_size, response);
     540            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     541            1 :     assert_int_equal(response_size, sizeof(spdm_error_response_t));
     542            1 :     spdm_response = (void *)response;
     543            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
     544            1 :     assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESET_REQUIRED);
     545            1 :     assert_int_equal(spdm_response->header.param2, 0);
     546              : 
     547              :     /*After reset, generate: generate a new key pair*/
     548            1 :     status = libspdm_get_response_set_key_pair_info_ack(
     549              :         spdm_context, set_key_pair_info_request_size,
     550              :         set_key_pair_info_request, &response_size, response);
     551            1 :     assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
     552            1 :     assert_int_equal(response_size, sizeof(spdm_set_key_pair_info_ack_response_t));
     553            1 :     spdm_response = (void *)response;
     554            1 :     assert_int_equal(spdm_response->header.request_response_code, SPDM_SET_KEY_PAIR_INFO_ACK);
     555            1 :     free(set_key_pair_info_request);
     556            1 : }
     557              : 
     558              : /**
     559              :  * Test 5: SET_KEY_PAIR_RESET replay where two requests differ only in DesiredPqcAsymAlgo.
     560              :  * This exercises the device_secret HAL (libspdm_write_key_pair_info) directly, since the
     561              :  * cached-request match that decides whether a post-reset replay is applied lives in the HAL.
     562              :  * Expected Behavior: a replay that changes only the PQC algorithm shall not be accepted as the
     563              :  * cached request; the correct PQC algorithm shall be applied only once the matching request is
     564              :  * replayed.
     565              :  **/
     566            1 : static void rsp_set_key_pair_info_ack_case5(void **state)
     567              : {
     568              :     libspdm_test_context_t *spdm_test_context;
     569              :     libspdm_context_t *spdm_context;
     570              :     uint8_t key_pair_id;
     571              :     bool need_reset;
     572              :     bool result;
     573              :     uint8_t total_key_pairs;
     574              :     uint16_t capabilities;
     575              :     uint16_t key_usage_capabilities;
     576              :     uint16_t current_key_usage;
     577              :     uint32_t asym_algo_capabilities;
     578              :     uint32_t current_asym_algo;
     579              :     uint32_t pqc_asym_algo_capabilities;
     580              :     uint32_t current_pqc_asym_algo;
     581              :     uint8_t assoc_cert_slot_mask;
     582              : 
     583            1 :     spdm_test_context = *state;
     584            1 :     spdm_context = spdm_test_context->spdm_context;
     585            1 :     spdm_test_context->case_id = 0x5;
     586              : 
     587            1 :     key_pair_id = 4;
     588              : 
     589              :     /* First request: GenerateKeyPair with ML-DSA-44. With need_reset = true the HAL caches the
     590              :      * request and reports that a reset is still required (not yet applied). */
     591            1 :     need_reset = true;
     592            1 :     result = libspdm_write_key_pair_info(
     593              :         spdm_context, key_pair_id, SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION,
     594              :         SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE, 0,
     595              :         SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_ML_DSA_44, 0, &need_reset);
     596            1 :     assert_true(result);
     597            1 :     assert_true(need_reset);
     598              : 
     599              :     /* Post-reset replay that differs only in DesiredPqcAsymAlgo (ML-DSA-65). This must NOT be
     600              :      * treated as the cached request: the HAL caches the new request and again reports that a
     601              :      * reset is required, rather than applying the stale ML-DSA-44 value. */
     602            1 :     need_reset = true;
     603            1 :     result = libspdm_write_key_pair_info(
     604              :         spdm_context, key_pair_id, SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION,
     605              :         SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE, 0,
     606              :         SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_ML_DSA_65, 0, &need_reset);
     607            1 :     assert_true(result);
     608            1 :     assert_true(need_reset);
     609              : 
     610              :     /* Replay the ML-DSA-65 request identically: now it matches the cached request and is
     611              :      * applied (need_reset cleared). */
     612            1 :     need_reset = true;
     613            1 :     result = libspdm_write_key_pair_info(
     614              :         spdm_context, key_pair_id, SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION,
     615              :         SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE, 0,
     616              :         SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_ML_DSA_65, 0, &need_reset);
     617            1 :     assert_true(result);
     618            1 :     assert_false(need_reset);
     619              : 
     620              :     /* The applied PQC algorithm shall be ML-DSA-65 (the replayed value), not ML-DSA-44. */
     621            1 :     assert_true(libspdm_read_key_pair_info(
     622              :                     spdm_context, key_pair_id, &total_key_pairs, &capabilities,
     623              :                     &key_usage_capabilities, &current_key_usage, &asym_algo_capabilities,
     624              :                     &current_asym_algo, &pqc_asym_algo_capabilities, &current_pqc_asym_algo,
     625              :                     &assoc_cert_slot_mask, NULL, NULL));
     626            1 :     assert_int_equal(current_pqc_asym_algo, SPDM_KEY_PAIR_PQC_ASYM_ALGO_CAP_ML_DSA_65);
     627            1 : }
     628              : 
     629            1 : int libspdm_rsp_set_key_pair_info_ack_test(void)
     630              : {
     631            1 :     const struct CMUnitTest test_cases[] = {
     632              :         /* Success Case to set key pair info*/
     633              :         cmocka_unit_test(rsp_set_key_pair_info_ack_case1),
     634              :         /* Can be populated with new test*/
     635              :         cmocka_unit_test(rsp_set_key_pair_info_ack_case2),
     636              :         /* The collection of multiple sub-cases.*/
     637              :         cmocka_unit_test(rsp_set_key_pair_info_ack_case3),
     638              :         /* Success Case to set key pair info with reset, spdm 1.4*/
     639              :         cmocka_unit_test(rsp_set_key_pair_info_ack_case4),
     640              :         /* Reset replay differing only in DesiredPqcAsymAlgo*/
     641              :         cmocka_unit_test(rsp_set_key_pair_info_ack_case5),
     642              :     };
     643              : 
     644            1 :     libspdm_test_context_t test_context = {
     645              :         LIBSPDM_TEST_CONTEXT_VERSION,
     646              :         false,
     647              :     };
     648            1 :     libspdm_setup_test_context(&test_context);
     649              : 
     650            1 :     return cmocka_run_group_tests(test_cases,
     651              :                                   libspdm_unit_test_group_setup,
     652              :                                   libspdm_unit_test_group_teardown);
     653              : }
     654              : 
     655              : #endif /* LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP*/
        

Generated by: LCOV version 2.0-1