Include defer_rbp in the hidden input of DICE am: ffadd4d13c
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Virtualization/+/3036974
Change-Id: Ib70acfd4aa399db481ac48cd6b36a5826048c8c3
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/pvmfw/src/dice.rs b/pvmfw/src/dice.rs
index aaf2691..3d7168d 100644
--- a/pvmfw/src/dice.rs
+++ b/pvmfw/src/dice.rs
@@ -96,6 +96,7 @@
current_bcc_handover: &[u8],
salt: &[u8; HIDDEN_SIZE],
instance_hash: Option<Hash>,
+ deferred_rollback_protection: bool,
next_bcc: &mut [u8],
) -> Result<()> {
let config = self
@@ -107,16 +108,23 @@
Config::Descriptor(&config),
self.auth_hash,
self.mode,
- self.make_hidden(salt)?,
+ self.make_hidden(salt, deferred_rollback_protection)?,
);
let _ = bcc_handover_main_flow(current_bcc_handover, &dice_inputs, next_bcc)?;
Ok(())
}
- fn make_hidden(&self, salt: &[u8; HIDDEN_SIZE]) -> Result<[u8; HIDDEN_SIZE]> {
+ fn make_hidden(
+ &self,
+ salt: &[u8; HIDDEN_SIZE],
+ deferred_rollback_protection: bool,
+ ) -> diced_open_dice::Result<[u8; HIDDEN_SIZE]> {
// We want to make sure we get a different sealing CDI for:
// - VMs with different salt values
// - An RKP VM and any other VM (regardless of salt)
+ // - depending on whether rollback protection has been deferred to payload. This ensures the
+ // adversary cannot leak the secrets by using old images & setting
+ // `deferred_rollback_protection` to true.
// The hidden input for DICE affects the sealing CDI (but the values in the config
// descriptor do not).
// Since the hidden input has to be a fixed size, create it as a hash of the values we
@@ -126,10 +134,16 @@
struct HiddenInput {
rkp_vm_marker: bool,
salt: [u8; HIDDEN_SIZE],
+ deferred_rollback_protection: bool,
}
- // TODO(b/291213394): Include `defer_rollback_protection` flag in the Hidden Input to
- // differentiate the secrets in both cases.
- Ok(hash(HiddenInput { rkp_vm_marker: self.rkp_vm_marker, salt: *salt }.as_bytes())?)
+ hash(
+ HiddenInput {
+ rkp_vm_marker: self.rkp_vm_marker,
+ salt: *salt,
+ deferred_rollback_protection,
+ }
+ .as_bytes(),
+ )
}
fn generate_config_descriptor(&self, instance_hash: Option<Hash>) -> Result<Vec<u8>> {
diff --git a/pvmfw/src/main.rs b/pvmfw/src/main.rs
index 5893907..299d1c0 100644
--- a/pvmfw/src/main.rs
+++ b/pvmfw/src/main.rs
@@ -144,9 +144,9 @@
})?;
let instance_hash = if cfg!(llpvm_changes) { Some(salt_from_instance_id(fdt)?) } else { None };
- let (new_instance, salt) = if should_defer_rollback_protection(fdt)?
- && verified_boot_data.has_capability(Capability::SecretkeeperProtection)
- {
+ let defer_rollback_protection = should_defer_rollback_protection(fdt)?
+ && verified_boot_data.has_capability(Capability::SecretkeeperProtection);
+ let (new_instance, salt) = if defer_rollback_protection {
info!("Guest OS is capable of Secretkeeper protection, deferring rollback protection");
// rollback_index of the image is used as security_version and is expected to be > 0 to
// discourage implicit allocation.
@@ -201,12 +201,18 @@
Cow::Owned(truncated_bcc_handover)
};
- dice_inputs.write_next_bcc(new_bcc_handover.as_ref(), &salt, instance_hash, next_bcc).map_err(
- |e| {
+ dice_inputs
+ .write_next_bcc(
+ new_bcc_handover.as_ref(),
+ &salt,
+ instance_hash,
+ defer_rollback_protection,
+ next_bcc,
+ )
+ .map_err(|e| {
error!("Failed to derive next-stage DICE secrets: {e:?}");
RebootReason::SecretDerivationError
- },
- )?;
+ })?;
flush(next_bcc);
let kaslr_seed = u64::from_ne_bytes(rand::random_array().map_err(|e| {