[dice] Add trait DiceArtifacts to access BCC and CDI values

The added DiceArtifacts is implemented for both BccHandover and
OwnedDiceArtifacts. This allows us to access the dice artifacts in
an easy and uniform way.

[u8; CDI_SIZE] is used instead of the alias Cdi to facilitate a
future conversion from Cdi alias to Cdi type so that we can have
more controle over the memory security of CDI. More context in
b/268587826.

Bug: 267575445
Test: atest diced_utils_test diced_sample_inputs_test \
diced_vendor_test diced_open_dice_cbor_test \
libdiced_open_dice_nostd.integration_test \
libdiced_open_dice.integration_test diced_open_dice_cbor_test

Change-Id: Iabb87ad18f2f4a4d46283da045eb21a5776ad4b4
diff --git a/diced/Android.bp b/diced/Android.bp
index dfa81ec..b640326a 100644
--- a/diced/Android.bp
+++ b/diced/Android.bp
@@ -58,6 +58,7 @@
     rustlibs: [
         "android.hardware.security.dice-V1-rust",
         "libanyhow",
+        "libdiced_open_dice",
         "libdiced_open_dice_cbor",
         "libdiced_utils",
     ],
@@ -72,6 +73,7 @@
     rustlibs: [
         "android.hardware.security.dice-V1-rust",
         "libanyhow",
+        "libdiced_open_dice",
         "libdiced_open_dice_cbor",
         "libdiced_utils",
     ],
