Merge "Update needed for Rust v1.73.0" into main
diff --git a/diced/OWNERS b/diced/OWNERS
deleted file mode 100644
index 387cd93..0000000
--- a/diced/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-alanstokes@google.com
-aliceywang@google.com
-ascull@google.com
diff --git a/diced/TEST_MAPPING b/diced/TEST_MAPPING
deleted file mode 100644
index 7628d25..0000000
--- a/diced/TEST_MAPPING
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "libdiced_open_dice.integration_test"
-    },
-    {
-      "name": "libdiced_open_dice_nostd.integration_test"
-    },
-    {
-      "name": "libopen_dice_cbor_bindgen_test"
-    },
-    {
-      "name": "libopen_dice_android_bindgen_test"
-    },
-    {
-      "name": "libdiced_sample_inputs.integration_test"
-    }
-  ],
-  "postsubmit": [
-    {
-      "name": "libdiced_sample_inputs_nostd.integration_test"
-    }
-  ]
-}
diff --git a/diced/open_dice/Android.bp b/diced/open_dice/Android.bp
deleted file mode 100644
index 745b86e..0000000
--- a/diced/open_dice/Android.bp
+++ /dev/null
@@ -1,260 +0,0 @@
-package {
-    default_visibility: [":__subpackages__"],
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-rust_defaults {
-    name: "libdiced_open_dice_defaults",
-    crate_name: "diced_open_dice",
-    srcs: ["src/lib.rs"],
-}
-
-rust_library_rlib {
-    name: "libdiced_open_dice_nostd",
-    defaults: ["libdiced_open_dice_defaults"],
-    rustlibs: [
-        "libopen_dice_android_bindgen_nostd",
-        "libopen_dice_cbor_bindgen_nostd",
-        "libzeroize_nostd",
-    ],
-    features: [
-        "alloc",
-    ],
-    whole_static_libs: [
-        "libopen_dice_cbor",
-        "libcrypto_baremetal",
-    ],
-    visibility: [
-        "//packages/modules/Virtualization:__subpackages__",
-        "//system/security/diced/sample_inputs",
-    ],
-}
-
-rust_library {
-    name: "libdiced_open_dice",
-    defaults: ["libdiced_open_dice_defaults"],
-    vendor_available: true,
-    rustlibs: [
-        "libopen_dice_android_bindgen",
-        "libopen_dice_cbor_bindgen",
-        "libzeroize",
-    ],
-    features: [
-        "alloc",
-        "std",
-    ],
-    shared_libs: [
-        "libcrypto",
-    ],
-    static_libs: [
-        "libopen_dice_cbor",
-    ],
-    whole_static_libs: [
-        "libopen_dice_android",
-    ],
-    visibility: [
-        "//system/security/diced:__subpackages__",
-        "//packages/modules/Virtualization:__subpackages__",
-        "//hardware/interfaces/security/dice/aidl:__subpackages__",
-    ],
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.virt",
-    ],
-}
-
-rust_defaults {
-    name: "libdiced_open_dice_test_defaults",
-    crate_name: "diced_open_dice_test",
-    srcs: ["tests/*.rs"],
-    test_suites: ["general-tests"],
-}
-
-rust_test {
-    name: "libdiced_open_dice.integration_test",
-    defaults: ["libdiced_open_dice_test_defaults"],
-    rustlibs: [
-        "libdiced_open_dice",
-    ],
-}
-
-rust_test {
-    name: "libdiced_open_dice_nostd.integration_test",
-    defaults: ["libdiced_open_dice_test_defaults"],
-    rustlibs: [
-        "libdiced_open_dice_nostd",
-    ],
-}
-
-rust_defaults {
-    name: "libopen_dice_bindgen_nostd.rust_defaults",
-    bindgen_flags: [
-        "--use-core",
-        "--ctypes-prefix=core::ffi",
-        "--raw-line=#![no_std]",
-    ],
-    no_stdlibs: true,
-    prefer_rlib: true,
-    stdlibs: [
-        "libcore.rust_sysroot",
-        "libcompiler_builtins.rust_sysroot",
-    ],
-    target: {
-        musl: {
-            enabled: false,
-        },
-        glibc: {
-            enabled: false,
-        },
-        darwin: {
-            enabled: false,
-        },
-    },
-}
-
-rust_defaults {
-    name: "libopen_dice.rust_defaults",
-    host_supported: true,
-    vendor_available: true,
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.compos",
-        "com.android.virt",
-    ],
-}
-
-rust_defaults {
-    name: "libopen_dice_cbor_bindgen.rust_defaults",
-    wrapper_src: "bindgen/dice.h",
-    crate_name: "open_dice_cbor_bindgen",
-    source_stem: "bindings",
-    bindgen_flags: [
-        "--rustified-enum DiceConfigType",
-        "--rustified-enum DiceMode",
-        "--rustified-enum DiceResult",
-
-        // By generating only essential functions, we can make bindings concise and
-        // optimize compilation time.
-        "--allowlist-function=DiceDeriveCdiPrivateKeySeed",
-        "--allowlist-function=DiceDeriveCdiCertificateId",
-        "--allowlist-function=DiceMainFlow",
-        "--allowlist-function=DiceHash",
-        "--allowlist-function=DiceKdf",
-        "--allowlist-function=DiceKeypairFromSeed",
-        "--allowlist-function=DiceSign",
-        "--allowlist-function=DiceVerify",
-        "--allowlist-function=DiceGenerateCertificate",
-
-        // We also need some constants in addition to the functions.
-        "--allowlist-var=DICE_CDI_SIZE",
-        "--allowlist-var=DICE_HASH_SIZE",
-        "--allowlist-var=DICE_HIDDEN_SIZE",
-        "--allowlist-var=DICE_INLINE_CONFIG_SIZE",
-        "--allowlist-var=DICE_PRIVATE_KEY_SEED_SIZE",
-        "--allowlist-var=DICE_ID_SIZE",
-        "--allowlist-var=DICE_PUBLIC_KEY_SIZE",
-        "--allowlist-var=DICE_PRIVATE_KEY_SIZE",
-        "--allowlist-var=DICE_SIGNATURE_SIZE",
-    ],
-}
-
-rust_bindgen {
-    name: "libopen_dice_cbor_bindgen",
-    defaults: [
-        "libopen_dice.rust_defaults",
-        "libopen_dice_cbor_bindgen.rust_defaults",
-    ],
-    whole_static_libs: ["libopen_dice_cbor"],
-}
-
-rust_bindgen {
-    name: "libopen_dice_cbor_bindgen_nostd",
-    defaults: [
-        "libopen_dice_cbor_bindgen.rust_defaults",
-        "libopen_dice_bindgen_nostd.rust_defaults",
-    ],
-    whole_static_libs: ["libopen_dice_cbor_baremetal"],
-}
-
-rust_defaults {
-    name: "libopen_dice_android_bindgen.rust_defaults",
-    wrapper_src: "bindgen/android.h",
-    crate_name: "open_dice_android_bindgen",
-    source_stem: "bindings",
-    bindgen_flags: [
-        // By generating only essential functions, we can make bindings concise and
-        // optimize compilation time.
-        "--allowlist-function=DiceAndroidFormatConfigDescriptor",
-        "--allowlist-function=DiceAndroidMainFlow",
-        "--allowlist-function=DiceAndroidHandoverMainFlow",
-        "--allowlist-function=DiceAndroidHandoverParse",
-
-        // We also need some constants in addition to the functions.
-        "--allowlist-var=DICE_ANDROID_CONFIG_.*",
-
-        // Prevent DiceInputValues from being generated a second time and
-        // import it instead from open_dice_cbor_bindgen.
-        "--blocklist-type=DiceInputValues_",
-        "--blocklist-type=DiceInputValues",
-        "--raw-line",
-        "pub use open_dice_cbor_bindgen::DiceInputValues;",
-
-        // Prevent DiceResult from being generated a second time and
-        // import it instead from open_dice_cbor_bindgen.
-        "--blocklist-type=DiceResult",
-        "--raw-line",
-        "pub use open_dice_cbor_bindgen::DiceResult;",
-    ],
-
-}
-
-rust_bindgen {
-    name: "libopen_dice_android_bindgen",
-    defaults: [
-        "libopen_dice.rust_defaults",
-        "libopen_dice_android_bindgen.rust_defaults",
-    ],
-    rustlibs: [
-        "libopen_dice_cbor_bindgen",
-    ],
-    whole_static_libs: ["libopen_dice_android"],
-}
-
-rust_bindgen {
-    name: "libopen_dice_android_bindgen_nostd",
-    defaults: [
-        "libopen_dice_android_bindgen.rust_defaults",
-        "libopen_dice_bindgen_nostd.rust_defaults",
-    ],
-    rustlibs: [
-        "libopen_dice_cbor_bindgen_nostd",
-    ],
-    whole_static_libs: ["libopen_dice_android_baremetal"],
-}
-
-rust_test {
-    name: "libopen_dice_cbor_bindgen_test",
-    srcs: [
-        ":libopen_dice_cbor_bindgen",
-    ],
-    crate_name: "open_dice_cbor_bindgen_test",
-    test_suites: ["general-tests"],
-    auto_gen_config: true,
-    clippy_lints: "none",
-    lints: "none",
-}
-
-rust_test {
-    name: "libopen_dice_android_bindgen_test",
-    srcs: [
-        ":libopen_dice_android_bindgen",
-    ],
-    crate_name: "open_dice_android_bindgen_test",
-    rustlibs: [
-        "libopen_dice_cbor_bindgen",
-    ],
-    test_suites: ["general-tests"],
-    auto_gen_config: true,
-    clippy_lints: "none",
-    lints: "none",
-}
diff --git a/diced/open_dice/bindgen/android.h b/diced/open_dice/bindgen/android.h
deleted file mode 100644
index 18f6476..0000000
--- a/diced/open_dice/bindgen/android.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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
-//
-//     https://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.
-
-#pragma once
-
-#include <dice/android.h>
diff --git a/diced/open_dice/bindgen/dice.h b/diced/open_dice/bindgen/dice.h
deleted file mode 100644
index 47fe911..0000000
--- a/diced/open_dice/bindgen/dice.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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
-//
-//     https://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.
-
-#pragma once
-
-#include <dice/dice.h>
-#include <dice/ops.h>
diff --git a/diced/open_dice/src/bcc.rs b/diced/open_dice/src/bcc.rs
deleted file mode 100644
index 199e1a9..0000000
--- a/diced/open_dice/src/bcc.rs
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2023, 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.
-
-//! This module mirrors the content in open-dice/include/dice/android.h
-
-use crate::dice::{Cdi, CdiValues, DiceArtifacts, InputValues, CDI_SIZE};
-use crate::error::{check_result, DiceError, Result};
-use open_dice_android_bindgen::{
-    DiceAndroidConfigValues, DiceAndroidFormatConfigDescriptor, DiceAndroidHandoverMainFlow,
-    DiceAndroidHandoverParse, DiceAndroidMainFlow, DICE_ANDROID_CONFIG_COMPONENT_NAME,
-    DICE_ANDROID_CONFIG_COMPONENT_VERSION, DICE_ANDROID_CONFIG_RESETTABLE,
-    DICE_ANDROID_CONFIG_SECURITY_VERSION,
-};
-use std::{ffi::CStr, ptr};
-
-/// Contains the input values used to construct the Android Profile for DICE
-/// configuration descriptor.
-#[derive(Default, Debug)]
-pub struct DiceConfigValues<'a> {
-    /// Name of the component.
-    pub component_name: Option<&'a CStr>,
-    /// Version of the component.
-    pub component_version: Option<u64>,
-    /// Whether the key changes on factory reset.
-    pub resettable: bool,
-    /// Monotonically increasing version of the component.
-    pub security_version: Option<u64>,
-}
-
-/// Formats a configuration descriptor following the Android Profile for DICE specification.
-/// See https://pigweed.googlesource.com/open-dice/+/refs/heads/main/docs/android.md.
-pub fn bcc_format_config_descriptor(values: &DiceConfigValues, buffer: &mut [u8]) -> Result<usize> {
-    let mut configs = 0;
-
-    let component_name = values.component_name.map_or(ptr::null(), |name| {
-        configs |= DICE_ANDROID_CONFIG_COMPONENT_NAME;
-        name.as_ptr()
-    });
-    let component_version = values.component_version.map_or(0, |version| {
-        configs |= DICE_ANDROID_CONFIG_COMPONENT_VERSION;
-        version
-    });
-    if values.resettable {
-        configs |= DICE_ANDROID_CONFIG_RESETTABLE;
-    }
-    let security_version = values.security_version.map_or(0, |version| {
-        configs |= DICE_ANDROID_CONFIG_SECURITY_VERSION;
-        version
-    });
-
-    let values =
-        DiceAndroidConfigValues { configs, component_name, component_version, security_version };
-
-    let mut buffer_size = 0;
-    check_result(
-        // SAFETY: The function writes to the buffer, within the given bounds, and only reads the
-        // input values. It writes its result to buffer_size.
-        unsafe {
-            DiceAndroidFormatConfigDescriptor(
-                &values,
-                buffer.len(),
-                buffer.as_mut_ptr(),
-                &mut buffer_size,
-            )
-        },
-        buffer_size,
-    )?;
-    Ok(buffer_size)
-}
-
-/// Executes the main Android DICE flow.
-///
-/// Given a full set of input values along with the current DICE chain and CDI values,
-/// computes the next CDI values and matching updated DICE chain.
-pub fn bcc_main_flow(
-    current_cdi_attest: &Cdi,
-    current_cdi_seal: &Cdi,
-    current_chain: &[u8],
-    input_values: &InputValues,
-    next_cdi_values: &mut CdiValues,
-    next_chain: &mut [u8],
-) -> Result<usize> {
-    let mut next_chain_size = 0;
-    check_result(
-        // SAFETY: `DiceAndroidMainFlow` only reads the `current_chain` and CDI values and writes
-        // to `next_chain` 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.
-        unsafe {
-            DiceAndroidMainFlow(
-                ptr::null_mut(), // context
-                current_cdi_attest.as_ptr(),
-                current_cdi_seal.as_ptr(),
-                current_chain.as_ptr(),
-                current_chain.len(),
-                input_values.as_ptr(),
-                next_chain.len(),
-                next_chain.as_mut_ptr(),
-                &mut next_chain_size,
-                next_cdi_values.cdi_attest.as_mut_ptr(),
-                next_cdi_values.cdi_seal.as_mut_ptr(),
-            )
-        },
-        next_chain_size,
-    )?;
-    Ok(next_chain_size)
-}
-
-/// Executes the main Android DICE handover flow.
-///
-/// A handover combines the DICE chain and CDIs in a single CBOR object.
-/// This function takes the current boot stage's handover bundle and produces a
-/// bundle for the next stage.
-pub fn bcc_handover_main_flow(
-    current_handover: &[u8],
-    input_values: &InputValues,
-    next_handover: &mut [u8],
-) -> Result<usize> {
-    let mut next_handover_size = 0;
-    check_result(
-        // SAFETY: The function only reads `current_handover` and writes to `next_handover`
-        // 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.
-        unsafe {
-            DiceAndroidHandoverMainFlow(
-                ptr::null_mut(), // context
-                current_handover.as_ptr(),
-                current_handover.len(),
-                input_values.as_ptr(),
-                next_handover.len(),
-                next_handover.as_mut_ptr(),
-                &mut next_handover_size,
-            )
-        },
-        next_handover_size,
-    )?;
-
-    Ok(next_handover_size)
-}
-
-/// An Android DICE handover object combines the DICE chain and CDIs in a single CBOR object.
-/// This struct is used as return of the function `android_dice_handover_parse`, its lifetime is
-/// tied to the lifetime of the raw handover slice.
-#[derive(Debug)]
-pub struct BccHandover<'a> {
-    /// Attestation CDI.
-    cdi_attest: &'a [u8; CDI_SIZE],
-    /// Sealing CDI.
-    cdi_seal: &'a [u8; CDI_SIZE],
-    /// DICE chain.
-    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
-    }
-}
-
-/// This function parses the `handover` to extracts the DICE chain and CDIs.
-/// The lifetime of the returned `DiceAndroidHandover` is tied to the given `handover` slice.
-pub fn bcc_handover_parse(handover: &[u8]) -> Result<BccHandover> {
-    let mut cdi_attest: *const u8 = ptr::null();
-    let mut cdi_seal: *const u8 = ptr::null();
-    let mut chain: *const u8 = ptr::null();
-    let mut chain_size = 0;
-    check_result(
-        // SAFETY: The `handover` is only read and never stored and the returned pointers should
-        // all point within the address range of the `handover` or be NULL.
-        unsafe {
-            DiceAndroidHandoverParse(
-                handover.as_ptr(),
-                handover.len(),
-                &mut cdi_attest,
-                &mut cdi_seal,
-                &mut chain,
-                &mut chain_size,
-            )
-        },
-        chain_size,
-    )?;
-    let cdi_attest = sub_slice(handover, cdi_attest, CDI_SIZE)?;
-    let cdi_seal = sub_slice(handover, cdi_seal, CDI_SIZE)?;
-    let bcc = sub_slice(handover, chain, chain_size).ok();
-    Ok(BccHandover {
-        cdi_attest: cdi_attest.try_into().map_err(|_| DiceError::PlatformError)?,
-        cdi_seal: cdi_seal.try_into().map_err(|_| DiceError::PlatformError)?,
-        bcc,
-    })
-}
-
-/// Gets a slice the `addr` points to and of length `len`.
-/// The slice should be contained in the buffer.
-fn sub_slice(buffer: &[u8], addr: *const u8, len: usize) -> Result<&[u8]> {
-    if addr.is_null() || !buffer.as_ptr_range().contains(&addr) {
-        return Err(DiceError::PlatformError);
-    }
-    // SAFETY: This is safe because addr is not null and is within the range of the buffer.
-    let start: usize = unsafe {
-        addr.offset_from(buffer.as_ptr()).try_into().map_err(|_| DiceError::PlatformError)?
-    };
-    start.checked_add(len).and_then(|end| buffer.get(start..end)).ok_or(DiceError::PlatformError)
-}
diff --git a/diced/open_dice/src/dice.rs b/diced/open_dice/src/dice.rs
deleted file mode 100644
index e42e373..0000000
--- a/diced/open_dice/src/dice.rs
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2023, 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.
-
-//! Structs and functions about the types used in DICE.
-//! This module mirrors the content in open-dice/include/dice/dice.h
-
-use crate::error::{check_result, Result};
-pub use open_dice_cbor_bindgen::DiceMode;
-use open_dice_cbor_bindgen::{
-    DiceConfigType, DiceDeriveCdiCertificateId, DiceDeriveCdiPrivateKeySeed, DiceInputValues,
-    DiceMainFlow, DICE_CDI_SIZE, DICE_HASH_SIZE, DICE_HIDDEN_SIZE, DICE_ID_SIZE,
-    DICE_INLINE_CONFIG_SIZE, DICE_PRIVATE_KEY_SEED_SIZE, DICE_PRIVATE_KEY_SIZE,
-    DICE_PUBLIC_KEY_SIZE, DICE_SIGNATURE_SIZE,
-};
-use std::{marker::PhantomData, ptr};
-use zeroize::{Zeroize, ZeroizeOnDrop};
-
-/// The size of a DICE hash.
-pub const HASH_SIZE: usize = DICE_HASH_SIZE as usize;
-/// The size of the DICE hidden value.
-pub const HIDDEN_SIZE: usize = DICE_HIDDEN_SIZE as usize;
-/// The size of a DICE inline config.
-const INLINE_CONFIG_SIZE: usize = DICE_INLINE_CONFIG_SIZE as usize;
-/// The size of a CDI.
-pub const CDI_SIZE: usize = DICE_CDI_SIZE as usize;
-/// The size of a private key seed.
-pub const PRIVATE_KEY_SEED_SIZE: usize = DICE_PRIVATE_KEY_SEED_SIZE as usize;
-/// The size of a private key.
-pub const PRIVATE_KEY_SIZE: usize = DICE_PRIVATE_KEY_SIZE as usize;
-/// The size of a public key.
-pub const PUBLIC_KEY_SIZE: usize = DICE_PUBLIC_KEY_SIZE as usize;
-/// The size of a signature.
-pub const SIGNATURE_SIZE: usize = DICE_SIGNATURE_SIZE as usize;
-/// The size of an ID.
-pub const ID_SIZE: usize = DICE_ID_SIZE as usize;
-
-/// Array type of hashes used by DICE.
-pub type Hash = [u8; HASH_SIZE];
-/// Array type of additional input.
-pub type Hidden = [u8; HIDDEN_SIZE];
-/// Array type of inline configuration values.
-pub type InlineConfig = [u8; INLINE_CONFIG_SIZE];
-/// Array type of CDIs.
-pub type Cdi = [u8; CDI_SIZE];
-/// Array type of the public key.
-pub type PublicKey = [u8; PUBLIC_KEY_SIZE];
-/// Array type of the signature.
-pub type Signature = [u8; SIGNATURE_SIZE];
-/// 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]>;
-}
-
-/// TODO(b/268587826): Clean up the memory cache after zeroing out the memory
-/// for sensitive data like CDI values and private key.
-/// CDI Values.
-#[derive(Debug, Zeroize, ZeroizeOnDrop, Default)]
-pub struct CdiValues {
-    /// Attestation CDI.
-    pub cdi_attest: [u8; CDI_SIZE],
-    /// Sealing CDI.
-    pub cdi_seal: [u8; CDI_SIZE],
-}
-
-/// Private key seed. The data is zeroed out when the struct is dropped.
-#[derive(Zeroize, ZeroizeOnDrop, Default)]
-pub struct PrivateKeySeed([u8; PRIVATE_KEY_SEED_SIZE]);
-
-impl PrivateKeySeed {
-    /// Returns an array reference of the private key seed.
-    pub fn as_array(&self) -> &[u8; PRIVATE_KEY_SEED_SIZE] {
-        &self.0
-    }
-
-    /// Returns a mutable pointer to the slice buffer of the private key seed.
-    pub fn as_mut_ptr(&mut self) -> *mut u8 {
-        self.0.as_mut_ptr()
-    }
-}
-
-/// Private key. The data is zeroed out when the struct is dropped.
-#[derive(Zeroize, ZeroizeOnDrop)]
-pub struct PrivateKey([u8; PRIVATE_KEY_SIZE]);
-
-impl Default for PrivateKey {
-    /// Creates a new `PrivateKey` instance with all bytes set to 0.
-    ///
-    /// Since the size of the private key array is too large to be initialized
-    /// with a default value, this implementation sets all the bytes in the array
-    /// to 0 using the `[0u8; PRIVATE_KEY_SIZE]` syntax.
-    fn default() -> Self {
-        Self([0u8; PRIVATE_KEY_SIZE])
-    }
-}
-
-impl PrivateKey {
-    /// Returns an array reference of the private key.
-    pub fn as_array(&self) -> &[u8; PRIVATE_KEY_SIZE] {
-        &self.0
-    }
-
-    /// Returns a mutable pointer to the slice buffer of the private key.
-    pub fn as_mut_ptr(&mut self) -> *mut u8 {
-        self.0.as_mut_ptr()
-    }
-}
-
-/// Configuration descriptor for DICE input values.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum Config<'a> {
-    /// Reference to an inline descriptor.
-    Inline(&'a InlineConfig),
-    /// Reference to a free form descriptor that will be hashed by the implementation.
-    Descriptor(&'a [u8]),
-}
-
-impl Config<'_> {
-    fn dice_config_type(&self) -> DiceConfigType {
-        match self {
-            Self::Inline(_) => DiceConfigType::kDiceConfigTypeInline,
-            Self::Descriptor(_) => DiceConfigType::kDiceConfigTypeDescriptor,
-        }
-    }
-
-    fn inline_config(&self) -> InlineConfig {
-        match self {
-            Self::Inline(inline) => **inline,
-            Self::Descriptor(_) => [0u8; INLINE_CONFIG_SIZE],
-        }
-    }
-
-    fn descriptor_ptr(&self) -> *const u8 {
-        match self {
-            Self::Descriptor(descriptor) => descriptor.as_ptr(),
-            _ => ptr::null(),
-        }
-    }
-
-    fn descriptor_size(&self) -> usize {
-        match self {
-            Self::Descriptor(descriptor) => descriptor.len(),
-            _ => 0,
-        }
-    }
-}
-
-/// Wrap of `DiceInputValues`.
-#[derive(Clone, Debug)]
-pub struct InputValues<'a> {
-    dice_inputs: DiceInputValues,
-    // DiceInputValues contains a pointer to the separate config descriptor, which must therefore
-    // outlive it. Make sure the borrow checker can enforce that.
-    config_descriptor: PhantomData<&'a [u8]>,
-}
-
-impl<'a> InputValues<'a> {
-    /// Creates a new `InputValues`.
-    pub fn new(
-        code_hash: Hash,
-        config: Config<'a>,
-        authority_hash: Hash,
-        mode: DiceMode,
-        hidden: Hidden,
-    ) -> Self {
-        Self {
-            dice_inputs: DiceInputValues {
-                code_hash,
-                code_descriptor: ptr::null(),
-                code_descriptor_size: 0,
-                config_type: config.dice_config_type(),
-                config_value: config.inline_config(),
-                config_descriptor: config.descriptor_ptr(),
-                config_descriptor_size: config.descriptor_size(),
-                authority_hash,
-                authority_descriptor: ptr::null(),
-                authority_descriptor_size: 0,
-                mode,
-                hidden,
-            },
-            config_descriptor: PhantomData,
-        }
-    }
-
-    /// Returns a raw pointer to the wrapped `DiceInputValues`.
-    pub fn as_ptr(&self) -> *const DiceInputValues {
-        &self.dice_inputs as *const DiceInputValues
-    }
-}
-
-/// Derives a CDI private key seed from a `cdi_attest` value.
-pub fn derive_cdi_private_key_seed(cdi_attest: &Cdi) -> Result<PrivateKeySeed> {
-    let mut seed = PrivateKeySeed::default();
-    check_result(
-        // SAFETY: The function writes to the buffer within the given bounds, and only reads the
-        // input values. The first argument context is not used in this function.
-        unsafe {
-            DiceDeriveCdiPrivateKeySeed(
-                ptr::null_mut(), // context
-                cdi_attest.as_ptr(),
-                seed.as_mut_ptr(),
-            )
-        },
-        seed.0.len(),
-    )?;
-    Ok(seed)
-}
-
-/// Derives an ID from the given `cdi_public_key` value.
-pub fn derive_cdi_certificate_id(cdi_public_key: &[u8]) -> Result<DiceId> {
-    let mut id = [0u8; ID_SIZE];
-    check_result(
-        // SAFETY: The function writes to the buffer within the given bounds, and only reads the
-        // input values. The first argument context is not used in this function.
-        unsafe {
-            DiceDeriveCdiCertificateId(
-                ptr::null_mut(), // context
-                cdi_public_key.as_ptr(),
-                cdi_public_key.len(),
-                id.as_mut_ptr(),
-            )
-        },
-        id.len(),
-    )?;
-    Ok(id)
-}
-
-/// Executes the main DICE flow.
-///
-/// Given a full set of input values and the current CDI values, computes the
-/// next CDI values and a matching certificate.
-/// Returns the actual size of the next CDI certificate.
-pub fn dice_main_flow(
-    current_cdi_attest: &Cdi,
-    current_cdi_seal: &Cdi,
-    input_values: &InputValues,
-    next_cdi_certificate: &mut [u8],
-    next_cdi_values: &mut CdiValues,
-) -> Result<usize> {
-    let mut next_cdi_certificate_actual_size = 0;
-    check_result(
-        // SAFETY: The function only reads the current CDI values and inputs and writes
-        // to `next_cdi_certificate` and next CDI values within its bounds.
-        // The first argument can be null and is not used in the current implementation.
-        unsafe {
-            DiceMainFlow(
-                ptr::null_mut(), // context
-                current_cdi_attest.as_ptr(),
-                current_cdi_seal.as_ptr(),
-                input_values.as_ptr(),
-                next_cdi_certificate.len(),
-                next_cdi_certificate.as_mut_ptr(),
-                &mut next_cdi_certificate_actual_size,
-                next_cdi_values.cdi_attest.as_mut_ptr(),
-                next_cdi_values.cdi_seal.as_mut_ptr(),
-            )
-        },
-        next_cdi_certificate_actual_size,
-    )?;
-    Ok(next_cdi_certificate_actual_size)
-}
diff --git a/diced/open_dice/src/error.rs b/diced/open_dice/src/error.rs
deleted file mode 100644
index 53ffd2d..0000000
--- a/diced/open_dice/src/error.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2023, 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.
-
-//! Errors and relating functions thrown in this library.
-
-use open_dice_cbor_bindgen::DiceResult;
-use std::{fmt, result};
-
-#[cfg(feature = "std")]
-use std::error::Error;
-
-/// Error type used by DICE.
-#[derive(Debug)]
-pub enum DiceError {
-    /// Provided input was invalid.
-    InvalidInput,
-    /// Provided buffer was too small.
-    BufferTooSmall(usize),
-    /// Platform error.
-    PlatformError,
-}
-
-/// This makes `DiceError` accepted by anyhow.
-#[cfg(feature = "std")]
-impl Error for DiceError {}
-
-impl fmt::Display for DiceError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match self {
-            Self::InvalidInput => write!(f, "invalid input"),
-            Self::BufferTooSmall(buffer_required_size) => {
-                write!(f, "buffer too small. Required {buffer_required_size} bytes.")
-            }
-            Self::PlatformError => write!(f, "platform error"),
-        }
-    }
-}
-
-/// DICE result type.
-pub type Result<T> = result::Result<T, DiceError>;
-
-/// Checks the given `DiceResult`. Returns an error if it's not OK.
-pub(crate) fn check_result(result: DiceResult, buffer_required_size: usize) -> Result<()> {
-    match result {
-        DiceResult::kDiceResultOk => Ok(()),
-        DiceResult::kDiceResultInvalidInput => Err(DiceError::InvalidInput),
-        DiceResult::kDiceResultBufferTooSmall => {
-            Err(DiceError::BufferTooSmall(buffer_required_size))
-        }
-        DiceResult::kDiceResultPlatformError => Err(DiceError::PlatformError),
-    }
-}
diff --git a/diced/open_dice/src/lib.rs b/diced/open_dice/src/lib.rs
deleted file mode 100644
index d0004b1..0000000
--- a/diced/open_dice/src/lib.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2023, 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.
-
-//! Implements safe wrappers around the public API of libopen-dice for
-//! both std and nostd usages.
-
-#![cfg_attr(not(feature = "std"), no_std)]
-
-#[cfg(feature = "alloc")]
-extern crate alloc;
-
-#[cfg(not(feature = "std"))]
-extern crate core as std;
-
-mod bcc;
-mod dice;
-mod error;
-mod ops;
-#[cfg(feature = "alloc")]
-mod retry;
-
-pub use bcc::{
-    bcc_format_config_descriptor, bcc_handover_main_flow, bcc_handover_parse, bcc_main_flow,
-    BccHandover, DiceConfigValues,
-};
-pub use dice::{
-    derive_cdi_certificate_id, derive_cdi_private_key_seed, dice_main_flow, Cdi, CdiValues, Config,
-    DiceArtifacts, DiceMode, Hash, Hidden, InlineConfig, InputValues, PrivateKey, PrivateKeySeed,
-    PublicKey, Signature, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
-};
-pub use error::{DiceError, Result};
-pub use ops::{
-    derive_cdi_leaf_priv, generate_certificate, hash, kdf, keypair_from_seed, sign, verify,
-};
-#[cfg(feature = "alloc")]
-pub use retry::{
-    retry_bcc_format_config_descriptor, retry_bcc_main_flow, retry_dice_main_flow,
-    retry_generate_certificate, OwnedDiceArtifacts,
-};
diff --git a/diced/open_dice/src/ops.rs b/diced/open_dice/src/ops.rs
deleted file mode 100644
index fe981df..0000000
--- a/diced/open_dice/src/ops.rs
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2023, 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.
-
-//! This module mirrors the content in open-dice/include/dice/ops.h
-//! It contains the set of functions that implement various operations that the
-//! main DICE functions depend on.
-
-use crate::dice::{
-    derive_cdi_private_key_seed, DiceArtifacts, Hash, InputValues, PrivateKey, PublicKey,
-    Signature, HASH_SIZE, PRIVATE_KEY_SEED_SIZE, PRIVATE_KEY_SIZE, PUBLIC_KEY_SIZE, SIGNATURE_SIZE,
-};
-use crate::error::{check_result, Result};
-use open_dice_cbor_bindgen::{
-    DiceGenerateCertificate, DiceHash, DiceKdf, DiceKeypairFromSeed, DiceSign, DiceVerify,
-};
-use std::ptr;
-
-/// Hashes the provided input using DICE's hash function `DiceHash`.
-pub fn hash(input: &[u8]) -> Result<Hash> {
-    let mut output: Hash = [0; HASH_SIZE];
-    check_result(
-        // SAFETY: DiceHash takes a sized input buffer and writes to a constant-sized output buffer.
-        // The first argument context is not used in this function.
-        unsafe {
-            DiceHash(
-                ptr::null_mut(), // context
-                input.as_ptr(),
-                input.len(),
-                output.as_mut_ptr(),
-            )
-        },
-        output.len(),
-    )?;
-    Ok(output)
-}
-
-/// An implementation of HKDF-SHA512. Derives a key of `derived_key.len()` bytes from `ikm`, `salt`,
-/// and `info`. The derived key is written to the `derived_key`.
-pub fn kdf(ikm: &[u8], salt: &[u8], info: &[u8], derived_key: &mut [u8]) -> Result<()> {
-    check_result(
-        // SAFETY: The function writes to the `derived_key`, within the given bounds, and only reads
-        // the input values. The first argument context is not used in this function.
-        unsafe {
-            DiceKdf(
-                ptr::null_mut(), // context
-                derived_key.len(),
-                ikm.as_ptr(),
-                ikm.len(),
-                salt.as_ptr(),
-                salt.len(),
-                info.as_ptr(),
-                info.len(),
-                derived_key.as_mut_ptr(),
-            )
-        },
-        derived_key.len(),
-    )
-}
-
-/// Deterministically generates a public and private key pair from `seed`.
-/// Since this is deterministic, `seed` is as sensitive as a private key and can
-/// be used directly as the private key.
-pub fn keypair_from_seed(seed: &[u8; PRIVATE_KEY_SEED_SIZE]) -> Result<(PublicKey, PrivateKey)> {
-    let mut public_key = [0u8; PUBLIC_KEY_SIZE];
-    let mut private_key = PrivateKey::default();
-    check_result(
-        // SAFETY: The function writes to the `public_key` and `private_key` within the given
-        // bounds, and only reads the `seed`. The first argument context is not used in this
-        // function.
-        unsafe {
-            DiceKeypairFromSeed(
-                ptr::null_mut(), // context
-                seed.as_ptr(),
-                public_key.as_mut_ptr(),
-                private_key.as_mut_ptr(),
-            )
-        },
-        public_key.len(),
-    )?;
-    Ok((public_key, private_key))
-}
-
-/// Derives the CDI_Leaf_Priv from the provided `dice_artifacts`.
-///
-/// The corresponding public key is included in the leaf certificate of the DICE chain
-/// contained in `dice_artifacts`.
-pub fn derive_cdi_leaf_priv(dice_artifacts: &dyn DiceArtifacts) -> Result<PrivateKey> {
-    let cdi_priv_key_seed = derive_cdi_private_key_seed(dice_artifacts.cdi_attest())?;
-    let (_, private_key) = keypair_from_seed(cdi_priv_key_seed.as_array())?;
-    Ok(private_key)
-}
-
-/// Signs the `message` with the give `private_key` using `DiceSign`.
-pub fn sign(message: &[u8], private_key: &[u8; PRIVATE_KEY_SIZE]) -> Result<Signature> {
-    let mut signature = [0u8; SIGNATURE_SIZE];
-    check_result(
-        // SAFETY: The function writes to the `signature` within the given bounds, and only reads
-        // the message and the private key. The first argument context is not used in this function.
-        unsafe {
-            DiceSign(
-                ptr::null_mut(), // context
-                message.as_ptr(),
-                message.len(),
-                private_key.as_ptr(),
-                signature.as_mut_ptr(),
-            )
-        },
-        signature.len(),
-    )?;
-    Ok(signature)
-}
-
-/// Verifies the `signature` of the `message` with the given `public_key` using `DiceVerify`.
-pub fn verify(message: &[u8], signature: &Signature, public_key: &PublicKey) -> Result<()> {
-    check_result(
-        // SAFETY: only reads the messages, signature and public key as constant values.
-        // The first argument context is not used in this function.
-        unsafe {
-            DiceVerify(
-                ptr::null_mut(), // context
-                message.as_ptr(),
-                message.len(),
-                signature.as_ptr(),
-                public_key.as_ptr(),
-            )
-        },
-        0,
-    )
-}
-
-/// Generates an X.509 certificate from the given `subject_private_key_seed` and
-/// `input_values`, and signed by `authority_private_key_seed`.
-/// The subject private key seed is supplied here so the implementation can choose
-/// between asymmetric mechanisms, for example ECDSA vs Ed25519.
-/// Returns the actual size of the generated certificate.
-pub fn generate_certificate(
-    subject_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
-    authority_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
-    input_values: &InputValues,
-    certificate: &mut [u8],
-) -> Result<usize> {
-    let mut certificate_actual_size = 0;
-    check_result(
-        // SAFETY: The function writes to the `certificate` within the given bounds, and only reads
-        // the input values and the key seeds. The first argument context is not used in this
-        // function.
-        unsafe {
-            DiceGenerateCertificate(
-                ptr::null_mut(), // context
-                subject_private_key_seed.as_ptr(),
-                authority_private_key_seed.as_ptr(),
-                input_values.as_ptr(),
-                certificate.len(),
-                certificate.as_mut_ptr(),
-                &mut certificate_actual_size,
-            )
-        },
-        certificate_actual_size,
-    )?;
-    Ok(certificate_actual_size)
-}
diff --git a/diced/open_dice/src/retry.rs b/diced/open_dice/src/retry.rs
deleted file mode 100644
index a6303bd..0000000
--- a/diced/open_dice/src/retry.rs
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2023, 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.
-
-//! This module implements a retry version for multiple DICE functions that
-//! require preallocated output buffer. As the retry functions require
-//! memory allocation on heap, currently we only expose these functions in
-//! std environment.
-
-use crate::bcc::{bcc_format_config_descriptor, bcc_main_flow, DiceConfigValues};
-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;
-#[cfg(feature = "alloc")]
-use alloc::vec::Vec;
-
-/// 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.
-#[derive(Debug)]
-pub struct OwnedDiceArtifacts {
-    /// CDI Values.
-    cdi_values: CdiValues,
-    /// Boot Certificate Chain.
-    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 measured buffer size.
-fn retry_with_measured_buffer<F>(mut f: F) -> Result<Vec<u8>>
-where
-    F: FnMut(&mut Vec<u8>) -> Result<usize>,
-{
-    let mut buffer = Vec::new();
-    match f(&mut buffer) {
-        Err(DiceError::BufferTooSmall(actual_size)) => {
-            buffer.resize(actual_size, 0);
-            f(&mut buffer)?;
-        }
-        Err(e) => return Err(e),
-        Ok(_) => {}
-    };
-    Ok(buffer)
-}
-
-/// Formats a configuration descriptor following the BCC's specification.
-pub fn retry_bcc_format_config_descriptor(values: &DiceConfigValues) -> Result<Vec<u8>> {
-    retry_with_measured_buffer(|buffer| bcc_format_config_descriptor(values, 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_measured_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 })
-}
-
-/// Executes the main DICE flow.
-///
-/// Given a full set of input values and the current CDI values, computes the
-/// next CDI values and a matching certificate.
-pub fn retry_dice_main_flow(
-    current_cdi_attest: &Cdi,
-    current_cdi_seal: &Cdi,
-    input_values: &InputValues,
-) -> Result<(CdiValues, Vec<u8>)> {
-    let mut next_cdi_values = CdiValues::default();
-    let next_cdi_certificate = retry_with_measured_buffer(|next_cdi_certificate| {
-        dice_main_flow(
-            current_cdi_attest,
-            current_cdi_seal,
-            input_values,
-            next_cdi_certificate,
-            &mut next_cdi_values,
-        )
-    })?;
-    Ok((next_cdi_values, next_cdi_certificate))
-}
-
-/// Generates an X.509 certificate from the given `subject_private_key_seed` and
-/// `input_values`, and signed by `authority_private_key_seed`.
-/// The subject private key seed is supplied here so the implementation can choose
-/// between asymmetric mechanisms, for example ECDSA vs Ed25519.
-/// Returns the generated certificate.
-pub fn retry_generate_certificate(
-    subject_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
-    authority_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
-    input_values: &InputValues,
-) -> Result<Vec<u8>> {
-    retry_with_measured_buffer(|certificate| {
-        generate_certificate(
-            subject_private_key_seed,
-            authority_private_key_seed,
-            input_values,
-            certificate,
-        )
-    })
-}
diff --git a/diced/open_dice/tests/api_test.rs b/diced/open_dice/tests/api_test.rs
deleted file mode 100644
index a47265b..0000000
--- a/diced/open_dice/tests/api_test.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2023 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.
- */
-
-use diced_open_dice::{
-    derive_cdi_certificate_id, derive_cdi_private_key_seed, hash, kdf, keypair_from_seed, sign,
-    verify, CDI_SIZE, HASH_SIZE, ID_SIZE, PRIVATE_KEY_SEED_SIZE,
-};
-
-#[test]
-fn hash_succeeds() {
-    const EXPECTED_HASH: [u8; HASH_SIZE] = [
-        0x30, 0x9e, 0xcc, 0x48, 0x9c, 0x12, 0xd6, 0xeb, 0x4c, 0xc4, 0x0f, 0x50, 0xc9, 0x02, 0xf2,
-        0xb4, 0xd0, 0xed, 0x77, 0xee, 0x51, 0x1a, 0x7c, 0x7a, 0x9b, 0xcd, 0x3c, 0xa8, 0x6d, 0x4c,
-        0xd8, 0x6f, 0x98, 0x9d, 0xd3, 0x5b, 0xc5, 0xff, 0x49, 0x96, 0x70, 0xda, 0x34, 0x25, 0x5b,
-        0x45, 0xb0, 0xcf, 0xd8, 0x30, 0xe8, 0x1f, 0x60, 0x5d, 0xcf, 0x7d, 0xc5, 0x54, 0x2e, 0x93,
-        0xae, 0x9c, 0xd7, 0x6f,
-    ];
-    assert_eq!(EXPECTED_HASH, hash(b"hello world").expect("hash failed"));
-}
-
-#[test]
-fn kdf_succeeds() {
-    let mut derived_key = [0u8; PRIVATE_KEY_SEED_SIZE];
-    kdf(b"myInitialKeyMaterial", b"mySalt", b"myInfo", &mut derived_key).unwrap();
-    const EXPECTED_DERIVED_KEY: [u8; PRIVATE_KEY_SEED_SIZE] = [
-        0x91, 0x9b, 0x8d, 0x29, 0xc4, 0x1b, 0x93, 0xd7, 0xeb, 0x09, 0xfa, 0xd7, 0xc9, 0x87, 0xb0,
-        0xd1, 0xcc, 0x26, 0xef, 0x07, 0x83, 0x42, 0xcf, 0xa3, 0x45, 0x0a, 0x57, 0xe9, 0x19, 0x86,
-        0xef, 0x48,
-    ];
-    assert_eq!(EXPECTED_DERIVED_KEY, derived_key);
-}
-
-#[test]
-fn derive_cdi_certificate_id_succeeds() {
-    const EXPECTED_ID: [u8; ID_SIZE] = [
-        0x7a, 0x36, 0x45, 0x2c, 0x02, 0xf6, 0x2b, 0xec, 0xf9, 0x80, 0x06, 0x75, 0x87, 0xa5, 0xc1,
-        0x44, 0x0c, 0xd3, 0xc0, 0x6d,
-    ];
-    assert_eq!(EXPECTED_ID, derive_cdi_certificate_id(b"MyPubKey").unwrap());
-}
-
-const EXPECTED_SEED: &[u8] = &[
-    0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba, 0xaa,
-    0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5, 0x3a, 0x08,
-    0x84, 0x8a, 0x98, 0x85, 0x6d, 0xf5, 0x69, 0x21, 0x03, 0xcd, 0x09, 0xc3, 0x28, 0xd6, 0x06, 0xa7,
-    0x57, 0xbd, 0x48, 0x4b, 0x0f, 0x79, 0x0f, 0xf8, 0x2f, 0xf0, 0x0a, 0x41, 0x94, 0xd8, 0x8c, 0xa8,
-];
-
-const EXPECTED_CDI_ATTEST: &[u8] = &[
-    0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba, 0xaa,
-    0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5, 0x3a, 0x08,
-];
-
-const EXPECTED_CDI_PRIVATE_KEY_SEED: &[u8] = &[
-    0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe, 0x0d,
-    0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72, 0x02, 0x6e,
-];
-
-const EXPECTED_PUB_KEY: &[u8] = &[
-    0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23, 0xc9,
-    0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61, 0x06, 0x37,
-];
-const EXPECTED_PRIV_KEY: &[u8] = &[
-    0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe, 0x0d,
-    0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72, 0x02, 0x6e,
-    0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23, 0xc9,
-    0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61, 0x06, 0x37,
-];
-
-const EXPECTED_SIGNATURE: &[u8] = &[
-    0x44, 0xae, 0xcc, 0xe2, 0xb9, 0x96, 0x18, 0x39, 0x0e, 0x61, 0x0f, 0x53, 0x07, 0xbf, 0xf2, 0x32,
-    0x3d, 0x44, 0xd4, 0xf2, 0x07, 0x23, 0x30, 0x85, 0x32, 0x18, 0xd2, 0x69, 0xb8, 0x29, 0x3c, 0x26,
-    0xe6, 0x0d, 0x9c, 0xa5, 0xc2, 0x73, 0xcd, 0x8c, 0xb8, 0x3c, 0x3e, 0x5b, 0xfd, 0x62, 0x8d, 0xf6,
-    0xc4, 0x27, 0xa6, 0xe9, 0x11, 0x06, 0x5a, 0xb2, 0x2b, 0x64, 0xf7, 0xfc, 0xbb, 0xab, 0x4a, 0x0e,
-];
-
-#[test]
-fn hash_derive_sign_verify() {
-    let seed = hash(b"MySeedString").unwrap();
-    assert_eq!(seed, EXPECTED_SEED);
-    let cdi_attest = &seed[..CDI_SIZE];
-    assert_eq!(cdi_attest, EXPECTED_CDI_ATTEST);
-    let cdi_private_key_seed = derive_cdi_private_key_seed(cdi_attest.try_into().unwrap()).unwrap();
-    assert_eq!(cdi_private_key_seed.as_array(), EXPECTED_CDI_PRIVATE_KEY_SEED);
-    let (pub_key, priv_key) = keypair_from_seed(cdi_private_key_seed.as_array()).unwrap();
-    assert_eq!(&pub_key, EXPECTED_PUB_KEY);
-    assert_eq!(priv_key.as_array(), EXPECTED_PRIV_KEY);
-    let mut signature = sign(b"MyMessage", priv_key.as_array()).unwrap();
-    assert_eq!(&signature, EXPECTED_SIGNATURE);
-    assert!(verify(b"MyMessage", &signature, &pub_key).is_ok());
-    assert!(verify(b"MyMessage_fail", &signature, &pub_key).is_err());
-    signature[0] += 1;
-    assert!(verify(b"MyMessage", &signature, &pub_key).is_err());
-}
diff --git a/diced/sample_inputs/Android.bp b/diced/sample_inputs/Android.bp
deleted file mode 100644
index ba76769..0000000
--- a/diced/sample_inputs/Android.bp
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2021, 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.
-
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "system_security_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["system_security_license"],
-}
-
-rust_defaults {
-    name: "libdiced_sample_inputs_defaults",
-    crate_name: "diced_sample_inputs",
-    srcs: ["src/lib.rs"],
-}
-
-rust_library {
-    name: "libdiced_sample_inputs",
-    defaults: ["libdiced_sample_inputs_defaults"],
-    features: [
-        "std",
-    ],
-    rustlibs: [
-        "libciborium",
-        "libcoset",
-        "libdiced_open_dice",
-        "liblog_rust",
-    ],
-}
-
-rust_library_rlib {
-    name: "libdiced_sample_inputs_nostd",
-    defaults: ["libdiced_sample_inputs_defaults"],
-    rustlibs: [
-        "libciborium_nostd",
-        "libcoset_nostd",
-        "libdiced_open_dice_nostd",
-        "liblog_rust_nostd",
-    ],
-    visibility: [
-        "//packages/modules/Virtualization:__subpackages__",
-    ],
-}
-
-rust_defaults {
-    name: "libdiced_sample_inputs_test_defaults",
-    crate_name: "diced_sample_inputs_test",
-    srcs: ["tests/*.rs"],
-    test_suites: ["general-tests"],
-    rustlibs: [
-        "libanyhow",
-        "libhwtrust",
-    ],
-}
-
-rust_test {
-    name: "libdiced_sample_inputs.integration_test",
-    defaults: ["libdiced_sample_inputs_test_defaults"],
-    rustlibs: [
-        "libdiced_open_dice",
-        "libdiced_sample_inputs",
-    ],
-}
-
-rust_test {
-    name: "libdiced_sample_inputs_nostd.integration_test",
-    defaults: ["libdiced_sample_inputs_test_defaults"],
-    rustlibs: [
-        "libdiced_open_dice_nostd",
-        "libdiced_sample_inputs_nostd",
-    ],
-}
diff --git a/diced/sample_inputs/src/lib.rs b/diced/sample_inputs/src/lib.rs
deleted file mode 100644
index 9d6deca..0000000
--- a/diced/sample_inputs/src/lib.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2023 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.
- */
-
-//! Provides a set of sample inputs for a DICE chain and CDI values derived
-//! from it.
-
-#![cfg_attr(not(feature = "std"), no_std)]
-
-extern crate alloc;
-
-mod sample_inputs;
-
-pub use sample_inputs::make_sample_bcc_and_cdis;
diff --git a/diced/sample_inputs/src/sample_inputs.rs b/diced/sample_inputs/src/sample_inputs.rs
deleted file mode 100644
index 54f551b..0000000
--- a/diced/sample_inputs/src/sample_inputs.rs
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright 2021, 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.
-
-//! This module provides a set of sample input values for a DICE chain, a sample UDS,
-//! as well as tuple of CDIs and BCC derived thereof.
-
-use alloc::vec;
-use alloc::vec::Vec;
-use ciborium::{de, ser, value::Value};
-use core::ffi::CStr;
-use coset::{iana, Algorithm, AsCborValue, CoseKey, KeyOperation, KeyType, Label};
-use diced_open_dice::{
-    derive_cdi_private_key_seed, keypair_from_seed, retry_bcc_format_config_descriptor,
-    retry_bcc_main_flow, retry_dice_main_flow, Config, DiceArtifacts, DiceConfigValues, DiceError,
-    DiceMode, InputValues, OwnedDiceArtifacts, Result, CDI_SIZE, HASH_SIZE, HIDDEN_SIZE,
-};
-use log::error;
-
-/// Sample UDS used to perform the root dice flow by `make_sample_bcc_and_cdis`.
-const UDS: &[u8; CDI_SIZE] = &[
-    0x65, 0x4f, 0xab, 0xa9, 0xa5, 0xad, 0x0f, 0x5e, 0x15, 0xc3, 0x12, 0xf7, 0x77, 0x45, 0xfa, 0x55,
-    0x18, 0x6a, 0xa6, 0x34, 0xb6, 0x7c, 0x82, 0x7b, 0x89, 0x4c, 0xc5, 0x52, 0xd3, 0x27, 0x35, 0x8e,
-];
-
-const CODE_HASH_ABL: [u8; HASH_SIZE] = [
-    0x16, 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38, 0xc3, 0x64, 0x38, 0x63, 0x26,
-    0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34, 0x4c, 0x6d, 0xa2, 0xbe, 0x25,
-    0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2, 0xb3, 0x91, 0x4d, 0xd3, 0xfb,
-    0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba, 0x30, 0xf7, 0x15, 0x98, 0x14,
-];
-const AUTHORITY_HASH_ABL: [u8; HASH_SIZE] = [
-    0xf9, 0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3, 0x97, 0x4a, 0xcb, 0x3c, 0xe7,
-    0x6b, 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59, 0x15, 0xb1, 0x23, 0xe6, 0xc8, 0xdf,
-    0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc, 0x5b, 0x37, 0x0e, 0x12, 0x12, 0xb2, 0xfd,
-    0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6, 0x29, 0x1b, 0x99, 0xea, 0xae, 0xfd, 0xaa, 0x0d,
-];
-const HIDDEN_ABL: [u8; HIDDEN_SIZE] = [
-    0xa2, 0x01, 0xd0, 0xc0, 0xaa, 0x75, 0x3c, 0x06, 0x43, 0x98, 0x6c, 0xc3, 0x5a, 0xb5, 0x5f, 0x1f,
-    0x0f, 0x92, 0x44, 0x3b, 0x0e, 0xd4, 0x29, 0x75, 0xe3, 0xdb, 0x36, 0xda, 0xc8, 0x07, 0x97, 0x4d,
-    0xff, 0xbc, 0x6a, 0xa4, 0x8a, 0xef, 0xc4, 0x7f, 0xf8, 0x61, 0x7d, 0x51, 0x4d, 0x2f, 0xdf, 0x7e,
-    0x8c, 0x3d, 0xa3, 0xfc, 0x63, 0xd4, 0xd4, 0x74, 0x8a, 0xc4, 0x14, 0x45, 0x83, 0x6b, 0x12, 0x7e,
-];
-const CODE_HASH_AVB: [u8; HASH_SIZE] = [
-    0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43, 0x83, 0x7f, 0x46, 0x8d,
-    0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0, 0xd9, 0x56, 0xb3, 0xbf, 0x2f, 0xfa,
-    0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9, 0x6b, 0x18, 0x28, 0xe8, 0x29, 0x20, 0x49, 0x0f,
-    0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54, 0xe9, 0x71, 0xd2, 0x7e, 0xa4, 0xfe, 0x58, 0x7f, 0xd3, 0xc7,
-];
-const AUTHORITY_HASH_AVB: [u8; HASH_SIZE] = [
-    0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa, 0x55, 0x6f, 0xac, 0x56, 0xd9, 0x02, 0x35, 0x2b, 0xaa,
-    0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a, 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d, 0xe4, 0x43,
-    0x13, 0xbf, 0xfe, 0xd3, 0x36, 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6, 0x66, 0xef, 0xab,
-    0x3d, 0x0f, 0x89, 0xa4, 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a, 0xef, 0xbc, 0x05, 0x98,
-];
-const HIDDEN_AVB: [u8; HIDDEN_SIZE] = [
-    0x5b, 0x3f, 0xc9, 0x6b, 0xe3, 0x95, 0x59, 0x40, 0x5e, 0x64, 0xe5, 0x64, 0x3f, 0xfd, 0x21, 0x09,
-    0x9d, 0xf3, 0xcd, 0xc7, 0xa4, 0x2a, 0xe2, 0x97, 0xdd, 0xe2, 0x4f, 0xb0, 0x7d, 0x7e, 0xf5, 0x8e,
-    0xd6, 0x4d, 0x84, 0x25, 0x54, 0x41, 0x3f, 0x8f, 0x78, 0x64, 0x1a, 0x51, 0x27, 0x9d, 0x55, 0x8a,
-    0xe9, 0x90, 0x35, 0xab, 0x39, 0x80, 0x4b, 0x94, 0x40, 0x84, 0xa2, 0xfd, 0x73, 0xeb, 0x35, 0x7a,
-];
-const AUTHORITY_HASH_ANDROID: [u8; HASH_SIZE] = [
-    0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30, 0x03, 0xb8, 0xd6,
-    0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37, 0x68, 0x4e, 0x1d, 0xc0,
-    0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2, 0x9c, 0xfc, 0x12, 0x9e, 0x77,
-    0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5, 0x73, 0xd4, 0xc6, 0xdf, 0x62, 0x9f,
-];
-
-fn ed25519_public_key_to_cbor_value(public_key: &[u8]) -> Result<Value> {
-    let key = CoseKey {
-        kty: KeyType::Assigned(iana::KeyType::OKP),
-        alg: Some(Algorithm::Assigned(iana::Algorithm::EdDSA)),
-        key_ops: vec![KeyOperation::Assigned(iana::KeyOperation::Verify)].into_iter().collect(),
-        params: vec![
-            (
-                Label::Int(iana::Ec2KeyParameter::Crv as i64),
-                Value::from(iana::EllipticCurve::Ed25519 as u64),
-            ),
-            (Label::Int(iana::Ec2KeyParameter::X as i64), Value::Bytes(public_key.to_vec())),
-        ],
-        ..Default::default()
-    };
-    key.to_cbor_value().map_err(|e| {
-        error!("Failed to serialize the key to CBOR data: {e}");
-        DiceError::InvalidInput
-    })
-}
-
-/// Makes a DICE chain (BCC) from the sample input.
-///
-/// The DICE chain is of the following format:
-/// public key derived from UDS -> ABL certificate -> AVB certificate -> Android certificate
-pub fn make_sample_bcc_and_cdis() -> Result<OwnedDiceArtifacts> {
-    let private_key_seed = derive_cdi_private_key_seed(UDS).map_err(|e| {
-        error!("In make_sample_bcc_and_cdis: Trying to derive private key seed. Error: {e}");
-        e
-    })?;
-
-    // Gets the root public key in DICE chain (BCC).
-    let (public_key, _) = keypair_from_seed(private_key_seed.as_array()).map_err(|e| {
-        error!("In make_sample_bcc_and_cids: Failed to generate key pair. Error: {e}");
-        e
-    })?;
-    let ed25519_public_key_value = ed25519_public_key_to_cbor_value(&public_key)?;
-
-    // Gets the ABL certificate to as the root certificate of DICE chain.
-    let config_values = DiceConfigValues {
-        component_name: Some(CStr::from_bytes_with_nul(b"ABL\0").unwrap()),
-        component_version: Some(1),
-        resettable: true,
-        ..Default::default()
-    };
-    let config_descriptor = retry_bcc_format_config_descriptor(&config_values)?;
-    let input_values = InputValues::new(
-        CODE_HASH_ABL,
-        Config::Descriptor(config_descriptor.as_slice()),
-        AUTHORITY_HASH_ABL,
-        DiceMode::kDiceModeNormal,
-        HIDDEN_ABL,
-    );
-    let (cdi_values, cert) = retry_dice_main_flow(UDS, UDS, &input_values).map_err(|e| {
-        error!("In make_sample_bcc_and_cdis: Trying to run first main flow. Error: {e}");
-        e
-    })?;
-    let bcc_value = Value::Array(vec![
-        ed25519_public_key_value,
-        de::from_reader(&cert[..]).map_err(|e| {
-            error!("Deserialize root DICE certificate failed: {e}");
-            DiceError::InvalidInput
-        })?,
-    ]);
-    let mut bcc: Vec<u8> = vec![];
-    ser::into_writer(&bcc_value, &mut bcc).map_err(|e| {
-        error!("Serialize BCC failed: {e}");
-        DiceError::InvalidInput
-    })?;
-
-    // Appends AVB certificate to DICE chain.
-    let config_values = DiceConfigValues {
-        component_name: Some(CStr::from_bytes_with_nul(b"AVB\0").unwrap()),
-        component_version: Some(1),
-        resettable: true,
-        ..Default::default()
-    };
-    let config_descriptor = retry_bcc_format_config_descriptor(&config_values)?;
-    let input_values = InputValues::new(
-        CODE_HASH_AVB,
-        Config::Descriptor(config_descriptor.as_slice()),
-        AUTHORITY_HASH_AVB,
-        DiceMode::kDiceModeNormal,
-        HIDDEN_AVB,
-    );
-    let dice_artifacts =
-        retry_bcc_main_flow(&cdi_values.cdi_attest, &cdi_values.cdi_seal, &bcc, &input_values)
-            .map_err(|e| {
-                error!(
-                    "In make_sample_bcc_and_cdis: Trying to run first bcc main flow. Error: {e}"
-                );
-                e
-            })?;
-
-    // Appends Android certificate to DICE chain.
-    let config_values = DiceConfigValues {
-        component_name: Some(CStr::from_bytes_with_nul(b"Android\0").unwrap()),
-        component_version: Some(12),
-        resettable: true,
-        ..Default::default()
-    };
-    let config_descriptor = retry_bcc_format_config_descriptor(&config_values)?;
-    let input_values = InputValues::new(
-        [0u8; HASH_SIZE], // code_hash
-        Config::Descriptor(config_descriptor.as_slice()),
-        AUTHORITY_HASH_ANDROID,
-        DiceMode::kDiceModeNormal,
-        [0u8; HIDDEN_SIZE], // hidden
-    );
-    retry_bcc_main_flow(
-        dice_artifacts.cdi_attest(),
-        dice_artifacts.cdi_seal(),
-        dice_artifacts.bcc().ok_or_else(|| {
-            error!("bcc is none");
-            DiceError::InvalidInput
-        })?,
-        &input_values,
-    )
-    .map_err(|e| {
-        error!("In make_sample_bcc_and_cdis: Trying to run second bcc main flow. Error: {e}");
-        e
-    })
-}
diff --git a/diced/sample_inputs/tests/api_test.rs b/diced/sample_inputs/tests/api_test.rs
deleted file mode 100644
index 0823f16..0000000
--- a/diced/sample_inputs/tests/api_test.rs
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2023 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.
- */
-
-use anyhow::Result;
-use diced_open_dice::{derive_cdi_leaf_priv, sign, DiceArtifacts};
-use diced_sample_inputs::make_sample_bcc_and_cdis;
-use hwtrust::{dice, session::Session};
-
-const EXPECTED_SAMPLE_CDI_ATTEST: &[u8] = &[
-    0x3e, 0x57, 0x65, 0x5d, 0x48, 0x02, 0xbd, 0x5c, 0x66, 0xcc, 0x1f, 0x0f, 0xbe, 0x5e, 0x32, 0xb6,
-    0x9e, 0x3d, 0x04, 0xaf, 0x00, 0x15, 0xbc, 0xdd, 0x1f, 0xbc, 0x59, 0xe4, 0xc3, 0x87, 0x95, 0x5e,
-];
-
-const EXPECTED_SAMPLE_CDI_SEAL: &[u8] = &[
-    0x36, 0x1b, 0xd2, 0xb3, 0xc4, 0xda, 0x77, 0xb2, 0x9c, 0xba, 0x39, 0x53, 0x82, 0x93, 0xd9, 0xb8,
-    0x9f, 0x73, 0x2d, 0x27, 0x06, 0x15, 0xa8, 0xcb, 0x6d, 0x1d, 0xf2, 0xb1, 0x54, 0xbb, 0x62, 0xf1,
-];
-
-const EXPECTED_SAMPLE_BCC: &[u8] = &[
-    0x84, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x3e, 0x85,
-    0xe5, 0x72, 0x75, 0x55, 0xe5, 0x1e, 0xe7, 0xf3, 0x35, 0x94, 0x8e, 0xbb, 0xbd, 0x74, 0x1e, 0x1d,
-    0xca, 0x49, 0x9c, 0x97, 0x39, 0x77, 0x06, 0xd3, 0xc8, 0x6e, 0x8b, 0xd7, 0x33, 0xf9, 0x84, 0x43,
-    0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9, 0x01, 0x78, 0x28, 0x34, 0x32, 0x64, 0x38, 0x38,
-    0x36, 0x34, 0x66, 0x39, 0x37, 0x62, 0x36, 0x35, 0x34, 0x37, 0x61, 0x35, 0x30, 0x63, 0x31, 0x65,
-    0x30, 0x61, 0x37, 0x34, 0x39, 0x66, 0x38, 0x65, 0x66, 0x38, 0x62, 0x38, 0x31, 0x65, 0x63, 0x36,
-    0x32, 0x61, 0x66, 0x02, 0x78, 0x28, 0x31, 0x66, 0x36, 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35,
-    0x32, 0x66, 0x32, 0x39, 0x65, 0x39, 0x33, 0x66, 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65,
-    0x33, 0x32, 0x63, 0x64, 0x38, 0x31, 0x64, 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x3a, 0x00,
-    0x47, 0x44, 0x50, 0x58, 0x40, 0x16, 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38,
-    0xc3, 0x64, 0x38, 0x63, 0x26, 0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34,
-    0x4c, 0x6d, 0xa2, 0xbe, 0x25, 0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2,
-    0xb3, 0x91, 0x4d, 0xd3, 0xfb, 0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba,
-    0x30, 0xf7, 0x15, 0x98, 0x14, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56, 0xa3, 0x3a, 0x00, 0x01, 0x11,
-    0x71, 0x63, 0x41, 0x42, 0x4c, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a, 0x00, 0x01, 0x11, 0x73,
-    0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x47, 0xae, 0x42, 0x27, 0x4c, 0xcb, 0x65, 0x4d,
-    0xee, 0x74, 0x2d, 0x05, 0x78, 0x2a, 0x08, 0x2a, 0xa5, 0xf0, 0xcf, 0xea, 0x3e, 0x60, 0xee, 0x97,
-    0x11, 0x4b, 0x5b, 0xe6, 0x05, 0x0c, 0xe8, 0x90, 0xf5, 0x22, 0xc4, 0xc6, 0x67, 0x7a, 0x22, 0x27,
-    0x17, 0xb3, 0x79, 0xcc, 0x37, 0x64, 0x5e, 0x19, 0x4f, 0x96, 0x37, 0x67, 0x3c, 0xd0, 0xc5, 0xed,
-    0x0f, 0xdd, 0xe7, 0x2e, 0x4f, 0x70, 0x97, 0x30, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0xf9,
-    0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3, 0x97, 0x4a, 0xcb, 0x3c, 0xe7, 0x6b,
-    0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59, 0x15, 0xb1, 0x23, 0xe6, 0xc8, 0xdf, 0xfb,
-    0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc, 0x5b, 0x37, 0x0e, 0x12, 0x12, 0xb2, 0xfd, 0xc1,
-    0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6, 0x29, 0x1b, 0x99, 0xea, 0xae, 0xfd, 0xaa, 0x0d, 0x3a,
-    0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01,
-    0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0xb1, 0x02, 0xcc, 0x2c, 0xb2, 0x6a,
-    0x3b, 0xe9, 0xc1, 0xd3, 0x95, 0x10, 0xa0, 0xe1, 0xff, 0x51, 0xde, 0x57, 0xd5, 0x65, 0x28, 0xfd,
-    0x7f, 0xeb, 0xd4, 0xca, 0x15, 0xf3, 0xca, 0xdf, 0x37, 0x88, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41,
-    0x20, 0x58, 0x40, 0x58, 0xd8, 0x03, 0x24, 0x53, 0x60, 0x57, 0xa9, 0x09, 0xfa, 0xab, 0xdc, 0x57,
-    0x1e, 0xf0, 0xe5, 0x1e, 0x51, 0x6f, 0x9e, 0xa3, 0x42, 0xe6, 0x6a, 0x8c, 0xaa, 0xad, 0x08, 0x48,
-    0xde, 0x7f, 0x4f, 0x6e, 0x2f, 0x7f, 0x39, 0x6c, 0xa1, 0xf8, 0x42, 0x71, 0xfe, 0x17, 0x3d, 0xca,
-    0x31, 0x83, 0x92, 0xed, 0xbb, 0x40, 0xb8, 0x10, 0xe0, 0xf2, 0x5a, 0x99, 0x53, 0x38, 0x46, 0x33,
-    0x97, 0x78, 0x05, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9, 0x01, 0x78, 0x28,
-    0x31, 0x66, 0x36, 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35, 0x32, 0x66, 0x32, 0x39, 0x65, 0x39,
-    0x33, 0x66, 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65, 0x33, 0x32, 0x63, 0x64, 0x38, 0x31,
-    0x64, 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x02, 0x78, 0x28, 0x32, 0x35, 0x39, 0x34, 0x38,
-    0x39, 0x65, 0x36, 0x39, 0x37, 0x34, 0x38, 0x37, 0x30, 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66,
-    0x34, 0x34, 0x32, 0x36, 0x37, 0x65, 0x61, 0x34, 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35,
-    0x37, 0x32, 0x35, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa,
-    0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43, 0x83, 0x7f, 0x46, 0x8d, 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14,
-    0x1f, 0x6e, 0xb3, 0xa0, 0xd9, 0x56, 0xb3, 0xbf, 0x2f, 0xfa, 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4,
-    0xd2, 0xa9, 0x6b, 0x18, 0x28, 0xe8, 0x29, 0x20, 0x49, 0x0f, 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54,
-    0xe9, 0x71, 0xd2, 0x7e, 0xa4, 0xfe, 0x58, 0x7f, 0xd3, 0xc7, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56,
-    0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x63, 0x41, 0x56, 0x42, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01,
-    0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x93, 0x17, 0xe1,
-    0x11, 0x27, 0x59, 0xd0, 0xef, 0x75, 0x0b, 0x2b, 0x1c, 0x0f, 0x5f, 0x52, 0xc3, 0x29, 0x23, 0xb5,
-    0x2a, 0xe6, 0x12, 0x72, 0x6f, 0x39, 0x86, 0x65, 0x2d, 0xf2, 0xe4, 0xe7, 0xd0, 0xaf, 0x0e, 0xa7,
-    0x99, 0x16, 0x89, 0x97, 0x21, 0xf7, 0xdc, 0x89, 0xdc, 0xde, 0xbb, 0x94, 0x88, 0x1f, 0xda, 0xe2,
-    0xf3, 0xe0, 0x54, 0xf9, 0x0e, 0x29, 0xb1, 0xbd, 0xe1, 0x0c, 0x0b, 0xd7, 0xf6, 0x3a, 0x00, 0x47,
-    0x44, 0x54, 0x58, 0x40, 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa, 0x55, 0x6f, 0xac, 0x56, 0xd9,
-    0x02, 0x35, 0x2b, 0xaa, 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a, 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9,
-    0x35, 0x7d, 0xe4, 0x43, 0x13, 0xbf, 0xfe, 0xd3, 0x36, 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e,
-    0xf6, 0x66, 0xef, 0xab, 0x3d, 0x0f, 0x89, 0xa4, 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a,
-    0xef, 0xbc, 0x05, 0x98, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57,
-    0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x96,
-    0x6d, 0x96, 0x42, 0xda, 0x64, 0x51, 0xad, 0xfa, 0x00, 0xbc, 0xbc, 0x95, 0x8a, 0xb0, 0xb9, 0x76,
-    0x01, 0xe6, 0xbd, 0xc0, 0x26, 0x79, 0x26, 0xfc, 0x0f, 0x1d, 0x87, 0x65, 0xf1, 0xf3, 0x99, 0x3a,
-    0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40, 0x10, 0x7f, 0x77, 0xad, 0x70, 0xbd, 0x52, 0x81,
-    0x28, 0x8d, 0x24, 0x81, 0xb4, 0x3f, 0x21, 0x68, 0x9f, 0xc3, 0x80, 0x68, 0x86, 0x55, 0xfb, 0x2e,
-    0x6d, 0x96, 0xe1, 0xe1, 0xb7, 0x28, 0x8d, 0x63, 0x85, 0xba, 0x2a, 0x01, 0x33, 0x87, 0x60, 0x63,
-    0xbb, 0x16, 0x3f, 0x2f, 0x3d, 0xf4, 0x2d, 0x48, 0x5b, 0x87, 0xed, 0xda, 0x34, 0xeb, 0x9c, 0x4d,
-    0x14, 0xac, 0x65, 0xf4, 0xfa, 0xef, 0x45, 0x0b, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01,
-    0x8f, 0xa9, 0x01, 0x78, 0x28, 0x32, 0x35, 0x39, 0x34, 0x38, 0x39, 0x65, 0x36, 0x39, 0x37, 0x34,
-    0x38, 0x37, 0x30, 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66, 0x34, 0x34, 0x32, 0x36, 0x37, 0x65,
-    0x61, 0x34, 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35, 0x37, 0x32, 0x35, 0x02, 0x78, 0x28,
-    0x35, 0x64, 0x34, 0x65, 0x64, 0x37, 0x66, 0x34, 0x31, 0x37, 0x61, 0x39, 0x35, 0x34, 0x61, 0x31,
-    0x38, 0x31, 0x34, 0x30, 0x37, 0x62, 0x35, 0x38, 0x38, 0x35, 0x61, 0x66, 0x64, 0x37, 0x32, 0x61,
-    0x35, 0x62, 0x66, 0x34, 0x30, 0x64, 0x61, 0x36, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a,
-    0x00, 0x47, 0x44, 0x53, 0x58, 0x1a, 0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x67, 0x41, 0x6e, 0x64,
-    0x72, 0x6f, 0x69, 0x64, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x0c, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6,
-    0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x26, 0x1a, 0xbd, 0x26, 0xd8, 0x37, 0x8f, 0x4a, 0xf2,
-    0x9e, 0x49, 0x4d, 0x93, 0x23, 0xc4, 0x6e, 0x02, 0xda, 0xe0, 0x00, 0x02, 0xe7, 0xed, 0x29, 0xdf,
-    0x2b, 0xb3, 0x69, 0xf3, 0x55, 0x0e, 0x4c, 0x22, 0xdc, 0xcf, 0xf5, 0x92, 0xc9, 0xfa, 0x78, 0x98,
-    0xf1, 0x0e, 0x55, 0x5f, 0xf4, 0x45, 0xed, 0xc0, 0x0a, 0x72, 0x2a, 0x7a, 0x3a, 0xd2, 0xb1, 0xf7,
-    0x76, 0xfe, 0x2a, 0x6b, 0x7b, 0x2a, 0x53, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0x04, 0x25,
-    0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30, 0x03, 0xb8, 0xd6, 0xe1, 0x99,
-    0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37, 0x68, 0x4e, 0x1d, 0xc0, 0x24, 0x74,
-    0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2, 0x9c, 0xfc, 0x12, 0x9e, 0x77, 0x0a, 0xde,
-    0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5, 0x73, 0xd4, 0xc6, 0xdf, 0x62, 0x9f, 0x3a, 0x00,
-    0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03,
-    0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0xdb, 0xe7, 0x5b, 0x3f, 0xa3, 0x42, 0xb0,
-    0x9c, 0xf8, 0x40, 0x8c, 0xb0, 0x9c, 0xf0, 0x0a, 0xaf, 0xdf, 0x6f, 0xe5, 0x09, 0x21, 0x11, 0x92,
-    0xe1, 0xf8, 0xc5, 0x09, 0x02, 0x3d, 0x1f, 0xb7, 0xc5, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20,
-    0x58, 0x40, 0xc4, 0xc1, 0xd7, 0x1c, 0x2d, 0x26, 0x89, 0x22, 0xcf, 0xa6, 0x99, 0x77, 0x30, 0x84,
-    0x86, 0x27, 0x59, 0x8f, 0xd8, 0x08, 0x75, 0xe0, 0xb2, 0xef, 0xf9, 0xfa, 0xa5, 0x40, 0x8c, 0xd3,
-    0xeb, 0xbb, 0xda, 0xf2, 0xc8, 0xae, 0x41, 0x22, 0x50, 0x9c, 0xe8, 0xb2, 0x9c, 0x9b, 0x3f, 0x8a,
-    0x78, 0x76, 0xab, 0xd0, 0xbe, 0xfc, 0xe4, 0x79, 0xcb, 0x1b, 0x2b, 0xaa, 0x4d, 0xdd, 0x15, 0x61,
-    0x42, 0x06,
-];
-const MESSAGE: &[u8] = b"Message for testing";
-
-#[test]
-fn sample_bcc_and_cdis_are_as_expected() {
-    let dice_artifacts = make_sample_bcc_and_cdis().unwrap();
-    assert_eq!(dice_artifacts.cdi_attest(), EXPECTED_SAMPLE_CDI_ATTEST);
-    assert_eq!(dice_artifacts.cdi_seal(), EXPECTED_SAMPLE_CDI_SEAL);
-    assert_eq!(dice_artifacts.bcc(), Some(EXPECTED_SAMPLE_BCC));
-}
-
-#[test]
-fn cdi_leaf_priv_corresponds_to_leaf_public_key_in_dice_chain() -> Result<()> {
-    let dice_artifacts = make_sample_bcc_and_cdis().unwrap();
-    let private_key = derive_cdi_leaf_priv(&dice_artifacts).unwrap();
-    let signature = sign(MESSAGE, private_key.as_array()).unwrap();
-
-    let session = Session::default();
-    let chain = dice::Chain::from_cbor(&session, dice_artifacts.bcc().unwrap())?;
-    let public_key = chain.leaf().subject_public_key();
-    public_key.verify(&signature, MESSAGE)
-}
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index cfac54d..1c7eebe 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -100,6 +100,7 @@
     defaults: ["libkeystore2_defaults"],
     rustlibs: [
         "libandroid_logger",
+        "libhex",
         "libkeystore2_test_utils",
         "liblibsqlite3_sys",
         "libnix",
diff --git a/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
index 9618842..86d38d7 100644
--- a/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
+++ b/keystore2/aidl/android/security/maintenance/IKeystoreMaintenance.aidl
@@ -16,7 +16,6 @@
 
 import android.system.keystore2.Domain;
 import android.system.keystore2.KeyDescriptor;
-import android.security.maintenance.UserState;
 
 /**
  * IKeystoreMaintenance interface exposes the methods for adding/removing users and changing the
@@ -77,19 +76,6 @@
     void clearNamespace(Domain domain, long nspace);
 
     /**
-     * Allows querying user state, given user id.
-     * Callers require 'GetState' permission.
-     *
-     * ## Error conditions:
-     * `ResponseCode::PERMISSION_DENIED` - if the callers do not have the 'GetState'
-     *                                     permission.
-     * `ResponseCode::SYSTEM_ERROR` - if an error occurred when querying the user state.
-     *
-     * @param userId - Android user id
-     */
-    UserState getState(in int userId);
-
-    /**
      * This function notifies the Keymint device of the specified securityLevel that
      * early boot has ended, so that they no longer allow early boot keys to be used.
      * ## Error conditions:
diff --git a/keystore2/aidl/android/security/maintenance/UserState.aidl b/keystore2/aidl/android/security/maintenance/UserState.aidl
deleted file mode 100644
index 376f4fb..0000000
--- a/keystore2/aidl/android/security/maintenance/UserState.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2021, 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.
-
-package android.security.maintenance;
-
-/** @hide */
-@Backing(type="int")
-enum UserState {
-    UNINITIALIZED = 0,
-    LSKF_UNLOCKED = 1,
-    LSKF_LOCKED = 2,
-}
\ No newline at end of file
diff --git a/keystore2/src/km_compat.rs b/keystore2/src/km_compat.rs
index 8eba02d..f8673fb 100644
--- a/keystore2/src/km_compat.rs
+++ b/keystore2/src/km_compat.rs
@@ -200,6 +200,15 @@
         let _ = self.soft.earlyBootEnded();
         self.real.earlyBootEnded()
     }
