LCOV - code coverage report
Current view: top level - spdm_requester_lib - libspdm_req_encap_event_ack.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.2 % 95 80
Test Date: 2026-10-01 20:56:25 Functions: 100.0 % 1 1
Branches: 71.0 % 62 44

             Branch data     Line data    Source code
       1                 :             : /**
       2                 :             :  *  Copyright Notice:
       3                 :             :  *  Copyright 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                 :             : 
       9                 :             :  #if (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && (LIBSPDM_EVENT_RECIPIENT_SUPPORT)
      10                 :             : 
      11                 :           8 : libspdm_return_t libspdm_get_encap_response_event_ack(void *spdm_context,
      12                 :             :                                                       size_t request_size,
      13                 :             :                                                       void *request,
      14                 :             :                                                       size_t *response_size,
      15                 :             :                                                       void *response)
      16                 :             : {
      17                 :             :     spdm_send_event_request_t *spdm_request;
      18                 :             :     spdm_event_ack_response_t *spdm_response;
      19                 :             :     libspdm_context_t *context;
      20                 :             :     uint32_t session_id;
      21                 :             :     libspdm_session_info_t *session_info;
      22                 :             :     libspdm_session_state_t session_state;
      23                 :             :     uint64_t index;
      24                 :             :     uint32_t prev_event_instance_id;
      25                 :             :     uint32_t event_instance_id_min;
      26                 :             :     uint32_t event_instance_id_max;
      27                 :             :     bool events_list_is_sequential;
      28                 :             :     uint8_t *ptr;
      29                 :           8 :     const uint8_t *end_ptr = (uint8_t *)request + request_size;
      30                 :             :     size_t calculated_request_size;
      31                 :             : 
      32                 :           8 :     context = spdm_context;
      33                 :           8 :     spdm_request = request;
      34                 :             : 
      35         [ -  + ]:           8 :     if (libspdm_get_connection_version(context) < SPDM_MESSAGE_VERSION_13) {
      36                 :           0 :         return libspdm_generate_encap_error_response(
      37                 :             :             context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST, SPDM_SEND_EVENT, response_size, response);
      38                 :             :     }
      39         [ -  + ]:           8 :     if (spdm_request->header.spdm_version != libspdm_get_connection_version(context)) {
      40                 :           0 :         return libspdm_generate_encap_error_response(
      41                 :             :             context, SPDM_ERROR_CODE_VERSION_MISMATCH, 0, response_size, response);
      42                 :             :     }
      43         [ -  + ]:           8 :     if (!libspdm_is_capabilities_flag_supported(
      44                 :             :             context, true, 0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EVENT_CAP)) {
      45                 :           0 :         return libspdm_generate_encap_error_response(
      46                 :             :             context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST, SPDM_SEND_EVENT, response_size, response);
      47                 :             :     }
      48         [ -  + ]:           8 :     if (!context->last_spdm_request_session_id_valid) {
      49                 :           0 :         return libspdm_generate_encap_error_response(
      50                 :             :             context, SPDM_ERROR_CODE_SESSION_REQUIRED, 0, response_size, response);
      51                 :             :     }
      52                 :             : 
      53                 :           8 :     session_id = context->last_spdm_request_session_id;
      54                 :           8 :     session_info = libspdm_get_session_info_via_session_id(context, session_id);
      55         [ -  + ]:           8 :     if (session_info == NULL) {
      56                 :           0 :         return libspdm_generate_encap_error_response(
      57                 :             :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
      58                 :             :     }
      59                 :             : 
      60                 :           8 :     session_state = libspdm_secured_message_get_session_state(
      61                 :             :         session_info->secured_message_context);
      62         [ -  + ]:           8 :     if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
      63                 :           0 :         return libspdm_generate_encap_error_response(
      64                 :             :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
      65                 :             :     }
      66                 :             : 
      67                 :           8 :     libspdm_reset_message_buffer_via_request_code(context, NULL,
      68                 :           8 :                                                   spdm_request->header.request_response_code);
      69                 :             : 
      70         [ -  + ]:           8 :     if (!libspdm_check_for_space((uint8_t *)request, end_ptr, sizeof(spdm_send_event_request_t))) {
      71                 :           0 :         return libspdm_generate_encap_error_response(
      72                 :             :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
      73                 :             :     }
      74                 :             : 
      75         [ +  + ]:           8 :     if (spdm_request->event_count == 0) {
      76                 :           1 :         return libspdm_generate_encap_error_response(
      77                 :             :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
      78                 :             :     }
      79                 :             : 
      80                 :           7 :     ptr = (uint8_t *)(spdm_request + 1);
      81                 :             : 
      82                 :           7 :     event_instance_id_min = UINT32_MAX;
      83                 :           7 :     event_instance_id_max = 0;
      84                 :           7 :     events_list_is_sequential = true;
      85                 :             : 
      86                 :           7 :     calculated_request_size = sizeof(spdm_send_event_request_t);
      87                 :             : 
      88                 :             :     /* Parse and validate all events for size and fields. */
      89         [ +  + ]:          20 :     for (index = 0; index < spdm_request->event_count; index++) {
      90                 :             :         uint32_t event_instance_id;
      91                 :             :         uint8_t svh_id;
      92                 :             :         uint8_t svh_vendor_id_len;
      93                 :             :         uint16_t event_type_id;
      94                 :             :         uint16_t event_detail_len;
      95                 :             : 
      96         [ +  + ]:          14 :         if (!libspdm_check_for_space(ptr, end_ptr,
      97                 :             :                                      sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t) +
      98                 :             :                                      sizeof(uint8_t))) {
      99                 :           1 :             return libspdm_generate_encap_error_response(
     100                 :             :                 context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     101                 :             :         }
     102                 :             : 
     103                 :          13 :         event_instance_id = libspdm_read_uint32(ptr);
     104                 :             : 
     105   [ +  +  +  - ]:          13 :         if ((index != 0) && events_list_is_sequential) {
     106         [ +  + ]:           6 :             if (event_instance_id != (prev_event_instance_id + 1)) {
     107                 :           2 :                 events_list_is_sequential = false;
     108                 :             :             }
     109                 :             :         }
     110         [ +  + ]:          13 :         if (event_instance_id < event_instance_id_min) {
     111                 :           8 :             event_instance_id_min = event_instance_id;
     112                 :             :         }
     113         [ +  + ]:          13 :         if (event_instance_id > event_instance_id_max) {
     114                 :          12 :             event_instance_id_max = event_instance_id;
     115                 :             :         }
     116                 :          13 :         prev_event_instance_id = event_instance_id;
     117                 :             : 
     118                 :          13 :         ptr += sizeof(uint32_t) + sizeof(uint32_t);
     119                 :          13 :         svh_id = *ptr;
     120                 :          13 :         ptr += sizeof(uint8_t);
     121                 :          13 :         svh_vendor_id_len = *ptr;
     122                 :          13 :         ptr += sizeof(uint8_t);
     123                 :             : 
     124         [ -  + ]:          13 :         if (!libspdm_validate_svh_vendor_id_len(svh_id, svh_vendor_id_len)) {
     125                 :           0 :             return libspdm_generate_encap_error_response(
     126                 :             :                 context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     127                 :             :         }
     128                 :             : 
     129         [ -  + ]:          13 :         if (!libspdm_check_for_space(
     130                 :          13 :                 ptr, end_ptr, (size_t)svh_vendor_id_len + sizeof(uint16_t) + sizeof(uint16_t))) {
     131                 :           0 :             return libspdm_generate_encap_error_response(
     132                 :             :                 context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     133                 :             :         }
     134                 :             : 
     135                 :          13 :         ptr += svh_vendor_id_len;
     136                 :             : 
     137                 :          13 :         event_type_id = libspdm_read_uint16(ptr);
     138                 :          13 :         ptr += sizeof(uint16_t);
     139                 :          13 :         event_detail_len = libspdm_read_uint16(ptr);
     140                 :          13 :         ptr += sizeof(uint16_t);
     141                 :             : 
     142         [ +  - ]:          13 :         if (svh_id == SPDM_REGISTRY_ID_DMTF) {
     143         [ -  + ]:          13 :             if (!libspdm_validate_dmtf_event_type(event_type_id, event_detail_len)) {
     144                 :           0 :                 return libspdm_generate_encap_error_response(
     145                 :             :                     context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     146                 :             :             }
     147                 :             :         }
     148                 :             : 
     149         [ -  + ]:          13 :         if (!libspdm_check_for_space(ptr, end_ptr, (size_t)event_detail_len)) {
     150                 :           0 :             return libspdm_generate_encap_error_response(
     151                 :             :                 context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     152                 :             :         }
     153                 :             : 
     154                 :          13 :         ptr += event_detail_len;
     155                 :          13 :         calculated_request_size += sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t) +
     156                 :          13 :                                    sizeof(uint8_t) + (size_t)svh_vendor_id_len + sizeof(uint16_t) +
     157                 :          13 :                                    sizeof(uint16_t) + (size_t)event_detail_len;
     158                 :             :     }
     159                 :             : 
     160                 :             :     /* Event must be sent in a secure session so message size can be calculated exactly. */
     161         [ +  + ]:           6 :     if (request_size != calculated_request_size) {
     162                 :           1 :         return libspdm_generate_encap_error_response(
     163                 :             :             context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     164                 :             :     }
     165                 :             : 
     166                 :             :     /* If event instance IDs are not sequential then ensure there are no gaps or duplicates before
     167                 :             :      * sending individual events to Integrator. */
     168         [ +  + ]:           5 :     if (!events_list_is_sequential) {
     169                 :           2 :         void *event_data = spdm_request + 1;
     170                 :             : 
     171         [ +  + ]:           2 :         if ((event_instance_id_max - event_instance_id_min + 1) != spdm_request->event_count) {
     172                 :           1 :             return libspdm_generate_encap_error_response(
     173                 :             :                 context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     174                 :             :         }
     175                 :             : 
     176         [ +  + ]:           3 :         for (index = 0; index < spdm_request->event_count; index++) {
     177         [ -  + ]:           2 :             if (libspdm_find_event_instance_id(event_data, spdm_request->event_count,
     178                 :           2 :                                                event_instance_id_min + (uint32_t)index) == NULL) {
     179                 :           0 :                 return libspdm_generate_encap_error_response(
     180                 :             :                     context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     181                 :             :             }
     182                 :             :         }
     183                 :             :     }
     184                 :             : 
     185         [ +  - ]:           4 :     if (context->process_event != NULL) {
     186                 :           4 :         const void *next_event_data = spdm_request + 1;
     187                 :             : 
     188         [ +  + ]:          13 :         for (index = 0; index < spdm_request->event_count; index++) {
     189         [ +  + ]:           9 :             if (events_list_is_sequential) {
     190         [ -  + ]:           7 :                 if (!libspdm_parse_and_send_event(
     191                 :             :                         context, session_id, next_event_data, &next_event_data)) {
     192                 :           0 :                     return libspdm_generate_encap_error_response(
     193                 :             :                         context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     194                 :             :                 }
     195                 :             :             } else {
     196                 :             :                 const void *event_data;
     197                 :             : 
     198                 :           2 :                 event_data = libspdm_find_event_instance_id(
     199                 :             :                     next_event_data, spdm_request->event_count,
     200                 :           2 :                     event_instance_id_min + (uint32_t)index);
     201         [ -  + ]:           2 :                 if (event_data == NULL) {
     202                 :           0 :                     return libspdm_generate_encap_error_response(
     203                 :             :                         context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     204                 :             :                 }
     205                 :             : 
     206         [ -  + ]:           2 :                 if (!libspdm_parse_and_send_event(context, session_id, event_data, NULL)) {
     207                 :           0 :                     return libspdm_generate_encap_error_response(
     208                 :             :                         context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response);
     209                 :             :                 }
     210                 :             :             }
     211                 :             :         }
     212                 :             :     }
     213                 :             : 
     214                 :           4 :     spdm_response = response;
     215                 :             : 
     216                 :           4 :     spdm_response->header.spdm_version = spdm_request->header.spdm_version;
     217                 :           4 :     spdm_response->header.request_response_code = SPDM_EVENT_ACK;
     218                 :           4 :     spdm_response->header.param1 = 0;
     219                 :           4 :     spdm_response->header.param2 = 0;
     220                 :             : 
     221                 :           4 :     *response_size = sizeof(spdm_event_ack_response_t);
     222                 :             : 
     223                 :           4 :     return LIBSPDM_STATUS_SUCCESS;
     224                 :             : }
     225                 :             : 
     226                 :             : #endif /* (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && (LIBSPDM_EVENT_RECIPIENT_SUPPORT) */
        

Generated by: LCOV version 2.0-1