LCOV - code coverage report
Current view: top level - spdm_requester_lib - libspdm_req_challenge.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 80.1 % 246 197
Test Date: 2026-10-01 20:56:25 Functions: 100.0 % 4 4
Branches: 68.8 % 144 99

             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_SEND_CHALLENGE_SUPPORT
      10                 :             : 
      11                 :             : #pragma pack(1)
      12                 :             : typedef struct {
      13                 :             :     spdm_message_header_t header;
      14                 :             :     uint8_t cert_chain_hash[LIBSPDM_MAX_HASH_SIZE];
      15                 :             :     uint8_t nonce[SPDM_NONCE_SIZE];
      16                 :             :     uint8_t measurement_summary_hash[LIBSPDM_MAX_HASH_SIZE];
      17                 :             :     uint16_t opaque_length;
      18                 :             :     uint8_t opaque_data[SPDM_MAX_OPAQUE_DATA_SIZE];
      19                 :             :     uint8_t requester_context[SPDM_REQ_CONTEXT_SIZE];
      20                 :             :     uint8_t signature[LIBSPDM_RSP_SIGNATURE_DATA_MAX_SIZE];
      21                 :             : } libspdm_challenge_auth_response_max_t;
      22                 :             : #pragma pack()
      23                 :             : 
      24                 :             : /**
      25                 :             :  * This function sends CHALLENGE to authenticate the device based upon the key in one slot.
      26                 :             :  *
      27                 :             :  * This function verifies the signature in the challenge auth.
      28                 :             :  *
      29                 :             :  * If basic mutual authentication is requested from the responder,
      30                 :             :  * this function also perform the basic mutual authentication.
      31                 :             :  *
      32                 :             :  * @param  spdm_context           A pointer to the SPDM context.
      33                 :             :  * @param  slot_id                The number of slot for the challenge.
      34                 :             :  * @param  requester_context      If not NULL, a buffer to hold the requester context (8 bytes).
      35                 :             :  *                                It is used only if the negotiated version >= 1.3.
      36                 :             :  * @param  measurement_hash_type  The type of the measurement hash.
      37                 :             :  * @param  measurement_hash       A pointer to a destination buffer to store the measurement hash.
      38                 :             :  * @param  slot_mask              A pointer to a destination to store the slot mask.
      39                 :             :  * @param  requester_nonce_in     If not NULL, a buffer that holds the requester nonce (32 bytes)
      40                 :             :  * @param  requester_nonce        If not NULL, a buffer to hold the requester nonce (32 bytes).
      41                 :             :  * @param  responder_nonce        If not NULL, a buffer to hold the responder nonce (32 bytes).
      42                 :             :  **/
      43                 :          51 : static libspdm_return_t libspdm_try_challenge(libspdm_context_t *spdm_context,
      44                 :             :                                               uint8_t slot_id,
      45                 :             :                                               const void *requester_context,
      46                 :             :                                               uint8_t measurement_hash_type,
      47                 :             :                                               void *measurement_hash,
      48                 :             :                                               uint8_t *slot_mask,
      49                 :             :                                               const void *requester_nonce_in,
      50                 :             :                                               void *requester_nonce,
      51                 :             :                                               void *responder_nonce,
      52                 :             :                                               void *opaque_data,
      53                 :             :                                               size_t *opaque_data_size)
      54                 :             : {
      55                 :             :     libspdm_return_t status;
      56                 :             :     bool result;
      57                 :             :     spdm_challenge_request_t *spdm_request;
      58                 :             :     size_t spdm_request_size;
      59                 :             :     libspdm_challenge_auth_response_max_t *spdm_response;
      60                 :             :     size_t spdm_response_size;
      61                 :             :     uint8_t *ptr;
      62                 :             :     void *cert_chain_hash;
      63                 :             :     size_t hash_size;
      64                 :             :     uint32_t measurement_summary_hash_size;
      65                 :             :     void *nonce;
      66                 :             :     void *measurement_summary_hash;
      67                 :             :     uint16_t opaque_length;
      68                 :             :     void *signature;
      69                 :             :     size_t signature_size;
      70                 :             :     uint8_t auth_attribute;
      71                 :             :     uint8_t *message;
      72                 :             :     size_t message_size;
      73                 :             :     size_t transport_header_size;
      74                 :             : 
      75                 :             :     /* -=[Check Parameters Phase]=- */
      76   [ +  +  -  + ]:          51 :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xff));
      77   [ +  +  -  + ]:          51 :     LIBSPDM_ASSERT((slot_id != 0xff) ||
      78                 :             :                    (spdm_context->local_context.peer_public_key_provision_size != 0));
      79   [ +  +  +  +  :          51 :     LIBSPDM_ASSERT(measurement_hash_type == SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH ||
                   -  + ]
      80                 :             :                    measurement_hash_type == SPDM_CHALLENGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH ||
      81                 :             :                    measurement_hash_type == SPDM_CHALLENGE_REQUEST_ALL_MEASUREMENTS_HASH);
      82                 :             : 
      83                 :             :     /* -=[Verify State Phase]=- */
      84         [ +  + ]:          51 :     if (!libspdm_is_capabilities_flag_supported(
      85                 :             :             spdm_context, true, 0,
      86                 :             :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP)) {
      87                 :           1 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
      88                 :             :     }
      89         [ +  + ]:          50 :     if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
      90                 :           1 :         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
      91                 :             :     }
      92                 :             : 
      93                 :          49 :     libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_CHALLENGE);
      94                 :             : 
      95                 :             :     /* -=[Construct Request Phase]=- */
      96                 :          49 :     transport_header_size = spdm_context->local_context.capability.transport_header_size;
      97                 :          49 :     status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
      98         [ -  + ]:          49 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
      99                 :           0 :         return status;
     100                 :             :     }
     101         [ -  + ]:          49 :     LIBSPDM_ASSERT (message_size >= transport_header_size +
     102                 :             :                     spdm_context->local_context.capability.transport_tail_size);
     103                 :          49 :     spdm_request = (void *)(message + transport_header_size);
     104                 :          49 :     spdm_request_size = message_size - transport_header_size -
     105                 :          49 :                         spdm_context->local_context.capability.transport_tail_size;
     106                 :             : 
     107         [ -  + ]:          49 :     LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_challenge_request_t));
     108                 :          49 :     spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
     109                 :          49 :     spdm_request->header.request_response_code = SPDM_CHALLENGE;
     110                 :          49 :     spdm_request->header.param1 = slot_id;
     111                 :          49 :     spdm_request->header.param2 = measurement_hash_type;
     112         [ +  + ]:          49 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     113         [ -  + ]:           2 :         LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_challenge_request_t) +
     114                 :             :                         SPDM_REQ_CONTEXT_SIZE);
     115                 :           2 :         spdm_request_size = sizeof(spdm_challenge_request_t) + SPDM_REQ_CONTEXT_SIZE;
     116                 :             :     } else {
     117                 :          47 :         spdm_request_size = sizeof(spdm_challenge_request_t);
     118                 :             :     }
     119         [ +  + ]:          49 :     if (requester_nonce_in == NULL) {
     120         [ -  + ]:          48 :         if (!libspdm_get_random_number(SPDM_NONCE_SIZE, spdm_request->nonce)) {
     121                 :           0 :             libspdm_release_sender_buffer (spdm_context);
     122                 :           0 :             return LIBSPDM_STATUS_LOW_ENTROPY;
     123                 :             :         }
     124                 :             :     } else {
     125                 :           1 :         libspdm_copy_mem(spdm_request->nonce, sizeof(spdm_request->nonce),
     126                 :             :                          requester_nonce_in, SPDM_NONCE_SIZE);
     127                 :             :     }
     128                 :          49 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterNonce - "));
     129                 :          49 :     LIBSPDM_INTERNAL_DUMP_DATA(spdm_request->nonce, SPDM_NONCE_SIZE);
     130                 :          49 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     131         [ +  + ]:          49 :     if (requester_nonce != NULL) {
     132                 :           1 :         libspdm_copy_mem(requester_nonce, SPDM_NONCE_SIZE, spdm_request->nonce, SPDM_NONCE_SIZE);
     133                 :             :     }
     134         [ +  + ]:          49 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     135         [ -  + ]:           2 :         if (requester_context == NULL) {
     136                 :           0 :             libspdm_zero_mem(spdm_request + 1, SPDM_REQ_CONTEXT_SIZE);
     137                 :             :         } else {
     138                 :           2 :             libspdm_copy_mem(spdm_request + 1, SPDM_REQ_CONTEXT_SIZE,
     139                 :             :                              requester_context, SPDM_REQ_CONTEXT_SIZE);
     140                 :             :         }
     141                 :           2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterContext - "));
     142                 :           2 :         LIBSPDM_INTERNAL_DUMP_DATA((uint8_t *)(spdm_request + 1), SPDM_REQ_CONTEXT_SIZE);
     143                 :           2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     144                 :             :     }
     145                 :             : 
     146                 :             :     /* -=[Send Request Phase]=- */
     147                 :          49 :     status = libspdm_send_spdm_request(spdm_context, NULL, spdm_request_size, spdm_request);
     148         [ +  + ]:          49 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     149                 :           1 :         libspdm_release_sender_buffer (spdm_context);
     150                 :           1 :         return status;
     151                 :             :     }
     152                 :          48 :     libspdm_release_sender_buffer (spdm_context);
     153                 :          48 :     spdm_request = (void *)spdm_context->last_spdm_request;
     154                 :             : 
     155                 :             :     /* -=[Receive Response Phase]=- */
     156                 :          48 :     status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
     157         [ -  + ]:          48 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     158                 :           0 :         return status;
     159                 :             :     }
     160         [ -  + ]:          48 :     LIBSPDM_ASSERT (message_size >= transport_header_size);
     161                 :          48 :     spdm_response = (void *)(message);
     162                 :          48 :     spdm_response_size = message_size;
     163                 :             : 
     164                 :          48 :     status = libspdm_receive_spdm_response(
     165                 :             :         spdm_context, NULL, &spdm_response_size, (void **)&spdm_response);
     166         [ -  + ]:          48 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     167                 :           0 :         goto receive_done;
     168                 :             :     }
     169                 :             : 
     170                 :             :     /* -=[Validate Response Phase]=- */
     171         [ -  + ]:          48 :     if (spdm_response_size < sizeof(spdm_message_header_t)) {
     172                 :           0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     173                 :           0 :         goto receive_done;
     174                 :             :     }
     175         [ +  + ]:          48 :     if (spdm_response->header.request_response_code == SPDM_ERROR) {
     176                 :          24 :         status = libspdm_handle_error_response_main(
     177                 :             :             spdm_context, NULL,
     178                 :             :             &spdm_response_size,
     179                 :             :             (void **)&spdm_response, SPDM_CHALLENGE, SPDM_CHALLENGE_AUTH);
     180         [ +  + ]:          24 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     181                 :          23 :             goto receive_done;
     182                 :             :         }
     183         [ +  + ]:          24 :     } else if (spdm_response->header.request_response_code != SPDM_CHALLENGE_AUTH) {
     184                 :           1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     185                 :           1 :         goto receive_done;
     186                 :             :     }
     187         [ +  + ]:          24 :     if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
     188                 :           1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     189                 :           1 :         goto receive_done;
     190                 :             :     }
     191         [ -  + ]:          23 :     if (spdm_response_size < sizeof(spdm_challenge_auth_response_t)) {
     192                 :           0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     193                 :           0 :         goto receive_done;
     194                 :             :     }
     195                 :          23 :     auth_attribute = spdm_response->header.param1;
     196   [ +  -  +  + ]:          23 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11 && slot_id == 0xFF) {
     197         [ -  + ]:           1 :         if ((auth_attribute & SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_SLOT_ID_MASK) != 0xF) {
     198                 :           0 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     199                 :           0 :             goto receive_done;
     200                 :             :         }
     201                 :             :     } else {
     202         [ +  - ]:          22 :         if ((spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_11 &&
     203         [ +  + ]:          22 :              (auth_attribute & SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_SLOT_ID_MASK) != slot_id) ||
     204   [ -  +  -  - ]:          21 :             (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_10 &&
     205                 :             :              auth_attribute != slot_id)) {
     206                 :           1 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     207                 :           1 :             goto receive_done;
     208                 :             :         }
     209         [ +  + ]:          21 :         if ((spdm_response->header.param2 & (1 << slot_id)) == 0) {
     210                 :           1 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     211                 :           1 :             goto receive_done;
     212                 :             :         }
     213                 :             :     }
     214         [ -  + ]:          21 :     if ((auth_attribute & SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_BASIC_MUT_AUTH_REQ) != 0) {
     215         [ #  # ]:           0 :         if (!libspdm_is_capabilities_flag_supported(
     216                 :             :                 spdm_context, true,
     217                 :             :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP,
     218                 :             :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP)) {
     219                 :           0 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     220                 :           0 :             goto receive_done;
     221                 :             :         }
     222                 :             :     }
     223                 :             : 
     224                 :             :     /* -=[Process Response Phase]=- */
     225                 :          21 :     hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     226         [ -  + ]:          21 :     if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
     227                 :           0 :         signature_size = libspdm_get_pqc_asym_signature_size(
     228                 :             :             spdm_context->connection_info.algorithm.pqc_asym_algo);
     229                 :             :     } else {
     230                 :          21 :         signature_size = libspdm_get_asym_signature_size(
     231                 :             :             spdm_context->connection_info.algorithm.base_asym_algo);
     232                 :             :     }
     233                 :          21 :     measurement_summary_hash_size = libspdm_get_measurement_summary_hash_size(
     234                 :             :         spdm_context, true, measurement_hash_type);
     235                 :             : 
     236                 :          21 :     if (spdm_response_size <= sizeof(spdm_challenge_auth_response_t) +
     237         [ -  + ]:          21 :         hash_size + SPDM_NONCE_SIZE + measurement_summary_hash_size + sizeof(uint16_t)) {
     238                 :           0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     239                 :           0 :         goto receive_done;
     240                 :             :     }
     241                 :             : 
     242                 :          21 :     ptr = spdm_response->cert_chain_hash;
     243                 :             : 
     244                 :          21 :     cert_chain_hash = ptr;
     245                 :          21 :     ptr += hash_size;
     246                 :          21 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "cert_chain_hash (0x%zx) - ", hash_size));
     247                 :          21 :     LIBSPDM_INTERNAL_DUMP_DATA(cert_chain_hash, hash_size);
     248                 :          21 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     249         [ +  + ]:          21 :     if (slot_id == 0xFF) {
     250                 :           1 :         result = libspdm_verify_public_key_hash(spdm_context, cert_chain_hash, hash_size);
     251                 :             :     } else {
     252                 :          20 :         result = libspdm_verify_certificate_chain_hash(spdm_context, slot_id, cert_chain_hash,
     253                 :             :                                                        hash_size);
     254                 :             :     }
     255         [ -  + ]:          21 :     if (!result) {
     256                 :           0 :         status = LIBSPDM_STATUS_VERIF_FAIL;
     257                 :           0 :         goto receive_done;
     258                 :             :     }
     259                 :             : 
     260                 :          21 :     nonce = ptr;
     261                 :          21 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "nonce (0x%x) - ", SPDM_NONCE_SIZE));
     262                 :          21 :     LIBSPDM_INTERNAL_DUMP_DATA(nonce, SPDM_NONCE_SIZE);
     263                 :          21 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     264                 :          21 :     ptr += SPDM_NONCE_SIZE;
     265         [ +  + ]:          21 :     if (responder_nonce != NULL) {
     266                 :           1 :         libspdm_copy_mem(responder_nonce, SPDM_NONCE_SIZE, nonce, SPDM_NONCE_SIZE);
     267                 :             :     }
     268                 :             : 
     269                 :          21 :     measurement_summary_hash = ptr;
     270                 :          21 :     ptr += measurement_summary_hash_size;
     271                 :          21 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "measurement_summary_hash (0x%x) - ",
     272                 :             :                    measurement_summary_hash_size));
     273                 :          21 :     LIBSPDM_INTERNAL_DUMP_DATA(measurement_summary_hash, measurement_summary_hash_size);
     274                 :          21 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     275                 :             : 
     276                 :          21 :     opaque_length = libspdm_read_uint16((const uint8_t *)ptr);
     277         [ +  + ]:          21 :     if (opaque_length > SPDM_MAX_OPAQUE_DATA_SIZE) {
     278                 :           1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     279                 :           1 :         goto receive_done;
     280                 :             :     }
     281         [ +  + ]:          20 :     if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     282         [ +  + ]:           4 :         if (((spdm_context->connection_info.algorithm.other_params_support &
     283                 :             :               SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) ==
     284         [ -  + ]:           1 :              SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE) &&
     285                 :             :             (opaque_length != 0)) {
     286                 :           0 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     287                 :           0 :             goto receive_done;
     288                 :             :         }
     289                 :             :     }
     290                 :          20 :     ptr += sizeof(uint16_t);
     291                 :          20 :     if (spdm_response_size <
     292                 :          20 :         sizeof(spdm_challenge_auth_response_t) + hash_size + SPDM_NONCE_SIZE +
     293         [ -  + ]:          20 :         measurement_summary_hash_size + sizeof(uint16_t) + opaque_length) {
     294                 :           0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     295                 :           0 :         goto receive_done;
     296                 :             :     }
     297         [ +  + ]:          20 :     if (opaque_length != 0) {
     298                 :           2 :         result = libspdm_process_general_opaque_data_check(spdm_context, opaque_length, ptr);
     299         [ -  + ]:           2 :         if (!result) {
     300                 :           0 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     301                 :           0 :             goto receive_done;
     302                 :             :         }
     303                 :             :     }
     304                 :             : 
     305         [ +  + ]:          20 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     306                 :           2 :         if (spdm_response_size <
     307                 :             :             sizeof(spdm_challenge_auth_response_t) + hash_size +
     308                 :           2 :             SPDM_NONCE_SIZE + measurement_summary_hash_size +
     309         [ -  + ]:           2 :             sizeof(uint16_t) + opaque_length + SPDM_REQ_CONTEXT_SIZE +
     310                 :             :             signature_size) {
     311                 :           0 :             status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     312                 :           0 :             goto receive_done;
     313                 :             :         }
     314                 :           2 :         spdm_response_size = sizeof(spdm_challenge_auth_response_t) +
     315                 :           2 :                              hash_size + SPDM_NONCE_SIZE +
     316                 :           2 :                              measurement_summary_hash_size + sizeof(uint16_t) +
     317                 :           2 :                              opaque_length + SPDM_REQ_CONTEXT_SIZE + signature_size;
     318                 :             :     } else {
     319                 :          18 :         if (spdm_response_size <
     320                 :             :             sizeof(spdm_challenge_auth_response_t) + hash_size +
     321                 :          18 :             SPDM_NONCE_SIZE + measurement_summary_hash_size +
     322         [ -  + ]:          18 :             sizeof(uint16_t) + opaque_length + signature_size) {
     323                 :           0 :             status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     324                 :           0 :             goto receive_done;
     325                 :             :         }
     326                 :          18 :         spdm_response_size = sizeof(spdm_challenge_auth_response_t) +
     327                 :          18 :                              hash_size + SPDM_NONCE_SIZE +
     328                 :          18 :                              measurement_summary_hash_size + sizeof(uint16_t) +
     329                 :          18 :                              opaque_length + signature_size;
     330                 :             :     }
     331                 :             : 
     332   [ +  +  +  - ]:          20 :     if ((opaque_data != NULL) && (opaque_data_size != NULL)) {
     333         [ -  + ]:           3 :         if (opaque_length >= *opaque_data_size) {
     334                 :           0 :             status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     335                 :           0 :             goto receive_done;
     336                 :             :         }
     337                 :           3 :         libspdm_copy_mem(opaque_data, *opaque_data_size, ptr, opaque_length);
     338                 :           3 :         *opaque_data_size = opaque_length;
     339                 :             :     }
     340                 :             : 
     341                 :          20 :     ptr += opaque_length;
     342         [ +  + ]:          20 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) {
     343                 :           2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterContext - "));
     344                 :           2 :         LIBSPDM_INTERNAL_DUMP_DATA(ptr, SPDM_REQ_CONTEXT_SIZE);
     345                 :           2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     346         [ +  + ]:           2 :         if (!libspdm_consttime_is_mem_equal(spdm_request + 1, ptr, SPDM_REQ_CONTEXT_SIZE)) {
     347                 :           1 :             libspdm_reset_message_c(spdm_context);
     348                 :           1 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     349                 :           1 :             goto receive_done;
     350                 :             :         }
     351                 :           1 :         ptr += SPDM_REQ_CONTEXT_SIZE;
     352                 :             :     }
     353                 :             : 
     354                 :          19 :     status = libspdm_append_message_c(spdm_context, spdm_request, spdm_request_size);
     355         [ -  + ]:          19 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     356                 :           0 :         goto receive_done;
     357                 :             :     }
     358                 :          19 :     status = libspdm_append_message_c(spdm_context, spdm_response,
     359                 :             :                                       spdm_response_size - signature_size);
     360         [ -  + ]:          19 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     361                 :           0 :         libspdm_reset_message_c(spdm_context);
     362                 :           0 :         goto receive_done;
     363                 :             :     }
     364                 :             : 
     365                 :          19 :     signature = ptr;
     366                 :          19 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "signature (0x%zx):\n", signature_size));
     367                 :          19 :     LIBSPDM_INTERNAL_DUMP_HEX(signature, signature_size);
     368                 :          19 :     result = libspdm_verify_challenge_auth_signature(spdm_context, true, slot_id,
     369                 :             :                                                      signature, signature_size);
     370         [ +  + ]:          19 :     if (!result) {
     371                 :           1 :         libspdm_reset_message_c(spdm_context);
     372                 :           1 :         status = LIBSPDM_STATUS_VERIF_FAIL;
     373                 :           1 :         goto receive_done;
     374                 :             :     }
     375                 :             : 
     376         [ +  - ]:          18 :     if (measurement_hash != NULL) {
     377                 :          18 :         libspdm_copy_mem(measurement_hash, measurement_summary_hash_size,
     378                 :             :                          measurement_summary_hash, measurement_summary_hash_size);
     379                 :             :     }
     380         [ +  + ]:          18 :     if (slot_mask != NULL) {
     381                 :           1 :         *slot_mask = spdm_response->header.param2;
     382                 :             :     }
     383                 :             : 
     384                 :             :     /* At this point the Requester has successfully authenticated the Responder, even if the
     385                 :             :      * Responder intends to authenticate the Requester. */
     386                 :          18 :     spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
     387                 :             : 
     388                 :             :     /* -=[Log Message Phase]=- */
     389                 :             :     /* Logged here rather than at the end of the function because the BasicMutAuth path below
     390                 :             :      * releases the receiver buffer, which spdm_response points into, and then returns. */
     391                 :             :     #if LIBSPDM_ENABLE_MSG_LOG
     392                 :          18 :     libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
     393                 :             :     #endif /* LIBSPDM_ENABLE_MSG_LOG */
     394                 :             : 
     395                 :             :     /* -=[Update State Phase]=- */
     396                 :             : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP)
     397         [ -  + ]:          18 :     if ((auth_attribute & SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_BASIC_MUT_AUTH_REQ) != 0) {
     398                 :             :         /* we must release it here, because libspdm_encapsulated_request() will acquire again. */
     399                 :           0 :         libspdm_release_receiver_buffer (spdm_context);
     400                 :             : 
     401                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "BasicMutAuth :\n"));
     402                 :           0 :         status = libspdm_encapsulated_request(spdm_context, NULL, 0, NULL);
     403                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     404                 :             :                        "libspdm_challenge - libspdm_encapsulated_request - %x\n", status));
     405         [ #  # ]:           0 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     406                 :           0 :             libspdm_reset_message_c(spdm_context);
     407                 :           0 :             return status;
     408                 :             :         }
     409                 :           0 :         return LIBSPDM_STATUS_SUCCESS;
     410                 :             :     }
     411                 :             : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) */
     412                 :             : 
     413                 :          18 :     status = LIBSPDM_STATUS_SUCCESS;
     414                 :             : 
     415                 :          48 : receive_done:
     416                 :          48 :     libspdm_release_receiver_buffer (spdm_context);
     417                 :          48 :     return status;
     418                 :             : }
     419                 :             : 
     420                 :          45 : libspdm_return_t libspdm_challenge(void *spdm_context, void *reserved,
     421                 :             :                                    uint8_t slot_id,
     422                 :             :                                    uint8_t measurement_hash_type,
     423                 :             :                                    void *measurement_hash,
     424                 :             :                                    uint8_t *slot_mask)
     425                 :             : {
     426                 :             :     libspdm_context_t *context;
     427                 :             :     size_t retry;
     428                 :             :     uint64_t retry_delay_time;
     429                 :             :     libspdm_return_t status;
     430                 :             : 
     431                 :          45 :     context = spdm_context;
     432                 :          45 :     context->crypto_request = true;
     433                 :          45 :     retry = context->retry_times;
     434                 :          45 :     retry_delay_time = context->retry_delay_time;
     435                 :             :     do {
     436                 :          46 :         status = libspdm_try_challenge(context, slot_id, NULL,
     437                 :             :                                        measurement_hash_type,
     438                 :             :                                        measurement_hash, slot_mask,
     439                 :             :                                        NULL, NULL, NULL, NULL, NULL);
     440         [ +  + ]:          46 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     441                 :          44 :             return status;
     442                 :             :         }
     443                 :             : 
     444                 :           2 :         libspdm_sleep(retry_delay_time);
     445         [ +  + ]:           2 :     } while (retry-- != 0);
     446                 :             : 
     447                 :           1 :     return status;
     448                 :             : }
     449                 :             : 
     450                 :           3 : libspdm_return_t libspdm_challenge_ex(void *spdm_context, void *reserved,
     451                 :             :                                       uint8_t slot_id,
     452                 :             :                                       uint8_t measurement_hash_type,
     453                 :             :                                       void *measurement_hash,
     454                 :             :                                       uint8_t *slot_mask,
     455                 :             :                                       const void *requester_nonce_in,
     456                 :             :                                       void *requester_nonce,
     457                 :             :                                       void *responder_nonce,
     458                 :             :                                       void *opaque_data,
     459                 :             :                                       size_t *opaque_data_size)
     460                 :             : {
     461                 :             :     libspdm_context_t *context;
     462                 :             :     size_t retry;
     463                 :             :     uint64_t retry_delay_time;
     464                 :             :     libspdm_return_t status;
     465                 :             : 
     466                 :           3 :     context = spdm_context;
     467                 :           3 :     context->crypto_request = true;
     468                 :           3 :     retry = context->retry_times;
     469                 :           3 :     retry_delay_time = context->retry_delay_time;
     470                 :             :     do {
     471                 :           3 :         status = libspdm_try_challenge(context, slot_id, NULL,
     472                 :             :                                        measurement_hash_type,
     473                 :             :                                        measurement_hash,
     474                 :             :                                        slot_mask,
     475                 :             :                                        requester_nonce_in,
     476                 :             :                                        requester_nonce, responder_nonce,
     477                 :             :                                        opaque_data,
     478                 :             :                                        opaque_data_size);
     479         [ +  - ]:           3 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     480                 :           3 :             return status;
     481                 :             :         }
     482                 :             : 
     483                 :           0 :         libspdm_sleep(retry_delay_time);
     484         [ #  # ]:           0 :     } while (retry-- != 0);
     485                 :             : 
     486                 :           0 :     return status;
     487                 :             : }
     488                 :             : 
     489                 :           2 : libspdm_return_t libspdm_challenge_ex2(void *spdm_context, void *reserved,
     490                 :             :                                        uint8_t slot_id,
     491                 :             :                                        const void *requester_context,
     492                 :             :                                        uint8_t measurement_hash_type,
     493                 :             :                                        void *measurement_hash,
     494                 :             :                                        uint8_t *slot_mask,
     495                 :             :                                        const void *requester_nonce_in,
     496                 :             :                                        void *requester_nonce,
     497                 :             :                                        void *responder_nonce,
     498                 :             :                                        void *opaque_data,
     499                 :             :                                        size_t *opaque_data_size)
     500                 :             : {
     501                 :             :     libspdm_context_t *context;
     502                 :             :     size_t retry;
     503                 :             :     uint64_t retry_delay_time;
     504                 :             :     libspdm_return_t status;
     505                 :             : 
     506                 :           2 :     context = spdm_context;
     507                 :           2 :     context->crypto_request = true;
     508                 :           2 :     retry = context->retry_times;
     509                 :           2 :     retry_delay_time = context->retry_delay_time;
     510                 :             :     do {
     511                 :           2 :         status = libspdm_try_challenge(context, slot_id, requester_context,
     512                 :             :                                        measurement_hash_type,
     513                 :             :                                        measurement_hash,
     514                 :             :                                        slot_mask,
     515                 :             :                                        requester_nonce_in,
     516                 :             :                                        requester_nonce, responder_nonce,
     517                 :             :                                        opaque_data,
     518                 :             :                                        opaque_data_size);
     519         [ +  - ]:           2 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     520                 :           2 :             return status;
     521                 :             :         }
     522                 :             : 
     523                 :           0 :         libspdm_sleep(retry_delay_time);
     524         [ #  # ]:           0 :     } while (retry-- != 0);
     525                 :             : 
     526                 :           0 :     return status;
     527                 :             : }
     528                 :             : 
     529                 :             : #endif /* LIBSPDM_SEND_CHALLENGE_SUPPORT */
        

Generated by: LCOV version 2.0-1