+    fn getRootOfTrustChallenge(&self) -> binder::Result<[u8; 16]> {
+        self.real.getRootOfTrustChallenge()
+    }
+    fn getRootOfTrust(&self, challenge: &[u8; 16]) -> binder::Result<Vec<u8>> {
+        self.real.getRootOfTrust(challenge)
+    }
+    fn sendRootOfTrust(&self, root_of_trust: &[u8]) -> binder::Result<()> {
+        self.real.sendRootOfTrust(root_of_trust)
+    }
 
     // For methods that emit keyblobs, check whether the underlying real device
     // supports the relevant parameters, and forward to the appropriate device.
@@ -304,15 +313,6 @@
             KeyBlob::Wrapped(keyblob) => self.soft.getKeyCharacteristics(keyblob, app_id, app_data),
         }
     }
-    fn getRootOfTrustChallenge(&self) -> binder::Result<[u8; 16]> {
-        self.real.getRootOfTrustChallenge()
-    }
-    fn getRootOfTrust(&self, challenge: &[u8; 16]) -> binder::Result<Vec<u8>> {
-        self.real.getRootOfTrust(challenge)
-    }
-    fn sendRootOfTrust(&self, root_of_trust: &[u8]) -> binder::Result<()> {
-        self.real.sendRootOfTrust(root_of_trust)
-    }
     fn convertStorageKeyToEphemeral(&self, storage_keyblob: &[u8]) -> binder::Result<Vec<u8>> {
         // Storage keys should never be associated with a software emulated device.
         self.real.convertStorageKeyToEphemeral(storage_keyblob)
diff --git a/keystore2/src/lib.rs b/keystore2/src/lib.rs
index 9794889..3233017 100644
--- a/keystore2/src/lib.rs
+++ b/keystore2/src/lib.rs
@@ -49,6 +49,7 @@
 mod gc;
 mod km_compat;
 mod super_key;
+mod sw_keyblob;
 
 #[cfg(feature = "watchdog")]
 mod watchdog;
diff --git a/keystore2/src/maintenance.rs b/keystore2/src/maintenance.rs
index 59f5d70..f25233f 100644
--- a/keystore2/src/maintenance.rs
+++ b/keystore2/src/maintenance.rs
@@ -29,9 +29,8 @@
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
     IKeyMintDevice::IKeyMintDevice, SecurityLevel::SecurityLevel,
 };
