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 */
|