Test deferred_rbp changes secrets
Add a unit test that uses a sample DICE chain, does derivation with
different values of `deferred_rollback_protection` & checks that the
sealing CDIs of output are different.
Test: atest #changing_deferred_rpb_changes_secrets
Bug: 342378315
Change-Id: I9a69e76f9802fcf14c550956fb6e23431a38688f
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index 66b34a6..144e81e 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -117,9 +117,10 @@
rustlibs: [
"libcbor_util",
"libciborium",
- "libdiced_open_dice_nostd",
+ "libdiced_open_dice",
"libpvmfw_avb_nostd",
"libzerocopy_nostd",
+ "libhex",
],
}
diff --git a/pvmfw/src/dice.rs b/pvmfw/src/dice.rs
index 3d7168d..da19931 100644
--- a/pvmfw/src/dice.rs
+++ b/pvmfw/src/dice.rs
@@ -71,6 +71,7 @@
Ok(hash(&digests)?)
}
+#[derive(Clone)]
pub struct PartialInputs {
pub code_hash: Hash,
pub auth_hash: Hash,
@@ -190,9 +191,20 @@
#[cfg(test)]
mod tests {
- use super::*;
+ use crate::{
+ Hash, PartialInputs, COMPONENT_NAME_KEY, INSTANCE_HASH_KEY, RKP_VM_MARKER_KEY,
+ SECURITY_VERSION_KEY,
+ };
use ciborium::Value;
+ use diced_open_dice::DiceArtifacts;
+ use diced_open_dice::DiceMode;
+ use diced_open_dice::HIDDEN_SIZE;
+ use pvmfw_avb::Capability;
+ use pvmfw_avb::DebugLevel;
+ use pvmfw_avb::Digest;
+ use pvmfw_avb::VerifiedBootData;
use std::collections::HashMap;
+ use std::mem::size_of;
use std::vec;
const COMPONENT_VERSION_KEY: i64 = -70003;
@@ -298,4 +310,67 @@
.map(|(k, v)| ((k.into_integer().unwrap().try_into().unwrap()), v))
.collect()
}
+
+ #[test]
+ fn changing_deferred_rpb_changes_secrets() {
+ let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
+ let inputs = PartialInputs::new(&vb_data).unwrap();
+ let mut buffer_without_defer = [0; 4096];
+ let mut buffer_with_defer = [0; 4096];
+ let mut buffer_without_defer_retry = [0; 4096];
+
+ let sample_dice_input: &[u8] = &[
+ 0xa3, // CDI attest
+ 0x01, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // CDI seal
+ 0x02, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // DICE chain
+ 0x03, 0x82, 0xa6, 0x01, 0x02, 0x03, 0x27, 0x04, 0x02, 0x20, 0x01, 0x21, 0x40, 0x22,
+ 0x40, 0x84, 0x40, 0xa0, 0x40, 0x40,
+ // 8-bytes of trailing data that aren't part of the DICE chain.
+ 0x84, 0x41, 0x55, 0xa0, 0x42, 0x11, 0x22, 0x40,
+ ];
+
+ inputs
+ .clone()
+ .write_next_bcc(
+ sample_dice_input,
+ &[0u8; HIDDEN_SIZE],
+ Some([0u8; 64]),
+ false,
+ &mut buffer_without_defer,
+ )
+ .unwrap();
+ let bcc_handover1 = diced_open_dice::bcc_handover_parse(&buffer_without_defer).unwrap();
+
+ inputs
+ .clone()
+ .write_next_bcc(
+ sample_dice_input,
+ &[0u8; HIDDEN_SIZE],
+ Some([0u8; 64]),
+ true,
+ &mut buffer_with_defer,
+ )
+ .unwrap();
+ let bcc_handover2 = diced_open_dice::bcc_handover_parse(&buffer_with_defer).unwrap();
+
+ inputs
+ .clone()
+ .write_next_bcc(
+ sample_dice_input,
+ &[0u8; HIDDEN_SIZE],
+ Some([0u8; 64]),
+ false,
+ &mut buffer_without_defer_retry,
+ )
+ .unwrap();
+ let bcc_handover3 =
+ diced_open_dice::bcc_handover_parse(&buffer_without_defer_retry).unwrap();
+
+ assert_ne!(bcc_handover1.cdi_seal(), bcc_handover2.cdi_seal());
+ assert_eq!(bcc_handover1.cdi_seal(), bcc_handover3.cdi_seal());
+ }
}