-use android_security_maintenance::aidl::android::security::maintenance::{
-    IKeystoreMaintenance::{BnKeystoreMaintenance, IKeystoreMaintenance},
-    UserState::UserState as AidlUserState,
+use android_security_maintenance::aidl::android::security::maintenance::IKeystoreMaintenance::{
+    BnKeystoreMaintenance, IKeystoreMaintenance,
 };
 use android_security_maintenance::binder::{
     BinderFeatures, Interface, Result as BinderResult, Strong, ThreadState,
@@ -135,27 +134,6 @@
             .context(ks_err!("While invoking the delete listener."))
     }
 
-    fn get_state(user_id: i32) -> Result<AidlUserState> {
-        // Check permission. Function should return if this failed. Therefore having '?' at the end
-        // is very important.
-        check_keystore_permission(KeystorePerm::GetState).context("In get_state.")?;
-        let state = DB
-            .with(|db| {
-                SUPER_KEY.read().unwrap().get_user_state(
-                    &mut db.borrow_mut(),
-                    &LEGACY_IMPORTER,
-                    user_id as u32,
-                )
-            })
-            .context(ks_err!("Trying to get UserState."))?;
-
-        match state {
-            UserState::Uninitialized => Ok(AidlUserState::UNINITIALIZED),
-            UserState::LskfUnlocked(_) => Ok(AidlUserState::LSKF_UNLOCKED),
-            UserState::LskfLocked => Ok(AidlUserState::LSKF_LOCKED),
-        }
-    }
-
     fn call_with_watchdog<F>(sec_level: SecurityLevel, name: &'static str, op: &F) -> Result<()>
     where
         F: Fn(Strong<dyn IKeyMintDevice>) -> binder::Result<()>,
@@ -306,11 +284,6 @@
         map_or_log_err(self.clear_namespace(domain, nspace), Ok)
     }
 
-    fn getState(&self, user_id: i32) -> BinderResult<AidlUserState> {
-        let _wp = wd::watch_millis("IKeystoreMaintenance::getState", 500);
-        map_or_log_err(Self::get_state(user_id), Ok)
-    }
-
     fn earlyBootEnded(&self) -> BinderResult<()> {
         log::info!("earlyBootEnded()");
         let _wp = wd::watch_millis("IKeystoreMaintenance::earlyBootEnded", 500);
diff --git a/keystore2/src/permission.rs b/keystore2/src/permission.rs
index d9bdf79..35d6988 100644
--- a/keystore2/src/permission.rs
+++ b/keystore2/src/permission.rs
@@ -109,9 +109,6 @@
         /// Checked when an app is uninstalled or wiped.
         #[selinux(name = clear_ns)]
         ClearNs,
-        /// Checked when the user state is queried from Keystore 2.0.
-        #[selinux(name = get_state)]
-        GetState,
         /// Checked when Keystore 2.0 is asked to list a namespace that the caller
         /// does not have the get_info permission for.
         #[selinux(name = list)]
@@ -500,7 +497,6 @@
         let system_server_ctx = Context::new("u:r:system_server:s0")?;
         assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::AddAuth).is_ok());
         assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::ClearNs).is_ok());