@@ -85,6 +87,7 @@
     vendor_available: true,
     rustlibs: [
         "android.hardware.security.dice-V1-rust",
+        "libdiced_open_dice",
         "libdiced_open_dice_cbor",
         "libanyhow",
         "libbinder_rs",
@@ -108,6 +111,7 @@
     rustlibs: [
         "android.hardware.security.dice-V1-rust",
         "libanyhow",
+        "libdiced_open_dice",
         "libdiced_open_dice_cbor",
         "libdiced_sample_inputs",
         "libdiced_utils",
@@ -138,6 +142,7 @@
         "android.security.dice-rust",
         "libanyhow",
         "libbinder_rs",
+        "libdiced_open_dice",
         "libdiced_open_dice_cbor",
         "libdiced_sample_inputs",
         "libdiced_utils",
diff --git a/diced/open_dice/src/bcc.rs b/diced/open_dice/src/bcc.rs
index f343bc5..1575113 100644
--- a/diced/open_dice/src/bcc.rs
+++ b/diced/open_dice/src/bcc.rs
@@ -14,7 +14,7 @@
 
 //! This module mirrors the content in open-dice/include/dice/android/bcc.h
 
-use crate::dice::{Cdi, CdiValues, InputValues, CDI_SIZE};
+use crate::dice::{Cdi, CdiValues, DiceArtifacts, InputValues, CDI_SIZE};
 use crate::error::{check_result, DiceError, Result};
 use open_dice_bcc_bindgen::{
     BccConfigValues, BccFormatConfigDescriptor, BccHandoverMainFlow, BccHandoverParse, BccMainFlow,
@@ -127,11 +127,25 @@
 #[derive(Debug)]
 pub struct BccHandover<'a> {
     /// Attestation CDI.
-    pub cdi_attest: &'a Cdi,
+    cdi_attest: &'a [u8; CDI_SIZE],
     /// Sealing CDI.
-    pub cdi_seal: &'a Cdi,
+    cdi_seal: &'a [u8; CDI_SIZE],
     /// Boot Certificate Chain.
-    pub bcc: Option<&'a [u8]>,
+    bcc: Option<&'a [u8]>,
+}
+
+impl<'a> DiceArtifacts for BccHandover<'a> {
+    fn cdi_attest(&self) -> &[u8; CDI_SIZE] {
+        self.cdi_attest
+    }
+
+    fn cdi_seal(&self) -> &[u8; CDI_SIZE] {
+        self.cdi_seal
+    }
+
+    fn bcc(&self) -> Option<&[u8]> {
+        self.bcc
+    }
 }
 
 /// A BCC handover combines the BCC and CDIs in a single CBOR object.
diff --git a/diced/open_dice/src/dice.rs b/diced/open_dice/src/dice.rs
index 350237d..f5e7f71 100644
--- a/diced/open_dice/src/dice.rs
+++ b/diced/open_dice/src/dice.rs
@@ -62,13 +62,31 @@
 /// Array type of DICE ID.
 pub type DiceId = [u8; ID_SIZE];
 
+/// A trait for types that represent Dice artifacts, which include:
+///
+/// - Attestation CDI
+/// - Sealing CDI
+/// - Boot Certificate Chain
+///
+/// Types that implement this trait provide an access these artifacts.
+pub trait DiceArtifacts {
+    /// Returns a reference to the attestation CDI.
+    fn cdi_attest(&self) -> &[u8; CDI_SIZE];
+
+    /// Returns a reference to the sealing CDI.
+    fn cdi_seal(&self) -> &[u8; CDI_SIZE];
+
+    /// Returns a reference to the Boot Certificate Chain, if present.
+    fn bcc(&self) -> Option<&[u8]>;
+}
+
 /// CDI Values.
 #[derive(Debug, Zeroize, ZeroizeOnDrop, Default)]
 pub struct CdiValues {
     /// Attestation CDI.
-    pub cdi_attest: Cdi,
+    pub cdi_attest: [u8; CDI_SIZE],
     /// Sealing CDI.
-    pub cdi_seal: Cdi,
+    pub cdi_seal: [u8; CDI_SIZE],
 }
 
 /// Configuration descriptor for DICE input values.
diff --git a/diced/open_dice/src/lib.rs b/diced/open_dice/src/lib.rs
index c10626b..925b5e8 100644
--- a/diced/open_dice/src/lib.rs
+++ b/diced/open_dice/src/lib.rs
@@ -33,8 +33,8 @@
 };
 pub use dice::{
     derive_cdi_certificate_id, derive_cdi_private_key_seed, dice_main_flow, Cdi, CdiValues, Config,
-    DiceMode, Hash, Hidden, InlineConfig, InputValues, PrivateKeySeed, CDI_SIZE, HASH_SIZE,
-    HIDDEN_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
+    DiceArtifacts, DiceMode, Hash, Hidden, InlineConfig, InputValues, PrivateKeySeed, CDI_SIZE,
+    HASH_SIZE, HIDDEN_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
 };
 pub use error::{check_result, DiceError, Result};
 pub use ops::{generate_certificate, hash, kdf, sign, verify};
diff --git a/diced/open_dice/src/retry.rs b/diced/open_dice/src/retry.rs
index b7c1a71..76a214c 100644
--- a/diced/open_dice/src/retry.rs
+++ b/diced/open_dice/src/retry.rs
@@ -18,7 +18,9 @@
 //! std environment.
 
 use crate::bcc::{bcc_format_config_descriptor, bcc_main_flow};
-use crate::dice::{dice_main_flow, Cdi, CdiValues, InputValues, PRIVATE_KEY_SEED_SIZE};
+use crate::dice::{
+    dice_main_flow, Cdi, CdiValues, DiceArtifacts, InputValues, CDI_SIZE, PRIVATE_KEY_SEED_SIZE,
+};
 use crate::error::{DiceError, Result};
 use crate::ops::generate_certificate;
 use std::ffi::CStr;
@@ -30,9 +32,23 @@
 #[derive(Debug)]
 pub struct OwnedDiceArtifacts {
     /// CDI Values.
-    pub cdi_values: CdiValues,
+    cdi_values: CdiValues,
     /// Boot Certificate Chain.
-    pub bcc: Vec<u8>,
+    bcc: Vec<u8>,
+}
+
+impl DiceArtifacts for OwnedDiceArtifacts {
+    fn cdi_attest(&self) -> &[u8; CDI_SIZE] {
+        &self.cdi_values.cdi_attest
+    }
+
+    fn cdi_seal(&self) -> &[u8; CDI_SIZE] {
+        &self.cdi_values.cdi_seal
+    }
+
+    fn bcc(&self) -> Option<&[u8]> {
+        Some(&self.bcc)
+    }
 }
 
 /// Retries the given function with bigger output buffer size.
diff --git a/diced/open_dice_cbor/lib.rs b/diced/open_dice_cbor/lib.rs
index ef797dc..0e68e70 100644
--- a/diced/open_dice_cbor/lib.rs
+++ b/diced/open_dice_cbor/lib.rs
@@ -126,6 +126,7 @@
 #[cfg(test)]
 mod test {
     use super::*;
+    use diced_open_dice::DiceArtifacts;
     use diced_sample_inputs::make_sample_bcc_and_cdis;
     use std::convert::TryInto;
 
@@ -319,8 +320,8 @@
     #[test]
     fn main_flow_and_bcc_main_flow() {
         let dice_artifacts = make_sample_bcc_and_cdis().unwrap();
-        assert_eq!(&dice_artifacts.cdi_values.cdi_attest, SAMPLE_CDI_ATTEST_TEST_VECTOR);
-        assert_eq!(&dice_artifacts.cdi_values.cdi_seal, SAMPLE_CDI_SEAL_TEST_VECTOR);
-        assert_eq!(&dice_artifacts.bcc, SAMPLE_BCC_TEST_VECTOR);
+        assert_eq!(dice_artifacts.cdi_attest(), SAMPLE_CDI_ATTEST_TEST_VECTOR);
+        assert_eq!(dice_artifacts.cdi_seal(), SAMPLE_CDI_SEAL_TEST_VECTOR);
+        assert_eq!(dice_artifacts.bcc(), Some(SAMPLE_BCC_TEST_VECTOR));
     }
 }
diff --git a/diced/src/diced_client_test.rs b/diced/src/diced_client_test.rs
index 054b2d1..29d7295 100644
--- a/diced/src/diced_client_test.rs
+++ b/diced/src/diced_client_test.rs
@@ -19,6 +19,7 @@
 use android_security_dice::aidl::android::security::dice::IDiceMaintenance::IDiceMaintenance;
 use android_security_dice::aidl::android::security::dice::IDiceNode::IDiceNode;
 use binder::Strong;
+use diced_open_dice::DiceArtifacts;
 use diced_open_dice_cbor as dice;
 use nix::libc::uid_t;
 use std::convert::TryInto;
@@ -54,11 +55,10 @@
             .unwrap();
 
     let artifacts = artifacts.execute_steps(input_values.iter()).unwrap();
-    let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
     let from_former = diced_utils::make_bcc_handover(
-        cdi_attest[..].try_into().unwrap(),
-        cdi_seal[..].try_into().unwrap(),
-        &bcc,
+        artifacts.cdi_attest(),
+        artifacts.cdi_seal(),
+        artifacts.bcc().expect("bcc is none"),
     )
     .unwrap();
     // TODO when we have a parser/verifier, check equivalence rather
@@ -94,11 +94,10 @@
     .unwrap();
 
     let artifacts = artifacts.execute_steps(input_values.iter()).unwrap();
-    let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
     let from_former = diced_utils::make_bcc_handover(
-        cdi_attest[..].try_into().unwrap(),
-        cdi_seal[..].try_into().unwrap(),
-        &bcc,
+        artifacts.cdi_attest(),
+        artifacts.cdi_seal(),
+        artifacts.bcc().expect("bcc is none"),
     )
     .unwrap();
     // TODO b/204938506 when we have a parser/verifier, check equivalence rather
@@ -156,11 +155,10 @@
     let client = [client];
 
     let artifacts = artifacts.execute_steps(input_values.iter().chain(client.iter())).unwrap();
-    let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
     let from_former = diced_utils::make_bcc_handover(
-        cdi_attest[..].try_into().unwrap(),
-        cdi_seal[..].try_into().unwrap(),
-        &bcc,
+        artifacts.cdi_attest(),
+        artifacts.cdi_seal(),
+        artifacts.bcc().expect("bcc is none"),
     )
     .unwrap();
     // TODO b/204938506 when we have a parser/verifier, check equivalence rather
diff --git a/diced/src/hal_node.rs b/diced/src/hal_node.rs
index 7a397ec..04602bd 100644
--- a/diced/src/hal_node.rs
+++ b/diced/src/hal_node.rs
@@ -35,6 +35,7 @@
 use anyhow::{Context, Result};
 use binder::{BinderFeatures, Result as BinderResult, Strong};
 use dice::{ContextImpl, OpenDiceCborContext};
+pub use diced_open_dice::DiceArtifacts;
 use diced_open_dice_cbor as dice;
 use diced_utils as utils;
 use nix::sys::wait::{waitpid, WaitStatus};
@@ -47,7 +48,7 @@
 use std::os::unix::io::RawFd;
 use std::sync::{Arc, RwLock};
 use utils::ResidentArtifacts;
-pub use utils::{DiceArtifacts, UpdatableDiceArtifacts};
+pub use utils::UpdatableDiceArtifacts;
 
 /// PipeReader is a simple wrapper around raw pipe file descriptors.
 /// It takes ownership of the file descriptor and closes it on drop. It provides `read_all`, which
@@ -331,7 +332,7 @@
         BccHandover::BccHandover, Config::Config as BinderConfig,
         InputValues::InputValues as BinderInputValues, Mode::Mode as BinderMode,
     };
