[dice] Move bcc_main_flow to the library libdiced_open_dice

This cl splits the existing BccMainFlow wrapper with retries
into a raw version and a retry version. The former is
available in both std and nostd environment. The latter
returns a ZerorizeOnDrop struct containing Attestation CDI
and Sealing CDI. This struct is going to replace the
`DiceContext` in microdroid as it is sets all the CDIs to
zero when the struct goes out of scope, which is more secure.

This is part of the project of merging the two existing dice
wrapper libraries into one library libdiced_open_dice.

Test: atest diced_utils_test diced_sample_inputs_test \
diced_test diced_vendor_test diced_open_dice_cbor_test
Test: m pvmfw_img microdroid_manager && atest \
microdroid_manager_test
Bug: 267575445

Change-Id: I94444619fe2dcddf8541a6c9971c7e565c44dda1
diff --git a/diced/Android.bp b/diced/Android.bp
index ddcc8c1..d51fac2 100644
--- a/diced/Android.bp
+++ b/diced/Android.bp
@@ -60,7 +60,6 @@
         "libanyhow",
         "libdiced_open_dice_cbor",
         "libdiced_utils",
-        "libkeystore2_crypto_rust",
     ],
 }
 
@@ -75,7 +74,6 @@
         "libanyhow",
         "libdiced_open_dice_cbor",
         "libdiced_utils",
-        "libkeystore2_crypto_rust",
     ],
 }
 
diff --git a/diced/open_dice/Android.bp b/diced/open_dice/Android.bp
index e2c7dd1..ea3ee3b 100644
--- a/diced/open_dice/Android.bp
+++ b/diced/open_dice/Android.bp
@@ -22,6 +22,7 @@
     rustlibs: [
         "libopen_dice_bcc_bindgen_nostd",
         "libopen_dice_cbor_bindgen_nostd",
+        "libzeroize_nostd",
     ],
      whole_static_libs: [
         "libopen_dice_cbor",
@@ -37,6 +38,7 @@
         "libopen_dice_cbor_bindgen",
         // For ZVec
         "libkeystore2_crypto_rust",
+        "libzeroize",
     ],
     features: [
         "std",
diff --git a/diced/open_dice/src/bcc.rs b/diced/open_dice/src/bcc.rs
index 8bda225..e3a96fe 100644
--- a/diced/open_dice/src/bcc.rs
+++ b/diced/open_dice/src/bcc.rs
@@ -14,9 +14,10 @@
 
 //! This module mirrors the content in open-dice/include/dice/android/bcc.h
 
+use crate::dice::{Cdi, CdiValues, InputValues};
 use crate::error::{check_result, Result};
 use open_dice_bcc_bindgen::{
-    BccConfigValues, BccFormatConfigDescriptor, BCC_INPUT_COMPONENT_NAME,
+    BccConfigValues, BccFormatConfigDescriptor, BccMainFlow, BCC_INPUT_COMPONENT_NAME,
     BCC_INPUT_COMPONENT_VERSION, BCC_INPUT_RESETTABLE,
 };
 use std::{ffi::CStr, ptr};
@@ -54,3 +55,38 @@
     })?;
     Ok(buffer_size)
 }
+
+/// Executes the main BCC flow.
+///
+/// Given a full set of input values along with the current BCC and CDI values,
+/// computes the next CDI values and matching updated BCC.
+pub fn bcc_main_flow(
+    current_cdi_attest: &Cdi,
+    current_cdi_seal: &Cdi,
+    current_bcc: &[u8],
+    input_values: &InputValues,
+    next_cdi_values: &mut CdiValues,
+    next_bcc: &mut [u8],
+) -> Result<usize> {
+    let mut next_bcc_size = 0;
+    // SAFETY: `BccMainFlow` only reads the current `bcc` and CDI values and writes
+    // to `next_bcc` and next CDI values within its bounds. It also reads
+    // `input_values` as a constant input and doesn't store any pointer.
+    // The first argument can be null and is not used in the current implementation.
+    check_result(unsafe {
+        BccMainFlow(
+            ptr::null_mut(), // context
+            current_cdi_attest.as_ptr(),
+            current_cdi_seal.as_ptr(),
+            current_bcc.as_ptr(),
+            current_bcc.len(),
+            input_values.as_ptr(),
+            next_bcc.len(),
+            next_bcc.as_mut_ptr(),
+            &mut next_bcc_size,
+            next_cdi_values.cdi_attest.as_mut_ptr(),
+            next_cdi_values.cdi_seal.as_mut_ptr(),
+        )
+    })?;
+    Ok(next_bcc_size)
+}
diff --git a/diced/open_dice/src/dice.rs b/diced/open_dice/src/dice.rs
index 014d5fd..9e3c59d 100644
--- a/diced/open_dice/src/dice.rs
+++ b/diced/open_dice/src/dice.rs
@@ -23,6 +23,7 @@
     DICE_PRIVATE_KEY_SEED_SIZE,
 };
 use std::ptr;
