pvmfw: Perform DICE derivation

Integrate DICE derivation into pvmfw and fail if the operation fails.

Note that we still need to get the salt ("hidden" DICE input) from the
instance.img or TRNG and pass the result to the next stage.

Bug: 256827715
Test: atest MicrodroidHostTests
Change-Id: Ibebaf526fd6055b9d05ce6017b560fb8814471e5
diff --git a/pvmfw/src/dice.rs b/pvmfw/src/dice.rs
new file mode 100644
index 0000000..b322850
--- /dev/null
+++ b/pvmfw/src/dice.rs
@@ -0,0 +1,58 @@
+// 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.
+
+//! Support for DICE derivation and BCC generation.
+
+use core::ffi::CStr;
+
+use dice::bcc::format_config_descriptor;
+use dice::bcc::Handover;
+use dice::hash;
+use dice::ConfigType;
+use dice::InputValues;
+
+/// Derive the VM-specific secrets and certificate through DICE.
+pub fn derive_next_bcc(
+    bcc: &Handover,
+    next_bcc: &mut [u8],
+    code: &[u8],
+    debug_mode: bool,
+    authority: &[u8],
+) -> dice::Result<usize> {
+    let code_hash = hash(code)?;
+    let auth_hash = hash(authority)?;
+    let mode = if debug_mode { dice::Mode::Debug } else { dice::Mode::Normal };
+    let component_name = CStr::from_bytes_with_nul(b"vm_entry\0").unwrap();
+    let mut config_descriptor_buffer = [0; 128];
+    let config_descriptor_size = format_config_descriptor(
+        &mut config_descriptor_buffer,
+        Some(component_name),
+        None,  // component_version
+        false, // resettable
+    )?;
+    let config = &config_descriptor_buffer[..config_descriptor_size];
+    let config = ConfigType::Descriptor(config);
+
+    let input_values = InputValues::new(
+        &code_hash,
+        None, // code_descriptor
+        &config,
+        Some(&auth_hash),
+        None, // auth_descriptor
+        mode,
+        None, // TODO(b/249723852): Get salt from instance.img (virtio-blk) and/or TRNG.
+    );
+
+    bcc.main_flow(&input_values, next_bcc)
+}