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

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

Generated by: LCOV version 2.0-1