-        assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::GetState).is_ok());
         assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::Lock).is_ok());
         assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::Reset).is_ok());
         assert!(check_keystore_permission(&system_server_ctx, KeystorePerm::Unlock).is_ok());
@@ -510,7 +506,6 @@
         let shell_ctx = Context::new("u:r:shell:s0")?;
         assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::AddAuth));
         assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::ClearNs));
-        assert!(check_keystore_permission(&shell_ctx, KeystorePerm::GetState).is_ok());
         assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::List));
         assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::Lock));
         assert_perm_failed!(check_keystore_permission(&shell_ctx, KeystorePerm::Reset));
diff --git a/keystore2/src/sw_keyblob.rs b/keystore2/src/sw_keyblob.rs
new file mode 100644
index 0000000..11a9b41
--- /dev/null
+++ b/keystore2/src/sw_keyblob.rs
@@ -0,0 +1,812 @@
+// Copyright 2023, 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.
+
+//! Code for parsing software-backed keyblobs, as emitted by the C++ reference implementation of
+//! KeyMint.
+
+#![allow(dead_code)]
+
+use crate::error::Error;
+use crate::ks_err;
+use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+    Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
+    ErrorCode::ErrorCode, HardwareAuthenticatorType::HardwareAuthenticatorType,
+    KeyFormat::KeyFormat, KeyOrigin::KeyOrigin, KeyParameter::KeyParameter,
+    KeyParameterValue::KeyParameterValue, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
+    Tag::Tag, TagType::TagType,
+};
+use anyhow::Result;
+use keystore2_crypto::hmac_sha256;
+use std::mem::size_of;
+
+/// Root of trust value.
+const SOFTWARE_ROOT_OF_TRUST: &[u8] = b"SW";
+
+/// Error macro.
+macro_rules! bloberr {
+    { $($arg:tt)+ } => {
+        anyhow::Error::new(Error::Km(ErrorCode::INVALID_KEY_BLOB)).context(ks_err!($($arg)+))
+    };
+}
+
+/// Get the `KeyParameterValue` associated with a tag from a collection of `KeyParameter`s.
+fn get_tag_value(params: &[KeyParameter], tag: Tag) -> Option<&KeyParameterValue> {
+    params.iter().find_map(|kp| if kp.tag == tag { Some(&kp.value) } else { None })
+}
+
+/// Get the [`TagType`] for a [`Tag`].
+fn tag_type(tag: &Tag) -> TagType {
+    TagType((tag.0 as u32 & 0xf0000000) as i32)
+}
+
+/// Extract key material and combined key characteristics from a legacy authenticated keyblob.
+pub fn export_key(
+    data: &[u8],
+    params: &[KeyParameter],
+) -> Result<(KeyFormat, Vec<u8>, Vec<KeyParameter>)> {
+    let hidden = hidden_params(params, &[SOFTWARE_ROOT_OF_TRUST]);
+    let KeyBlob { key_material, hw_enforced, sw_enforced } =
+        KeyBlob::new_from_serialized(data, &hidden)?;
+
+    let mut combined = hw_enforced;
+    combined.extend_from_slice(&sw_enforced);
+
+    let algo_val =
+        get_tag_value(&combined, Tag::ALGORITHM).ok_or_else(|| bloberr!("No algorithm found!"))?;
+
+    let format = match algo_val {
+        KeyParameterValue::Algorithm(Algorithm::AES)
+        | KeyParameterValue::Algorithm(Algorithm::TRIPLE_DES)
+        | KeyParameterValue::Algorithm(Algorithm::HMAC) => KeyFormat::RAW,
+        KeyParameterValue::Algorithm(Algorithm::RSA)
+        | KeyParameterValue::Algorithm(Algorithm::EC) => KeyFormat::PKCS8,
+        _ => return Err(bloberr!("Unexpected algorithm {:?}", algo_val)),
+    };
+    Ok((format, key_material, combined))
+}
+
+/// Plaintext key blob, with key characteristics.
+#[derive(PartialEq, Eq)]
+struct KeyBlob {
+    /// Raw key material.
+    key_material: Vec<u8>,
+    /// Hardware-enforced key characteristics.
+    hw_enforced: Vec<KeyParameter>,
+    /// Software-enforced key characteristics.
+    sw_enforced: Vec<KeyParameter>,
+}
+
+impl KeyBlob {
+    /// Key blob version.
+    const KEY_BLOB_VERSION: u8 = 0;
+
+    /// Hard-coded HMAC key used for keyblob authentication.
+    const LEGACY_HMAC_KEY: &[u8] = b"IntegrityAssuredBlob0\0";
+
+    /// Size (in bytes) of appended MAC.
+    const MAC_LEN: usize = 8;
+
+    /// Parse a serialized [`KeyBlob`].
+    fn new_from_serialized(mut data: &[u8], hidden: &[KeyParameter]) -> Result<Self> {
+        // Keyblob needs to be at least long enough for:
+        // - version byte,
+        // - 4-byte len for key material
+        // - 4-byte len for hw_enforced params
+        // - 4-byte len for sw_enforced params
+        // - MAC tag.
+        if data.len() < (1 + 3 * size_of::<u32>() + Self::MAC_LEN) {
+            return Err(bloberr!("blob not long enough (len = {})", data.len()));
+        }
+
+        // Check the HMAC in the last 8 bytes before doing anything else.
+        let mac = &data[data.len() - Self::MAC_LEN..];
+        let computed_mac = Self::compute_hmac(&data[..data.len() - Self::MAC_LEN], hidden)?;
+        if mac != computed_mac {
+            return Err(bloberr!("invalid key blob"));
+        }
+
+        let version = consume_u8(&mut data)?;
+        if version != Self::KEY_BLOB_VERSION {
+            return Err(bloberr!("unexpected blob version {}", version));
+        }
+        let key_material = consume_vec(&mut data)?;
+        let hw_enforced = deserialize_params(&mut data)?;
+        let sw_enforced = deserialize_params(&mut data)?;
+
+        // Should just be the (already-checked) MAC left.
+        let rest = &data[Self::MAC_LEN..];
+        if !rest.is_empty() {
+            return Err(bloberr!("extra data (len {})", rest.len()));
+        }
+        Ok(KeyBlob { key_material, hw_enforced, sw_enforced })
+    }
+
+    /// Compute the authentication HMAC for a KeyBlob. This is built as:
+    ///   HMAC-SHA256(HK, data || serialize(hidden))
+    /// with HK = b"IntegrityAssuredBlob0\0".
+    fn compute_hmac(data: &[u8], hidden: &[KeyParameter]) -> Result<Vec<u8>> {
+        let hidden_data = serialize_params(hidden)?;
+        let mut combined = data.to_vec();
+        combined.extend_from_slice(&hidden_data);
+        let mut tag = hmac_sha256(Self::LEGACY_HMAC_KEY, &combined)?;
+        tag.truncate(Self::MAC_LEN);
+        Ok(tag)
+    }
+}
+
+/// Build the parameters that are used as the hidden input to HMAC calculations:
+/// - `ApplicationId(data)` if present
+/// - `ApplicationData(data)` if present
+/// - (repeated) `RootOfTrust(rot)` where `rot` is a hardcoded piece of root of trust information.
+fn hidden_params(params: &[KeyParameter], rots: &[&[u8]]) -> Vec<KeyParameter> {
+    let mut results = Vec::new();
+    if let Some(app_id) = get_tag_value(params, Tag::APPLICATION_ID) {
+        results.push(KeyParameter { tag: Tag::APPLICATION_ID, value: app_id.clone() });
+    }
+    if let Some(app_data) = get_tag_value(params, Tag::APPLICATION_DATA) {
+        results.push(KeyParameter { tag: Tag::APPLICATION_DATA, value: app_data.clone() });
+    }
+    for rot in rots {
+        results.push(KeyParameter {
+            tag: Tag::ROOT_OF_TRUST,
+            value: KeyParameterValue::Blob(rot.to_vec()),
+        });
+    }
+    results
+}
+
+/// Retrieve a `u8` from the start of the given slice, if possible.
+fn consume_u8(data: &mut &[u8]) -> Result<u8> {
+    match data.first() {
+        Some(b) => {
+            *data = &(*data)[1..];
+            Ok(*b)
+        }
+        None => Err(bloberr!("failed to find 1 byte")),
+    }
+}
+
+/// Move past a bool value from the start of the given slice, if possible.
+/// Bool values should only be included if `true`, so fail if the value
+/// is anything other than 1.
+fn consume_bool(data: &mut &[u8]) -> Result<bool> {
+    let b = consume_u8(data)?;
+    if b == 0x01 {
+        Ok(true)
+    } else {
+        Err(bloberr!("bool value other than 1 encountered"))
+    }
+}
+
+/// Retrieve a (host-ordered) `u32` from the start of the given slice, if possible.
+fn consume_u32(data: &mut &[u8]) -> Result<u32> {
+    const LEN: usize = size_of::<u32>();
+    if data.len() < LEN {
+        return Err(bloberr!("failed to find {LEN} bytes"));
+    }
+    let chunk: [u8; LEN] = data[..LEN].try_into().unwrap(); // safe: just checked
+    *data = &(*data)[LEN..];
+    Ok(u32::from_ne_bytes(chunk))
+}
+
+/// Retrieve a (host-ordered) `i32` from the start of the given slice, if possible.
+fn consume_i32(data: &mut &[u8]) -> Result<i32> {
+    const LEN: usize = size_of::<i32>();
+    if data.len() < LEN {
+        return Err(bloberr!("failed to find {LEN} bytes"));
+    }
+    let chunk: [u8; LEN] = data[..LEN].try_into().unwrap(); // safe: just checked
+    *data = &(*data)[4..];
+    Ok(i32::from_ne_bytes(chunk))
+}
+
+/// Retrieve a (host-ordered) `i64` from the start of the given slice, if possible.
+fn consume_i64(data: &mut &[u8]) -> Result<i64> {
+    const LEN: usize = size_of::<i64>();
+    if data.len() < LEN {
+        return Err(bloberr!("failed to find {LEN} bytes"));
+    }
+    let chunk: [u8; LEN] = data[..LEN].try_into().unwrap(); // safe: just checked
+    *data = &(*data)[LEN..];
+    Ok(i64::from_ne_bytes(chunk))
+}
+
+/// Retrieve a vector of bytes from the start of the given slice, if possible,
+/// with the length of the data expected to appear as a host-ordered `u32` prefix.
+fn consume_vec(data: &mut &[u8]) -> Result<Vec<u8>> {
+    let len = consume_u32(data)? as usize;
+    if len > data.len() {
+        return Err(bloberr!("failed to find {} bytes", len));
+    }
+    let result = data[..len].to_vec();
+    *data = &(*data)[len..];
+    Ok(result)
+}
+
+/// Retrieve the contents of a tag of `TagType::Bytes`.  The `data` parameter holds
+/// the as-yet unparsed data, and a length and offset are read from this (and consumed).
+/// This length and offset refer to a location in the combined `blob_data`; however,
+/// the offset is expected to be the next unconsumed chunk of `blob_data`, as indicated
+/// by `next_blob_offset` (which itself is updated as a result of consuming the data).
+fn consume_blob(
+    data: &mut &[u8],
+    next_blob_offset: &mut usize,
+    blob_data: &[u8],
+) -> Result<Vec<u8>> {
+    let data_len = consume_u32(data)? as usize;
+    let data_offset = consume_u32(data)? as usize;
+    // Expect the blob data to come from the next offset in the initial blob chunk.
+    if data_offset != *next_blob_offset {
+        return Err(bloberr!("got blob offset {} instead of {}", data_offset, next_blob_offset));
+    }
+    if (data_offset + data_len) > blob_data.len() {
+        return Err(bloberr!(
+            "blob at offset [{}..{}+{}] goes beyond blob data size {}",
+            data_offset,
+            data_offset,
+            data_len,
+            blob_data.len(),
+        ));
+    }
+
+    let slice = &blob_data[data_offset..data_offset + data_len];
+    *next_blob_offset += data_len;
+    Ok(slice.to_vec())
+}
+
+/// Deserialize a collection of [`KeyParam`]s in legacy serialized format. The provided slice is
+/// modified to contain the unconsumed part of the data.
+fn deserialize_params(data: &mut &[u8]) -> Result<Vec<KeyParameter>> {
+    let blob_data_size = consume_u32(data)? as usize;
+    if blob_data_size > data.len() {
+        return Err(bloberr!(
+            "blob data size {} bigger than data (len={})",
+            blob_data_size,
+            data.len()
+        ));
+    }
+
+    let blob_data = &data[..blob_data_size];
+    let mut next_blob_offset = 0;
+
+    // Move past the blob data.
+    *data = &data[blob_data_size..];
+
+    let param_count = consume_u32(data)? as usize;
+    let param_size = consume_u32(data)? as usize;
+    if param_size > data.len() {
+        return Err(bloberr!(
+            "size mismatch 4+{}+4+4+{} > {}",
+            blob_data_size,
+            param_size,
+            data.len()
+        ));
+    }
+
+    let mut results = Vec::new();
+    for _i in 0..param_count {
+        let tag_num = consume_u32(data)? as i32;
+        let tag = Tag(tag_num);
+        let value = match tag_type(&tag) {
+            TagType::INVALID => return Err(bloberr!("invalid tag {:?} encountered", tag)),
+            TagType::ENUM | TagType::ENUM_REP => {
+                let val = consume_i32(data)?;
+                match tag {
+                    Tag::ALGORITHM => KeyParameterValue::Algorithm(Algorithm(val)),
+                    Tag::BLOCK_MODE => KeyParameterValue::BlockMode(BlockMode(val)),
+                    Tag::PADDING => KeyParameterValue::PaddingMode(PaddingMode(val)),
+                    Tag::DIGEST | Tag::RSA_OAEP_MGF_DIGEST => {
+                        KeyParameterValue::Digest(Digest(val))
+                    }
+                    Tag::EC_CURVE => KeyParameterValue::EcCurve(EcCurve(val)),
+                    Tag::ORIGIN => KeyParameterValue::Origin(KeyOrigin(val)),
+                    Tag::PURPOSE => KeyParameterValue::KeyPurpose(KeyPurpose(val)),
+                    Tag::USER_AUTH_TYPE => {
+                        KeyParameterValue::HardwareAuthenticatorType(HardwareAuthenticatorType(val))
+                    }
+                    _ => KeyParameterValue::Integer(val),
+                }
+            }
+            TagType::UINT | TagType::UINT_REP => KeyParameterValue::Integer(consume_i32(data)?),
+            TagType::ULONG | TagType::ULONG_REP => {
+                KeyParameterValue::LongInteger(consume_i64(data)?)
+            }
+            TagType::DATE => KeyParameterValue::DateTime(consume_i64(data)?),
+            TagType::BOOL => KeyParameterValue::BoolValue(consume_bool(data)?),
+            TagType::BIGNUM | TagType::BYTES => {
+                KeyParameterValue::Blob(consume_blob(data, &mut next_blob_offset, blob_data)?)
+            }
+            _ => return Err(bloberr!("unexpected tag type for {:?}", tag)),
+        };
+        results.push(KeyParameter { tag, value });
+    }
+
+    Ok(results)
+}
+
+/// Serialize a collection of [`KeyParameter`]s into a format that is compatible with previous
+/// implementations:
+///
+/// ```text
+/// [0..4]              Size B of `TagType::Bytes` data, in host order.
+/// [4..4+B]      (*)   Concatenated contents of each `TagType::Bytes` tag.
+/// [4+B..4+B+4]        Count N of the number of parameters, in host order.
+/// [8+B..8+B+4]        Size Z of encoded parameters.
+/// [12+B..12+B+Z]      Serialized parameters one after another.
+/// ```
+///
+/// Individual parameters are serialized in the last chunk as:
+///
+/// ```text
+/// [0..4]              Tag number, in host order.
+/// Followed by one of the following depending on the tag's `TagType`; all integers in host order:
+///   [4..5]            Bool value (`TagType::Bool`)
+///   [4..8]            i32 values (`TagType::Uint[Rep]`, `TagType::Enum[Rep]`)
+///   [4..12]           i64 values, in host order (`TagType::UlongRep`, `TagType::Date`)
+///   [4..8] + [8..12]  Size + offset of data in (*) above (`TagType::Bytes`, `TagType::Bignum`)
+/// ```
+fn serialize_params(params: &[KeyParameter]) -> Result<Vec<u8>> {
+    // First 4 bytes are the length of the combined [`TagType::Bytes`] data; come back to set that
+    // in a moment.
+    let mut result = vec![0; 4];
+
+    // Next append the contents of all of the [`TagType::Bytes`] data.
+    let mut blob_size = 0u32;
+    for param in params {
+        let tag_type = tag_type(&param.tag);
+        if let KeyParameterValue::Blob(v) = &param.value {
+            if tag_type != TagType::BIGNUM && tag_type != TagType::BYTES {
+                return Err(bloberr!("unexpected tag type for tag {:?} with blob", param.tag));
+            }
+            result.extend_from_slice(v);
+            blob_size += v.len() as u32;
+        }
+    }
+    // Go back and fill in the combined blob length in native order at the start.
+    result[..4].clone_from_slice(&blob_size.to_ne_bytes());
+
+    result.extend_from_slice(&(params.len() as u32).to_ne_bytes());
+
+    let params_size_offset = result.len();
+    result.extend_from_slice(&[0u8; 4]); // placeholder for size of elements
+    let first_param_offset = result.len();
+    let mut blob_offset = 0u32;
+    for param in params {
+        result.extend_from_slice(&(param.tag.0 as u32).to_ne_bytes());
+        match &param.value {
+            KeyParameterValue::Invalid(_v) => {
+                return Err(bloberr!("invalid tag found in {:?}", param))
+            }
+
+            // Enum-holding variants.
+            KeyParameterValue::Algorithm(v) => {
+                result.extend_from_slice(&(v.0 as u32).to_ne_bytes())
+            }
+            KeyParameterValue::BlockMode(v) => {
+                result.extend_from_slice(&(v.0 as u32).to_ne_bytes())
+            }
+            KeyParameterValue::PaddingMode(v) => {
+                result.extend_from_slice(&(v.0 as u32).to_ne_bytes())
+            }
+            KeyParameterValue::Digest(v) => result.extend_from_slice(&(v.0 as u32).to_ne_bytes()),
+            KeyParameterValue::EcCurve(v) => result.extend_from_slice(&(v.0 as u32).to_ne_bytes()),
+            KeyParameterValue::Origin(v) => result.extend_from_slice(&(v.0 as u32).to_ne_bytes()),
+            KeyParameterValue::KeyPurpose(v) => {
+                result.extend_from_slice(&(v.0 as u32).to_ne_bytes())
+            }
+            KeyParameterValue::HardwareAuthenticatorType(v) => {
+                result.extend_from_slice(&(v.0 as u32).to_ne_bytes())
+            }
+
+            // Value-holding variants.
+            KeyParameterValue::Integer(v) => result.extend_from_slice(&(*v as u32).to_ne_bytes()),
+            KeyParameterValue::BoolValue(_v) => result.push(0x01u8),
+            KeyParameterValue::LongInteger(v) | KeyParameterValue::DateTime(v) => {
+                result.extend_from_slice(&(*v as u64).to_ne_bytes())
+            }
+            KeyParameterValue::Blob(v) => {
+                let blob_len = v.len() as u32;
+                result.extend_from_slice(&blob_len.to_ne_bytes());
+                result.extend_from_slice(&blob_offset.to_ne_bytes());
+                blob_offset += blob_len;
+            }
+
+            _ => return Err(bloberr!("unknown value found in {:?}", param)),
+        }
+    }
+    let serialized_size = (result.len() - first_param_offset) as u32;
+
+    // Go back and fill in the total serialized size.
+    result[params_size_offset..params_size_offset + 4]
+        .clone_from_slice(&serialized_size.to_ne_bytes());
+    Ok(result)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
+        Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
+        KeyOrigin::KeyOrigin, KeyParameter::KeyParameter,
+        KeyParameterValue::KeyParameterValue as KPV, KeyPurpose::KeyPurpose,
+        PaddingMode::PaddingMode, Tag::Tag,
+    };
+
+    macro_rules! expect_err {
+        ($result:expr, $err_msg:expr) => {
+            assert!(
+                $result.is_err(),
+                "Expected error containing '{}', got success {:?}",
+                $err_msg,
+                $result
+            );
+            let err = $result.err();
+            assert!(
+                format!("{:?}", err).contains($err_msg),
+                "Unexpected error {:?}, doesn't contain '{}'",
+                err,
+                $err_msg
+            );
+        };
+    }
+
+    #[test]
+    fn test_consume_u8() {
+        let buffer = [1, 2];
+        let mut data = &buffer[..];
+        assert_eq!(1u8, consume_u8(&mut data).unwrap());
+        assert_eq!(2u8, consume_u8(&mut data).unwrap());
+        let result = consume_u8(&mut data);
+        expect_err!(result, "failed to find 1 byte");
+    }
+
+    #[test]
+    fn test_consume_u32() {
+        // All supported platforms are little-endian.
+        let buffer = [
+            0x01, 0x02, 0x03, 0x04, // little-endian u32
+            0x04, 0x03, 0x02, 0x01, // little-endian u32
+            0x11, 0x12, 0x13,
+        ];
+        let mut data = &buffer[..];
+        assert_eq!(0x04030201u32, consume_u32(&mut data).unwrap());
+        assert_eq!(0x01020304u32, consume_u32(&mut data).unwrap());
+        let result = consume_u32(&mut data);
+        expect_err!(result, "failed to find 4 bytes");
+    }
+
+    #[test]
+    fn test_consume_i64() {
+        // All supported platforms are little-endian.
+        let buffer = [
+            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // little-endian i64
+            0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, // little-endian i64
+            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+        ];
+        let mut data = &buffer[..];
+        assert_eq!(0x0807060504030201i64, consume_i64(&mut data).unwrap());
+        assert_eq!(0x0102030405060708i64, consume_i64(&mut data).unwrap());
+        let result = consume_i64(&mut data);
+        expect_err!(result, "failed to find 8 bytes");
+    }
+
+    #[test]
+    fn test_consume_vec() {
+        let buffer = [
+            0x01, 0x00, 0x00, 0x00, 0xaa, //
+            0x00, 0x00, 0x00, 0x00, //
+            0x01, 0x00, 0x00, 0x00, 0xbb, //
+            0x07, 0x00, 0x00, 0x00, 0xbb, // not enough data
+        ];
+        let mut data = &buffer[..];
+        assert_eq!(vec![0xaa], consume_vec(&mut data).unwrap());
+        assert_eq!(Vec::<u8>::new(), consume_vec(&mut data).unwrap());
+        assert_eq!(vec![0xbb], consume_vec(&mut data).unwrap());
+        let result = consume_vec(&mut data);
+        expect_err!(result, "failed to find 7 bytes");
+
+        let buffer = [
+            0x01, 0x00, 0x00, //
+        ];
+        let mut data = &buffer[..];
+        let result = consume_vec(&mut data);
+        expect_err!(result, "failed to find 4 bytes");
+    }
+
+    #[test]
+    fn test_key_new_from_serialized() {
+        let hidden = hidden_params(&[], &[SOFTWARE_ROOT_OF_TRUST]);
+        // Test data originally generated by instrumenting Cuttlefish C++ KeyMint while running VTS
+        // tests.
+        let tests = [
+            (
+                concat!(
+                    "0010000000d43c2f04f948521b81bdbf001310f5920000000000000000000000",
+                    "00000000000c0000006400000002000010200000000300003080000000010000",
+                    "2000000000010000200100000004000020020000000600002001000000be0200",
+                    "1000000000c1020030b0ad0100c20200307b150300bd020060a8bb52407b0100",
+                    "00ce02003011643401cf020030000000003b06b13ae6ae6671",
+                ),
+                KeyBlob {
+                    key_material: hex::decode("d43c2f04f948521b81bdbf001310f592").unwrap(),
+                    hw_enforced: vec![],
+                    sw_enforced: vec![
+                        KeyParameter { tag: Tag::ALGORITHM, value: KPV::Algorithm(Algorithm::AES) },
+                        KeyParameter { tag: Tag::KEY_SIZE, value: KPV::Integer(128) },
+                        KeyParameter {
+                            tag: Tag::PURPOSE,
+                            value: KPV::KeyPurpose(KeyPurpose::ENCRYPT),
+                        },
+                        KeyParameter {
+                            tag: Tag::PURPOSE,
+                            value: KPV::KeyPurpose(KeyPurpose::DECRYPT),
+                        },
+                        KeyParameter {
+                            tag: Tag::BLOCK_MODE,
+                            value: KPV::BlockMode(BlockMode::CBC),
+                        },
+                        KeyParameter {
+                            tag: Tag::PADDING,
+                            value: KPV::PaddingMode(PaddingMode::NONE),
+                        },
+                        KeyParameter { tag: Tag::ORIGIN, value: KPV::Origin(KeyOrigin::GENERATED) },
+                        KeyParameter { tag: Tag::OS_VERSION, value: KPV::Integer(110000) },
+                        KeyParameter { tag: Tag::OS_PATCHLEVEL, value: KPV::Integer(202107) },
+                        KeyParameter {
+                            tag: Tag::CREATION_DATETIME,
+                            value: KPV::DateTime(1628871769000),
+                        },
+                        KeyParameter { tag: Tag::VENDOR_PATCHLEVEL, value: KPV::Integer(20210705) },
+                        KeyParameter { tag: Tag::BOOT_PATCHLEVEL, value: KPV::Integer(0) },
+                    ],
+                },
+                Some(KeyFormat::RAW),
+            ),
+            (
+                concat!(
+                    "00df0000003081dc020101044200b6ce876b947e263d61b8e3998d50dc0afb6b",
+                    "a14e46ab7ca532fbe2a379b155d0a5bb99265402857b1601fb20be6c244bf654",
+                    "e9e79413cd503eae3d9cf68ed24f47a00706052b81040023a181890381860004",
+                    "006b840f0db0b12f074ab916c7773cfa7d42967c9e5b4fae09cf999f7e116d14",
+                    "0743bdd028db0a3fcc670e721b9f00bc7fb70aa401c7d6de6582fc26962a29b7",
+                    "45e30142e90685646661550344113aaf28bdee6cb02d19df1faab4398556a909",
+                    "7d6f64b95209601a549389a311231c6cce78354f2cdbc3a904abf70686f5f0c3",
+                    "b877984d000000000000000000000000000000000c0000006400000002000010",
+                    "030000000a000010030000000100002002000000010000200300000005000020",
+                    "000000000300003009020000be02001000000000c1020030b0ad0100c2020030",
+                    "7b150300bd02006018d352407b010000ce02003011643401cf02003000000000",
+                    "2f69002e55e9b0a3"
+                ),
+                KeyBlob {
+                    key_material: hex::decode(concat!(
+                        "3081dc020101044200b6ce876b947e263d61b8e3998d50dc0afb6ba14e46ab7c",
+                        "a532fbe2a379b155d0a5bb99265402857b1601fb20be6c244bf654e9e79413cd",
+                        "503eae3d9cf68ed24f47a00706052b81040023a181890381860004006b840f0d",
+                        "b0b12f074ab916c7773cfa7d42967c9e5b4fae09cf999f7e116d140743bdd028",
+                        "db0a3fcc670e721b9f00bc7fb70aa401c7d6de6582fc26962a29b745e30142e9",
+                        "0685646661550344113aaf28bdee6cb02d19df1faab4398556a9097d6f64b952",
+                        "09601a549389a311231c6cce78354f2cdbc3a904abf70686f5f0c3b877984d",
+                    ))
+                    .unwrap(),
+                    hw_enforced: vec![],
+                    sw_enforced: vec![
+                        KeyParameter { tag: Tag::ALGORITHM, value: KPV::Algorithm(Algorithm::EC) },
+                        KeyParameter { tag: Tag::EC_CURVE, value: KPV::EcCurve(EcCurve::P_521) },
+                        KeyParameter {
+                            tag: Tag::PURPOSE,
+                            value: KPV::KeyPurpose(KeyPurpose::SIGN),
+                        },
+                        KeyParameter {
+                            tag: Tag::PURPOSE,
+                            value: KPV::KeyPurpose(KeyPurpose::VERIFY),
+                        },
+                        KeyParameter { tag: Tag::DIGEST, value: KPV::Digest(Digest::NONE) },
+                        KeyParameter { tag: Tag::KEY_SIZE, value: KPV::Integer(521) },
+                        KeyParameter { tag: Tag::ORIGIN, value: KPV::Origin(KeyOrigin::GENERATED) },
+                        KeyParameter { tag: Tag::OS_VERSION, value: KPV::Integer(110000) },
+                        KeyParameter { tag: Tag::OS_PATCHLEVEL, value: KPV::Integer(202107) },
+                        KeyParameter {
+                            tag: Tag::CREATION_DATETIME,
+                            value: KPV::DateTime(1628871775000),
+                        },
+                        KeyParameter { tag: Tag::VENDOR_PATCHLEVEL, value: KPV::Integer(20210705) },
+                        KeyParameter { tag: Tag::BOOT_PATCHLEVEL, value: KPV::Integer(0) },
+                    ],
+                },
+                Some(KeyFormat::PKCS8),
+            ),
+            (
+                concat!(
+                    "0037000000541d4c440223650d5f51753c1abd80c725034485551e874d62327c",
+                    "65f6247a057f1218bd6c8cd7d319103ddb823fc11fb6c2c7268b5acc00000000",
+                    "0000000000000000000000000c00000064000000020000108000000003000030",
+                    "b801000001000020020000000100002003000000050000200400000008000030",
+                    "00010000be02001000000000c1020030b0ad0100c20200307b150300bd020060",
+                    "00d752407b010000ce02003011643401cf0200300000000036e6986ffc45fbb0",
+                ),
+                KeyBlob {
+                    key_material: hex::decode(concat!(
+                        "541d4c440223650d5f51753c1abd80c725034485551e874d62327c65f6247a05",
+                        "7f1218bd6c8cd7d319103ddb823fc11fb6c2c7268b5acc"
+                    ))
+                    .unwrap(),
+                    hw_enforced: vec![],
+                    sw_enforced: vec![
+                        KeyParameter {
+                            tag: Tag::ALGORITHM,
+                            value: KPV::Algorithm(Algorithm::HMAC),
+                        },
+                        KeyParameter { tag: Tag::KEY_SIZE, value: KPV::Integer(440) },
+                        KeyParameter {
+                            tag: Tag::PURPOSE,
+                            value: KPV::KeyPurpose(KeyPurpose::SIGN),
+                        },
+                        KeyParameter {
+                            tag: Tag::PURPOSE,
+                            value: KPV::KeyPurpose(KeyPurpose::VERIFY),
+                        },
+                        KeyParameter { tag: Tag::DIGEST, value: KPV::Digest(Digest::SHA_2_256) },
+                        KeyParameter { tag: Tag::MIN_MAC_LENGTH, value: KPV::Integer(256) },
+                        KeyParameter { tag: Tag::ORIGIN, value: KPV::Origin(KeyOrigin::GENERATED) },
+                        KeyParameter { tag: Tag::OS_VERSION, value: KPV::Integer(110000) },
+                        KeyParameter { tag: Tag::OS_PATCHLEVEL, value: KPV::Integer(202107) },
+                        KeyParameter {
+                            tag: Tag::CREATION_DATETIME,
+                            value: KPV::DateTime(1628871776000),
+                        },
+                        KeyParameter { tag: Tag::VENDOR_PATCHLEVEL, value: KPV::Integer(20210705) },
+                        KeyParameter { tag: Tag::BOOT_PATCHLEVEL, value: KPV::Integer(0) },
+                    ],
+                },
+                Some(KeyFormat::RAW),
+            ),
+            (
+                concat!(
+                    "00a8040000308204a40201000282010100bc47b5c71116766669b91fa747df87",
+                    "a1963df83956569d4ac232aeba8a246c0ec73bf606374a6d07f30c2162f97082",
+                    "825c7c6e482a2841dfeaec1429d84e52c54a6b2f760dec952c9c44a3c3a80f31",
+                    "c1ced84878edd4858059071c4d20d9ab0aae978bd68c1eb448e174a9736c3973",
+                    "6838151642eda8215107375865a99a57f29467c74c40f37b0221b93ec3f4f22d",
+                    "5337c8bf9245d56936196a92b1dea315ecce8785f9fa9b7d159ca207612cc0de",
+                    "b0957d61dbba5d9bd38784f4fecbf233b04e686a340528665ecd03db8e8a09b2",
+                    "540c84e45c4a99fb338b76bba7722856b5113341c349708937228f167d238ed8",
+                    "efb9cc19547dd620f6a90d95f07e50bfe102030100010282010002f91b69d9af",
+                    "59fe87421af9ba60f15c77f9c1c90effd6634332876f8ee5a116b126f55d3703",
+                    "8bf9f588ae20c8d951d842e35c9ef35a7822d3ebf72c0b7c3e229b289ae2e178",
+                    "a848e06d558c2e03d26871ee98a35f370d461ff1c4acc39d684de680a25ec88e",
+                    "e610260e406c400bdeb2893b2d0330cb483e662fa5abd24c2b82143e85dfe30a",
+                    "e7a31f8262da2903d882b35a34a26b699ff2d812bad4b126a0065ec0e101d73a",
+                    "e6f8b29a9144eb83f54940a371fc7416c2c0370df6a41cb5391f17ba33239e1b",
+                    "4217c8db50db5c6bf77ccf621354ecc652a4f7196054c254566fd7b3bc0f3817",
+                    "d9380b190bd382aaffa37785759f285194c11a188bccde0e2e2902818100fb23",
+                    "3335770c9f3cbd4b6ede5f12d03c449b1997bce06a8249bc3de99972fd0d0a63",
+                    "3f7790d1011bf5eedee16fa45a9107a910656ecaee364ce9edb4369843be71f2",
+                    "7a74852d6c7215a6cc60d9803bcac544922f806d8e5844e0ddd914bd78009490",
+                    "4c2856d2b944fade3fb1d67d4a33fb7663a9ab660ab372c2e4868a0f45990281",
+                    "8100bfecf2bb4012e880fd065a0b088f2d757af2878d3f1305f21ce7a7158458",
+                    "18e01181ff06b2f406239fc50808ce3dbe7b68ec01174913c0f237feb3c8c7eb",
+                    "0078b77fb5b8f214b72f6d3835b1a7ebe8b132feb6cb34ab09ce22b98160fc84",
+                    "20fcbf48d1eee49f874e902f049b206a61a095f0405a4935e7c5e49757ab7b57",
+                    "298902818100ec0049383e16f3716de5fc5b2677148efe5dceb02483b43399bd",
+                    "3765559994a9f3900eed7a7e9e8f3b0eee0e660eca392e3cb736cae612f39e55",
+                    "dad696d3821def10d1f8bbca52f5e6d8e7893ffbdcb491aafdc17bebf86f84d2",
+                    "d8480ed07a7bf9209d20ef6e79429489d4cb7768281a2f7e32ec1830fd6f6332",
+                    "38f521ba764902818100b2c3ce5751580b4e51df3fb175387f5c24b79040a4d6",
+                    "603c6265f70018b441ff3aef7d8e4cd2f480ec0906f1c4c0481304e8861f9d46",
+                    "93fa48e3a9abc362859eeb343e1c5507ac94b5439ce7ac04154a2fb886a4819b",
+                    "2a57e18a2e131b412ac4a09b004766959cdf357745f003e272aab3de02e2d5bc",
+                    "2af4ed75760858ab181902818061d19c2a8dcacde104b97f7c4fae11216157c1",
+                    "c0a258d882984d12383a73dc56fe2ac93512bb321df9706ecdb2f70a44c949c4",
+                    "340a9fae64a0646cf51f37c58c08bebde91667b3b2fa7c895f7983d4786c5526",
+                    "1941b3654533b0598383ebbcffcdf28b6cf13d376e3a70b49b14d8d06e8563a2",
+                    "47f56a337e3b9845b4f2b61356000000000000000000000000000000000d0000",
+                    "007000000002000010010000000300003000080000c800005001000100000000",
+                    "0001000020020000000100002003000000050000200000000006000020010000",
+                    "00be02001000000000c1020030b0ad0100c20200307b150300bd020060a8bb52",
+                    "407b010000ce02003011643401cf02003000000000544862e9c961e857",
+                ),
+                KeyBlob {
+                    key_material: hex::decode(concat!(
+                        "308204a40201000282010100bc47b5c71116766669b91fa747df87a1963df839",
+                        "56569d4ac232aeba8a246c0ec73bf606374a6d07f30c2162f97082825c7c6e48",
+                        "2a2841dfeaec1429d84e52c54a6b2f760dec952c9c44a3c3a80f31c1ced84878",
+                        "edd4858059071c4d20d9ab0aae978bd68c1eb448e174a9736c39736838151642",
+                        "eda8215107375865a99a57f29467c74c40f37b0221b93ec3f4f22d5337c8bf92",
+                        "45d56936196a92b1dea315ecce8785f9fa9b7d159ca207612cc0deb0957d61db",
+                        "ba5d9bd38784f4fecbf233b04e686a340528665ecd03db8e8a09b2540c84e45c",
+                        "4a99fb338b76bba7722856b5113341c349708937228f167d238ed8efb9cc1954",
+                        "7dd620f6a90d95f07e50bfe102030100010282010002f91b69d9af59fe87421a",
+                        "f9ba60f15c77f9c1c90effd6634332876f8ee5a116b126f55d37038bf9f588ae",
+                        "20c8d951d842e35c9ef35a7822d3ebf72c0b7c3e229b289ae2e178a848e06d55",
+                        "8c2e03d26871ee98a35f370d461ff1c4acc39d684de680a25ec88ee610260e40",
+                        "6c400bdeb2893b2d0330cb483e662fa5abd24c2b82143e85dfe30ae7a31f8262",
+                        "da2903d882b35a34a26b699ff2d812bad4b126a0065ec0e101d73ae6f8b29a91",
+                        "44eb83f54940a371fc7416c2c0370df6a41cb5391f17ba33239e1b4217c8db50",
+                        "db5c6bf77ccf621354ecc652a4f7196054c254566fd7b3bc0f3817d9380b190b",
+                        "d382aaffa37785759f285194c11a188bccde0e2e2902818100fb233335770c9f",
+                        "3cbd4b6ede5f12d03c449b1997bce06a8249bc3de99972fd0d0a633f7790d101",
+                        "1bf5eedee16fa45a9107a910656ecaee364ce9edb4369843be71f27a74852d6c",
+                        "7215a6cc60d9803bcac544922f806d8e5844e0ddd914bd780094904c2856d2b9",
+                        "44fade3fb1d67d4a33fb7663a9ab660ab372c2e4868a0f459902818100bfecf2",
+                        "bb4012e880fd065a0b088f2d757af2878d3f1305f21ce7a715845818e01181ff",
+                        "06b2f406239fc50808ce3dbe7b68ec01174913c0f237feb3c8c7eb0078b77fb5",
+                        "b8f214b72f6d3835b1a7ebe8b132feb6cb34ab09ce22b98160fc8420fcbf48d1",
+                        "eee49f874e902f049b206a61a095f0405a4935e7c5e49757ab7b572989028181",
+                        "00ec0049383e16f3716de5fc5b2677148efe5dceb02483b43399bd3765559994",
+                        "a9f3900eed7a7e9e8f3b0eee0e660eca392e3cb736cae612f39e55dad696d382",
+                        "1def10d1f8bbca52f5e6d8e7893ffbdcb491aafdc17bebf86f84d2d8480ed07a",
+                        "7bf9209d20ef6e79429489d4cb7768281a2f7e32ec1830fd6f633238f521ba76",
+                        "4902818100b2c3ce5751580b4e51df3fb175387f5c24b79040a4d6603c6265f7",
+                        "0018b441ff3aef7d8e4cd2f480ec0906f1c4c0481304e8861f9d4693fa48e3a9",
+                        "abc362859eeb343e1c5507ac94b5439ce7ac04154a2fb886a4819b2a57e18a2e",
+                        "131b412ac4a09b004766959cdf357745f003e272aab3de02e2d5bc2af4ed7576",
+                        "0858ab181902818061d19c2a8dcacde104b97f7c4fae11216157c1c0a258d882",
+                        "984d12383a73dc56fe2ac93512bb321df9706ecdb2f70a44c949c4340a9fae64",
+                        "a0646cf51f37c58c08bebde91667b3b2fa7c895f7983d4786c55261941b36545",
+                        "33b0598383ebbcffcdf28b6cf13d376e3a70b49b14d8d06e8563a247f56a337e",
+                        "3b9845b4f2b61356",
+                    ))
+                    .unwrap(),
+                    hw_enforced: vec![],
+                    sw_enforced: vec![
+                        KeyParameter { tag: Tag::ALGORITHM, value: KPV::Algorithm(Algorithm::RSA) },
+                        KeyParameter { tag: Tag::KEY_SIZE, value: KPV::Integer(2048) },
+                        KeyParameter {
+                            tag: Tag::RSA_PUBLIC_EXPONENT,
+                            value: KPV::LongInteger(65537),
+                        },
+                        KeyParameter {
+                            tag: Tag::PURPOSE,
+                            value: KPV::KeyPurpose(KeyPurpose::SIGN),
+                        },
+                        KeyParameter {
+                            tag: Tag::PURPOSE,
+                            value: KPV::KeyPurpose(KeyPurpose::VERIFY),
+                        },
+                        KeyParameter { tag: Tag::DIGEST, value: KPV::Digest(Digest::NONE) },
+                        KeyParameter {
+                            tag: Tag::PADDING,
+                            value: KPV::PaddingMode(PaddingMode::NONE),
+                        },
+                        KeyParameter { tag: Tag::ORIGIN, value: KPV::Origin(KeyOrigin::GENERATED) },
+                        KeyParameter { tag: Tag::OS_VERSION, value: KPV::Integer(110000) },
+                        KeyParameter { tag: Tag::OS_PATCHLEVEL, value: KPV::Integer(202107) },
+                        KeyParameter {
+                            tag: Tag::CREATION_DATETIME,
+                            value: KPV::DateTime(1628871769000),
+                        },
+                        KeyParameter { tag: Tag::VENDOR_PATCHLEVEL, value: KPV::Integer(20210705) },
+                        KeyParameter { tag: Tag::BOOT_PATCHLEVEL, value: KPV::Integer(0) },
+                    ],
+                },
+                // No support for RSA keys in export_key().
+                None,
+            ),
+        ];
+
+        for (input, want, want_format) in tests {
+            let input = hex::decode(input).unwrap();
+            let got = KeyBlob::new_from_serialized(&input, &hidden).expect("invalid keyblob!");
+            assert!(got == want);
+
+            if let Some(want_format) = want_format {
+                let (got_format, _key_material, params) =
+                    export_key(&input, &[]).expect("invalid keyblob!");
+                assert_eq!(got_format, want_format);
+                // All the test cases are software-only keys.
+                assert_eq!(params, got.sw_enforced);
+            }
+        }
+    }
+}
diff --git a/keystore2/test_utils/authorizations.rs b/keystore2/test_utils/authorizations.rs
index b73aab5..ebe2665 100644
--- a/keystore2/test_utils/authorizations.rs
+++ b/keystore2/test_utils/authorizations.rs
@@ -305,6 +305,24 @@
         });
         self
     }