-    use anyhow::{Context, Result};
+    use anyhow::{anyhow, Context, Result};
     use diced_open_dice_cbor as dice;
     use diced_sample_inputs;
     use diced_utils as utils;
@@ -346,11 +347,11 @@
 
     impl From<dice::OwnedDiceArtifacts> for InsecureSerializableArtifacts {
         fn from(dice_artifacts: dice::OwnedDiceArtifacts) -> Self {
-            Self {
-                cdi_attest: dice_artifacts.cdi_values.cdi_attest,
-                cdi_seal: dice_artifacts.cdi_values.cdi_seal,
-                bcc: dice_artifacts.bcc[..].to_vec(),
-            }
+            let mut cdi_attest = [0u8; dice::CDI_SIZE];
+            cdi_attest.copy_from_slice(dice_artifacts.cdi_attest());
+            let mut cdi_seal = [0u8; dice::CDI_SIZE];
+            cdi_seal.copy_from_slice(dice_artifacts.cdi_seal());
+            Self { cdi_attest, cdi_seal, bcc: dice_artifacts.bcc().expect("bcc is none").to_vec() }
         }
     }
 
@@ -361,8 +362,8 @@
         fn cdi_seal(&self) -> &[u8; dice::CDI_SIZE] {
             &self.cdi_seal
         }
