LCOV - code coverage report
Current view: top level - os_stub/spdm_device_secret_lib_sample - meas.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 79.4 % 291 231
Test Date: 2025-09-14 08:11:04 Functions: 100.0 % 10 10

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2024-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 <stdarg.h>
       8              : #include <stddef.h>
       9              : #include <setjmp.h>
      10              : #include <stdint.h>
      11              : #include <stdlib.h>
      12              : #include <stdio.h>
      13              : #include <assert.h>
      14              : #include <string.h>
      15              : 
      16              : #include <base.h>
      17              : #include "library/memlib.h"
      18              : #include "spdm_device_secret_lib_internal.h"
      19              : #include "internal/libspdm_common_lib.h"
      20              : 
      21              : #if (LIBSPDM_ENABLE_CAPABILITY_MEL_CAP) || (LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP)
      22              : 
      23              : #define LIBSPDM_MAX_MEASUREMENT_EXTENSION_LOG_SIZE 0x1000
      24              : uint8_t m_libspdm_mel[LIBSPDM_MAX_MEASUREMENT_EXTENSION_LOG_SIZE];
      25              : 
      26              : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MEL_CAP) || (LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP) */
      27              : 
      28              : #if (LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP) || (LIBSPDM_ENABLE_CAPABILITY_MEL_CAP)
      29           26 : void libspdm_generate_mel(uint32_t measurement_hash_algo)
      30              : {
      31              :     spdm_measurement_extension_log_dmtf_t *measurement_extension_log;
      32              :     spdm_mel_entry_dmtf_t *mel_entry1;
      33              :     spdm_mel_entry_dmtf_t *mel_entry2;
      34              :     spdm_mel_entry_dmtf_t *mel_entry3;
      35              : 
      36           26 :     uint8_t rom_informational[] = "ROM";
      37           26 :     uint8_t bootfv_informational[] = "Boot FW";
      38           26 :     uint32_t version = 0x0100030A;
      39              : 
      40              :     /*generate MEL*/
      41           26 :     measurement_extension_log = (spdm_measurement_extension_log_dmtf_t *)m_libspdm_mel;
      42              : 
      43           26 :     measurement_extension_log->number_of_entries = 3;
      44           26 :     measurement_extension_log->mel_entries_len =
      45           26 :         measurement_extension_log->number_of_entries * sizeof(spdm_mel_entry_dmtf_t) +
      46           26 :         sizeof(rom_informational) - 1 + sizeof(bootfv_informational) - 1 + sizeof(version);
      47           26 :     measurement_extension_log->reserved = 0;
      48              : 
      49              :     /*MEL Entry 1: informational ROM */
      50           26 :     mel_entry1 = (spdm_mel_entry_dmtf_t *)((uint8_t *)measurement_extension_log +
      51              :                                            sizeof(spdm_measurement_extension_log_dmtf_t));
      52           26 :     mel_entry1->mel_index = 1;
      53           26 :     mel_entry1->meas_index = LIBSPDM_MEASUREMENT_INDEX_HEM;
      54           26 :     libspdm_write_uint24(mel_entry1->reserved, 0);
      55           26 :     mel_entry1->measurement_block_dmtf_header.dmtf_spec_measurement_value_type =
      56              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_INFORMATIONAL |
      57              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_RAW_BIT_STREAM;
      58           26 :     mel_entry1->measurement_block_dmtf_header.dmtf_spec_measurement_value_size =
      59              :         sizeof(rom_informational) - 1;
      60           26 :     libspdm_copy_mem((void *)(mel_entry1 + 1), sizeof(rom_informational) - 1,
      61              :                      rom_informational, sizeof(rom_informational) - 1);
      62              : 
      63              :     /*MEL Entry 2: informational Boot FW */
      64           26 :     mel_entry2 = (spdm_mel_entry_dmtf_t *)((uint8_t *)(mel_entry1 + 1) +
      65              :                                            sizeof(rom_informational) - 1);
      66           26 :     mel_entry2->mel_index = 2;
      67           26 :     mel_entry2->meas_index = LIBSPDM_MEASUREMENT_INDEX_HEM;
      68           26 :     libspdm_write_uint24(mel_entry2->reserved, 0);
      69           26 :     mel_entry2->measurement_block_dmtf_header.dmtf_spec_measurement_value_type =
      70              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_INFORMATIONAL |
      71              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_RAW_BIT_STREAM;
      72           26 :     mel_entry2->measurement_block_dmtf_header.dmtf_spec_measurement_value_size =
      73              :         sizeof(bootfv_informational) - 1;
      74           26 :     libspdm_copy_mem((void *)(mel_entry2 + 1), sizeof(bootfv_informational) - 1,
      75              :                      bootfv_informational, sizeof(bootfv_informational) - 1);
      76              : 
      77              :     /*MEL Entry 3: version 0x0100030A */
      78           26 :     mel_entry3 = (spdm_mel_entry_dmtf_t *)((uint8_t *)(mel_entry2 + 1) +
      79              :                                            sizeof(bootfv_informational) - 1);
      80           26 :     mel_entry3->mel_index = 3;
      81           26 :     mel_entry3->meas_index = LIBSPDM_MEASUREMENT_INDEX_HEM;
      82           26 :     libspdm_write_uint24(mel_entry3->reserved, 0);
      83           26 :     mel_entry3->measurement_block_dmtf_header.dmtf_spec_measurement_value_type =
      84              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_VERSION |
      85              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_RAW_BIT_STREAM;
      86           26 :     mel_entry3->measurement_block_dmtf_header.dmtf_spec_measurement_value_size = sizeof(version);
      87           26 :     libspdm_copy_mem((void *)(mel_entry3 + 1), sizeof(version), &version, sizeof(version));
      88           26 : }
      89              : #endif /*(LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP) || (LIBSPDM_ENABLE_CAPABILITY_MEL_CAP)*/
      90              : 
      91              : #if LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
      92              : /**
      93              :  * Fill image hash measurement block.
      94              :  *
      95              :  * @return measurement block size.
      96              :  **/
      97          170 : size_t libspdm_fill_measurement_image_hash_block (
      98              :     bool use_bit_stream,
      99              :     uint32_t measurement_hash_algo,
     100              :     uint8_t measurements_index,
     101              :     spdm_measurement_block_dmtf_t *measurement_block
     102              :     )
     103              : {
     104              :     size_t hash_size;
     105              :     uint8_t data[LIBSPDM_MEASUREMENT_RAW_DATA_SIZE];
     106              :     bool result;
     107              : 
     108          170 :     hash_size = libspdm_get_measurement_hash_size(measurement_hash_algo);
     109              : 
     110              :     measurement_block->measurement_block_common_header
     111          170 :     .index = measurements_index;
     112              :     measurement_block->measurement_block_common_header
     113          170 :     .measurement_specification =
     114              :         SPDM_MEASUREMENT_SPECIFICATION_DMTF;
     115              : 
     116          170 :     libspdm_set_mem(data, sizeof(data), (uint8_t)(measurements_index));
     117              : 
     118          170 :     if (!use_bit_stream) {
     119              :         measurement_block->measurement_block_dmtf_header
     120          169 :         .dmtf_spec_measurement_value_type =
     121          169 :             (measurements_index - 1);
     122              :         measurement_block->measurement_block_dmtf_header
     123          169 :         .dmtf_spec_measurement_value_size =
     124          169 :             (uint16_t)hash_size;
     125              : 
     126              :         measurement_block->measurement_block_common_header
     127          169 :         .measurement_size =
     128          169 :             (uint16_t)(sizeof(spdm_measurement_block_dmtf_header_t) +
     129          169 :                        (uint16_t)hash_size);
     130              : 
     131          169 :         result = libspdm_measurement_hash_all(
     132              :             measurement_hash_algo, data,
     133              :             sizeof(data),
     134          169 :             (void *)(measurement_block + 1));
     135          169 :         if (!result) {
     136            0 :             return 0;
     137              :         }
     138              : 
     139          169 :         return sizeof(spdm_measurement_block_dmtf_t) + hash_size;
     140              : 
     141              :     } else {
     142              :         measurement_block->measurement_block_dmtf_header
     143            1 :         .dmtf_spec_measurement_value_type =
     144            1 :             (measurements_index - 1) |
     145              :             SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_RAW_BIT_STREAM;
     146              :         measurement_block->measurement_block_dmtf_header
     147            1 :         .dmtf_spec_measurement_value_size =
     148              :             (uint16_t)sizeof(data);
     149              : 
     150              :         measurement_block->measurement_block_common_header
     151            1 :         .measurement_size =
     152              :             (uint16_t)(sizeof(spdm_measurement_block_dmtf_header_t) +
     153              :                        (uint16_t)sizeof(data));
     154              : 
     155            1 :         libspdm_copy_mem((void *)(measurement_block + 1), sizeof(data), data, sizeof(data));
     156              : 
     157            1 :         return sizeof(spdm_measurement_block_dmtf_t) + sizeof(data);
     158              :     }
     159              : }
     160              : 
     161              : /**
     162              :  * Fill svn measurement block.
     163              :  *
     164              :  * @return measurement block size.
     165              :  **/
     166           15 : size_t libspdm_fill_measurement_svn_block (
     167              :     spdm_measurement_block_dmtf_t *measurement_block
     168              :     )
     169              : {
     170              :     spdm_measurements_secure_version_number_t svn;
     171              : 
     172              :     measurement_block->measurement_block_common_header
     173           15 :     .index = LIBSPDM_MEASUREMENT_INDEX_SVN;
     174              :     measurement_block->measurement_block_common_header
     175           15 :     .measurement_specification =
     176              :         SPDM_MEASUREMENT_SPECIFICATION_DMTF;
     177              : 
     178           15 :     svn = 0x7;
     179              : 
     180              :     measurement_block->measurement_block_dmtf_header
     181           15 :     .dmtf_spec_measurement_value_type =
     182              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_SECURE_VERSION_NUMBER |
     183              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_RAW_BIT_STREAM;
     184              :     measurement_block->measurement_block_dmtf_header
     185           15 :     .dmtf_spec_measurement_value_size =
     186              :         (uint16_t)sizeof(svn);
     187              : 
     188              :     measurement_block->measurement_block_common_header
     189           15 :     .measurement_size =
     190              :         (uint16_t)(sizeof(spdm_measurement_block_dmtf_header_t) +
     191              :                    (uint16_t)sizeof(svn));
     192              : 
     193           15 :     libspdm_copy_mem((void *)(measurement_block + 1), sizeof(svn), (void *)&svn, sizeof(svn));
     194              : 
     195           15 :     return sizeof(spdm_measurement_block_dmtf_t) + sizeof(svn);
     196              : }
     197              : 
     198              : /**
     199              :  * Fill HEM measurement block.
     200              :  *
     201              :  * @param  measurement_block          A pointer to store measurement block.
     202              :  * @param  measurement_hash_algo      Indicates the measurement hash algorithm.
     203              :  *                                    It must align with measurement_hash_alg
     204              :  *                                    (SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_*)
     205              :  *
     206              :  * @return measurement block size.
     207              :  **/
     208           15 : size_t libspdm_fill_measurement_hem_block (
     209              :     spdm_measurement_block_dmtf_t *measurement_block, uint32_t measurement_hash_algo
     210              :     )
     211              : {
     212              :     size_t hash_size;
     213              :     spdm_measurement_extension_log_dmtf_t *measurement_extension_log;
     214              :     spdm_mel_entry_dmtf_t *mel_entry;
     215              :     uint32_t index;
     216              :     uint8_t *verify_hem;
     217              : 
     218           15 :     if (measurement_hash_algo == SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_RAW_BIT_STREAM_ONLY) {
     219            0 :         return 0;
     220              :     }
     221              : 
     222           15 :     libspdm_generate_mel(measurement_hash_algo);
     223              : 
     224           15 :     hash_size = libspdm_get_measurement_hash_size(measurement_hash_algo);
     225           15 :     if (measurement_block == NULL) {
     226            0 :         return sizeof(spdm_measurement_block_dmtf_t) + hash_size;
     227              :     }
     228              : 
     229              :     /*MEL*/
     230           15 :     measurement_extension_log = (spdm_measurement_extension_log_dmtf_t *)m_libspdm_mel;
     231              : 
     232              :     /*generate measurement block*/
     233              :     measurement_block->measurement_block_common_header
     234           15 :     .index = LIBSPDM_MEASUREMENT_INDEX_HEM;
     235              :     measurement_block->measurement_block_common_header
     236           15 :     .measurement_specification =
     237              :         SPDM_MEASUREMENT_SPECIFICATION_DMTF;
     238              : 
     239              :     measurement_block->measurement_block_dmtf_header
     240           15 :     .dmtf_spec_measurement_value_type =
     241              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_HASH_EXTEND_MEASUREMENT;
     242              :     measurement_block->measurement_block_dmtf_header
     243           15 :     .dmtf_spec_measurement_value_size =
     244           15 :         (uint16_t)hash_size;
     245              : 
     246              :     measurement_block->measurement_block_common_header
     247           15 :     .measurement_size =
     248           15 :         (uint16_t)(sizeof(spdm_measurement_block_dmtf_header_t) +
     249           15 :                    (uint16_t)hash_size);
     250              : 
     251           15 :     verify_hem = malloc(measurement_extension_log->mel_entries_len + hash_size);
     252           15 :     if (verify_hem == NULL) {
     253            0 :         return 0;
     254              :     }
     255              : 
     256           15 :     libspdm_zero_mem(verify_hem, measurement_extension_log->mel_entries_len + hash_size);
     257           15 :     mel_entry = (spdm_mel_entry_dmtf_t *)((uint8_t *)measurement_extension_log +
     258              :                                           sizeof(spdm_measurement_extension_log_dmtf_t));
     259           60 :     for (index = 0; index < measurement_extension_log->number_of_entries; index++) {
     260           45 :         libspdm_copy_mem(
     261           45 :             verify_hem + hash_size,
     262           45 :             measurement_extension_log->mel_entries_len,
     263              :             mel_entry,
     264              :             sizeof(spdm_mel_entry_dmtf_t) +
     265           45 :             mel_entry->measurement_block_dmtf_header.dmtf_spec_measurement_value_size);
     266              : 
     267           45 :         if (!libspdm_measurement_hash_all(
     268              :                 measurement_hash_algo,
     269              :                 verify_hem,
     270           45 :                 hash_size + sizeof(spdm_mel_entry_dmtf_t) +
     271           45 :                 mel_entry->measurement_block_dmtf_header.dmtf_spec_measurement_value_size,
     272              :                 verify_hem
     273              :                 )) {
     274            0 :             free(verify_hem);
     275            0 :             return 0;
     276              :         }
     277           45 :         mel_entry = (spdm_mel_entry_dmtf_t *)
     278           45 :                     ((uint8_t *)mel_entry + sizeof(spdm_mel_entry_dmtf_t)+
     279           45 :                      mel_entry->measurement_block_dmtf_header.dmtf_spec_measurement_value_size);
     280              :     }
     281              : 
     282           15 :     libspdm_copy_mem((void *)(measurement_block + 1), hash_size, verify_hem, hash_size);
     283           15 :     free(verify_hem);
     284           15 :     return sizeof(spdm_measurement_block_dmtf_t) + hash_size;
     285              : }
     286              : 
     287              : /**
     288              :  * Fill manifest measurement block.
     289              :  *
     290              :  * @return measurement block size.
     291              :  **/
     292           15 : size_t libspdm_fill_measurement_manifest_block (
     293              :     spdm_measurement_block_dmtf_t *measurement_block
     294              :     )
     295              : {
     296              :     uint8_t data[LIBSPDM_MEASUREMENT_MANIFEST_SIZE];
     297              : 
     298              :     measurement_block->measurement_block_common_header
     299           15 :     .index = SPDM_MEASUREMENT_BLOCK_MEASUREMENT_INDEX_MEASUREMENT_MANIFEST;
     300              :     measurement_block->measurement_block_common_header
     301           15 :     .measurement_specification =
     302              :         SPDM_MEASUREMENT_SPECIFICATION_DMTF;
     303              : 
     304           15 :     libspdm_set_mem(data, sizeof(data),
     305              :                     (uint8_t)SPDM_MEASUREMENT_BLOCK_MEASUREMENT_INDEX_MEASUREMENT_MANIFEST);
     306              : 
     307              :     measurement_block->measurement_block_dmtf_header
     308           15 :     .dmtf_spec_measurement_value_type =
     309              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MEASUREMENT_MANIFEST |
     310              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_RAW_BIT_STREAM;
     311              :     measurement_block->measurement_block_dmtf_header
     312           15 :     .dmtf_spec_measurement_value_size =
     313              :         (uint16_t)sizeof(data);
     314              : 
     315              :     measurement_block->measurement_block_common_header
     316           15 :     .measurement_size =
     317              :         (uint16_t)(sizeof(spdm_measurement_block_dmtf_header_t) +
     318              :                    (uint16_t)sizeof(data));
     319              : 
     320           15 :     libspdm_copy_mem((void *)(measurement_block + 1), sizeof(data), data, sizeof(data));
     321              : 
     322           15 :     return sizeof(spdm_measurement_block_dmtf_t) + sizeof(data);
     323              : }
     324              : 
     325              : /**
     326              :  * Fill device mode measurement block.
     327              :  *
     328              :  * @return measurement block size.
     329              :  **/
     330           15 : size_t libspdm_fill_measurement_device_mode_block (
     331              :     spdm_measurement_block_dmtf_t *measurement_block
     332              :     )
     333              : {
     334              :     spdm_measurements_device_mode_t device_mode;
     335              : 
     336              :     measurement_block->measurement_block_common_header
     337           15 :     .index = SPDM_MEASUREMENT_BLOCK_MEASUREMENT_INDEX_DEVICE_MODE;
     338              :     measurement_block->measurement_block_common_header
     339           15 :     .measurement_specification =
     340              :         SPDM_MEASUREMENT_SPECIFICATION_DMTF;
     341              : 
     342           15 :     device_mode.operational_mode_capabilities =
     343              :         SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_MANUFACTURING_MODE |
     344              :         SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_VALIDATION_MODE |
     345              :         SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_NORMAL_MODE |
     346              :         SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_RECOVERY_MODE |
     347              :         SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_RMA_MODE |
     348              :         SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_DECOMMISSIONED_MODE;
     349           15 :     device_mode.operational_mode_state =
     350              :         SPDM_MEASUREMENT_DEVICE_OPERATION_MODE_NORMAL_MODE;
     351           15 :     device_mode.device_mode_capabilities =
     352              :         SPDM_MEASUREMENT_DEVICE_MODE_NON_INVASIVE_DEBUG_MODE_IS_ACTIVE |
     353              :         SPDM_MEASUREMENT_DEVICE_MODE_INVASIVE_DEBUG_MODE_IS_ACTIVE |
     354              :         SPDM_MEASUREMENT_DEVICE_MODE_NON_INVASIVE_DEBUG_MODE_HAS_BEEN_ACTIVE |
     355              :         SPDM_MEASUREMENT_DEVICE_MODE_INVASIVE_DEBUG_MODE_HAS_BEEN_ACTIVE |
     356              :         SPDM_MEASUREMENT_DEVICE_MODE_INVASIVE_DEBUG_MODE_HAS_BEEN_ACTIVE_AFTER_MFG;
     357           15 :     device_mode.device_mode_state =
     358              :         SPDM_MEASUREMENT_DEVICE_MODE_NON_INVASIVE_DEBUG_MODE_IS_ACTIVE |
     359              :         SPDM_MEASUREMENT_DEVICE_MODE_INVASIVE_DEBUG_MODE_HAS_BEEN_ACTIVE_AFTER_MFG;
     360              : 
     361              :     measurement_block->measurement_block_dmtf_header
     362           15 :     .dmtf_spec_measurement_value_type =
     363              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_DEVICE_MODE |
     364              :         SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_RAW_BIT_STREAM;
     365              :     measurement_block->measurement_block_dmtf_header
     366           15 :     .dmtf_spec_measurement_value_size =
     367              :         (uint16_t)sizeof(device_mode);
     368              : 
     369              :     measurement_block->measurement_block_common_header
     370           15 :     .measurement_size =
     371              :         (uint16_t)(sizeof(spdm_measurement_block_dmtf_header_t) +
     372              :                    (uint16_t)sizeof(device_mode));
     373              : 
     374           15 :     libspdm_copy_mem((void *)(measurement_block + 1), sizeof(device_mode),
     375              :                      (void *)&device_mode, sizeof(device_mode));
     376              : 
     377           15 :     return sizeof(spdm_measurement_block_dmtf_t) + sizeof(device_mode);
     378              : }
     379              : 
     380          137 : libspdm_return_t libspdm_measurement_collection(
     381              :     void *spdm_context,
     382              :     spdm_version_number_t spdm_version,
     383              :     uint8_t measurement_specification,
     384              :     uint32_t measurement_hash_algo,
     385              :     uint8_t measurements_index,
     386              :     uint8_t request_attribute,
     387              :     uint8_t *content_changed,
     388              :     uint8_t *measurements_count,
     389              :     void *measurements,
     390              :     size_t *measurements_size)
     391              : {
     392              :     spdm_measurement_block_dmtf_t *measurement_block;
     393              :     size_t hash_size;
     394              :     uint8_t index;
     395              :     size_t total_size_needed;
     396              :     bool use_bit_stream;
     397              :     size_t measurement_block_size;
     398              : 
     399          137 :     if ((measurement_specification !=
     400          137 :          SPDM_MEASUREMENT_SPECIFICATION_DMTF) ||
     401              :         (measurement_hash_algo == 0)) {
     402            0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     403              :     }
     404              : 
     405          137 :     hash_size = libspdm_get_measurement_hash_size(measurement_hash_algo);
     406          137 :     LIBSPDM_ASSERT(hash_size != 0);
     407              : 
     408          137 :     use_bit_stream = false;
     409          137 :     if ((measurement_hash_algo == SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_RAW_BIT_STREAM_ONLY) ||
     410          137 :         ((request_attribute & SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_RAW_BIT_STREAM_REQUESTED) !=
     411              :          0)) {
     412            1 :         use_bit_stream = true;
     413              :     }
     414              : 
     415          137 :     if (measurements_index ==
     416              :         SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS) {
     417           11 :         *measurements_count = LIBSPDM_MEASUREMENT_BLOCK_NUMBER;
     418           11 :         goto successful_return;
     419          126 :     } else if (measurements_index ==
     420              :                SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_ALL_MEASUREMENTS) {
     421              : 
     422              :         /* Calculate total_size_needed based on hash algo selected.
     423              :          * If we have an hash algo, then the first HASH_NUMBER elements will be
     424              :          * hash values, otherwise HASH_NUMBER raw bitstream values.*/
     425           15 :         if (!use_bit_stream) {
     426           15 :             total_size_needed =
     427              :                 LIBSPDM_MEASUREMENT_BLOCK_HASH_NUMBER *
     428           15 :                 (sizeof(spdm_measurement_block_dmtf_t) + hash_size);
     429              :         } else {
     430            0 :             total_size_needed =
     431              :                 LIBSPDM_MEASUREMENT_BLOCK_HASH_NUMBER *
     432              :                 (sizeof(spdm_measurement_block_dmtf_t) + LIBSPDM_MEASUREMENT_RAW_DATA_SIZE);
     433              :         }
     434              :         /* Next one - SVN is always raw bitstream data.*/
     435           15 :         total_size_needed +=
     436              :             (sizeof(spdm_measurement_block_dmtf_t) +
     437              :              sizeof(spdm_measurements_secure_version_number_t));
     438              :         /* Next one - HEM is always digest data.*/
     439           15 :         total_size_needed +=
     440              :             (sizeof(spdm_measurement_block_dmtf_t) + hash_size);
     441              :         /* Next one - manifest is always raw bitstream data.*/
     442           15 :         total_size_needed +=
     443              :             (sizeof(spdm_measurement_block_dmtf_t) + LIBSPDM_MEASUREMENT_MANIFEST_SIZE);
     444              :         /* Next one - device_mode is always raw bitstream data.*/
     445           15 :         total_size_needed +=
     446              :             (sizeof(spdm_measurement_block_dmtf_t) + sizeof(spdm_measurements_device_mode_t));
     447              : 
     448           15 :         LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     449           15 :         if (total_size_needed > *measurements_size) {
     450            0 :             return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     451              :         }
     452              : 
     453           15 :         *measurements_size = total_size_needed;
     454           15 :         *measurements_count = LIBSPDM_MEASUREMENT_BLOCK_NUMBER;
     455           15 :         measurement_block = measurements;
     456              : 
     457              :         /* The first HASH_NUMBER blocks may be hash values or raw bitstream*/
     458           75 :         for (index = 1; index <= LIBSPDM_MEASUREMENT_BLOCK_HASH_NUMBER; index++) {
     459           60 :             measurement_block_size = libspdm_fill_measurement_image_hash_block (use_bit_stream,
     460              :                                                                                 measurement_hash_algo,
     461              :                                                                                 index,
     462              :                                                                                 measurement_block);
     463           60 :             if (measurement_block_size == 0) {
     464            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     465              :             }
     466           60 :             measurement_block = (void *)((uint8_t *)measurement_block + measurement_block_size);
     467              :         }
     468              :         /* Next one - SVN is always raw bitstream data.*/
     469              :         {
     470           15 :             measurement_block_size = libspdm_fill_measurement_svn_block (measurement_block);
     471           15 :             measurement_block = (void *)((uint8_t *)measurement_block + measurement_block_size);
     472              :         }
     473              :         /* Next one - HEM is always digest data.*/
     474              :         {
     475           15 :             measurement_block_size = libspdm_fill_measurement_hem_block (measurement_block,
     476              :                                                                          measurement_hash_algo);
     477           15 :             measurement_block = (void *)((uint8_t *)measurement_block + measurement_block_size);
     478              :         }
     479              :         /* Next one - manifest is always raw bitstream data.*/
     480              :         {
     481           15 :             measurement_block_size = libspdm_fill_measurement_manifest_block (measurement_block);
     482           15 :             measurement_block = (void *)((uint8_t *)measurement_block + measurement_block_size);
     483              :         }
     484              :         /* Next one - device_mode is always raw bitstream data.*/
     485              :         {
     486           15 :             measurement_block_size = libspdm_fill_measurement_device_mode_block (measurement_block);
     487           15 :             measurement_block = (void *)((uint8_t *)measurement_block + measurement_block_size);
     488              :         }
     489              : 
     490           15 :         goto successful_return;
     491              :     } else {
     492              :         /* One Index */
     493          111 :         if (measurements_index <= LIBSPDM_MEASUREMENT_BLOCK_HASH_NUMBER) {
     494          110 :             if (!use_bit_stream) {
     495          109 :                 total_size_needed =
     496              :                     sizeof(spdm_measurement_block_dmtf_t) +
     497              :                     hash_size;
     498              :             } else {
     499            1 :                 total_size_needed =
     500              :                     sizeof(spdm_measurement_block_dmtf_t) +
     501              :                     LIBSPDM_MEASUREMENT_RAW_DATA_SIZE;
     502              :             }
     503          110 :             LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     504          110 :             if (total_size_needed > *measurements_size) {
     505            0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     506              :             }
     507              : 
     508          110 :             *measurements_count = 1;
     509          110 :             *measurements_size = total_size_needed;
     510              : 
     511          110 :             measurement_block = measurements;
     512          110 :             measurement_block_size = libspdm_fill_measurement_image_hash_block (use_bit_stream,
     513              :                                                                                 measurement_hash_algo,
     514              :                                                                                 measurements_index,
     515              :                                                                                 measurement_block);
     516          110 :             if (measurement_block_size == 0) {
     517            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     518              :             }
     519            1 :         } else if (measurements_index == LIBSPDM_MEASUREMENT_INDEX_SVN) {
     520            0 :             total_size_needed =
     521              :                 sizeof(spdm_measurement_block_dmtf_t) +
     522              :                 sizeof(spdm_measurements_secure_version_number_t);
     523            0 :             LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     524            0 :             if (total_size_needed > *measurements_size) {
     525            0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     526              :             }
     527              : 
     528            0 :             *measurements_count = 1;
     529            0 :             *measurements_size = total_size_needed;
     530              : 
     531            0 :             measurement_block = measurements;
     532            0 :             measurement_block_size = libspdm_fill_measurement_svn_block (measurement_block);
     533            0 :             if (measurement_block_size == 0) {
     534            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     535              :             }
     536            1 :         } else if (measurements_index == LIBSPDM_MEASUREMENT_INDEX_HEM) {
     537            0 :             total_size_needed =
     538              :                 sizeof(spdm_measurement_block_dmtf_t) + hash_size;
     539            0 :             LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     540            0 :             if (total_size_needed > *measurements_size) {
     541            0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     542              :             }
     543              : 
     544            0 :             *measurements_count = 1;
     545            0 :             *measurements_size = total_size_needed;
     546              : 
     547            0 :             measurement_block = measurements;
     548            0 :             measurement_block_size = libspdm_fill_measurement_hem_block (measurement_block,
     549              :                                                                          measurement_hash_algo);
     550            0 :             if (measurement_block_size == 0) {
     551            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     552              :             }
     553            1 :         } else if (measurements_index ==
     554              :                    SPDM_MEASUREMENT_BLOCK_MEASUREMENT_INDEX_MEASUREMENT_MANIFEST) {
     555            0 :             total_size_needed =
     556              :                 sizeof(spdm_measurement_block_dmtf_t) +
     557              :                 LIBSPDM_MEASUREMENT_MANIFEST_SIZE;
     558            0 :             LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     559            0 :             if (total_size_needed > *measurements_size) {
     560            0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     561              :             }
     562              : 
     563            0 :             *measurements_count = 1;
     564            0 :             *measurements_size = total_size_needed;
     565              : 
     566            0 :             measurement_block = measurements;
     567            0 :             measurement_block_size = libspdm_fill_measurement_manifest_block (measurement_block);
     568            0 :             if (measurement_block_size == 0) {
     569            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     570              :             }
     571            1 :         } else if (measurements_index == SPDM_MEASUREMENT_BLOCK_MEASUREMENT_INDEX_DEVICE_MODE) {
     572            0 :             total_size_needed =
     573              :                 sizeof(spdm_measurement_block_dmtf_t) +
     574              :                 sizeof(spdm_measurements_device_mode_t);
     575            0 :             LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     576            0 :             if (total_size_needed > *measurements_size) {
     577            0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     578              :             }
     579              : 
     580            0 :             *measurements_count = 1;
     581            0 :             *measurements_size = total_size_needed;
     582              : 
     583            0 :             measurement_block = measurements;
     584            0 :             measurement_block_size = libspdm_fill_measurement_device_mode_block (measurement_block);
     585            0 :             if (measurement_block_size == 0) {
     586            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     587              :             }
     588              :         } else {
     589            1 :             *measurements_count = 0;
     590            1 :             return LIBSPDM_STATUS_MEAS_INVALID_INDEX;
     591              :         }
     592              :     }
     593              : 
     594          136 : successful_return:
     595          136 :     if ((content_changed != NULL) &&
     596          126 :         ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >= SPDM_MESSAGE_VERSION_12)) {
     597              :         /* return content change*/
     598            9 :         if ((request_attribute & SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE) !=
     599              :             0) {
     600            7 :             *content_changed = SPDM_MEASUREMENTS_RESPONSE_CONTENT_NO_CHANGE_DETECTED;
     601              :         } else {
     602            2 :             *content_changed = SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_NO_DETECTION;
     603              :         }
     604              :     }
     605              : 
     606          136 :     return LIBSPDM_STATUS_SUCCESS;
     607              : }
     608              : 
     609              : size_t libspdm_secret_lib_meas_opaque_data_size;
     610              : 
     611          122 : bool libspdm_measurement_opaque_data(
     612              :     void *spdm_context,
     613              :     spdm_version_number_t spdm_version,
     614              :     uint8_t measurement_specification,
     615              :     uint32_t measurement_hash_algo,
     616              :     uint8_t measurement_index,
     617              :     uint8_t request_attribute,
     618              :     void *opaque_data,
     619              :     size_t *opaque_data_size)
     620              : {
     621              :     size_t index;
     622              : 
     623          122 :     LIBSPDM_ASSERT(libspdm_secret_lib_meas_opaque_data_size <= *opaque_data_size);
     624              : 
     625          122 :     *opaque_data_size = libspdm_secret_lib_meas_opaque_data_size;
     626              : 
     627          218 :     for (index = 0; index < *opaque_data_size; index++)
     628              :     {
     629           96 :         ((uint8_t *)opaque_data)[index] = (uint8_t)index;
     630              :     }
     631              : 
     632          122 :     return true;
     633              : }
     634              : 
     635           10 : bool libspdm_generate_measurement_summary_hash(
     636              :     void *spdm_context,
     637              :     spdm_version_number_t spdm_version, uint32_t base_hash_algo,
     638              :     uint8_t measurement_specification, uint32_t measurement_hash_algo,
     639              :     uint8_t measurement_summary_hash_type,
     640              :     uint8_t *measurement_summary_hash,
     641              :     uint32_t measurement_summary_hash_size)
     642              : {
     643              :     uint8_t measurement_data[LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE];
     644              :     size_t index;
     645              :     spdm_measurement_block_dmtf_t *cached_measurement_block;
     646              :     size_t measurement_data_size;
     647              :     size_t measurement_block_size;
     648              :     uint8_t device_measurement[LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE];
     649              :     uint8_t device_measurement_count;
     650              :     size_t device_measurement_size;
     651              :     libspdm_return_t status;
     652              :     bool result;
     653              : 
     654           10 :     switch (measurement_summary_hash_type) {
     655            0 :     case SPDM_REQUEST_NO_MEASUREMENT_SUMMARY_HASH:
     656            0 :         return false;
     657              : 
     658           10 :     case SPDM_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH:
     659              :     case SPDM_REQUEST_ALL_MEASUREMENTS_HASH:
     660           10 :         if (measurement_summary_hash_size != libspdm_get_hash_size(base_hash_algo)) {
     661            0 :             return false;
     662              :         }
     663              : 
     664              :         /* get all measurement data*/
     665           10 :         device_measurement_size = sizeof(device_measurement);
     666           10 :         status = libspdm_measurement_collection(
     667              :             spdm_context,
     668              :             spdm_version, measurement_specification,
     669              :             measurement_hash_algo,
     670              :             0xFF, /* Get all measurements*/
     671              :             0,
     672              :             NULL,
     673              :             &device_measurement_count, device_measurement,
     674              :             &device_measurement_size);
     675           10 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     676            0 :             return false;
     677              :         }
     678              : 
     679              :         /* double confirm that MeasurementData internal size is correct*/
     680           10 :         measurement_data_size = 0;
     681           10 :         cached_measurement_block = (void *)device_measurement;
     682           90 :         for (index = 0; index < device_measurement_count; index++) {
     683           80 :             measurement_block_size =
     684              :                 sizeof(spdm_measurement_block_common_header_t) +
     685              :                 cached_measurement_block
     686              :                 ->measurement_block_common_header
     687           80 :                 .measurement_size;
     688           80 :             LIBSPDM_ASSERT(cached_measurement_block
     689              :                            ->measurement_block_common_header
     690              :                            .measurement_size ==
     691              :                            sizeof(spdm_measurement_block_dmtf_header_t) +
     692              :                            cached_measurement_block
     693              :                            ->measurement_block_dmtf_header
     694              :                            .dmtf_spec_measurement_value_size);
     695           80 :             measurement_data_size +=
     696              :                 cached_measurement_block
     697              :                 ->measurement_block_common_header
     698           80 :                 .measurement_size;
     699           80 :             cached_measurement_block =
     700           80 :                 (void *)((size_t)cached_measurement_block +
     701              :                          measurement_block_size);
     702              :         }
     703              : 
     704           10 :         LIBSPDM_ASSERT(measurement_data_size <=
     705              :                        LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE);
     706              : 
     707              :         /* get required data and hash them*/
     708           10 :         cached_measurement_block = (void *)device_measurement;
     709           10 :         measurement_data_size = 0;
     710           90 :         for (index = 0; index < device_measurement_count; index++) {
     711           80 :             measurement_block_size =
     712              :                 sizeof(spdm_measurement_block_common_header_t) +
     713              :                 cached_measurement_block
     714              :                 ->measurement_block_common_header
     715           80 :                 .measurement_size;
     716              :             /* filter unneeded data*/
     717           80 :             if ((measurement_summary_hash_type ==
     718           40 :                  SPDM_REQUEST_ALL_MEASUREMENTS_HASH) ||
     719              :                 ((cached_measurement_block
     720              :                   ->measurement_block_dmtf_header
     721           40 :                   .dmtf_spec_measurement_value_type &
     722              :                   SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MASK) ==
     723              :                  SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_IMMUTABLE_ROM)) {
     724           50 :                 libspdm_copy_mem(&measurement_data[measurement_data_size],
     725              :                                  sizeof(measurement_data)
     726           50 :                                  - (&measurement_data[measurement_data_size] - measurement_data),
     727              :                                  cached_measurement_block,
     728              :                                  sizeof(cached_measurement_block->
     729              :                                         measurement_block_common_header) +
     730              :                                  cached_measurement_block->measurement_block_common_header
     731           50 :                                  .measurement_size);
     732           50 :                 measurement_data_size +=
     733              :                     sizeof(cached_measurement_block->measurement_block_common_header) +
     734              :                     cached_measurement_block
     735              :                     ->measurement_block_common_header
     736           50 :                     .measurement_size;
     737              :             }
     738           80 :             cached_measurement_block =
     739           80 :                 (void *)((size_t)cached_measurement_block +
     740              :                          measurement_block_size);
     741              :         }
     742              : 
     743           10 :         result = libspdm_hash_all(base_hash_algo, measurement_data,
     744              :                                   measurement_data_size, measurement_summary_hash);
     745           10 :         if (!result) {
     746            0 :             return false;
     747              :         }
     748           10 :         break;
     749            0 :     default:
     750            0 :         return false;
     751              :         break;
     752              :     }
     753           10 :     return true;
     754              : }
     755              : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP */
     756              : 
     757              : #if LIBSPDM_ENABLE_CAPABILITY_MEL_CAP
     758              : /*Collect the measurement extension log.*/
     759           11 : bool libspdm_measurement_extension_log_collection(
     760              :     void *spdm_context,
     761              :     uint8_t mel_specification,
     762              :     uint8_t measurement_specification,
     763              :     uint32_t measurement_hash_algo,
     764              :     void **spdm_mel,
     765              :     size_t *spdm_mel_size)
     766              : {
     767              :     spdm_measurement_extension_log_dmtf_t *measurement_extension_log;
     768              : 
     769           11 :     if ((measurement_specification !=
     770           11 :          SPDM_MEASUREMENT_SPECIFICATION_DMTF) ||
     771           11 :         (mel_specification != SPDM_MEL_SPECIFICATION_DMTF) ||
     772              :         (measurement_hash_algo == 0)) {
     773            0 :         return false;
     774              :     }
     775              : 
     776           11 :     libspdm_generate_mel(measurement_hash_algo);
     777              : 
     778           11 :     measurement_extension_log = (spdm_measurement_extension_log_dmtf_t *)m_libspdm_mel;
     779           11 :     *spdm_mel = (spdm_measurement_extension_log_dmtf_t *)m_libspdm_mel;
     780           11 :     *spdm_mel_size = (size_t)(measurement_extension_log->mel_entries_len) +
     781              :                      sizeof(spdm_measurement_extension_log_dmtf_t);
     782           11 :     return true;
     783              : }
     784              : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEL_CAP */
        

Generated by: LCOV version 2.0-1