LCOV - code coverage report
Current view: top level - library/spdm_responder_lib - libspdm_rsp_set_key_pair_info_ack.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 61.1 % 108 66
Test Date: 2025-08-24 08:11:14 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2024-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 "internal/libspdm_responder_lib.h"
       8              : 
       9              : #if LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP
      10              : 
      11           15 : libspdm_return_t libspdm_get_response_set_key_pair_info_ack(libspdm_context_t *spdm_context,
      12              :                                                             size_t request_size,
      13              :                                                             const void *request,
      14              :                                                             size_t *response_size,
      15              :                                                             void *response)
      16              : {
      17              :     const spdm_set_key_pair_info_request_t *spdm_request;
      18              :     spdm_set_key_pair_info_ack_response_t *spdm_response;
      19              : 
      20              :     libspdm_session_info_t *session_info;
      21              :     libspdm_session_state_t session_state;
      22              : 
      23              :     uint16_t capabilities;
      24              :     uint16_t key_usage_capabilities;
      25              :     uint16_t current_key_usage;
      26              :     uint32_t asym_algo_capabilities;
      27              :     uint32_t current_asym_algo;
      28              :     uint32_t pqc_asym_algo_capabilities;
      29              :     uint32_t current_pqc_asym_algo;
      30              :     uint8_t assoc_cert_slot_mask;
      31              :     uint8_t key_pair_id;
      32              :     uint8_t total_key_pairs;
      33              :     bool result;
      34              : 
      35              :     uint16_t desired_key_usage;
      36              :     uint32_t desired_asym_algo;
      37              :     uint8_t desired_assoc_cert_slot_mask;
      38              :     uint8_t desired_pqc_asym_algo_len;
      39              :     uint32_t desired_pqc_asym_algo;
      40              :     uint8_t operation;
      41              :     bool need_reset;
      42              :     const uint8_t *ptr;
      43              : 
      44           15 :     spdm_request = request;
      45              : 
      46              :     /* -=[Check Parameters Phase]=- */
      47           15 :     LIBSPDM_ASSERT(spdm_request->header.request_response_code == SPDM_SET_KEY_PAIR_INFO);
      48              : 
      49           15 :     if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_13) {
      50            0 :         return libspdm_generate_error_response(spdm_context,
      51              :                                                SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
      52              :                                                SPDM_SET_KEY_PAIR_INFO,
      53              :                                                response_size, response);
      54              :     }
      55              : 
      56           15 :     if (spdm_request->header.spdm_version != libspdm_get_connection_version(spdm_context)) {
      57            0 :         return libspdm_generate_error_response(spdm_context,
      58              :                                                SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
      59              :                                                response_size, response);
      60              :     }
      61              : 
      62           15 :     if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
      63            0 :         return libspdm_responder_handle_response_state(spdm_context,
      64            0 :                                                        spdm_request->header.request_response_code,
      65              :                                                        response_size, response);
      66              :     }
      67              : 
      68           15 :     if (request_size < sizeof(spdm_set_key_pair_info_request_t)) {
      69            0 :         return libspdm_generate_error_response(spdm_context,
      70              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
      71              :                                                response_size, response);
      72              :     }
      73              : 
      74           15 :     if (spdm_context->connection_info.connection_state <
      75              :         LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
      76            0 :         return libspdm_generate_error_response(
      77              :             spdm_context,
      78              :             SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
      79              :             response_size, response);
      80              :     }
      81              : 
      82           15 :     if (spdm_context->last_spdm_request_session_id_valid) {
      83            0 :         session_info = libspdm_get_session_info_via_session_id(
      84              :             spdm_context,
      85              :             spdm_context->last_spdm_request_session_id);
      86            0 :         if (session_info == NULL) {
      87            0 :             return libspdm_generate_error_response(
      88              :                 spdm_context,
      89              :                 SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
      90              :                 response_size, response);
      91              :         }
      92            0 :         session_state = libspdm_secured_message_get_session_state(
      93              :             session_info->secured_message_context);
      94            0 :         if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
      95            0 :             return libspdm_generate_error_response(
      96              :                 spdm_context,
      97              :                 SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
      98              :                 response_size, response);
      99              :         }
     100              :     }
     101              : 
     102           15 :     if (!libspdm_is_capabilities_flag_supported(
     103              :             spdm_context, false, 0,
     104              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_KEY_PAIR_INFO_CAP)) {
     105            0 :         return libspdm_generate_error_response(
     106              :             spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
     107              :             SPDM_SET_KEY_PAIR_INFO, response_size, response);
     108              :     }
     109              : 
     110           15 :     total_key_pairs = spdm_context->local_context.total_key_pairs;
     111           15 :     key_pair_id = spdm_request->key_pair_id;
     112           15 :     if ((key_pair_id == 0) || (key_pair_id > total_key_pairs)) {
     113            1 :         return libspdm_generate_error_response(spdm_context,
     114              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     115              :                                                response_size, response);
     116              :     }
     117              : 
     118           14 :     LIBSPDM_ASSERT(*response_size >= sizeof(spdm_set_key_pair_info_ack_response_t));
     119              : 
     120           14 :     libspdm_zero_mem(response, *response_size);
     121              : 
     122           14 :     result = libspdm_read_key_pair_info(
     123              :         spdm_context,
     124              :         key_pair_id,
     125              :         &capabilities,
     126              :         &key_usage_capabilities,
     127              :         &current_key_usage,
     128              :         &asym_algo_capabilities,
     129              :         &current_asym_algo,
     130              :         &pqc_asym_algo_capabilities,
     131              :         &current_pqc_asym_algo,
     132              :         &assoc_cert_slot_mask,
     133              :         NULL, NULL);
     134           14 :     if (!result) {
     135            0 :         return libspdm_generate_error_response(spdm_context,
     136              :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     137              :                                                response_size, response);
     138              :     }
     139              : 
     140           14 :     operation = spdm_request->header.param1;
     141              : 
     142           14 :     if (operation != SPDM_SET_KEY_PAIR_INFO_ERASE_OPERATION) {
     143           10 :         if (request_size < sizeof(spdm_set_key_pair_info_request_t) +
     144              :             sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t)) {
     145            1 :             return libspdm_generate_error_response(spdm_context,
     146              :                                                    SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     147              :                                                    response_size, response);
     148              :         }
     149              : 
     150            9 :         ptr = (const uint8_t*)(spdm_request + 1);
     151            9 :         ptr += sizeof(uint8_t);
     152              : 
     153            9 :         desired_key_usage = libspdm_read_uint16((const uint8_t *)ptr);
     154            9 :         ptr += sizeof(uint16_t);
     155              : 
     156            9 :         desired_asym_algo = libspdm_read_uint32((const uint8_t *)ptr);
     157            9 :         ptr += sizeof(uint32_t);
     158              : 
     159            9 :         desired_assoc_cert_slot_mask = *ptr;
     160            9 :         ptr += sizeof(uint8_t);
     161              : 
     162            9 :         desired_pqc_asym_algo = 0;
     163            9 :         if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_14) {
     164            0 :             if (request_size < sizeof(spdm_set_key_pair_info_request_t) +
     165              :                 sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t) +
     166              :                 sizeof(uint8_t)) {
     167            0 :                 return libspdm_generate_error_response(spdm_context,
     168              :                                                        SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     169              :                                                        response_size, response);
     170              :             }
     171              : 
     172            0 :             desired_pqc_asym_algo_len = *ptr;
     173            0 :             ptr += sizeof(uint8_t);
     174              : 
     175            0 :             if (request_size < sizeof(spdm_set_key_pair_info_request_t) +
     176              :                 sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint8_t) +
     177            0 :                 sizeof(uint8_t) + desired_pqc_asym_algo_len) {
     178            0 :                 return libspdm_generate_error_response(spdm_context,
     179              :                                                        SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     180              :                                                        response_size, response);
     181              :             }
     182              : 
     183            0 :             if (desired_pqc_asym_algo_len > sizeof(uint32_t)) {
     184            0 :                 desired_pqc_asym_algo_len = sizeof(uint32_t);
     185              :             }
     186            0 :             libspdm_copy_mem (&desired_pqc_asym_algo, sizeof(desired_pqc_asym_algo),
     187              :                               ptr, desired_pqc_asym_algo_len);
     188            0 :             ptr += desired_pqc_asym_algo_len;
     189              :         }
     190              : 
     191              :     } else {
     192            4 :         desired_key_usage = 0;
     193            4 :         desired_asym_algo = 0;
     194            4 :         desired_pqc_asym_algo = 0;
     195            4 :         desired_assoc_cert_slot_mask = 0;
     196              :     }
     197              : 
     198           13 :     if (((capabilities & SPDM_KEY_PAIR_CAP_GEN_KEY_CAP) == 0) &&
     199              :         (operation == SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION)) {
     200            0 :         return libspdm_generate_error_response(spdm_context,
     201              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     202              :                                                response_size, response);
     203              :     }
     204           13 :     if (((capabilities & SPDM_KEY_PAIR_CAP_ERASABLE_CAP) == 0) &&
     205              :         (operation == SPDM_SET_KEY_PAIR_INFO_ERASE_OPERATION)) {
     206            0 :         return libspdm_generate_error_response(spdm_context,
     207              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     208              :                                                response_size, response);
     209              :     }
     210           13 :     if (((capabilities & SPDM_KEY_PAIR_CAP_CERT_ASSOC_CAP) == 0) &&
     211            0 :         (desired_assoc_cert_slot_mask != 0) &&
     212            0 :         (desired_assoc_cert_slot_mask != assoc_cert_slot_mask)) {
     213            0 :         return libspdm_generate_error_response(spdm_context,
     214              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     215              :                                                response_size, response);
     216              :     }
     217              : 
     218           13 :     if (((capabilities & SPDM_KEY_PAIR_CAP_KEY_USAGE_CAP) == 0) && (desired_key_usage != 0)) {
     219            0 :         return libspdm_generate_error_response(spdm_context,
     220              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     221              :                                                response_size, response);
     222              :     }
     223           13 :     if ((desired_key_usage != 0) &&
     224            4 :         ((key_usage_capabilities | desired_key_usage) != key_usage_capabilities)) {
     225            0 :         return libspdm_generate_error_response(spdm_context,
     226              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     227              :                                                response_size, response);
     228              :     }
     229              : 
     230           13 :     if (((capabilities & SPDM_KEY_PAIR_CAP_ASYM_ALGO_CAP) == 0) &&
     231            0 :         ((desired_asym_algo != 0) || (desired_pqc_asym_algo != 0))) {
     232            0 :         return libspdm_generate_error_response(spdm_context,
     233              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     234              :                                                response_size, response);
     235              :     }
     236           13 :     if (!libspdm_onehot0(desired_asym_algo) || !libspdm_onehot0(desired_pqc_asym_algo)) {
     237            1 :         return libspdm_generate_error_response(spdm_context,
     238              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     239              :                                                response_size, response);
     240              :     }
     241           12 :     if ((desired_asym_algo != 0) && (desired_pqc_asym_algo != 0)) {
     242            0 :         return libspdm_generate_error_response(spdm_context,
     243              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     244              :                                                response_size, response);
     245              :     }
     246           12 :     if ((desired_asym_algo != 0) &&
     247            3 :         ((asym_algo_capabilities | desired_asym_algo) != asym_algo_capabilities)) {
     248            0 :         return libspdm_generate_error_response(spdm_context,
     249              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     250              :                                                response_size, response);
     251              :     }
     252           12 :     if ((desired_pqc_asym_algo != 0) &&
     253            0 :         ((pqc_asym_algo_capabilities | desired_pqc_asym_algo) != pqc_asym_algo_capabilities)) {
     254            0 :         return libspdm_generate_error_response(
     255              :             spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
     256              :             SPDM_SET_KEY_PAIR_INFO, response_size, response);
     257              :     }
     258              : 
     259           12 :     if (((capabilities & SPDM_KEY_PAIR_CAP_SHAREABLE_CAP) == 0) &&
     260            0 :         (!libspdm_onehot0(desired_assoc_cert_slot_mask))) {
     261            0 :         return libspdm_generate_error_response(spdm_context,
     262              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     263              :                                                response_size, response);
     264              :     }
     265           12 :     if (operation > SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION) {
     266            0 :         return libspdm_generate_error_response(spdm_context,
     267              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     268              :                                                response_size, response);
     269              :     }
     270           12 :     if ((operation == SPDM_SET_KEY_PAIR_INFO_ERASE_OPERATION) ||
     271              :         (operation == SPDM_SET_KEY_PAIR_INFO_GENERATE_OPERATION)) {
     272            4 :         if (assoc_cert_slot_mask != 0) {
     273            1 :             return libspdm_generate_error_response(spdm_context,
     274              :                                                    SPDM_ERROR_CODE_OPERATION_FAILED, 0,
     275              :                                                    response_size, response);
     276              :         }
     277              :     }
     278              : 
     279           11 :     need_reset = libspdm_is_capabilities_flag_supported(
     280              :         spdm_context, false, 0,
     281              :         SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP);
     282           11 :     result = libspdm_write_key_pair_info(
     283              :         spdm_context,
     284              :         key_pair_id,
     285              :         operation,
     286              :         desired_key_usage,
     287              :         desired_asym_algo,
     288              :         desired_pqc_asym_algo,
     289              :         desired_assoc_cert_slot_mask,
     290              :         &need_reset);
     291           11 :     if (!result) {
     292            0 :         return libspdm_generate_error_response(spdm_context,
     293              :                                                SPDM_ERROR_CODE_OPERATION_FAILED, 0,
     294              :                                                response_size, response);
     295              :     }
     296              : 
     297           11 :     spdm_response = response;
     298           11 :     *response_size = sizeof(spdm_set_key_pair_info_ack_response_t);
     299              : 
     300           11 :     if (need_reset) {
     301            5 :         return libspdm_generate_error_response(spdm_context,
     302              :                                                SPDM_ERROR_CODE_RESET_REQUIRED, 0,
     303              :                                                response_size, response);
     304              :     } else {
     305            6 :         spdm_response->header.spdm_version = spdm_request->header.spdm_version;
     306            6 :         spdm_response->header.request_response_code = SPDM_SET_KEY_PAIR_INFO_ACK;
     307            6 :         spdm_response->header.param1 = 0;
     308            6 :         spdm_response->header.param2 = 0;
     309              :     }
     310              : 
     311            6 :     return LIBSPDM_STATUS_SUCCESS;
     312              : }
     313              : 
     314              : #endif /*LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP*/
        

Generated by: LCOV version 2.0-1