pvmfw: rollback: Force fixed RBP for RemoteAttest

If an image pretends to be the RKP VM ("Capability::RemoteAttest"),
force that it goes through the intended fixed-index rollback solution
instead of potentially enabling the use of other RB solutions (such as
deferred) and still adding the RKP VM marker to the DICE chain. This
effectively makes pvmfw ignore the other use-case-specific Capability
values when it recognizes the RKP VM.

More fundamentally, this introduces the logic that pvmfw should always
(and only) check "special" VMs with the appropriate RBP method, an
approach that should survive converting Capability::RemoteAttest into a
separate (re-usable) identifying property (b/378673494) but also adding
support for new fixed RBP methods such as "fixed digest" (b/392628867).

Bug: 377276983
Bug: 391620545
Bug: 392628867
Test: m pvmfw_bin
Change-Id: Ia25a6265ed3f0466ff8bd22411636e5f7a9e5d60
diff --git a/guest/pvmfw/src/rollback.rs b/guest/pvmfw/src/rollback.rs
index 004acdb..e51b6d5 100644
--- a/guest/pvmfw/src/rollback.rs
+++ b/guest/pvmfw/src/rollback.rs
@@ -44,15 +44,16 @@
     cdi_seal: &[u8],
     instance_hash: Option<Hidden>,
 ) -> Result<(bool, Hidden, bool), RebootReason> {
-    if (should_defer_rollback_protection(fdt)?
+    if let Some(fixed) = get_fixed_rollback_protection(verified_boot_data) {
+        // Prevent attackers from impersonating well-known images.
+        perform_fixed_index_rollback_protection(verified_boot_data, fixed)?;
+        Ok((false, instance_hash.unwrap(), false))
+    } else if (should_defer_rollback_protection(fdt)?
         && verified_boot_data.has_capability(Capability::SecretkeeperProtection))
         || verified_boot_data.has_capability(Capability::TrustySecurityVm)
     {
         perform_deferred_rollback_protection(verified_boot_data)?;
         Ok((false, instance_hash.unwrap(), true))
-    } else if verified_boot_data.has_capability(Capability::RemoteAttest) {
-        perform_fixed_index_rollback_protection(verified_boot_data)?;
-        Ok((false, instance_hash.unwrap(), false))
     } else {
         perform_legacy_rollback_protection(fdt, dice_inputs, cdi_seal, instance_hash)
     }
@@ -72,11 +73,19 @@
     }
 }
 
+fn get_fixed_rollback_protection(verified_boot_data: &VerifiedBootData) -> Option<u64> {
+    if verified_boot_data.has_capability(Capability::RemoteAttest) {
+        Some(service_vm_version::VERSION)
+    } else {
+        None
+    }
+}
+
 fn perform_fixed_index_rollback_protection(
     verified_boot_data: &VerifiedBootData,
+    fixed_index: u64,
 ) -> Result<(), RebootReason> {
     info!("Performing fixed-index rollback protection");
-    let fixed_index = service_vm_version::VERSION;
     let index = verified_boot_data.rollback_index;
     if index != fixed_index {
         error!("Rollback index mismatch: expected {fixed_index}, found {index}");