diff --git a/remote_provisioning/cert_validator/src/bcc.rs b/remote_provisioning/cert_validator/src/bcc.rs
index f157cf7..32d7494 100644
--- a/remote_provisioning/cert_validator/src/bcc.rs
+++ b/remote_provisioning/cert_validator/src/bcc.rs
@@ -1,20 +1,16 @@
 //! This module provides functions for validating chains of bcc certificates
 
-use crate::dice;
-use crate::publickey;
-use crate::valueas::ValueAs;
+pub mod entry;
 
 use self::entry::SubjectPublicKey;
-use anyhow::{anyhow, bail, ensure, Context, Result};
+use anyhow::{anyhow, Context, Result};
 use coset::AsCborValue;
 use coset::{
     cbor::value::Value::{self, Array},
-    iana::{self, EnumI64},
-    Algorithm, CborSerializable,
+    CborSerializable,
     CoseError::{self, EncodeFailed, UnexpectedItem},
-    CoseKey, CoseSign1, Header, RegisteredLabel,
+    CoseKey, CoseSign1,
 };
-use std::fmt;
 use std::io::Read;
 
 /// Represents a full Boot Certificate Chain (BCC). This consists of the root public key (which
@@ -113,376 +109,3 @@
 pub fn get_label_value_as_bytes(key: &coset::CoseKey, label: i64) -> Result<&Vec<u8>> {
     get_label_value(key, label)?.as_bytes().ok_or_else(|| anyhow!("Value not a bstr."))
 }