+use zeroize::{Zeroize, ZeroizeOnDrop};
 
 /// The size of a DICE hash.
 pub const HASH_SIZE: usize = DICE_HASH_SIZE as usize;
@@ -50,6 +51,15 @@
 /// Array type of DICE ID.
 pub type DiceId = [u8; ID_SIZE];
 
+/// CDI Values.
+#[derive(Zeroize, ZeroizeOnDrop, Default)]
+pub struct CdiValues {
+    /// Attestation CDI.
+    pub cdi_attest: Cdi,
+    /// Sealing CDI.
+    pub cdi_seal: Cdi,
+}
+
 /// Configuration descriptor for DICE input values.
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum Config<'a> {
diff --git a/diced/open_dice/src/lib.rs b/diced/open_dice/src/lib.rs
index 5a34698..9184a44 100644
--- a/diced/open_dice/src/lib.rs
+++ b/diced/open_dice/src/lib.rs
@@ -27,13 +27,13 @@
 #[cfg(feature = "std")]
 mod retry;
 
-pub use bcc::bcc_format_config_descriptor;
+pub use bcc::{bcc_format_config_descriptor, bcc_main_flow};
 pub use dice::{
-    derive_cdi_certificate_id, derive_cdi_private_key_seed, Cdi, Config, DiceMode, Hash, Hidden,
-    InlineConfig, InputValues, PrivateKeySeed, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE, ID_SIZE,
+    derive_cdi_certificate_id, derive_cdi_private_key_seed, Cdi, CdiValues, Config, 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::hash;
 #[cfg(feature = "std")]
-pub use retry::retry_bcc_format_config_descriptor;
+pub use retry::{retry_bcc_format_config_descriptor, retry_bcc_main_flow, OwnedDiceArtifacts};
diff --git a/diced/open_dice/src/retry.rs b/diced/open_dice/src/retry.rs
index 648fd91..6af6f00 100644
--- a/diced/open_dice/src/retry.rs
+++ b/diced/open_dice/src/retry.rs
@@ -17,10 +17,22 @@
 //! memory allocation on heap, currently we only expose these functions in
 //! std environment.
 
-use crate::bcc::bcc_format_config_descriptor;
+use crate::bcc::{bcc_format_config_descriptor, bcc_main_flow};
+use crate::dice::{Cdi, CdiValues, InputValues};
 use crate::error::{DiceError, Result};
 use std::ffi::CStr;
 
+/// Artifacts stores a set of dice artifacts comprising CDI_ATTEST, CDI_SEAL,
+/// and the BCC formatted attestation certificate chain.
+/// As we align with the DICE standards today, this is the certificate chain
+/// is also called DICE certificate chain.
+pub struct OwnedDiceArtifacts {
+    /// CDI Values.
+    pub cdi_values: CdiValues,
+    /// Boot Certificate Chain.
+    pub bcc: Vec<u8>,
+}
+
 /// Retries the given function with bigger output buffer size.
 fn retry_with_bigger_buffer<F>(mut f: F) -> Result<Vec<u8>>
 where
@@ -62,3 +74,27 @@
         bcc_format_config_descriptor(name, version, resettable, buffer)
     })
 }
