| 10 | GenericArray<u8, <DigestType as sha3::digest::OutputSizeUser>::OutputSize>; |
| 11 | |
| 12 | pub fn measure(kernel_file: String, embedded_tap: bool, base_address: u64) -> Result<(), Error> { |
| 13 | use std::io::BufReader; |
| 14 | use std::io::Read; |
| 15 | |
| 16 | let mut digest = MeasurementDigest::default(); |
| 17 | |
| 18 | let kernel = OpenOptions::new().read(true).open(kernel_file)?; |
| 19 | let mut buf = BufReader::new(kernel); |
| 20 | let mut buffer = [0u8; 4096]; // 1 4KiB page |
| 21 | let mut address = base_address; |
| 22 | while let Ok(bytes_read) = buf.read(&mut buffer) { |
| 23 | if bytes_read == 0 { |
| 24 | break; |
| 25 | } |
| 26 | let header = [buffer[0], buffer[1], buffer[2], buffer[3]]; |
| 27 | if embedded_tap { |
| 28 | if u32::from_le_bytes(header) == riscv_cove_tap::ACE_MAGIC_TAP_START { |
| 29 | (0..4096).for_each(|i| buffer[i] = 0); // security monitor will clear it |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | if buffer.iter().find(|b| **b != 0).is_some() { |
| 34 | use sha3::Digest; |
| 35 | let mut hasher = DigestType::new_with_prefix(digest.clone()); |
| 36 | hasher.update(address.to_le_bytes()); |
| 37 | hasher.update(&buffer); |
| 38 | hasher.finalize_into(&mut digest); |
| 39 | // println!("Page 0x{:x} {:100x}", address, digest); |
| 40 | } else { |
| 41 | // println!("Page 0x{:x} empty", address); |
| 42 | } |
| 43 | address += 4096; |
| 44 | (0..4096).for_each(|i| buffer[i] = 0); |
| 45 | } |
| 46 | println!("Digest 0x{:100x}", digest); |
| 47 | Ok(()) |
| 48 | } |