blob: 78bd6b8cca20958272ac0509cee564aca7fd9aea [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;
Alan Stokesa639b582023-11-22 13:14:27 +000095 let rkp_vm_marker = data.has_capability(Capability::RemoteAttest);
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +000096
Alan Stokesa639b582023-11-22 13:14:27 +000097 Ok(Self { code_hash, auth_hash, mode, security_version, rkp_vm_marker })
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +000098 }
99
Alan Stokesc4354b82023-05-04 16:06:52 +0100100 pub fn write_next_bcc(
Alice Wang843d8312023-02-15 09:47:06 +0000101 self,
Alan Stokesc4354b82023-05-04 16:06:52 +0100102 current_bcc_handover: &[u8],
Alice Wang843d8312023-02-15 09:47:06 +0000103 salt: &[u8; HIDDEN_SIZE],
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000104 instance_hash: Option<Hash>,
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000105 deferred_rollback_protection: bool,
Alan Stokesc4354b82023-05-04 16:06:52 +0100106 next_bcc: &mut [u8],
Alice Wang87fbc4b2024-11-05 13:09:58 +0000107 context: DiceContext,
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000108 ) -> Result<()> {
109 let config = self
110 .generate_config_descriptor(instance_hash)
111 .map_err(|_| diced_open_dice::DiceError::InvalidInput)?;
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +0000112
Alan Stokesc4354b82023-05-04 16:06:52 +0100113 let dice_inputs = InputValues::new(
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +0000114 self.code_hash,
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000115 Config::Descriptor(&config),
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +0000116 self.auth_hash,
117 self.mode,
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000118 self.make_hidden(salt, deferred_rollback_protection)?,
Alan Stokesc4354b82023-05-04 16:06:52 +0100119 );
Alice Wang87fbc4b2024-11-05 13:09:58 +0000120 let _ = bcc_handover_main_flow(current_bcc_handover, &dice_inputs, next_bcc, context)?;
Alan Stokesc4354b82023-05-04 16:06:52 +0100121 Ok(())
Pierre-Clément Tosif58f3a32023-02-02 16:24:23 +0000122 }
Alan Stokesddb988c2023-11-27 11:13:06 +0000123
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000124 fn make_hidden(
125 &self,
126 salt: &[u8; HIDDEN_SIZE],
127 deferred_rollback_protection: bool,
128 ) -> diced_open_dice::Result<[u8; HIDDEN_SIZE]> {
Alan Stokesa17cfba2024-02-14 17:34:51 +0000129 // We want to make sure we get a different sealing CDI for:
130 // - VMs with different salt values
131 // - An RKP VM and any other VM (regardless of salt)
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000132 // - depending on whether rollback protection has been deferred to payload. This ensures the
133 // adversary cannot leak the secrets by using old images & setting
134 // `deferred_rollback_protection` to true.
Alan Stokesa17cfba2024-02-14 17:34:51 +0000135 // The hidden input for DICE affects the sealing CDI (but the values in the config
136 // descriptor do not).
137 // Since the hidden input has to be a fixed size, create it as a hash of the values we
138 // want included.
Andrew Walbran47d316e2024-11-28 18:41:09 +0000139 #[derive(Immutable, IntoBytes, KnownLayout)]
Alan Stokesa17cfba2024-02-14 17:34:51 +0000140 #[repr(C, packed)]
141 struct HiddenInput {
142 rkp_vm_marker: bool,
143 salt: [u8; HIDDEN_SIZE],
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000144 deferred_rollback_protection: bool,
Alan Stokesa17cfba2024-02-14 17:34:51 +0000145 }
Shikha Panwarffadd4d2024-05-28 13:47:56 +0000146 hash(
147 HiddenInput {
148 rkp_vm_marker: self.rkp_vm_marker,
149 salt: *salt,
150 deferred_rollback_protection,
151 }
152 .as_bytes(),
153 )
Alan Stokesa17cfba2024-02-14 17:34:51 +0000154 }
155
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000156 fn generate_config_descriptor(&self, instance_hash: Option<Hash>) -> Result<Vec<u8>> {
157 let mut config = Vec::with_capacity(4);
158 config.push((cbor!(COMPONENT_NAME_KEY)?, cbor!("vm_entry")?));
159 if cfg!(dice_changes) {
160 config.push((cbor!(SECURITY_VERSION_KEY)?, cbor!(self.security_version)?));
161 }
162 if self.rkp_vm_marker {
163 config.push((cbor!(RKP_VM_MARKER_KEY)?, Value::Null))
164 }
165 if let Some(instance_hash) = instance_hash {
166 config.push((cbor!(INSTANCE_HASH_KEY)?, Value::from(instance_hash.as_slice())));
167 }
168 let config = Value::Map(config);
169 Ok(cbor_util::serialize(&config).map_err(|e| {
170 ciborium::value::Error::Custom(format!("Error in serialization: {e:?}"))
171 })?)
Alan Stokesddb988c2023-11-27 11:13:06 +0000172 }
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +0000173}
Pierre-Clément Tosibec84662023-01-04 14:25:33 +0000174
Alan Stokesddb988c2023-11-27 11:13:06 +0000175#[cfg(test)]
176mod tests {
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000177 use crate::{
178 Hash, PartialInputs, COMPONENT_NAME_KEY, INSTANCE_HASH_KEY, RKP_VM_MARKER_KEY,
179 SECURITY_VERSION_KEY,
180 };
Alan Stokesddb988c2023-11-27 11:13:06 +0000181 use ciborium::Value;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000182 use diced_open_dice::DiceArtifacts;
Alice Wang87fbc4b2024-11-05 13:09:58 +0000183 use diced_open_dice::DiceContext;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000184 use diced_open_dice::DiceMode;
Alice Wang87fbc4b2024-11-05 13:09:58 +0000185 use diced_open_dice::KeyAlgorithm;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000186 use diced_open_dice::HIDDEN_SIZE;
Alice Wang87fbc4b2024-11-05 13:09:58 +0000187 use diced_sample_inputs::make_sample_bcc_and_cdis;
Alice Wang4dc62912024-12-11 08:27:15 +0000188 use hwtrust::{dice, session::Session};
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000189 use pvmfw_avb::Capability;
190 use pvmfw_avb::DebugLevel;
191 use pvmfw_avb::Digest;
192 use pvmfw_avb::VerifiedBootData;
Alan Stokesddb988c2023-11-27 11:13:06 +0000193 use std::collections::HashMap;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000194 use std::mem::size_of;
Alan Stokesddb988c2023-11-27 11:13:06 +0000195 use std::vec;
196
Alan Stokesddb988c2023-11-27 11:13:06 +0000197 const COMPONENT_VERSION_KEY: i64 = -70003;
198 const RESETTABLE_KEY: i64 = -70004;
Alan Stokesddb988c2023-11-27 11:13:06 +0000199 const BASE_VB_DATA: VerifiedBootData = VerifiedBootData {
200 debug_level: DebugLevel::None,
201 kernel_digest: [1u8; size_of::<Digest>()],
202 initrd_digest: Some([2u8; size_of::<Digest>()]),
203 public_key: b"public key",
204 capabilities: vec![],
205 rollback_index: 42,
Pierre-Clément Tosi938b4fb2024-11-26 12:59:47 +0000206 page_size: None,
Alan Stokesddb988c2023-11-27 11:13:06 +0000207 };
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000208 const HASH: Hash = *b"sixtyfourbyteslongsentencearerarebutletsgiveitatrycantbethathard";
Alan Stokesddb988c2023-11-27 11:13:06 +0000209
210 #[test]
211 fn base_data_conversion() {
212 let vb_data = BASE_VB_DATA;
213 let inputs = PartialInputs::new(&vb_data).unwrap();
214
215 assert_eq!(inputs.mode, DiceMode::kDiceModeNormal);
216 assert_eq!(inputs.security_version, 42);
217 assert!(!inputs.rkp_vm_marker);
218
219 // TODO(b/313608219): Consider checks for code_hash and possibly auth_hash.
220 }
221
222 #[test]
223 fn debuggable_conversion() {
224 let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
225 let inputs = PartialInputs::new(&vb_data).unwrap();
226
227 assert_eq!(inputs.mode, DiceMode::kDiceModeDebug);
228 }
229
230 #[test]
231 fn rkp_vm_conversion() {
232 let vb_data =
233 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
234 let inputs = PartialInputs::new(&vb_data).unwrap();
235
236 assert!(inputs.rkp_vm_marker);
237 }
238
239 #[test]
240 fn base_config_descriptor() {
241 let vb_data = BASE_VB_DATA;
242 let inputs = PartialInputs::new(&vb_data).unwrap();
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000243 let config_map = decode_config_descriptor(&inputs, None);
Alan Stokesddb988c2023-11-27 11:13:06 +0000244
245 assert_eq!(config_map.get(&COMPONENT_NAME_KEY).unwrap().as_text().unwrap(), "vm_entry");
246 assert_eq!(config_map.get(&COMPONENT_VERSION_KEY), None);
247 assert_eq!(config_map.get(&RESETTABLE_KEY), None);
248 if cfg!(dice_changes) {
249 assert_eq!(
250 config_map.get(&SECURITY_VERSION_KEY).unwrap().as_integer().unwrap(),
251 42.into()
252 );
253 } else {
254 assert_eq!(config_map.get(&SECURITY_VERSION_KEY), None);
255 }
256 assert_eq!(config_map.get(&RKP_VM_MARKER_KEY), None);
257 }
258
259 #[test]
260 fn config_descriptor_with_rkp_vm() {
261 let vb_data =
262 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
263 let inputs = PartialInputs::new(&vb_data).unwrap();
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000264 let config_map = decode_config_descriptor(&inputs, Some(HASH));
Alan Stokesddb988c2023-11-27 11:13:06 +0000265
266 assert!(config_map.get(&RKP_VM_MARKER_KEY).unwrap().is_null());
267 }
268
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000269 #[test]
270 fn config_descriptor_with_instance_hash() {
271 let vb_data =
272 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
273 let inputs = PartialInputs::new(&vb_data).unwrap();
274 let config_map = decode_config_descriptor(&inputs, Some(HASH));
275 assert_eq!(*config_map.get(&INSTANCE_HASH_KEY).unwrap(), Value::from(HASH.as_slice()));
276 }
277
278 #[test]
279 fn config_descriptor_without_instance_hash() {
280 let vb_data =
281 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
282 let inputs = PartialInputs::new(&vb_data).unwrap();
283 let config_map = decode_config_descriptor(&inputs, None);
Chris Wailese9579642024-05-29 18:25:19 -0700284 assert!(!config_map.contains_key(&INSTANCE_HASH_KEY));
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000285 }
286
287 fn decode_config_descriptor(
288 inputs: &PartialInputs,
289 instance_hash: Option<Hash>,
290 ) -> HashMap<i64, Value> {
291 let config_descriptor = inputs.generate_config_descriptor(instance_hash).unwrap();
Alan Stokesddb988c2023-11-27 11:13:06 +0000292
293 let cbor_map =
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000294 cbor_util::deserialize::<Value>(&config_descriptor).unwrap().into_map().unwrap();
Alan Stokesddb988c2023-11-27 11:13:06 +0000295
296 cbor_map
297 .into_iter()
298 .map(|(k, v)| ((k.into_integer().unwrap().try_into().unwrap()), v))
299 .collect()
300 }
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000301
302 #[test]
303 fn changing_deferred_rpb_changes_secrets() {
304 let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
305 let inputs = PartialInputs::new(&vb_data).unwrap();
306 let mut buffer_without_defer = [0; 4096];
307 let mut buffer_with_defer = [0; 4096];
308 let mut buffer_without_defer_retry = [0; 4096];
Alice Wang87fbc4b2024-11-05 13:09:58 +0000309 let context = DiceContext {
310 authority_algorithm: KeyAlgorithm::Ed25519,
311 subject_algorithm: KeyAlgorithm::Ed25519,
312 };
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000313
314 let sample_dice_input: &[u8] = &[
315 0xa3, // CDI attest
316 0x01, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // CDI seal
319 0x02, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // DICE chain
322 0x03, 0x82, 0xa6, 0x01, 0x02, 0x03, 0x27, 0x04, 0x02, 0x20, 0x01, 0x21, 0x40, 0x22,
323 0x40, 0x84, 0x40, 0xa0, 0x40, 0x40,
324 // 8-bytes of trailing data that aren't part of the DICE chain.
325 0x84, 0x41, 0x55, 0xa0, 0x42, 0x11, 0x22, 0x40,
326 ];
327
328 inputs
329 .clone()
330 .write_next_bcc(
331 sample_dice_input,
332 &[0u8; HIDDEN_SIZE],
333 Some([0u8; 64]),
334 false,
335 &mut buffer_without_defer,
Alice Wang87fbc4b2024-11-05 13:09:58 +0000336 context.clone(),
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000337 )
338 .unwrap();
339 let bcc_handover1 = diced_open_dice::bcc_handover_parse(&buffer_without_defer).unwrap();
340
341 inputs
342 .clone()
343 .write_next_bcc(
344 sample_dice_input,
345 &[0u8; HIDDEN_SIZE],
346 Some([0u8; 64]),
347 true,
348 &mut buffer_with_defer,
Alice Wang87fbc4b2024-11-05 13:09:58 +0000349 context.clone(),
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000350 )
351 .unwrap();
352 let bcc_handover2 = diced_open_dice::bcc_handover_parse(&buffer_with_defer).unwrap();
353
354 inputs
355 .clone()
356 .write_next_bcc(
357 sample_dice_input,
358 &[0u8; HIDDEN_SIZE],
359 Some([0u8; 64]),
360 false,
361 &mut buffer_without_defer_retry,
Alice Wang87fbc4b2024-11-05 13:09:58 +0000362 context.clone(),
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000363 )
364 .unwrap();
365 let bcc_handover3 =
366 diced_open_dice::bcc_handover_parse(&buffer_without_defer_retry).unwrap();
367
368 assert_ne!(bcc_handover1.cdi_seal(), bcc_handover2.cdi_seal());
369 assert_eq!(bcc_handover1.cdi_seal(), bcc_handover3.cdi_seal());
370 }
Alice Wang87fbc4b2024-11-05 13:09:58 +0000371
372 #[test]
373 fn dice_derivation_with_different_algorithms_is_valid() {
374 let dice_artifacts = make_sample_bcc_and_cdis().unwrap();
375 let bcc_handover0_bytes = to_bcc_handover(&dice_artifacts);
376 let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
377 let inputs = PartialInputs::new(&vb_data).unwrap();
378 let mut buffer = [0; 4096];
379
380 inputs
381 .clone()
382 .write_next_bcc(
383 &bcc_handover0_bytes,
384 &[0u8; HIDDEN_SIZE],
385 Some([0u8; 64]),
386 true,
387 &mut buffer,
388 DiceContext {
389 authority_algorithm: KeyAlgorithm::Ed25519,
390 subject_algorithm: KeyAlgorithm::EcdsaP256,
391 },
392 )
393 .expect("Failed to derive Ed25519 -> EcdsaP256 BCC");
394 let bcc_handover1 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
395 let bcc_handover1_bytes = to_bcc_handover(&bcc_handover1);
396 buffer.fill(0);
397
398 inputs
399 .clone()
400 .write_next_bcc(
401 &bcc_handover1_bytes,
402 &[0u8; HIDDEN_SIZE],
403 Some([0u8; 64]),
404 true,
405 &mut buffer,
406 DiceContext {
407 authority_algorithm: KeyAlgorithm::EcdsaP256,
408 subject_algorithm: KeyAlgorithm::EcdsaP384,
409 },
410 )
411 .expect("Failed to derive EcdsaP256 -> EcdsaP384 BCC");
412 let bcc_handover2 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
413 let bcc_handover2_bytes = to_bcc_handover(&bcc_handover2);
414 buffer.fill(0);
415
416 inputs
417 .clone()
418 .write_next_bcc(
419 &bcc_handover2_bytes,
420 &[0u8; HIDDEN_SIZE],
421 Some([0u8; 64]),
422 true,
423 &mut buffer,
424 DiceContext {
425 authority_algorithm: KeyAlgorithm::EcdsaP384,
426 subject_algorithm: KeyAlgorithm::Ed25519,
427 },
428 )
429 .expect("Failed to derive EcdsaP384 -> Ed25519 BCC");
Alice Wang4dc62912024-12-11 08:27:15 +0000430 let bcc_handover3 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
Alice Wang87fbc4b2024-11-05 13:09:58 +0000431
Alice Wang4dc62912024-12-11 08:27:15 +0000432 let mut session = Session::default();
433 session.set_allow_any_mode(true);
434 let _chain = dice::Chain::from_cbor(&session, bcc_handover3.bcc().unwrap()).unwrap();
Alice Wang87fbc4b2024-11-05 13:09:58 +0000435 }
436
437 fn to_bcc_handover(dice_artifacts: &dyn DiceArtifacts) -> Vec<u8> {
438 let dice_chain = cbor_util::deserialize::<Value>(dice_artifacts.bcc().unwrap()).unwrap();
439 let bcc_handover = Value::Map(vec![
440 (Value::Integer(1.into()), Value::Bytes(dice_artifacts.cdi_attest().to_vec())),
441 (Value::Integer(2.into()), Value::Bytes(dice_artifacts.cdi_seal().to_vec())),
442 (Value::Integer(3.into()), dice_chain),
443 ]);
444 cbor_util::serialize(&bcc_handover).unwrap()
445 }
Alan Stokesddb988c2023-11-27 11:13:06 +0000446}