blob: 239bc18d7f13226349e469c9d9e828966cf48cbd [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 Wang7cc59562023-02-08 13:17:10 +000042 DiceGenerateCertificate, DiceKdf, DiceKeypairFromSeed, DiceMainFlow, DiceSign, DiceVerify,
43 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 DiceKdf, see open dice
212 /// documentation for details.
213 fn kdf(&mut self, length: usize, input_key: &[u8], salt: &[u8], info: &[u8]) -> Result<ZVec> {
214 let mut output = ZVec::new(length)?;
215
216 // SAFETY:
217 // * The first context argument may be NULL and is unused by the wrapped
218 // implementation.
219 // * The second argument is primitive.
220 // * The third argument and the fourth argument are the pointer to and length of the given
221 // input key.
222 // * The fifth argument and the sixth argument are the pointer to and length of the given
223 // salt.
224 // * The seventh argument and the eighth argument are the pointer to and length of the
225 // given info field.
226 // * The ninth argument is a pointer to the output buffer which must have the
227 // length given by the `length` argument (see second argument). This is
228 // fulfilled if the allocation of `output` succeeds.
229 // * All pointers must be valid for the duration of the function call, but not
230 // longer.
231 check_result(unsafe {
232 DiceKdf(
233 self.get_context(),
234 length,
235 input_key.as_ptr(),
236 input_key.len(),
237 salt.as_ptr(),
238 salt.len(),
239 info.as_ptr(),
240 info.len(),
241 output.as_mut_ptr(),
242 )
243 })?;
244 Ok(output)
245 }
246
247 /// Safe wrapper around open-dice DiceKeyPairFromSeed, see open dice
248 /// documentation for details.
249 fn keypair_from_seed(&mut self, seed: &[u8; PRIVATE_KEY_SEED_SIZE]) -> Result<(Vec<u8>, ZVec)> {
250 let mut private_key = ZVec::new(PRIVATE_KEY_SIZE)?;
251 let mut public_key = vec![0u8; PUBLIC_KEY_SIZE];
252
253 // SAFETY:
254 // * The first context argument may be NULL and is unused by the wrapped
255 // implementation.
256 // * The second argument is a pointer to a const buffer of size `PRIVATE_KEY_SEED_SIZE`
257 // fulfilled by the definition of the argument.
258 // * The third argument and the fourth argument are mutable buffers of size
259 // `PRIVATE_KEY_SIZE` and `PUBLIC_KEY_SIZE` respectively. This is fulfilled by the
260 // allocations above.
261 // * All pointers must be valid for the duration of the function call but not beyond.
262 check_result(unsafe {
263 DiceKeypairFromSeed(
264 self.get_context(),
265 seed.as_ptr(),
266 public_key.as_mut_ptr(),
267 private_key.as_mut_ptr(),
268 )
269 })?;
270 Ok((public_key, private_key))
271 }
272
273 /// Safe wrapper around open-dice DiceSign, see open dice
274 /// documentation for details.
275 fn sign(&mut self, message: &[u8], private_key: &[u8; PRIVATE_KEY_SIZE]) -> Result<Vec<u8>> {
276 let mut signature = vec![0u8; SIGNATURE_SIZE];
277
278 // SAFETY:
279 // * The first context argument may be NULL and is unused by the wrapped
280 // implementation.
281 // * The second argument and the third argument are the pointer to and length of the given
282 // message buffer.
283 // * The fourth argument is a const buffer of size `PRIVATE_KEY_SIZE`. This is fulfilled
284 // by the definition of `private key`.
285 // * The fifth argument is mutable buffer of size `SIGNATURE_SIZE`. This is fulfilled
286 // by the allocation above.
287 // * All pointers must be valid for the duration of the function call but not beyond.
288 check_result(unsafe {
289 DiceSign(
290 self.get_context(),
291 message.as_ptr(),
292 message.len(),
293 private_key.as_ptr(),
294 signature.as_mut_ptr(),
295 )
296 })?;
297 Ok(signature)
298 }
299
300 /// Safe wrapper around open-dice DiceVerify, see open dice
301 /// documentation for details.
302 fn verify(
303 &mut self,
304 message: &[u8],
305 signature: &[u8; SIGNATURE_SIZE],
306 public_key: &[u8; PUBLIC_KEY_SIZE],
307 ) -> Result<()> {
308 // SAFETY:
309 // * The first context argument may be NULL and is unused by the wrapped
310 // implementation.
311 // * The second argument and the third argument are the pointer to and length of the given
312 // message buffer.
313 // * The fourth argument is a const buffer of size `SIGNATURE_SIZE`. This is fulfilled
314 // by the definition of `signature`.
315 // * The fifth argument is a const buffer of size `PUBLIC_KEY_SIZE`. This is fulfilled
316 // by the definition of `public_key`.
317 // * All pointers must be valid for the duration of the function call but not beyond.
318 check_result(unsafe {
319 DiceVerify(
320 self.get_context(),
321 message.as_ptr(),
322 message.len(),
323 signature.as_ptr(),
324 public_key.as_ptr(),
325 )
326 })
327 }
328
329 /// Safe wrapper around open-dice DiceGenerateCertificate, see open dice
330 /// documentation for details.
Alice Wangb68814b2023-02-02 13:15:32 +0000331 fn generate_certificate(
Janis Danisevskis13356b22021-10-20 09:44:12 -0700332 &mut self,
333 subject_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
334 authority_private_key_seed: &[u8; PRIVATE_KEY_SEED_SIZE],
Alice Wangb68814b2023-02-02 13:15:32 +0000335 input_values: &InputValues,
Janis Danisevskis13356b22021-10-20 09:44:12 -0700336 ) -> Result<Vec<u8>> {
Alice Wangb68814b2023-02-02 13:15:32 +0000337 // SAFETY (DiceGenerateCertificate):
Janis Danisevskis13356b22021-10-20 09:44:12 -0700338 // * The first context argument may be NULL and is unused by the wrapped
339 // implementation.
340 // * The second argument and the third argument are const arrays of size
341 // `PRIVATE_KEY_SEED_SIZE`. This is fulfilled as per the definition of the arguments.
342 // * The fourth argument is a pointer to `DiceInputValues` it, and its indirect
Alice Wangb68814b2023-02-02 13:15:32 +0000343 // references must be valid for the duration of the function call.
Janis Danisevskis13356b22021-10-20 09:44:12 -0700344 // * The fifth argument and the sixth argument are the length of and the pointer to the
345 // allocated certificate buffer respectively. They are used to return
346 // the generated certificate.
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700347 // * The seventh argument is a pointer to a mutable usize object. It is
Janis Danisevskis13356b22021-10-20 09:44:12 -0700348 // used to return the actual size of the output certificate.
349 // * All pointers must be valid for the duration of the function call but not beyond.
Alice Wangb68814b2023-02-02 13:15:32 +0000350 let cert = retry_while_adjusting_output_buffer(|cert, actual_size| {
351 check_result(unsafe {
352 DiceGenerateCertificate(
353 self.get_context(),
354 subject_private_key_seed.as_ptr(),
355 authority_private_key_seed.as_ptr(),
356 input_values.as_ptr(),
357 cert.len(),
358 cert.as_mut_ptr(),
359 actual_size as *mut _,
360 )
361 })
362 })?;
363 Ok(cert)
Janis Danisevskis13356b22021-10-20 09:44:12 -0700364 }
Janis Danisevskis2cef73f2021-11-03 15:02:48 -0700365}
366
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800367#[cfg(test)]
368mod test {
369 use super::*;
370 use diced_sample_inputs::make_sample_bcc_and_cdis;
371 use std::convert::TryInto;
372
373 static SEED_TEST_VECTOR: &[u8] = &[
374 0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
375 0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
376 0x3a, 0x08, 0x84, 0x8a, 0x98, 0x85, 0x6d, 0xf5, 0x69, 0x21, 0x03, 0xcd, 0x09, 0xc3, 0x28,
377 0xd6, 0x06, 0xa7, 0x57, 0xbd, 0x48, 0x4b, 0x0f, 0x79, 0x0f, 0xf8, 0x2f, 0xf0, 0x0a, 0x41,
378 0x94, 0xd8, 0x8c, 0xa8,
379 ];
380
381 static CDI_ATTEST_TEST_VECTOR: &[u8] = &[
382 0xfa, 0x3c, 0x2f, 0x58, 0x37, 0xf5, 0x8e, 0x96, 0x16, 0x09, 0xf5, 0x22, 0xa1, 0xf1, 0xba,
383 0xaa, 0x19, 0x95, 0x01, 0x79, 0x2e, 0x60, 0x56, 0xaf, 0xf6, 0x41, 0xe7, 0xff, 0x48, 0xf5,
384 0x3a, 0x08,
385 ];
386 static CDI_PRIVATE_KEY_SEED_TEST_VECTOR: &[u8] = &[
387 0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
388 0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
389 0x02, 0x6e,
390 ];
391
392 static PUB_KEY_TEST_VECTOR: &[u8] = &[
393 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b, 0xfc, 0x23,
394 0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52, 0xf1, 0x61,
395 0x06, 0x37,
396 ];
397 static PRIV_KEY_TEST_VECTOR: &[u8] = &[
398 0x5f, 0xcc, 0x8e, 0x1a, 0xd1, 0xc2, 0xb3, 0xe9, 0xfb, 0xe1, 0x68, 0xf0, 0xf6, 0x98, 0xfe,
399 0x0d, 0xee, 0xd4, 0xb5, 0x18, 0xcb, 0x59, 0x70, 0x2d, 0xee, 0x06, 0xe5, 0x70, 0xf1, 0x72,
400 0x02, 0x6e, 0x47, 0x42, 0x4b, 0xbd, 0xd7, 0x23, 0xb4, 0xcd, 0xca, 0xe2, 0x8e, 0xdc, 0x6b,
401 0xfc, 0x23, 0xc9, 0x21, 0x5c, 0x48, 0x21, 0x47, 0xee, 0x5b, 0xfa, 0xaf, 0x88, 0x9a, 0x52,
402 0xf1, 0x61, 0x06, 0x37,
403 ];
404
405 static SIGNATURE_TEST_VECTOR: &[u8] = &[
406 0x44, 0xae, 0xcc, 0xe2, 0xb9, 0x96, 0x18, 0x39, 0x0e, 0x61, 0x0f, 0x53, 0x07, 0xbf, 0xf2,
407 0x32, 0x3d, 0x44, 0xd4, 0xf2, 0x07, 0x23, 0x30, 0x85, 0x32, 0x18, 0xd2, 0x69, 0xb8, 0x29,
408 0x3c, 0x26, 0xe6, 0x0d, 0x9c, 0xa5, 0xc2, 0x73, 0xcd, 0x8c, 0xb8, 0x3c, 0x3e, 0x5b, 0xfd,
409 0x62, 0x8d, 0xf6, 0xc4, 0x27, 0xa6, 0xe9, 0x11, 0x06, 0x5a, 0xb2, 0x2b, 0x64, 0xf7, 0xfc,
410 0xbb, 0xab, 0x4a, 0x0e,
411 ];
412
413 #[test]
414 fn hash_derive_sign_verify() {
415 let mut ctx = OpenDiceCborContext::new();
Alice Wang24954b42023-02-06 10:03:45 +0000416 let seed = diced_open_dice::hash("MySeedString".as_bytes()).unwrap();
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800417 assert_eq!(seed, SEED_TEST_VECTOR);
418 let cdi_attest = &seed[..CDI_SIZE];
419 assert_eq!(cdi_attest, CDI_ATTEST_TEST_VECTOR);
420 let cdi_private_key_seed =
Alice Wang7cc59562023-02-08 13:17:10 +0000421 derive_cdi_private_key_seed(cdi_attest.try_into().unwrap()).unwrap();
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800422 assert_eq!(&cdi_private_key_seed[..], CDI_PRIVATE_KEY_SEED_TEST_VECTOR);
423 let (pub_key, priv_key) =
424 ctx.keypair_from_seed(cdi_private_key_seed[..].try_into().unwrap()).unwrap();
425 assert_eq!(&pub_key, PUB_KEY_TEST_VECTOR);
426 assert_eq!(&priv_key[..], PRIV_KEY_TEST_VECTOR);
427 let mut signature =
428 ctx.sign("MyMessage".as_bytes(), priv_key[..].try_into().unwrap()).unwrap();
429 assert_eq!(&signature, SIGNATURE_TEST_VECTOR);
430 assert!(ctx
431 .verify(
432 "MyMessage".as_bytes(),
433 signature[..].try_into().unwrap(),
434 pub_key[..].try_into().unwrap()
435 )
436 .is_ok());
437 assert!(ctx
438 .verify(
439 "MyMessage_fail".as_bytes(),
440 signature[..].try_into().unwrap(),
441 pub_key[..].try_into().unwrap()
442 )
443 .is_err());
444 signature[0] += 1;
445 assert!(ctx
446 .verify(
447 "MyMessage".as_bytes(),
448 signature[..].try_into().unwrap(),
449 pub_key[..].try_into().unwrap()
450 )
451 .is_err());
452 }
453
454 static SAMPLE_CDI_ATTEST_TEST_VECTOR: &[u8] = &[
455 0x3e, 0x57, 0x65, 0x5d, 0x48, 0x02, 0xbd, 0x5c, 0x66, 0xcc, 0x1f, 0x0f, 0xbe, 0x5e, 0x32,
456 0xb6, 0x9e, 0x3d, 0x04, 0xaf, 0x00, 0x15, 0xbc, 0xdd, 0x1f, 0xbc, 0x59, 0xe4, 0xc3, 0x87,
457 0x95, 0x5e,
458 ];
459
460 static SAMPLE_CDI_SEAL_TEST_VECTOR: &[u8] = &[
461 0x36, 0x1b, 0xd2, 0xb3, 0xc4, 0xda, 0x77, 0xb2, 0x9c, 0xba, 0x39, 0x53, 0x82, 0x93, 0xd9,
462 0xb8, 0x9f, 0x73, 0x2d, 0x27, 0x06, 0x15, 0xa8, 0xcb, 0x6d, 0x1d, 0xf2, 0xb1, 0x54, 0xbb,
463 0x62, 0xf1,
464 ];
465
466 static SAMPLE_BCC_TEST_VECTOR: &[u8] = &[
Alan Stokes7cdcf992022-05-24 07:42:24 +0000467 0x84, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x3e,
468 0x85, 0xe5, 0x72, 0x75, 0x55, 0xe5, 0x1e, 0xe7, 0xf3, 0x35, 0x94, 0x8e, 0xbb, 0xbd, 0x74,
469 0x1e, 0x1d, 0xca, 0x49, 0x9c, 0x97, 0x39, 0x77, 0x06, 0xd3, 0xc8, 0x6e, 0x8b, 0xd7, 0x33,
470 0xf9, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9, 0x01, 0x78, 0x28, 0x34,
471 0x32, 0x64, 0x38, 0x38, 0x36, 0x34, 0x66, 0x39, 0x37, 0x62, 0x36, 0x35, 0x34, 0x37, 0x61,
472 0x35, 0x30, 0x63, 0x31, 0x65, 0x30, 0x61, 0x37, 0x34, 0x39, 0x66, 0x38, 0x65, 0x66, 0x38,
473 0x62, 0x38, 0x31, 0x65, 0x63, 0x36, 0x32, 0x61, 0x66, 0x02, 0x78, 0x28, 0x31, 0x66, 0x36,
474 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35, 0x32, 0x66, 0x32, 0x39, 0x65, 0x39, 0x33, 0x66,
475 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65, 0x33, 0x32, 0x63, 0x64, 0x38, 0x31, 0x64,
476 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x16,
477 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38, 0xc3, 0x64, 0x38, 0x63, 0x26,
478 0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34, 0x4c, 0x6d, 0xa2, 0xbe,
479 0x25, 0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2, 0xb3, 0x91, 0x4d,
480 0xd3, 0xfb, 0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba, 0x30, 0xf7,
481 0x15, 0x98, 0x14, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56, 0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71,
482 0x63, 0x41, 0x42, 0x4c, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a, 0x00, 0x01, 0x11, 0x73,
483 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x47, 0xae, 0x42, 0x27, 0x4c, 0xcb, 0x65,
484 0x4d, 0xee, 0x74, 0x2d, 0x05, 0x78, 0x2a, 0x08, 0x2a, 0xa5, 0xf0, 0xcf, 0xea, 0x3e, 0x60,
485 0xee, 0x97, 0x11, 0x4b, 0x5b, 0xe6, 0x05, 0x0c, 0xe8, 0x90, 0xf5, 0x22, 0xc4, 0xc6, 0x67,
486 0x7a, 0x22, 0x27, 0x17, 0xb3, 0x79, 0xcc, 0x37, 0x64, 0x5e, 0x19, 0x4f, 0x96, 0x37, 0x67,
487 0x3c, 0xd0, 0xc5, 0xed, 0x0f, 0xdd, 0xe7, 0x2e, 0x4f, 0x70, 0x97, 0x30, 0x3a, 0x00, 0x47,
488 0x44, 0x54, 0x58, 0x40, 0xf9, 0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3,
489 0x97, 0x4a, 0xcb, 0x3c, 0xe7, 0x6b, 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59,
490 0x15, 0xb1, 0x23, 0xe6, 0xc8, 0xdf, 0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc,
491 0x5b, 0x37, 0x0e, 0x12, 0x12, 0xb2, 0xfd, 0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6,
492 0x29, 0x1b, 0x99, 0xea, 0xae, 0xfd, 0xaa, 0x0d, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01,
493 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02,
494 0x20, 0x06, 0x21, 0x58, 0x20, 0xb1, 0x02, 0xcc, 0x2c, 0xb2, 0x6a, 0x3b, 0xe9, 0xc1, 0xd3,
495 0x95, 0x10, 0xa0, 0xe1, 0xff, 0x51, 0xde, 0x57, 0xd5, 0x65, 0x28, 0xfd, 0x7f, 0xeb, 0xd4,
496 0xca, 0x15, 0xf3, 0xca, 0xdf, 0x37, 0x88, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58,
497 0x40, 0x58, 0xd8, 0x03, 0x24, 0x53, 0x60, 0x57, 0xa9, 0x09, 0xfa, 0xab, 0xdc, 0x57, 0x1e,
498 0xf0, 0xe5, 0x1e, 0x51, 0x6f, 0x9e, 0xa3, 0x42, 0xe6, 0x6a, 0x8c, 0xaa, 0xad, 0x08, 0x48,
499 0xde, 0x7f, 0x4f, 0x6e, 0x2f, 0x7f, 0x39, 0x6c, 0xa1, 0xf8, 0x42, 0x71, 0xfe, 0x17, 0x3d,
500 0xca, 0x31, 0x83, 0x92, 0xed, 0xbb, 0x40, 0xb8, 0x10, 0xe0, 0xf2, 0x5a, 0x99, 0x53, 0x38,
501 0x46, 0x33, 0x97, 0x78, 0x05, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9,
502 0x01, 0x78, 0x28, 0x31, 0x66, 0x36, 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35, 0x32, 0x66,
503 0x32, 0x39, 0x65, 0x39, 0x33, 0x66, 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65, 0x33,
504 0x32, 0x63, 0x64, 0x38, 0x31, 0x64, 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x02, 0x78,
505 0x28, 0x32, 0x35, 0x39, 0x34, 0x38, 0x39, 0x65, 0x36, 0x39, 0x37, 0x34, 0x38, 0x37, 0x30,
506 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66, 0x34, 0x34, 0x32, 0x36, 0x37, 0x65, 0x61, 0x34,
507 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35, 0x37, 0x32, 0x35, 0x3a, 0x00, 0x47, 0x44,
508 0x50, 0x58, 0x40, 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43,
509 0x83, 0x7f, 0x46, 0x8d, 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0, 0xd9,
510 0x56, 0xb3, 0xbf, 0x2f, 0xfa, 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9, 0x6b, 0x18,
511 0x28, 0xe8, 0x29, 0x20, 0x49, 0x0f, 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54, 0xe9, 0x71, 0xd2,
512 0x7e, 0xa4, 0xfe, 0x58, 0x7f, 0xd3, 0xc7, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56, 0xa3, 0x3a,
513 0x00, 0x01, 0x11, 0x71, 0x63, 0x41, 0x56, 0x42, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a,
514 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x93, 0x17, 0xe1,
515 0x11, 0x27, 0x59, 0xd0, 0xef, 0x75, 0x0b, 0x2b, 0x1c, 0x0f, 0x5f, 0x52, 0xc3, 0x29, 0x23,
516 0xb5, 0x2a, 0xe6, 0x12, 0x72, 0x6f, 0x39, 0x86, 0x65, 0x2d, 0xf2, 0xe4, 0xe7, 0xd0, 0xaf,
517 0x0e, 0xa7, 0x99, 0x16, 0x89, 0x97, 0x21, 0xf7, 0xdc, 0x89, 0xdc, 0xde, 0xbb, 0x94, 0x88,
518 0x1f, 0xda, 0xe2, 0xf3, 0xe0, 0x54, 0xf9, 0x0e, 0x29, 0xb1, 0xbd, 0xe1, 0x0c, 0x0b, 0xd7,
519 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa,
520 0x55, 0x6f, 0xac, 0x56, 0xd9, 0x02, 0x35, 0x2b, 0xaa, 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a,
521 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d, 0xe4, 0x43, 0x13, 0xbf, 0xfe, 0xd3, 0x36,
522 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6, 0x66, 0xef, 0xab, 0x3d, 0x0f, 0x89, 0xa4,
523 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a, 0xef, 0xbc, 0x05, 0x98, 0x3a, 0x00, 0x47,
524 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03,
525 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x96, 0x6d, 0x96, 0x42, 0xda, 0x64,
526 0x51, 0xad, 0xfa, 0x00, 0xbc, 0xbc, 0x95, 0x8a, 0xb0, 0xb9, 0x76, 0x01, 0xe6, 0xbd, 0xc0,
527 0x26, 0x79, 0x26, 0xfc, 0x0f, 0x1d, 0x87, 0x65, 0xf1, 0xf3, 0x99, 0x3a, 0x00, 0x47, 0x44,
528 0x58, 0x41, 0x20, 0x58, 0x40, 0x10, 0x7f, 0x77, 0xad, 0x70, 0xbd, 0x52, 0x81, 0x28, 0x8d,
529 0x24, 0x81, 0xb4, 0x3f, 0x21, 0x68, 0x9f, 0xc3, 0x80, 0x68, 0x86, 0x55, 0xfb, 0x2e, 0x6d,
530 0x96, 0xe1, 0xe1, 0xb7, 0x28, 0x8d, 0x63, 0x85, 0xba, 0x2a, 0x01, 0x33, 0x87, 0x60, 0x63,
531 0xbb, 0x16, 0x3f, 0x2f, 0x3d, 0xf4, 0x2d, 0x48, 0x5b, 0x87, 0xed, 0xda, 0x34, 0xeb, 0x9c,
532 0x4d, 0x14, 0xac, 0x65, 0xf4, 0xfa, 0xef, 0x45, 0x0b, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0,
533 0x59, 0x01, 0x8f, 0xa9, 0x01, 0x78, 0x28, 0x32, 0x35, 0x39, 0x34, 0x38, 0x39, 0x65, 0x36,
534 0x39, 0x37, 0x34, 0x38, 0x37, 0x30, 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66, 0x34, 0x34,
535 0x32, 0x36, 0x37, 0x65, 0x61, 0x34, 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35, 0x37,
536 0x32, 0x35, 0x02, 0x78, 0x28, 0x35, 0x64, 0x34, 0x65, 0x64, 0x37, 0x66, 0x34, 0x31, 0x37,
537 0x61, 0x39, 0x35, 0x34, 0x61, 0x31, 0x38, 0x31, 0x34, 0x30, 0x37, 0x62, 0x35, 0x38, 0x38,
538 0x35, 0x61, 0x66, 0x64, 0x37, 0x32, 0x61, 0x35, 0x62, 0x66, 0x34, 0x30, 0x64, 0x61, 0x36,
539 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800540 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Alan Stokes7cdcf992022-05-24 07:42:24 +0000543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x47, 0x44,
544 0x53, 0x58, 0x1a, 0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x67, 0x41, 0x6e, 0x64, 0x72, 0x6f,
545 0x69, 0x64, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x0c, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a,
546 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x26, 0x1a, 0xbd, 0x26, 0xd8, 0x37, 0x8f, 0x4a, 0xf2,
547 0x9e, 0x49, 0x4d, 0x93, 0x23, 0xc4, 0x6e, 0x02, 0xda, 0xe0, 0x00, 0x02, 0xe7, 0xed, 0x29,
548 0xdf, 0x2b, 0xb3, 0x69, 0xf3, 0x55, 0x0e, 0x4c, 0x22, 0xdc, 0xcf, 0xf5, 0x92, 0xc9, 0xfa,
549 0x78, 0x98, 0xf1, 0x0e, 0x55, 0x5f, 0xf4, 0x45, 0xed, 0xc0, 0x0a, 0x72, 0x2a, 0x7a, 0x3a,
550 0xd2, 0xb1, 0xf7, 0x76, 0xfe, 0x2a, 0x6b, 0x7b, 0x2a, 0x53, 0x3a, 0x00, 0x47, 0x44, 0x54,
551 0x58, 0x40, 0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30,
552 0x03, 0xb8, 0xd6, 0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37,
553 0x68, 0x4e, 0x1d, 0xc0, 0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2,
554 0x9c, 0xfc, 0x12, 0x9e, 0x77, 0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5,
555 0x73, 0xd4, 0xc6, 0xdf, 0x62, 0x9f, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00,
556 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06,
557 0x21, 0x58, 0x20, 0xdb, 0xe7, 0x5b, 0x3f, 0xa3, 0x42, 0xb0, 0x9c, 0xf8, 0x40, 0x8c, 0xb0,
558 0x9c, 0xf0, 0x0a, 0xaf, 0xdf, 0x6f, 0xe5, 0x09, 0x21, 0x11, 0x92, 0xe1, 0xf8, 0xc5, 0x09,
559 0x02, 0x3d, 0x1f, 0xb7, 0xc5, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40, 0xc4,
560 0xc1, 0xd7, 0x1c, 0x2d, 0x26, 0x89, 0x22, 0xcf, 0xa6, 0x99, 0x77, 0x30, 0x84, 0x86, 0x27,
561 0x59, 0x8f, 0xd8, 0x08, 0x75, 0xe0, 0xb2, 0xef, 0xf9, 0xfa, 0xa5, 0x40, 0x8c, 0xd3, 0xeb,
562 0xbb, 0xda, 0xf2, 0xc8, 0xae, 0x41, 0x22, 0x50, 0x9c, 0xe8, 0xb2, 0x9c, 0x9b, 0x3f, 0x8a,
563 0x78, 0x76, 0xab, 0xd0, 0xbe, 0xfc, 0xe4, 0x79, 0xcb, 0x1b, 0x2b, 0xaa, 0x4d, 0xdd, 0x15,
564 0x61, 0x42, 0x06,
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800565 ];
566
567 // This test invokes make_sample_bcc_and_cdis and compares the result bitwise to the target
568 // vectors. The function uses main_flow, bcc_main_flow, format_config_descriptor,
569 // derive_cdi_private_key_seed, and keypair_from_seed. This test is sensitive to errors
570 // and changes in any of those functions.
571 #[test]
572 fn main_flow_and_bcc_main_flow() {
Alice Wangf4bd1c62023-02-08 08:38:44 +0000573 let dice_artifacts = make_sample_bcc_and_cdis().unwrap();
574 assert_eq!(&dice_artifacts.cdi_values.cdi_attest, SAMPLE_CDI_ATTEST_TEST_VECTOR);
575 assert_eq!(&dice_artifacts.cdi_values.cdi_seal, SAMPLE_CDI_SEAL_TEST_VECTOR);
576 assert_eq!(&dice_artifacts.bcc, SAMPLE_BCC_TEST_VECTOR);
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800577 }
578
579 static DERIVED_KEY_TEST_VECTOR: &[u8] = &[
580 0x0e, 0xd6, 0x07, 0x0e, 0x1c, 0x38, 0x2c, 0x76, 0x13, 0xc6, 0x76, 0x25, 0x7e, 0x07, 0x6f,
581 0xdb, 0x1d, 0xb1, 0x0f, 0x3f, 0xed, 0xc5, 0x2b, 0x95, 0xd1, 0x32, 0xf1, 0x63, 0x2f, 0x2a,
582 0x01, 0x5e,
583 ];
584
585 #[test]
586 fn kdf() {
587 let mut ctx = OpenDiceCborContext::new();
588 let derived_key = ctx
589 .kdf(
590 PRIVATE_KEY_SEED_SIZE,
591 "myKey".as_bytes(),
592 "mySalt".as_bytes(),
593 "myInfo".as_bytes(),
594 )
595 .unwrap();
596 assert_eq!(&derived_key[..], DERIVED_KEY_TEST_VECTOR);
597 }
Janis Danisevskisdb78b772021-11-29 17:59:50 -0800598}