-        fn bcc(&self) -> Vec<u8> {
-            self.bcc.clone()
+        fn bcc(&self) -> Option<&[u8]> {
+            Some(&self.bcc)
         }
     }
 
@@ -377,7 +378,7 @@
             Ok(Self {
                 cdi_attest: *new_artifacts.cdi_attest(),
                 cdi_seal: *new_artifacts.cdi_seal(),
-                bcc: new_artifacts.bcc(),
+                bcc: new_artifacts.bcc().ok_or_else(|| anyhow!("bcc is none"))?.to_vec(),
             })
         }
     }
@@ -430,7 +431,7 @@
         let result = utils::make_bcc_handover(
             new_artifacts.cdi_attest(),
             new_artifacts.cdi_seal(),
-            &new_artifacts.bcc(),
+            new_artifacts.bcc().unwrap(),
         )?;
 
         assert_eq!(result, make_derive_test_vector());
diff --git a/diced/src/sample_inputs.rs b/diced/src/sample_inputs.rs
index 802a6d3..824ee9e 100644
--- a/diced/src/sample_inputs.rs
+++ b/diced/src/sample_inputs.rs
@@ -18,11 +18,11 @@
 use android_hardware_security_dice::aidl::android::hardware::security::dice::{
     Config::Config as BinderConfig, InputValues::InputValues as BinderInputValues, Mode::Mode,
 };
-use anyhow::{Context, Result};
+use anyhow::{anyhow, Context, Result};
 use dice::ContextImpl;
+use diced_open_dice::DiceArtifacts;
 use diced_open_dice_cbor as dice;
 use diced_utils::{cbor, to_dice_input_values};
-use std::convert::TryInto;
 use std::ffi::CStr;
 use std::io::Write;
 
@@ -100,9 +100,9 @@
     )
     .context("In make_sample_bcc_and_cdis: Trying to run first bcc main flow.")?;
     dice::retry_bcc_main_flow(
-        &dice_artifacts.cdi_values.cdi_attest,
-        &dice_artifacts.cdi_values.cdi_seal,
-        &dice_artifacts.bcc,
+        dice_artifacts.cdi_attest(),
+        dice_artifacts.cdi_seal(),
+        dice_artifacts.bcc().ok_or_else(|| anyhow!("bcc is none"))?,
         &to_dice_input_values(&input_values_vector[2]),
     )
     .context("In make_sample_bcc_and_cdis: Trying to run second bcc main flow.")
