Migrate DICE access to IVmPayloadService
Take control of the microdroid interface to DICE so we can eventually
expose only what we need to with a simple interface.
Merge the DICE logic into microdroid_manager, removing a process,
removing IDiceMaintenance, and replacing IDiceNode with
IVmPayloadService for access to the DICE values. The current interface
is just meant to be enough to migrate current payload but it will need
to be refined.
The new interface is exposed in the vm_payload library and clients are
updated to use the new library functions.
Bug: 243133253
Bug: 243514248
Test: atest MicrodroidTests
Test: atest ComposHostTestCases
Change-Id: I2d659576ca3ccdb8f8ffd9d22ff0d1b96e85a3b8
diff --git a/microdroid/vm_payload/src/lib.rs b/microdroid/vm_payload/src/lib.rs
index 394578a..e3da227 100644
--- a/microdroid/vm_payload/src/lib.rs
+++ b/microdroid/vm_payload/src/lib.rs
@@ -16,4 +16,7 @@
mod vm_service;
-pub use vm_service::notify_payload_ready;
+pub use vm_service::{
+ get_dice_attestation_cdi, get_dice_attestation_chain, get_dice_sealing_cdi,
+ notify_payload_ready,
+};
diff --git a/microdroid/vm_payload/src/vm_service.rs b/microdroid/vm_payload/src/vm_service.rs
index 7414827..18d8222 100644
--- a/microdroid/vm_payload/src/vm_service.rs
+++ b/microdroid/vm_payload/src/vm_service.rs
@@ -28,7 +28,7 @@
android_logger::Config::default().with_tag("vm_payload").with_min_level(Level::Debug),
);
if let Err(e) = try_notify_payload_ready() {
- error!("Failed to notify ready: {}", e);
+ error!("{:?}", e);
false
} else {
info!("Notified host payload ready successfully");
@@ -42,6 +42,90 @@
get_vm_payload_service()?.notifyPayloadReady().context("Cannot notify payload ready")
}
+/// Get the VM's attestation chain.
+/// Returns the size of data or 0 on failure.
+///
+/// # Safety
+///
+/// The data must be size bytes big.
+#[no_mangle]
+pub unsafe extern "C" fn get_dice_attestation_chain(data: *mut u8, size: usize) -> usize {
+ match try_get_dice_attestation_chain() {
+ Err(e) => {
+ error!("{:?}", e);
+ 0
+ }
+ Ok(chain) => {
+ if size < chain.len() {
+ 0
+ } else {
+ std::ptr::copy_nonoverlapping(chain.as_ptr(), data, chain.len());
+ chain.len()
+ }
+ }
+ }
+}
+
+fn try_get_dice_attestation_chain() -> Result<Vec<u8>> {
+ get_vm_payload_service()?.getDiceAttestationChain().context("Cannot get attestation chain")
+}
+
+/// Get the VM's attestation CDI.
+/// Returns the size of data or 0 on failure.
+///
+/// # Safety
+///
+/// The data must be size bytes big.
+#[no_mangle]
+pub unsafe extern "C" fn get_dice_attestation_cdi(data: *mut u8, size: usize) -> usize {
+ match try_get_dice_attestation_cdi() {
+ Err(e) => {
+ error!("{:?}", e);
+ 0
+ }
+ Ok(cdi) => {
+ if size < cdi.len() {
+ 0
+ } else {
+ std::ptr::copy_nonoverlapping(cdi.as_ptr(), data, cdi.len());
+ cdi.len()
+ }
+ }
+ }
+}
+
+fn try_get_dice_attestation_cdi() -> Result<Vec<u8>> {
+ get_vm_payload_service()?.getDiceAttestationCdi().context("Cannot get attestation CDI")
+}
+
+/// Get the VM's sealing CDI.
+/// Returns the size of data or 0 on failure.
+///
+/// # Safety
+///
+/// The data must be size bytes big.
+#[no_mangle]
+pub unsafe extern "C" fn get_dice_sealing_cdi(data: *mut u8, size: usize) -> usize {
+ match try_get_dice_sealing_cdi() {
+ Err(e) => {
+ error!("{:?}", e);
+ 0
+ }
+ Ok(cdi) => {
+ if size < cdi.len() {
+ 0
+ } else {
+ std::ptr::copy_nonoverlapping(cdi.as_ptr(), data, cdi.len());
+ cdi.len()
+ }
+ }
+ }
+}
+
+fn try_get_dice_sealing_cdi() -> Result<Vec<u8>> {
+ get_vm_payload_service()?.getDiceSealingCdi().context("Cannot get sealing CDI")
+}
+
fn get_vm_payload_service() -> Result<Strong<dyn IVmPayloadService>> {
wait_for_interface(VM_PAYLOAD_SERVICE_NAME)
.context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_NAME))