+
+    /// Set creation date-time.
+    pub fn creation_date_time(mut self, date: i64) -> Self {
+        self.0.push(KeyParameter {
+            tag: Tag::CREATION_DATETIME,
+            value: KeyParameterValue::DateTime(date),
+        });
+        self
+    }
+
+    /// Set include unique id.
+    pub fn include_unique_id(mut self) -> Self {
+        self.0.push(KeyParameter {
+            tag: Tag::INCLUDE_UNIQUE_ID,
+            value: KeyParameterValue::BoolValue(true),
+        });
+        self
+    }
 }
 
 impl Deref for AuthSetBuilder {
diff --git a/keystore2/test_utils/key_generations.rs b/keystore2/test_utils/key_generations.rs
index ccf27bc..0ffc32a 100644
--- a/keystore2/test_utils/key_generations.rs
+++ b/keystore2/test_utils/key_generations.rs
@@ -26,7 +26,7 @@
     Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
     ErrorCode::ErrorCode, HardwareAuthenticatorType::HardwareAuthenticatorType,
     KeyOrigin::KeyOrigin, KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue,
-    KeyPurpose::KeyPurpose, PaddingMode::PaddingMode, Tag::Tag,
+    KeyPurpose::KeyPurpose, PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
     AuthenticatorSpec::AuthenticatorSpec, Authorization::Authorization,
@@ -38,7 +38,10 @@
 use crate::authorizations::AuthSetBuilder;
 use android_system_keystore2::binder::{ExceptionCode, Result as BinderResult};
 
-use crate::ffi_test_utils::{get_os_patchlevel, get_os_version, get_vendor_patchlevel};
+use crate::ffi_test_utils::{
+    get_os_patchlevel, get_os_version, get_value_from_attest_record, get_vendor_patchlevel,
+    validate_certchain,
+};
 
 /// Shell namespace.
 pub const SELINUX_SHELL_NAMESPACE: i64 = 1;
@@ -388,6 +391,12 @@
     })
 }
 