diff --git a/diced/src/utils.rs b/diced/src/utils.rs
index 2b47dac..2789a60 100644
--- a/diced/src/utils.rs
+++ b/diced/src/utils.rs
@@ -18,8 +18,9 @@
     Bcc::Bcc, BccHandover::BccHandover, InputValues::InputValues as BinderInputValues,
     Mode::Mode as BinderMode,
 };
-use anyhow::{Context, Result};
+use anyhow::{anyhow, Context, Result};
 use diced_open_dice as dice;
+use diced_open_dice::DiceArtifacts;
 use keystore2_crypto::ZVec;
 use std::convert::TryInto;
 
@@ -61,6 +62,7 @@
 /// and the BCC formatted attestation certificate chain. The sensitive secrets are
 /// stored in zeroing vectors, and it implements functionality to perform DICE
 /// derivation steps using libopen-dice-cbor.
+/// TODO(b/268322533): Remove this struct with the unused HAL service dice
 pub struct ResidentArtifacts {
     cdi_attest: ZVec,
     cdi_seal: ZVec,
@@ -72,9 +74,9 @@
 
     fn try_from(dice_artifacts: dice::OwnedDiceArtifacts) -> Result<Self, Self::Error> {
         Ok(ResidentArtifacts {
-            cdi_attest: dice_artifacts.cdi_values.cdi_attest[..].try_into()?,
-            cdi_seal: dice_artifacts.cdi_values.cdi_seal[..].try_into()?,
-            bcc: dice_artifacts.bcc[..].to_vec(),
+            cdi_attest: dice_artifacts.cdi_attest().to_vec().try_into()?,
+            cdi_seal: dice_artifacts.cdi_seal().to_vec().try_into()?,
+            bcc: dice_artifacts.bcc().ok_or_else(|| anyhow!("bcc is none"))?.to_vec(),
         })
     }
 }
@@ -104,9 +106,9 @@
     /// because DiceArtifacts returns array references of appropriate size.
     pub fn new_from<T: DiceArtifacts + ?Sized>(artifacts: &T) -> Result<Self> {
         Ok(ResidentArtifacts {
-            cdi_attest: artifacts.cdi_attest()[..].try_into()?,
-            cdi_seal: artifacts.cdi_seal()[..].try_into()?,
-            bcc: artifacts.bcc(),
+            cdi_attest: artifacts.cdi_attest().to_vec().try_into()?,
+            cdi_seal: artifacts.cdi_seal().to_vec().try_into()?,
+            bcc: artifacts.bcc().ok_or_else(|| anyhow!("bcc is none"))?.to_vec(),
         })
     }
 
@@ -163,20 +165,6 @@
     }
 }
 
-/// An object that implements this trait provides the typical DICE artifacts.
-/// CDI_ATTEST, CDI_SEAL, and a certificate chain up to the public key that
-/// can be derived from CDI_ATTEST. Implementations should check the length of
-/// the stored CDI_* secrets on creation so that any valid instance returns the
-/// correct secrets in an infallible way.
-pub trait DiceArtifacts {
-    /// Returns CDI_ATTEST.
-    fn cdi_attest(&self) -> &[u8; dice::CDI_SIZE];
-    /// Returns CDI_SEAL.
-    fn cdi_seal(&self) -> &[u8; dice::CDI_SIZE];
-    /// Returns the attestation certificate chain in BCC format.
-    fn bcc(&self) -> Vec<u8>;
-}
-
 /// Implement this trait to provide read and write access to a secure artifact
 /// storage that can be used by the ResidentHal implementation.
 pub trait UpdatableDiceArtifacts {
@@ -199,8 +187,8 @@
     fn cdi_seal(&self) -> &[u8; dice::CDI_SIZE] {
         self.cdi_seal[..].try_into().unwrap()
     }
-    fn bcc(&self) -> Vec<u8> {
-        self.bcc.clone()
+    fn bcc(&self) -> Option<&[u8]> {
+        Some(&self.bcc)
     }
 }