1use super::*;
2use crate::{BootMeasurement, ValueHash};
3use alloc::vec::Vec;
4use measurement::*;
5use sha2::{Digest, Sha256, Sha384, Sha512};
6
7#[derive(Debug)]
8struct MeasurementSlot {
10 measurement: Measurement,
12 is_locked: bool,
14 is_populated: bool,
16}
17
18impl Default for MeasurementSlot {
19 fn default() -> Self {
21 Self {
22 is_locked: false,
23 is_populated: false,
24 measurement: Measurement::default(),
25 }
26 }
27}
28
29impl MeasurementSlot {
30 pub fn extend(&mut self, measurement: Measurement, lock: bool) {
32 self.extend_metadata(measurement.metadata);
33 self.extend_value(measurement.value, lock);
34 }
35
36 fn extend_metadata(&mut self, metadata: MeasurementMetaData) {
39 self.measurement.metadata.sw_type = metadata.sw_type;
43 self.measurement.metadata.sw_version = metadata.sw_version;
44 }
45
46 fn extend_value(&mut self, value: ValueHash, lock: bool) {
49 let measurement_value_len = self.measurement.metadata.algorithm.hash_len();
50
51 let total_len = measurement_value_len + value.len();
52 let mut temp = Vec::with_capacity(total_len);
53 temp.resize(total_len, 0);
54 temp[..measurement_value_len]
55 .copy_from_slice(&self.measurement.value[..measurement_value_len]);
56 temp[measurement_value_len..].copy_from_slice(&value);
57
58 match self.measurement.metadata.algorithm {
59 MeasurementType::Sha256 => {
60 let mut hasher = Sha256::new();
61 hasher.update(&temp);
62 let result = hasher.finalize();
63 self.measurement.value[..result.len()].copy_from_slice(&result);
64 }
65 MeasurementType::Sha384 => {
66 let mut hasher = Sha384::new();
67 hasher.update(&temp);
68 let result = hasher.finalize();
69 self.measurement.value[..result.len()].copy_from_slice(&result);
70 }
71 MeasurementType::Sha512 => {
72 let mut hasher = Sha512::new();
73 hasher.update(&temp);
74 let result = hasher.finalize();
75 self.measurement.value[..result.len()].copy_from_slice(&result);
76 }
77 };
78
79 self.is_populated = true;
80 self.is_locked = lock;
81 }
82
83 pub fn initialize(&mut self, measurement: Measurement, lock: bool) {
86 assert!(!self.is_populated, "Do not initialize a populated slot!");
87
88 self.set_metadata(measurement.metadata);
89 self.measurement
90 .value
91 .resize(self.measurement.metadata.algorithm.hash_len(), 0);
92 self.extend_value(measurement.value, lock);
93 }
94
95 fn set_metadata(&mut self, metadata: MeasurementMetaData) {
98 self.measurement.metadata = metadata;
99 }
100
101 pub fn is_locked(&self) -> bool {
102 self.is_locked
103 }
104
105 pub fn is_populated(&self) -> bool {
106 self.is_populated
107 }
108
109 pub fn mark_as_populated(&mut self) {
110 self.is_populated = true;
111 }
112
113 pub fn is_prohibited(&self, metadata: &MeasurementMetaData) -> bool {
116 metadata.signer_id != self.measurement.metadata.signer_id
117 || metadata.algorithm != self.measurement.metadata.algorithm
118 }
119}
120
121#[derive(Debug)]
122pub struct MeasurementMgr {
125 measurements: [MeasurementSlot; NUM_OF_MEASUREMENT_SLOTS],
126}
127
128pub const NUM_OF_MEASUREMENT_SLOTS: usize = 32;
130
131impl MeasurementMgr {
132 pub fn init(
134 boot_measurements: Vec<BootMeasurement>,
135 ) -> Result<MeasurementMgr, MeasurementError> {
136 assert!(
137 boot_measurements.len() <= NUM_OF_MEASUREMENT_SLOTS,
138 "MeasurementMgr cannot contain HW measurements"
139 );
140
141 let mut measurements = core::array::from_fn(|_| MeasurementSlot::default());
142
143 boot_measurements
144 .into_iter()
145 .enumerate()
146 .try_for_each(|(index, boot_measurement)| {
147 let measurement = boot_measurement.try_into()?;
148 measurements[index].initialize(measurement, false);
149 Ok::<(), MeasurementError>(())
150 })
151 .unwrap();
152
153 Ok(MeasurementMgr { measurements })
154 }
155
156 pub fn read_measurement(
160 &self,
161 slot_id: usize,
162 ) -> Result<(&Measurement, bool), MeasurementError> {
163 if slot_id >= NUM_OF_MEASUREMENT_SLOTS {
164 return Err(MeasurementError::InvalidArgument);
165 }
166 let slot = &self.measurements[slot_id];
167
168 if !slot.is_populated() {
169 return Err(MeasurementError::DoesNotExist);
170 }
171 Ok((&slot.measurement, slot.is_locked))
172 }
173
174 pub fn extend_measurement(
180 &mut self,
181 slot_id: usize,
182 measurement: Measurement,
183 lock: bool,
184 ) -> Result<(), MeasurementError> {
185 if slot_id >= NUM_OF_MEASUREMENT_SLOTS {
186 return Err(MeasurementError::InvalidArgument);
187 }
188
189 let slot = &mut self.measurements[slot_id];
190
191 if slot.is_locked() {
192 return Err(MeasurementError::BadState);
193 }
194
195 if slot.is_populated() {
196 if slot.is_prohibited(&measurement.metadata) {
197 return Err(MeasurementError::NotPermitted);
198 }
199 slot.extend(measurement, lock);
200 } else {
201 slot.initialize(measurement, lock);
202 slot.mark_as_populated();
203 }
204
205 Ok(())
206 }
207}
208
209#[cfg(test)]
210mod tests {
211 use crate::hw::BootMeasurementMetadata;
212 use alloc::{string::ToString, vec::Vec};
213 use core::{iter, str::from_utf8};
214
215 use super::*;
216 use tinyvec::ArrayVec;
217
218 fn metadata(algorithm: MeasurementType) -> MeasurementMetaData {
219 let signer_id: SignerHash = ArrayVec::from([
220 0x01, 0x05, 0x01, 0xEF, 0x68, 0x07, 0x88, 0xCC, 0x33, 0x06, 0x54, 0xAB, 0x09, 0x01,
221 0x74, 0x77, 0x49, 0x08, 0x93, 0xA8, 0x01, 0x07, 0xEF, 0x01, 0x83, 0x09, 0x22, 0xCD,
222 0x09, 0x61, 0xB6, 0xFF, 0x01, 0x05, 0x01, 0xEF, 0x68, 0x07, 0x88, 0xCC, 0x33, 0x06,
223 0x54, 0xAB, 0x09, 0x01, 0x74, 0x77, 0x49, 0x08, 0x93, 0xA8, 0x01, 0x07, 0xEF, 0x01,
224 0x83, 0x09, 0x22, 0xCD, 0x09, 0x61, 0xB6, 0xFF,
225 ]);
226
227 let sw_version: SWVersion = from_utf8(&[
228 0x32, 0x35, 0x35, 0x2E, 0x32, 0x35, 0x35, 0x2E, 0x36, 0x35, 0x35, 0x33, 0x35, 0x0,
229 ])
230 .unwrap()
231 .to_string();
232
233 let sw_type: SWType = from_utf8(&[
234 0x4D, 0x45, 0x41, 0x53, 0x55, 0x52, 0x45, 0x44, 0x5F, 0x42, 0x4F, 0x4F, 0x54, 0x5F,
235 0x54, 0x45, 0x53, 0x54, 0x53, 0x0,
236 ])
237 .unwrap()
238 .to_string();
239
240 MeasurementMetaData {
241 signer_id,
242 sw_version,
243 algorithm,
244 sw_type,
245 }
246 }
247
248 fn value(len: usize) -> ValueHash {
249 let mut value: ValueHash = ValueHash::from([
250 0x8a, 0x66, 0x01, 0xf6, 0x70, 0x74, 0x8b, 0xe2, 0x33, 0xff, 0x5d, 0x75, 0xd7, 0xea,
251 0x89, 0xa8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x01, 0x05, 0x01, 0xEF,
252 0x68, 0x07, 0x88, 0xCC, 0x83, 0x09, 0x22, 0xCD, 0x09, 0x61, 0xB6, 0xFF, 0xbb, 0xbb,
253 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x56, 0x46, 0x58, 0x49, 0x99, 0x31, 0xcf, 0x59,
254 0x7d, 0xbc, 0x3a, 0x4e, 0x68, 0x79, 0x8a, 0x1c,
255 ]);
256 value.truncate(len);
257 value
258 }
259
260 fn test_extend(
261 mgr: &mut MeasurementMgr,
262 slot_id: usize,
263 algorithm: MeasurementType,
264 value: ValueHash,
265 expected_value: &[u8],
266 ) {
267 let metadata = metadata(algorithm);
268 let measurement = Measurement {
269 metadata: metadata.clone(),
270 value,
271 };
272
273 mgr.extend_measurement(slot_id, measurement, false).unwrap();
274
275 let (read_measurement, lock) = mgr.read_measurement(slot_id).unwrap();
276
277 assert_eq!(lock, false);
278 assert_eq!(metadata, read_measurement.metadata);
279 assert_eq!(&read_measurement.value[..], expected_value);
280 }
281
282 #[test]
285 fn extend_256_with_256() {
286 let slot_id = 20;
287 let algorithm = MeasurementType::Sha256;
288
289 let value_256_0: ValueHash = [
291 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
292 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
293 0xbb, 0xbb, 0xbb, 0xbb,
294 ]
295 .iter()
296 .cloned()
297 .collect();
298
299 let expected_value_256_0 = [
300 0x86, 0xbf, 0xbc, 0xe7, 0xf8, 0x8e, 0x77, 0xda, 0xb6, 0xbb, 0xfb, 0x92, 0x3b, 0xb7,
301 0x0e, 0x24, 0x11, 0xd3, 0x74, 0xdc, 0x65, 0x8d, 0xb7, 0x51, 0xc9, 0xbd, 0xec, 0x43,
302 0x8f, 0x5c, 0xce, 0x54,
303 ];
304
305 let mut mgr = MeasurementMgr::init(Vec::new()).unwrap();
306
307 test_extend(
308 &mut mgr,
309 slot_id,
310 algorithm,
311 value_256_0,
312 &expected_value_256_0,
313 );
314
315 let value_256_different_slot: ValueHash = [
317 0x75, 0xb2, 0x20, 0xfd, 0x5f, 0xfc, 0xdb, 0xfc, 0x20, 0x73, 0xe4, 0xa0, 0x2f, 0x8c,
318 0x53, 0x38, 0x3c, 0x74, 0xbd, 0xf3, 0xb6, 0xab, 0x9f, 0xb6, 0xb3, 0xd2, 0xbb, 0x7a,
319 0xa2, 0x08, 0xc5, 0x98,
320 ]
321 .iter()
322 .cloned()
323 .collect();
324
325 let expected_value_256_different_slot = [
326 0x84, 0x8A, 0x8C, 0xA6, 0x4F, 0x17, 0x54, 0x6A, 0x71, 0x8E, 0xE2, 0x59, 0x45, 0x92,
327 0x01, 0xBE, 0x31, 0xF8, 0x85, 0xF1, 0xD3, 0x3F, 0x38, 0x09, 0xE6, 0xF6, 0xF1, 0x82,
328 0x3A, 0x90, 0x04, 0x5A,
329 ];
330
331 test_extend(
332 &mut mgr,
333 slot_id + 1,
334 algorithm,
335 value_256_different_slot,
336 &expected_value_256_different_slot,
337 );
338
339 let value_256_1: ValueHash = [
341 0x01, 0x05, 0x01, 0xEF, 0x68, 0x07, 0x88, 0xCC, 0x33, 0x06, 0x54, 0xAB, 0x09, 0x01,
342 0x74, 0x77, 0x49, 0x08, 0x93, 0xA8, 0x01, 0x07, 0xEF, 0x01, 0x83, 0x09, 0x22, 0xCD,
343 0x09, 0x61, 0xB6, 0xFF,
344 ]
345 .iter()
346 .cloned()
347 .collect();
348
349 let expected_value_256_1 = [
350 0xd2, 0xab, 0xc1, 0x26, 0xeb, 0x5c, 0x25, 0x9d, 0x30, 0x33, 0x9c, 0x02, 0xd7, 0x49,
351 0x4f, 0x04, 0xe2, 0xd4, 0x49, 0xbe, 0x81, 0xa9, 0x60, 0x39, 0x56, 0x0e, 0x56, 0x90,
352 0xb3, 0xda, 0xaf, 0x25,
353 ];
354
355 test_extend(
356 &mut mgr,
357 slot_id,
358 algorithm,
359 value_256_1,
360 &expected_value_256_1,
361 );
362 }
363
364 #[test]
365 fn test_extend_256_with_512() {
366 let slot_id = 22;
367 let algorithm = MeasurementType::Sha256;
368
369 let value_512_0 = ArrayVec::from([
370 0x8a, 0x66, 0x01, 0xf6, 0x70, 0x74, 0x8b, 0xe2, 0x33, 0xff, 0x5d, 0x75, 0xd7, 0xea,
371 0x89, 0xa8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x01, 0x05, 0x01, 0xEF,
372 0x68, 0x07, 0x88, 0xCC, 0x83, 0x09, 0x22, 0xCD, 0x09, 0x61, 0xB6, 0xFF, 0xbb, 0xbb,
373 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x56, 0x46, 0x58, 0x49, 0x99, 0x31, 0xcf, 0x59,
374 0x7d, 0xbc, 0x3a, 0x4e, 0x68, 0x79, 0x8a, 0x1c,
375 ]);
376
377 let expected_value_256_0 = [
378 0x75, 0xb2, 0x20, 0xfd, 0x5f, 0xfc, 0xdb, 0xfc, 0x20, 0x73, 0xe4, 0xa0, 0x2f, 0x8c,
379 0x53, 0x38, 0x3c, 0x74, 0xbd, 0xf3, 0xb6, 0xab, 0x9f, 0xb6, 0xb3, 0xd2, 0xbb, 0x7a,
380 0xa2, 0x08, 0xc5, 0x98,
381 ];
382
383 let mut mgr = MeasurementMgr::init(Vec::new()).unwrap();
384
385 test_extend(
386 &mut mgr,
387 slot_id,
388 algorithm,
389 value_512_0,
390 &expected_value_256_0,
391 );
392
393 let value_512_1 = ArrayVec::from([
394 0x56, 0x46, 0x58, 0x49, 0x99, 0x31, 0xcf, 0x59, 0x7d, 0xbc, 0x3a, 0x4e, 0x68, 0x79,
395 0x8a, 0x1c, 0x01, 0x05, 0x01, 0xEF, 0x68, 0x07, 0x88, 0xCC, 0x83, 0x09, 0x22, 0xCD,
396 0x09, 0x61, 0xB6, 0xFF, 0x7d, 0xbc, 0x3a, 0x4e, 0x68, 0x79, 0x8a, 0x1c, 0x01, 0x05,
397 0x01, 0xEF, 0x68, 0x07, 0x88, 0xCC, 0x8a, 0x66, 0x01, 0xf6, 0x70, 0x74, 0x8b, 0xe2,
398 0x83, 0x09, 0x22, 0xCD, 0x09, 0x61, 0xB6, 0xFF,
399 ]);
400
401 let expected_value_256_1 = [
402 0x79, 0xc3, 0xb9, 0xca, 0xf7, 0x7b, 0xa7, 0xf3, 0x20, 0x65, 0x77, 0x04, 0x09, 0x60,
403 0x8a, 0x02, 0x4f, 0xa5, 0x45, 0x9c, 0x6d, 0x10, 0xa7, 0xca, 0x59, 0x3f, 0xf1, 0x4d,
404 0x9b, 0x37, 0xe8, 0x3c,
405 ];
406
407 test_extend(
408 &mut mgr,
409 slot_id,
410 algorithm,
411 value_512_1,
412 &expected_value_256_1,
413 );
414 }
415
416 #[test]
417 fn test_extend_512_with_256() {
418 let slot_id = 23;
419 let algorithm = MeasurementType::Sha512;
420
421 let value_256_0: ValueHash = [
422 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
423 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
424 0xbb, 0xbb, 0xbb, 0xbb,
425 ]
426 .iter()
427 .cloned()
428 .collect();
429
430 let expected_value_512_0 = [
431 0xa6, 0x34, 0xb5, 0xb6, 0xe5, 0xe9, 0x71, 0x5d, 0x47, 0x88, 0xf7, 0x2f, 0x1a, 0x39,
432 0xc3, 0xe2, 0xd2, 0xe1, 0x03, 0xde, 0xcf, 0xb8, 0xf8, 0xd6, 0x22, 0xcc, 0xff, 0x8c,
433 0xb2, 0xe3, 0xe8, 0x22, 0x74, 0x31, 0x6c, 0x4b, 0x8d, 0x66, 0x25, 0x11, 0xcc, 0x1c,
434 0xf9, 0x0a, 0x24, 0x56, 0xdf, 0xf2, 0xb6, 0x20, 0xd3, 0xbe, 0xf0, 0xe0, 0xb9, 0x56,
435 0xcf, 0x3a, 0xcc, 0x78, 0xe6, 0x58, 0xbe, 0x40,
436 ];
437
438 let mut mgr = MeasurementMgr::init(Vec::new()).unwrap();
439
440 test_extend(
441 &mut mgr,
442 slot_id,
443 algorithm,
444 value_256_0,
445 &expected_value_512_0,
446 );
447
448 let value_256_1: ValueHash = [
449 0x01, 0x05, 0x01, 0xEF, 0x68, 0x07, 0x88, 0xCC, 0x33, 0x06, 0x54, 0xAB, 0x09, 0x01,
450 0x74, 0x77, 0x49, 0x08, 0x93, 0xA8, 0x01, 0x07, 0xEF, 0x01, 0x83, 0x09, 0x22, 0xCD,
451 0x09, 0x61, 0xB6, 0xFF,
452 ]
453 .iter()
454 .cloned()
455 .collect();
456
457 let expected_value_512_1 = [
458 0x53, 0x2e, 0x19, 0xa7, 0xdf, 0x21, 0xe7, 0x7f, 0x6a, 0xe0, 0xe6, 0x30, 0xda, 0xfb,
459 0x39, 0x67, 0x8c, 0xdd, 0x74, 0x5f, 0x30, 0x9f, 0x10, 0x80, 0xb3, 0xfa, 0x88, 0x75,
460 0x33, 0x31, 0x00, 0x46, 0x59, 0x4f, 0x76, 0xb8, 0xfe, 0x5b, 0xae, 0xc4, 0xeb, 0xe2,
461 0xe9, 0x15, 0x02, 0x4f, 0x34, 0x4e, 0x88, 0xc0, 0x43, 0xcd, 0x90, 0x14, 0xcd, 0xaa,
462 0xd1, 0xc5, 0x73, 0xba, 0xc3, 0x4c, 0x56, 0xbe,
463 ];
464
465 test_extend(
466 &mut mgr,
467 slot_id,
468 algorithm,
469 value_256_1,
470 &expected_value_512_1,
471 );
472 }
473
474 #[test]
475 fn extend_512_with_512() {
476 let slot_id = NUM_OF_MEASUREMENT_SLOTS - 1;
477 let algorithm = MeasurementType::Sha512;
478
479 let value_512_0: ValueHash = [
480 0x8a, 0x66, 0x01, 0xf6, 0x70, 0x74, 0x8b, 0xe2, 0x33, 0xff, 0x5d, 0x75, 0xd7, 0xea,
481 0x89, 0xa8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x01, 0x05, 0x01, 0xEF,
482 0x68, 0x07, 0x88, 0xCC, 0x83, 0x09, 0x22, 0xCD, 0x09, 0x61, 0xB6, 0xFF, 0xbb, 0xbb,
483 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x56, 0x46, 0x58, 0x49, 0x99, 0x31, 0xcf, 0x59,
484 0x7d, 0xbc, 0x3a, 0x4e, 0x68, 0x79, 0x8a, 0x1c,
485 ]
486 .iter()
487 .cloned()
488 .collect();
489
490 let expected_value_512_0 = [
491 0x8e, 0x17, 0x5a, 0x1d, 0xcd, 0x79, 0xb8, 0xb5, 0x1c, 0xe9, 0xe2, 0x59, 0xc2, 0x56,
492 0x83, 0x05, 0xb7, 0x3f, 0x5f, 0x26, 0xf5, 0x67, 0x3a, 0x8c, 0xf7, 0x81, 0xa9, 0x45,
493 0x98, 0xe4, 0x4f, 0x67, 0xfd, 0xf4, 0x92, 0x68, 0x69, 0xee, 0x76, 0x67, 0xe9, 0x12,
494 0x0b, 0x5c, 0x1b, 0x97, 0x62, 0x5c, 0xc9, 0x6d, 0x34, 0x7c, 0x23, 0xce, 0x3c, 0x5f,
495 0x76, 0x3b, 0xf1, 0xd9, 0xb5, 0x47, 0x81, 0xf6,
496 ];
497
498 let mut mgr = MeasurementMgr::init(Vec::new()).unwrap();
499
500 test_extend(
501 &mut mgr,
502 slot_id,
503 algorithm,
504 value_512_0,
505 &expected_value_512_0,
506 );
507
508 let value_512_1: ValueHash = [
509 0x56, 0x46, 0x58, 0x49, 0x99, 0x31, 0xcf, 0x59, 0x7d, 0xbc, 0x3a, 0x4e, 0x68, 0x79,
510 0x8a, 0x1c, 0x01, 0x05, 0x01, 0xEF, 0x68, 0x07, 0x88, 0xCC, 0x83, 0x09, 0x22, 0xCD,
511 0x09, 0x61, 0xB6, 0xFF, 0x7d, 0xbc, 0x3a, 0x4e, 0x68, 0x79, 0x8a, 0x1c, 0x01, 0x05,
512 0x01, 0xEF, 0x68, 0x07, 0x88, 0xCC, 0x8a, 0x66, 0x01, 0xf6, 0x70, 0x74, 0x8b, 0xe2,
513 0x83, 0x09, 0x22, 0xCD, 0x09, 0x61, 0xB6, 0xFF,
514 ]
515 .iter()
516 .cloned()
517 .collect();
518
519 let expected_value_512_1 = [
520 0x69, 0x8f, 0xc1, 0x9d, 0xc0, 0xfb, 0x93, 0xc9, 0x78, 0x31, 0x52, 0xd9, 0x33, 0x6f,
521 0x35, 0xa7, 0x9a, 0x2d, 0x48, 0xdb, 0x45, 0xa8, 0xd4, 0xc4, 0x8c, 0x0e, 0xef, 0xcb,
522 0xeb, 0xc0, 0x11, 0x0d, 0xa2, 0xe4, 0x0f, 0x62, 0x78, 0x34, 0xdd, 0x8e, 0x46, 0xa9,
523 0x2b, 0xaa, 0x23, 0x00, 0x6b, 0x36, 0xc6, 0x79, 0xc0, 0x4e, 0x14, 0xca, 0x91, 0x3f,
524 0xd2, 0xde, 0xe2, 0x38, 0x58, 0xd5, 0x43, 0xd2,
525 ];
526
527 test_extend(
528 &mut mgr,
529 slot_id,
530 algorithm,
531 value_512_1,
532 &expected_value_512_1,
533 );
534 }
535
536 #[test]
539 fn test_prohibited_extend_after_lock() {
540 let slot_id = 9;
541
542 let measurement = Measurement {
543 metadata: metadata(MeasurementType::Sha256),
544 value: value(32),
545 };
546
547 let mut mgr = MeasurementMgr::init(Vec::new()).unwrap();
548
549 mgr.extend_measurement(slot_id, measurement.clone(), true)
550 .unwrap();
551
552 assert_eq!(
553 mgr.extend_measurement(slot_id, measurement, false)
554 .unwrap_err(),
555 MeasurementError::BadState
556 );
557 }
558
559 #[test]
560 fn test_prohibited_algorithm_change() {
561 let slot_id = 10;
562 let value = value(32);
563 let mut metadata = metadata(MeasurementType::Sha256);
564
565 let measurement = Measurement {
566 metadata: metadata.clone(),
567 value: value.clone(),
568 };
569
570 let mut mgr = MeasurementMgr::init(Vec::new()).unwrap();
571
572 mgr.extend_measurement(slot_id, measurement, false).unwrap();
573
574 metadata.algorithm = MeasurementType::Sha384;
575
576 let measurement = Measurement {
577 metadata: metadata.clone(),
578 value: value.clone(),
579 };
580
581 assert_eq!(
582 mgr.extend_measurement(slot_id, measurement, false)
583 .unwrap_err(),
584 MeasurementError::NotPermitted
585 );
586 }
587
588 #[test]
589 fn test_prohibited_signer_change() {
590 let slot_id = 10;
591 let value = value(32);
592 let mut metadata = metadata(MeasurementType::Sha256);
593
594 let measurement = Measurement {
595 metadata: metadata.clone(),
596 value: value.clone(),
597 };
598
599 let mut mgr = MeasurementMgr::init(Vec::new()).unwrap();
600
601 mgr.extend_measurement(slot_id, measurement, false).unwrap();
602
603 metadata.signer_id[13] = 13;
604
605 let measurement = Measurement {
606 metadata: metadata.clone(),
607 value: value.clone(),
608 };
609
610 assert_eq!(
611 mgr.extend_measurement(slot_id, measurement, false)
612 .unwrap_err(),
613 MeasurementError::NotPermitted
614 );
615 }
616
617 #[test]
618 fn test_extend_slot_out_of_bounds() {
619 let slot_id = NUM_OF_MEASUREMENT_SLOTS;
620 let value = value(32);
621 let metadata = metadata(MeasurementType::Sha256);
622
623 let mut mgr = MeasurementMgr::init(Vec::new()).unwrap();
624
625 assert_eq!(
626 mgr.extend_measurement(slot_id, Measurement { metadata, value }, false)
627 .unwrap_err(),
628 MeasurementError::InvalidArgument
629 );
630 }
631
632 #[test]
633 fn test_read_slot_out_of_bounds() {
634 let slot_id = NUM_OF_MEASUREMENT_SLOTS;
635 let mgr = MeasurementMgr::init(Vec::new()).unwrap();
636
637 assert_eq!(
638 mgr.read_measurement(slot_id).unwrap_err(),
639 MeasurementError::InvalidArgument
640 );
641 }
642
643 #[test]
644 fn test_read_slot_unpopulated() {
645 let slot_id = 20;
646 let mgr = MeasurementMgr::init(Vec::new()).unwrap();
647
648 assert_eq!(
649 mgr.read_measurement(slot_id).unwrap_err(),
650 MeasurementError::DoesNotExist
651 );
652 }
653
654 fn boot_measurements() -> Vec<BootMeasurement> {
656 Vec::from([
657 BootMeasurement {
658 measurement_value: [
659 0x61, 0x97, 0x3b, 0x4f, 0x62, 0x0c, 0x2a, 0xe6, 0xc7, 0x63, 0x51, 0x18, 0xa0,
660 0xb4, 0x37, 0x6d, 0x15, 0x34, 0x4c, 0x1c, 0x53, 0xa2, 0x17, 0x89, 0xb1, 0xaa,
661 0x95, 0xd2, 0x0f, 0x3c, 0x45, 0x06,
662 ]
663 .iter()
664 .cloned()
665 .collect(),
666 metadata: BootMeasurementMetadata {
667 signer_id: [
668 0xc6, 0xc3, 0x2a, 0x95, 0x7d, 0xf4, 0xc6, 0x69, 0x8c, 0x55, 0x0b, 0x69,
669 0x5d, 0x02, 0x2e, 0xd5, 0x18, 0x0c, 0xae, 0x71, 0xf8, 0xb4, 0x9c, 0xbb,
670 0x75, 0xe6, 0x06, 0x1c, 0x2e, 0xf4, 0x97, 0xe1,
671 ]
672 .iter()
673 .cloned()
674 .collect(),
675 measurement_type: 0,
676 sw_type: b"BL1".iter().cloned().collect(),
677 sw_version: b"0.1.0".iter().cloned().collect(),
678 },
679 },
680 BootMeasurement {
681 measurement_value: [
682 0xf1, 0x5f, 0x95, 0x3b, 0xe5, 0x0d, 0xad, 0x92, 0xc3, 0xb2, 0xaa, 0x32, 0x97,
683 0xe6, 0xa4, 0xa8, 0xd6, 0x6d, 0x33, 0x63, 0x84, 0x49, 0xec, 0x19, 0x22, 0xb4,
684 0xa7, 0x92, 0x4a, 0x7b, 0x30, 0x22,
685 ]
686 .iter()
687 .cloned()
688 .collect(),
689 metadata: BootMeasurementMetadata {
690 signer_id: [
691 0xa0, 0x64, 0xb1, 0xad, 0x60, 0xfa, 0x18, 0x33, 0x94, 0xdd, 0xa5, 0x78,
692 0x91, 0x35, 0x7f, 0x97, 0x2e, 0x4f, 0xe7, 0x22, 0x78, 0x2a, 0xdf, 0xf1,
693 0x85, 0x4c, 0x8b, 0x2a, 0x14, 0x2c, 0x04, 0x10,
694 ]
695 .iter()
696 .cloned()
697 .collect(),
698 measurement_type: 0,
699 sw_type: b"BL2".iter().cloned().collect(),
700 sw_version: b"1.9.0+0".iter().cloned().collect(),
701 },
702 },
703 ])
704 }
705
706 const BL_1_MEASUREMENT_SLOT_ID: usize = 0;
707 const BL_2_MEASUREMENT_SLOT_ID: usize = 1;
708
709 #[test]
710 fn test_boot_measurements_ok() {
711 let boot_measurements = boot_measurements();
712 let mgr = MeasurementMgr::init(boot_measurements.clone()).unwrap();
713
714 let bl1_measurement = &boot_measurements[0];
715 let (measurement, lock) = mgr.read_measurement(BL_1_MEASUREMENT_SLOT_ID).unwrap();
716
717 let expected_measurement_value: ValueHash = [
718 0x69, 0x7d, 0xe4, 0x40, 0x7d, 0xae, 0x45, 0xc0, 0x75, 0x06, 0xd1, 0xf0, 0x0b, 0x3d,
719 0xbf, 0x5c, 0xe1, 0xdb, 0x41, 0xf6, 0x9e, 0x17, 0x50, 0xa3, 0x11, 0xf9, 0x1d, 0x21,
720 0x3e, 0x11, 0x98, 0x89,
721 ]
722 .iter()
723 .cloned()
724 .collect();
725
726 assert_eq!(lock, false);
727 assert_eq!(
728 measurement.metadata,
729 <BootMeasurement as TryInto<Measurement>>::try_into(bl1_measurement.clone())
730 .unwrap()
731 .metadata
732 );
733 assert_eq!(measurement.value, expected_measurement_value);
734
735 let bl2_measurement = &boot_measurements[1];
736 let (measurement, lock) = mgr.read_measurement(BL_2_MEASUREMENT_SLOT_ID).unwrap();
737
738 let expected_measurement_value_2: ValueHash = [
739 0xa1, 0x9b, 0x4c, 0xf9, 0x32, 0x89, 0xd6, 0x89, 0xc8, 0xa9, 0xb7, 0xfe, 0x16, 0x6b,
740 0x4c, 0x5c, 0x12, 0xab, 0xc1, 0x12, 0xb3, 0x5f, 0xba, 0x81, 0xdf, 0x12, 0xf1, 0x4a,
741 0x99, 0x6f, 0x9d, 0x81,
742 ]
743 .iter()
744 .cloned()
745 .collect();
746
747 assert_eq!(lock, false);
748 assert_eq!(
749 measurement.metadata,
750 <BootMeasurement as TryInto<Measurement>>::try_into(bl2_measurement.clone())
751 .unwrap()
752 .metadata
753 );
754 assert_eq!(measurement.value, expected_measurement_value_2);
755 }
756
757 #[test]
758 #[should_panic(expected = "MeasurementMgr cannot contain HW measurements")]
759 fn test_boot_measurements_too_many() {
760 let boot_measurements = Vec::from_iter(
761 iter::repeat(BootMeasurement::default()).take(NUM_OF_MEASUREMENT_SLOTS + 1),
762 );
763
764 let _ = MeasurementMgr::init(boot_measurements);
765 }
766}