+/// Indicate whether the default device is KeyMint (rather than Keymaster).
+pub fn has_default_keymint() -> bool {
+    binder::is_declared("android.hardware.security.keymint.IKeyMintDevice/default")
+        .expect("Could not check for declared keymint interface")
+}
+
 /// Verify that given key param is listed in given authorizations list.
 pub fn check_key_param(authorizations: &[Authorization], key_param: &KeyParameter) -> bool {
     authorizations.iter().any(|auth| &auth.keyParameter == key_param)
@@ -468,6 +477,13 @@
             )
         }
     ));
+
+    if has_default_keymint() {
+        assert!(authorizations
+            .iter()
+            .map(|auth| &auth.keyParameter)
+            .any(|key_param| key_param.tag == Tag::CREATION_DATETIME));
+    }
 }
 
 /// Get the key `Authorization` for the given auth `Tag`.
@@ -1400,6 +1416,32 @@
         assert!(key_metadata.certificate.is_some());
         if gen_params.iter().any(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE) {
             assert!(key_metadata.certificateChain.is_some());
+            let mut cert_chain: Vec<u8> = Vec::new();
+            cert_chain.extend(key_metadata.certificate.as_ref().unwrap());
+            cert_chain.extend(key_metadata.certificateChain.as_ref().unwrap());
+            validate_certchain(&cert_chain).expect("Error while validating cert chain");
+        }
+
+        if let Some(challenge_param) =
+            gen_params.iter().find(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE)
+        {
+            if let KeyParameterValue::Blob(val) = &challenge_param.value {
+                let att_challenge = get_value_from_attest_record(
+                    key_metadata.certificate.as_ref().unwrap(),
+                    challenge_param.tag,
+                    key_metadata.keySecurityLevel,
+                )
+                .expect("Attestation challenge verification failed.");
+                assert_eq!(&att_challenge, val);
+            }
+
+            let att_app_id = get_value_from_attest_record(
+                key_metadata.certificate.as_ref().unwrap(),
+                Tag::ATTESTATION_APPLICATION_ID,
+                SecurityLevel::KEYSTORE,
+            )
+            .expect("Attestation application id verification failed.");
+            assert!(!att_app_id.is_empty());
         }
     }
     check_key_authorizations(&key_metadata.authorizations, gen_params, KeyOrigin::GENERATED);
