blob: f6116c838749e3d2a775f4f990045cfd0c936ded [file] [log] [blame]
Janis Danisevskis13356b22021-10-20 09:44:12 -07001// Copyright 2021, 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//! Implements safe wrappers around the public API of libopen-dice.
16//! ## Example:
17//! ```
18//! use diced_open_dice_cbor as dice;
19//!
20//! let context = dice::dice::OpenDiceCborContext::new()
21//! let parent_cdi_attest = [1u8, dice::CDI_SIZE];
22//! let parent_cdi_seal = [2u8, dice::CDI_SIZE];
Alice Wangb68814b2023-02-02 13:15:32 +000023//! let input_values = dice::InputValues::new(
24//! [3u8, dice::HASH_SIZE], // code_hash
25//! dice::Config::Descriptor(&"My descriptor".as_bytes().to_vec()),
26//! [0u8, dice::HASH_SIZE], // authority_hash
27//! dice::DiceMode::kDiceModeNormal,
28//! [0u8, dice::HIDDEN_SIZE], // hidden
Janis Danisevskis13356b22021-10-20 09:44:12 -070029//! };
30//! let (cdi_attest, cdi_seal, cert_chain) = context
31//! .main_flow(&parent_cdi_attest, &parent_cdi_seal, &input_values)?;
32//! ```
33
Alice Wang856d6562023-02-03 13:51:08 +000034pub use diced_open_dice::{
Alice Wangf4bd1c62023-02-08 08:38:44 +000035 check_result, derive_cdi_private_key_seed, hash, retry_bcc_format_config_descriptor,
36 retry_bcc_main_flow, Config, DiceError, Hash, Hidden, InputValues, OwnedDiceArtifacts, Result,
37 CDI_SIZE, HASH_SIZE, HIDDEN_SIZE, PRIVATE_KEY_SEED_SIZE,
Alice Wang856d6562023-02-03 13:51:08 +000038};
39use keystore2_crypto::ZVec;
Alice Wang97d47a72023-01-31 12:48:02 +000040pub use open_dice_cbor_bindgen::DiceMode;
Janis Danisevskis13356b22021-10-20 09:44:12 -070041use open_dice_cbor_bindgen::{
Alice Wang6ef44bc2023-02-08 12:08:32 +000042 DiceGenerateCertificate, DiceKeypairFromSeed, DiceMainFlow, DiceSign, DiceVerify,
Alice Wang7cc59562023-02-08 13:17:10 +000043 DICE_PRIVATE_KEY_SIZE, DICE_PUBLIC_KEY_SIZE, DICE_SIGNATURE_SIZE,
Janis Danisevskis13356b22021-10-20 09:44:12 -070044};
Alice Wang856d6562023-02-03 13:51:08 +000045use std::ffi::c_void;
Janis Danisevskis13356b22021-10-20 09:44:12 -070046
Janis Danisevskis13356b22021-10-20 09:44:12 -070047/// The size of a private key.
48pub const PRIVATE_KEY_SIZE: usize = DICE_PRIVATE_KEY_SIZE as usize;
49/// The size of a public key.
50pub const PUBLIC_KEY_SIZE: usize = DICE_PUBLIC_KEY_SIZE as usize;
51/// The size of a signature.
52pub const SIGNATURE_SIZE: usize = DICE_SIGNATURE_SIZE as usize;
53
Janis Danisevskis13356b22021-10-20 09:44:12 -070054/// Multiple of the open dice function required preallocated output buffer
55/// which may be too small, this function implements the retry logic to handle
56/// too small buffer allocations.
57/// The callback `F` must expect a mutable reference to a buffer and a size hint
58/// field. The callback is called repeatedly as long as it returns
59/// `Err(Error::BufferTooSmall)`. If the size hint remains 0, the buffer size is
60/// doubled with each iteration. If the size hint is set by the callback, the buffer
61/// will be set to accommodate at least this many bytes.
62/// If the callback returns `Ok(())`, the buffer is truncated to the size hint
63/// exactly.
64/// The function panics if the callback returns `Ok(())` and the size hint is
65/// larger than the buffer size.
Alice Wang9c40eca2023-02-03 13:10:24 +000066/// TODO(b/267575445): Remove this method once we migrate all its callers to
67/// `retry_with_bigger_buffer` in `diced_open_dice`.
Janis Danisevskis13356b22021-10-20 09:44:12 -070068fn retry_while_adjusting_output_buffer<F>(mut f: F) -> Result<Vec<u8>>
69where
70 F: FnMut(&mut Vec<u8>, &mut usize) -> Result<()>,
71{
72 let mut buffer = vec![0; INITIAL_OUT_BUFFER_SIZE];
73 let mut actual_size: usize = 0;
74 loop {
75 match f(&mut buffer, &mut actual_size) {
76 // If Error::BufferTooSmall was returned, the allocated certificate
77 // buffer was to small for the output. So the buffer is resized to the actual
78 // size, and a second attempt is made with the new buffer.
Alice Wang856d6562023-02-03 13:51:08 +000079 Err(DiceError::BufferTooSmall) => {
Janis Danisevskis13356b22021-10-20 09:44:12 -070080 let new_size = if actual_size == 0 {
81 // Due to an off spec implementation of open dice cbor, actual size
82 // does not return the required size if the buffer was too small. So
83 // we have to try and approach it gradually.
84 buffer.len() * 2
85 } else {
86 actual_size
87 };
88 buffer.resize(new_size, 0);
89 continue;
90 }
91 Err(e) => return Err(e),
92 Ok(()) => {
93 if actual_size > buffer.len() {
94 panic!(
95 "actual_size larger than buffer size: open-dice function
96 may have written past the end of the buffer."
97 );
98 }
99 // Truncate the certificate buffer to the actual size because it may be
100 // smaller than the original allocation.
101 buffer.truncate(actual_size);
102 return Ok(buffer);
103 }
104 }
105 }
106}
107
108/// Some libopen-dice variants use a context. Developers that want to customize these
109/// bindings may want to implement their own Context factory that creates a context
110/// useable by their preferred backend.
111pub trait Context {
112 /// # Safety
113 /// The return value of get_context is passed to any open dice function.
114 /// Implementations must explain why the context pointer returned is safe
115 /// to be used by the open dice library.
116 unsafe fn get_context(&mut self) -> *mut c_void;
117}
118
119impl<T: Context + Send> ContextImpl for T {}
120
121/// This represents a context for the open dice library. The wrapped open dice instance, which
122/// is based on boringssl and cbor, does not use a context, so that this type is empty.
123#[derive(Default)]
124pub struct OpenDiceCborContext();
125
126impl OpenDiceCborContext {
127 /// Construct a new instance of OpenDiceCborContext.
128 pub fn new() -> Self {
129 Default::default()
130 }
131}
132
133impl Context for OpenDiceCborContext {
134 unsafe fn get_context(&mut self) -> *mut c_void {
135 // # Safety
136 // The open dice cbor implementation does not use a context. It is safe
137 // to return NULL.
138 std::ptr::null_mut()
139 }
140}
141
142/// Type alias for ZVec indicating that it holds a CDI_ATTEST secret.
143pub type CdiAttest = ZVec;
144
145/// Type alias for ZVec indicating that it holds a CDI_SEAL secret.
146pub type CdiSeal = ZVec;
147
148/// Type alias for Vec<u8> indicating that it hold a DICE certificate.
149pub type Cert = Vec<u8>;
150
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700151/// Type alias for Vec<u8> indicating that it holds a BCC certificate chain.
152pub type Bcc = Vec<u8>;
153
Janis Danisevskis13356b22021-10-20 09:44:12 -0700154const INITIAL_OUT_BUFFER_SIZE: usize = 1024;
155
156/// ContextImpl is a mixin trait that implements the safe wrappers around the open dice
157/// library calls. Implementations must implement Context::get_context(). As of
158/// this writing, the only implementation is OpenDiceCborContext, which returns NULL.
159pub trait ContextImpl: Context + Send {
Janis Danisevskis13356b22021-10-20 09:44:12 -0700160 /// Safe wrapper around open-dice DiceMainFlow, see open dice
161 /// documentation for details.
162 /// Returns a tuple of:
163 /// * The next attestation CDI,
164 /// * the next seal CDI, and
165 /// * the next attestation certificate.
166 /// `(next_attest_cdi, next_seal_cdi, next_attestation_cert)`
Alice Wangb68814b2023-02-02 13:15:32 +0000167 fn main_flow(
Janis Danisevskis13356b22021-10-20 09:44:12 -0700168 &mut self,
169 current_cdi_attest: &[u8; CDI_SIZE],
170 current_cdi_seal: &[u8; CDI_SIZE],
Alice Wangb68814b2023-02-02 13:15:32 +0000171 input_values: &InputValues,
Janis Danisevskis13356b22021-10-20 09:44:12 -0700172 ) -> Result<(CdiAttest, CdiSeal, Cert)> {
173 let mut next_attest = CdiAttest::new(CDI_SIZE)?;
174 let mut next_seal = CdiSeal::new(CDI_SIZE)?;
175
176 // SAFETY (DiceMainFlow):
177 // * The first context argument may be NULL and is unused by the wrapped
178 // implementation.
179 // * The second argument and the third argument are const arrays of size CDI_SIZE.
180 // This is fulfilled as per the definition of the arguments `current_cdi_attest`
181 // and `current_cdi_seal.
182 // * The fourth argument is a pointer to `DiceInputValues`. It, and its indirect
Alice Wangb68814b2023-02-02 13:15:32 +0000183 // references must be valid for the duration of the function call.
Janis Danisevskis13356b22021-10-20 09:44:12 -0700184 // * The fifth and sixth argument are the length of and the pointer to the
185 // allocated certificate buffer respectively. They are used to return
186 // the generated certificate.
187 // * The seventh argument is a pointer to a mutable usize object. It is
188 // used to return the actual size of the output certificate.
189 // * The eighth argument and the ninth argument are pointers to mutable buffers of size
190 // CDI_SIZE. This is fulfilled if the allocation above succeeded.
191 // * No pointers are expected to be valid beyond the scope of the function
192 // call.
Alice Wangb68814b2023-02-02 13:15:32 +0000193 let cert = retry_while_adjusting_output_buffer(|cert, actual_size| {
194 check_result(unsafe {
195 DiceMainFlow(
196 self.get_context(),
197 current_cdi_attest.as_ptr(),
198 current_cdi_seal.as_ptr(),
199 input_values.as_ptr(),
200 cert.len(),
201 cert.as_mut_ptr(),
202 actual_size as *mut _,
203 next_attest.as_mut_ptr(),
204 next_seal.as_mut_ptr(),
205 )
206 })
207 })?;
208 Ok((next_attest, next_seal, cert))
Janis Danisevskis13356b22021-10-20 09:44:12 -0700209 }
210
Janis Danisevskis13356b22021-10-20 09:44:12 -0700211 /// Safe wrapper around open-dice DiceKeyPairFromSeed, see open dice
212 /// documentation for details.
213 fn keypair_from_seed(&mut self, seed: &[u8; PRIVATE_KEY_SEED_SIZE]) -> Result<(Vec<u8>, ZVec)> {
214 let mut private_key = ZVec::new(PRIVATE_KEY_SIZE)?;
215 let mut public_key = vec![0u8; PUBLIC_KEY_SIZE];
216
217 // SAFETY:
218 // * The first context argument may be NULL and is unused by the wrapped
219 // implementation.
220 // * The second argument is a pointer to a const buffer of size `PRIVATE_KEY_SEED_SIZE`
221 // fulfilled by the definition of the argument.
222 // * The third argument and the fourth argument are mutable buffers of size
223 // `PRIVATE_KEY_SIZE` and `PUBLIC_KEY_SIZE` respectively. This is fulfilled by the
224 // allocations above.
225 // * All pointers must be valid for the duration of the function call but not beyond.
226 check_result(unsafe {
227 DiceKeypairFromSeed(
228 self.get_context(),
229 seed.as_ptr(),
230 public_key.as_mut_ptr(),
231 private_key.as_mut_ptr(),
232 )
233 })?;
234 Ok((public_key, private_key))
235 }
236
237 /// Safe wrapper around open-dice DiceSign, see open dice
238 /// documentation for details.
239 fn sign(&mut self, message: &[u8], private_key: &[u8; PRIVATE_KEY_SIZE]) -> Result<Vec<u8>> {
240 let mut signature = vec![0u8; SIGNATURE_SIZE];
241
242 // SAFETY:
243 // * The first context argument may be NULL and is unused by the wrapped
244 // implementation.
245 // * The second argument and the third argument are the pointer to and length of the given
246 // message buffer.
247 // * The fourth argument is a const buffer of size `PRIVATE_KEY_SIZE`. This is fulfilled
248 // by the definition of `private key`.
249 // * The fifth argument is mutable buffer of size `SIGNATURE_SIZE`. This is fulfilled
250 // by the allocation above.
251 // * All pointers must be valid for the duration of the function call but not beyond.
252 check_result(unsafe {
253 DiceSign(
254 self.get_context(),
255 message.as_ptr(),
256 message.len(),
257 private_key.as_ptr(),
258 signature.as_mut_ptr(),
259 )
260 })?;
261 Ok(signature)
262 }
263
264 /// Safe wrapper around open-dice DiceVerify, see open dice
265 /// documentation for details.
266 fn verify(
267 &mut self,
268 message: &[u8],
269 signature: &[u8; SIGNATURE_SIZE],
270 public_key: &[u8; PUBLIC_KEY_SIZE],
271 ) -> Result<()> {
272 // SAFETY:
273 // * The first context argument may be NULL and is unused by the wrapped
274 // implementation.
275 // * The second argument and the third argument are the pointer to and length of the given
276 // message buffer.
277 // * The fourth argument is a const buffer of size `SIGNATURE_SIZE`. This is fulfilled
278 // by the definition of `signature`.
279 // * The fifth argument is a const buffer of size `PUBLIC_KEY_SIZE`. This is fulfilled
280 // by the definition of `public_key`.
281 // * All pointers must be valid for the duration of the function call but not beyond.
282 check_result(unsafe {
283 DiceVerify(
284 self.get_context(),
285 message.as_ptr(),
286 message.len(),
287 signature.as_ptr(),
288 public_key.as_ptr(),
289 )
290 })
291 }
292
293 /// Safe wrapper around open-dice DiceGenerateCertificate, see open dice
294 /// documentation for details.
Alice Wangb68814b2023-02-02 13:15:32 +0000295 fn generate_certificate(
Janis Danisevskis13356b22021-10-20 09:44:12 -0700296 &mut self,
297 subject_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
298 authority_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
Alice Wangb68814b2023-02-02 13:15:32 +0000299 input_values: &InputValues,
Janis Danisevskis13356b22021-10-20 09:44:12 -0700300 ) -> Result<Vec<u8>> {
Alice Wangb68814b2023-02-02 13:15:32 +0000301 // SAFETY (DiceGenerateCertificate):
Janis Danisevskis13356b22021-10-20 09:44:12 -0700302 // * The first context argument may be NULL and is unused by the wrapped
303 // implementation.
304 // * The second argument and the third argument are const arrays of size
305 // `PRIVATE_KEY_SEED_SIZE`. This is fulfilled as per the definition of the arguments.
306 // * The fourth argument is a pointer to `DiceInputValues` it, and its indirect
Alice Wangb68814b2023-02-02 13:15:32 +0000307 // references must be valid for the duration of the function call.
Janis Danisevskis13356b22021-10-20 09:44:12 -0700308 // * The fifth argument and the sixth argument are the length of and the pointer to the
309 // allocated certificate buffer respectively. They are used to return
310 // the generated certificate.
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700311 // * The seventh argument is a pointer to a mutable usize object. It is
Janis Danisevskis13356b22021-10-20 09:44:12 -0700312 // used to return the actual size of the output certificate.
313 // * All pointers must be valid for the duration of the function call but not beyond.
Alice Wangb68814b2023-02-02 13:15:32 +0000314 let cert = retry_while_adjusting_output_buffer(|cert, actual_size| {
315 check_result(unsafe {
316 DiceGenerateCertificate(
317 self.get_context(),
318 subject_private_key_seed.as_ptr(),
319 authority_private_key_seed.as_ptr(),
320 input_values.as_ptr(),
321 cert.len(),
322 cert.as_mut_ptr(),
323 actual_size as *mut _,
324 )
325 })
326 })?;
327 Ok(cert)
Janis Danisevskis13356b22021-10-20 09:44:12 -0700328 }
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700329}
330
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800331#[cfg(test)]
332mod test {
333 use super::*;
334 use diced_sample_inputs::make_sample_bcc_and_cdis;
335 use std::convert::TryInto;
336
337 static SEED_TEST_VECTOR: &[u8] = &[
338 0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
339 0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
340 0x3a, 0x08, 0x84, 0x8a, 0x98, 0x85, 0x6d, 0xf5, 0x69, 0x21, 0x03, 0xcd, 0x09, 0xc3, 0x28,
341 0xd6, 0x06, 0xa7, 0x57, 0xbd, 0x48, 0x4b, 0x0f, 0x79, 0x0f, 0xf8, 0x2f, 0xf0, 0x0a, 0x41,
342 0x94, 0xd8, 0x8c, 0xa8,
343 ];
344
345 static CDI_ATTEST_TEST_VECTOR: &[u8] = &[
346 0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
347 0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
348 0x3a, 0x08,
349 ];
350 static CDI_PRIVATE_KEY_SEED_TEST_VECTOR: &[u8] = &[
351 0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
352 0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
353 0x02, 0x6e,
354 ];
355
356 static PUB_KEY_TEST_VECTOR: &[u8] = &[
357 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23,
358 0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61,
359 0x06, 0x37,
360 ];
361 static PRIV_KEY_TEST_VECTOR: &[u8] = &[
362 0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
363 0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
364 0x02, 0x6e, 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b,
365 0xfc, 0x23, 0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52,
366 0xf1, 0x61, 0x06, 0x37,
367 ];
368
369 static SIGNATURE_TEST_VECTOR: &[u8] = &[
370 0x44, 0xae, 0xcc, 0xe2, 0xb9, 0x96, 0x18, 0x39, 0x0e, 0x61, 0x0f, 0x53, 0x07, 0xbf, 0xf2,
371 0x32, 0x3d, 0x44, 0xd4, 0xf2, 0x07, 0x23, 0x30, 0x85, 0x32, 0x18, 0xd2, 0x69, 0xb8, 0x29,
372 0x3c, 0x26, 0xe6, 0x0d, 0x9c, 0xa5, 0xc2, 0x73, 0xcd, 0x8c, 0xb8, 0x3c, 0x3e, 0x5b, 0xfd,
373 0x62, 0x8d, 0xf6, 0xc4, 0x27, 0xa6, 0xe9, 0x11, 0x06, 0x5a, 0xb2, 0x2b, 0x64, 0xf7, 0xfc,
374 0xbb, 0xab, 0x4a, 0x0e,
375 ];
376
377 #[test]
378 fn hash_derive_sign_verify() {
379 let mut ctx = OpenDiceCborContext::new();
Alice Wang24954b42023-02-06 10:03:45 +0000380 let seed = diced_open_dice::hash("MySeedString".as_bytes()).unwrap();
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800381 assert_eq!(seed, SEED_TEST_VECTOR);
382 let cdi_attest = &seed[..CDI_SIZE];
383 assert_eq!(cdi_attest, CDI_ATTEST_TEST_VECTOR);
384 let cdi_private_key_seed =
Alice Wang7cc59562023-02-08 13:17:10 +0000385 derive_cdi_private_key_seed(cdi_attest.try_into().unwrap()).unwrap();
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800386 assert_eq!(&cdi_private_key_seed[..], CDI_PRIVATE_KEY_SEED_TEST_VECTOR);
387 let (pub_key, priv_key) =
388 ctx.keypair_from_seed(cdi_private_key_seed[..].try_into().unwrap()).unwrap();
389 assert_eq!(&pub_key, PUB_KEY_TEST_VECTOR);
390 assert_eq!(&priv_key[..], PRIV_KEY_TEST_VECTOR);
391 let mut signature =
392 ctx.sign("MyMessage".as_bytes(), priv_key[..].try_into().unwrap()).unwrap();
393 assert_eq!(&signature, SIGNATURE_TEST_VECTOR);
394 assert!(ctx
395 .verify(
396 "MyMessage".as_bytes(),
397 signature[..].try_into().unwrap(),
398 pub_key[..].try_into().unwrap()
399 )
400 .is_ok());
401 assert!(ctx
402 .verify(
403 "MyMessage_fail".as_bytes(),
404 signature[..].try_into().unwrap(),
405 pub_key[..].try_into().unwrap()
406 )
407 .is_err());
408 signature[0] += 1;
409 assert!(ctx
410 .verify(
411 "MyMessage".as_bytes(),
412 signature[..].try_into().unwrap(),
413 pub_key[..].try_into().unwrap()
414 )
415 .is_err());
416 }
417
418 static SAMPLE_CDI_ATTEST_TEST_VECTOR: &[u8] = &[
419 0x3e, 0x57, 0x65, 0x5d, 0x48, 0x02, 0xbd, 0x5c, 0x66, 0xcc, 0x1f, 0x0f, 0xbe, 0x5e, 0x32,
420 0xb6, 0x9e, 0x3d, 0x04, 0xaf, 0x00, 0x15, 0xbc, 0xdd, 0x1f, 0xbc, 0x59, 0xe4, 0xc3, 0x87,
421 0x95, 0x5e,
422 ];
423
424 static SAMPLE_CDI_SEAL_TEST_VECTOR: &[u8] = &[
425 0x36, 0x1b, 0xd2, 0xb3, 0xc4, 0xda, 0x77, 0xb2, 0x9c, 0xba, 0x39, 0x53, 0x82, 0x93, 0xd9,
426 0xb8, 0x9f, 0x73, 0x2d, 0x27, 0x06, 0x15, 0xa8, 0xcb, 0x6d, 0x1d, 0xf2, 0xb1, 0x54, 0xbb,
427 0x62, 0xf1,
428 ];
429
430 static SAMPLE_BCC_TEST_VECTOR: &[u8] = &[
Alan Stokes7cdcf992022-05-24 07:42:24 +0000431 0x84, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x3e,
432 0x85, 0xe5, 0x72, 0x75, 0x55, 0xe5, 0x1e, 0xe7, 0xf3, 0x35, 0x94, 0x8e, 0xbb, 0xbd, 0x74,
433 0x1e, 0x1d, 0xca, 0x49, 0x9c, 0x97, 0x39, 0x77, 0x06, 0xd3, 0xc8, 0x6e, 0x8b, 0xd7, 0x33,
434 0xf9, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9, 0x01, 0x78, 0x28, 0x34,
435 0x32, 0x64, 0x38, 0x38, 0x36, 0x34, 0x66, 0x39, 0x37, 0x62, 0x36, 0x35, 0x34, 0x37, 0x61,
436 0x35, 0x30, 0x63, 0x31, 0x65, 0x30, 0x61, 0x37, 0x34, 0x39, 0x66, 0x38, 0x65, 0x66, 0x38,
437 0x62, 0x38, 0x31, 0x65, 0x63, 0x36, 0x32, 0x61, 0x66, 0x02, 0x78, 0x28, 0x31, 0x66, 0x36,
438 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35, 0x32, 0x66, 0x32, 0x39, 0x65, 0x39, 0x33, 0x66,
439 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65, 0x33, 0x32, 0x63, 0x64, 0x38, 0x31, 0x64,
440 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x16,
441 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38, 0xc3, 0x64, 0x38, 0x63, 0x26,
442 0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34, 0x4c, 0x6d, 0xa2, 0xbe,
443 0x25, 0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2, 0xb3, 0x91, 0x4d,
444 0xd3, 0xfb, 0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba, 0x30, 0xf7,
445 0x15, 0x98, 0x14, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56, 0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71,
446 0x63, 0x41, 0x42, 0x4c, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a, 0x00, 0x01, 0x11, 0x73,
447 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x47, 0xae, 0x42, 0x27, 0x4c, 0xcb, 0x65,
448 0x4d, 0xee, 0x74, 0x2d, 0x05, 0x78, 0x2a, 0x08, 0x2a, 0xa5, 0xf0, 0xcf, 0xea, 0x3e, 0x60,
449 0xee, 0x97, 0x11, 0x4b, 0x5b, 0xe6, 0x05, 0x0c, 0xe8, 0x90, 0xf5, 0x22, 0xc4, 0xc6, 0x67,
450 0x7a, 0x22, 0x27, 0x17, 0xb3, 0x79, 0xcc, 0x37, 0x64, 0x5e, 0x19, 0x4f, 0x96, 0x37, 0x67,
451 0x3c, 0xd0, 0xc5, 0xed, 0x0f, 0xdd, 0xe7, 0x2e, 0x4f, 0x70, 0x97, 0x30, 0x3a, 0x00, 0x47,
452 0x44, 0x54, 0x58, 0x40, 0xf9, 0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3,
453 0x97, 0x4a, 0xcb, 0x3c, 0xe7, 0x6b, 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59,
454 0x15, 0xb1, 0x23, 0xe6, 0xc8, 0xdf, 0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc,
455 0x5b, 0x37, 0x0e, 0x12, 0x12, 0xb2, 0xfd, 0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6,
456 0x29, 0x1b, 0x99, 0xea, 0xae, 0xfd, 0xaa, 0x0d, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01,
457 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02,
458 0x20, 0x06, 0x21, 0x58, 0x20, 0xb1, 0x02, 0xcc, 0x2c, 0xb2, 0x6a, 0x3b, 0xe9, 0xc1, 0xd3,
459 0x95, 0x10, 0xa0, 0xe1, 0xff, 0x51, 0xde, 0x57, 0xd5, 0x65, 0x28, 0xfd, 0x7f, 0xeb, 0xd4,
460 0xca, 0x15, 0xf3, 0xca, 0xdf, 0x37, 0x88, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58,
461 0x40, 0x58, 0xd8, 0x03, 0x24, 0x53, 0x60, 0x57, 0xa9, 0x09, 0xfa, 0xab, 0xdc, 0x57, 0x1e,
462 0xf0, 0xe5, 0x1e, 0x51, 0x6f, 0x9e, 0xa3, 0x42, 0xe6, 0x6a, 0x8c, 0xaa, 0xad, 0x08, 0x48,
463 0xde, 0x7f, 0x4f, 0x6e, 0x2f, 0x7f, 0x39, 0x6c, 0xa1, 0xf8, 0x42, 0x71, 0xfe, 0x17, 0x3d,
464 0xca, 0x31, 0x83, 0x92, 0xed, 0xbb, 0x40, 0xb8, 0x10, 0xe0, 0xf2, 0x5a, 0x99, 0x53, 0x38,
465 0x46, 0x33, 0x97, 0x78, 0x05, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9,
466 0x01, 0x78, 0x28, 0x31, 0x66, 0x36, 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35, 0x32, 0x66,
467 0x32, 0x39, 0x65, 0x39, 0x33, 0x66, 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65, 0x33,
468 0x32, 0x63, 0x64, 0x38, 0x31, 0x64, 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x02, 0x78,
469 0x28, 0x32, 0x35, 0x39, 0x34, 0x38, 0x39, 0x65, 0x36, 0x39, 0x37, 0x34, 0x38, 0x37, 0x30,
470 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66, 0x34, 0x34, 0x32, 0x36, 0x37, 0x65, 0x61, 0x34,
471 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35, 0x37, 0x32, 0x35, 0x3a, 0x00, 0x47, 0x44,
472 0x50, 0x58, 0x40, 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43,
473 0x83, 0x7f, 0x46, 0x8d, 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0, 0xd9,
474 0x56, 0xb3, 0xbf, 0x2f, 0xfa, 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9, 0x6b, 0x18,
475 0x28, 0xe8, 0x29, 0x20, 0x49, 0x0f, 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54, 0xe9, 0x71, 0xd2,
476 0x7e, 0xa4, 0xfe, 0x58, 0x7f, 0xd3, 0xc7, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56, 0xa3, 0x3a,
477 0x00, 0x01, 0x11, 0x71, 0x63, 0x41, 0x56, 0x42, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a,
478 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x93, 0x17, 0xe1,
479 0x11, 0x27, 0x59, 0xd0, 0xef, 0x75, 0x0b, 0x2b, 0x1c, 0x0f, 0x5f, 0x52, 0xc3, 0x29, 0x23,
480 0xb5, 0x2a, 0xe6, 0x12, 0x72, 0x6f, 0x39, 0x86, 0x65, 0x2d, 0xf2, 0xe4, 0xe7, 0xd0, 0xaf,
481 0x0e, 0xa7, 0x99, 0x16, 0x89, 0x97, 0x21, 0xf7, 0xdc, 0x89, 0xdc, 0xde, 0xbb, 0x94, 0x88,
482 0x1f, 0xda, 0xe2, 0xf3, 0xe0, 0x54, 0xf9, 0x0e, 0x29, 0xb1, 0xbd, 0xe1, 0x0c, 0x0b, 0xd7,
483 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa,
484 0x55, 0x6f, 0xac, 0x56, 0xd9, 0x02, 0x35, 0x2b, 0xaa, 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a,
485 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d, 0xe4, 0x43, 0x13, 0xbf, 0xfe, 0xd3, 0x36,
486 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6, 0x66, 0xef, 0xab, 0x3d, 0x0f, 0x89, 0xa4,
487 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a, 0xef, 0xbc, 0x05, 0x98, 0x3a, 0x00, 0x47,
488 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03,
489 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x96, 0x6d, 0x96, 0x42, 0xda, 0x64,
490 0x51, 0xad, 0xfa, 0x00, 0xbc, 0xbc, 0x95, 0x8a, 0xb0, 0xb9, 0x76, 0x01, 0xe6, 0xbd, 0xc0,
491 0x26, 0x79, 0x26, 0xfc, 0x0f, 0x1d, 0x87, 0x65, 0xf1, 0xf3, 0x99, 0x3a, 0x00, 0x47, 0x44,
492 0x58, 0x41, 0x20, 0x58, 0x40, 0x10, 0x7f, 0x77, 0xad, 0x70, 0xbd, 0x52, 0x81, 0x28, 0x8d,
493 0x24, 0x81, 0xb4, 0x3f, 0x21, 0x68, 0x9f, 0xc3, 0x80, 0x68, 0x86, 0x55, 0xfb, 0x2e, 0x6d,
494 0x96, 0xe1, 0xe1, 0xb7, 0x28, 0x8d, 0x63, 0x85, 0xba, 0x2a, 0x01, 0x33, 0x87, 0x60, 0x63,
495 0xbb, 0x16, 0x3f, 0x2f, 0x3d, 0xf4, 0x2d, 0x48, 0x5b, 0x87, 0xed, 0xda, 0x34, 0xeb, 0x9c,
496 0x4d, 0x14, 0xac, 0x65, 0xf4, 0xfa, 0xef, 0x45, 0x0b, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0,
497 0x59, 0x01, 0x8f, 0xa9, 0x01, 0x78, 0x28, 0x32, 0x35, 0x39, 0x34, 0x38, 0x39, 0x65, 0x36,
498 0x39, 0x37, 0x34, 0x38, 0x37, 0x30, 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66, 0x34, 0x34,
499 0x32, 0x36, 0x37, 0x65, 0x61, 0x34, 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35, 0x37,
500 0x32, 0x35, 0x02, 0x78, 0x28, 0x35, 0x64, 0x34, 0x65, 0x64, 0x37, 0x66, 0x34, 0x31, 0x37,
501 0x61, 0x39, 0x35, 0x34, 0x61, 0x31, 0x38, 0x31, 0x34, 0x30, 0x37, 0x62, 0x35, 0x38, 0x38,
502 0x35, 0x61, 0x66, 0x64, 0x37, 0x32, 0x61, 0x35, 0x62, 0x66, 0x34, 0x30, 0x64, 0x61, 0x36,
503 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Alan Stokes7cdcf992022-05-24 07:42:24 +0000507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x47, 0x44,
508 0x53, 0x58, 0x1a, 0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x67, 0x41, 0x6e, 0x64, 0x72, 0x6f,
509 0x69, 0x64, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x0c, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a,
510 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x26, 0x1a, 0xbd, 0x26, 0xd8, 0x37, 0x8f, 0x4a, 0xf2,
511 0x9e, 0x49, 0x4d, 0x93, 0x23, 0xc4, 0x6e, 0x02, 0xda, 0xe0, 0x00, 0x02, 0xe7, 0xed, 0x29,
512 0xdf, 0x2b, 0xb3, 0x69, 0xf3, 0x55, 0x0e, 0x4c, 0x22, 0xdc, 0xcf, 0xf5, 0x92, 0xc9, 0xfa,
513 0x78, 0x98, 0xf1, 0x0e, 0x55, 0x5f, 0xf4, 0x45, 0xed, 0xc0, 0x0a, 0x72, 0x2a, 0x7a, 0x3a,
514 0xd2, 0xb1, 0xf7, 0x76, 0xfe, 0x2a, 0x6b, 0x7b, 0x2a, 0x53, 0x3a, 0x00, 0x47, 0x44, 0x54,
515 0x58, 0x40, 0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30,
516 0x03, 0xb8, 0xd6, 0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37,
517 0x68, 0x4e, 0x1d, 0xc0, 0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2,
518 0x9c, 0xfc, 0x12, 0x9e, 0x77, 0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5,
519 0x73, 0xd4, 0xc6, 0xdf, 0x62, 0x9f, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00,
520 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06,
521 0x21, 0x58, 0x20, 0xdb, 0xe7, 0x5b, 0x3f, 0xa3, 0x42, 0xb0, 0x9c, 0xf8, 0x40, 0x8c, 0xb0,
522 0x9c, 0xf0, 0x0a, 0xaf, 0xdf, 0x6f, 0xe5, 0x09, 0x21, 0x11, 0x92, 0xe1, 0xf8, 0xc5, 0x09,
523 0x02, 0x3d, 0x1f, 0xb7, 0xc5, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40, 0xc4,
524 0xc1, 0xd7, 0x1c, 0x2d, 0x26, 0x89, 0x22, 0xcf, 0xa6, 0x99, 0x77, 0x30, 0x84, 0x86, 0x27,
525 0x59, 0x8f, 0xd8, 0x08, 0x75, 0xe0, 0xb2, 0xef, 0xf9, 0xfa, 0xa5, 0x40, 0x8c, 0xd3, 0xeb,
526 0xbb, 0xda, 0xf2, 0xc8, 0xae, 0x41, 0x22, 0x50, 0x9c, 0xe8, 0xb2, 0x9c, 0x9b, 0x3f, 0x8a,
527 0x78, 0x76, 0xab, 0xd0, 0xbe, 0xfc, 0xe4, 0x79, 0xcb, 0x1b, 0x2b, 0xaa, 0x4d, 0xdd, 0x15,
528 0x61, 0x42, 0x06,
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800529 ];
530
531 // This test invokes make_sample_bcc_and_cdis and compares the result bitwise to the target
532 // vectors. The function uses main_flow, bcc_main_flow, format_config_descriptor,
533 // derive_cdi_private_key_seed, and keypair_from_seed. This test is sensitive to errors
534 // and changes in any of those functions.
535 #[test]
536 fn main_flow_and_bcc_main_flow() {
Alice Wangf4bd1c62023-02-08 08:38:44 +0000537 let dice_artifacts = make_sample_bcc_and_cdis().unwrap();
538 assert_eq!(&dice_artifacts.cdi_values.cdi_attest, SAMPLE_CDI_ATTEST_TEST_VECTOR);
539 assert_eq!(&dice_artifacts.cdi_values.cdi_seal, SAMPLE_CDI_SEAL_TEST_VECTOR);
540 assert_eq!(&dice_artifacts.bcc, SAMPLE_BCC_TEST_VECTOR);
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800541 }
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800542}