Merge "Import translations. DO NOT MERGE ANYWHERE" into main
diff --git a/build/avf_flags.aconfig b/build/avf_flags.aconfig
index 9815c60..921c374 100644
--- a/build/avf_flags.aconfig
+++ b/build/avf_flags.aconfig
@@ -9,3 +9,11 @@
bug: "383347947"
is_fixed_read_only: true
}
+
+flag {
+ name: "terminal_gui_support"
+ is_exported: true
+ namespace: "virtualization"
+ description: "Flag for GUI support in terminal"
+ bug: "386296118"
+}
\ No newline at end of file
diff --git a/libs/dice/open_dice/Android.bp b/libs/dice/open_dice/Android.bp
index f799fb1..1870ab6 100644
--- a/libs/dice/open_dice/Android.bp
+++ b/libs/dice/open_dice/Android.bp
@@ -128,7 +128,7 @@
rust_defaults {
name: "libopen_dice_cbor_bindgen.rust_defaults",
- wrapper_src: "bindgen/dice.h",
+ wrapper_src: "bindgen/dice/dice.h",
crate_name: "open_dice_cbor_bindgen",
source_stem: "bindings",
bindgen_flags: [
@@ -184,7 +184,7 @@
rust_defaults {
name: "libopen_dice_android_bindgen.rust_defaults",
- wrapper_src: "bindgen/android.h",
+ wrapper_src: "bindgen/android/android.h",
crate_name: "open_dice_android_bindgen",
source_stem: "bindings",
bindgen_flags: [
@@ -264,3 +264,9 @@
clippy_lints: "none",
lints: "none",
}
+
+dirgroup {
+ name: "trusty_dirgroup_packages_modules_virtualization_libs_open_dice",
+ visibility: ["//trusty/vendor/google/aosp/scripts"],
+ dirs: ["."],
+}
diff --git a/libs/dice/open_dice/bindgen/android.h b/libs/dice/open_dice/bindgen/android/android.h
similarity index 100%
rename from libs/dice/open_dice/bindgen/android.h
rename to libs/dice/open_dice/bindgen/android/android.h
diff --git a/libs/dice/open_dice/bindgen/android/lib.rs b/libs/dice/open_dice/bindgen/android/lib.rs
new file mode 100644
index 0000000..7c300de
--- /dev/null
+++ b/libs/dice/open_dice/bindgen/android/lib.rs
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+// Get the bindgen definitions.
+// The trusty build system doesn't have support for packaging generated
+// bindgen sources as a crate automatically. In the Android tree, this
+// entire file is not used.
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(unused)]
+
+include!(env!("BINDGEN_INC_FILE"));
diff --git a/libs/dice/open_dice/bindgen/android/rules.mk b/libs/dice/open_dice/bindgen/android/rules.mk
new file mode 100644
index 0000000..200ec52
--- /dev/null
+++ b/libs/dice/open_dice/bindgen/android/rules.mk
@@ -0,0 +1,54 @@
+# 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS := $(LOCAL_DIR)/lib.rs
+
+MODULE_CRATE_NAME := open_dice_android_bindgen
+
+MODULE_LIBRARY_DEPS += \
+ external/open-dice \
+ $(LOCAL_DIR)/../dice \
+ trusty/user/base/lib/trusty-sys \
+
+MODULE_BINDGEN_ALLOW_FUNCTIONS := \
+ DiceAndroidFormatConfigDescriptor \
+ DiceAndroidMainFlow \
+ DiceAndroidHandoverParse \
+
+MODULE_BINDGEN_ALLOW_VARS := \
+ DICE_ANDROID_CONFIG_.* \
+
+# Prevent DiceInputValues from being generated a second time and
+# import it instead from open_dice_cbor_bindgen.
+MODULE_BINDGEN_FLAGS += \
+ --blocklist-type="DiceInputValues_" \
+ --blocklist-type="DiceInputValues" \
+ --raw-line \
+ "pub use open_dice_cbor_bindgen::DiceInputValues;" \
+
+# Prevent DiceResult from being generated a second time and
+# import it instead from open_dice_cbor_bindgen.
+MODULE_BINDGEN_FLAGS += \
+ --blocklist-type="DiceResult" \
+ --raw-line \
+ "pub use open_dice_cbor_bindgen::DiceResult;" \
+
+MODULE_BINDGEN_SRC_HEADER := $(LOCAL_DIR)/android.h
+
+include make/library.mk
diff --git a/libs/dice/open_dice/bindgen/dice.h b/libs/dice/open_dice/bindgen/dice/dice.h
similarity index 100%
rename from libs/dice/open_dice/bindgen/dice.h
rename to libs/dice/open_dice/bindgen/dice/dice.h
diff --git a/libs/dice/open_dice/bindgen/dice/lib.rs b/libs/dice/open_dice/bindgen/dice/lib.rs
new file mode 100644
index 0000000..ed2fd23
--- /dev/null
+++ b/libs/dice/open_dice/bindgen/dice/lib.rs
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+// Get the bindgen definitions.
+// The trusty build system doesn't have support for packaging generated
+// bindgen sources as a crate automatically. In the Android tree, this
+// entire file is not used.
+
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(unused)]
+
+include!(env!("BINDGEN_INC_FILE"));
diff --git a/libs/dice/open_dice/bindgen/dice/rules.mk b/libs/dice/open_dice/bindgen/dice/rules.mk
new file mode 100644
index 0000000..0ea5c7c
--- /dev/null
+++ b/libs/dice/open_dice/bindgen/dice/rules.mk
@@ -0,0 +1,56 @@
+# 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS := $(LOCAL_DIR)/lib.rs
+
+MODULE_CRATE_NAME := open_dice_cbor_bindgen
+
+MODULE_LIBRARY_DEPS += \
+ external/open-dice \
+ trusty/user/base/lib/trusty-sys \
+
+MODULE_BINDGEN_FLAGS += \
+ --rustified-enum DiceConfigType \
+ --rustified-enum DiceMode \
+ --rustified-enum DiceResult \
+ --rustified-enum DicePrincipal \
+
+MODULE_BINDGEN_ALLOW_FUNCTIONS := \
+ DiceDeriveCdiPrivateKeySeed \
+ DiceDeriveCdiCertificateId \
+ DiceMainFlow \
+ DiceHash \
+ DiceKdf \
+ DiceKeypairFromSeed \
+ DiceSign \
+ DiceVerify \
+ DiceGenerateCertificate \
+
+MODULE_BINDGEN_ALLOW_VARS := \
+ DICE_CDI_SIZE \
+ DICE_HASH_SIZE \
+ DICE_HIDDEN_SIZE \
+ DICE_INLINE_CONFIG_SIZE \
+ DICE_PRIVATE_KEY_SEED_SIZE \
+ DICE_ID_SIZE \
+ DICE_PRIVATE_KEY_BUFFER_SIZE \
+
+MODULE_BINDGEN_SRC_HEADER := $(LOCAL_DIR)/dice.h
+
+include make/library.mk
diff --git a/libs/dice/open_dice/rules.mk b/libs/dice/open_dice/rules.mk
new file mode 100644
index 0000000..d84468d
--- /dev/null
+++ b/libs/dice/open_dice/rules.mk
@@ -0,0 +1,30 @@
+# 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS := $(LOCAL_DIR)/src/lib.rs
+
+MODULE_CRATE_NAME := diced_open_dice
+
+MODULE_LIBRARY_DEPS += \
+ $(call FIND_CRATE,coset) \
+ $(call FIND_CRATE,zeroize) \
+ $(LOCAL_DIR)/bindgen/android \
+ $(LOCAL_DIR)/bindgen/dice \
+
+include make/library.mk
diff --git a/libs/dice/open_dice/src/bcc.rs b/libs/dice/open_dice/src/bcc.rs
index fabd7c7..a3ddd76 100644
--- a/libs/dice/open_dice/src/bcc.rs
+++ b/libs/dice/open_dice/src/bcc.rs
@@ -41,7 +41,7 @@
}
/// Formats a configuration descriptor following the Android Profile for DICE specification.
-/// See https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/android.md.
+/// See <https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/android.md>.
pub fn bcc_format_config_descriptor(values: &DiceConfigValues, buffer: &mut [u8]) -> Result<usize> {
let mut configs = 0;
diff --git a/libs/dice/open_dice/tests/api_test.rs b/libs/dice/open_dice/tests/api_test.rs
index a47265b..d3a91ff 100644
--- a/libs/dice/open_dice/tests/api_test.rs
+++ b/libs/dice/open_dice/tests/api_test.rs
@@ -14,94 +14,108 @@
* limitations under the License.
*/
-use diced_open_dice::{
- derive_cdi_certificate_id, derive_cdi_private_key_seed, hash, kdf, keypair_from_seed, sign,
- verify, CDI_SIZE, HASH_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
-};
+#[cfg(test)]
+mod tests {
+ use diced_open_dice::{
+ derive_cdi_certificate_id, derive_cdi_private_key_seed, hash, kdf, keypair_from_seed, sign,
+ verify, CDI_SIZE, HASH_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
+ };
-#[test]
-fn hash_succeeds() {
- const EXPECTED_HASH: [u8; HASH_SIZE] = [
- 0x30, 0x9e, 0xcc, 0x48, 0x9c, 0x12, 0xd6, 0xeb, 0x4c, 0xc4, 0x0f, 0x50, 0xc9, 0x02, 0xf2,
- 0xb4, 0xd0, 0xed, 0x77, 0xee, 0x51, 0x1a, 0x7c, 0x7a, 0x9b, 0xcd, 0x3c, 0xa8, 0x6d, 0x4c,
- 0xd8, 0x6f, 0x98, 0x9d, 0xd3, 0x5b, 0xc5, 0xff, 0x49, 0x96, 0x70, 0xda, 0x34, 0x25, 0x5b,
- 0x45, 0xb0, 0xcf, 0xd8, 0x30, 0xe8, 0x1f, 0x60, 0x5d, 0xcf, 0x7d, 0xc5, 0x54, 0x2e, 0x93,
- 0xae, 0x9c, 0xd7, 0x6f,
+ // This test initialization is only required for the trusty test harness.
+ #[cfg(feature = "trusty")]
+ test::init!();
+
+ #[test]
+ fn hash_succeeds() {
+ const EXPECTED_HASH: [u8; HASH_SIZE] = [
+ 0x30, 0x9e, 0xcc, 0x48, 0x9c, 0x12, 0xd6, 0xeb, 0x4c, 0xc4, 0x0f, 0x50, 0xc9, 0x02,
+ 0xf2, 0xb4, 0xd0, 0xed, 0x77, 0xee, 0x51, 0x1a, 0x7c, 0x7a, 0x9b, 0xcd, 0x3c, 0xa8,
+ 0x6d, 0x4c, 0xd8, 0x6f, 0x98, 0x9d, 0xd3, 0x5b, 0xc5, 0xff, 0x49, 0x96, 0x70, 0xda,
+ 0x34, 0x25, 0x5b, 0x45, 0xb0, 0xcf, 0xd8, 0x30, 0xe8, 0x1f, 0x60, 0x5d, 0xcf, 0x7d,
+ 0xc5, 0x54, 0x2e, 0x93, 0xae, 0x9c, 0xd7, 0x6f,
+ ];
+ assert_eq!(EXPECTED_HASH, hash(b"hello world").expect("hash failed"));
+ }
+
+ #[test]
+ fn kdf_succeeds() {
+ let mut derived_key = [0u8; PRIVATE_KEY_SEED_SIZE];
+ kdf(b"myInitialKeyMaterial", b"mySalt", b"myInfo", &mut derived_key).unwrap();
+ const EXPECTED_DERIVED_KEY: [u8; PRIVATE_KEY_SEED_SIZE] = [
+ 0x91, 0x9b, 0x8d, 0x29, 0xc4, 0x1b, 0x93, 0xd7, 0xeb, 0x09, 0xfa, 0xd7, 0xc9, 0x87,
+ 0xb0, 0xd1, 0xcc, 0x26, 0xef, 0x07, 0x83, 0x42, 0xcf, 0xa3, 0x45, 0x0a, 0x57, 0xe9,
+ 0x19, 0x86, 0xef, 0x48,
+ ];
+ assert_eq!(EXPECTED_DERIVED_KEY, derived_key);
+ }
+
+ #[test]
+ fn derive_cdi_certificate_id_succeeds() {
+ const EXPECTED_ID: [u8; ID_SIZE] = [
+ 0x7a, 0x36, 0x45, 0x2c, 0x02, 0xf6, 0x2b, 0xec, 0xf9, 0x80, 0x06, 0x75, 0x87, 0xa5,
+ 0xc1, 0x44, 0x0c, 0xd3, 0xc0, 0x6d,
+ ];
+ assert_eq!(EXPECTED_ID, derive_cdi_certificate_id(b"MyPubKey").unwrap());
+ }
+
+ const EXPECTED_SEED: &[u8] = &[
+ 0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
+ 0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
+ 0x3a, 0x08, 0x84, 0x8a, 0x98, 0x85, 0x6d, 0xf5, 0x69, 0x21, 0x03, 0xcd, 0x09, 0xc3, 0x28,
+ 0xd6, 0x06, 0xa7, 0x57, 0xbd, 0x48, 0x4b, 0x0f, 0x79, 0x0f, 0xf8, 0x2f, 0xf0, 0x0a, 0x41,
+ 0x94, 0xd8, 0x8c, 0xa8,
];
- assert_eq!(EXPECTED_HASH, hash(b"hello world").expect("hash failed"));
-}
-#[test]
-fn kdf_succeeds() {
- let mut derived_key = [0u8; PRIVATE_KEY_SEED_SIZE];
- kdf(b"myInitialKeyMaterial", b"mySalt", b"myInfo", &mut derived_key).unwrap();
- const EXPECTED_DERIVED_KEY: [u8; PRIVATE_KEY_SEED_SIZE] = [
- 0x91, 0x9b, 0x8d, 0x29, 0xc4, 0x1b, 0x93, 0xd7, 0xeb, 0x09, 0xfa, 0xd7, 0xc9, 0x87, 0xb0,
- 0xd1, 0xcc, 0x26, 0xef, 0x07, 0x83, 0x42, 0xcf, 0xa3, 0x45, 0x0a, 0x57, 0xe9, 0x19, 0x86,
- 0xef, 0x48,
+ const EXPECTED_CDI_ATTEST: &[u8] = &[
+ 0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
+ 0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
+ 0x3a, 0x08,
];
- assert_eq!(EXPECTED_DERIVED_KEY, derived_key);
-}
-#[test]
-fn derive_cdi_certificate_id_succeeds() {
- const EXPECTED_ID: [u8; ID_SIZE] = [
- 0x7a, 0x36, 0x45, 0x2c, 0x02, 0xf6, 0x2b, 0xec, 0xf9, 0x80, 0x06, 0x75, 0x87, 0xa5, 0xc1,
- 0x44, 0x0c, 0xd3, 0xc0, 0x6d,
+ const EXPECTED_CDI_PRIVATE_KEY_SEED: &[u8] = &[
+ 0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
+ 0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
+ 0x02, 0x6e,
];
- assert_eq!(EXPECTED_ID, derive_cdi_certificate_id(b"MyPubKey").unwrap());
-}
-const EXPECTED_SEED: &[u8] = &[
- 0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba, 0xaa,
- 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5, 0x3a, 0x08,
- 0x84, 0x8a, 0x98, 0x85, 0x6d, 0xf5, 0x69, 0x21, 0x03, 0xcd, 0x09, 0xc3, 0x28, 0xd6, 0x06, 0xa7,
- 0x57, 0xbd, 0x48, 0x4b, 0x0f, 0x79, 0x0f, 0xf8, 0x2f, 0xf0, 0x0a, 0x41, 0x94, 0xd8, 0x8c, 0xa8,
-];
+ const EXPECTED_PUB_KEY: &[u8] = &[
+ 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23,
+ 0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61,
+ 0x06, 0x37,
+ ];
+ const EXPECTED_PRIV_KEY: &[u8] = &[
+ 0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
+ 0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
+ 0x02, 0x6e, 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b,
+ 0xfc, 0x23, 0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52,
+ 0xf1, 0x61, 0x06, 0x37,
+ ];
-const EXPECTED_CDI_ATTEST: &[u8] = &[
- 0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba, 0xaa,
- 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5, 0x3a, 0x08,
-];
+ const EXPECTED_SIGNATURE: &[u8] = &[
+ 0x44, 0xae, 0xcc, 0xe2, 0xb9, 0x96, 0x18, 0x39, 0x0e, 0x61, 0x0f, 0x53, 0x07, 0xbf, 0xf2,
+ 0x32, 0x3d, 0x44, 0xd4, 0xf2, 0x07, 0x23, 0x30, 0x85, 0x32, 0x18, 0xd2, 0x69, 0xb8, 0x29,
+ 0x3c, 0x26, 0xe6, 0x0d, 0x9c, 0xa5, 0xc2, 0x73, 0xcd, 0x8c, 0xb8, 0x3c, 0x3e, 0x5b, 0xfd,
+ 0x62, 0x8d, 0xf6, 0xc4, 0x27, 0xa6, 0xe9, 0x11, 0x06, 0x5a, 0xb2, 0x2b, 0x64, 0xf7, 0xfc,
+ 0xbb, 0xab, 0x4a, 0x0e,
+ ];
-const EXPECTED_CDI_PRIVATE_KEY_SEED: &[u8] = &[
- 0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe, 0x0d,
- 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72, 0x02, 0x6e,
-];
-
-const EXPECTED_PUB_KEY: &[u8] = &[
- 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23, 0xc9,
- 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61, 0x06, 0x37,
-];
-const EXPECTED_PRIV_KEY: &[u8] = &[
- 0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe, 0x0d,
- 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72, 0x02, 0x6e,
- 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23, 0xc9,
- 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61, 0x06, 0x37,
-];
-
-const EXPECTED_SIGNATURE: &[u8] = &[
- 0x44, 0xae, 0xcc, 0xe2, 0xb9, 0x96, 0x18, 0x39, 0x0e, 0x61, 0x0f, 0x53, 0x07, 0xbf, 0xf2, 0x32,
- 0x3d, 0x44, 0xd4, 0xf2, 0x07, 0x23, 0x30, 0x85, 0x32, 0x18, 0xd2, 0x69, 0xb8, 0x29, 0x3c, 0x26,
- 0xe6, 0x0d, 0x9c, 0xa5, 0xc2, 0x73, 0xcd, 0x8c, 0xb8, 0x3c, 0x3e, 0x5b, 0xfd, 0x62, 0x8d, 0xf6,
- 0xc4, 0x27, 0xa6, 0xe9, 0x11, 0x06, 0x5a, 0xb2, 0x2b, 0x64, 0xf7, 0xfc, 0xbb, 0xab, 0x4a, 0x0e,
-];
-
-#[test]
-fn hash_derive_sign_verify() {
- let seed = hash(b"MySeedString").unwrap();
- assert_eq!(seed, EXPECTED_SEED);
- let cdi_attest = &seed[..CDI_SIZE];
- assert_eq!(cdi_attest, EXPECTED_CDI_ATTEST);
- let cdi_private_key_seed = derive_cdi_private_key_seed(cdi_attest.try_into().unwrap()).unwrap();
- assert_eq!(cdi_private_key_seed.as_array(), EXPECTED_CDI_PRIVATE_KEY_SEED);
- let (pub_key, priv_key) = keypair_from_seed(cdi_private_key_seed.as_array()).unwrap();
- assert_eq!(&pub_key, EXPECTED_PUB_KEY);
- assert_eq!(priv_key.as_array(), EXPECTED_PRIV_KEY);
- let mut signature = sign(b"MyMessage", priv_key.as_array()).unwrap();
- assert_eq!(&signature, EXPECTED_SIGNATURE);
- assert!(verify(b"MyMessage", &signature, &pub_key).is_ok());
- assert!(verify(b"MyMessage_fail", &signature, &pub_key).is_err());
- signature[0] += 1;
- assert!(verify(b"MyMessage", &signature, &pub_key).is_err());
+ #[test]
+ fn hash_derive_sign_verify() {
+ let seed = hash(b"MySeedString").unwrap();
+ assert_eq!(seed, EXPECTED_SEED);
+ let cdi_attest = &seed[..CDI_SIZE];
+ assert_eq!(cdi_attest, EXPECTED_CDI_ATTEST);
+ let cdi_private_key_seed =
+ derive_cdi_private_key_seed(cdi_attest.try_into().unwrap()).unwrap();
+ assert_eq!(cdi_private_key_seed.as_array(), EXPECTED_CDI_PRIVATE_KEY_SEED);
+ let (pub_key, priv_key) = keypair_from_seed(cdi_private_key_seed.as_array()).unwrap();
+ assert_eq!(&pub_key, EXPECTED_PUB_KEY);
+ assert_eq!(priv_key.as_array(), EXPECTED_PRIV_KEY);
+ let mut signature = sign(b"MyMessage", priv_key.as_array()).unwrap();
+ assert_eq!(&signature, EXPECTED_SIGNATURE);
+ assert!(verify(b"MyMessage", &signature, &pub_key).is_ok());
+ assert!(verify(b"MyMessage_fail", &signature, &pub_key).is_err());
+ signature[0] += 1;
+ assert!(verify(b"MyMessage", &signature, &pub_key).is_err());
+ }
}
diff --git a/libs/dice/open_dice/tests/manifest.json b/libs/dice/open_dice/tests/manifest.json
new file mode 100644
index 0000000..28db874
--- /dev/null
+++ b/libs/dice/open_dice/tests/manifest.json
@@ -0,0 +1,9 @@
+{
+ "app_name": "diced_open_dice_tests",
+ "uuid": "0b772481-7c24-4b9b-9d7c-441ac10d969b",
+ "min_heap": 32768,
+ "min_stack": 32768,
+ "mgmt_flags": {
+ "non_critical_app": true
+ }
+}
diff --git a/libs/dice/open_dice/tests/rules.mk b/libs/dice/open_dice/tests/rules.mk
new file mode 100644
index 0000000..a9d332c
--- /dev/null
+++ b/libs/dice/open_dice/tests/rules.mk
@@ -0,0 +1,35 @@
+# 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.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS := $(LOCAL_DIR)/api_test.rs
+
+MODULE_CRATE_NAME := diced_open_dice_tests
+
+MODULE_LIBRARY_DEPS += \
+ packages/modules/Virtualization/libs/dice/open_dice \
+
+MODULE_RUST_TESTS := true
+
+# Enables trusty test initialization
+MODULE_RUSTFLAGS += \
+ --cfg 'feature="trusty"' \
+
+MANIFEST := $(LOCAL_DIR)/manifest.json
+
+include make/library.mk
diff --git a/libs/libavf/Android.bp b/libs/libavf/Android.bp
index b583e21..c958796 100644
--- a/libs/libavf/Android.bp
+++ b/libs/libavf/Android.bp
@@ -10,7 +10,10 @@
source_stem: "bindings",
bindgen_flags: ["--default-enum-style rust"],
apex_available: ["com.android.virt"],
- visibility: ["//packages/modules/Virtualization/tests/vts"],
+ visibility: [
+ "//packages/modules/Virtualization/tests/vts",
+ "//packages/modules/Virtualization/tests/old_images_avf_test",
+ ],
}
rust_defaults {
diff --git a/tests/old_images_avf_test/Android.bp b/tests/old_images_avf_test/Android.bp
new file mode 100644
index 0000000..b3d5baf
--- /dev/null
+++ b/tests/old_images_avf_test/Android.bp
@@ -0,0 +1,57 @@
+prebuilt_etc {
+ name: "backcompat_rialto_kernel",
+ filename: "rialto.bin",
+ src: ":empty_file",
+ target: {
+ android_arm64: {
+ src: ":rialto_signed",
+ },
+ },
+ installable: false,
+ visibility: ["//visibility:private"],
+}
+
+prebuilt_etc {
+ name: "android16_rialto_kernel",
+ filename: "android16_rialto.bin",
+ src: ":empty_file",
+ target: {
+ android_arm64: {
+ src: "images/android16_rialto.bin",
+ },
+ },
+ installable: false,
+ visibility: ["//visibility:private"],
+}
+
+rust_test {
+ name: "old_images_avf_test",
+ crate_name: "old_images_avf_test",
+ srcs: ["src/main.rs"],
+ rustlibs: [
+ "libanyhow",
+ "libavf_bindgen",
+ "libciborium",
+ "liblog_rust",
+ "libhypervisor_props",
+ "libscopeguard",
+ "libservice_vm_comm",
+ "libvsock",
+ ],
+ shared_libs: ["libavf"],
+ test_suites: [
+ "general-tests",
+ ],
+ data: [
+ ":android16_rialto_kernel",
+ ":backcompat_rialto_kernel",
+ ],
+ enabled: false,
+ target: {
+ android_arm64: {
+ enabled: true,
+ },
+ },
+ test_config: "AndroidTest.xml",
+ compile_multilib: "first",
+}
diff --git a/tests/old_images_avf_test/AndroidTest.xml b/tests/old_images_avf_test/AndroidTest.xml
new file mode 100644
index 0000000..089a424
--- /dev/null
+++ b/tests/old_images_avf_test/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 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.
+-->
+<configuration description="Runs old images on current AVF VM.">
+ <option name="test-suite-tag" value="general-tests" />
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="old_images_avf_test->/data/local/tmp/old_images_avf_test" />
+ <option name="push" value="rialto.bin->/data/local/tmp/rialto.bin" />
+ <option name="push" value="android16_rialto.bin->/data/local/tmp/android16_rialto.bin" />
+ </target_preparer>
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.ArchModuleController">
+ <option name="arch" value="arm64" />
+ </object>
+ <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
+ <option name="test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="old_images_avf_test" />
+ <!-- rialto uses a fixed port number for the host, can't run two tests at the same time -->
+ <option name="native-test-flag" value="--test-threads=1" />
+ </test>
+</configuration>
diff --git a/tests/old_images_avf_test/images/android16_rialto.bin b/tests/old_images_avf_test/images/android16_rialto.bin
new file mode 100644
index 0000000..ff4c38e
--- /dev/null
+++ b/tests/old_images_avf_test/images/android16_rialto.bin
Binary files differ
diff --git a/tests/old_images_avf_test/src/main.rs b/tests/old_images_avf_test/src/main.rs
new file mode 100644
index 0000000..018a80e
--- /dev/null
+++ b/tests/old_images_avf_test/src/main.rs
@@ -0,0 +1,229 @@
+// Copyright 2025 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.
+
+//! Tests running a VM with older images
+
+use anyhow::{bail, ensure, Context, Result};
+use log::info;
+use std::ffi::CStr;
+use std::fs::File;
+use std::io::{self, BufWriter, Write};
+use std::os::fd::IntoRawFd;
+use std::time::{Duration, Instant};
+use vsock::{VsockListener, VsockStream, VMADDR_CID_HOST};
+
+use avf_bindgen::*;
+use service_vm_comm::{Request, Response, ServiceVmRequest, VmType};
+
+const VM_MEMORY_MB: i32 = 16;
+const WRITE_BUFFER_CAPACITY: usize = 512;
+
+const LISTEN_TIMEOUT: Duration = Duration::from_secs(10);
+const READ_TIMEOUT: Duration = Duration::from_secs(10);
+const WRITE_TIMEOUT: Duration = Duration::from_secs(10);
+const STOP_TIMEOUT: timespec = timespec { tv_sec: 10, tv_nsec: 0 };
+
+/// Processes the request in the service VM.
+fn process_request(vsock_stream: &mut VsockStream, request: Request) -> Result<Response> {
+ write_request(vsock_stream, &ServiceVmRequest::Process(request))?;
+ read_response(vsock_stream)
+}
+
+/// Sends the request to the service VM.
+fn write_request(vsock_stream: &mut VsockStream, request: &ServiceVmRequest) -> Result<()> {
+ let mut buffer = BufWriter::with_capacity(WRITE_BUFFER_CAPACITY, vsock_stream);
+ ciborium::into_writer(request, &mut buffer)?;
+ buffer.flush().context("Failed to flush the buffer")?;
+ Ok(())
+}
+
+/// Reads the response from the service VM.
+fn read_response(vsock_stream: &mut VsockStream) -> Result<Response> {
+ let response: Response = ciborium::from_reader(vsock_stream)
+ .context("Failed to read the response from the service VM")?;
+ Ok(response)
+}
+
+fn listen_from_guest(port: u32) -> Result<VsockStream> {
+ let vsock_listener =
+ VsockListener::bind_with_cid_port(VMADDR_CID_HOST, port).context("Failed to bind vsock")?;
+ vsock_listener.set_nonblocking(true).context("Failed to set nonblocking")?;
+ let start_time = Instant::now();
+ loop {
+ if start_time.elapsed() >= LISTEN_TIMEOUT {
+ bail!("Timeout while listening");
+ }
+ match vsock_listener.accept() {
+ Ok((vsock_stream, _peer_addr)) => return Ok(vsock_stream),
+ Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
+ std::thread::sleep(Duration::from_millis(100));
+ }
+ Err(e) => bail!("Failed to listen: {e:?}"),
+ }
+ }
+}
+
+fn run_vm(image_path: &str, test_name: &CStr, protected_vm: bool) -> Result<()> {
+ let kernel_file = File::open(image_path).context("Failed to open kernel file")?;
+ let kernel_fd = kernel_file.into_raw_fd();
+
+ // SAFETY: AVirtualMachineRawConfig_create() isn't unsafe but rust_bindgen forces it to be seen
+ // as unsafe
+ let config = unsafe { AVirtualMachineRawConfig_create() };
+
+ info!("raw config created");
+
+ // SAFETY: config is the only reference to a valid object
+ unsafe {
+ AVirtualMachineRawConfig_setName(config, test_name.as_ptr());
+ AVirtualMachineRawConfig_setKernel(config, kernel_fd);
+ AVirtualMachineRawConfig_setProtectedVm(config, protected_vm);
+ AVirtualMachineRawConfig_setMemoryMiB(config, VM_MEMORY_MB);
+ }
+
+ let mut vm = std::ptr::null_mut();
+ let mut service = std::ptr::null_mut();
+
+ ensure!(
+ // SAFETY: &mut service is a valid pointer to *AVirtualizationService
+ unsafe { AVirtualizationService_create(&mut service, false) } == 0,
+ "AVirtualizationService_create failed"
+ );
+
+ scopeguard::defer! {
+ // SAFETY: service is a valid pointer to AVirtualizationService
+ unsafe { AVirtualizationService_destroy(service); }
+ }
+
+ ensure!(
+ // SAFETY: &mut vm is a valid pointer to *AVirtualMachine
+ unsafe {
+ AVirtualMachine_createRaw(
+ service, config, -1, // console_in
+ -1, // console_out
+ -1, // log
+ &mut vm,
+ )
+ } == 0,
+ "AVirtualMachine_createRaw failed"
+ );
+
+ scopeguard::defer! {
+ // SAFETY: vm is a valid pointer to AVirtualMachine
+ unsafe { AVirtualMachine_destroy(vm); }
+ }
+
+ info!("vm created");
+
+ let vm_type = if protected_vm { VmType::ProtectedVm } else { VmType::NonProtectedVm };
+
+ let listener_thread = std::thread::spawn(move || listen_from_guest(vm_type.port()));
+
+ // SAFETY: vm is the only reference to a valid object
+ unsafe {
+ AVirtualMachine_start(vm);
+ }
+
+ info!("VM started");
+
+ let mut vsock_stream = listener_thread.join().unwrap()?;
+ vsock_stream.set_read_timeout(Some(READ_TIMEOUT))?;
+ vsock_stream.set_write_timeout(Some(WRITE_TIMEOUT))?;
+
+ info!("client connected");
+
+ let request_data = vec![1, 2, 3, 4, 5];
+ let expected_data = vec![5, 4, 3, 2, 1];
+ let response = process_request(&mut vsock_stream, Request::Reverse(request_data))
+ .context("Failed to process request")?;
+ let Response::Reverse(reversed_data) = response else {
+ bail!("Expected Response::Reverse but was {response:?}");
+ };
+ ensure!(reversed_data == expected_data, "Expected {expected_data:?} but was {reversed_data:?}");
+
+ info!("request processed");
+
+ write_request(&mut vsock_stream, &ServiceVmRequest::Shutdown)
+ .context("Failed to send shutdown")?;
+
+ info!("shutdown sent");
+
+ let mut stop_reason = AVirtualMachineStopReason::AVIRTUAL_MACHINE_UNRECOGNISED;
+ ensure!(
+ // SAFETY: vm is the only reference to a valid object
+ unsafe { AVirtualMachine_waitForStop(vm, &STOP_TIMEOUT, &mut stop_reason) },
+ "AVirtualMachine_waitForStop failed"
+ );
+ assert_eq!(stop_reason, AVirtualMachineStopReason::AVIRTUAL_MACHINE_SHUTDOWN);
+
+ info!("stopped");
+
+ Ok(())
+}
+
+#[test]
+fn test_run_rialto_protected() -> Result<()> {
+ if hypervisor_props::is_protected_vm_supported()? {
+ run_vm(
+ "/data/local/tmp/rialto.bin", /* image_path */
+ c"test_rialto", /* test_name */
+ true, /* protected_vm */
+ )
+ } else {
+ info!("pVMs are not supported on device. skipping test");
+ Ok(())
+ }
+}
+
+#[test]
+fn test_run_rialto_non_protected() -> Result<()> {
+ if hypervisor_props::is_vm_supported()? {
+ run_vm(
+ "/data/local/tmp/rialto.bin", /* image_path */
+ c"test_rialto", /* test_name */
+ false, /* protected_vm */
+ )
+ } else {
+ info!("VMs are not supported on device. skipping test");
+ Ok(())
+ }
+}
+
+#[test]
+fn test_run_android16_rialto_protected() -> Result<()> {
+ if hypervisor_props::is_protected_vm_supported()? {
+ run_vm(
+ "/data/local/tmp/android16_rialto.bin", /* image_path */
+ c"android16_test_rialto", /* test_name */
+ true, /* protected_vm */
+ )
+ } else {
+ info!("pVMs are not supported on device. skipping test");
+ Ok(())
+ }
+}
+
+#[test]
+fn test_run_android16_rialto_non_protected() -> Result<()> {
+ if hypervisor_props::is_vm_supported()? {
+ run_vm(
+ "/data/local/tmp/android16_rialto.bin", /* image_path */
+ c"android16_test_rialto", /* test_name */
+ false, /* protected_vm */
+ )
+ } else {
+ info!("VMs are not supported on device. skipping test");
+ Ok(())
+ }
+}