From 3b80c9b14bd28c06f675f583e8b12693d9063705 Mon Sep 17 00:00:00 2001 From: Andrew Scull Date: Thu, 6 Oct 2022 18:54:05 +0000 Subject: [PATCH] Remove the DICE service from microdroid The DICE logic is provided by microdroid_maanger so remove the legacy DICE service from microdroid. Bug: 243133253 Test: atest MicrodroidTests Test: atest ComposHostTestCases Change-Id: Ibc1a074b4c6f26b56e8723d135f7e862c6fd5203 --- microdroid/Android.bp | 10 - microdroid/dice/Android.bp | 26 -- microdroid/dice/dice-service.microdroid.rc | 3 - microdroid/dice/service.rs | 303 ------------------ microdroid/init.rc | 2 - .../microdroid_compatibility_matrix.xml | 11 - 6 files changed, 355 deletions(-) delete mode 100644 microdroid/dice/Android.bp delete mode 100644 microdroid/dice/dice-service.microdroid.rc delete mode 100644 microdroid/dice/service.rs delete mode 100644 microdroid/microdroid_compatibility_matrix.xml diff --git a/microdroid/Android.bp b/microdroid/Android.bp index 10e58587..81f94bc3 100644 --- a/microdroid/Android.bp +++ b/microdroid/Android.bp @@ -70,7 +70,6 @@ android_system_image { "apexd", "atrace", "debuggerd", - "dice-service.microdroid", "linker", "linkerconfig", "servicemanager.microdroid", @@ -80,7 +79,6 @@ android_system_image { "task_profiles.json", "public.libraries.android.txt", - "microdroid_compatibility_matrix", "microdroid_event-log-tags", "microdroid_file_contexts", "microdroid_manifest", @@ -532,14 +530,6 @@ prebuilt_etc { installable: false, } -prebuilt_etc { - name: "microdroid_compatibility_matrix", - src: "microdroid_compatibility_matrix.xml", - filename: "compatibility_matrix.current.xml", - relative_install_path: "vintf", - installable: false, -} - prebuilt_etc { name: "microdroid_manifest", src: "microdroid_manifest.xml", diff --git a/microdroid/dice/Android.bp b/microdroid/dice/Android.bp deleted file mode 100644 index 859533e7..00000000 --- a/microdroid/dice/Android.bp +++ /dev/null @@ -1,26 +0,0 @@ -package { - default_applicable_licenses: ["Android-Apache-2.0"], -} - -rust_binary { - name: "dice-service.microdroid", - srcs: ["service.rs"], - prefer_rlib: true, - rustlibs: [ - "android.hardware.security.dice-V1-rust", - "android.security.dice-rust", - "libandroid_logger", - "libanyhow", - "libbinder_rs", - "libbyteorder", - "libdiced", - "libdiced_open_dice_cbor", - "libdiced_sample_inputs", - "libdiced_utils", - "liblibc", - "liblog_rust", - "libserde", - ], - init_rc: ["dice-service.microdroid.rc"], - bootstrap: true, -} diff --git a/microdroid/dice/dice-service.microdroid.rc b/microdroid/dice/dice-service.microdroid.rc deleted file mode 100644 index 5bcb0498..00000000 --- a/microdroid/dice/dice-service.microdroid.rc +++ /dev/null @@ -1,3 +0,0 @@ -service dice-microdroid /system/bin/dice-service.microdroid - user diced - group diced diff --git a/microdroid/dice/service.rs b/microdroid/dice/service.rs deleted file mode 100644 index 2c19481f..00000000 --- a/microdroid/dice/service.rs +++ /dev/null @@ -1,303 +0,0 @@ -// 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 DICE service implementation. - -use android_hardware_security_dice::aidl::android::hardware::security::dice::{ - Bcc::Bcc, BccHandover::BccHandover, InputValues::InputValues as BinderInputValues, - Signature::Signature, -}; -use anyhow::{bail, ensure, Context, Error, Result}; -use byteorder::{NativeEndian, ReadBytesExt}; -use dice::{ContextImpl, OpenDiceCborContext}; -use diced::{dice, DiceMaintenance, DiceNode, DiceNodeImpl}; -use diced_utils::make_bcc_handover; -use libc::{c_void, mmap, munmap, MAP_FAILED, MAP_PRIVATE, PROT_READ}; -use serde::{Deserialize, Serialize}; -use std::fs; -use std::os::unix::io::AsRawFd; -use std::panic; -use std::path::{Path, PathBuf}; -use std::ptr::null_mut; -use std::slice; -use std::sync::{Arc, RwLock}; - -const AVF_STRICT_BOOT: &str = "/sys/firmware/devicetree/base/chosen/avf,strict-boot"; -const DICE_NODE_SERVICE_NAME: &str = "android.security.dice.IDiceNode"; -const DICE_MAINTENANCE_SERVICE_NAME: &str = "android.security.dice.IDiceMaintenance"; - -/// Artifacts that are mapped into the process address space from the driver. -struct MappedDriverArtifacts<'a> { - mmap_addr: *mut c_void, - mmap_size: usize, - cdi_attest: &'a [u8; dice::CDI_SIZE], - cdi_seal: &'a [u8; dice::CDI_SIZE], - bcc: &'a [u8], -} - -impl MappedDriverArtifacts<'_> { - fn new(driver_path: &Path) -> Result { - let mut file = fs::File::open(driver_path) - .map_err(|error| Error::new(error).context("Opening driver"))?; - let mmap_size = - file.read_u64::() - .map_err(|error| Error::new(error).context("Reading driver"))? as usize; - // It's safe to map the driver as the service will only create a single - // mapping per process. - let mmap_addr = unsafe { - let fd = file.as_raw_fd(); - mmap(null_mut(), mmap_size, PROT_READ, MAP_PRIVATE, fd, 0) - }; - if mmap_addr == MAP_FAILED { - bail!("Failed to mmap {:?}", driver_path); - } - // The slice is created for the region of memory that was just - // successfully mapped into the process address space so it will be - // accessible and not referenced from anywhere else. - let mmap_buf = - unsafe { slice::from_raw_parts((mmap_addr as *const u8).as_ref().unwrap(), mmap_size) }; - // Very inflexible parsing / validation of the BccHandover data. Assumes deterministically - // encoded CBOR. - // - // BccHandover = { - // 1 : bstr .size 32, ; CDI_Attest - // 2 : bstr .size 32, ; CDI_Seal - // 3 : Bcc, ; Certificate chain - // } - if mmap_buf[0..4] != [0xa3, 0x01, 0x58, 0x20] - || mmap_buf[36..39] != [0x02, 0x58, 0x20] - || mmap_buf[71] != 0x03 - { - bail!("BccHandover format mismatch"); - } - Ok(Self { - mmap_addr, - mmap_size, - cdi_attest: mmap_buf[4..36].try_into().unwrap(), - cdi_seal: mmap_buf[39..71].try_into().unwrap(), - bcc: &mmap_buf[72..], - }) - } -} - -impl Drop for MappedDriverArtifacts<'_> { - fn drop(&mut self) { - // All references to the mapped region have the same lifetime as self. - // Since self is being dropped, so are all the references to the mapped - // region meaning its safe to unmap. - let ret = unsafe { munmap(self.mmap_addr, self.mmap_size) }; - if ret != 0 { - log::warn!("Failed to munmap ({})", ret); - } - } -} - -/// 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, -} - -#[derive(Clone, Serialize, Deserialize)] -enum UpdatableArtifacts { - Invalid, - Driver(PathBuf), - Updated(RawArtifacts), -} - -impl UpdatableArtifacts { - fn get( - &self, - input_values: &BinderInputValues, - ) -> Result<(dice::CdiAttest, dice::CdiSeal, Vec)> { - let input_values: diced_utils::InputValues = input_values.into(); - match self { - Self::Invalid => bail!("No DICE artifacts available."), - Self::Driver(driver_path) => { - let artifacts = MappedDriverArtifacts::new(driver_path.as_path())?; - dice::OpenDiceCborContext::new().bcc_main_flow( - artifacts.cdi_attest, - artifacts.cdi_seal, - artifacts.bcc, - &input_values, - ) - } - Self::Updated(artifacts) => dice::OpenDiceCborContext::new().bcc_main_flow( - &artifacts.cdi_attest, - &artifacts.cdi_seal, - &artifacts.bcc, - &input_values, - ), - } - .context("Deriving artifacts") - } - - fn update(self, inputs: &BinderInputValues) -> Result { - if let Self::Invalid = self { - bail!("Cannot update invalid DICE artifacts."); - } - let (cdi_attest, cdi_seal, bcc) = - self.get(inputs).context("Failed to get update artifacts.")?; - if let Self::Driver(ref driver_path) = self { - // Writing to the device wipes the artifacts. The string is ignored - // by the driver but included for documentation. - fs::write(driver_path, "wipe") - .map_err(|error| Error::new(error).context("Wiping driver"))?; - } - Ok(Self::Updated(RawArtifacts { - cdi_attest: cdi_attest[..].try_into().unwrap(), - cdi_seal: cdi_seal[..].try_into().unwrap(), - bcc, - })) - } -} - -struct ArtifactManager { - artifacts: RwLock, -} - -impl ArtifactManager { - fn new(driver_path: &Path) -> Self { - Self { - artifacts: RwLock::new(if driver_path.exists() { - log::info!("Using DICE values from driver"); - UpdatableArtifacts::Driver(driver_path.to_path_buf()) - } else if Path::new(AVF_STRICT_BOOT).exists() { - log::error!("Strict boot requires DICE value from driver but none were found"); - UpdatableArtifacts::Invalid - } else { - log::warn!("Using sample DICE values"); - let (cdi_attest, cdi_seal, bcc) = diced_sample_inputs::make_sample_bcc_and_cdis() - .expect("Failed to create sample dice artifacts."); - UpdatableArtifacts::Updated(RawArtifacts { - cdi_attest: cdi_attest[..].try_into().unwrap(), - cdi_seal: cdi_seal[..].try_into().unwrap(), - bcc, - }) - }), - } - } -} - -impl DiceNodeImpl for ArtifactManager { - fn sign( - &self, - client: BinderInputValues, - input_values: &[BinderInputValues], - message: &[u8], - ) -> Result { - ensure!(input_values.is_empty(), "Extra input values not supported"); - let artifacts = self.artifacts.read().unwrap().clone(); - let (cdi_attest, _, _) = - artifacts.get(&client).context("Failed to get signing artifacts.")?; - let mut dice = OpenDiceCborContext::new(); - let seed = dice - .derive_cdi_private_key_seed( - cdi_attest[..].try_into().context("Failed to convert cdi_attest.")?, - ) - .context("Failed to derive seed from cdi_attest.")?; - let (_public_key, private_key) = dice - .keypair_from_seed(seed[..].try_into().context("Failed to convert seed.")?) - .context("Failed to derive keypair from seed.")?; - let signature = dice - .sign(message, private_key[..].try_into().context("Failed to convert private_key.")?) - .context("Failed to sign.")?; - Ok(Signature { data: signature }) - } - - fn get_attestation_chain( - &self, - client: BinderInputValues, - input_values: &[BinderInputValues], - ) -> Result { - ensure!(input_values.is_empty(), "Extra input values not supported"); - let artifacts = self.artifacts.read().unwrap().clone(); - let (_, _, bcc) = - artifacts.get(&client).context("Failed to get attestation chain artifacts.")?; - Ok(Bcc { data: bcc }) - } - - fn derive( - &self, - client: BinderInputValues, - input_values: &[BinderInputValues], - ) -> Result { - ensure!(input_values.is_empty(), "Extra input values not supported"); - let artifacts = self.artifacts.read().unwrap().clone(); - let (cdi_attest, cdi_seal, bcc) = - artifacts.get(&client).context("Failed to get attestation chain artifacts.")?; - make_bcc_handover( - &cdi_attest - .to_vec() - .as_slice() - .try_into() - .context("Trying to convert cdi_attest to sized array.")?, - &cdi_seal - .to_vec() - .as_slice() - .try_into() - .context("Trying to convert cdi_seal to sized array.")?, - &bcc, - ) - .context("Trying to construct BccHandover.") - } - - fn demote( - &self, - _client: BinderInputValues, - _input_values: &[BinderInputValues], - ) -> Result<()> { - bail!("Demote not supported."); - } - - fn demote_self(&self, input_values: &[BinderInputValues]) -> Result<()> { - ensure!(input_values.len() == 1, "Can only demote_self one level."); - let mut artifacts = self.artifacts.write().unwrap(); - *artifacts = (*artifacts).clone().update(&input_values[0])?; - Ok(()) - } -} - -fn main() { - android_logger::init_once( - android_logger::Config::default().with_tag("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!("DICE service is starting."); - - let node_impl = Arc::new(ArtifactManager::new(Path::new("/dev/open-dice0"))); - - let node = DiceNode::new_as_binder(node_impl.clone()) - .expect("Failed to create IDiceNode service instance."); - - let maintenance = DiceMaintenance::new_as_binder(node_impl) - .expect("Failed to create IDiceMaintenance service instance."); - - binder::add_service(DICE_NODE_SERVICE_NAME, node.as_binder()) - .expect("Failed to register IDiceNode Service"); - - binder::add_service(DICE_MAINTENANCE_SERVICE_NAME, maintenance.as_binder()) - .expect("Failed to register IDiceMaintenance Service"); - - log::info!("Joining thread pool now."); - binder::ProcessState::join_thread_pool(); -} diff --git a/microdroid/init.rc b/microdroid/init.rc index 8b2bbdb5..2b4295f1 100644 --- a/microdroid/init.rc +++ b/microdroid/init.rc @@ -67,8 +67,6 @@ on init start servicemanager - start dice-microdroid - on init mkdir /mnt/apk 0755 system system mkdir /mnt/extra-apk 0755 root root diff --git a/microdroid/microdroid_compatibility_matrix.xml b/microdroid/microdroid_compatibility_matrix.xml deleted file mode 100644 index a345e301..00000000 --- a/microdroid/microdroid_compatibility_matrix.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - android.hardware.security.dice - 1 - - IDiceDevice - default - - -