-/// This module wraps the certificate validation functions intended for BccEntry.
-pub mod entry {
-    use std::fmt::{Display, Formatter, Write};
-
-    use super::*;
-
-    /// Read a series of bcc file certificates and verify that the public key of
-    /// any given cert's payload in the series correctly signs the next cose
-    /// sign1 cert.
-    pub fn check_sign1_cert_chain(certs: &[&str]) -> Result<()> {
-        ensure!(!certs.is_empty());
-        let mut payload = Payload::from_sign1(&read(certs[0])?)
-            .context("Failed to read the first bccEntry payload")?;
-        for item in certs.iter().skip(1) {
-            payload.check().context("Validation of BccPayload entries failed.")?;
-            payload =
-                payload.check_sign1(&read(item).context("Failed to read the bccEntry payload")?)?;
-        }
-        Ok(())
-    }
-
-    /// Read a given cbor array containing bcc entries and verify that the public key
-    /// of any given cert's payload in the series correctly signs the next cose sign1
-    /// cert.
-    pub fn check_sign1_chain_array(cbor_arr: &[Value]) -> Result<()> {
-        ensure!(!cbor_arr.is_empty());
-
-        let mut writeme: Vec<u8> = Vec::new();
-        ciborium::ser::into_writer(&cbor_arr[0], &mut writeme)?;
-        let mut payload =
-            Payload::from_sign1(&CoseSign1::from_slice(&writeme).map_err(cose_error)?)
-                .context("Failed to read bccEntry payload")?;
-        for item in cbor_arr.iter().skip(1) {
-            payload.check().context("Validation of BccPayload entries failed")?;
-            writeme = Vec::new();
-            ciborium::ser::into_writer(item, &mut writeme)?;
-            let next_sign1 = &CoseSign1::from_slice(&writeme).map_err(cose_error)?;
-            payload = payload.check_sign1(next_sign1).context("Failed to read bccEntry payload")?;
-        }
-        Ok(())
-    }
-
-    /// Read a file name as string and create the BccEntry as COSE_sign1 structure.
-    pub fn read(fname: &str) -> Result<CoseSign1> {
-        let mut f = std::fs::File::open(fname)?;
-        let mut content = Vec::new();
-        f.read_to_end(&mut content)?;
-        CoseSign1::from_slice(&content).map_err(cose_error)
-    }
-
-    /// Validate the protected header of a bcc entry with respect to the provided
-    /// alg (typically originating from the subject public key of the payload).
-    pub fn check_protected_header(alg: &Option<Algorithm>, header: &Header) -> Result<()> {
-        ensure!(&header.alg == alg);
-        ensure!(header
-            .crit
-            .iter()
-            .all(|l| l == &RegisteredLabel::Assigned(iana::HeaderParameter::Alg)));
-        Ok(())
-    }
-    /// Struct describing BccPayload cbor of the BccEntry.
-    #[derive(Debug)]
-    pub struct Payload(Value);
-    impl Payload {
-        /// Construct the Payload from the parent BccEntry COSE_sign1 structure.
-        pub fn from_sign1(sign1: &CoseSign1) -> Result<Payload> {
-            Self::from_slice(sign1.payload.as_ref().ok_or_else(|| anyhow!("no payload"))?)
-        }
-
-        /// Validate entries in the Payload to be correct.
-        pub fn check(&self) -> Result<()> {
-            // Validate required fields.
-            self.map_lookup(dice::ISS)?.as_string()?;
-            self.map_lookup(dice::SUB)?.as_string()?;
-            SubjectPublicKey::from_payload(self)?.check().context("Public key failed checking")?;
-            self.map_lookup(dice::KEY_USAGE)?
-                .as_bytes()
-                .ok_or_else(|| anyhow!("Payload Key usage not bytes"))?;
-
-            // Validate required and optional fields. The required fields are those defined
-            // to be present for CDI_Certificates in the open-DICE profile.
-            // TODO: Check if the optional fields are present, and if so, ensure that
-            //       the operations applied to the mandatory fields actually reproduce the
-            //       values in the optional fields as specified in open-DICE.
-            self.0.map_lookup(dice::CODE_HASH).context("Code hash must be present.")?;
-            self.0.map_lookup(dice::CONFIG_DESC).context("Config descriptor must be present.")?;
-            self.0.map_lookup(dice::AUTHORITY_HASH).context("Authority hash must be present.")?;
-            self.0.map_lookup(dice::MODE).context("Mode must be present.")?;
-
-            // Verify that each key that does exist has the expected type.
-            self.0
-                .check_bytes_val_if_key_in_map(dice::CODE_HASH)
-                .context("Code Hash value not bytes.")?;
-            self.0
-                .check_bytes_val_if_key_in_map(dice::CODE_DESC)
-                .context("Code Descriptor value not bytes.")?;
-            self.0
-                .check_bytes_val_if_key_in_map(dice::CONFIG_HASH)
-                .context("Configuration Hash value not bytes.")?;
-            self.0
-                .check_bytes_val_if_key_in_map(dice::CONFIG_DESC)
-                .context("Configuration descriptor value not bytes.")?;
-            self.0
-                .check_bytes_val_if_key_in_map(dice::AUTHORITY_HASH)
-                .context("Authority Hash value not bytes.")?;
-            self.0
-                .check_bytes_val_if_key_in_map(dice::AUTHORITY_DESC)
-                .context("Authority descriptor value not bytes.")?;
-            self.0.check_bytes_val_if_key_in_map(dice::MODE).context("Mode value not bytes.")?;
-            Ok(())
-        }
-
-        /// Verify that the public key of this payload correctly signs the provided
-        /// BccEntry sign1 object.
-        pub fn check_sign1(&self, sign1: &CoseSign1) -> Result<Payload> {
-            let pkey = SubjectPublicKey::from_payload(self)
-                .context("Failed to construct Public key from the Bcc payload.")?;
-            let new_payload = Self::check_sign1_signature(&pkey, sign1)?;
-            ensure!(
-                self.map_lookup(dice::SUB)? == new_payload.map_lookup(dice::ISS)?,
-                "Subject/Issuer mismatch"
-            );
-            Ok(new_payload)
-        }
-
-        pub(super) fn check_sign1_signature(
-            pkey: &SubjectPublicKey,
-            sign1: &CoseSign1,
-        ) -> Result<Payload> {
-            check_protected_header(&pkey.0.alg, &sign1.protected.header)
-                .context("Validation of bcc entry protected header failed.")?;
-            let v = publickey::PublicKey::from_cose_key(&pkey.0)
-                .context("Extracting the Public key from coseKey failed.")?;
-            sign1
-                .verify_signature(b"", |s, m| v.verify(s, m, &pkey.0.alg))
-                .context("public key incorrectly signs the given cose_sign1 cert.")?;
-            let new_payload = Payload::from_sign1(sign1)
-                .context("Failed to extract bcc payload from cose_sign1")?;
-            Ok(new_payload)
-        }
-
-        fn from_slice(b: &[u8]) -> Result<Self> {
-            Ok(Payload(coset::cbor::de::from_reader(b).map_err(|e| anyhow!("CborError: {}", e))?))
-        }
-
-        fn map_lookup(&self, key: i64) -> Result<&Value> {
-            Ok(&self
-                .0
-                .as_map()
-                .ok_or_else(|| anyhow!("not a map"))?
-                .iter()
-                .find(|(k, _v)| k == &Value::from(key))
-                .ok_or_else(|| anyhow!("missing key {}", key))?
-                .1)
-        }
-    }
-
-    /// Struct wrapping the CoseKey for BccEntry.BccPayload.SubjectPublicKey
-    /// and the methods used for its validation.
-    pub struct SubjectPublicKey(CoseKey);
-    impl SubjectPublicKey {
-        pub(super) fn from_cose_key(cose_key: CoseKey) -> Self {
-            Self(cose_key)
-        }
-
-        /// Construct the SubjectPublicKey from the (bccEntry's) Payload.
-        pub fn from_payload(payload: &Payload) -> Result<SubjectPublicKey> {
-            let bytes = payload
-                .map_lookup(dice::SUBJECT_PUBLIC_KEY)?
-                .as_bytes()
-                .ok_or_else(|| anyhow!("public key not bytes"))?;
-            Self::from_slice(bytes)
-        }
-
-        fn from_slice(bytes: &[u8]) -> Result<SubjectPublicKey> {
-            Ok(SubjectPublicKey(CoseKey::from_slice(bytes).map_err(cose_error)?))
-        }
-
-        /// Perform validation on the items in the public key.
-        pub fn check(&self) -> Result<()> {
-            let pkey = &self.0;
-            if !pkey.key_ops.is_empty() {
-                ensure!(pkey
-                    .key_ops
-                    .contains(&coset::KeyOperation::Assigned(iana::KeyOperation::Verify)));
-            }
-            match pkey.kty {
-                coset::KeyType::Assigned(iana::KeyType::OKP) => {
-                    ensure!(pkey.alg == Some(coset::Algorithm::Assigned(iana::Algorithm::EdDSA)));
-                    let crv = get_label_value(pkey, iana::OkpKeyParameter::Crv as i64)?;
-                    ensure!(crv == &Value::from(iana::EllipticCurve::Ed25519 as i64));
-                }
-                coset::KeyType::Assigned(iana::KeyType::EC2) => {
-                    ensure!(pkey.alg == Some(coset::Algorithm::Assigned(iana::Algorithm::ES256)));
-                    let crv = get_label_value(pkey, iana::Ec2KeyParameter::Crv as i64)?;
-                    ensure!(crv == &Value::from(iana::EllipticCurve::P_256 as i64));
-                }
-                _ => bail!("Unexpected KeyType value: {:?}", pkey.kty),
-            }
-            Ok(())
-        }
-    }
-
-    struct ConfigDesc(Vec<(Value, Value)>);
-
-    impl AsCborValue for ConfigDesc {
-        /*
-         * CDDL (from keymint/ProtectedData.aidl):
-         *
-         *  bstr .cbor {      // Configuration Descriptor
-         *     ? -70002 : tstr,           // Component name
-         *     ? -70003 : int,            // Firmware version
-         *     ? -70004 : null,           // Resettable
-         * },
-         */
-
-        fn from_cbor_value(value: Value) -> Result<Self, CoseError> {
-            match value {
-                Value::Map(m) => Ok(Self(m)),
-                _ => Err(UnexpectedItem("something", "a map")),
-            }
-        }
-
-        fn to_cbor_value(self) -> Result<Value, CoseError> {
-            // TODO: Implement when needed
-            Err(EncodeFailed)
-        }
-    }
-
-    impl CborSerializable for ConfigDesc {}
-
-    impl Display for ConfigDesc {
-        fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
-            write_payload_label(f, dice::CONFIG_DESC)?;
-            f.write_str(":\n")?;
-            for (label, value) in &self.0 {
-                f.write_str("  ")?;
-                if let Ok(i) = label.as_i64() {
-                    write_config_desc_label(f, i)?;
-                } else {
-                    write_value(f, label)?;
-                }
-                f.write_str(": ")?;
-                write_value(f, value)?;
-                f.write_char('\n')?;
-            }
-            Ok(())
-        }
-    }
-
-    fn write_config_desc_label(f: &mut Formatter, label: i64) -> Result<(), fmt::Error> {
-        match label {
-            dice::COMPONENT_NAME => f.write_str("Component Name"),
-            dice::FIRMWARE_VERSION => f.write_str("Firmware Version"),
-            dice::RESETTABLE => f.write_str("Resettable"),
-            _ => write!(f, "{}", label),
-        }
-    }
-
-    impl Display for SubjectPublicKey {
-        fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
-            let pkey = &self.0;
-            if pkey.kty != coset::KeyType::Assigned(iana::KeyType::OKP)
-                || pkey.alg != Some(coset::Algorithm::Assigned(iana::Algorithm::EdDSA))
-            {
-                return Err(fmt::Error);
-            }
-
-            let mut separator = "";
-            for (label, value) in &pkey.params {
-                use coset::Label;
-                use iana::OkpKeyParameter;
-                if let Label::Int(i) = label {
-                    match OkpKeyParameter::from_i64(*i) {
-                        Some(OkpKeyParameter::Crv) => {
-                            if let Some(crv) =
-                                value.as_i64().ok().and_then(iana::EllipticCurve::from_i64)
-                            {
-                                f.write_str(separator)?;
-                                write!(f, "Curve: {:?}", crv)?;
-                                separator = " ";
-                            }
-                        }
-                        Some(OkpKeyParameter::X) => {
-                            if let Ok(x) = ValueAs::as_bytes(value) {
-                                f.write_str(separator)?;
-                                f.write_str("X: ")?;
-                                write_bytes_in_hex(f, x)?;
-                                separator = " ";
-                            }
-                        }
-                        _ => (),
-                    }
-                }
-            }
-
-            Ok(())
-        }
-    }
-
-    impl Display for Payload {
-        fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
-            for (label, value) in self.0.as_map().ok_or(fmt::Error)? {
-                if let Ok(i) = label.as_i64() {
-                    if i == dice::CONFIG_DESC {
-                        write_config_desc(f, value)?;
-                        continue;
-                    } else if i == dice::SUBJECT_PUBLIC_KEY {
-                        write_payload_label(f, i)?;
-                        f.write_str(": ")?;
-                        write_subject_public_key(f, value)?;
-                        continue;
-                    }
-                    write_payload_label(f, i)?;
-                } else {
-                    write_value(f, label)?;
-                }
-                f.write_str(": ")?;
-                write_value(f, value)?;
-                f.write_char('\n')?;
-            }
-            Ok(())
-        }
-    }
-
-    fn write_payload_label(f: &mut Formatter, label: i64) -> Result<(), fmt::Error> {
-        match label {
-            dice::ISS => f.write_str("Issuer"),
-            dice::SUB => f.write_str("Subject"),
-            dice::CODE_HASH => f.write_str("Code Hash"),
-            dice::CODE_DESC => f.write_str("Code Desc"),
-            dice::CONFIG_DESC => f.write_str("Config Desc"),
-            dice::CONFIG_HASH => f.write_str("Config Hash"),
-            dice::AUTHORITY_HASH => f.write_str("Authority Hash"),
-            dice::AUTHORITY_DESC => f.write_str("Authority Desc"),
-            dice::MODE => f.write_str("Mode"),
-            dice::SUBJECT_PUBLIC_KEY => f.write_str("Subject Public Key"),
-            dice::KEY_USAGE => f.write_str("Key Usage"),
-            _ => write!(f, "{}", label),
-        }
-    }
-
-    fn write_config_desc(f: &mut Formatter, value: &Value) -> Result<(), fmt::Error> {
-        let bytes = value.as_bytes().ok_or(fmt::Error)?;
-        let config_desc = ConfigDesc::from_slice(bytes).map_err(|_| fmt::Error)?;
-        write!(f, "{}", config_desc)
-    }
-
-    fn write_subject_public_key(f: &mut Formatter, value: &Value) -> Result<(), fmt::Error> {
-        let bytes = value.as_bytes().ok_or(fmt::Error)?;
-        let subject_public_key = SubjectPublicKey::from_slice(bytes).map_err(|_| fmt::Error)?;
-        write!(f, "{}", subject_public_key)
-    }
-
-    fn write_value(f: &mut Formatter, value: &Value) -> Result<(), fmt::Error> {
-        if let Some(bytes) = value.as_bytes() {
-            write_bytes_in_hex(f, bytes)
-        } else if let Some(text) = value.as_text() {
-            write!(f, "\"{}\"", text)
-        } else if let Ok(integer) = value.as_i64() {
-            write!(f, "{}", integer)
-        } else {
-            write!(f, "{:?}", value)
-        }
-    }
-
-    fn write_bytes_in_hex(f: &mut Formatter, bytes: &[u8]) -> Result<(), fmt::Error> {
-        for b in bytes {
-            write!(f, "{:02x}", b)?
-        }
-        Ok(())
-    }
-}
diff --git a/remote_provisioning/cert_validator/src/bcc/entry.rs b/remote_provisioning/cert_validator/src/bcc/entry.rs
new file mode 100644
index 0000000..2ebc12e
--- /dev/null
+++ b/remote_provisioning/cert_validator/src/bcc/entry.rs
@@ -0,0 +1,383 @@
+//! This module wraps the certificate validation functions intended for BccEntry.
+
+use super::{cose_error, get_label_value};
+use crate::dice;
+use crate::publickey;
+use crate::valueas::ValueAs;
+use anyhow::{anyhow, bail, ensure, Context, Result};
+use coset::AsCborValue;
+use coset::{
+    cbor::value::Value,
+    iana::{self, EnumI64},
+    Algorithm, CborSerializable,
+    CoseError::{self, EncodeFailed, UnexpectedItem},
+    CoseKey, CoseSign1, Header, RegisteredLabel,
+};
+use std::fmt::{self, Display, Formatter, Write};
+use std::io::Read;
+
+/// Read a series of bcc file certificates and verify that the public key of
+/// any given cert's payload in the series correctly signs the next cose
+/// sign1 cert.
+pub fn check_sign1_cert_chain(certs: &[&str]) -> Result<()> {
+    ensure!(!certs.is_empty());
+    let mut payload = Payload::from_sign1(&read(certs[0])?)
+        .context("Failed to read the first bccEntry payload")?;
+    for item in certs.iter().skip(1) {
+        payload.check().context("Validation of BccPayload entries failed.")?;
+        payload =
+            payload.check_sign1(&read(item).context("Failed to read the bccEntry payload")?)?;
+    }
+    Ok(())
+}
+
+/// Read a given cbor array containing bcc entries and verify that the public key
+/// of any given cert's payload in the series correctly signs the next cose sign1
+/// cert.
+pub fn check_sign1_chain_array(cbor_arr: &[Value]) -> Result<()> {
+    ensure!(!cbor_arr.is_empty());
+
+    let mut writeme: Vec<u8> = Vec::new();
+    ciborium::ser::into_writer(&cbor_arr[0], &mut writeme)?;
+    let mut payload = Payload::from_sign1(&CoseSign1::from_slice(&writeme).map_err(cose_error)?)
+        .context("Failed to read bccEntry payload")?;
+    for item in cbor_arr.iter().skip(1) {
+        payload.check().context("Validation of BccPayload entries failed")?;
+        writeme = Vec::new();
+        ciborium::ser::into_writer(item, &mut writeme)?;
+        let next_sign1 = &CoseSign1::from_slice(&writeme).map_err(cose_error)?;
+        payload = payload.check_sign1(next_sign1).context("Failed to read bccEntry payload")?;
+    }
+    Ok(())
+}
+
+/// Read a file name as string and create the BccEntry as COSE_sign1 structure.
+pub fn read(fname: &str) -> Result<CoseSign1> {
+    let mut f = std::fs::File::open(fname)?;
+    let mut content = Vec::new();
+    f.read_to_end(&mut content)?;
+    CoseSign1::from_slice(&content).map_err(cose_error)
+}
+
+/// Validate the protected header of a bcc entry with respect to the provided
+/// alg (typically originating from the subject public key of the payload).
+pub fn check_protected_header(alg: &Option<Algorithm>, header: &Header) -> Result<()> {
+    ensure!(&header.alg == alg);
+    ensure!(header
+        .crit
+        .iter()
+        .all(|l| l == &RegisteredLabel::Assigned(iana::HeaderParameter::Alg)));
+    Ok(())
+}
+/// Struct describing BccPayload cbor of the BccEntry.
+#[derive(Debug)]
+pub struct Payload(Value);
+impl Payload {
+    /// Construct the Payload from the parent BccEntry COSE_sign1 structure.
+    pub fn from_sign1(sign1: &CoseSign1) -> Result<Payload> {
+        Self::from_slice(sign1.payload.as_ref().ok_or_else(|| anyhow!("no payload"))?)
+    }
+
+    /// Validate entries in the Payload to be correct.
+    pub fn check(&self) -> Result<()> {
+        // Validate required fields.
+        self.map_lookup(dice::ISS)?.as_string()?;
+        self.map_lookup(dice::SUB)?.as_string()?;
+        SubjectPublicKey::from_payload(self)?.check().context("Public key failed checking")?;
+        self.map_lookup(dice::KEY_USAGE)?
+            .as_bytes()
+            .ok_or_else(|| anyhow!("Payload Key usage not bytes"))?;
+
+        // Validate required and optional fields. The required fields are those defined
+        // to be present for CDI_Certificates in the open-DICE profile.
+        // TODO: Check if the optional fields are present, and if so, ensure that
+        //       the operations applied to the mandatory fields actually reproduce the
+        //       values in the optional fields as specified in open-DICE.
+        self.0.map_lookup(dice::CODE_HASH).context("Code hash must be present.")?;
+        self.0.map_lookup(dice::CONFIG_DESC).context("Config descriptor must be present.")?;
+        self.0.map_lookup(dice::AUTHORITY_HASH).context("Authority hash must be present.")?;
+        self.0.map_lookup(dice::MODE).context("Mode must be present.")?;
+
+        // Verify that each key that does exist has the expected type.
+        self.0
+            .check_bytes_val_if_key_in_map(dice::CODE_HASH)
+            .context("Code Hash value not bytes.")?;
+        self.0
+            .check_bytes_val_if_key_in_map(dice::CODE_DESC)
+            .context("Code Descriptor value not bytes.")?;
+        self.0
+            .check_bytes_val_if_key_in_map(dice::CONFIG_HASH)
+            .context("Configuration Hash value not bytes.")?;
+        self.0
+            .check_bytes_val_if_key_in_map(dice::CONFIG_DESC)
+            .context("Configuration descriptor value not bytes.")?;
+        self.0
+            .check_bytes_val_if_key_in_map(dice::AUTHORITY_HASH)
+            .context("Authority Hash value not bytes.")?;
+        self.0
+            .check_bytes_val_if_key_in_map(dice::AUTHORITY_DESC)
+            .context("Authority descriptor value not bytes.")?;
+        self.0.check_bytes_val_if_key_in_map(dice::MODE).context("Mode value not bytes.")?;
+        Ok(())
+    }
+
+    /// Verify that the public key of this payload correctly signs the provided
+    /// BccEntry sign1 object.
+    pub fn check_sign1(&self, sign1: &CoseSign1) -> Result<Payload> {
+        let pkey = SubjectPublicKey::from_payload(self)
+            .context("Failed to construct Public key from the Bcc payload.")?;
+        let new_payload = Self::check_sign1_signature(&pkey, sign1)?;
+        ensure!(
+            self.map_lookup(dice::SUB)? == new_payload.map_lookup(dice::ISS)?,
+            "Subject/Issuer mismatch"
+        );
+        Ok(new_payload)
+    }
+
+    pub(super) fn check_sign1_signature(
+        pkey: &SubjectPublicKey,
+        sign1: &CoseSign1,
+    ) -> Result<Payload> {
+        check_protected_header(&pkey.0.alg, &sign1.protected.header)
+            .context("Validation of bcc entry protected header failed.")?;
+        let v = publickey::PublicKey::from_cose_key(&pkey.0)
+            .context("Extracting the Public key from coseKey failed.")?;
+        sign1
+            .verify_signature(b"", |s, m| v.verify(s, m, &pkey.0.alg))
+            .context("public key incorrectly signs the given cose_sign1 cert.")?;
+        let new_payload =
+            Payload::from_sign1(sign1).context("Failed to extract bcc payload from cose_sign1")?;
+        Ok(new_payload)
+    }
+
+    fn from_slice(b: &[u8]) -> Result<Self> {
+        Ok(Payload(coset::cbor::de::from_reader(b).map_err(|e| anyhow!("CborError: {}", e))?))
+    }
+
+    fn map_lookup(&self, key: i64) -> Result<&Value> {
+        Ok(&self
+            .0
+            .as_map()
+            .ok_or_else(|| anyhow!("not a map"))?
+            .iter()
+            .find(|(k, _v)| k == &Value::from(key))
+            .ok_or_else(|| anyhow!("missing key {}", key))?
+            .1)
+    }
+}
+
+/// Struct wrapping the CoseKey for BccEntry.BccPayload.SubjectPublicKey
+/// and the methods used for its validation.
+pub struct SubjectPublicKey(CoseKey);
+impl SubjectPublicKey {
+    pub(super) fn from_cose_key(cose_key: CoseKey) -> Self {
+        Self(cose_key)
+    }
+
+    /// Construct the SubjectPublicKey from the (bccEntry's) Payload.
+    pub fn from_payload(payload: &Payload) -> Result<SubjectPublicKey> {
+        let bytes = payload
+            .map_lookup(dice::SUBJECT_PUBLIC_KEY)?
+            .as_bytes()
+            .ok_or_else(|| anyhow!("public key not bytes"))?;
+        Self::from_slice(bytes)
+    }
+
+    fn from_slice(bytes: &[u8]) -> Result<SubjectPublicKey> {
+        Ok(SubjectPublicKey(CoseKey::from_slice(bytes).map_err(cose_error)?))
+    }
+
+    /// Perform validation on the items in the public key.
+    pub fn check(&self) -> Result<()> {
+        let pkey = &self.0;
+        if !pkey.key_ops.is_empty() {
+            ensure!(pkey
+                .key_ops
+                .contains(&coset::KeyOperation::Assigned(iana::KeyOperation::Verify)));
+        }
+        match pkey.kty {
+            coset::KeyType::Assigned(iana::KeyType::OKP) => {
+                ensure!(pkey.alg == Some(coset::Algorithm::Assigned(iana::Algorithm::EdDSA)));
+                let crv = get_label_value(pkey, iana::OkpKeyParameter::Crv as i64)?;
+                ensure!(crv == &Value::from(iana::EllipticCurve::Ed25519 as i64));
+            }
+            coset::KeyType::Assigned(iana::KeyType::EC2) => {
+                ensure!(pkey.alg == Some(coset::Algorithm::Assigned(iana::Algorithm::ES256)));
+                let crv = get_label_value(pkey, iana::Ec2KeyParameter::Crv as i64)?;
+                ensure!(crv == &Value::from(iana::EllipticCurve::P_256 as i64));
+            }
+            _ => bail!("Unexpected KeyType value: {:?}", pkey.kty),
+        }
+        Ok(())
+    }
+}
+
+struct ConfigDesc(Vec<(Value, Value)>);
+
+impl AsCborValue for ConfigDesc {
+    /*
+     * CDDL (from keymint/ProtectedData.aidl):
+     *
+     *  bstr .cbor {      // Configuration Descriptor
+     *     ? -70002 : tstr,           // Component name
+     *     ? -70003 : int,            // Firmware version
+     *     ? -70004 : null,           // Resettable
+     * },
+     */
+
+    fn from_cbor_value(value: Value) -> Result<Self, CoseError> {
+        match value {
+            Value::Map(m) => Ok(Self(m)),
+            _ => Err(UnexpectedItem("something", "a map")),
+        }
+    }
+
+    fn to_cbor_value(self) -> Result<Value, CoseError> {
+        // TODO: Implement when needed
+        Err(EncodeFailed)
+    }
+}
+
+impl CborSerializable for ConfigDesc {}
+
+impl Display for ConfigDesc {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
+        write_payload_label(f, dice::CONFIG_DESC)?;
+        f.write_str(":\n")?;
+        for (label, value) in &self.0 {
+            f.write_str("  ")?;
+            if let Ok(i) = label.as_i64() {
+                write_config_desc_label(f, i)?;
+            } else {
+                write_value(f, label)?;
+            }
+            f.write_str(": ")?;
+            write_value(f, value)?;
+            f.write_char('\n')?;
+        }
+        Ok(())
+    }
+}
+
+fn write_config_desc_label(f: &mut Formatter, label: i64) -> Result<(), fmt::Error> {
+    match label {
+        dice::COMPONENT_NAME => f.write_str("Component Name"),
+        dice::FIRMWARE_VERSION => f.write_str("Firmware Version"),
+        dice::RESETTABLE => f.write_str("Resettable"),
+        _ => write!(f, "{}", label),
+    }
+}
+
+impl Display for SubjectPublicKey {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
+        let pkey = &self.0;
+        if pkey.kty != coset::KeyType::Assigned(iana::KeyType::OKP)
+            || pkey.alg != Some(coset::Algorithm::Assigned(iana::Algorithm::EdDSA))
+        {
+            return Err(fmt::Error);
+        }
+
+        let mut separator = "";
+        for (label, value) in &pkey.params {
+            use coset::Label;
+            use iana::OkpKeyParameter;
+            if let Label::Int(i) = label {
+                match OkpKeyParameter::from_i64(*i) {
+                    Some(OkpKeyParameter::Crv) => {
+                        if let Some(crv) =
+                            value.as_i64().ok().and_then(iana::EllipticCurve::from_i64)
+                        {
+                            f.write_str(separator)?;
+                            write!(f, "Curve: {:?}", crv)?;
+                            separator = " ";
+                        }
+                    }
+                    Some(OkpKeyParameter::X) => {
+                        if let Ok(x) = ValueAs::as_bytes(value) {
+                            f.write_str(separator)?;
+                            f.write_str("X: ")?;
+                            write_bytes_in_hex(f, x)?;
+                            separator = " ";
+                        }
+                    }
+                    _ => (),
+                }
+            }
+        }
+
+        Ok(())
+    }
+}
+
+impl Display for Payload {
+    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
+        for (label, value) in self.0.as_map().ok_or(fmt::Error)? {
+            if let Ok(i) = label.as_i64() {
+                if i == dice::CONFIG_DESC {
+                    write_config_desc(f, value)?;
+                    continue;
+                } else if i == dice::SUBJECT_PUBLIC_KEY {
+                    write_payload_label(f, i)?;
+                    f.write_str(": ")?;
+                    write_subject_public_key(f, value)?;
+                    continue;
+                }
+                write_payload_label(f, i)?;
+            } else {
+                write_value(f, label)?;
+            }
+            f.write_str(": ")?;
+            write_value(f, value)?;
+            f.write_char('\n')?;
+        }
+        Ok(())
+    }
+}
+
+fn write_payload_label(f: &mut Formatter, label: i64) -> Result<(), fmt::Error> {
+    match label {
+        dice::ISS => f.write_str("Issuer"),
+        dice::SUB => f.write_str("Subject"),
+        dice::CODE_HASH => f.write_str("Code Hash"),
+        dice::CODE_DESC => f.write_str("Code Desc"),
+        dice::CONFIG_DESC => f.write_str("Config Desc"),
+        dice::CONFIG_HASH => f.write_str("Config Hash"),
+        dice::AUTHORITY_HASH => f.write_str("Authority Hash"),
+        dice::AUTHORITY_DESC => f.write_str("Authority Desc"),
+        dice::MODE => f.write_str("Mode"),
+        dice::SUBJECT_PUBLIC_KEY => f.write_str("Subject Public Key"),
+        dice::KEY_USAGE => f.write_str("Key Usage"),
+        _ => write!(f, "{}", label),
+    }
+}
+
+fn write_config_desc(f: &mut Formatter, value: &Value) -> Result<(), fmt::Error> {
+    let bytes = value.as_bytes().ok_or(fmt::Error)?;
+    let config_desc = ConfigDesc::from_slice(bytes).map_err(|_| fmt::Error)?;
+    write!(f, "{}", config_desc)
+}
+
+fn write_subject_public_key(f: &mut Formatter, value: &Value) -> Result<(), fmt::Error> {
+    let bytes = value.as_bytes().ok_or(fmt::Error)?;
+    let subject_public_key = SubjectPublicKey::from_slice(bytes).map_err(|_| fmt::Error)?;
+    write!(f, "{}", subject_public_key)
+}
+
+fn write_value(f: &mut Formatter, value: &Value) -> Result<(), fmt::Error> {
+    if let Some(bytes) = value.as_bytes() {
+        write_bytes_in_hex(f, bytes)
+    } else if let Some(text) = value.as_text() {
+        write!(f, "\"{}\"", text)
+    } else if let Ok(integer) = value.as_i64() {
+        write!(f, "{}", integer)
+    } else {
+        write!(f, "{:?}", value)
+    }
+}
+
+fn write_bytes_in_hex(f: &mut Formatter, bytes: &[u8]) -> Result<(), fmt::Error> {
+    for b in bytes {
+        write!(f, "{:02x}", b)?
+    }
+    Ok(())
+}
