currently, the measurement policies look like:
[
{
"measurement_id": "dcap-tdx-example",
"attestation_type": "dcap-tdx",
"measurements": {
"mrtd": {
"expected_any": [
"47a1cc074b914df8596bad0ed13d50d561ad1effc7f7cc530ab86da7ea49ffc03e57e7da829f8cba9c629c3970505323"
]
},
"rtmr0": {
"expected_any": [
"da6e07866635cb34a9ffcdc26ec6622f289e625c42c39b320f29cdf1dc84390b4f89dd0b073be52ac38ca7b0a0f375bb"
]
},
// ...
}
}
]
which poses 2 problems:
- it gives false impression that attestation type binds the measurements to platform (e.g.
qemu-tdx vs. gcp-tdx)
- it makes hard to write complex policies (e.g. if we want to allow any permutation of 2 values for RTMR0 and 3 values for RTMR1, then we'd have to create a list of 6 entries)
the suggestion is to consider moving towards policies that are built along the lines of:
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum TdxRegister {
MRTD,
RTMR(u8),
}
pub type TdxMeasurement = [u8; 48];
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum PcrRegister {
Pcr(u8),
}
pub type PcrMeasurement = [u8; 32];
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Measurements {
Dcap(HashMap<TdxRegister, TdxMeasurement>),
Vtpm(HashMap<PcrRegister, PcrMeasurement>),
None,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ExpectedMeasurement {
Dcap(HashMap<TdxRegister, Vec<TdxMeasurement>>),
Vtpm(HashMap<PcrRegister, Vec<PcrMeasurement>>),
None,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DcapPlatform {
Azure,
Gcp,
Qemu,
None,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct MeasurementRecord {
#[serde(skip_serializing_if = "Option::is_none")]
pub platform: Option<DcapPlatform>,
#[serde(skip_serializing_if = "Option::is_none")]
pub measurements: Option<Vec<ExpectedMeasurement>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum MeasurementClause {
Match(Box<MeasurementRecord>),
Not(Box<MeasurementClause>),
And(Box<Vec<MeasurementClause>>),
Or(Box<Vec<MeasurementClause>>),
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct MeasurementPolicy {
pub policy: MeasurementClause,
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
}
this would allow:
- writing complex policies with and/or/not logical predicates
- decouple platform from measurements (e.g. if in the future azure implements native tdx attestation, we could easily extend support for that)
- when we have DCAP verification implemented, it could be easily plugged into
DcapPlatform
currently, the measurement policies look like:
which poses 2 problems:
qemu-tdxvs.gcp-tdx)the suggestion is to consider moving towards policies that are built along the lines of:
this would allow:
DcapPlatform