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