Include instance-hash in DICE chain
In order to limit access to a particular VM instance, local verifiers of
DICE chains (such as Secretkeeper) require instance-hash to be part DICE
chains. Let this be part of DICE chain of VM (specifically, part of
vm_entry certificate).
Test: #config_descriptor_with_instance_hash & #config_descriptor_without_instance_hash
Bug: 291245237
Change-Id: Ib5666dfbd9ed32250bc37903c134e806db6ddf9c
diff --git a/pvmfw/src/main.rs b/pvmfw/src/main.rs
index 2af19c4..5893907 100644
--- a/pvmfw/src/main.rs
+++ b/pvmfw/src/main.rs
@@ -143,8 +143,8 @@
RebootReason::InternalError
})?;
- let (new_instance, salt) = if cfg!(llpvm_changes)
- && should_defer_rollback_protection(fdt)?
+ 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)
{
info!("Guest OS is capable of Secretkeeper protection, deferring rollback protection");
@@ -155,7 +155,7 @@
return Err(RebootReason::InvalidPayload);
};
// `new_instance` cannot be known to pvmfw
- (false, salt_from_instance_id(fdt)?)
+ (false, instance_hash.unwrap())
} else {
let (recorded_entry, mut instance_img, header_index) =
get_recorded_entry(&mut pci_root, cdi_seal).map_err(|e| {
@@ -164,18 +164,15 @@
})?;
let (new_instance, salt) = if let Some(entry) = recorded_entry {
maybe_check_dice_measurements_match_entry(&dice_inputs, &entry)?;
- let salt = if cfg!(llpvm_changes) { salt_from_instance_id(fdt)? } else { entry.salt };
+ let salt = instance_hash.unwrap_or(entry.salt);
(false, salt)
} else {
// New instance!
- let salt = if cfg!(llpvm_changes) {
- salt_from_instance_id(fdt)?
- } else {
- rand::random_array().map_err(|e| {
- error!("Failed to generated instance.img salt: {e}");
- RebootReason::InternalError
- })?
- };
+ let salt = instance_hash.map_or_else(rand::random_array, Ok).map_err(|e| {
+ error!("Failed to generated instance.img salt: {e}");
+ RebootReason::InternalError
+ })?;
+
let entry = EntryBody::new(&dice_inputs, &salt);
record_instance_entry(&entry, cdi_seal, &mut instance_img, header_index).map_err(
|e| {
@@ -204,10 +201,12 @@
Cow::Owned(truncated_bcc_handover)
};
- dice_inputs.write_next_bcc(new_bcc_handover.as_ref(), &salt, next_bcc).map_err(|e| {
- error!("Failed to derive next-stage DICE secrets: {e:?}");
- RebootReason::SecretDerivationError
- })?;
+ dice_inputs.write_next_bcc(new_bcc_handover.as_ref(), &salt, instance_hash, 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| {