Check whether remote attestation is supported with system property

This cl introduces a new system property
avf.remote_attestation.enabled to allow vendors to
disable the remote attestation feature in vendor init.

Bug: 341598459
Test: enable/disable the feature and check VmAttestationTestApp

Change-Id: I5b26ba029ea1be74d8c0d139d69aee608c92f327
diff --git a/docs/vm_remote_attestation.md b/docs/vm_remote_attestation.md
index 3483351..195804f 100644
--- a/docs/vm_remote_attestation.md
+++ b/docs/vm_remote_attestation.md
@@ -117,7 +117,16 @@
 - The DICE chain should have RKP VM markers that help identify RKP VM as required
   by the [remote provisioning HAL][rkp-hal-markers].
 
-The feature is enabled by default. To disable it, you can set
-`PRODUCT_AVF_REMOTE_ATTESTATION_DISABLED` to true in your Makefile.
+The feature is enabled by default. To disable it, you have two options:
+
+1. Set `PRODUCT_AVF_REMOTE_ATTESTATION_DISABLED` to `true` in your Makefile to
+   disable the feature at build time.
+
+2. Set the system property `avf.remote_attestation.enabled` to `0` to disable
+   the feature at boot time by including the following line in vendor init:
+   `setprop avf.remote_attestation.enabled 0`.
+
+If you don't set any of these variables, VM remote attestation will be enabled
+by default.
 
 [rkp-hal-markers]: https://android.googlesource.com/platform/hardware/interfaces/+/main/security/rkp/README.md#hal
diff --git a/service_vm/test_apk/src/java/com/android/virt/vm_attestation/testapp/VmAttestationTests.java b/service_vm/test_apk/src/java/com/android/virt/vm_attestation/testapp/VmAttestationTests.java
index af99711..ff760b4 100644
--- a/service_vm/test_apk/src/java/com/android/virt/vm_attestation/testapp/VmAttestationTests.java
+++ b/service_vm/test_apk/src/java/com/android/virt/vm_attestation/testapp/VmAttestationTests.java
@@ -69,6 +69,9 @@
                 .that(isCuttlefish())
                 .isFalse();
         assumeFeatureEnabled(VirtualMachineManager.FEATURE_REMOTE_ATTESTATION);
+        assume().withMessage("Test needs Remote Attestation support")
+                .that(getVirtualMachineManager().isRemoteAttestationSupported())
+                .isTrue();
 
         VirtualMachineConfig.Builder builder =
                 newVmConfigBuilderWithPayloadBinary(VM_PAYLOAD_PATH)
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 8fe4167..41d09bc 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -353,6 +353,7 @@
             ))
             .with_log();
         }
+        remote_provisioning::check_remote_attestation_is_supported()?;
         info!("Received csr. Requestting attestation...");
         let (key_blob, certificate_chain) = if test_mode {
             check_use_custom_virtual_machine()?;
@@ -403,7 +404,8 @@
     }
 
     fn isRemoteAttestationSupported(&self) -> binder::Result<bool> {
-        is_remote_provisioning_hal_declared()
+        Ok(is_remote_provisioning_hal_declared()?
+            && remote_provisioning::is_remote_attestation_supported())
     }
 
     fn getAssignableDevices(&self) -> binder::Result<Vec<AssignableDevice>> {
diff --git a/virtualizationservice/src/remote_provisioning.rs b/virtualizationservice/src/remote_provisioning.rs
index c2c04df..490ff01 100644
--- a/virtualizationservice/src/remote_provisioning.rs
+++ b/virtualizationservice/src/remote_provisioning.rs
@@ -32,6 +32,7 @@
     Strong,
 };
 use hypervisor_props::is_protected_vm_supported;
+use rustutils::system_properties;
 use service_vm_comm::{RequestProcessingError, Response};
 
 /// Constructs a binder object that implements `IRemotelyProvisionedComponent`.
@@ -49,7 +50,7 @@
 #[allow(non_snake_case)]
 impl IRemotelyProvisionedComponent for AvfRemotelyProvisionedComponent {
     fn getHardwareInfo(&self) -> BinderResult<RpcHardwareInfo> {
-        check_protected_vm_is_supported()?;
+        check_remote_attestation_is_supported()?;
 
         Ok(RpcHardwareInfo {
             versionNumber: 3,
@@ -65,7 +66,7 @@
         testMode: bool,
         macedPublicKey: &mut MacedPublicKey,
     ) -> BinderResult<Vec<u8>> {
-        check_protected_vm_is_supported()?;
+        check_remote_attestation_is_supported()?;
 
         if testMode {
             return Err(Status::new_service_specific_error_str(
@@ -109,7 +110,7 @@
         keysToSign: &[MacedPublicKey],
         challenge: &[u8],
     ) -> BinderResult<Vec<u8>> {
-        check_protected_vm_is_supported()?;
+        check_remote_attestation_is_supported()?;
 
         const MAX_CHALLENGE_SIZE: usize = 64;
         if challenge.len() > MAX_CHALLENGE_SIZE {
@@ -133,16 +134,27 @@
     }
 }
 
-fn check_protected_vm_is_supported() -> BinderResult<()> {
-    if is_protected_vm_supported().unwrap_or(false) {
-        Ok(())
-    } else {
-        Err(Status::new_exception_str(
+pub(crate) fn check_remote_attestation_is_supported() -> BinderResult<()> {
+    if !is_protected_vm_supported().unwrap_or(false) {
+        return Err(Status::new_exception_str(
             ExceptionCode::UNSUPPORTED_OPERATION,
             Some("Protected VM support is missing for this operation"),
         ))
-        .with_log()
+        .with_log();
     }
+    if !is_remote_attestation_supported() {
+        return Err(Status::new_exception_str(
+            ExceptionCode::UNSUPPORTED_OPERATION,
+            Some("Remote attestation is disabled"),
+        ))
+        .with_log();
+    }
+    Ok(())
+}
+
+pub(crate) fn is_remote_attestation_supported() -> bool {
+    // Remote attestation is enabled by default.
+    system_properties::read_bool("avf.remote_attestation.enabled", true).unwrap_or(true)
 }
 
 pub(crate) fn to_service_specific_error(response: Response) -> Status {