Merge "[Test] Add VSR test to validate pVM's DICE chain" into main
diff --git a/tests/testapk/Android.bp b/tests/testapk/Android.bp
index e32ff88..8314f43 100644
--- a/tests/testapk/Android.bp
+++ b/tests/testapk/Android.bp
@@ -57,6 +57,9 @@
"MicrodroidCrashNativeLib",
"libmicrodroid_testlib_rust",
"libvm_attestation_test_payload",
+
+ // Non-VM payload libraries
+ "libhwtrust_jni",
],
min_sdk_version: "33",
}
@@ -186,3 +189,20 @@
"libvm_payload_rs",
],
}
+
+rust_ffi_shared {
+ name: "libhwtrust_jni",
+ crate_name: "hwtrust_jni",
+ srcs: ["src/native/hwtrust_jni.rs"],
+ prefer_rlib: true,
+ rustlibs: [
+ "libandroid_logger",
+ "libanyhow",
+ "liblog_rust",
+ "libhwtrust",
+ "libjni",
+ ],
+ shared_libs: [
+ "libcrypto",
+ ],
+}
diff --git a/tests/testapk/src/java/com/android/microdroid/test/HwTrustJni.java b/tests/testapk/src/java/com/android/microdroid/test/HwTrustJni.java
new file mode 100644
index 0000000..3b237aa
--- /dev/null
+++ b/tests/testapk/src/java/com/android/microdroid/test/HwTrustJni.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.microdroid.test;
+
+class HwTrustJni {
+ static {
+ System.loadLibrary("hwtrust_jni");
+ }
+
+ /**
+ * Validates a DICE chain.
+ *
+ * @param diceChain The dice chain to validate.
+ * @return true if the dice chain is valid, false otherwise.
+ */
+ public static native boolean validateDiceChain(byte[] diceChain);
+}
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index fd67659..658b1bb 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -1308,6 +1308,36 @@
}
@Test
+ @VsrTest(requirements = {"VSR-7.1-001.005"})
+ public void protectedVmHasValidDiceChain() throws Exception {
+ // This test validates two things regarding the pVM DICE chain:
+ // 1. The DICE chain is well-formed that all the entries conform to the DICE spec.
+ // 2. Each entry in the DICE chain is signed by the previous entry's subject public key.
+ assumeSupportedDevice();
+ assumeProtectedVM();
+ assumeVsrCompliant();
+ assumeTrue("Vendor API must be at least 202404", getVendorApiLevel() >= 202404);
+
+ grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
+ VirtualMachineConfig config =
+ newVmConfigBuilderWithPayloadConfig("assets/vm_config.json")
+ .setDebugLevel(DEBUG_LEVEL_FULL)
+ .build();
+ VirtualMachine vm = forceCreateNewVirtualMachine("bcc_vm_for_vsr", config);
+ TestResults testResults =
+ runVmTestService(
+ TAG,
+ vm,
+ (service, results) -> {
+ results.mBcc = service.getBcc();
+ });
+ testResults.assertNoException();
+ byte[] bccBytes = testResults.mBcc;
+ assertThat(bccBytes).isNotNull();
+ assertThat(HwTrustJni.validateDiceChain(bccBytes)).isTrue();
+ }
+
+ @Test
@CddTest(requirements = {
"9.17/C-1-1",
"9.17/C-1-2"
diff --git a/tests/testapk/src/native/hwtrust_jni.rs b/tests/testapk/src/native/hwtrust_jni.rs
new file mode 100644
index 0000000..3b00364
--- /dev/null
+++ b/tests/testapk/src/native/hwtrust_jni.rs
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2024, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! JNI bindings to call into `hwtrust` from Java.
+
+use anyhow::Result;
+use hwtrust::{dice, session::Session};
+use jni::objects::{JByteArray, JClass};
+use jni::sys::jboolean;
+use jni::JNIEnv;
+use log::{debug, error, info};
+
+/// Validates the given DICE chain.
+#[no_mangle]
+pub extern "system" fn Java_com_android_microdroid_test_HwTrustJni_validateDiceChain(
+ env: JNIEnv,
+ _class: JClass,
+ dice_chain: JByteArray,
+) -> jboolean {
+ android_logger::init_once(
+ android_logger::Config::default()
+ .with_tag("hwtrust_jni")
+ .with_max_level(log::LevelFilter::Debug),
+ );
+ debug!("Starting the DICE chain validation ...");
+ match validate_dice_chain(env, dice_chain) {
+ Ok(_) => {
+ info!("DICE chain validated successfully");
+ true
+ }
+ Err(e) => {
+ error!("Failed to validate DICE chain: {:?}", e);
+ false
+ }
+ }
+ .into()
+}
+
+fn validate_dice_chain(env: JNIEnv, jdice_chain: JByteArray) -> Result<()> {
+ let dice_chain = env.convert_byte_array(jdice_chain)?;
+ let session = Session::default();
+ let _chain = dice::Chain::from_cbor(&session, &dice_chain)?;
+ Ok(())
+}