LCOV - code coverage report
Current view: top level - library/spdm_responder_lib - libspdm_rsp_digests.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.7 % 87 78
Test Date: 2025-06-29 08:09:00 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2024 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_CERT_CAP
      10              : 
      11           13 : libspdm_return_t libspdm_get_response_digests(libspdm_context_t *spdm_context, size_t request_size,
      12              :                                               const void *request,
      13              :                                               size_t *response_size,
      14              :                                               void *response)
      15              : {
      16              :     const spdm_get_digest_request_t *spdm_request;
      17              :     spdm_digest_response_t *spdm_response;
      18              :     size_t index;
      19              :     bool no_local_cert_chain;
      20              :     uint32_t hash_size;
      21              :     uint8_t *digest;
      22              :     libspdm_return_t status;
      23              :     bool result;
      24              :     libspdm_session_info_t *session_info;
      25              :     libspdm_session_state_t session_state;
      26              :     /*total populated slot count*/
      27              :     uint8_t slot_count;
      28              :     /*populated slot index*/
      29              :     uint8_t slot_index;
      30              :     size_t additional_size;
      31              :     spdm_key_pair_id_t *key_pair_id;
      32              :     spdm_certificate_info_t *cert_info;
      33              :     spdm_key_usage_bit_mask_t *key_usage_bit_mask;
      34              : 
      35           13 :     spdm_request = request;
      36              : 
      37              :     /* -=[Check Parameters Phase]=- */
      38           13 :     LIBSPDM_ASSERT(spdm_request->header.request_response_code == SPDM_GET_DIGESTS);
      39              : 
      40           13 :     if (spdm_request->header.spdm_version != libspdm_get_connection_version(spdm_context)) {
      41            0 :         return libspdm_generate_error_response(spdm_context,
      42              :                                                SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
      43              :                                                response_size, response);
      44              :     }
      45           13 :     if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
      46            4 :         return libspdm_responder_handle_response_state(
      47              :             spdm_context,
      48            4 :             spdm_request->header.request_response_code,
      49              :             response_size, response);
      50              :     }
      51            9 :     if (!libspdm_is_capabilities_flag_supported(
      52              :             spdm_context, false, 0,
      53              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP)) {
      54            0 :         return libspdm_generate_error_response(
      55              :             spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
      56              :             SPDM_GET_DIGESTS, response_size, response);
      57              :     }
      58            9 :     if (spdm_context->connection_info.connection_state <
      59              :         LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
      60            1 :         return libspdm_generate_error_response(spdm_context,
      61              :                                                SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
      62              :                                                0, response_size, response);
      63              :     }
      64            8 :     session_info = NULL;
      65            8 :     if (spdm_context->last_spdm_request_session_id_valid) {
      66            1 :         session_info = libspdm_get_session_info_via_session_id(
      67              :             spdm_context,
      68              :             spdm_context->last_spdm_request_session_id);
      69            1 :         if (session_info == NULL) {
      70            0 :             return libspdm_generate_error_response(
      71              :                 spdm_context,
      72              :                 SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
      73              :                 response_size, response);
      74              :         }
      75            1 :         session_state = libspdm_secured_message_get_session_state(
      76              :             session_info->secured_message_context);
      77            1 :         if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
      78            0 :             return libspdm_generate_error_response(
      79              :                 spdm_context,
      80              :                 SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
      81              :                 response_size, response);
      82              :         }
      83              :     }
      84              : 
      85            8 :     if (request_size < sizeof(spdm_get_digest_request_t)) {
      86            0 :         return libspdm_generate_error_response(spdm_context,
      87              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
      88              :                                                response_size, response);
      89              :     }
      90            8 :     if (spdm_context->local_context.cert_slot_reset_mask != 0) {
      91            1 :         LIBSPDM_ASSERT(spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12);
      92            1 :         return libspdm_generate_error_response(spdm_context,
      93              :                                                SPDM_ERROR_CODE_RESET_REQUIRED, 0,
      94              :                                                response_size, response);
      95              :     }
      96              : 
      97            7 :     libspdm_reset_message_buffer_via_request_code(spdm_context, session_info,
      98            7 :                                                   spdm_request->header.request_response_code);
      99              : 
     100            7 :     no_local_cert_chain = true;
     101           63 :     for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
     102           56 :         if (spdm_context->local_context
     103           56 :             .local_cert_chain_provision[index] != NULL) {
     104           13 :             no_local_cert_chain = false;
     105              :         }
     106              :     }
     107            7 :     if (no_local_cert_chain) {
     108            1 :         return libspdm_generate_error_response(
     109              :             spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
     110              :             0, response_size, response);
     111              :     }
     112              : 
     113            6 :     hash_size = libspdm_get_hash_size(
     114              :         spdm_context->connection_info.algorithm.base_hash_algo);
     115              : 
     116            6 :     slot_count = libspdm_get_cert_slot_count(spdm_context);
     117            6 :     additional_size = 0;
     118            6 :     if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
     119            3 :         spdm_context->connection_info.multi_key_conn_rsp) {
     120            2 :         additional_size = sizeof(spdm_key_pair_id_t) + sizeof(spdm_certificate_info_t) +
     121              :                           sizeof(spdm_key_usage_bit_mask_t);
     122              :     }
     123            6 :     LIBSPDM_ASSERT(*response_size >=
     124              :                    sizeof(spdm_digest_response_t) + (hash_size + additional_size) * slot_count);
     125            6 :     *response_size = sizeof(spdm_digest_response_t) + (hash_size + additional_size) * slot_count;
     126            6 :     libspdm_zero_mem(response, *response_size);
     127            6 :     spdm_response = response;
     128              : 
     129            6 :     spdm_response->header.spdm_version = spdm_request->header.spdm_version;
     130            6 :     spdm_response->header.request_response_code = SPDM_DIGESTS;
     131            6 :     spdm_response->header.param1 = 0;
     132            6 :     spdm_response->header.param2 = 0;
     133              : 
     134            6 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     135            3 :         spdm_response->header.param1 = spdm_context->local_context.local_supported_slot_mask;
     136              :     }
     137              : 
     138            6 :     digest = (void *)(spdm_response + 1);
     139            6 :     key_pair_id = (spdm_key_pair_id_t *)((uint8_t *)digest + hash_size * slot_count);
     140            6 :     cert_info = (spdm_certificate_info_t *)((uint8_t *)key_pair_id +
     141            6 :                                             sizeof(spdm_key_pair_id_t) * slot_count);
     142            6 :     key_usage_bit_mask = (spdm_key_usage_bit_mask_t *)((uint8_t *)cert_info +
     143            6 :                                                        sizeof(spdm_certificate_info_t) *
     144              :                                                        slot_count);
     145              : 
     146            6 :     slot_index = 0;
     147           54 :     for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
     148           48 :         if (spdm_context->local_context
     149           48 :             .local_cert_chain_provision[index] != NULL) {
     150           13 :             spdm_response->header.param2 |= (1 << index);
     151           13 :             result = libspdm_generate_cert_chain_hash(spdm_context, index,
     152           13 :                                                       &digest[hash_size * slot_index]);
     153           13 :             if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
     154           10 :                 spdm_context->connection_info.multi_key_conn_rsp) {
     155            9 :                 key_pair_id[slot_index] = spdm_context->local_context.local_key_pair_id[index];
     156            9 :                 cert_info[slot_index] = spdm_context->local_context.local_cert_info[index];
     157            9 :                 key_usage_bit_mask[slot_index] =
     158            9 :                     spdm_context->local_context.local_key_usage_bit_mask[index];
     159              :             }
     160           13 :             slot_index++;
     161           13 :             if (!result) {
     162            0 :                 return libspdm_generate_error_response(
     163              :                     spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
     164              :                     0, response_size, response);
     165              :             }
     166              :         }
     167              :     }
     168              : 
     169            6 :     if (session_info == NULL) {
     170              :         /* Log to transcript. */
     171            5 :         const size_t spdm_request_size = sizeof(spdm_get_digest_request_t);
     172              : 
     173            5 :         status = libspdm_append_message_b(spdm_context, spdm_request, spdm_request_size);
     174            5 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     175            0 :             return libspdm_generate_error_response(spdm_context,
     176              :                                                    SPDM_ERROR_CODE_UNSPECIFIED, 0,
     177              :                                                    response_size, response);
     178              :         }
     179              : 
     180            5 :         status = libspdm_append_message_b(spdm_context, spdm_response, *response_size);
     181            5 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     182            0 :             return libspdm_generate_error_response(spdm_context,
     183              :                                                    SPDM_ERROR_CODE_UNSPECIFIED, 0,
     184              :                                                    response_size, response);
     185              :         }
     186              : 
     187            5 :         if (spdm_context->connection_info.multi_key_conn_rsp) {
     188            2 :             status = libspdm_append_message_d(spdm_context, spdm_response, *response_size);
     189            2 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     190            0 :                 return libspdm_generate_error_response(spdm_context,
     191              :                                                        SPDM_ERROR_CODE_UNSPECIFIED, 0,
     192              :                                                        response_size, response);
     193              :             }
     194              :         }
     195              :     }
     196              : 
     197            6 :     if (spdm_context->connection_info.connection_state <
     198              :         LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS) {
     199            5 :         libspdm_set_connection_state(spdm_context,
     200              :                                      LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS);
     201              :     }
     202              : 
     203            6 :     return LIBSPDM_STATUS_SUCCESS;
     204              : }
     205              : 
     206              : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
        

Generated by: LCOV version 2.0-1