diff --git a/keystore2/tests/keystore2_client_authorizations_tests.rs b/keystore2/tests/keystore2_client_authorizations_tests.rs
index fe48acd..4fce1d9 100644
--- a/keystore2/tests/keystore2_client_authorizations_tests.rs
+++ b/keystore2/tests/keystore2_client_authorizations_tests.rs
@@ -21,8 +21,8 @@
 };
 
 use android_system_keystore2::aidl::android::system::keystore2::{
-    IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyMetadata::KeyMetadata,
-    ResponseCode::ResponseCode,
+    Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
+    KeyMetadata::KeyMetadata, ResponseCode::ResponseCode,
 };
 
 use keystore2_test_utils::{
@@ -36,6 +36,32 @@
 
 use keystore2_test_utils::ffi_test_utils::get_value_from_attest_record;
 
+fn gen_key_including_unique_id(
+    sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
+    alias: &str,
+) -> Vec<u8> {
+    let gen_params = authorizations::AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::EC)
+        .purpose(KeyPurpose::SIGN)
+        .purpose(KeyPurpose::VERIFY)
+        .digest(Digest::SHA_2_256)
+        .ec_curve(EcCurve::P_256)
+        .attestation_challenge(b"foo".to_vec())
+        .include_unique_id();
+
+    let key_metadata = key_generations::generate_key(sec_level, &gen_params, alias).unwrap();
+
+    let unique_id = get_value_from_attest_record(
+        key_metadata.certificate.as_ref().unwrap(),
+        Tag::UNIQUE_ID,
+        key_metadata.keySecurityLevel,
+    )
+    .expect("Unique id not found.");
+    assert!(!unique_id.is_empty());
+    unique_id
+}
+
 fn generate_key_and_perform_sign_verify_op_max_times(
     sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
     gen_params: &authorizations::AuthSetBuilder,
@@ -590,3 +616,60 @@
         false,
     );
 }