+
+/// Executes the main BCC flow.
+///
+/// Given a full set of input values along with the current BCC and CDI values,
+/// computes the next CDI values and matching updated BCC.
+pub fn retry_bcc_main_flow(
+    current_cdi_attest: &Cdi,
+    current_cdi_seal: &Cdi,
+    bcc: &[u8],
+    input_values: &InputValues,
+) -> Result<OwnedDiceArtifacts> {
+    let mut next_cdi_values = CdiValues::default();
+    let next_bcc = retry_with_bigger_buffer(|next_bcc| {
+        bcc_main_flow(
+            current_cdi_attest,
+            current_cdi_seal,
+            bcc,
+            input_values,
+            &mut next_cdi_values,
+            next_bcc,
+        )
+    })?;
+    Ok(OwnedDiceArtifacts { cdi_values: next_cdi_values, bcc: next_bcc })
+}
diff --git a/diced/open_dice_cbor/Android.bp b/diced/open_dice_cbor/Android.bp
index 61d4d50..e52af7d 100644
--- a/diced/open_dice_cbor/Android.bp
+++ b/diced/open_dice_cbor/Android.bp
@@ -25,11 +25,9 @@
         "libdiced_open_dice",
         // For ZVec
         "libkeystore2_crypto_rust",
-        "libopen_dice_bcc_bindgen",
         "libopen_dice_cbor_bindgen",
     ],
     static_libs: [
-        "libopen_dice_bcc",
         "libopen_dice_cbor",
     ],
     vendor_available: true,
@@ -49,12 +47,9 @@
         "libdiced_open_dice",
         "libdiced_sample_inputs",
         "libkeystore2_crypto_rust",
-        "libopen_dice_bcc_bindgen",
         "libopen_dice_cbor_bindgen",
-        "libthiserror",
     ],
     static_libs: [
-        "libopen_dice_bcc",
         "libopen_dice_cbor",
     ],
 }
diff --git a/diced/open_dice_cbor/lib.rs b/diced/open_dice_cbor/lib.rs
index 7b098a8..239bc18 100644
--- a/diced/open_dice_cbor/lib.rs
+++ b/diced/open_dice_cbor/lib.rs
@@ -32,12 +32,11 @@
 //! ```
 
 pub use diced_open_dice::{
-    check_result, derive_cdi_private_key_seed, hash, retry_bcc_format_config_descriptor, Config,
-    DiceError, Hash, Hidden, InputValues, Result, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE,
-    PRIVATE_KEY_SEED_SIZE,
+    check_result, derive_cdi_private_key_seed, hash, retry_bcc_format_config_descriptor,
+    retry_bcc_main_flow, Config, DiceError, Hash, Hidden, InputValues, OwnedDiceArtifacts, Result,
+    CDI_SIZE, HASH_SIZE, HIDDEN_SIZE, PRIVATE_KEY_SEED_SIZE,
 };
 use keystore2_crypto::ZVec;
-use open_dice_bcc_bindgen::BccMainFlow;
 pub use open_dice_cbor_bindgen::DiceMode;
 use open_dice_cbor_bindgen::{
     DiceGenerateCertificate, DiceKdf, DiceKeypairFromSeed, DiceMainFlow, DiceSign, DiceVerify,
@@ -363,62 +362,6 @@
         })?;
         Ok(cert)
     }
-
-    /// Safe wrapper around open-dice BccDiceMainFlow, see open dice
-    /// documentation for details.
-    /// Returns a tuple of:
-    ///  * The next attestation CDI,
-    ///  * the next seal CDI, and
-    ///  * the next bcc adding the new certificate to the given bcc.
-    /// `(next_attest_cdi, next_seal_cdi, next_bcc)`
-    fn bcc_main_flow(
-        &mut self,
-        current_cdi_attest: &[u8; CDI_SIZE],
-        current_cdi_seal: &[u8; CDI_SIZE],
-        bcc: &[u8],
-        input_values: &InputValues,
-    ) -> Result<(CdiAttest, CdiSeal, Bcc)> {
-        let mut next_attest = CdiAttest::new(CDI_SIZE)?;
-        let mut next_seal = CdiSeal::new(CDI_SIZE)?;
-
-        // SAFETY (BccMainFlow):
-        // * The first context argument may be NULL and is unused by the wrapped
-        //   implementation.
-        // * The second argument and the third argument are const arrays of size CDI_SIZE.
-        //   This is fulfilled as per the definition of the arguments `current_cdi_attest`
-        //   and `current_cdi_seal`.
-        // * The fourth argument and the fifth argument are the pointer to and size of the buffer
-        //   holding the current bcc.
-        // * The sixth argument is a pointer to `DiceInputValues` it, and its indirect
-        //   references must be valid for the duration of the function call.
-        // * The seventh argument and the eighth argument are the length of and the pointer to the
-        //   allocated certificate buffer respectively. They are used to return the generated
-        //   certificate.
-        // * The ninth argument is a pointer to a mutable usize object. It is
-        //   used to return the actual size of the output certificate.
-        // * The tenth argument and the eleventh argument are pointers to mutable buffers of
-        //   size CDI_SIZE. This is fulfilled if the allocation above succeeded.
-        // * No pointers are expected to be valid beyond the scope of the function
-        //   call.
-        let next_bcc = retry_while_adjusting_output_buffer(|next_bcc, actual_size| {
-            check_result(unsafe {
-                BccMainFlow(
-                    self.get_context(),
-                    current_cdi_attest.as_ptr(),
-                    current_cdi_seal.as_ptr(),
-                    bcc.as_ptr(),
-                    bcc.len(),
-                    input_values.as_ptr(),
-                    next_bcc.len(),
-                    next_bcc.as_mut_ptr(),
-                    actual_size as *mut _,
-                    next_attest.as_mut_ptr(),
-                    next_seal.as_mut_ptr(),
-                )
-            })
-        })?;
-        Ok((next_attest, next_seal, next_bcc))
-    }
 }
 
 #[cfg(test)]
