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-06-29 08:09:00 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              : 
      12           15 : libspdm_return_t libspdm_get_encap_response_key_update(void *spdm_context,
      13              :                                                        size_t request_size,
      14              :                                                        void *request,
      15              :                                                        size_t *response_size,
      16              :                                                        void *response)
      17              : {
      18              :     uint32_t session_id;
      19              :     spdm_key_update_response_t *spdm_response;
      20              :     spdm_key_update_request_t *spdm_request;
      21              :     libspdm_context_t *context;
      22              :     libspdm_session_info_t *session_info;
      23              :     libspdm_session_state_t session_state;
      24              :     spdm_key_update_request_t *prev_spdm_request;
      25              :     spdm_key_update_request_t spdm_key_init_update_operation;
      26              :     bool result;
      27              : 
      28           15 :     context = spdm_context;
      29           15 :     spdm_request = request;
      30              : 
      31           15 :     if (libspdm_get_connection_version(context) < SPDM_MESSAGE_VERSION_11) {
      32            0 :         return libspdm_generate_encap_error_response(
      33              :             context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
      34              :             SPDM_KEY_UPDATE, response_size, response);
      35              :     }
      36              : 
      37           15 :     if (spdm_request->header.spdm_version != libspdm_get_connection_version(context)) {
      38            0 :         return libspdm_generate_encap_error_response(
      39              :             context, SPDM_ERROR_CODE_VERSION_MISMATCH,
      40              :             0, response_size, response);
      41              :     }
      42              : 
      43           15 :     if (!libspdm_is_capabilities_flag_supported(
      44              :             context, true,
      45              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP,
      46              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_UPD_CAP)) {
      47            1 :         return libspdm_generate_encap_error_response(
      48              :             context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
      49              :             SPDM_KEY_UPDATE, response_size, response);
      50              :     }
      51              : 
      52           14 :     if (!context->last_spdm_request_session_id_valid) {
      53            1 :         if (libspdm_get_connection_version(context) >= SPDM_MESSAGE_VERSION_12) {
      54            0 :             return libspdm_generate_encap_error_response(context,
      55              :                                                          SPDM_ERROR_CODE_SESSION_REQUIRED, 0,
      56              :                                                          response_size, response);
      57              :         } else {
      58            1 :             return libspdm_generate_encap_error_response(context,
      59              :                                                          SPDM_ERROR_CODE_UNSPECIFIED, 0,
      60              :                                                          response_size, response);
      61              :         }
      62              :     }
      63           13 :     session_id = context->last_spdm_request_session_id;
      64              :     session_info =
      65           13 :         libspdm_get_session_info_via_session_id(context, session_id);
      66           13 :     if (session_info == NULL) {
      67            0 :         return libspdm_generate_encap_error_response(
      68              :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
      69              :             response_size, response);
      70              :     }
      71           13 :     session_state = libspdm_secured_message_get_session_state(
      72              :         session_info->secured_message_context);
      73           13 :     if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
      74            1 :         return libspdm_generate_encap_error_response(
      75              :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
      76              :             response_size, response);
      77              :     }
      78              : 
      79              :     /* this message can only be in secured session
      80              :      * thus don't need to consider transport layer padding, just check its exact size */
      81           12 :     if (request_size != sizeof(spdm_key_update_request_t)) {
      82            2 :         return libspdm_generate_encap_error_response(
      83              :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
      84              :             response_size, response);
      85              :     }
      86              : 
      87              :     /*last key operation*/
      88           10 :     prev_spdm_request = &(session_info->last_key_update_request);
      89              : 
      90              :     /*the end status of the successful key update overall flow*/
      91           10 :     libspdm_zero_mem(&spdm_key_init_update_operation, sizeof(spdm_key_update_request_t));
      92              : 
      93           10 :     result = true;
      94           10 :     switch (spdm_request->header.param1) {
      95            5 :     case SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_KEY:
      96            5 :         if(!libspdm_consttime_is_mem_equal(prev_spdm_request,
      97              :                                            &spdm_key_init_update_operation,
      98              :                                            sizeof(spdm_key_update_request_t))) {
      99            1 :             result = false;
     100            1 :             break;
     101              :         }
     102            4 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     103              :                        "libspdm_create_update_session_data_key[%x] Responder\n",
     104              :                        session_id));
     105            4 :         result = libspdm_create_update_session_data_key(
     106              :             session_info->secured_message_context,
     107              :             LIBSPDM_KEY_UPDATE_ACTION_RESPONDER);
     108              : 
     109              :         /*save the last update operation*/
     110            4 :         libspdm_copy_mem(prev_spdm_request, sizeof(spdm_key_update_request_t),
     111              :                          spdm_request, request_size);
     112            4 :         break;
     113            1 :     case SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_ALL_KEYS:
     114            1 :         result = false;
     115            1 :         break;
     116            3 :     case SPDM_KEY_UPDATE_OPERATIONS_TABLE_VERIFY_NEW_KEY:
     117            3 :         if(prev_spdm_request->header.param1 !=
     118              :            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