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