Implement the DICE HAL using fake values
THe values are placeholders until true values are made available for the
HAL to pick up. Adding the HAL allows diced to connect to it and get
some values rather than it trying to connect to the HAL for a little
bit, failing and then generating its own fake values. The result is
still fake, but there it less waiting and the components are connecting
as they are expected to.
Bug: 214231981
Test: run microdroid
Change-Id: I3e6d2995e388418f99d1987fa1af22f9818bd745
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index 940094d..e078108 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -178,6 +178,7 @@
partition_name: "vendor",
use_avb: true,
deps: [
+ "android.hardware.security.dice-service.microdroid",
"android.hardware.security.keymint-service.microdroid",
"microdroid_fstab",
"microdroid_precompiled_sepolicy.plat_sepolicy_and_mapping.sha256",
diff --git a/microdroid/dice/Android.bp b/microdroid/dice/Android.bp
new file mode 100644
index 0000000..1342a84
--- /dev/null
+++ b/microdroid/dice/Android.bp
@@ -0,0 +1,28 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+rust_binary {
+ name: "android.hardware.security.dice-service.microdroid",
+ srcs: ["service.rs"],
+ relative_install_path: "hw",
+ vendor: true,
+ rustlibs: [
+ "android.hardware.security.dice-V1-rust",
+ "libandroid_logger",
+ "libanyhow",
+ "libbinder_rs",
+ "libbyteorder",
+ "libdiced_open_dice_cbor",
+ "libdiced_sample_inputs",
+ "libdiced_vendor",
+ "liblibc",
+ "liblog_rust",
+ "libserde",
+ ],
+ init_rc: ["android.hardware.security.dice-service.microdroid.rc"],
+ vintf_fragments: [
+ "android.hardware.security.dice-service.microdroid.xml",
+ ],
+ bootstrap: true,
+}
diff --git a/microdroid/dice/android.hardware.security.dice-service.microdroid.rc b/microdroid/dice/android.hardware.security.dice-service.microdroid.rc
new file mode 100644
index 0000000..162081e
--- /dev/null
+++ b/microdroid/dice/android.hardware.security.dice-service.microdroid.rc
@@ -0,0 +1,3 @@
+service vendor.dice-microdroid /vendor/bin/hw/android.hardware.security.dice-service.microdroid
+ class early_hal
+ user nobody
diff --git a/microdroid/dice/android.hardware.security.dice-service.microdroid.xml b/microdroid/dice/android.hardware.security.dice-service.microdroid.xml
new file mode 100644
index 0000000..cf6c482
--- /dev/null
+++ b/microdroid/dice/android.hardware.security.dice-service.microdroid.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+ <hal format="aidl">
+ <name>android.hardware.security.dice</name>
+ <fqname>IDiceDevice/default</fqname>
+ </hal>
+</manifest>
diff --git a/microdroid/dice/service.rs b/microdroid/dice/service.rs
new file mode 100644
index 0000000..3401654
--- /dev/null
+++ b/microdroid/dice/service.rs
@@ -0,0 +1,117 @@
+// Copyright 2022, 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.
+
+//! Main entry point for the microdroid IDiceDevice HAL implementation.
+
+use anyhow::Result;
+use diced::{
+ dice,
+ hal_node::{DiceArtifacts, DiceDevice, ResidentHal, UpdatableDiceArtifacts},
+};
+use serde::{Deserialize, Serialize};
+use std::panic;
+use std::sync::Arc;
+
+const DICE_HAL_SERVICE_NAME: &str = "android.hardware.security.dice.IDiceDevice/default";
+
+/// Artifacts that are kept in the process address space after the artifacts
+/// from the driver have been consumed.
+#[derive(Clone, Serialize, Deserialize)]
+struct RawArtifacts {
+ cdi_attest: [u8; dice::CDI_SIZE],
+ cdi_seal: [u8; dice::CDI_SIZE],
+ bcc: Vec<u8>,
+}
+
+impl DiceArtifacts for RawArtifacts {
+ fn cdi_attest(&self) -> &[u8; dice::CDI_SIZE] {
+ &self.cdi_attest
+ }
+ fn cdi_seal(&self) -> &[u8; dice::CDI_SIZE] {
+ &self.cdi_seal
+ }
+ fn bcc(&self) -> Vec<u8> {
+ // The BCC only contains public information so it's fine to copy.
+ self.bcc.clone()
+ }
+}
+
+#[derive(Clone, Serialize, Deserialize)]
+enum DriverArtifactManager {
+ Updated(RawArtifacts),
+}
+
+impl DriverArtifactManager {
+ fn new() -> Self {
+ // TODO(214231981): replace with true values passed by bootloader
+ let (cdi_attest, cdi_seal, bcc) = diced_sample_inputs::make_sample_bcc_and_cdis()
+ .expect("Failed to create sample dice artifacts.");
+ Self::Updated(RawArtifacts {
+ cdi_attest: cdi_attest[..].try_into().unwrap(),
+ cdi_seal: cdi_seal[..].try_into().unwrap(),
+ bcc,
+ })
+ }
+}
+
+impl UpdatableDiceArtifacts for DriverArtifactManager {
+ fn with_artifacts<F, T>(&self, f: F) -> Result<T>
+ where
+ F: FnOnce(&dyn DiceArtifacts) -> Result<T>,
+ {
+ match self {
+ Self::Updated(raw_artifacts) => f(raw_artifacts),
+ }
+ }
+ fn update(self, new_artifacts: &impl DiceArtifacts) -> Result<Self> {
+ Ok(Self::Updated(RawArtifacts {
+ cdi_attest: *new_artifacts.cdi_attest(),
+ cdi_seal: *new_artifacts.cdi_seal(),
+ bcc: new_artifacts.bcc(),
+ }))
+ }
+}
+
+fn main() {
+ android_logger::init_once(
+ android_logger::Config::default()
+ .with_tag("android.hardware.security.dice")
+ .with_min_level(log::Level::Debug),
+ );
+ // Redirect panic messages to logcat.
+ panic::set_hook(Box::new(|panic_info| {
+ log::error!("{}", panic_info);
+ }));
+
+ // Saying hi.
+ log::info!("android.hardware.security.dice is starting.");
+
+ let hal_impl = Arc::new(
+ unsafe {
+ // Safety: ResidentHal cannot be used in multi threaded processes.
+ // This service does not start a thread pool. The main thread is the only thread
+ // joining the thread pool, thereby keeping the process single threaded.
+ ResidentHal::new(DriverArtifactManager::new())
+ }
+ .expect("Failed to create ResidentHal implementation."),
+ );
+
+ let hal = DiceDevice::new_as_binder(hal_impl).expect("Failed to construct hal service.");
+
+ binder::add_service(DICE_HAL_SERVICE_NAME, hal.as_binder())
+ .expect("Failed to register IDiceDevice Service");
+
+ log::info!("Joining thread pool now.");
+ binder::ProcessState::join_thread_pool();
+}
diff --git a/microdroid/init.rc b/microdroid/init.rc
index 117b62c..e76260e 100644
--- a/microdroid/init.rc
+++ b/microdroid/init.rc
@@ -61,6 +61,7 @@
start servicemanager
+ start vendor.dice-microdroid
start diced
mkdir /mnt/apk 0755 system system