LCOV - code coverage report
Current view: top level - spdm_requester_lib - libspdm_req_get_csr.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 93.3 % 120 112
Test Date: 2026-10-01 20:56:25 Functions: 100.0 % 2 2
Branches: 87.5 % 88 77

             Branch data     Line data    Source code
       1                 :             : /**
       2                 :             :  *  Copyright Notice:
       3                 :             :  *  Copyright 2021-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 "internal/libspdm_requester_lib.h"
       8                 :             : 
       9                 :             : #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP
      10                 :             : 
      11                 :             : /**
      12                 :             :  * This function sends GET_CSR
      13                 :             :  * to get csr from the device.
      14                 :             :  *
      15                 :             :  * @param[in]  spdm_context                 A pointer to the SPDM context.
      16                 :             :  * @param[in]  session_id                   Indicates if it is a secured message protected via SPDM session.
      17                 :             :  *                                          If session_id is NULL, it is a normal message.
      18                 :             :  *                                          If session_id is NOT NULL, it is a secured message.
      19                 :             :  * @param[in]  requester_info               requester info to gen CSR
      20                 :             :  * @param[in]  requester_info_length        The len of requester info
      21                 :             :  * @param[in]  opaque_data                  opaque data
      22                 :             :  * @param[in]  opaque_data_length           The len of opaque data
      23                 :             :  * @param[out] csr                          address to store CSR.
      24                 :             :  * @param[in, out] csr_len                  on input, *csr_len indicates the max csr buffer size.
      25                 :             :  *                                          on output, *csr_len indicates the actual csr buffer size.
      26                 :             :  * @param[in]  request_attribute            GET_CSR request attributes. This field is only used for SPDM 1.3 and above.
      27                 :             :  * @param[in]  key_pair_id                  The value of this field shall be the unique key pair number identifying the desired
      28                 :             :  *                                          asymmetric key pair to associate with SlotID .
      29                 :             :  * @param[out] available_csr_tracking_tag   available CSRTrackingTag when the Responder sends a ResetRequired error message
      30                 :             :  **/
      31                 :          29 : static libspdm_return_t libspdm_try_get_csr(libspdm_context_t *spdm_context,
      32                 :             :                                             const uint32_t *session_id,
      33                 :             :                                             void *requester_info, uint16_t requester_info_length,
      34                 :             :                                             void *opaque_data, uint16_t opaque_data_length,
      35                 :             :                                             void *csr, size_t *csr_len,
      36                 :             :                                             uint8_t request_attribute,
      37                 :             :                                             uint8_t key_pair_id,
      38                 :             :                                             uint8_t *available_csr_tracking_tag)
      39                 :             : {
      40                 :             :     libspdm_return_t status;
      41                 :             :     libspdm_return_t warning;
      42                 :             :     spdm_get_csr_request_t *spdm_request;
      43                 :             :     size_t spdm_request_size;
      44                 :             :     spdm_csr_response_t *spdm_response;
      45                 :             :     size_t spdm_response_size;
      46                 :             :     size_t transport_header_size;
      47                 :             :     uint8_t *message;
      48                 :             :     size_t message_size;
      49                 :             :     libspdm_session_info_t *session_info;
      50                 :             :     libspdm_session_state_t session_state;
      51                 :             : 
      52                 :          29 :     warning = LIBSPDM_STATUS_SUCCESS;
      53                 :             : 
      54         [ +  + ]:          29 :     if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_12) {
      55                 :           1 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
      56                 :             :     }
      57         [ +  + ]:          28 :     if (libspdm_get_connection_version(spdm_context) == SPDM_MESSAGE_VERSION_12) {
      58   [ +  +  +  + ]:           7 :         if ((key_pair_id != 0) || (request_attribute != 0)) {
      59                 :           2 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
      60                 :             :         }
      61                 :             :     }
      62                 :             : 
      63         [ +  + ]:          26 :     if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) {
      64                 :          21 :         const uint8_t csr_cert_model = request_attribute &
      65                 :             :                                        SPDM_GET_CSR_REQUEST_ATTRIBUTES_CERT_MODEL_MASK;
      66                 :             : 
      67                 :             :         /* CSR_CAP for a 1.2 Responder is not checked because it was not defined in SPDM 1.2.0. */
      68         [ +  + ]:          21 :         if (!libspdm_is_capabilities_flag_supported(
      69                 :             :                 spdm_context, true, 0,
      70                 :             :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP)) {
      71                 :           1 :             return LIBSPDM_STATUS_UNSUPPORTED_CAP;
      72                 :             :         }
      73         [ +  + ]:          20 :         if (spdm_context->connection_info.multi_key_conn_rsp) {
      74         [ +  + ]:           3 :             if (key_pair_id == 0) {
      75                 :           1 :                 return LIBSPDM_STATUS_INVALID_PARAMETER;
      76                 :             :             }
      77   [ +  +  +  - ]:           2 :             if ((csr_cert_model == SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE) ||
      78                 :             :                 (csr_cert_model > SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT)) {
      79                 :           2 :                 return LIBSPDM_STATUS_INVALID_PARAMETER;
      80                 :             :             }
      81                 :             :         } else {
      82   [ +  +  +  + ]:          17 :             if ((key_pair_id != 0) || (csr_cert_model != 0)) {
      83                 :           2 :                 return LIBSPDM_STATUS_INVALID_PARAMETER;
      84                 :             :             }
      85                 :             :         }
      86                 :             :     }
      87                 :             : 
      88         [ -  + ]:          20 :     LIBSPDM_ASSERT(opaque_data_length < SPDM_MAX_OPAQUE_DATA_SIZE);
      89                 :             : 
      90         [ +  + ]:          20 :     if (spdm_context->connection_info.connection_state <
      91                 :             :         LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
      92                 :           1 :         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
      93                 :             :     }
      94                 :             : 
      95         [ +  + ]:          19 :     if (session_id != NULL) {
      96                 :           1 :         session_info = libspdm_get_session_info_via_session_id(
      97                 :             :             spdm_context, *session_id);
      98         [ -  + ]:           1 :         if (session_info == NULL) {
      99                 :           0 :             LIBSPDM_ASSERT(false);
     100                 :           0 :             return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     101                 :             :         }
     102                 :           1 :         session_state = libspdm_secured_message_get_session_state(
     103                 :             :             session_info->secured_message_context);
     104         [ +  - ]:           1 :         if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
     105                 :           1 :             return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     106                 :             :         }
     107                 :             :     }
     108                 :             : 
     109                 :          18 :     transport_header_size = spdm_context->local_context.capability.transport_header_size;
     110                 :          18 :     status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
     111         [ +  + ]:          18 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     112                 :           1 :         return status;
     113                 :             :     }
     114         [ -  + ]:          17 :     LIBSPDM_ASSERT (message_size >= transport_header_size +
     115                 :             :                     spdm_context->local_context.capability.transport_tail_size);
     116                 :          17 :     spdm_request = (void *)(message + transport_header_size);
     117                 :          17 :     spdm_request_size = message_size - transport_header_size -
     118                 :          17 :                         spdm_context->local_context.capability.transport_tail_size;
     119                 :             : 
     120         [ -  + ]:          17 :     LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_get_csr_request_t) + opaque_data_length
     121                 :             :                     + requester_info_length);
     122                 :          17 :     spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
     123                 :          17 :     spdm_request->header.request_response_code = SPDM_GET_CSR;
     124                 :          17 :     spdm_request->header.param1 = key_pair_id;
     125                 :          17 :     spdm_request->header.param2 = request_attribute;
     126                 :             : 
     127                 :          17 :     spdm_request->opaque_data_length = opaque_data_length;
     128                 :          17 :     spdm_request->requester_info_length = requester_info_length;
     129                 :             : 
     130         [ +  + ]:          17 :     if (requester_info_length != 0) {
     131                 :           2 :         libspdm_copy_mem(spdm_request + 1,
     132                 :             :                          spdm_request_size - sizeof(spdm_get_csr_request_t),
     133                 :             :                          (uint8_t *)requester_info, requester_info_length);
     134                 :             :     }
     135                 :             : 
     136         [ +  + ]:          17 :     if (((spdm_context->connection_info.algorithm.other_params_support &
     137         [ -  + ]:           4 :           SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) == SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE) &&
     138                 :             :         (opaque_data_length != 0)) {
     139                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Overriding opaque_data_length to 0 since there is "
     140                 :             :                        "no negotiated opaque data format.\n"));
     141                 :           0 :         opaque_data_length = 0;
     142                 :           0 :         warning = LIBSPDM_STATUS_OVERRIDDEN_PARAMETER;
     143                 :             :     }
     144                 :             : 
     145         [ +  + ]:          17 :     if (opaque_data_length != 0) {
     146                 :           2 :         libspdm_copy_mem((uint8_t *)(spdm_request + 1) + requester_info_length,
     147                 :           2 :                          spdm_request_size - sizeof(spdm_get_csr_request_t) - requester_info_length,
     148                 :             :                          (uint8_t *)opaque_data, opaque_data_length);
     149                 :             :     }
     150                 :             : 
     151                 :          17 :     spdm_request_size = sizeof(spdm_get_csr_request_t) + opaque_data_length
     152                 :          17 :                         + requester_info_length;
     153                 :             : 
     154                 :          17 :     status = libspdm_send_spdm_request(spdm_context, session_id, spdm_request_size, spdm_request);
     155         [ +  + ]:          17 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     156                 :           1 :         libspdm_release_sender_buffer (spdm_context);
     157                 :           1 :         return status;
     158                 :             :     }
     159                 :          16 :     libspdm_release_sender_buffer (spdm_context);
     160                 :          16 :     spdm_request = (void *)spdm_context->last_spdm_request;
     161                 :             : 
     162                 :             :     /* receive */
     163                 :          16 :     status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
     164         [ +  + ]:          16 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     165                 :           1 :         return status;
     166                 :             :     }
     167         [ -  + ]:          15 :     LIBSPDM_ASSERT (message_size >= transport_header_size);
     168                 :          15 :     spdm_response = (void *)(message);
     169                 :          15 :     spdm_response_size = message_size;
     170                 :             : 
     171                 :          15 :     status = libspdm_receive_spdm_response(spdm_context, session_id,
     172                 :             :                                            &spdm_response_size, (void **)&spdm_response);
     173                 :             : 
     174         [ +  + ]:          15 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     175                 :           1 :         goto receive_done;
     176                 :             :     }
     177         [ -  + ]:          14 :     if (spdm_response_size < sizeof(spdm_message_header_t)) {
     178                 :           0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     179                 :           0 :         goto receive_done;
     180                 :             :     }
     181         [ +  + ]:          14 :     if (spdm_response->header.request_response_code == SPDM_ERROR) {
     182   [ +  +  +  + ]:           8 :         if ((spdm_response->header.param1 == SPDM_ERROR_CODE_RESET_REQUIRED) &&
     183         [ +  + ]:           5 :             (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) &&
     184                 :             :             (available_csr_tracking_tag != NULL)) {
     185                 :           1 :             *available_csr_tracking_tag = spdm_response->header.param2;
     186                 :             :         }
     187                 :             : 
     188                 :           5 :         status = libspdm_handle_error_response_main(
     189                 :             :             spdm_context, session_id,
     190                 :             :             &spdm_response_size,
     191                 :             :             (void **)&spdm_response, SPDM_GET_CSR, SPDM_CSR);
     192         [ +  - ]:           5 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     193                 :           5 :             goto receive_done;
     194                 :             :         }
     195         [ +  + ]:           9 :     } else if (spdm_response->header.request_response_code != SPDM_CSR) {
     196                 :           1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     197                 :           1 :         goto receive_done;
     198                 :             :     }
     199         [ +  + ]:           8 :     if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
     200                 :           1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     201                 :           1 :         goto receive_done;
     202                 :             :     }
     203                 :             : 
     204         [ +  + ]:           7 :     if (spdm_response_size < sizeof(spdm_csr_response_t)) {
     205                 :           1 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     206                 :           1 :         goto receive_done;
     207                 :             :     }
     208         [ +  + ]:           6 :     if (spdm_response->csr_length == 0) {
     209                 :           1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     210                 :           1 :         goto receive_done;
     211                 :             :     }
     212                 :             : 
     213         [ +  + ]:           5 :     if (spdm_response_size < sizeof(spdm_csr_response_t) + spdm_response->csr_length) {
     214                 :           1 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     215                 :           1 :         goto receive_done;
     216                 :             :     }
     217         [ +  + ]:           4 :     if (*csr_len < spdm_response->csr_length) {
     218                 :           1 :         *csr_len = spdm_response->csr_length;
     219                 :           1 :         status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     220                 :           1 :         goto receive_done;
     221                 :             :     }
     222                 :             : 
     223                 :           3 :     libspdm_copy_mem(csr, *csr_len, spdm_response + 1, spdm_response->csr_length);
     224                 :           3 :     *csr_len = spdm_response->csr_length;
     225                 :             : 
     226                 :           3 :     status = LIBSPDM_STATUS_SUCCESS;
     227                 :             : 
     228                 :             :     /* -=[Log Message Phase]=- */
     229                 :             :     #if LIBSPDM_ENABLE_MSG_LOG
     230                 :           3 :     libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
     231                 :             :     #endif /* LIBSPDM_ENABLE_MSG_LOG */
     232                 :             : 
     233                 :          15 : receive_done:
     234                 :          15 :     libspdm_release_receiver_buffer (spdm_context);
     235                 :             : 
     236   [ +  +  -  + ]:          15 :     if (LIBSPDM_STATUS_IS_SUCCESS(status) && LIBSPDM_STATUS_IS_WARNING(warning)) {
     237                 :           0 :         status = warning;
     238                 :             :     }
     239                 :          15 :     return status;
     240                 :             : }
     241                 :             : 
     242                 :          28 : libspdm_return_t libspdm_get_csr(void * spdm_context,
     243                 :             :                                  const uint32_t *session_id,
     244                 :             :                                  void * requester_info, uint16_t requester_info_length,
     245                 :             :                                  void * opaque_data, uint16_t opaque_data_length,
     246                 :             :                                  void *csr, size_t *csr_len,
     247                 :             :                                  uint8_t request_attribute,
     248                 :             :                                  uint8_t key_pair_id,
     249                 :             :                                  uint8_t *available_csr_tracking_tag)
     250                 :             : {
     251                 :             :     libspdm_context_t *context;
     252                 :             :     size_t retry;
     253                 :             :     uint64_t retry_delay_time;
     254                 :             :     libspdm_return_t status;
     255                 :             : 
     256                 :          28 :     context = spdm_context;
     257                 :          28 :     context->crypto_request = true;
     258                 :          28 :     retry = context->retry_times;
     259                 :          28 :     retry_delay_time = context->retry_delay_time;
     260                 :             :     do {
     261                 :          29 :         status = libspdm_try_get_csr(context, session_id,
     262                 :             :                                      requester_info, requester_info_length,
     263                 :             :                                      opaque_data, opaque_data_length,
     264                 :             :                                      csr, csr_len,
     265                 :             :                                      request_attribute, key_pair_id,
     266                 :             :                                      available_csr_tracking_tag);
     267         [ +  + ]:          29 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     268                 :          27 :             return status;
     269                 :             :         }
     270                 :             : 
     271                 :           2 :         libspdm_sleep(retry_delay_time);
     272         [ +  + ]:           2 :     } while (retry-- != 0);
     273                 :             : 
     274                 :           1 :     return status;
     275                 :             : }
     276                 :             : 
     277                 :             : #endif /*LIBSPDM_ENABLE_CAPABILITY_CSR_CAP*/
        

Generated by: LCOV version 2.0-1