• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use ciborium::de::Error as CbError;
2 use coset::cbor::value::Value;
3 #[cfg(feature = "builtin-bcc")]
4 use coset::AsCborValue;
5 use coset::CoseError;
6 #[cfg(feature = "builtin-bcc")]
7 use kmr_wire::read_to_value;
8 
9 pub mod cdi;
10 pub mod cwt;
11 pub mod dice;
12 pub mod gsc;
13 pub mod pub_key;
14 
15 use crate::cdi::ConfigurationDescriptor;
16 use crate::dice::CdiCert;
17 use crate::dice::DiceHandover;
18 use crate::gsc::GscBootParams;
19 use crate::pub_key::SubjectPublicKey;
20 
21 #[derive(Debug)]
22 pub enum Error {
23     NotAvailable,
24 }
25 
26 #[allow(dead_code)]
27 pub struct BootParams {
28     pub dice: DiceHandover,
29     pub gsc_boot_params: GscBootParams,
30 }
31 
32 impl Default for BootParams {
default() -> Self33     fn default() -> Self {
34         Self::new()
35     }
36 }
37 
38 #[cfg(feature = "builtin-bcc")]
39 const BOOT_PARAM_KEY: i32 = 2;
40 #[cfg(feature = "builtin-bcc")]
41 const DICE_KEY: i32 = 3;
42 
43 #[allow(dead_code)]
44 impl BootParams {
45     /// Create a boot params struct from constant data.
46     #[cfg(feature = "builtin-bcc")]
new() -> Self47     pub fn new() -> Self {
48         let data = desktop_test_data::boot::BOOT_PARAM;
49         let data = read_to_value(data).unwrap();
50         let data = data.as_map().unwrap();
51 
52         let dice = find_in_cbor_map(data, Value::Integer(DICE_KEY.into())).unwrap();
53         let dice = DiceHandover::from_cbor_value(dice.clone()).unwrap();
54 
55         let gsc_boot_params =
56             find_in_cbor_map(data, Value::Integer(BOOT_PARAM_KEY.into())).unwrap();
57         let gsc_boot_params = GscBootParams::from_cbor_value(gsc_boot_params.clone()).unwrap();
58 
59         Self { dice, gsc_boot_params }
60     }
61 
62     #[cfg(not(feature = "builtin-bcc"))]
new() -> Self63     pub fn new() -> Self {
64         Self { dice: DiceHandover::default(), gsc_boot_params: GscBootParams::default() }
65     }
66 
67     /// Returns the UDS public key for the device.
get_uds_public_key(&self) -> Result<&SubjectPublicKey, Error>68     pub fn get_uds_public_key(&self) -> Result<&SubjectPublicKey, Error> {
69         Ok(&self.dice.uds_pubkey)
70     }
71 
72     /// Returns the AP firmware CDI.
get_ap_fw_cdi(&self) -> Result<&ConfigurationDescriptor, Error>73     pub fn get_ap_fw_cdi(&self) -> Result<&ConfigurationDescriptor, Error> {
74         Ok(&self.dice.cdi_cert.cwt.cfg_descr)
75     }
76 
77     /// Returns the attestation CDI certificate.
get_attestation_cdi_certificate(&self) -> Result<&CdiCert, Error>78     pub fn get_attestation_cdi_certificate(&self) -> Result<&CdiCert, Error> {
79         Ok(&self.dice.cdi_cert)
80     }
81 
82     /// Returns the CDI keypair as a tuple (attest, seal).
get_cdi_keypair(&self) -> Result<(&[u8], &[u8]), Error>83     fn get_cdi_keypair(&self) -> Result<(&[u8], &[u8]), Error> {
84         Ok((&self.dice.cdi_attest, &self.dice.cdi_seal))
85     }
86 }
87 
88 /// Find a value in a CBOR map for the given key.
find_in_cbor_map(map: &[(Value, Value)], target: Value) -> coset::Result<&Value>89 fn find_in_cbor_map(map: &[(Value, Value)], target: Value) -> coset::Result<&Value> {
90     for (key, val) in map.iter() {
91         if *key == target {
92             return Ok(val);
93         }
94     }
95     Err(CoseError::DecodeFailed(CbError::Syntax(0)))
96 }
97 
98 /// Find a value in a CBOR map for the given key and attempt to parse it as an int.
get_cbor_int_from_map<T: std::convert::TryFrom<ciborium::value::Integer>>( map: &[(Value, Value)], key: i32, ) -> coset::Result<T>99 fn get_cbor_int_from_map<T: std::convert::TryFrom<ciborium::value::Integer>>(
100     map: &[(Value, Value)],
101     key: i32,
102 ) -> coset::Result<T> {
103     find_in_cbor_map(map, Value::Integer(key.into()))?
104         .as_integer()
105         .ok_or(CoseError::DecodeFailed(CbError::Syntax(0)))?
106         .try_into()
107         .map_err(|_| CoseError::DecodeFailed(CbError::Syntax(0)))
108 }
109 
110 /// Find a value in a CBOR map for the given key and attempt to parse it as a map.
get_cbor_array_from_map(map: &[(Value, Value)], key: i32) -> coset::Result<&Vec<Value>>111 fn get_cbor_array_from_map(map: &[(Value, Value)], key: i32) -> coset::Result<&Vec<Value>> {
112     find_in_cbor_map(map, Value::Integer(key.into()))?
113         .as_array()
114         .ok_or(CoseError::DecodeFailed(CbError::Syntax(0)))
115 }
116 
117 /// Find a value in a CBOR map for the given key and attempt to parse it as a Vec<u8>.
get_cbor_bytes_from_map(map: &[(Value, Value)], key: i32) -> coset::Result<&Vec<u8>>118 fn get_cbor_bytes_from_map(map: &[(Value, Value)], key: i32) -> coset::Result<&Vec<u8>> {
119     find_in_cbor_map(map, Value::Integer(key.into()))?
120         .as_bytes()
121         .ok_or(CoseError::DecodeFailed(CbError::Syntax(0)))
122 }
123 
124 /// Find a value in a CBOR map for the given key and attempt to parse it as a str.
get_cbor_string_from_map(map: &[(Value, Value)], key: i32) -> coset::Result<&str>125 fn get_cbor_string_from_map(map: &[(Value, Value)], key: i32) -> coset::Result<&str> {
126     find_in_cbor_map(map, Value::Integer(key.into()))?
127         .as_text()
128         .ok_or(CoseError::DecodeFailed(CbError::Syntax(0)))
129 }
130 
131 #[cfg(test)]
132 mod tests {
133     use super::*;
134     use coset::AsCborValue;
135     use kmr_wire::read_to_value;
136 
137     test::init!();
138 
139     #[test]
boot_params_test()140     fn boot_params_test() {
141         let data = desktop_test_data::boot::BOOT_PARAM;
142         let data = read_to_value(data).unwrap();
143         let data = data.as_map().unwrap();
144 
145         let dice = find_in_cbor_map(data, Value::Integer(2.into())).unwrap();
146         let _ = DiceHandover::from_cbor_value(dice.clone()).unwrap();
147 
148         let gsc_boot_params = find_in_cbor_map(data, Value::Integer(3.into())).unwrap();
149         let _ = GscBootParams::from_cbor_value(gsc_boot_params.clone()).unwrap();
150     }
151 }
152