LCOV - code coverage report
Current view: top level - library/spdm_common_lib - libspdm_com_opaque_data.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.0 % 120 102
Test Date: 2026-02-22 08:11:49 Functions: 100.0 % 5 5

            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_common_lib.h"
       8              : 
       9          171 : size_t libspdm_get_opaque_data_version_selection_data_size(const libspdm_context_t *spdm_context)
      10              : {
      11              :     size_t size;
      12              : 
      13          171 :     if (spdm_context->local_context.secured_message_version.secured_message_version_count == 0) {
      14            0 :         return 0;
      15              :     }
      16              : 
      17          171 :     if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_12) {
      18           21 :         size = sizeof(spdm_general_opaque_data_table_header_t) +
      19              :                sizeof(secured_message_opaque_element_table_header_t) +
      20              :                sizeof(secured_message_opaque_element_version_selection_t);
      21              :     } else {
      22          150 :         size = sizeof(secured_message_general_opaque_data_table_header_t) +
      23              :                sizeof(secured_message_opaque_element_table_header_t) +
      24              :                sizeof(secured_message_opaque_element_version_selection_t);
      25              :     }
      26              :     /* Add Padding*/
      27          171 :     return (size + 3) & ~3;
      28              : }
      29              : 
      30          344 : size_t libspdm_get_opaque_data_supported_version_data_size(libspdm_context_t *spdm_context)
      31              : {
      32              :     size_t size;
      33              : 
      34          344 :     if (spdm_context->local_context.secured_message_version.secured_message_version_count == 0) {
      35            0 :         return 0;
      36              :     }
      37              : 
      38          344 :     if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_12) {
      39           24 :         size = sizeof(spdm_general_opaque_data_table_header_t) +
      40              :                sizeof(secured_message_opaque_element_table_header_t) +
      41              :                sizeof(secured_message_opaque_element_supported_version_t) +
      42           24 :                sizeof(spdm_version_number_t) *
      43           24 :                spdm_context->local_context.secured_message_version.secured_message_version_count;
      44              :     } else {
      45          320 :         size = sizeof(secured_message_general_opaque_data_table_header_t) +
      46              :                sizeof(secured_message_opaque_element_table_header_t) +
      47              :                sizeof(secured_message_opaque_element_supported_version_t) +
      48          320 :                sizeof(spdm_version_number_t) *
      49          320 :                spdm_context->local_context.secured_message_version.secured_message_version_count;
      50              :     }
      51              :     /* Add Padding*/
      52          344 :     return (size + 3) & ~3;
      53              : }
      54              : 
      55           26 : size_t libspdm_get_untrusted_opaque_data_supported_version_data_size(
      56              :     libspdm_context_t *spdm_context, uint8_t version_count)
      57              : {
      58              :     size_t size;
      59              : 
      60           26 :     if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_12) {
      61            8 :         size = sizeof(spdm_general_opaque_data_table_header_t) +
      62              :                sizeof(secured_message_opaque_element_table_header_t) +
      63              :                sizeof(secured_message_opaque_element_supported_version_t) +
      64            8 :                sizeof(spdm_version_number_t) * version_count;
      65              :     } else {
      66           18 :         size = sizeof(secured_message_general_opaque_data_table_header_t) +
      67              :                sizeof(secured_message_opaque_element_table_header_t) +
      68              :                sizeof(secured_message_opaque_element_supported_version_t) +
      69           18 :                sizeof(spdm_version_number_t) * version_count;
      70              :     }
      71              :     /* Add Padding*/
      72           26 :     return (size + 3) & ~3;
      73              : }
      74              : 
      75           69 : bool libspdm_get_element_from_opaque_data(libspdm_context_t *spdm_context,
      76              :                                           size_t data_in_size, const void *data_in,
      77              :                                           uint8_t element_id, uint8_t sm_data_id,
      78              :                                           const void **get_element_ptr, size_t *get_element_len)
      79              : {
      80              :     const secured_message_general_opaque_data_table_header_t *general_opaque_data_table_header;
      81              :     const spdm_general_opaque_data_table_header_t *spdm_general_opaque_data_table_header;
      82              :     const opaque_element_table_header_t *opaque_element_table_header;
      83              :     uint16_t opaque_element_data_len;
      84              :     const secured_message_opaque_element_table_header_t *secured_message_element_table_header;
      85              :     const secured_message_opaque_element_header_t *secured_message_element_header;
      86              : 
      87              :     bool result;
      88              :     uint8_t element_num;
      89              :     uint8_t element_index;
      90              :     size_t data_element_size;
      91              :     size_t current_element_len;
      92              :     size_t total_element_len;
      93              : 
      94              :     /*check parameter in*/
      95           69 :     if (element_id > SPDM_REGISTRY_ID_MAX) {
      96            0 :         return false;
      97              :     }
      98           69 :     if ((data_in_size == 0) || (data_in == NULL)) {
      99            0 :         return false;
     100              :     }
     101              : 
     102           69 :     if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_12) {
     103           17 :         spdm_general_opaque_data_table_header = data_in;
     104           17 :         if (data_in_size < sizeof(spdm_general_opaque_data_table_header_t)) {
     105            0 :             return false;
     106              :         }
     107           17 :         if (spdm_general_opaque_data_table_header->total_elements < 1) {
     108            0 :             return false;
     109              :         }
     110           17 :         opaque_element_table_header = (const void *)(spdm_general_opaque_data_table_header + 1);
     111              : 
     112           17 :         element_num = spdm_general_opaque_data_table_header->total_elements;
     113              : 
     114           17 :         data_element_size = data_in_size - sizeof(spdm_general_opaque_data_table_header_t);
     115              :     } else {
     116           52 :         general_opaque_data_table_header = data_in;
     117           52 :         if (data_in_size < sizeof(secured_message_general_opaque_data_table_header_t)) {
     118            0 :             return false;
     119              :         }
     120           52 :         if ((general_opaque_data_table_header->spec_id != SECURED_MESSAGE_OPAQUE_DATA_SPEC_ID) ||
     121           51 :             (general_opaque_data_table_header->opaque_version != SECURED_MESSAGE_OPAQUE_VERSION) ||
     122           51 :             (general_opaque_data_table_header->total_elements < 1)) {
     123            1 :             return false;
     124              :         }
     125           51 :         opaque_element_table_header = (const void *)(general_opaque_data_table_header + 1);
     126              : 
     127           51 :         element_num = general_opaque_data_table_header->total_elements;
     128              : 
     129           51 :         data_element_size = data_in_size -
     130              :                             sizeof(secured_message_general_opaque_data_table_header_t);
     131              :     }
     132              : 
     133           68 :     total_element_len = 0;
     134           68 :     result = false;
     135              : 
     136          208 :     for (element_index = 0; element_index < element_num; element_index++) {
     137              :         /*ensure the opaque_element_table_header is valid*/
     138          144 :         if (total_element_len + sizeof(opaque_element_table_header_t) >
     139              :             data_element_size) {
     140            0 :             return false;
     141              :         }
     142              : 
     143              :         /*check element header id*/
     144          144 :         if ((opaque_element_table_header->id > SPDM_REGISTRY_ID_MAX)) {
     145            4 :             return false;
     146              :         }
     147              : 
     148          140 :         if ((total_element_len + sizeof(opaque_element_table_header_t) +
     149          140 :              opaque_element_table_header->vendor_len + 2) > data_element_size) {
     150            0 :             return false;
     151              :         }
     152              : 
     153          140 :         opaque_element_data_len = libspdm_read_uint16(
     154          140 :             (const uint8_t *)opaque_element_table_header + sizeof(opaque_element_table_header_t) +
     155          140 :             opaque_element_table_header->vendor_len);
     156              : 
     157          140 :         current_element_len = sizeof(opaque_element_table_header_t) +
     158          140 :                               opaque_element_table_header->vendor_len + 2 + opaque_element_data_len;
     159              :         /* Add Padding*/
     160          140 :         current_element_len = (current_element_len + 3) & ~3;
     161              : 
     162          140 :         total_element_len += current_element_len;
     163              : 
     164          140 :         if (data_element_size < total_element_len) {
     165            0 :             return false;
     166              :         }
     167              : 
     168          140 :         if (opaque_element_table_header->id == element_id) {
     169           70 :             secured_message_element_table_header = (const void *)opaque_element_table_header;
     170           70 :             if (secured_message_element_table_header->vendor_len == 0) {
     171           70 :                 secured_message_element_header =
     172              :                     (const void *)(secured_message_element_table_header + 1);
     173           70 :                 if ((const uint8_t *)secured_message_element_header +
     174              :                     sizeof(secured_message_opaque_element_header_t) >
     175           70 :                     (const uint8_t *)data_in + data_in_size) {
     176            0 :                     return false;
     177              :                 }
     178              : 
     179           70 :                 if ((secured_message_element_header->sm_data_id == sm_data_id) &&
     180           68 :                     (secured_message_element_header->sm_data_version ==
     181              :                      SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION)) {
     182              :                     /*get element by element id*/
     183           68 :                     *get_element_ptr = opaque_element_table_header;
     184           68 :                     *get_element_len = current_element_len;
     185           68 :                     result = true;
     186              :                 }
     187              :             }
     188              :         }
     189              : 
     190              :         /*move to next element*/
     191          140 :         opaque_element_table_header = (const opaque_element_table_header_t *)
     192              :                                       ((const uint8_t *)opaque_element_table_header +
     193              :                                        current_element_len);
     194              :     }
     195              : 
     196              :     /*ensure data size is right*/
     197           64 :     if (data_element_size != total_element_len) {
     198            0 :         return false;
     199              :     }
     200              : 
     201           64 :     return result;
     202              : }
     203              : 
     204           78 : bool libspdm_process_general_opaque_data_check(libspdm_context_t *spdm_context,
     205              :                                                size_t data_in_size,
     206              :                                                const void *data_in)
     207              : {
     208              :     const spdm_general_opaque_data_table_header_t
     209              :     *spdm_general_opaque_data_table_header;
     210              :     const opaque_element_table_header_t
     211              :     *opaque_element_table_header;
     212              :     uint8_t element_num;
     213              :     uint8_t element_index;
     214              :     uint16_t opaque_element_data_len;
     215              :     size_t data_element_size;
     216              :     size_t current_element_len;
     217              :     size_t total_element_len;
     218           78 :     uint8_t zero_padding[4] = {0};
     219              : 
     220           78 :     total_element_len = 0;
     221              : 
     222           78 :     LIBSPDM_ASSERT(data_in_size <= SPDM_MAX_OPAQUE_DATA_SIZE);
     223              : 
     224           78 :     if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) {
     225           19 :         if ((spdm_context->connection_info.algorithm.other_params_support &
     226              :              SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) == SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
     227              :             /* Check byte alignment */
     228           15 :             if ((data_in_size & 3) != 0) {
     229            0 :                 return false;
     230              :             }
     231              : 
     232           15 :             spdm_general_opaque_data_table_header = data_in;
     233           15 :             if (data_in_size < sizeof(spdm_general_opaque_data_table_header_t)) {
     234            0 :                 return false;
     235              :             }
     236           15 :             if (spdm_general_opaque_data_table_header->total_elements < 1) {
     237            0 :                 return false;
     238              :             }
     239           15 :             opaque_element_table_header = (const void *)(spdm_general_opaque_data_table_header + 1);
     240              : 
     241           15 :             element_num = spdm_general_opaque_data_table_header->total_elements;
     242              : 
     243           15 :             data_element_size = data_in_size - sizeof(spdm_general_opaque_data_table_header_t);
     244              : 
     245           33 :             for (element_index = 0; element_index < element_num; element_index++) {
     246              :                 /*ensure the opaque_element_table_header is valid*/
     247           19 :                 if (total_element_len + sizeof(opaque_element_table_header_t) +
     248              :                     sizeof(opaque_element_data_len) >
     249              :                     data_element_size) {
     250            0 :                     return false;
     251              :                 }
     252              : 
     253              :                 /*check element header id*/
     254           19 :                 if (opaque_element_table_header->id > SPDM_REGISTRY_ID_MAX) {
     255            0 :                     return false;
     256              :                 }
     257              : 
     258           19 :                 opaque_element_data_len = *(uint16_t *)((size_t)(opaque_element_table_header + 1) +
     259           19 :                                                         opaque_element_table_header->vendor_len);
     260              : 
     261           19 :                 current_element_len = sizeof(opaque_element_table_header_t) +
     262           19 :                                       opaque_element_table_header->vendor_len +
     263           19 :                                       sizeof(opaque_element_data_len) +
     264              :                                       opaque_element_data_len;
     265              : 
     266           19 :                 if ((current_element_len & 3) != 0) {
     267           13 :                     if (!libspdm_consttime_is_mem_equal(zero_padding,
     268              :                                                         (uint8_t *)(size_t)
     269              :                                                         (opaque_element_table_header) +
     270              :                                                         current_element_len,
     271           13 :                                                         4 - (current_element_len & 3))) {
     272            1 :                         return false;
     273              :                     }
     274              :                 }
     275              :                 /* Add Padding*/
     276           18 :                 current_element_len = (current_element_len + 3) & ~3;
     277              : 
     278           18 :                 total_element_len += current_element_len;
     279              : 
     280           18 :                 if (total_element_len > data_element_size) {
     281            0 :                     return false;
     282              :                 }
     283              : 
     284              :                 /*move to next element*/
     285           18 :                 opaque_element_table_header =
     286              :                     (const opaque_element_table_header_t *)
     287              :                     ((const uint8_t *)opaque_element_table_header +
     288              :                      current_element_len);
     289              :             }
     290              :         }
     291              :     }
     292              : 
     293           77 :     return true;
     294              : }
        

Generated by: LCOV version 2.0-1