@@ -627,10 +570,10 @@
     // and changes in any of those functions.
     #[test]
     fn main_flow_and_bcc_main_flow() {
-        let (cdi_attest, cdi_seal, bcc) = make_sample_bcc_and_cdis().unwrap();
-        assert_eq!(&cdi_attest[..], SAMPLE_CDI_ATTEST_TEST_VECTOR);
-        assert_eq!(&cdi_seal[..], SAMPLE_CDI_SEAL_TEST_VECTOR);
-        assert_eq!(&bcc[..], SAMPLE_BCC_TEST_VECTOR);
+        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);
     }
 
     static DERIVED_KEY_TEST_VECTOR: &[u8] = &[
diff --git a/diced/src/hal_node.rs b/diced/src/hal_node.rs
index 1efee8b..ca470e5 100644
--- a/diced/src/hal_node.rs
+++ b/diced/src/hal_node.rs
@@ -343,6 +343,16 @@
         bcc: Vec<u8>,
     }
 
+    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(),
+            }
+        }
+    }
+
     impl DiceArtifacts for InsecureSerializableArtifacts {
         fn cdi_attest(&self) -> &[u8; dice::CDI_SIZE] {
             &self.cdi_attest
@@ -394,10 +404,8 @@
     /// Test the resident artifact batched derivation in process.
     #[test]
     fn derive_with_resident_artifacts() -> Result<()> {
-        let (cdi_attest, cdi_seal, bcc) = diced_sample_inputs::make_sample_bcc_and_cdis()?;
-
-        let artifacts =
-            ResidentArtifacts::new(cdi_attest[..].try_into()?, cdi_seal[..].try_into()?, &bcc)?;
+        let artifacts: ResidentArtifacts =
+            diced_sample_inputs::make_sample_bcc_and_cdis()?.try_into()?;
 
         let input_values = &[
             make_input_values(
@@ -433,18 +441,13 @@
     /// the same test vector as the in process test above.
     #[test]
     fn derive_with_insecure_artifacts() -> Result<()> {
-        let (cdi_attest, cdi_seal, bcc) = diced_sample_inputs::make_sample_bcc_and_cdis()?;
+        let dice_artifacts = diced_sample_inputs::make_sample_bcc_and_cdis()?;
 
         // Safety: ResidentHal can only be used in single threaded environments.
         // On-device Rust tests run each test in a separate process.
-        let hal_impl = unsafe {
-            ResidentHal::new(InsecureSerializableArtifacts {
-                cdi_attest: cdi_attest[..].try_into()?,
-                cdi_seal: cdi_seal[..].try_into()?,
-                bcc,
-            })
-        }
-        .expect("Failed to create ResidentHal.");
+        let hal_impl =
+            unsafe { ResidentHal::new(InsecureSerializableArtifacts::from(dice_artifacts)) }
+                .expect("Failed to create ResidentHal.");
 
         let bcc_handover = hal_impl
             .derive(&[
@@ -474,18 +477,13 @@
     /// must yield the same outcome as three derivations with the same input values.
     #[test]
     fn demote() -> Result<()> {
-        let (cdi_attest, cdi_seal, bcc) = diced_sample_inputs::make_sample_bcc_and_cdis()?;
+        let dice_artifacts = diced_sample_inputs::make_sample_bcc_and_cdis()?;
 
         // Safety: ResidentHal can only be used in single threaded environments.
         // On-device Rust tests run each test in a separate process.
-        let hal_impl = unsafe {
-            ResidentHal::new(InsecureSerializableArtifacts {
-                cdi_attest: cdi_attest[..].try_into()?,
-                cdi_seal: cdi_seal[..].try_into()?,
-                bcc,
-            })
-        }
-        .expect("Failed to create ResidentHal.");
+        let hal_impl =
+            unsafe { ResidentHal::new(InsecureSerializableArtifacts::from(dice_artifacts)) }
+                .expect("Failed to create ResidentHal.");
 
         hal_impl
             .demote(&[
diff --git a/diced/src/resident_node.rs b/diced/src/resident_node.rs
index d65f30c..4d6a7bc 100644
--- a/diced/src/resident_node.rs
+++ b/diced/src/resident_node.rs
@@ -36,21 +36,6 @@
 }
 
 impl ResidentNode {
-    /// Creates a new Resident node with the given dice secrets and certificate chain.
-    pub fn new(
-        cdi_attest: &[u8; dice::CDI_SIZE],
-        cdi_seal: &[u8; dice::CDI_SIZE],
-        bcc: Vec<u8>,
-    ) -> Result<Self> {
-        Ok(ResidentNode {
-            artifacts: RwLock::new(
-                ResidentArtifacts::new(cdi_attest, cdi_seal, &bcc)
-                    .context("In ResidentNode::new: Trying to initialize ResidentArtifacts")?,
-            ),
-            demotion_db: Default::default(),
-        })
-    }
-
     fn get_effective_artifacts(
         &self,
         client: BinderInputValues,
diff --git a/diced/src/sample_inputs.rs b/diced/src/sample_inputs.rs
index 5b61fed..92bdf76 100644
--- a/diced/src/sample_inputs.rs
+++ b/diced/src/sample_inputs.rs
@@ -22,7 +22,6 @@
 use dice::ContextImpl;
 use diced_open_dice_cbor as dice;
 use diced_utils::{cbor, to_dice_input_values};
-use keystore2_crypto::ZVec;
 use std::convert::TryInto;
 use std::ffi::CStr;
 use std::io::Write;
@@ -66,7 +65,7 @@
 
 /// Derives a tuple of (CDI_ATTEST, CDI_SEAL, BCC) derived of the vector of input values returned
 /// by `get_input_values_vector`.
-pub fn make_sample_bcc_and_cdis() -> Result<(ZVec, ZVec, Vec<u8>)> {
+pub fn make_sample_bcc_and_cdis() -> Result<dice::OwnedDiceArtifacts> {
     let mut dice_ctx = dice::OpenDiceCborContext::new();
     let private_key_seed = dice::derive_cdi_private_key_seed(UDS)
         .context("In make_sample_bcc_and_cdis: Trying to derive private key seed.")?;
@@ -93,30 +92,24 @@
 
     bcc.append(&mut cert);
 
-    let (cdi_attest, cdi_seal, bcc) = dice_ctx
-        .bcc_main_flow(
-            &cdi_attest[..].try_into().context(
-                "In make_sample_bcc_and_cdis: Failed to convert cdi_attest to array reference. (1)",
-            )?,
-            &cdi_seal[..].try_into().context(
-                "In make_sample_bcc_and_cdis: Failed to convert cdi_seal to array reference. (1)",
-            )?,
-            &bcc,
-            &to_dice_input_values(&input_values_vector[1]),
-        )
-        .context("In make_sample_bcc_and_cdis: Trying to run first bcc main flow.")?;
-    dice_ctx
-        .bcc_main_flow(
-            &cdi_attest[..].try_into().context(
-                "In make_sample_bcc_and_cdis: Failed to convert cdi_attest to array reference. (2)",
-            )?,
-            &cdi_seal[..].try_into().context(
-                "In make_sample_bcc_and_cdis: Failed to convert cdi_seal to array reference. (2)",
-            )?,
-            &bcc,
-            &to_dice_input_values(&input_values_vector[2]),
-        )
-        .context("In make_sample_bcc_and_cdis: Trying to run second bcc main flow.")
+    let dice_artifacts = dice::retry_bcc_main_flow(
+        &cdi_attest[..].try_into().context(
+            "In make_sample_bcc_and_cdis: Failed to convert cdi_attest to array reference. (1)",
+        )?,
+        &cdi_seal[..].try_into().context(
+            "In make_sample_bcc_and_cdis: Failed to convert cdi_seal to array reference. (1)",
+        )?,
+        &bcc,
+        &to_dice_input_values(&input_values_vector[1]),
+    )
+    .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,
+        &to_dice_input_values(&input_values_vector[2]),
+    )
+    .context("In make_sample_bcc_and_cdis: Trying to run second bcc main flow.")
 }
 
 fn make_input_values(
diff --git a/diced/src/utils.rs b/diced/src/utils.rs
index 3d35ae5..c249366 100644
--- a/diced/src/utils.rs
+++ b/diced/src/utils.rs
@@ -19,7 +19,6 @@
     Mode::Mode as BinderMode,
 };
 use anyhow::{Context, Result};
-use dice::{ContextImpl, DiceMode};
 use diced_open_dice_cbor as dice;
 use keystore2_crypto::ZVec;
 use std::convert::TryInto;
@@ -38,13 +37,13 @@
     )
 }
 
-fn to_dice_mode(binder_mode: BinderMode) -> DiceMode {
+fn to_dice_mode(binder_mode: BinderMode) -> dice::DiceMode {
     match binder_mode {
-        BinderMode::NOT_INITIALIZED => DiceMode::kDiceModeNotInitialized,
-        BinderMode::NORMAL => DiceMode::kDiceModeNormal,
-        BinderMode::DEBUG => DiceMode::kDiceModeDebug,
-        BinderMode::RECOVERY => DiceMode::kDiceModeMaintenance,
-        _ => DiceMode::kDiceModeNotInitialized,
+        BinderMode::NOT_INITIALIZED => dice::DiceMode::kDiceModeNotInitialized,
+        BinderMode::NORMAL => dice::DiceMode::kDiceModeNormal,
+        BinderMode::DEBUG => dice::DiceMode::kDiceModeDebug,
+        BinderMode::RECOVERY => dice::DiceMode::kDiceModeMaintenance,
+        _ => dice::DiceMode::kDiceModeNotInitialized,
     }
 }
 
@@ -68,6 +67,18 @@
     bcc: Vec<u8>,
 }
 
+impl TryFrom<dice::OwnedDiceArtifacts> for ResidentArtifacts {
+    type Error = anyhow::Error;
+
+    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(),
+        })
+    }
+}
+
 impl ResidentArtifacts {
     /// Create a ResidentArtifacts object. The parameters ensure that the stored secrets
     /// can only have the appropriate size, so that subsequent casts to array references
@@ -125,19 +136,18 @@
     fn execute_step(self, input_values: &BinderInputValues) -> Result<Self> {
         let ResidentArtifacts { cdi_attest, cdi_seal, bcc } = self;
 
-        let (cdi_attest, cdi_seal, bcc) = dice::OpenDiceCborContext::new()
-            .bcc_main_flow(
-                cdi_attest[..].try_into().with_context(|| {
-                    format!("Trying to convert cdi_attest. (length: {})", cdi_attest.len())
-                })?,
-                cdi_seal[..].try_into().with_context(|| {
-                    format!("Trying to convert cdi_seal. (length: {})", cdi_seal.len())
-                })?,
-                &bcc,
-                &to_dice_input_values(input_values),
-            )
-            .context("In ResidentArtifacts::execute_step:")?;
-        Ok(ResidentArtifacts { cdi_attest, cdi_seal, bcc })
+        dice::retry_bcc_main_flow(
+            cdi_attest[..].try_into().with_context(|| {
+                format!("Trying to convert cdi_attest. (length: {})", cdi_attest.len())
+            })?,
+            cdi_seal[..].try_into().with_context(|| {
+                format!("Trying to convert cdi_seal. (length: {})", cdi_seal.len())
+            })?,
+            &bcc,
+            &to_dice_input_values(input_values),
+        )
+        .context("In ResidentArtifacts::execute_step:")?
+        .try_into()
     }
 
     /// Iterate through the iterator of dice input values performing one