#![cfg(feature = "profile-intel")]
use std::collections::BTreeMap;
use corim::cbor::value::Value;
use corim::profile::intel::{
IntelProfile, MVAL_TEE_ADVISORY_IDS, MVAL_TEE_ATTRIBUTES, MVAL_TEE_EPOCH, MVAL_TEE_ISVSVN,
MVAL_TEE_MRTEE, MVAL_TEE_TCBSTATUS, MVAL_TEE_VENDOR, TAG_INTEL_EXPRESSION,
};
use corim::profile::{MatchContext, Profile};
use corim::types::common::MeasuredElement;
use corim::types::environment::{ClassMap, EnvironmentMap};
use corim::types::measurement::{Digest, MeasurementMap, MeasurementValuesMap};
use corim::types::triples::ReferenceTriple;
use corim::validate::{match_reference_values, match_reference_values_with_profile, EvidenceClaim};
fn env() -> EnvironmentMap {
EnvironmentMap {
class: Some(ClassMap::new("Intel", "TDX")),
instance: None,
group: None,
}
}
fn ref_triple_with_extras(extras: BTreeMap<i64, Value>) -> ReferenceTriple {
ReferenceTriple::new(
env(),
vec![MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: extras,
..Default::default()
},
authorized_by: None,
}],
)
}
fn evidence_with_extras(extras: BTreeMap<i64, Value>) -> Vec<EvidenceClaim> {
vec![EvidenceClaim {
environment: env(),
measurements: vec![MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: extras,
..Default::default()
},
authorized_by: None,
}],
}]
}
fn expr_tag(body: Value) -> Value {
Value::Tag(TAG_INTEL_EXPRESSION, Box::new(body))
}
#[test]
fn match_measurement_returns_none_when_reference_has_no_intel_keys() {
let p = IntelProfile::new();
let r = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
name: Some("x".into()),
..Default::default()
},
authorized_by: None,
};
let e = r.clone();
assert_eq!(p.match_measurement(&r, &e, &MatchContext::new()), None);
}
#[test]
fn match_measurement_returns_some_false_when_evidence_missing_intel_key() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(MVAL_TEE_VENDOR, Value::Text("Intel".into()));
let r_triple = ref_triple_with_extras(r_extras);
let r = r_triple.measurements()[0].clone();
let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap::default(),
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(false)
);
}
#[test]
fn match_measurement_some_true_when_bare_intel_equal_and_core_matches() {
let p = IntelProfile::new();
let mut extras = BTreeMap::new();
extras.insert(MVAL_TEE_VENDOR, Value::Text("Intel".into()));
let r_triple = ref_triple_with_extras(extras.clone());
let r = r_triple.measurements()[0].clone();
let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(true)
);
}
#[test]
fn match_measurement_some_false_when_bare_intel_unequal() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(MVAL_TEE_VENDOR, Value::Text("Intel".into()));
let r_triple = ref_triple_with_extras(r_extras);
let r = r_triple.measurements()[0].clone();
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_VENDOR, Value::Text("AMD".into()));
let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: e_extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(false)
);
}
#[test]
fn match_measurement_some_true_when_numeric_ge_satisfied() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(
MVAL_TEE_ISVSVN,
expr_tag(Value::Array(vec![Value::Integer(2), Value::Integer(5)])),
);
let r_triple = ref_triple_with_extras(r_extras);
let r = r_triple.measurements()[0].clone();
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_ISVSVN, Value::Integer(7));
let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: e_extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(true)
);
}
#[test]
fn match_measurement_some_false_when_numeric_ge_violated() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(
MVAL_TEE_ISVSVN,
expr_tag(Value::Array(vec![Value::Integer(2), Value::Integer(5)])),
);
let r_triple = ref_triple_with_extras(r_extras);
let r = r_triple.measurements()[0].clone();
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_ISVSVN, Value::Integer(3));
let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: e_extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(false)
);
}
#[test]
fn match_measurement_some_true_when_mask_eq_passes() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(
MVAL_TEE_ATTRIBUTES,
expr_tag(Value::Array(vec![
Value::Integer(1),
Value::Bytes(vec![0xF0]),
Value::Bytes(vec![0xF0]),
])),
);
let r_triple = ref_triple_with_extras(r_extras);
let r = r_triple.measurements()[0].clone();
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_ATTRIBUTES, Value::Bytes(vec![0xFA]));
let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: e_extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(true)
);
}
#[test]
fn match_measurement_some_false_when_mask_eq_fails() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(
MVAL_TEE_ATTRIBUTES,
expr_tag(Value::Array(vec![
Value::Integer(1),
Value::Bytes(vec![0xF0]),
Value::Bytes(vec![0xF0]),
])),
);
let r_triple = ref_triple_with_extras(r_extras);
let r = r_triple.measurements()[0].clone();
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_ATTRIBUTES, Value::Bytes(vec![0x1A]));
let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: e_extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(false)
);
}
#[test]
fn match_measurement_some_true_when_set_member_matches() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(
MVAL_TEE_TCBSTATUS,
expr_tag(Value::Array(vec![
Value::Integer(6), Value::Array(vec![
Value::Text("UpToDate".into()),
Value::Text("Hardening".into()),
]),
])),
);
let r_triple = ref_triple_with_extras(r_extras);
let r = r_triple.measurements()[0].clone();
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_TCBSTATUS, Value::Text("Hardening".into()));
let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: e_extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(true)
);
}
#[test]
fn match_measurement_some_false_when_set_not_member_violated() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(
MVAL_TEE_ADVISORY_IDS,
expr_tag(Value::Array(vec![
Value::Integer(7), Value::Array(vec![Value::Text("CVE-2024-1234".into())]),
])),
);
let r_triple = ref_triple_with_extras(r_extras);
let r = r_triple.measurements()[0].clone();
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_ADVISORY_IDS, Value::Text("CVE-2024-1234".into()));
let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: e_extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(false)
);
}
#[test]
fn match_measurement_returns_none_when_only_intel_key_is_epoch() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(
MVAL_TEE_EPOCH,
expr_tag(Value::Array(vec![
Value::Integer(2), Value::Integer(60), Value::Null, ])),
);
let r_triple = ref_triple_with_extras(r_extras);
let r = r_triple.measurements()[0].clone();
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_EPOCH, Value::Integer(0));
let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: e_extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(p.match_measurement(&r, &e, &MatchContext::new()), None);
}
#[test]
fn match_measurement_some_true_intel_pass_skip_mix() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(
MVAL_TEE_ISVSVN,
expr_tag(Value::Array(vec![Value::Integer(2), Value::Integer(1)])),
);
r_extras.insert(
MVAL_TEE_EPOCH,
expr_tag(Value::Array(vec![
Value::Integer(2),
Value::Integer(60),
Value::Null,
])),
);
let r_triple = ref_triple_with_extras(r_extras);
let r = r_triple.measurements()[0].clone();
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_ISVSVN, Value::Integer(7));
e_extras.insert(MVAL_TEE_EPOCH, Value::Integer(0)); let e = MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
extra_entries: e_extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(true)
);
}
#[test]
fn match_measurement_returns_some_false_when_core_fields_disagree() {
let p = IntelProfile::new();
let mut extras = BTreeMap::new();
extras.insert(MVAL_TEE_VENDOR, Value::Text("Intel".into()));
let r = MeasurementMap {
mkey: Some(MeasuredElement::Uint(1)),
mval: MeasurementValuesMap {
extra_entries: extras.clone(),
..Default::default()
},
authorized_by: None,
};
let e = MeasurementMap {
mkey: Some(MeasuredElement::Uint(2)),
mval: MeasurementValuesMap {
extra_entries: extras,
..Default::default()
},
authorized_by: None,
};
assert_eq!(
p.match_measurement(&r, &e, &MatchContext::new()),
Some(false)
);
}
#[test]
fn dispatch_through_validate_passes_with_intel_profile() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(
MVAL_TEE_ISVSVN,
expr_tag(Value::Array(vec![Value::Integer(2), Value::Integer(5)])),
);
let triple = ref_triple_with_extras(r_extras);
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_ISVSVN, Value::Integer(7));
let evidence = evidence_with_extras(e_extras);
let with_profile = match_reference_values_with_profile(
std::slice::from_ref(&triple),
&evidence,
Some(&p),
&MatchContext::new(),
);
assert_eq!(with_profile.len(), 1, "profile-aware match should succeed");
assert_eq!(with_profile[0].measurements.len(), 1);
let no_profile = match_reference_values(&[triple], &evidence);
assert_eq!(no_profile.len(), 1);
}
#[test]
fn dispatch_through_validate_rejects_with_intel_profile() {
let p = IntelProfile::new();
let mut r_extras = BTreeMap::new();
r_extras.insert(
MVAL_TEE_ISVSVN,
expr_tag(Value::Array(vec![Value::Integer(2), Value::Integer(5)])),
);
let triple = ref_triple_with_extras(r_extras);
let mut e_extras = BTreeMap::new();
e_extras.insert(MVAL_TEE_ISVSVN, Value::Integer(3));
let evidence = evidence_with_extras(e_extras);
let no_profile = match_reference_values(std::slice::from_ref(&triple), &evidence);
assert_eq!(
no_profile.len(),
1,
"core ignores extras so it reports a false-positive match"
);
let with_profile =
match_reference_values_with_profile(&[triple], &evidence, Some(&p), &MatchContext::new());
assert!(
with_profile.is_empty(),
"Intel profile should reject the pair"
);
}
#[test]
fn dispatch_through_validate_passes_combining_intel_and_core_digest() {
let p = IntelProfile::new();
let digest = Digest::new(1, vec![0xAAu8; 32]);
let mut r_extras = BTreeMap::new();
r_extras.insert(MVAL_TEE_MRTEE, Value::Bytes(vec![0xCCu8; 32]));
let triple = ReferenceTriple::new(
env(),
vec![MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
digests: Some(vec![digest.clone()]),
extra_entries: r_extras.clone(),
..Default::default()
},
authorized_by: None,
}],
);
let evidence = vec![EvidenceClaim {
environment: env(),
measurements: vec![MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
digests: Some(vec![digest]),
extra_entries: r_extras,
..Default::default()
},
authorized_by: None,
}],
}];
let claims =
match_reference_values_with_profile(&[triple], &evidence, Some(&p), &MatchContext::new());
assert_eq!(claims.len(), 1);
}
#[test]
fn dispatch_through_validate_rejects_when_core_disagrees() {
let p = IntelProfile::new();
let mut extras = BTreeMap::new();
extras.insert(MVAL_TEE_MRTEE, Value::Bytes(vec![0xCCu8; 32]));
let triple = ReferenceTriple::new(
env(),
vec![MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
digests: Some(vec![Digest::new(1, vec![0xAAu8; 32])]),
extra_entries: extras.clone(),
..Default::default()
},
authorized_by: None,
}],
);
let evidence = vec![EvidenceClaim {
environment: env(),
measurements: vec![MeasurementMap {
mkey: None,
mval: MeasurementValuesMap {
digests: Some(vec![Digest::new(1, vec![0xBBu8; 32])]), extra_entries: extras,
..Default::default()
},
authorized_by: None,
}],
}];
let claims =
match_reference_values_with_profile(&[triple], &evidence, Some(&p), &MatchContext::new());
assert!(claims.is_empty(), "core digest mismatch should reject");
}