use super::{
Hasher, Measurement, MeasurementError, MEASUREMENTS_SLOT_RIM, MEASURE_DESC_TYPE_DATA,
MEASURE_DESC_TYPE_REC, MEASURE_DESC_TYPE_RIPAS, RMI_MEASURE_CONTENT,
};
use crate::rmi::rec::params::Params as RecParams;
use crate::{host::DataPage, realm::rd::Rd, rmi::realm::params::Params as RealmParams, rsi};
pub struct HashContext<'a> {
hasher: Hasher,
rd: &'a mut Rd,
}
impl<'a> HashContext<'a> {
pub fn new(rd: &'a mut Rd) -> Result<Self, MeasurementError> {
Ok(Self {
hasher: Hasher::from_hash_algo(rd.hash_algo())?,
rd,
})
}
pub fn measure_realm_create(&mut self, params: &RealmParams) -> Result<(), rsi::error::Error> {
crate::rsi::measurement::extend(self.rd, MEASUREMENTS_SLOT_RIM, |rim| {
self.hasher.hash_object_into(params, rim)
})
}
pub fn extend_measurement(
&mut self,
buffer: &[u8],
index: usize,
) -> Result<(), rsi::error::Error> {
crate::rsi::measurement::extend(self.rd, index, |current| {
let old_value = *current;
self.hasher.hash_fields_into(current, |h| {
h.hash(&old_value.as_ref()[0..self.hasher.output_size()]);
h.hash(buffer);
})
})
}
pub fn measure_data_granule(
&mut self,
data: &DataPage,
ipa: usize,
flags: usize,
) -> Result<(), rsi::error::Error> {
let mut data_measurement = Measurement::empty();
if flags == RMI_MEASURE_CONTENT {
self.hasher.hash_fields_into(&mut data_measurement, |h| {
h.hash(data.as_slice());
})?;
}
crate::rsi::measurement::extend(self.rd, MEASUREMENTS_SLOT_RIM, |current| {
let oldrim = *current;
self.hasher.hash_fields_into(current, |h| {
h.hash_u8(MEASURE_DESC_TYPE_DATA); h.hash([0u8; 7]); h.hash_u64(0x100); h.hash(oldrim); h.hash_usize(ipa); h.hash_usize(flags); h.hash(data_measurement); h.hash([0u8; 0x100 - 0xa0]); })
})
}
pub fn measure_rec_params(&mut self, params: &RecParams) -> Result<(), rsi::error::Error> {
let mut params_measurement = Measurement::empty();
self.hasher
.hash_object_into(params, &mut params_measurement)?;
crate::rsi::measurement::extend(self.rd, MEASUREMENTS_SLOT_RIM, |current| {
let oldrim = *current;
self.hasher.hash_fields_into(current, |h| {
h.hash_u8(MEASURE_DESC_TYPE_REC); h.hash([0u8; 7]); h.hash_u64(0x100); h.hash(oldrim); h.hash(params_measurement); h.hash([0u8; 0x100 - 0x90]); })
})
}
pub fn measure_ripas_granule(
&mut self,
ipa: usize,
level: u8,
) -> Result<(), rsi::error::Error> {
crate::rsi::measurement::extend(self.rd, MEASUREMENTS_SLOT_RIM, |current| {
let oldrim = *current;
self.hasher.hash_fields_into(current, |h| {
h.hash_u8(MEASURE_DESC_TYPE_RIPAS); h.hash([0u8; 7]); h.hash_u64(0x100); h.hash(oldrim); h.hash_usize(ipa); h.hash_u8(level); h.hash([0u8; 7]); h.hash([0u8; 0xa0]); })
})
}
}