+
+/// Try to generate a key with `Tag::CREATION_DATETIME` set to valid value. Test should fail
+/// to generate a key with `INVALID_ARGUMENT` error as Keystore2 backend doesn't allow user to
+/// specify `CREATION_DATETIME`.
+#[test]
+fn keystore2_gen_key_auth_creation_date_time_test_fail_with_invalid_arg_error() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
+    let creation_datetime = duration_since_epoch.as_millis();
+    let gen_params = authorizations::AuthSetBuilder::new()
+        .no_auth_required()
+        .algorithm(Algorithm::EC)
+        .purpose(KeyPurpose::SIGN)
+        .purpose(KeyPurpose::VERIFY)
+        .digest(Digest::SHA_2_256)
+        .ec_curve(EcCurve::P_256)
+        .attestation_challenge(b"foo".to_vec())
+        .creation_date_time(creation_datetime.try_into().unwrap());
+
+    let alias = "ks_test_auth_tags_test";
+    let result = key_generations::map_ks_error(sec_level.generateKey(
+        &KeyDescriptor {
+            domain: Domain::APP,
+            nspace: -1,
+            alias: Some(alias.to_string()),
+            blob: None,
+        },
+        None,
+        &gen_params,
+        0,
+        b"entropy",
+    ));
+
+    assert!(result.is_err());
+    assert_eq!(Error::Rc(ResponseCode::INVALID_ARGUMENT), result.unwrap_err());
+}
+
+/// Generate a key with `Tag::INCLUDE_UNIQUE_ID` set. Test should verify that `Tag::UNIQUE_ID` is
+/// included in attest record and it remains the same for new keys generated.
+#[test]
+fn keystore2_gen_key_auth_include_unique_id_success() {
+    let keystore2 = get_keystore_service();
+    let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
+
+    let alias_first = "ks_test_auth_tags_test_1";
+    let unique_id_first = gen_key_including_unique_id(&sec_level, alias_first);
+
+    let alias_second = "ks_test_auth_tags_test_2";
+    let unique_id_second = gen_key_including_unique_id(&sec_level, alias_second);
+
+    assert_eq!(unique_id_first, unique_id_second);
+
+    delete_app_key(&keystore2, alias_first).unwrap();
+    delete_app_key(&keystore2, alias_second).unwrap();
+}
diff --git a/keystore2/tests/keystore2_client_import_keys_tests.rs b/keystore2/tests/keystore2_client_import_keys_tests.rs
index 3d108fe..31d57a2 100644
--- a/keystore2/tests/keystore2_client_import_keys_tests.rs
+++ b/keystore2/tests/keystore2_client_import_keys_tests.rs
@@ -37,9 +37,9 @@
 };
 
 use crate::keystore2_client_test_utils::{
-    encrypt_secure_key, encrypt_transport_key, has_default_keymint,
-    perform_sample_asym_sign_verify_op, perform_sample_hmac_sign_verify_op,
-    perform_sample_sym_key_decrypt_op, perform_sample_sym_key_encrypt_op, SAMPLE_PLAIN_TEXT,
+    encrypt_secure_key, encrypt_transport_key, perform_sample_asym_sign_verify_op,
+    perform_sample_hmac_sign_verify_op, perform_sample_sym_key_decrypt_op,
+    perform_sample_sym_key_encrypt_op, SAMPLE_PLAIN_TEXT,
 };
 
 pub fn import_rsa_sign_key_and_perform_sample_operation(
@@ -288,7 +288,7 @@
         key_generations::RSA_2048_KEY,
     ));
 
-    if has_default_keymint() {
+    if key_generations::has_default_keymint() {
         assert!(result.is_err());
         assert_eq!(Error::Km(ErrorCode::INCOMPATIBLE_PURPOSE), result.unwrap_err());
     } else {
diff --git a/keystore2/tests/keystore2_client_test_utils.rs b/keystore2/tests/keystore2_client_test_utils.rs
index f7e7985..e76c64b 100644
--- a/keystore2/tests/keystore2_client_test_utils.rs
+++ b/keystore2/tests/keystore2_client_test_utils.rs
@@ -104,12 +104,6 @@
     };
 }
 
-/// Indicate whether the default device is KeyMint (rather than Keymaster).
-pub fn has_default_keymint() -> bool {
-    binder::is_declared("android.hardware.security.keymint.IKeyMintDevice/default")
-        .expect("Could not check for declared keymint interface")
-}
-
 /// Generate EC key and grant it to the list of users with given access vector.
 /// Returns the list of granted keys `nspace` values in the order of given grantee uids.
 pub fn generate_ec_key_and_grant_to_users(
diff --git a/keystore2/tests/legacy_blobs/keystore2_legacy_blob_tests.rs b/keystore2/tests/legacy_blobs/keystore2_legacy_blob_tests.rs
index 63122fe..faf954a 100644
--- a/keystore2/tests/legacy_blobs/keystore2_legacy_blob_tests.rs
+++ b/keystore2/tests/legacy_blobs/keystore2_legacy_blob_tests.rs
@@ -25,9 +25,7 @@
     Domain::Domain, KeyDescriptor::KeyDescriptor,
 };
 
-use android_security_maintenance::aidl::android::security::maintenance::{
-    IKeystoreMaintenance::IKeystoreMaintenance, UserState::UserState,
-};
+use android_security_maintenance::aidl::android::security::maintenance::IKeystoreMaintenance::IKeystoreMaintenance;
 
 use android_security_authorization::aidl::android::security::authorization::{
     IKeystoreAuthorization::IKeystoreAuthorization, LockScreenEvent::LockScreenEvent,
@@ -241,9 +239,6 @@
                 }
             }
 
-            let maint_service = get_maintenance();
-            assert_eq!(Ok(UserState(1)), maint_service.getState(99));
-
             let mut key_params: Vec<KsKeyparameter> = Vec::new();
             for param in key_metadata.authorizations {
                 let key_param = KsKeyparameter::new(param.keyParameter.into(), param.securityLevel);
@@ -502,9 +497,6 @@
                 }
             }
 
-            let maint_service = get_maintenance();
-            assert_eq!(Ok(UserState(1)), maint_service.getState(98));
-
             let mut key_params: Vec<KsKeyparameter> = Vec::new();
             for param in key_metadata.authorizations {
                 let key_param = KsKeyparameter::new(param.keyParameter.into(), param.securityLevel);