blob: f49fedb0371f40fc405be793ebe35c4cac921489 [file] [log] [blame]
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +00001// Copyright 2022, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Support for DICE derivation and BCC generation.
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +000016extern crate alloc;
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +000017
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +000018use alloc::format;
19use alloc::vec::Vec;
20use ciborium::cbor;
21use ciborium::Value;
Alice Wang1f0add02023-01-23 16:22:53 +000022use core::mem::size_of;
Alice Wang843d8312023-02-15 09:47:06 +000023use diced_open_dice::{
Alice Wang87fbc4b2024-11-05 13:09:58 +000024 bcc_handover_main_flow, hash, Config, DiceContext, DiceMode, Hash, InputValues, HIDDEN_SIZE,
Alice Wang843d8312023-02-15 09:47:06 +000025};
Alan Stokesa639b582023-11-22 13:14:27 +000026use pvmfw_avb::{Capability, DebugLevel, Digest, VerifiedBootData};
Andrew Walbran47d316e2024-11-28 18:41:09 +000027use zerocopy::Immutable;
28use zerocopy::IntoBytes;
29use zerocopy::KnownLayout;
Alice Wang1f0add02023-01-23 16:22:53 +000030
Shikha Panwar47e5b612024-05-20 19:50:02 +000031// pVM firmware (like other VM components) is expected to populate some fields in DICE
32// Configuration Descriptor. See dice_for_avf_guest.cddl
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +000033const COMPONENT_NAME_KEY: i64 = -70002;
34const SECURITY_VERSION_KEY: i64 = -70005;
35const RKP_VM_MARKER_KEY: i64 = -70006;
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +000036const INSTANCE_HASH_KEY: i64 = -71003;
37
38#[derive(Debug)]
39pub enum Error {
40 /// Error in CBOR operations
Stephen Hinese1b42892024-08-07 11:03:44 -070041 #[allow(dead_code)]
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +000042 CborError(ciborium::value::Error),
43 /// Error in DICE operations
Stephen Hinese1b42892024-08-07 11:03:44 -070044 #[allow(dead_code)]
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +000045 DiceError(diced_open_dice::DiceError),
46}
47
48impl From<ciborium::value::Error> for Error {
49 fn from(e: ciborium::value::Error) -> Self {
50 Self::CborError(e)
51 }
52}
53
54impl From<diced_open_dice::DiceError> for Error {
55 fn from(e: diced_open_dice::DiceError) -> Self {
56 Self::DiceError(e)
57 }
58}
59
60// DICE in pvmfw result type.
61type Result<T> = core::result::Result<T, Error>;
62
Alice Wang31226132023-01-31 12:44:39 +000063fn to_dice_mode(debug_level: DebugLevel) -> DiceMode {
Alice Wang1f0add02023-01-23 16:22:53 +000064 match debug_level {
Alice Wang31226132023-01-31 12:44:39 +000065 DebugLevel::None => DiceMode::kDiceModeNormal,
66 DebugLevel::Full => DiceMode::kDiceModeDebug,
Alice Wang1f0add02023-01-23 16:22:53 +000067 }
68}
69
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +000070fn to_dice_hash(verified_boot_data: &VerifiedBootData) -> Result<Hash> {
Alice Wang1f0add02023-01-23 16:22:53 +000071 let mut digests = [0u8; size_of::<Digest>() * 2];
72 digests[..size_of::<Digest>()].copy_from_slice(&verified_boot_data.kernel_digest);
73 if let Some(initrd_digest) = verified_boot_data.initrd_digest {
74 digests[size_of::<Digest>()..].copy_from_slice(&initrd_digest);
75 }
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +000076 Ok(hash(&digests)?)
Alice Wang1f0add02023-01-23 16:22:53 +000077}
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +000078
Shikha Panwarf3acfd12024-05-28 15:48:13 +000079#[derive(Clone)]
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +000080pub struct PartialInputs {
Pierre-Clément Tosi1cc5eb72023-02-02 11:09:18 +000081 pub code_hash: Hash,
82 pub auth_hash: Hash,
83 pub mode: DiceMode,
Shikha Panwara26f16a2023-09-27 09:39:00 +000084 pub security_version: u64,
Alan Stokesa639b582023-11-22 13:14:27 +000085 pub rkp_vm_marker: bool,
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +000086}
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +000087
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +000088impl PartialInputs {
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +000089 pub fn new(data: &VerifiedBootData) -> Result<Self> {
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +000090 let code_hash = to_dice_hash(data)?;
91 let auth_hash = hash(data.public_key)?;
92 let mode = to_dice_mode(data.debug_level);
Shikha Panwara26f16a2023-09-27 09:39:00 +000093 // We use rollback_index from vbmeta as the security_version field in dice certificate.
94 let security_version = data.rollback_index;
Alice Wang8b5274a2025-01-17 09:31:43 +000095 let rkp_vm_marker = data.has_capability(Capability::RemoteAttest)
96 || data.has_capability(Capability::TrustySecurityVm);
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +000097
Alan Stokesa639b582023-11-22 13:14:27 +000098 Ok(Self { code_hash, auth_hash, mode, security_version, rkp_vm_marker })
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +000099 }
100
Alan Stokesc4354b82023-05-04 16:06:52 +0100101 pub fn write_next_bcc(
Alice Wang843d8312023-02-15 09:47:06 +0000102 self,
Alan Stokesc4354b82023-05-04 16:06:52 +0100103 current_bcc_handover: &[u8],
Alice Wang843d8312023-02-15 09:47:06 +0000104 salt: &[u8; HIDDEN_SIZE],
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000105 instance_hash: Option<Hash>,
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000106 deferred_rollback_protection: bool,
Alan Stokesc4354b82023-05-04 16:06:52 +0100107 next_bcc: &mut [u8],
Alice Wang87fbc4b2024-11-05 13:09:58 +0000108 context: DiceContext,
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000109 ) -> Result<()> {
110 let config = self
111 .generate_config_descriptor(instance_hash)
112 .map_err(|_| diced_open_dice::DiceError::InvalidInput)?;
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +0000113
Alan Stokesc4354b82023-05-04 16:06:52 +0100114 let dice_inputs = InputValues::new(
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +0000115 self.code_hash,
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000116 Config::Descriptor(&config),
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +0000117 self.auth_hash,
118 self.mode,
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000119 self.make_hidden(salt, deferred_rollback_protection)?,
Alan Stokesc4354b82023-05-04 16:06:52 +0100120 );
Alice Wang87fbc4b2024-11-05 13:09:58 +0000121 let _ = bcc_handover_main_flow(current_bcc_handover, &dice_inputs, next_bcc, context)?;
Alan Stokesc4354b82023-05-04 16:06:52 +0100122 Ok(())
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +0000123 }
Alan Stokesddb988c2023-11-27 11:13:06 +0000124
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000125 fn make_hidden(
126 &self,
127 salt: &[u8; HIDDEN_SIZE],
128 deferred_rollback_protection: bool,
129 ) -> diced_open_dice::Result<[u8; HIDDEN_SIZE]> {
Alan Stokesa17cfba2024-02-14 17:34:51 +0000130 // We want to make sure we get a different sealing CDI for:
131 // - VMs with different salt values
132 // - An RKP VM and any other VM (regardless of salt)
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000133 // - depending on whether rollback protection has been deferred to payload. This ensures the
134 // adversary cannot leak the secrets by using old images & setting
135 // `deferred_rollback_protection` to true.
Alan Stokesa17cfba2024-02-14 17:34:51 +0000136 // The hidden input for DICE affects the sealing CDI (but the values in the config
137 // descriptor do not).
138 // Since the hidden input has to be a fixed size, create it as a hash of the values we
139 // want included.
Andrew Walbran47d316e2024-11-28 18:41:09 +0000140 #[derive(Immutable, IntoBytes, KnownLayout)]
Alan Stokesa17cfba2024-02-14 17:34:51 +0000141 #[repr(C, packed)]
142 struct HiddenInput {
143 rkp_vm_marker: bool,
144 salt: [u8; HIDDEN_SIZE],
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000145 deferred_rollback_protection: bool,
Alan Stokesa17cfba2024-02-14 17:34:51 +0000146 }
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000147 hash(
148 HiddenInput {
149 rkp_vm_marker: self.rkp_vm_marker,
150 salt: *salt,
151 deferred_rollback_protection,
152 }
153 .as_bytes(),
154 )
Alan Stokesa17cfba2024-02-14 17:34:51 +0000155 }
156
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000157 fn generate_config_descriptor(&self, instance_hash: Option<Hash>) -> Result<Vec<u8>> {
158 let mut config = Vec::with_capacity(4);
159 config.push((cbor!(COMPONENT_NAME_KEY)?, cbor!("vm_entry")?));
Alice Wangf13bc4b2025-01-17 10:11:09 +0000160 config.push((cbor!(SECURITY_VERSION_KEY)?, cbor!(self.security_version)?));
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000161 if self.rkp_vm_marker {
162 config.push((cbor!(RKP_VM_MARKER_KEY)?, Value::Null))
163 }
164 if let Some(instance_hash) = instance_hash {
165 config.push((cbor!(INSTANCE_HASH_KEY)?, Value::from(instance_hash.as_slice())));
166 }
167 let config = Value::Map(config);
168 Ok(cbor_util::serialize(&config).map_err(|e| {
169 ciborium::value::Error::Custom(format!("Error in serialization: {e:?}"))
170 })?)
Alan Stokesddb988c2023-11-27 11:13:06 +0000171 }
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +0000172}
Pierre-Clément Tosibec84662023-01-04 14:25:33 +0000173
Alan Stokesddb988c2023-11-27 11:13:06 +0000174#[cfg(test)]
175mod tests {
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000176 use crate::{
177 Hash, PartialInputs, COMPONENT_NAME_KEY, INSTANCE_HASH_KEY, RKP_VM_MARKER_KEY,
178 SECURITY_VERSION_KEY,
179 };
Alan Stokesddb988c2023-11-27 11:13:06 +0000180 use ciborium::Value;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000181 use diced_open_dice::DiceArtifacts;
Alice Wang87fbc4b2024-11-05 13:09:58 +0000182 use diced_open_dice::DiceContext;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000183 use diced_open_dice::DiceMode;
Alice Wang87fbc4b2024-11-05 13:09:58 +0000184 use diced_open_dice::KeyAlgorithm;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000185 use diced_open_dice::HIDDEN_SIZE;
Alice Wang87fbc4b2024-11-05 13:09:58 +0000186 use diced_sample_inputs::make_sample_bcc_and_cdis;
Alice Wang4dc62912024-12-11 08:27:15 +0000187 use hwtrust::{dice, session::Session};
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000188 use pvmfw_avb::Capability;
189 use pvmfw_avb::DebugLevel;
190 use pvmfw_avb::Digest;
191 use pvmfw_avb::VerifiedBootData;
Alan Stokesddb988c2023-11-27 11:13:06 +0000192 use std::collections::HashMap;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000193 use std::mem::size_of;
Alan Stokesddb988c2023-11-27 11:13:06 +0000194 use std::vec;
195
Alan Stokesddb988c2023-11-27 11:13:06 +0000196 const COMPONENT_VERSION_KEY: i64 = -70003;
197 const RESETTABLE_KEY: i64 = -70004;
Alan Stokesddb988c2023-11-27 11:13:06 +0000198 const BASE_VB_DATA: VerifiedBootData = VerifiedBootData {
199 debug_level: DebugLevel::None,
200 kernel_digest: [1u8; size_of::<Digest>()],
201 initrd_digest: Some([2u8; size_of::<Digest>()]),
202 public_key: b"public key",
203 capabilities: vec![],
204 rollback_index: 42,
Pierre-Clément Tosi938b4fb2024-11-26 12:59:47 +0000205 page_size: None,
Alan Stokesddb988c2023-11-27 11:13:06 +0000206 };
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000207 const HASH: Hash = *b"sixtyfourbyteslongsentencearerarebutletsgiveitatrycantbethathard";
Alan Stokesddb988c2023-11-27 11:13:06 +0000208
209 #[test]
210 fn base_data_conversion() {
211 let vb_data = BASE_VB_DATA;
212 let inputs = PartialInputs::new(&vb_data).unwrap();
213
214 assert_eq!(inputs.mode, DiceMode::kDiceModeNormal);
215 assert_eq!(inputs.security_version, 42);
216 assert!(!inputs.rkp_vm_marker);
217
218 // TODO(b/313608219): Consider checks for code_hash and possibly auth_hash.
219 }
220
221 #[test]
222 fn debuggable_conversion() {
223 let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
224 let inputs = PartialInputs::new(&vb_data).unwrap();
225
226 assert_eq!(inputs.mode, DiceMode::kDiceModeDebug);
227 }
228
229 #[test]
230 fn rkp_vm_conversion() {
231 let vb_data =
232 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
233 let inputs = PartialInputs::new(&vb_data).unwrap();
234
235 assert!(inputs.rkp_vm_marker);
236 }
237
238 #[test]
239 fn base_config_descriptor() {
240 let vb_data = BASE_VB_DATA;
241 let inputs = PartialInputs::new(&vb_data).unwrap();
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000242 let config_map = decode_config_descriptor(&inputs, None);
Alan Stokesddb988c2023-11-27 11:13:06 +0000243
244 assert_eq!(config_map.get(&COMPONENT_NAME_KEY).unwrap().as_text().unwrap(), "vm_entry");
245 assert_eq!(config_map.get(&COMPONENT_VERSION_KEY), None);
246 assert_eq!(config_map.get(&RESETTABLE_KEY), None);
Alice Wangf13bc4b2025-01-17 10:11:09 +0000247 assert_eq!(config_map.get(&SECURITY_VERSION_KEY).unwrap().as_integer().unwrap(), 42.into());
Alan Stokesddb988c2023-11-27 11:13:06 +0000248 assert_eq!(config_map.get(&RKP_VM_MARKER_KEY), None);
249 }
250
251 #[test]
Alice Wang8b5274a2025-01-17 09:31:43 +0000252 fn rkp_vm_config_descriptor_has_rkp_vm_marker() {
Alan Stokesddb988c2023-11-27 11:13:06 +0000253 let vb_data =
254 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
255 let inputs = PartialInputs::new(&vb_data).unwrap();
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000256 let config_map = decode_config_descriptor(&inputs, Some(HASH));
Alan Stokesddb988c2023-11-27 11:13:06 +0000257
258 assert!(config_map.get(&RKP_VM_MARKER_KEY).unwrap().is_null());
259 }
260
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000261 #[test]
Alice Wang8b5274a2025-01-17 09:31:43 +0000262 fn security_vm_config_descriptor_has_rkp_vm_marker() {
263 let vb_data =
264 VerifiedBootData { capabilities: vec![Capability::TrustySecurityVm], ..BASE_VB_DATA };
265 let inputs = PartialInputs::new(&vb_data).unwrap();
266 let config_map = decode_config_descriptor(&inputs, Some(HASH));
267
268 assert!(config_map.get(&RKP_VM_MARKER_KEY).unwrap().is_null());
269 }
270
271 #[test]
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000272 fn config_descriptor_with_instance_hash() {
273 let vb_data =
274 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
275 let inputs = PartialInputs::new(&vb_data).unwrap();
276 let config_map = decode_config_descriptor(&inputs, Some(HASH));
277 assert_eq!(*config_map.get(&INSTANCE_HASH_KEY).unwrap(), Value::from(HASH.as_slice()));
278 }
279
280 #[test]
281 fn config_descriptor_without_instance_hash() {
282 let vb_data =
283 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
284 let inputs = PartialInputs::new(&vb_data).unwrap();
285 let config_map = decode_config_descriptor(&inputs, None);
Chris Wailese9579642024-05-29 18:25:19 -0700286 assert!(!config_map.contains_key(&INSTANCE_HASH_KEY));
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000287 }
288
289 fn decode_config_descriptor(
290 inputs: &PartialInputs,
291 instance_hash: Option<Hash>,
292 ) -> HashMap<i64, Value> {
293 let config_descriptor = inputs.generate_config_descriptor(instance_hash).unwrap();
Alan Stokesddb988c2023-11-27 11:13:06 +0000294
295 let cbor_map =
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000296 cbor_util::deserialize::<Value>(&config_descriptor).unwrap().into_map().unwrap();
Alan Stokesddb988c2023-11-27 11:13:06 +0000297
298 cbor_map
299 .into_iter()
300 .map(|(k, v)| ((k.into_integer().unwrap().try_into().unwrap()), v))
301 .collect()
302 }
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000303
304 #[test]
305 fn changing_deferred_rpb_changes_secrets() {
306 let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
307 let inputs = PartialInputs::new(&vb_data).unwrap();
308 let mut buffer_without_defer = [0; 4096];
309 let mut buffer_with_defer = [0; 4096];
310 let mut buffer_without_defer_retry = [0; 4096];
Alice Wang87fbc4b2024-11-05 13:09:58 +0000311 let context = DiceContext {
312 authority_algorithm: KeyAlgorithm::Ed25519,
313 subject_algorithm: KeyAlgorithm::Ed25519,
314 };
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000315
316 let sample_dice_input: &[u8] = &[
317 0xa3, // CDI attest
318 0x01, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // CDI seal
321 0x02, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // DICE chain
324 0x03, 0x82, 0xa6, 0x01, 0x02, 0x03, 0x27, 0x04, 0x02, 0x20, 0x01, 0x21, 0x40, 0x22,
325 0x40, 0x84, 0x40, 0xa0, 0x40, 0x40,
326 // 8-bytes of trailing data that aren't part of the DICE chain.
327 0x84, 0x41, 0x55, 0xa0, 0x42, 0x11, 0x22, 0x40,
328 ];
329
330 inputs
331 .clone()
332 .write_next_bcc(
333 sample_dice_input,
334 &[0u8; HIDDEN_SIZE],
335 Some([0u8; 64]),
336 false,
337 &mut buffer_without_defer,
Alice Wang87fbc4b2024-11-05 13:09:58 +0000338 context.clone(),
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000339 )
340 .unwrap();
341 let bcc_handover1 = diced_open_dice::bcc_handover_parse(&buffer_without_defer).unwrap();
342
343 inputs
344 .clone()
345 .write_next_bcc(
346 sample_dice_input,
347 &[0u8; HIDDEN_SIZE],
348 Some([0u8; 64]),
349 true,
350 &mut buffer_with_defer,
Alice Wang87fbc4b2024-11-05 13:09:58 +0000351 context.clone(),
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000352 )
353 .unwrap();
354 let bcc_handover2 = diced_open_dice::bcc_handover_parse(&buffer_with_defer).unwrap();
355
356 inputs
357 .clone()
358 .write_next_bcc(
359 sample_dice_input,
360 &[0u8; HIDDEN_SIZE],
361 Some([0u8; 64]),
362 false,
363 &mut buffer_without_defer_retry,
Alice Wang87fbc4b2024-11-05 13:09:58 +0000364 context.clone(),
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000365 )
366 .unwrap();
367 let bcc_handover3 =
368 diced_open_dice::bcc_handover_parse(&buffer_without_defer_retry).unwrap();
369
370 assert_ne!(bcc_handover1.cdi_seal(), bcc_handover2.cdi_seal());
371 assert_eq!(bcc_handover1.cdi_seal(), bcc_handover3.cdi_seal());
372 }
Alice Wang87fbc4b2024-11-05 13:09:58 +0000373
374 #[test]
375 fn dice_derivation_with_different_algorithms_is_valid() {
376 let dice_artifacts = make_sample_bcc_and_cdis().unwrap();
377 let bcc_handover0_bytes = to_bcc_handover(&dice_artifacts);
378 let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
379 let inputs = PartialInputs::new(&vb_data).unwrap();
380 let mut buffer = [0; 4096];
381
382 inputs
383 .clone()
384 .write_next_bcc(
385 &bcc_handover0_bytes,
386 &[0u8; HIDDEN_SIZE],
387 Some([0u8; 64]),
388 true,
389 &mut buffer,
390 DiceContext {
391 authority_algorithm: KeyAlgorithm::Ed25519,
392 subject_algorithm: KeyAlgorithm::EcdsaP256,
393 },
394 )
395 .expect("Failed to derive Ed25519 -> EcdsaP256 BCC");
396 let bcc_handover1 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
397 let bcc_handover1_bytes = to_bcc_handover(&bcc_handover1);
398 buffer.fill(0);
399
400 inputs
401 .clone()
402 .write_next_bcc(
403 &bcc_handover1_bytes,
404 &[0u8; HIDDEN_SIZE],
405 Some([0u8; 64]),
406 true,
407 &mut buffer,
408 DiceContext {
409 authority_algorithm: KeyAlgorithm::EcdsaP256,
410 subject_algorithm: KeyAlgorithm::EcdsaP384,
411 },
412 )
413 .expect("Failed to derive EcdsaP256 -> EcdsaP384 BCC");
414 let bcc_handover2 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
415 let bcc_handover2_bytes = to_bcc_handover(&bcc_handover2);
416 buffer.fill(0);
417
418 inputs
419 .clone()
420 .write_next_bcc(
421 &bcc_handover2_bytes,
422 &[0u8; HIDDEN_SIZE],
423 Some([0u8; 64]),
424 true,
425 &mut buffer,
426 DiceContext {
427 authority_algorithm: KeyAlgorithm::EcdsaP384,
428 subject_algorithm: KeyAlgorithm::Ed25519,
429 },
430 )
431 .expect("Failed to derive EcdsaP384 -> Ed25519 BCC");
Alice Wang4dc62912024-12-11 08:27:15 +0000432 let bcc_handover3 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
Alice Wang87fbc4b2024-11-05 13:09:58 +0000433
Alice Wang4dc62912024-12-11 08:27:15 +0000434 let mut session = Session::default();
435 session.set_allow_any_mode(true);
436 let _chain = dice::Chain::from_cbor(&session, bcc_handover3.bcc().unwrap()).unwrap();
Alice Wang87fbc4b2024-11-05 13:09:58 +0000437 }
438
439 fn to_bcc_handover(dice_artifacts: &dyn DiceArtifacts) -> Vec<u8> {
440 let dice_chain = cbor_util::deserialize::<Value>(dice_artifacts.bcc().unwrap()).unwrap();
441 let bcc_handover = Value::Map(vec![
442 (Value::Integer(1.into()), Value::Bytes(dice_artifacts.cdi_attest().to_vec())),
443 (Value::Integer(2.into()), Value::Bytes(dice_artifacts.cdi_seal().to_vec())),
444 (Value::Integer(3.into()), dice_chain),
445 ]);
446 cbor_util::serialize(&bcc_handover).unwrap()
447 }
Alan Stokesddb988c2023-11-27 11:13:06 +0000448}