LCOV - code coverage report
Current view: top level - library/spdm_requester_lib - libspdm_req_encap_key_update.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 86.9 % 61 53
Test Date: 2025-10-12 08:10:56 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-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_requester_lib.h"
       8              : #include "internal/libspdm_secured_message_lib.h"
       9              : 
      10              : #if (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && \
      11              :     ((LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP))
      12              : 
      13           15 : libspdm_return_t libspdm_get_encap_response_key_update(void *spdm_context,
      14              :                                                        size_t request_size,
      15              :                                                        void *request,
      16              :                                                        size_t *response_size,
      17              :                                                        void *response)
      18              : {
      19              :     uint32_t session_id;
      20              :     spdm_key_update_response_t *spdm_response;
      21              :     spdm_key_update_request_t *spdm_request;
      22              :     libspdm_context_t *context;
      23              :     libspdm_session_info_t *session_info;
      24              :     libspdm_session_state_t session_state;
      25              :     spdm_key_update_request_t *prev_spdm_request;
      26              :     spdm_key_update_request_t spdm_key_init_update_operation;
      27              :     bool result;
      28              : 
      29           15 :     context = spdm_context;
      30           15 :     spdm_request = request;
      31              : 
      32           15 :     if (libspdm_get_connection_version(context) < SPDM_MESSAGE_VERSION_11) {
      33            0 :         return libspdm_generate_encap_error_response(
      34              :             context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
      35              :             SPDM_KEY_UPDATE, response_size, response);
      36              :     }
      37              : 
      38           15 :     if (spdm_request->header.spdm_version != libspdm_get_connection_version(context)) {
      39            0 :         return libspdm_generate_encap_error_response(
      40              :             context, SPDM_ERROR_CODE_VERSION_MISMATCH,
      41              :             0, response_size, response);
      42              :     }
      43              : 
      44           15 :     if (!libspdm_is_capabilities_flag_supported(
      45              :             context, true,
      46              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP,
      47              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_UPD_CAP)) {
      48            1 :         return libspdm_generate_encap_error_response(
      49              :             context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
      50              :             SPDM_KEY_UPDATE, response_size, response);
      51              :     }
      52              : 
      53           14 :     if (!context->last_spdm_request_session_id_valid) {
      54            1 :         if (libspdm_get_connection_version(context) >= SPDM_MESSAGE_VERSION_12) {
      55            0 :             return libspdm_generate_encap_error_response(context,
      56              :                                                          SPDM_ERROR_CODE_SESSION_REQUIRED, 0,
      57              :                                                          response_size, response);
      58              :         } else {
      59            1 :             return libspdm_generate_encap_error_response(context,
      60              :                                                          SPDM_ERROR_CODE_UNSPECIFIED, 0,
      61              :                                                          response_size, response);
      62              :         }
      63              :     }
      64           13 :     session_id = context->last_spdm_request_session_id;
      65              :     session_info =
      66           13 :         libspdm_get_session_info_via_session_id(context, session_id);
      67           13 :     if (session_info == NULL) {
      68            0 :         return libspdm_generate_encap_error_response(
      69              :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
      70              :             response_size, response);
      71              :     }
      72           13 :     session_state = libspdm_secured_message_get_session_state(
      73              :         session_info->secured_message_context);
      74           13 :     if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
      75            1 :         return libspdm_generate_encap_error_response(
      76              :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
      77              :             response_size, response);
      78              :     }
      79              : 
      80              :     /* this message can only be in secured session
      81              :      * thus don't need to consider transport layer padding, just check its exact size */
      82           12 :     if (request_size != sizeof(spdm_key_update_request_t)) {
      83            2 :         return libspdm_generate_encap_error_response(
      84              :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
      85              :             response_size, response);
      86              :     }
      87              : 
      88              :     /*last key operation*/
      89           10 :     prev_spdm_request = &(session_info->last_key_update_request);
      90              : 
      91              :     /*the end status of the successful key update overall flow*/
      92           10 :     libspdm_zero_mem(&spdm_key_init_update_operation, sizeof(spdm_key_update_request_t));
      93              : 
      94           10 :     result = true;
      95           10 :     switch (spdm_request->header.param1) {
      96            5 :     case SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_KEY:
      97            5 :         if (!libspdm_consttime_is_mem_equal(prev_spdm_request,
      98              :                                             &spdm_key_init_update_operation,
      99              :                                             sizeof(spdm_key_update_request_t))) {
     100            1 :             result = false;
     101            1 :             break;
     102              :         }
     103            4 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     104              :                        "libspdm_create_update_session_data_key[%x] Responder\n",
     105              :                        session_id));
     106            4 :         result = libspdm_create_update_session_data_key(
     107              :             session_info->secured_message_context,
     108              :             LIBSPDM_KEY_UPDATE_ACTION_RESPONDER);
     109              : 
     110              :         /*save the last update operation*/
     111            4 :         libspdm_copy_mem(prev_spdm_request, sizeof(spdm_key_update_request_t),
     112              :                          spdm_request, request_size);
     113            4 :         break;
     114            1 :     case SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_ALL_KEYS:
     115            1 :         result = false;
     116            1 :         break;
     117            3 :     case SPDM_KEY_UPDATE_OPERATIONS_TABLE_VERIFY_NEW_KEY:
     118            3 :         if (prev_spdm_request->header.param1 != SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_KEY) {
     119            3 :             result = false;
     120            3 :             break;
     121              :         }
     122            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     123              :                        "libspdm_activate_update_session_data_key[%x] Responder new\n",
     124              :                        session_id));
     125            0 :         result = libspdm_activate_update_session_data_key(
     126              :             session_info->secured_message_context,
     127              :             LIBSPDM_KEY_UPDATE_ACTION_RESPONDER, true);
     128              : 
     129              :         /*clear last_key_update_request*/
     130            0 :         libspdm_zero_mem(prev_spdm_request, sizeof(spdm_key_update_request_t));
     131            0 :         break;
     132            1 :     default:
     133            1 :         result = false;
     134            1 :         break;
     135              :     }
     136              : 
     137           10 :     if (!result) {
     138            6 :         return libspdm_generate_encap_error_response(
     139              :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     140              :             response_size, response);
     141              :     }
     142              : 
     143            4 :     libspdm_reset_message_buffer_via_request_code(context, session_info,
     144            4 :                                                   spdm_request->header.request_response_code);
     145              : 
     146            4 :     LIBSPDM_ASSERT(*response_size >= sizeof(spdm_key_update_response_t));
     147            4 :     *response_size = sizeof(spdm_key_update_response_t);
     148            4 :     libspdm_zero_mem(response, *response_size);
     149            4 :     spdm_response = response;
     150              : 
     151            4 :     spdm_response->header.spdm_version = spdm_request->header.spdm_version;
     152            4 :     spdm_response->header.request_response_code = SPDM_KEY_UPDATE_ACK;
     153            4 :     spdm_response->header.param1 = spdm_request->header.param1;
     154            4 :     spdm_response->header.param2 = spdm_request->header.param2;
     155              : 
     156            4 :     return LIBSPDM_STATUS_SUCCESS;
     157              : }
     158              : 
     159              : #endif /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP && (...) */
        

Generated by: LCOV version 2.0-1