blob: 4df10b3c89db8cbd70d92025e33f148dfa24d181 [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")?));
Alice Wangf13bc4b2025-01-17 10:11:09 +0000159 config.push((cbor!(SECURITY_VERSION_KEY)?, cbor!(self.security_version)?));
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000160 if self.rkp_vm_marker {
161 config.push((cbor!(RKP_VM_MARKER_KEY)?, Value::Null))
162 }
163 if let Some(instance_hash) = instance_hash {
164 config.push((cbor!(INSTANCE_HASH_KEY)?, Value::from(instance_hash.as_slice())));
165 }
166 let config = Value::Map(config);
167 Ok(cbor_util::serialize(&config).map_err(|e| {
168 ciborium::value::Error::Custom(format!("Error in serialization: {e:?}"))
169 })?)
Alan Stokesddb988c2023-11-27 11:13:06 +0000170 }
Pierre-Clément Tosi4f4f5eb2022-12-08 14:31:42 +0000171}
Pierre-Clément Tosibec84662023-01-04 14:25:33 +0000172
Alan Stokesddb988c2023-11-27 11:13:06 +0000173#[cfg(test)]
174mod tests {
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000175 use crate::{
176 Hash, PartialInputs, COMPONENT_NAME_KEY, INSTANCE_HASH_KEY, RKP_VM_MARKER_KEY,
177 SECURITY_VERSION_KEY,
178 };
Alan Stokesddb988c2023-11-27 11:13:06 +0000179 use ciborium::Value;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000180 use diced_open_dice::DiceArtifacts;
Alice Wang87fbc4b2024-11-05 13:09:58 +0000181 use diced_open_dice::DiceContext;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000182 use diced_open_dice::DiceMode;
Alice Wang87fbc4b2024-11-05 13:09:58 +0000183 use diced_open_dice::KeyAlgorithm;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000184 use diced_open_dice::HIDDEN_SIZE;
Alice Wang87fbc4b2024-11-05 13:09:58 +0000185 use diced_sample_inputs::make_sample_bcc_and_cdis;
Alice Wang4dc62912024-12-11 08:27:15 +0000186 use hwtrust::{dice, session::Session};
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000187 use pvmfw_avb::Capability;
188 use pvmfw_avb::DebugLevel;
189 use pvmfw_avb::Digest;
190 use pvmfw_avb::VerifiedBootData;
Alan Stokesddb988c2023-11-27 11:13:06 +0000191 use std::collections::HashMap;
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000192 use std::mem::size_of;
Alan Stokesddb988c2023-11-27 11:13:06 +0000193 use std::vec;
194
Alan Stokesddb988c2023-11-27 11:13:06 +0000195 const COMPONENT_VERSION_KEY: i64 = -70003;
196 const RESETTABLE_KEY: i64 = -70004;
Alan Stokesddb988c2023-11-27 11:13:06 +0000197 const BASE_VB_DATA: VerifiedBootData = VerifiedBootData {
198 debug_level: DebugLevel::None,
199 kernel_digest: [1u8; size_of::<Digest>()],
200 initrd_digest: Some([2u8; size_of::<Digest>()]),
201 public_key: b"public key",
202 capabilities: vec![],
203 rollback_index: 42,
Pierre-Clément Tosi938b4fb2024-11-26 12:59:47 +0000204 page_size: None,
Alan Stokesddb988c2023-11-27 11:13:06 +0000205 };
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000206 const HASH: Hash = *b"sixtyfourbyteslongsentencearerarebutletsgiveitatrycantbethathard";
Alan Stokesddb988c2023-11-27 11:13:06 +0000207
208 #[test]
209 fn base_data_conversion() {
210 let vb_data = BASE_VB_DATA;
211 let inputs = PartialInputs::new(&vb_data).unwrap();
212
213 assert_eq!(inputs.mode, DiceMode::kDiceModeNormal);
214 assert_eq!(inputs.security_version, 42);
215 assert!(!inputs.rkp_vm_marker);
216
217 // TODO(b/313608219): Consider checks for code_hash and possibly auth_hash.
218 }
219
220 #[test]
221 fn debuggable_conversion() {
222 let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
223 let inputs = PartialInputs::new(&vb_data).unwrap();
224
225 assert_eq!(inputs.mode, DiceMode::kDiceModeDebug);
226 }
227
228 #[test]
229 fn rkp_vm_conversion() {
230 let vb_data =
231 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
232 let inputs = PartialInputs::new(&vb_data).unwrap();
233
234 assert!(inputs.rkp_vm_marker);
235 }
236
237 #[test]
238 fn base_config_descriptor() {
239 let vb_data = BASE_VB_DATA;
240 let inputs = PartialInputs::new(&vb_data).unwrap();
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000241 let config_map = decode_config_descriptor(&inputs, None);
Alan Stokesddb988c2023-11-27 11:13:06 +0000242
243 assert_eq!(config_map.get(&COMPONENT_NAME_KEY).unwrap().as_text().unwrap(), "vm_entry");
244 assert_eq!(config_map.get(&COMPONENT_VERSION_KEY), None);
245 assert_eq!(config_map.get(&RESETTABLE_KEY), None);
Alice Wangf13bc4b2025-01-17 10:11:09 +0000246 assert_eq!(config_map.get(&SECURITY_VERSION_KEY).unwrap().as_integer().unwrap(), 42.into());
Alan Stokesddb988c2023-11-27 11:13:06 +0000247 assert_eq!(config_map.get(&RKP_VM_MARKER_KEY), None);
248 }
249
250 #[test]
251 fn config_descriptor_with_rkp_vm() {
252 let vb_data =
253 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
254 let inputs = PartialInputs::new(&vb_data).unwrap();
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000255 let config_map = decode_config_descriptor(&inputs, Some(HASH));
Alan Stokesddb988c2023-11-27 11:13:06 +0000256
257 assert!(config_map.get(&RKP_VM_MARKER_KEY).unwrap().is_null());
258 }
259
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000260 #[test]
261 fn config_descriptor_with_instance_hash() {
262 let vb_data =
263 VerifiedBootData { capabilities: vec![Capability::RemoteAttest], ..BASE_VB_DATA };
264 let inputs = PartialInputs::new(&vb_data).unwrap();
265 let config_map = decode_config_descriptor(&inputs, Some(HASH));
266 assert_eq!(*config_map.get(&INSTANCE_HASH_KEY).unwrap(), Value::from(HASH.as_slice()));
267 }
268
269 #[test]
270 fn config_descriptor_without_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, None);
Chris Wailese9579642024-05-29 18:25:19 -0700275 assert!(!config_map.contains_key(&INSTANCE_HASH_KEY));
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000276 }
277
278 fn decode_config_descriptor(
279 inputs: &PartialInputs,
280 instance_hash: Option<Hash>,
281 ) -> HashMap<i64, Value> {
282 let config_descriptor = inputs.generate_config_descriptor(instance_hash).unwrap();
Alan Stokesddb988c2023-11-27 11:13:06 +0000283
284 let cbor_map =
Shikha Panwar8f7fc1a2024-04-10 10:41:34 +0000285 cbor_util::deserialize::<Value>(&config_descriptor).unwrap().into_map().unwrap();
Alan Stokesddb988c2023-11-27 11:13:06 +0000286
287 cbor_map
288 .into_iter()
289 .map(|(k, v)| ((k.into_integer().unwrap().try_into().unwrap()), v))
290 .collect()
291 }
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000292
293 #[test]
294 fn changing_deferred_rpb_changes_secrets() {
295 let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
296 let inputs = PartialInputs::new(&vb_data).unwrap();
297 let mut buffer_without_defer = [0; 4096];
298 let mut buffer_with_defer = [0; 4096];
299 let mut buffer_without_defer_retry = [0; 4096];
Alice Wang87fbc4b2024-11-05 13:09:58 +0000300 let context = DiceContext {
301 authority_algorithm: KeyAlgorithm::Ed25519,
302 subject_algorithm: KeyAlgorithm::Ed25519,
303 };
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000304
305 let sample_dice_input: &[u8] = &[
306 0xa3, // CDI attest
307 0x01, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // CDI seal
310 0x02, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // DICE chain
313 0x03, 0x82, 0xa6, 0x01, 0x02, 0x03, 0x27, 0x04, 0x02, 0x20, 0x01, 0x21, 0x40, 0x22,
314 0x40, 0x84, 0x40, 0xa0, 0x40, 0x40,
315 // 8-bytes of trailing data that aren't part of the DICE chain.
316 0x84, 0x41, 0x55, 0xa0, 0x42, 0x11, 0x22, 0x40,
317 ];
318
319 inputs
320 .clone()
321 .write_next_bcc(
322 sample_dice_input,
323 &[0u8; HIDDEN_SIZE],
324 Some([0u8; 64]),
325 false,
326 &mut buffer_without_defer,
Alice Wang87fbc4b2024-11-05 13:09:58 +0000327 context.clone(),
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000328 )
329 .unwrap();
330 let bcc_handover1 = diced_open_dice::bcc_handover_parse(&buffer_without_defer).unwrap();
331
332 inputs
333 .clone()
334 .write_next_bcc(
335 sample_dice_input,
336 &[0u8; HIDDEN_SIZE],
337 Some([0u8; 64]),
338 true,
339 &mut buffer_with_defer,
Alice Wang87fbc4b2024-11-05 13:09:58 +0000340 context.clone(),
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000341 )
342 .unwrap();
343 let bcc_handover2 = diced_open_dice::bcc_handover_parse(&buffer_with_defer).unwrap();
344
345 inputs
346 .clone()
347 .write_next_bcc(
348 sample_dice_input,
349 &[0u8; HIDDEN_SIZE],
350 Some([0u8; 64]),
351 false,
352 &mut buffer_without_defer_retry,
Alice Wang87fbc4b2024-11-05 13:09:58 +0000353 context.clone(),
Shikha Panwarf3acfd12024-05-28 15:48:13 +0000354 )
355 .unwrap();
356 let bcc_handover3 =
357 diced_open_dice::bcc_handover_parse(&buffer_without_defer_retry).unwrap();
358
359 assert_ne!(bcc_handover1.cdi_seal(), bcc_handover2.cdi_seal());
360 assert_eq!(bcc_handover1.cdi_seal(), bcc_handover3.cdi_seal());
361 }
Alice Wang87fbc4b2024-11-05 13:09:58 +0000362
363 #[test]
364 fn dice_derivation_with_different_algorithms_is_valid() {
365 let dice_artifacts = make_sample_bcc_and_cdis().unwrap();
366 let bcc_handover0_bytes = to_bcc_handover(&dice_artifacts);
367 let vb_data = VerifiedBootData { debug_level: DebugLevel::Full, ..BASE_VB_DATA };
368 let inputs = PartialInputs::new(&vb_data).unwrap();
369 let mut buffer = [0; 4096];
370
371 inputs
372 .clone()
373 .write_next_bcc(
374 &bcc_handover0_bytes,
375 &[0u8; HIDDEN_SIZE],
376 Some([0u8; 64]),
377 true,
378 &mut buffer,
379 DiceContext {
380 authority_algorithm: KeyAlgorithm::Ed25519,
381 subject_algorithm: KeyAlgorithm::EcdsaP256,
382 },
383 )
384 .expect("Failed to derive Ed25519 -> EcdsaP256 BCC");
385 let bcc_handover1 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
386 let bcc_handover1_bytes = to_bcc_handover(&bcc_handover1);
387 buffer.fill(0);
388
389 inputs
390 .clone()
391 .write_next_bcc(
392 &bcc_handover1_bytes,
393 &[0u8; HIDDEN_SIZE],
394 Some([0u8; 64]),
395 true,
396 &mut buffer,
397 DiceContext {
398 authority_algorithm: KeyAlgorithm::EcdsaP256,
399 subject_algorithm: KeyAlgorithm::EcdsaP384,
400 },
401 )
402 .expect("Failed to derive EcdsaP256 -> EcdsaP384 BCC");
403 let bcc_handover2 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
404 let bcc_handover2_bytes = to_bcc_handover(&bcc_handover2);
405 buffer.fill(0);
406
407 inputs
408 .clone()
409 .write_next_bcc(
410 &bcc_handover2_bytes,
411 &[0u8; HIDDEN_SIZE],
412 Some([0u8; 64]),
413 true,
414 &mut buffer,
415 DiceContext {
416 authority_algorithm: KeyAlgorithm::EcdsaP384,
417 subject_algorithm: KeyAlgorithm::Ed25519,
418 },
419 )
420 .expect("Failed to derive EcdsaP384 -> Ed25519 BCC");
Alice Wang4dc62912024-12-11 08:27:15 +0000421 let bcc_handover3 = diced_open_dice::bcc_handover_parse(&buffer).unwrap();
Alice Wang87fbc4b2024-11-05 13:09:58 +0000422
Alice Wang4dc62912024-12-11 08:27:15 +0000423 let mut session = Session::default();
424 session.set_allow_any_mode(true);
425 let _chain = dice::Chain::from_cbor(&session, bcc_handover3.bcc().unwrap()).unwrap();
Alice Wang87fbc4b2024-11-05 13:09:58 +0000426 }
427
428 fn to_bcc_handover(dice_artifacts: &dyn DiceArtifacts) -> Vec<u8> {
429 let dice_chain = cbor_util::deserialize::<Value>(dice_artifacts.bcc().unwrap()).unwrap();
430 let bcc_handover = Value::Map(vec![
431 (Value::Integer(1.into()), Value::Bytes(dice_artifacts.cdi_attest().to_vec())),
432 (Value::Integer(2.into()), Value::Bytes(dice_artifacts.cdi_seal().to_vec())),
433 (Value::Integer(3.into()), dice_chain),
434 ]);
435 cbor_util::serialize(&bcc_handover).unwrap()
436 }
Alan Stokesddb988c2023-11-27 11:13:06 +0000437}