[attestation] Add API to check AVF RKP Hal presence in VM Attestation

This cl adds a new API in VirtualMachineManager to check whether
remote attestation is supported on a device.

Since Remote Attestation is a strongly recommended feature for Android
V, the new API is needed to determine whether we should proceed with
the Remote Attestation CTS tests.

Bug: 329652894
Test: atest MicrodroidTests
Change-Id: I0941914e7a5f1a483705d3faf7091b47ada41b1f
diff --git a/service_vm/test_apk/Android.bp b/service_vm/test_apk/Android.bp
index cd992db..e69b348 100644
--- a/service_vm/test_apk/Android.bp
+++ b/service_vm/test_apk/Android.bp
@@ -45,7 +45,10 @@
 rust_ffi {
     name: "libvm_attestation_test_payload",
     defaults: ["vm_attestation_test_payload_defaults"],
-    visibility: [":__subpackages__"],
+    visibility: [
+        ":__subpackages__",
+        "//packages/modules/Virtualization/tests/testapk",
+    ],
 }
 
 android_test {
diff --git a/service_vm/test_apk/aidl/com/android/virt/vm_attestation/testservice/IAttestationService.aidl b/service_vm/test_apk/aidl/com/android/virt/vm_attestation/testservice/IAttestationService.aidl
index 34c8549..18df572 100644
--- a/service_vm/test_apk/aidl/com/android/virt/vm_attestation/testservice/IAttestationService.aidl
+++ b/service_vm/test_apk/aidl/com/android/virt/vm_attestation/testservice/IAttestationService.aidl
@@ -21,6 +21,27 @@
     const int PORT = 5679;
 
     /**
+     * The status of the attestation.
+     *
+     * The status here maps to the status defined in
+     * vm_payload/include/vm_payload.h
+     */
+    @Backing(type="int")
+    enum AttestationStatus {
+        /** The remote attestation completes successfully. */
+        ATTESTATION_OK = 0,
+
+        /** The challenge size is not between 0 and 64. */
+        ATTESTATION_ERROR_INVALID_CHALLENGE = 1,
+
+        /** Failed to attest the VM. Please retry at a later time. */
+        ATTESTATION_ERROR_ATTESTATION_FAILED = 2,
+
+        /** Remote attestation is not supported in the current environment. */
+        ATTESTATION_ERROR_UNSUPPORTED = 3,
+    }
+
+    /**
      * The result of signing a message with the attested key.
      */
     parcelable SigningResult {
@@ -29,6 +50,9 @@
 
         /** The DER-encoded attestation X509 certificate chain. */
         byte[] certificateChain;
+
+        /** The status of the attestation. */
+        AttestationStatus status;
     }
 
     /**
diff --git a/service_vm/test_apk/src/native/main.rs b/service_vm/test_apk/src/native/main.rs
index a04fb1f..ff21bd8 100644
--- a/service_vm/test_apk/src/native/main.rs
+++ b/service_vm/test_apk/src/native/main.rs
@@ -18,7 +18,8 @@
 use avflog::LogResult;
 use com_android_virt_vm_attestation_testservice::{
     aidl::com::android::virt::vm_attestation::testservice::IAttestationService::{
-        BnAttestationService, IAttestationService, SigningResult::SigningResult, PORT,
+        AttestationStatus::AttestationStatus, BnAttestationService, IAttestationService,
+        SigningResult::SigningResult, PORT,
     },
     binder::{self, unstable_api::AsNative, BinderFeatures, Interface, IntoBinderResult, Strong},
 };
@@ -103,14 +104,18 @@
         challenge: &[u8],
         message: &[u8],
     ) -> binder::Result<SigningResult> {
-        let res = AttestationResult::request_attestation(challenge)
-            .map_err(|e| anyhow!("Unexpected status: {:?}", status_to_cstr(e)))
-            .with_log()
-            .or_service_specific_exception(-1)?;
+        let res = match AttestationResult::request_attestation(challenge) {
+            Ok(res) => res,
+            Err(status) => {
+                let status = to_attestation_status(status);
+                return Ok(SigningResult { certificateChain: vec![], signature: vec![], status });
+            }
+        };
         let certificate_chain =
             res.certificate_chain().with_log().or_service_specific_exception(-1)?;
+        let status = AttestationStatus::ATTESTATION_OK;
         let signature = res.sign(message).with_log().or_service_specific_exception(-1)?;
-        Ok(SigningResult { certificateChain: certificate_chain, signature })
+        Ok(SigningResult { certificateChain: certificate_chain, signature, status })
     }
 
     fn validateAttestationResult(&self) -> binder::Result<()> {
@@ -119,6 +124,21 @@
     }
 }
 
+fn to_attestation_status(status: AVmAttestationStatus) -> AttestationStatus {
+    match status {
+        AVmAttestationStatus::ATTESTATION_OK => AttestationStatus::ATTESTATION_OK,
+        AVmAttestationStatus::ATTESTATION_ERROR_INVALID_CHALLENGE => {
+            AttestationStatus::ATTESTATION_ERROR_INVALID_CHALLENGE
+        }
+        AVmAttestationStatus::ATTESTATION_ERROR_ATTESTATION_FAILED => {
+            AttestationStatus::ATTESTATION_ERROR_ATTESTATION_FAILED
+        }
+        AVmAttestationStatus::ATTESTATION_ERROR_UNSUPPORTED => {
+            AttestationStatus::ATTESTATION_ERROR_UNSUPPORTED
+        }
+    }
+}
+
 #[derive(Debug)]
 struct AttestationResult(NonNull<AVmAttestationResult>);