blob: d92fecf8dca78f7314d72f8f60db948e29140acb [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 Wangb68814b2023-02-02 13:15:32 +000035 check_result, Config, DiceError, Hash, Hidden, InputValues, Result, HASH_SIZE, HIDDEN_SIZE,
Alice Wang856d6562023-02-03 13:51:08 +000036};
37use keystore2_crypto::ZVec;
Janis Danisevskis2cef73f2021-11-03 15:02:48 -070038use open_dice_bcc_bindgen::BccMainFlow;
Alice Wang97d47a72023-01-31 12:48:02 +000039pub use open_dice_cbor_bindgen::DiceMode;
Janis Danisevskis13356b22021-10-20 09:44:12 -070040use open_dice_cbor_bindgen::{
Alice Wang0b9e1102023-02-02 09:57:06 +000041 DiceDeriveCdiCertificateId, DiceDeriveCdiPrivateKeySeed, DiceGenerateCertificate, DiceHash,
Alice Wangb68814b2023-02-02 13:15:32 +000042 DiceKdf, DiceKeypairFromSeed, DiceMainFlow, DiceSign, DiceVerify, DICE_CDI_SIZE, DICE_ID_SIZE,
43 DICE_PRIVATE_KEY_SEED_SIZE, 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 seed.
48pub const PRIVATE_KEY_SEED_SIZE: usize = DICE_PRIVATE_KEY_SEED_SIZE as usize;
49/// The size of a CDI.
50pub const CDI_SIZE: usize = DICE_CDI_SIZE as usize;
51/// The size of an ID.
52pub const ID_SIZE: usize = DICE_ID_SIZE as usize;
53/// The size of a private key.
54pub const PRIVATE_KEY_SIZE: usize = DICE_PRIVATE_KEY_SIZE as usize;
55/// The size of a public key.
56pub const PUBLIC_KEY_SIZE: usize = DICE_PUBLIC_KEY_SIZE as usize;
57/// The size of a signature.
58pub const SIGNATURE_SIZE: usize = DICE_SIGNATURE_SIZE as usize;
59
Janis Danisevskis13356b22021-10-20 09:44:12 -070060/// Multiple of the open dice function required preallocated output buffer
61/// which may be too small, this function implements the retry logic to handle
62/// too small buffer allocations.
63/// The callback `F` must expect a mutable reference to a buffer and a size hint
64/// field. The callback is called repeatedly as long as it returns
65/// `Err(Error::BufferTooSmall)`. If the size hint remains 0, the buffer size is
66/// doubled with each iteration. If the size hint is set by the callback, the buffer
67/// will be set to accommodate at least this many bytes.
68/// If the callback returns `Ok(())`, the buffer is truncated to the size hint
69/// exactly.
70/// The function panics if the callback returns `Ok(())` and the size hint is
71/// larger than the buffer size.
72fn retry_while_adjusting_output_buffer<F>(mut f: F) -> Result<Vec<u8>>
73where
74 F: FnMut(&mut Vec<u8>, &mut usize) -> Result<()>,
75{
76 let mut buffer = vec![0; INITIAL_OUT_BUFFER_SIZE];
77 let mut actual_size: usize = 0;
78 loop {
79 match f(&mut buffer, &mut actual_size) {
80 // If Error::BufferTooSmall was returned, the allocated certificate
81 // buffer was to small for the output. So the buffer is resized to the actual
82 // size, and a second attempt is made with the new buffer.
Alice Wang856d6562023-02-03 13:51:08 +000083 Err(DiceError::BufferTooSmall) => {
Janis Danisevskis13356b22021-10-20 09:44:12 -070084 let new_size = if actual_size == 0 {
85 // Due to an off spec implementation of open dice cbor, actual size
86 // does not return the required size if the buffer was too small. So
87 // we have to try and approach it gradually.
88 buffer.len() * 2
89 } else {
90 actual_size
91 };
92 buffer.resize(new_size, 0);
93 continue;
94 }
95 Err(e) => return Err(e),
96 Ok(()) => {
97 if actual_size > buffer.len() {
98 panic!(
99 "actual_size larger than buffer size: open-dice function
100 may have written past the end of the buffer."
101 );
102 }
103 // Truncate the certificate buffer to the actual size because it may be
104 // smaller than the original allocation.
105 buffer.truncate(actual_size);
106 return Ok(buffer);
107 }
108 }
109 }
110}
111
112/// Some libopen-dice variants use a context. Developers that want to customize these
113/// bindings may want to implement their own Context factory that creates a context
114/// useable by their preferred backend.
115pub trait Context {
116 /// # Safety
117 /// The return value of get_context is passed to any open dice function.
118 /// Implementations must explain why the context pointer returned is safe
119 /// to be used by the open dice library.
120 unsafe fn get_context(&mut self) -> *mut c_void;
121}
122
123impl<T: Context + Send> ContextImpl for T {}
124
125/// This represents a context for the open dice library. The wrapped open dice instance, which
126/// is based on boringssl and cbor, does not use a context, so that this type is empty.
127#[derive(Default)]
128pub struct OpenDiceCborContext();
129
130impl OpenDiceCborContext {
131 /// Construct a new instance of OpenDiceCborContext.
132 pub fn new() -> Self {
133 Default::default()
134 }
135}
136
137impl Context for OpenDiceCborContext {
138 unsafe fn get_context(&mut self) -> *mut c_void {
139 // # Safety
140 // The open dice cbor implementation does not use a context. It is safe
141 // to return NULL.
142 std::ptr::null_mut()
143 }
144}
145
146/// Type alias for ZVec indicating that it holds a CDI_ATTEST secret.
147pub type CdiAttest = ZVec;
148
149/// Type alias for ZVec indicating that it holds a CDI_SEAL secret.
150pub type CdiSeal = ZVec;
151
152/// Type alias for Vec<u8> indicating that it hold a DICE certificate.
153pub type Cert = Vec<u8>;
154
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700155/// Type alias for Vec<u8> indicating that it holds a BCC certificate chain.
156pub type Bcc = Vec<u8>;
157
Janis Danisevskis13356b22021-10-20 09:44:12 -0700158const INITIAL_OUT_BUFFER_SIZE: usize = 1024;
159
160/// ContextImpl is a mixin trait that implements the safe wrappers around the open dice
161/// library calls. Implementations must implement Context::get_context(). As of
162/// this writing, the only implementation is OpenDiceCborContext, which returns NULL.
163pub trait ContextImpl: Context + Send {
164 /// Safe wrapper around open-dice DiceDeriveCdiPrivateKeySeed, see open dice
165 /// documentation for details.
166 fn derive_cdi_private_key_seed(&mut self, cdi_attest: &[u8; CDI_SIZE]) -> Result<ZVec> {
167 let mut seed = ZVec::new(PRIVATE_KEY_SEED_SIZE)?;
168 // SAFETY:
169 // * The first context argument may be NULL and is unused by the wrapped
170 // implementation.
171 // * The second argument is expected to be a const array of size CDI_SIZE.
172 // * The third argument is expected to be a non const array of size
173 // PRIVATE_KEY_SEED_SIZE which is fulfilled if the call to ZVec::new above
174 // succeeds.
175 // * No pointers are expected to be valid beyond the scope of the function
176 // call.
177 check_result(unsafe {
178 DiceDeriveCdiPrivateKeySeed(self.get_context(), cdi_attest.as_ptr(), seed.as_mut_ptr())
179 })?;
180 Ok(seed)
181 }
182
183 /// Safe wrapper around open-dice DiceDeriveCdiCertificateId, see open dice
184 /// documentation for details.
185 fn derive_cdi_certificate_id(&mut self, cdi_public_key: &[u8]) -> Result<ZVec> {
186 let mut id = ZVec::new(ID_SIZE)?;
187 // SAFETY:
188 // * The first context argument may be NULL and is unused by the wrapped
189 // implementation.
190 // * The second argument is expected to be a const array with a size given by the
191 // third argument.
192 // * The fourth argument is expected to be a non const array of size
193 // ID_SIZE which is fulfilled if the call to ZVec::new above succeeds.
194 // * No pointers are expected to be valid beyond the scope of the function
195 // call.
196 check_result(unsafe {
197 DiceDeriveCdiCertificateId(
198 self.get_context(),
199 cdi_public_key.as_ptr(),
200 cdi_public_key.len(),
201 id.as_mut_ptr(),
202 )
203 })?;
204 Ok(id)
205 }
206
207 /// Safe wrapper around open-dice DiceMainFlow, see open dice
208 /// documentation for details.
209 /// Returns a tuple of:
210 /// * The next attestation CDI,
211 /// * the next seal CDI, and
212 /// * the next attestation certificate.
213 /// `(next_attest_cdi, next_seal_cdi, next_attestation_cert)`
Alice Wangb68814b2023-02-02 13:15:32 +0000214 fn main_flow(
Janis Danisevskis13356b22021-10-20 09:44:12 -0700215 &mut self,
216 current_cdi_attest: &[u8; CDI_SIZE],
217 current_cdi_seal: &[u8; CDI_SIZE],
Alice Wangb68814b2023-02-02 13:15:32 +0000218 input_values: &InputValues,
Janis Danisevskis13356b22021-10-20 09:44:12 -0700219 ) -> Result<(CdiAttest, CdiSeal, Cert)> {
220 let mut next_attest = CdiAttest::new(CDI_SIZE)?;
221 let mut next_seal = CdiSeal::new(CDI_SIZE)?;
222
223 // SAFETY (DiceMainFlow):
224 // * The first context argument may be NULL and is unused by the wrapped
225 // implementation.
226 // * The second argument and the third argument are const arrays of size CDI_SIZE.
227 // This is fulfilled as per the definition of the arguments `current_cdi_attest`
228 // and `current_cdi_seal.
229 // * The fourth argument is a pointer to `DiceInputValues`. It, and its indirect
Alice Wangb68814b2023-02-02 13:15:32 +0000230 // references must be valid for the duration of the function call.
Janis Danisevskis13356b22021-10-20 09:44:12 -0700231 // * The fifth and sixth argument are the length of and the pointer to the
232 // allocated certificate buffer respectively. They are used to return
233 // the generated certificate.
234 // * The seventh argument is a pointer to a mutable usize object. It is
235 // used to return the actual size of the output certificate.
236 // * The eighth argument and the ninth argument are pointers to mutable buffers of size
237 // CDI_SIZE. This is fulfilled if the allocation above succeeded.
238 // * No pointers are expected to be valid beyond the scope of the function
239 // call.
Alice Wangb68814b2023-02-02 13:15:32 +0000240 let cert = retry_while_adjusting_output_buffer(|cert, actual_size| {
241 check_result(unsafe {
242 DiceMainFlow(
243 self.get_context(),
244 current_cdi_attest.as_ptr(),
245 current_cdi_seal.as_ptr(),
246 input_values.as_ptr(),
247 cert.len(),
248 cert.as_mut_ptr(),
249 actual_size as *mut _,
250 next_attest.as_mut_ptr(),
251 next_seal.as_mut_ptr(),
252 )
253 })
254 })?;
255 Ok((next_attest, next_seal, cert))
Janis Danisevskis13356b22021-10-20 09:44:12 -0700256 }
257
258 /// Safe wrapper around open-dice DiceHash, see open dice
259 /// documentation for details.
260 fn hash(&mut self, input: &[u8]) -> Result<Vec<u8>> {
261 let mut output: Vec<u8> = vec![0; HASH_SIZE];
262
263 // SAFETY:
264 // * The first context argument may be NULL and is unused by the wrapped
265 // implementation.
266 // * The second argument and the third argument are the pointer to and length of the given
267 // input buffer respectively.
268 // * The fourth argument must be a pointer to a mutable buffer of size HASH_SIZE
269 // which is fulfilled by the allocation above.
270 check_result(unsafe {
271 DiceHash(self.get_context(), input.as_ptr(), input.len(), output.as_mut_ptr())
272 })?;
273 Ok(output)
274 }
275
276 /// Safe wrapper around open-dice DiceKdf, see open dice
277 /// documentation for details.
278 fn kdf(&mut self, length: usize, input_key: &[u8], salt: &[u8], info: &[u8]) -> Result<ZVec> {
279 let mut output = ZVec::new(length)?;
280
281 // SAFETY:
282 // * The first context argument may be NULL and is unused by the wrapped
283 // implementation.
284 // * The second argument is primitive.
285 // * The third argument and the fourth argument are the pointer to and length of the given
286 // input key.
287 // * The fifth argument and the sixth argument are the pointer to and length of the given
288 // salt.
289 // * The seventh argument and the eighth argument are the pointer to and length of the
290 // given info field.
291 // * The ninth argument is a pointer to the output buffer which must have the
292 // length given by the `length` argument (see second argument). This is
293 // fulfilled if the allocation of `output` succeeds.
294 // * All pointers must be valid for the duration of the function call, but not
295 // longer.
296 check_result(unsafe {
297 DiceKdf(
298 self.get_context(),
299 length,
300 input_key.as_ptr(),
301 input_key.len(),
302 salt.as_ptr(),
303 salt.len(),
304 info.as_ptr(),
305 info.len(),
306 output.as_mut_ptr(),
307 )
308 })?;
309 Ok(output)
310 }
311
312 /// Safe wrapper around open-dice DiceKeyPairFromSeed, see open dice
313 /// documentation for details.
314 fn keypair_from_seed(&mut self, seed: &[u8; PRIVATE_KEY_SEED_SIZE]) -> Result<(Vec<u8>, ZVec)> {
315 let mut private_key = ZVec::new(PRIVATE_KEY_SIZE)?;
316 let mut public_key = vec![0u8; PUBLIC_KEY_SIZE];
317
318 // SAFETY:
319 // * The first context argument may be NULL and is unused by the wrapped
320 // implementation.
321 // * The second argument is a pointer to a const buffer of size `PRIVATE_KEY_SEED_SIZE`
322 // fulfilled by the definition of the argument.
323 // * The third argument and the fourth argument are mutable buffers of size
324 // `PRIVATE_KEY_SIZE` and `PUBLIC_KEY_SIZE` respectively. This is fulfilled by the
325 // allocations above.
326 // * All pointers must be valid for the duration of the function call but not beyond.
327 check_result(unsafe {
328 DiceKeypairFromSeed(
329 self.get_context(),
330 seed.as_ptr(),
331 public_key.as_mut_ptr(),
332 private_key.as_mut_ptr(),
333 )
334 })?;
335 Ok((public_key, private_key))
336 }
337
338 /// Safe wrapper around open-dice DiceSign, see open dice
339 /// documentation for details.
340 fn sign(&mut self, message: &[u8], private_key: &[u8; PRIVATE_KEY_SIZE]) -> Result<Vec<u8>> {
341 let mut signature = vec![0u8; SIGNATURE_SIZE];
342
343 // SAFETY:
344 // * The first context argument may be NULL and is unused by the wrapped
345 // implementation.
346 // * The second argument and the third argument are the pointer to and length of the given
347 // message buffer.
348 // * The fourth argument is a const buffer of size `PRIVATE_KEY_SIZE`. This is fulfilled
349 // by the definition of `private key`.
350 // * The fifth argument is mutable buffer of size `SIGNATURE_SIZE`. This is fulfilled
351 // by the allocation above.
352 // * All pointers must be valid for the duration of the function call but not beyond.
353 check_result(unsafe {
354 DiceSign(
355 self.get_context(),
356 message.as_ptr(),
357 message.len(),
358 private_key.as_ptr(),
359 signature.as_mut_ptr(),
360 )
361 })?;
362 Ok(signature)
363 }
364
365 /// Safe wrapper around open-dice DiceVerify, see open dice
366 /// documentation for details.
367 fn verify(
368 &mut self,
369 message: &[u8],
370 signature: &[u8; SIGNATURE_SIZE],
371 public_key: &[u8; PUBLIC_KEY_SIZE],
372 ) -> Result<()> {
373 // SAFETY:
374 // * The first context argument may be NULL and is unused by the wrapped
375 // implementation.
376 // * The second argument and the third argument are the pointer to and length of the given
377 // message buffer.
378 // * The fourth argument is a const buffer of size `SIGNATURE_SIZE`. This is fulfilled
379 // by the definition of `signature`.
380 // * The fifth argument is a const buffer of size `PUBLIC_KEY_SIZE`. This is fulfilled
381 // by the definition of `public_key`.
382 // * All pointers must be valid for the duration of the function call but not beyond.
383 check_result(unsafe {
384 DiceVerify(
385 self.get_context(),
386 message.as_ptr(),
387 message.len(),
388 signature.as_ptr(),
389 public_key.as_ptr(),
390 )
391 })
392 }
393
394 /// Safe wrapper around open-dice DiceGenerateCertificate, see open dice
395 /// documentation for details.
Alice Wangb68814b2023-02-02 13:15:32 +0000396 fn generate_certificate(
Janis Danisevskis13356b22021-10-20 09:44:12 -0700397 &mut self,
398 subject_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
399 authority_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
Alice Wangb68814b2023-02-02 13:15:32 +0000400 input_values: &InputValues,
Janis Danisevskis13356b22021-10-20 09:44:12 -0700401 ) -> Result<Vec<u8>> {
Alice Wangb68814b2023-02-02 13:15:32 +0000402 // SAFETY (DiceGenerateCertificate):
Janis Danisevskis13356b22021-10-20 09:44:12 -0700403 // * The first context argument may be NULL and is unused by the wrapped
404 // implementation.
405 // * The second argument and the third argument are const arrays of size
406 // `PRIVATE_KEY_SEED_SIZE`. This is fulfilled as per the definition of the arguments.
407 // * The fourth argument is a pointer to `DiceInputValues` it, and its indirect
Alice Wangb68814b2023-02-02 13:15:32 +0000408 // references must be valid for the duration of the function call.
Janis Danisevskis13356b22021-10-20 09:44:12 -0700409 // * The fifth argument and the sixth argument are the length of and the pointer to the
410 // allocated certificate buffer respectively. They are used to return
411 // the generated certificate.
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700412 // * The seventh argument is a pointer to a mutable usize object. It is
Janis Danisevskis13356b22021-10-20 09:44:12 -0700413 // used to return the actual size of the output certificate.
414 // * All pointers must be valid for the duration of the function call but not beyond.
Alice Wangb68814b2023-02-02 13:15:32 +0000415 let cert = retry_while_adjusting_output_buffer(|cert, actual_size| {
416 check_result(unsafe {
417 DiceGenerateCertificate(
418 self.get_context(),
419 subject_private_key_seed.as_ptr(),
420 authority_private_key_seed.as_ptr(),
421 input_values.as_ptr(),
422 cert.len(),
423 cert.as_mut_ptr(),
424 actual_size as *mut _,
425 )
426 })
427 })?;
428 Ok(cert)
Janis Danisevskis13356b22021-10-20 09:44:12 -0700429 }
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700430
431 /// Safe wrapper around open-dice BccDiceMainFlow, see open dice
432 /// documentation for details.
433 /// Returns a tuple of:
434 /// * The next attestation CDI,
435 /// * the next seal CDI, and
436 /// * the next bcc adding the new certificate to the given bcc.
437 /// `(next_attest_cdi, next_seal_cdi, next_bcc)`
Alice Wangb68814b2023-02-02 13:15:32 +0000438 fn bcc_main_flow(
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700439 &mut self,
440 current_cdi_attest: &[u8; CDI_SIZE],
441 current_cdi_seal: &[u8; CDI_SIZE],
442 bcc: &[u8],
Alice Wangb68814b2023-02-02 13:15:32 +0000443 input_values: &InputValues,
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700444 ) -> Result<(CdiAttest, CdiSeal, Bcc)> {
445 let mut next_attest = CdiAttest::new(CDI_SIZE)?;
446 let mut next_seal = CdiSeal::new(CDI_SIZE)?;
447
448 // SAFETY (BccMainFlow):
449 // * The first context argument may be NULL and is unused by the wrapped
450 // implementation.
451 // * The second argument and the third argument are const arrays of size CDI_SIZE.
452 // This is fulfilled as per the definition of the arguments `current_cdi_attest`
453 // and `current_cdi_seal`.
454 // * The fourth argument and the fifth argument are the pointer to and size of the buffer
455 // holding the current bcc.
456 // * The sixth argument is a pointer to `DiceInputValues` it, and its indirect
Alice Wangb68814b2023-02-02 13:15:32 +0000457 // references must be valid for the duration of the function call.
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700458 // * The seventh argument and the eighth argument are the length of and the pointer to the
459 // allocated certificate buffer respectively. They are used to return the generated
460 // certificate.
461 // * The ninth argument is a pointer to a mutable usize object. It is
462 // used to return the actual size of the output certificate.
463 // * The tenth argument and the eleventh argument are pointers to mutable buffers of
464 // size CDI_SIZE. This is fulfilled if the allocation above succeeded.
465 // * No pointers are expected to be valid beyond the scope of the function
466 // call.
Alice Wangb68814b2023-02-02 13:15:32 +0000467 let next_bcc = retry_while_adjusting_output_buffer(|next_bcc, actual_size| {
468 check_result(unsafe {
469 BccMainFlow(
470 self.get_context(),
471 current_cdi_attest.as_ptr(),
472 current_cdi_seal.as_ptr(),
473 bcc.as_ptr(),
474 bcc.len(),
475 input_values.as_ptr(),
476 next_bcc.len(),
477 next_bcc.as_mut_ptr(),
478 actual_size as *mut _,
479 next_attest.as_mut_ptr(),
480 next_seal.as_mut_ptr(),
481 )
482 })
483 })?;
484 Ok((next_attest, next_seal, next_bcc))
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700485 }
486}
487
488/// This submodule provides additional support for the Boot Certificate Chain (BCC)
489/// specification.
490/// See https://cs.android.com/android/platform/superproject/+/master:hardware/interfaces/security/keymint/aidl/android/hardware/security/keymint/ProtectedData.aidl
491pub mod bcc {
Alice Wang856d6562023-02-03 13:51:08 +0000492 use super::{check_result, retry_while_adjusting_output_buffer, DiceError, Result};
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700493 use open_dice_bcc_bindgen::{
494 BccConfigValues, BccFormatConfigDescriptor, BCC_INPUT_COMPONENT_NAME,
495 BCC_INPUT_COMPONENT_VERSION, BCC_INPUT_RESETTABLE,
496 };
497 use std::ffi::CString;
498
499 /// Safe wrapper around BccFormatConfigDescriptor, see open dice documentation for details.
Alice Wang856d6562023-02-03 13:51:08 +0000500 /// TODO(b/267575445): Make `component_name` take &CStr here.
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700501 pub fn format_config_descriptor(
502 component_name: Option<&str>,
503 component_version: Option<u64>,
504 resettable: bool,
505 ) -> Result<Vec<u8>> {
506 let component_name = match component_name {
Alice Wang856d6562023-02-03 13:51:08 +0000507 Some(n) => Some(CString::new(n).map_err(|_| DiceError::CStrNulError)?),
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700508 None => None,
509 };
510 let input = BccConfigValues {
511 inputs: if component_name.is_some() { BCC_INPUT_COMPONENT_NAME } else { 0 }
512 | if component_version.is_some() { BCC_INPUT_COMPONENT_VERSION } else { 0 }
513 | if resettable { BCC_INPUT_RESETTABLE } else { 0 },
514 // SAFETY: The as_ref() in the line below is vital to keep the component_name object
515 // alive. Removing as_ref will move the component_name and the pointer will
516 // become invalid after this statement.
517 component_name: component_name.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
518 component_version: component_version.unwrap_or(0),
519 };
520
521 // SAFETY:
522 // * The first argument is a pointer to the BccConfigValues input assembled above.
523 // It and its indirections must be valid for the duration of the function call.
524 // * The second argument and the third argument are the length of and the pointer to the
525 // allocated output buffer respectively. The buffer must be at least as long
526 // as indicated by the size argument.
527 // * The forth argument is a pointer to the actual size returned by the function.
528 // * All pointers must be valid for the duration of the function call but not beyond.
529 retry_while_adjusting_output_buffer(|config_descriptor, actual_size| {
530 check_result(unsafe {
531 BccFormatConfigDescriptor(
532 &input as *const BccConfigValues,
533 config_descriptor.len(),
534 config_descriptor.as_mut_ptr(),
535 actual_size as *mut _,
536 )
537 })
538 })
539 }
Janis Danisevskis13356b22021-10-20 09:44:12 -0700540}
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800541
542#[cfg(test)]
543mod test {
544 use super::*;
545 use diced_sample_inputs::make_sample_bcc_and_cdis;
546 use std::convert::TryInto;
547
548 static SEED_TEST_VECTOR: &[u8] = &[
549 0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
550 0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
551 0x3a, 0x08, 0x84, 0x8a, 0x98, 0x85, 0x6d, 0xf5, 0x69, 0x21, 0x03, 0xcd, 0x09, 0xc3, 0x28,
552 0xd6, 0x06, 0xa7, 0x57, 0xbd, 0x48, 0x4b, 0x0f, 0x79, 0x0f, 0xf8, 0x2f, 0xf0, 0x0a, 0x41,
553 0x94, 0xd8, 0x8c, 0xa8,
554 ];
555
556 static CDI_ATTEST_TEST_VECTOR: &[u8] = &[
557 0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
558 0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
559 0x3a, 0x08,
560 ];
561 static CDI_PRIVATE_KEY_SEED_TEST_VECTOR: &[u8] = &[
562 0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
563 0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
564 0x02, 0x6e,
565 ];
566
567 static PUB_KEY_TEST_VECTOR: &[u8] = &[
568 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23,
569 0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61,
570 0x06, 0x37,
571 ];
572 static PRIV_KEY_TEST_VECTOR: &[u8] = &[
573 0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
574 0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
575 0x02, 0x6e, 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b,
576 0xfc, 0x23, 0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52,
577 0xf1, 0x61, 0x06, 0x37,
578 ];
579
580 static SIGNATURE_TEST_VECTOR: &[u8] = &[
581 0x44, 0xae, 0xcc, 0xe2, 0xb9, 0x96, 0x18, 0x39, 0x0e, 0x61, 0x0f, 0x53, 0x07, 0xbf, 0xf2,
582 0x32, 0x3d, 0x44, 0xd4, 0xf2, 0x07, 0x23, 0x30, 0x85, 0x32, 0x18, 0xd2, 0x69, 0xb8, 0x29,
583 0x3c, 0x26, 0xe6, 0x0d, 0x9c, 0xa5, 0xc2, 0x73, 0xcd, 0x8c, 0xb8, 0x3c, 0x3e, 0x5b, 0xfd,
584 0x62, 0x8d, 0xf6, 0xc4, 0x27, 0xa6, 0xe9, 0x11, 0x06, 0x5a, 0xb2, 0x2b, 0x64, 0xf7, 0xfc,
585 0xbb, 0xab, 0x4a, 0x0e,
586 ];
587
588 #[test]
589 fn hash_derive_sign_verify() {
590 let mut ctx = OpenDiceCborContext::new();
591 let seed = ctx.hash("MySeedString".as_bytes()).unwrap();
592 assert_eq!(seed, SEED_TEST_VECTOR);
593 let cdi_attest = &seed[..CDI_SIZE];
594 assert_eq!(cdi_attest, CDI_ATTEST_TEST_VECTOR);
595 let cdi_private_key_seed =
596 ctx.derive_cdi_private_key_seed(cdi_attest.try_into().unwrap()).unwrap();
597 assert_eq!(&cdi_private_key_seed[..], CDI_PRIVATE_KEY_SEED_TEST_VECTOR);
598 let (pub_key, priv_key) =
599 ctx.keypair_from_seed(cdi_private_key_seed[..].try_into().unwrap()).unwrap();
600 assert_eq!(&pub_key, PUB_KEY_TEST_VECTOR);
601 assert_eq!(&priv_key[..], PRIV_KEY_TEST_VECTOR);
602 let mut signature =
603 ctx.sign("MyMessage".as_bytes(), priv_key[..].try_into().unwrap()).unwrap();
604 assert_eq!(&signature, SIGNATURE_TEST_VECTOR);
605 assert!(ctx
606 .verify(
607 "MyMessage".as_bytes(),
608 signature[..].try_into().unwrap(),
609 pub_key[..].try_into().unwrap()
610 )
611 .is_ok());
612 assert!(ctx
613 .verify(
614 "MyMessage_fail".as_bytes(),
615 signature[..].try_into().unwrap(),
616 pub_key[..].try_into().unwrap()
617 )
618 .is_err());
619 signature[0] += 1;
620 assert!(ctx
621 .verify(
622 "MyMessage".as_bytes(),
623 signature[..].try_into().unwrap(),
624 pub_key[..].try_into().unwrap()
625 )
626 .is_err());
627 }
628
629 static SAMPLE_CDI_ATTEST_TEST_VECTOR: &[u8] = &[
630 0x3e, 0x57, 0x65, 0x5d, 0x48, 0x02, 0xbd, 0x5c, 0x66, 0xcc, 0x1f, 0x0f, 0xbe, 0x5e, 0x32,
631 0xb6, 0x9e, 0x3d, 0x04, 0xaf, 0x00, 0x15, 0xbc, 0xdd, 0x1f, 0xbc, 0x59, 0xe4, 0xc3, 0x87,
632 0x95, 0x5e,
633 ];
634
635 static SAMPLE_CDI_SEAL_TEST_VECTOR: &[u8] = &[
636 0x36, 0x1b, 0xd2, 0xb3, 0xc4, 0xda, 0x77, 0xb2, 0x9c, 0xba, 0x39, 0x53, 0x82, 0x93, 0xd9,
637 0xb8, 0x9f, 0x73, 0x2d, 0x27, 0x06, 0x15, 0xa8, 0xcb, 0x6d, 0x1d, 0xf2, 0xb1, 0x54, 0xbb,
638 0x62, 0xf1,
639 ];
640
641 static SAMPLE_BCC_TEST_VECTOR: &[u8] = &[
Alan Stokes7cdcf992022-05-24 07:42:24 +0000642 0x84, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x3e,
643 0x85, 0xe5, 0x72, 0x75, 0x55, 0xe5, 0x1e, 0xe7, 0xf3, 0x35, 0x94, 0x8e, 0xbb, 0xbd, 0x74,
644 0x1e, 0x1d, 0xca, 0x49, 0x9c, 0x97, 0x39, 0x77, 0x06, 0xd3, 0xc8, 0x6e, 0x8b, 0xd7, 0x33,
645 0xf9, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9, 0x01, 0x78, 0x28, 0x34,
646 0x32, 0x64, 0x38, 0x38, 0x36, 0x34, 0x66, 0x39, 0x37, 0x62, 0x36, 0x35, 0x34, 0x37, 0x61,
647 0x35, 0x30, 0x63, 0x31, 0x65, 0x30, 0x61, 0x37, 0x34, 0x39, 0x66, 0x38, 0x65, 0x66, 0x38,
648 0x62, 0x38, 0x31, 0x65, 0x63, 0x36, 0x32, 0x61, 0x66, 0x02, 0x78, 0x28, 0x31, 0x66, 0x36,
649 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35, 0x32, 0x66, 0x32, 0x39, 0x65, 0x39, 0x33, 0x66,
650 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65, 0x33, 0x32, 0x63, 0x64, 0x38, 0x31, 0x64,
651 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x16,
652 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38, 0xc3, 0x64, 0x38, 0x63, 0x26,
653 0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34, 0x4c, 0x6d, 0xa2, 0xbe,
654 0x25, 0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2, 0xb3, 0x91, 0x4d,
655 0xd3, 0xfb, 0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba, 0x30, 0xf7,
656 0x15, 0x98, 0x14, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56, 0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71,
657 0x63, 0x41, 0x42, 0x4c, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a, 0x00, 0x01, 0x11, 0x73,
658 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x47, 0xae, 0x42, 0x27, 0x4c, 0xcb, 0x65,
659 0x4d, 0xee, 0x74, 0x2d, 0x05, 0x78, 0x2a, 0x08, 0x2a, 0xa5, 0xf0, 0xcf, 0xea, 0x3e, 0x60,
660 0xee, 0x97, 0x11, 0x4b, 0x5b, 0xe6, 0x05, 0x0c, 0xe8, 0x90, 0xf5, 0x22, 0xc4, 0xc6, 0x67,
661 0x7a, 0x22, 0x27, 0x17, 0xb3, 0x79, 0xcc, 0x37, 0x64, 0x5e, 0x19, 0x4f, 0x96, 0x37, 0x67,
662 0x3c, 0xd0, 0xc5, 0xed, 0x0f, 0xdd, 0xe7, 0x2e, 0x4f, 0x70, 0x97, 0x30, 0x3a, 0x00, 0x47,
663 0x44, 0x54, 0x58, 0x40, 0xf9, 0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3,
664 0x97, 0x4a, 0xcb, 0x3c, 0xe7, 0x6b, 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59,
665 0x15, 0xb1, 0x23, 0xe6, 0xc8, 0xdf, 0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc,
666 0x5b, 0x37, 0x0e, 0x12, 0x12, 0xb2, 0xfd, 0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6,
667 0x29, 0x1b, 0x99, 0xea, 0xae, 0xfd, 0xaa, 0x0d, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01,
668 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02,
669 0x20, 0x06, 0x21, 0x58, 0x20, 0xb1, 0x02, 0xcc, 0x2c, 0xb2, 0x6a, 0x3b, 0xe9, 0xc1, 0xd3,
670 0x95, 0x10, 0xa0, 0xe1, 0xff, 0x51, 0xde, 0x57, 0xd5, 0x65, 0x28, 0xfd, 0x7f, 0xeb, 0xd4,
671 0xca, 0x15, 0xf3, 0xca, 0xdf, 0x37, 0x88, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58,
672 0x40, 0x58, 0xd8, 0x03, 0x24, 0x53, 0x60, 0x57, 0xa9, 0x09, 0xfa, 0xab, 0xdc, 0x57, 0x1e,
673 0xf0, 0xe5, 0x1e, 0x51, 0x6f, 0x9e, 0xa3, 0x42, 0xe6, 0x6a, 0x8c, 0xaa, 0xad, 0x08, 0x48,
674 0xde, 0x7f, 0x4f, 0x6e, 0x2f, 0x7f, 0x39, 0x6c, 0xa1, 0xf8, 0x42, 0x71, 0xfe, 0x17, 0x3d,
675 0xca, 0x31, 0x83, 0x92, 0xed, 0xbb, 0x40, 0xb8, 0x10, 0xe0, 0xf2, 0x5a, 0x99, 0x53, 0x38,
676 0x46, 0x33, 0x97, 0x78, 0x05, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9,
677 0x01, 0x78, 0x28, 0x31, 0x66, 0x36, 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35, 0x32, 0x66,
678 0x32, 0x39, 0x65, 0x39, 0x33, 0x66, 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65, 0x33,
679 0x32, 0x63, 0x64, 0x38, 0x31, 0x64, 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x02, 0x78,
680 0x28, 0x32, 0x35, 0x39, 0x34, 0x38, 0x39, 0x65, 0x36, 0x39, 0x37, 0x34, 0x38, 0x37, 0x30,
681 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66, 0x34, 0x34, 0x32, 0x36, 0x37, 0x65, 0x61, 0x34,
682 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35, 0x37, 0x32, 0x35, 0x3a, 0x00, 0x47, 0x44,
683 0x50, 0x58, 0x40, 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43,
684 0x83, 0x7f, 0x46, 0x8d, 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0, 0xd9,
685 0x56, 0xb3, 0xbf, 0x2f, 0xfa, 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9, 0x6b, 0x18,
686 0x28, 0xe8, 0x29, 0x20, 0x49, 0x0f, 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54, 0xe9, 0x71, 0xd2,
687 0x7e, 0xa4, 0xfe, 0x58, 0x7f, 0xd3, 0xc7, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56, 0xa3, 0x3a,
688 0x00, 0x01, 0x11, 0x71, 0x63, 0x41, 0x56, 0x42, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a,
689 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x93, 0x17, 0xe1,
690 0x11, 0x27, 0x59, 0xd0, 0xef, 0x75, 0x0b, 0x2b, 0x1c, 0x0f, 0x5f, 0x52, 0xc3, 0x29, 0x23,
691 0xb5, 0x2a, 0xe6, 0x12, 0x72, 0x6f, 0x39, 0x86, 0x65, 0x2d, 0xf2, 0xe4, 0xe7, 0xd0, 0xaf,
692 0x0e, 0xa7, 0x99, 0x16, 0x89, 0x97, 0x21, 0xf7, 0xdc, 0x89, 0xdc, 0xde, 0xbb, 0x94, 0x88,
693 0x1f, 0xda, 0xe2, 0xf3, 0xe0, 0x54, 0xf9, 0x0e, 0x29, 0xb1, 0xbd, 0xe1, 0x0c, 0x0b, 0xd7,
694 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa,
695 0x55, 0x6f, 0xac, 0x56, 0xd9, 0x02, 0x35, 0x2b, 0xaa, 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a,
696 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d, 0xe4, 0x43, 0x13, 0xbf, 0xfe, 0xd3, 0x36,
697 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6, 0x66, 0xef, 0xab, 0x3d, 0x0f, 0x89, 0xa4,
698 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a, 0xef, 0xbc, 0x05, 0x98, 0x3a, 0x00, 0x47,
699 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03,
700 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x96, 0x6d, 0x96, 0x42, 0xda, 0x64,
701 0x51, 0xad, 0xfa, 0x00, 0xbc, 0xbc, 0x95, 0x8a, 0xb0, 0xb9, 0x76, 0x01, 0xe6, 0xbd, 0xc0,
702 0x26, 0x79, 0x26, 0xfc, 0x0f, 0x1d, 0x87, 0x65, 0xf1, 0xf3, 0x99, 0x3a, 0x00, 0x47, 0x44,
703 0x58, 0x41, 0x20, 0x58, 0x40, 0x10, 0x7f, 0x77, 0xad, 0x70, 0xbd, 0x52, 0x81, 0x28, 0x8d,
704 0x24, 0x81, 0xb4, 0x3f, 0x21, 0x68, 0x9f, 0xc3, 0x80, 0x68, 0x86, 0x55, 0xfb, 0x2e, 0x6d,
705 0x96, 0xe1, 0xe1, 0xb7, 0x28, 0x8d, 0x63, 0x85, 0xba, 0x2a, 0x01, 0x33, 0x87, 0x60, 0x63,
706 0xbb, 0x16, 0x3f, 0x2f, 0x3d, 0xf4, 0x2d, 0x48, 0x5b, 0x87, 0xed, 0xda, 0x34, 0xeb, 0x9c,
707 0x4d, 0x14, 0xac, 0x65, 0xf4, 0xfa, 0xef, 0x45, 0x0b, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0,
708 0x59, 0x01, 0x8f, 0xa9, 0x01, 0x78, 0x28, 0x32, 0x35, 0x39, 0x34, 0x38, 0x39, 0x65, 0x36,
709 0x39, 0x37, 0x34, 0x38, 0x37, 0x30, 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66, 0x34, 0x34,
710 0x32, 0x36, 0x37, 0x65, 0x61, 0x34, 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35, 0x37,
711 0x32, 0x35, 0x02, 0x78, 0x28, 0x35, 0x64, 0x34, 0x65, 0x64, 0x37, 0x66, 0x34, 0x31, 0x37,
712 0x61, 0x39, 0x35, 0x34, 0x61, 0x31, 0x38, 0x31, 0x34, 0x30, 0x37, 0x62, 0x35, 0x38, 0x38,
713 0x35, 0x61, 0x66, 0x64, 0x37, 0x32, 0x61, 0x35, 0x62, 0x66, 0x34, 0x30, 0x64, 0x61, 0x36,
714 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Alan Stokes7cdcf992022-05-24 07:42:24 +0000718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x47, 0x44,
719 0x53, 0x58, 0x1a, 0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x67, 0x41, 0x6e, 0x64, 0x72, 0x6f,
720 0x69, 0x64, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x0c, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a,
721 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x26, 0x1a, 0xbd, 0x26, 0xd8, 0x37, 0x8f, 0x4a, 0xf2,
722 0x9e, 0x49, 0x4d, 0x93, 0x23, 0xc4, 0x6e, 0x02, 0xda, 0xe0, 0x00, 0x02, 0xe7, 0xed, 0x29,
723 0xdf, 0x2b, 0xb3, 0x69, 0xf3, 0x55, 0x0e, 0x4c, 0x22, 0xdc, 0xcf, 0xf5, 0x92, 0xc9, 0xfa,
724 0x78, 0x98, 0xf1, 0x0e, 0x55, 0x5f, 0xf4, 0x45, 0xed, 0xc0, 0x0a, 0x72, 0x2a, 0x7a, 0x3a,
725 0xd2, 0xb1, 0xf7, 0x76, 0xfe, 0x2a, 0x6b, 0x7b, 0x2a, 0x53, 0x3a, 0x00, 0x47, 0x44, 0x54,
726 0x58, 0x40, 0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30,
727 0x03, 0xb8, 0xd6, 0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37,
728 0x68, 0x4e, 0x1d, 0xc0, 0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2,
729 0x9c, 0xfc, 0x12, 0x9e, 0x77, 0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5,
730 0x73, 0xd4, 0xc6, 0xdf, 0x62, 0x9f, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00,
731 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06,
732 0x21, 0x58, 0x20, 0xdb, 0xe7, 0x5b, 0x3f, 0xa3, 0x42, 0xb0, 0x9c, 0xf8, 0x40, 0x8c, 0xb0,
733 0x9c, 0xf0, 0x0a, 0xaf, 0xdf, 0x6f, 0xe5, 0x09, 0x21, 0x11, 0x92, 0xe1, 0xf8, 0xc5, 0x09,
734 0x02, 0x3d, 0x1f, 0xb7, 0xc5, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40, 0xc4,
735 0xc1, 0xd7, 0x1c, 0x2d, 0x26, 0x89, 0x22, 0xcf, 0xa6, 0x99, 0x77, 0x30, 0x84, 0x86, 0x27,
736 0x59, 0x8f, 0xd8, 0x08, 0x75, 0xe0, 0xb2, 0xef, 0xf9, 0xfa, 0xa5, 0x40, 0x8c, 0xd3, 0xeb,
737 0xbb, 0xda, 0xf2, 0xc8, 0xae, 0x41, 0x22, 0x50, 0x9c, 0xe8, 0xb2, 0x9c, 0x9b, 0x3f, 0x8a,
738 0x78, 0x76, 0xab, 0xd0, 0xbe, 0xfc, 0xe4, 0x79, 0xcb, 0x1b, 0x2b, 0xaa, 0x4d, 0xdd, 0x15,
739 0x61, 0x42, 0x06,
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800740 ];
741
742 // This test invokes make_sample_bcc_and_cdis and compares the result bitwise to the target
743 // vectors. The function uses main_flow, bcc_main_flow, format_config_descriptor,
744 // derive_cdi_private_key_seed, and keypair_from_seed. This test is sensitive to errors
745 // and changes in any of those functions.
746 #[test]
747 fn main_flow_and_bcc_main_flow() {
748 let (cdi_attest, cdi_seal, bcc) = make_sample_bcc_and_cdis().unwrap();
749 assert_eq!(&cdi_attest[..], SAMPLE_CDI_ATTEST_TEST_VECTOR);
750 assert_eq!(&cdi_seal[..], SAMPLE_CDI_SEAL_TEST_VECTOR);
751 assert_eq!(&bcc[..], SAMPLE_BCC_TEST_VECTOR);
752 }
753
754 static DERIVED_KEY_TEST_VECTOR: &[u8] = &[
755 0x0e, 0xd6, 0x07, 0x0e, 0x1c, 0x38, 0x2c, 0x76, 0x13, 0xc6, 0x76, 0x25, 0x7e, 0x07, 0x6f,
756 0xdb, 0x1d, 0xb1, 0x0f, 0x3f, 0xed, 0xc5, 0x2b, 0x95, 0xd1, 0x32, 0xf1, 0x63, 0x2f, 0x2a,
757 0x01, 0x5e,
758 ];
759
760 #[test]
761 fn kdf() {
762 let mut ctx = OpenDiceCborContext::new();
763 let derived_key = ctx
764 .kdf(
765 PRIVATE_KEY_SEED_SIZE,
766 "myKey".as_bytes(),
767 "mySalt".as_bytes(),
768 "myInfo".as_bytes(),
769 )
770 .unwrap();
771 assert_eq!(&derived_key[..], DERIVED_KEY_TEST_VECTOR);
772 }
773
774 static CERT_ID_TEST_VECTOR: &[u8] = &[
775 0x7a, 0x36, 0x45, 0x2c, 0x02, 0xf6, 0x2b, 0xec, 0xf9, 0x80, 0x06, 0x75, 0x87, 0xa5, 0xc1,
776 0x44, 0x0c, 0xd3, 0xc0, 0x6d,
777 ];
778
779 #[test]
780 fn derive_cdi_certificate_id() {
781 let mut ctx = OpenDiceCborContext::new();
782 let cert_id = ctx.derive_cdi_certificate_id("MyPubKey".as_bytes()).unwrap();
783 assert_eq!(&cert_id[..], CERT_ID_TEST_VECTOR);
784 }
785}