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: 2026-03-15 08:15:47 Functions: 100.0 % 10 10

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

Generated by: LCOV version 2.0-1