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: 76.8 % 302 232
Test Date: 2025-11-02 08:10:32 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              : bool g_check_measurement_request_context = false;
     381              : uint64_t g_measurement_request_context;
     382              : 
     383          137 : libspdm_return_t libspdm_measurement_collection(
     384              :     void *spdm_context,
     385              :     spdm_version_number_t spdm_version,
     386              :     uint8_t measurement_specification,
     387              :     uint32_t measurement_hash_algo,
     388              :     uint8_t measurements_index,
     389              :     uint8_t request_attribute,
     390              :     size_t request_context_size,
     391              :     const void *request_context,
     392              :     uint8_t *content_changed,
     393              :     uint8_t *measurements_count,
     394              :     void *measurements,
     395              :     size_t *measurements_size)
     396              : {
     397              :     spdm_measurement_block_dmtf_t *measurement_block;
     398              :     size_t hash_size;
     399              :     uint8_t index;
     400              :     size_t total_size_needed;
     401              :     bool use_bit_stream;
     402              :     size_t measurement_block_size;
     403              : 
     404          137 :     if ((measurement_specification != SPDM_MEASUREMENT_SPECIFICATION_DMTF) ||
     405              :         (measurement_hash_algo == 0)) {
     406            0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     407              :     }
     408              : 
     409          137 :     if (g_check_measurement_request_context) {
     410            0 :         if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >= SPDM_MESSAGE_VERSION_13) {
     411            0 :             LIBSPDM_ASSERT(request_context_size == SPDM_REQ_CONTEXT_SIZE);
     412            0 :             LIBSPDM_ASSERT(libspdm_read_uint64(request_context) == g_measurement_request_context);
     413              :         } else {
     414            0 :             LIBSPDM_ASSERT(request_context_size == 0);
     415            0 :             LIBSPDM_ASSERT(request_context == NULL);
     416              :         }
     417              :     }
     418              : 
     419          137 :     hash_size = libspdm_get_measurement_hash_size(measurement_hash_algo);
     420          137 :     LIBSPDM_ASSERT(hash_size != 0);
     421              : 
     422          137 :     use_bit_stream = false;
     423          137 :     if ((measurement_hash_algo == SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_RAW_BIT_STREAM_ONLY) ||
     424          137 :         ((request_attribute & SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_RAW_BIT_STREAM_REQUESTED) !=
     425              :          0)) {
     426            1 :         use_bit_stream = true;
     427              :     }
     428              : 
     429          137 :     if (measurements_index ==
     430              :         SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS) {
     431           11 :         *measurements_count = LIBSPDM_MEASUREMENT_BLOCK_NUMBER;
     432           11 :         goto successful_return;
     433          126 :     } else if (measurements_index ==
     434              :                SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_ALL_MEASUREMENTS) {
     435              : 
     436              :         /* Calculate total_size_needed based on hash algo selected.
     437              :          * If we have an hash algo, then the first HASH_NUMBER elements will be
     438              :          * hash values, otherwise HASH_NUMBER raw bitstream values.*/
     439           15 :         if (!use_bit_stream) {
     440           15 :             total_size_needed =
     441              :                 LIBSPDM_MEASUREMENT_BLOCK_HASH_NUMBER *
     442           15 :                 (sizeof(spdm_measurement_block_dmtf_t) + hash_size);
     443              :         } else {
     444            0 :             total_size_needed =
     445              :                 LIBSPDM_MEASUREMENT_BLOCK_HASH_NUMBER *
     446              :                 (sizeof(spdm_measurement_block_dmtf_t) + LIBSPDM_MEASUREMENT_RAW_DATA_SIZE);
     447              :         }
     448              :         /* Next one - SVN is always raw bitstream data.*/
     449           15 :         total_size_needed +=
     450              :             (sizeof(spdm_measurement_block_dmtf_t) +
     451              :              sizeof(spdm_measurements_secure_version_number_t));
     452              :         /* Next one - HEM is always digest data.*/
     453           15 :         total_size_needed +=
     454              :             (sizeof(spdm_measurement_block_dmtf_t) + hash_size);
     455              :         /* Next one - manifest is always raw bitstream data.*/
     456           15 :         total_size_needed +=
     457              :             (sizeof(spdm_measurement_block_dmtf_t) + LIBSPDM_MEASUREMENT_MANIFEST_SIZE);
     458              :         /* Next one - device_mode is always raw bitstream data.*/
     459           15 :         total_size_needed +=
     460              :             (sizeof(spdm_measurement_block_dmtf_t) + sizeof(spdm_measurements_device_mode_t));
     461              : 
     462           15 :         LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     463           15 :         if (total_size_needed > *measurements_size) {
     464            0 :             return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     465              :         }
     466              : 
     467           15 :         *measurements_size = total_size_needed;
     468           15 :         *measurements_count = LIBSPDM_MEASUREMENT_BLOCK_NUMBER;
     469           15 :         measurement_block = measurements;
     470              : 
     471              :         /* The first HASH_NUMBER blocks may be hash values or raw bitstream*/
     472           75 :         for (index = 1; index <= LIBSPDM_MEASUREMENT_BLOCK_HASH_NUMBER; index++) {
     473           60 :             measurement_block_size = libspdm_fill_measurement_image_hash_block (use_bit_stream,
     474              :                                                                                 measurement_hash_algo,
     475              :                                                                                 index,
     476              :                                                                                 measurement_block);
     477           60 :             if (measurement_block_size == 0) {
     478            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     479              :             }
     480           60 :             measurement_block = (void *)((uint8_t *)measurement_block + measurement_block_size);
     481              :         }
     482              :         /* Next one - SVN is always raw bitstream data.*/
     483              :         {
     484           15 :             measurement_block_size = libspdm_fill_measurement_svn_block (measurement_block);
     485           15 :             measurement_block = (void *)((uint8_t *)measurement_block + measurement_block_size);
     486              :         }
     487              :         /* Next one - HEM is always digest data.*/
     488              :         {
     489           15 :             measurement_block_size = libspdm_fill_measurement_hem_block (measurement_block,
     490              :                                                                          measurement_hash_algo);
     491           15 :             measurement_block = (void *)((uint8_t *)measurement_block + measurement_block_size);
     492              :         }
     493              :         /* Next one - manifest is always raw bitstream data.*/
     494              :         {
     495           15 :             measurement_block_size = libspdm_fill_measurement_manifest_block (measurement_block);
     496           15 :             measurement_block = (void *)((uint8_t *)measurement_block + measurement_block_size);
     497              :         }
     498              :         /* Next one - device_mode is always raw bitstream data.*/
     499              :         {
     500           15 :             measurement_block_size = libspdm_fill_measurement_device_mode_block (measurement_block);
     501           15 :             measurement_block = (void *)((uint8_t *)measurement_block + measurement_block_size);
     502              :         }
     503              : 
     504           15 :         goto successful_return;
     505              :     } else {
     506              :         /* One Index */
     507          111 :         if (measurements_index <= LIBSPDM_MEASUREMENT_BLOCK_HASH_NUMBER) {
     508          110 :             if (!use_bit_stream) {
     509          109 :                 total_size_needed =
     510              :                     sizeof(spdm_measurement_block_dmtf_t) +
     511              :                     hash_size;
     512              :             } else {
     513            1 :                 total_size_needed =
     514              :                     sizeof(spdm_measurement_block_dmtf_t) +
     515              :                     LIBSPDM_MEASUREMENT_RAW_DATA_SIZE;
     516              :             }
     517          110 :             LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     518          110 :             if (total_size_needed > *measurements_size) {
     519            0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     520              :             }
     521              : 
     522          110 :             *measurements_count = 1;
     523          110 :             *measurements_size = total_size_needed;
     524              : 
     525          110 :             measurement_block = measurements;
     526          110 :             measurement_block_size = libspdm_fill_measurement_image_hash_block (use_bit_stream,
     527              :                                                                                 measurement_hash_algo,
     528              :                                                                                 measurements_index,
     529              :                                                                                 measurement_block);
     530          110 :             if (measurement_block_size == 0) {
     531            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     532              :             }
     533            1 :         } else if (measurements_index == LIBSPDM_MEASUREMENT_INDEX_SVN) {
     534            0 :             total_size_needed =
     535              :                 sizeof(spdm_measurement_block_dmtf_t) +
     536              :                 sizeof(spdm_measurements_secure_version_number_t);
     537            0 :             LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     538            0 :             if (total_size_needed > *measurements_size) {
     539            0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     540              :             }
     541              : 
     542            0 :             *measurements_count = 1;
     543            0 :             *measurements_size = total_size_needed;
     544              : 
     545            0 :             measurement_block = measurements;
     546            0 :             measurement_block_size = libspdm_fill_measurement_svn_block (measurement_block);
     547            0 :             if (measurement_block_size == 0) {
     548            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     549              :             }
     550            1 :         } else if (measurements_index == LIBSPDM_MEASUREMENT_INDEX_HEM) {
     551            0 :             total_size_needed =
     552              :                 sizeof(spdm_measurement_block_dmtf_t) + hash_size;
     553            0 :             LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     554            0 :             if (total_size_needed > *measurements_size) {
     555            0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     556              :             }
     557              : 
     558            0 :             *measurements_count = 1;
     559            0 :             *measurements_size = total_size_needed;
     560              : 
     561            0 :             measurement_block = measurements;
     562            0 :             measurement_block_size = libspdm_fill_measurement_hem_block (measurement_block,
     563              :                                                                          measurement_hash_algo);
     564            0 :             if (measurement_block_size == 0) {
     565            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     566              :             }
     567            1 :         } else if (measurements_index ==
     568              :                    SPDM_MEASUREMENT_BLOCK_MEASUREMENT_INDEX_MEASUREMENT_MANIFEST) {
     569            0 :             total_size_needed =
     570              :                 sizeof(spdm_measurement_block_dmtf_t) +
     571              :                 LIBSPDM_MEASUREMENT_MANIFEST_SIZE;
     572            0 :             LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     573            0 :             if (total_size_needed > *measurements_size) {
     574            0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     575              :             }
     576              : 
     577            0 :             *measurements_count = 1;
     578            0 :             *measurements_size = total_size_needed;
     579              : 
     580            0 :             measurement_block = measurements;
     581            0 :             measurement_block_size = libspdm_fill_measurement_manifest_block (measurement_block);
     582            0 :             if (measurement_block_size == 0) {
     583            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     584              :             }
     585            1 :         } else if (measurements_index == SPDM_MEASUREMENT_BLOCK_MEASUREMENT_INDEX_DEVICE_MODE) {
     586            0 :             total_size_needed =
     587              :                 sizeof(spdm_measurement_block_dmtf_t) +
     588              :                 sizeof(spdm_measurements_device_mode_t);
     589            0 :             LIBSPDM_ASSERT(total_size_needed <= *measurements_size);
     590            0 :             if (total_size_needed > *measurements_size) {
     591            0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     592              :             }
     593              : 
     594            0 :             *measurements_count = 1;
     595            0 :             *measurements_size = total_size_needed;
     596              : 
     597            0 :             measurement_block = measurements;
     598            0 :             measurement_block_size = libspdm_fill_measurement_device_mode_block (measurement_block);
     599            0 :             if (measurement_block_size == 0) {
     600            0 :                 return LIBSPDM_STATUS_MEAS_INTERNAL_ERROR;
     601              :             }
     602              :         } else {
     603            1 :             *measurements_count = 0;
     604            1 :             return LIBSPDM_STATUS_MEAS_INVALID_INDEX;
     605              :         }
     606              :     }
     607              : 
     608          136 : successful_return:
     609          136 :     if ((content_changed != NULL) &&
     610          126 :         ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >= SPDM_MESSAGE_VERSION_12)) {
     611              :         /* return content change*/
     612            9 :         if ((request_attribute & SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE) !=
     613              :             0) {
     614            7 :             *content_changed = SPDM_MEASUREMENTS_RESPONSE_CONTENT_NO_CHANGE_DETECTED;
     615              :         } else {
     616            2 :             *content_changed = SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_NO_DETECTION;
     617              :         }
     618              :     }
     619              : 
     620          136 :     return LIBSPDM_STATUS_SUCCESS;
     621              : }
     622              : 
     623              : size_t libspdm_secret_lib_meas_opaque_data_size;
     624              : 
     625          122 : bool libspdm_measurement_opaque_data(
     626              :     void *spdm_context,
     627              :     spdm_version_number_t spdm_version,
     628              :     uint8_t measurement_specification,
     629              :     uint32_t measurement_hash_algo,
     630              :     uint8_t measurement_index,
     631              :     uint8_t request_attribute,
     632              :     size_t request_context_size,
     633              :     const void *request_context,
     634              :     void *opaque_data,
     635              :     size_t *opaque_data_size)
     636              : {
     637              :     size_t index;
     638              : 
     639          122 :     LIBSPDM_ASSERT(libspdm_secret_lib_meas_opaque_data_size <= *opaque_data_size);
     640              : 
     641          122 :     if (g_check_measurement_request_context) {
     642            0 :         if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >= SPDM_MESSAGE_VERSION_13) {
     643            0 :             LIBSPDM_ASSERT(request_context_size == SPDM_REQ_CONTEXT_SIZE);
     644            0 :             LIBSPDM_ASSERT(libspdm_read_uint64(request_context) == g_measurement_request_context);
     645              :         } else {
     646            0 :             LIBSPDM_ASSERT(request_context_size == 0);
     647            0 :             LIBSPDM_ASSERT(request_context == NULL);
     648              :         }
     649              :     }
     650              : 
     651          122 :     *opaque_data_size = libspdm_secret_lib_meas_opaque_data_size;
     652              : 
     653          218 :     for (index = 0; index < *opaque_data_size; index++)
     654              :     {
     655           96 :         ((uint8_t *)opaque_data)[index] = (uint8_t)index;
     656              :     }
     657              : 
     658          122 :     return true;
     659              : }
     660              : 
     661           10 : bool libspdm_generate_measurement_summary_hash(
     662              :     void *spdm_context,
     663              :     spdm_version_number_t spdm_version, uint32_t base_hash_algo,
     664              :     uint8_t measurement_specification, uint32_t measurement_hash_algo,
     665              :     uint8_t measurement_summary_hash_type,
     666              :     uint8_t *measurement_summary_hash,
     667              :     uint32_t measurement_summary_hash_size)
     668              : {
     669              :     uint8_t measurement_data[LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE];
     670              :     size_t index;
     671              :     spdm_measurement_block_dmtf_t *cached_measurement_block;
     672              :     size_t measurement_data_size;
     673              :     size_t measurement_block_size;
     674              :     uint8_t device_measurement[LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE];
     675              :     uint8_t device_measurement_count;
     676              :     size_t device_measurement_size;
     677              :     libspdm_return_t status;
     678              :     bool result;
     679              : 
     680           10 :     switch (measurement_summary_hash_type) {
     681            0 :     case SPDM_REQUEST_NO_MEASUREMENT_SUMMARY_HASH:
     682            0 :         return false;
     683              : 
     684           10 :     case SPDM_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH:
     685              :     case SPDM_REQUEST_ALL_MEASUREMENTS_HASH:
     686           10 :         if (measurement_summary_hash_size != libspdm_get_hash_size(base_hash_algo)) {
     687            0 :             return false;
     688              :         }
     689              : 
     690              :         /* get all measurement data*/
     691           10 :         device_measurement_size = sizeof(device_measurement);
     692           10 :         status = libspdm_measurement_collection(
     693              :             spdm_context,
     694              :             spdm_version, measurement_specification,
     695              :             measurement_hash_algo,
     696              :             0xFF, /* Get all measurements*/
     697              :             0,
     698              :             0,
     699              :             NULL,
     700              :             NULL,
     701              :             &device_measurement_count, device_measurement,
     702              :             &device_measurement_size);
     703           10 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     704            0 :             return false;
     705              :         }
     706              : 
     707              :         /* double confirm that MeasurementData internal size is correct*/
     708           10 :         measurement_data_size = 0;
     709           10 :         cached_measurement_block = (void *)device_measurement;
     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           80 :             LIBSPDM_ASSERT(cached_measurement_block
     717              :                            ->measurement_block_common_header
     718              :                            .measurement_size ==
     719              :                            sizeof(spdm_measurement_block_dmtf_header_t) +
     720              :                            cached_measurement_block
     721              :                            ->measurement_block_dmtf_header
     722              :                            .dmtf_spec_measurement_value_size);
     723           80 :             measurement_data_size +=
     724              :                 cached_measurement_block
     725              :                 ->measurement_block_common_header
     726           80 :                 .measurement_size;
     727           80 :             cached_measurement_block =
     728           80 :                 (void *)((size_t)cached_measurement_block +
     729              :                          measurement_block_size);
     730              :         }
     731              : 
     732           10 :         LIBSPDM_ASSERT(measurement_data_size <=
     733              :                        LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE);
     734              : 
     735              :         /* get required data and hash them*/
     736           10 :         cached_measurement_block = (void *)device_measurement;
     737           10 :         measurement_data_size = 0;
     738           90 :         for (index = 0; index < device_measurement_count; index++) {
     739           80 :             measurement_block_size =
     740              :                 sizeof(spdm_measurement_block_common_header_t) +
     741              :                 cached_measurement_block
     742              :                 ->measurement_block_common_header
     743           80 :                 .measurement_size;
     744              :             /* filter unneeded data*/
     745           80 :             if ((measurement_summary_hash_type ==
     746           40 :                  SPDM_REQUEST_ALL_MEASUREMENTS_HASH) ||
     747              :                 ((cached_measurement_block
     748              :                   ->measurement_block_dmtf_header
     749           40 :                   .dmtf_spec_measurement_value_type &
     750              :                   SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_MASK) ==
     751              :                  SPDM_MEASUREMENT_BLOCK_MEASUREMENT_TYPE_IMMUTABLE_ROM)) {
     752           50 :                 libspdm_copy_mem(&measurement_data[measurement_data_size],
     753              :                                  sizeof(measurement_data)
     754           50 :                                  - (&measurement_data[measurement_data_size] - measurement_data),
     755              :                                  cached_measurement_block,
     756              :                                  sizeof(cached_measurement_block->
     757              :                                         measurement_block_common_header) +
     758              :                                  cached_measurement_block->measurement_block_common_header
     759           50 :                                  .measurement_size);
     760           50 :                 measurement_data_size +=
     761              :                     sizeof(cached_measurement_block->measurement_block_common_header) +
     762              :                     cached_measurement_block
     763              :                     ->measurement_block_common_header
     764           50 :                     .measurement_size;
     765              :             }
     766           80 :             cached_measurement_block =
     767           80 :                 (void *)((size_t)cached_measurement_block +
     768              :                          measurement_block_size);
     769              :         }
     770              : 
     771           10 :         result = libspdm_hash_all(base_hash_algo, measurement_data,
     772              :                                   measurement_data_size, measurement_summary_hash);
     773           10 :         if (!result) {
     774            0 :             return false;
     775              :         }
     776           10 :         break;
     777            0 :     default:
     778            0 :         return false;
     779              :         break;
     780              :     }
     781           10 :     return true;
     782              : }
     783              : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP */
     784              : 
     785              : #if LIBSPDM_ENABLE_CAPABILITY_MEL_CAP
     786              : /*Collect the measurement extension log.*/
     787           11 : bool libspdm_measurement_extension_log_collection(
     788              :     void *spdm_context,
     789              :     uint8_t mel_specification,
     790              :     uint8_t measurement_specification,
     791              :     uint32_t measurement_hash_algo,
     792              :     void **spdm_mel,
     793              :     size_t *spdm_mel_size)
     794              : {
     795              :     spdm_measurement_extension_log_dmtf_t *measurement_extension_log;
     796              : 
     797           11 :     if ((measurement_specification !=
     798           11 :          SPDM_MEASUREMENT_SPECIFICATION_DMTF) ||
     799           11 :         (mel_specification != SPDM_MEL_SPECIFICATION_DMTF) ||
     800              :         (measurement_hash_algo == 0)) {
     801            0 :         return false;
     802              :     }
     803              : 
     804           11 :     libspdm_generate_mel(measurement_hash_algo);
     805              : 
     806           11 :     measurement_extension_log = (spdm_measurement_extension_log_dmtf_t *)m_libspdm_mel;
     807           11 :     *spdm_mel = (spdm_measurement_extension_log_dmtf_t *)m_libspdm_mel;
     808           11 :     *spdm_mel_size = (size_t)(measurement_extension_log->mel_entries_len) +
     809              :                      sizeof(spdm_measurement_extension_log_dmtf_t);
     810           11 :     return true;
     811              : }
     812              : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEL_CAP */
        

Generated by: LCOV version 2.0-1