blob: 04602bdc0463811423461d3f920064c9ea217aca [file] [log] [blame]
Janis Danisevskisaaba4af2021-11-18 14:25:07 -08001// 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//! This module provides `ResidentHal`, an implementation of a IDiceDevice HAL Interface.
16//! While the name implies that the DICE secrets are memory resident, the residency
17//! is augmented by the implementation of the traits `DiceArtifacts` and
18//! `UpdatableDiceArtifacts`. The implementation outsources all operations that
19//! involve the DICE secrets to a short lived child process. By implementing
20//! `UpdatableDiceArtifacts` accordingly, integrators can limit the exposure of
21//! the resident DICE secrets to user space memory. E.g., an implementation might only
22//! hold a path to a securefs file allowing the child to read and update the kernel state
23//! through this path directly.
24//!
25//! ## Important Safety Note.
26//! The module is not safe to use in multi threaded processes. It uses fork and runs
27//! code that is not async signal safe in the child. Implementing a HAL service without
28//! starting a thread pool is safe, but no secondary thread must be created.
29
30use crate::error_vendor::map_or_log_err;
31use android_hardware_security_dice::aidl::android::hardware::security::dice::{
32 Bcc::Bcc, BccHandover::BccHandover, IDiceDevice::BnDiceDevice, IDiceDevice::IDiceDevice,
33 InputValues::InputValues as BinderInputValues, Signature::Signature,
34};
35use anyhow::{Context, Result};
Stephen Crane23cf7242022-01-19 17:49:46 +000036use binder::{BinderFeatures, Result as BinderResult, Strong};
Janis Danisevskisaaba4af2021-11-18 14:25:07 -080037use dice::{ContextImpl, OpenDiceCborContext};
Alice Wang4d3059a2023-02-15 10:24:33 +000038pub use diced_open_dice::DiceArtifacts;
Janis Danisevskisaaba4af2021-11-18 14:25:07 -080039use diced_open_dice_cbor as dice;
40use diced_utils as utils;
41use nix::sys::wait::{waitpid, WaitStatus};
42use nix::unistd::{
43 close, fork, pipe as nix_pipe, read as nix_read, write as nix_write, ForkResult,
44};
45use serde::{de::DeserializeOwned, Deserialize, Serialize};
46use std::convert::TryInto;
47use std::io::{Read, Write};
48use std::os::unix::io::RawFd;
49use std::sync::{Arc, RwLock};
50use utils::ResidentArtifacts;
Alice Wang4d3059a2023-02-15 10:24:33 +000051pub use utils::UpdatableDiceArtifacts;
Janis Danisevskisaaba4af2021-11-18 14:25:07 -080052
53/// PipeReader is a simple wrapper around raw pipe file descriptors.
54/// It takes ownership of the file descriptor and closes it on drop. It provides `read_all`, which
55/// reads from the pipe into an expending vector, until no more data can be read.
56struct PipeReader(RawFd);
57
58impl Read for PipeReader {
59 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
60 let bytes = nix_read(self.0, buf)?;
61 Ok(bytes)
62 }
63}
64
65impl Drop for PipeReader {
66 fn drop(&mut self) {
67 close(self.0).expect("Failed to close reader pipe fd.");
68 }
69}
70
71/// PipeWriter is a simple wrapper around raw pipe file descriptors.
72/// It takes ownership of the file descriptor and closes it on drop. It provides `write`, which
73/// writes the given buffer into the pipe, returning the number of bytes written.
74struct PipeWriter(RawFd);
75
76impl Write for PipeWriter {
77 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
78 let written = nix_write(self.0, buf)?;
79 Ok(written)
80 }
81
82 fn flush(&mut self) -> std::io::Result<()> {
83 // Flush is a NO-OP.
84 Ok(())
85 }
86}
87
88impl Drop for PipeWriter {
89 fn drop(&mut self) {
90 close(self.0).expect("Failed to close writer pipe fd.");
91 }
92}
93
94fn pipe() -> Result<(PipeReader, PipeWriter), nix::Error> {
95 let (read_fd, write_fd) = nix_pipe()?;
96 Ok((PipeReader(read_fd), PipeWriter(write_fd)))
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, thiserror::Error)]
100enum RunForkedError {
101 #[error("RunForkedError::String({0:?})")]
102 String(String),
103}
104
105/// Run the given closure in a new process.
106/// Safety: The function runs code that is not async-signal-safe in the child after forking.
107/// This means, that this function must not be called by a multi threaded process.
108fn run_forked<F, R>(f: F) -> Result<R>
109where
110 R: Serialize + DeserializeOwned,
111 F: FnOnce() -> Result<R>,
112{
113 let (reader, writer) = pipe().expect("Failed to create pipe.");
114
115 match unsafe { fork() } {
116 Ok(ForkResult::Parent { child, .. }) => {
117 drop(writer);
118 let status = waitpid(child, None).expect("Failed while waiting for child.");
119 if let WaitStatus::Exited(_, 0) = status {
120 // Child exited successfully.
121 // Read the result from the pipe.
122 // Deserialize the result and return it.
123 let result: Result<R, RunForkedError> =
124 serde_cbor::from_reader(reader).expect("Failed to deserialize result.");
125
126 result.context("In run_forked:")
127 } else {
128 panic!("Child did not exit as expected {:?}", status);
129 }
130 }
131 Ok(ForkResult::Child) => {
132 // Run the closure.
133 let result = f()
134 .map_err(|err| RunForkedError::String(format! {"Nested anyhow error {:?}", err}));
135
136 // Serialize the result of the closure.
137 serde_cbor::to_writer(writer, &result).expect("Result serialization failed");
138
139 // Set exit status to `0`.
140 std::process::exit(0);
141 }
142 Err(errno) => {
143 panic!("Failed to fork: {:?}", errno);
144 }
145 }
146}
147
148/// A DiceHal backend implementation.
149/// All functions, except `demote`, derive effective dice artifacts starting from
150/// this node and iterating through `input_values` in ascending order.
151pub trait DiceHalImpl {
152 /// Signs the message using the effective dice artifacts and Ed25519Pure.
153 fn sign(&self, input_values: &[BinderInputValues], message: &[u8]) -> Result<Signature>;
154 /// Returns the effective attestation chain.
155 fn get_attestation_chain(&self, input_values: &[BinderInputValues]) -> Result<Bcc>;
156 /// Returns the effective dice artifacts.
157 fn derive(&self, input_values: &[BinderInputValues]) -> Result<BccHandover>;
158 /// This demotes the implementation itself. I.e. a resident node would replace its resident
159 /// artifacts with the effective artifacts derived using `input_values`. A proxy node would
160 /// simply call `demote` on its parent node. This is not reversible and changes
161 /// the effective dice artifacts of all clients.
162 fn demote(&self, input_values: &[BinderInputValues]) -> Result<()>;
163}
164
165/// The ResidentHal implements a IDiceDevice backend with memory resident DICE secrets.
166pub struct ResidentHal<T: UpdatableDiceArtifacts + Serialize + DeserializeOwned + Clone + Send> {
167 artifacts: RwLock<T>,
168}
169
170impl<T: UpdatableDiceArtifacts + Serialize + DeserializeOwned + Clone + Send> ResidentHal<T> {
171 /// Creates a new Resident node with the given dice secrets and certificate chain.
172 /// ## Safety
173 /// It is not safe to use implementations of ResidentHal in multi threaded environments.
174 /// If using this library to implement a HAL service make sure not to start a thread pool.
175 pub unsafe fn new(artifacts: T) -> Result<Self> {
176 Ok(ResidentHal { artifacts: RwLock::new(artifacts) })
177 }
178
179 fn with_effective_artifacts<R, F>(&self, input_values: &[BinderInputValues], f: F) -> Result<R>
180 where
181 R: Serialize + DeserializeOwned,
182 F: FnOnce(ResidentArtifacts) -> Result<R>,
183 {
184 let artifacts = self.artifacts.read().unwrap().clone();
185
186 // Safety: run_forked must not be be called by a multi threaded process.
187 // This requirement is propagated to the public interface of this module through
188 // `ResidentHal::new`
189 run_forked(move || {
190 let artifacts = artifacts.with_artifacts(|a| ResidentArtifacts::new_from(a))?;
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800191 let artifacts = artifacts
Alice Wang93e6e372023-02-02 14:36:17 +0000192 .execute_steps(input_values)
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800193 .context("In ResidentHal::get_effective_artifacts:")?;
194 f(artifacts)
195 })
196 }
197}
198
199impl<T: UpdatableDiceArtifacts + Serialize + DeserializeOwned + Clone + Send> DiceHalImpl
200 for ResidentHal<T>
201{
202 fn sign(&self, input_values: &[BinderInputValues], message: &[u8]) -> Result<Signature> {
203 let signature: Vec<u8> = self
204 .with_effective_artifacts(input_values, |artifacts| {
205 let (cdi_attest, _, _) = artifacts.into_tuple();
206 let mut dice = OpenDiceCborContext::new();
Alice Wang7cc59562023-02-08 13:17:10 +0000207 let seed = dice::derive_cdi_private_key_seed(
208 cdi_attest[..].try_into().with_context(|| {
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800209 format!(
210 "In ResidentHal::sign: Failed to convert cdi_attest (length: {}).",
211 cdi_attest.len()
212 )
Alice Wang7cc59562023-02-08 13:17:10 +0000213 })?,
214 )
215 .context("In ResidentHal::sign: Failed to derive seed from cdi_attest.")?;
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800216 let (_public_key, private_key) = dice
217 .keypair_from_seed(seed[..].try_into().with_context(|| {
218 format!(
219 "In ResidentHal::sign: Failed to convert seed (length: {}).",
220 seed.len()
221 )
222 })?)
223 .context("In ResidentHal::sign: Failed to derive keypair from seed.")?;
Alice Wang8722d9e2023-02-13 14:56:56 +0000224 let signature = dice::sign(
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800225 message,
226 private_key[..].try_into().with_context(|| {
227 format!(
228 "In ResidentHal::sign: Failed to convert private_key (length: {}).",
229 private_key.len()
230 )
231 })?,
232 )
Alice Wang8722d9e2023-02-13 14:56:56 +0000233 .context("In ResidentHal::sign: Failed to sign.")?;
234 Ok(signature.to_vec())
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800235 })
236 .context("In ResidentHal::sign:")?;
237 Ok(Signature { data: signature })
238 }
239
240 fn get_attestation_chain(&self, input_values: &[BinderInputValues]) -> Result<Bcc> {
241 let bcc = self
242 .with_effective_artifacts(input_values, |artifacts| {
243 let (_, _, bcc) = artifacts.into_tuple();
244 Ok(bcc)
245 })
246 .context("In ResidentHal::get_attestation_chain: Failed to get effective_artifacts.")?;
247
248 Ok(Bcc { data: bcc })
249 }
250
251 fn derive(&self, input_values: &[BinderInputValues]) -> Result<BccHandover> {
252 let (cdi_attest, cdi_seal, bcc): (Vec<u8>, Vec<u8>, Vec<u8>) = self
253 .with_effective_artifacts(input_values, |artifacts| {
254 let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
255 Ok((cdi_attest[..].to_vec(), cdi_seal[..].to_vec(), bcc))
256 })?;
257
258 utils::make_bcc_handover(
259 &cdi_attest
260 .as_slice()
261 .try_into()
262 .context("In ResidentHal::derive: Trying to convert cdi_attest to sized array.")?,
263 &cdi_seal
264 .as_slice()
265 .try_into()
266 .context("In ResidentHal::derive: Trying to convert cdi_seal to sized array.")?,
267 &bcc,
268 )
269 .context("In ResidentHal::derive: Trying to construct BccHandover.")
270 }
271
272 fn demote(&self, input_values: &[BinderInputValues]) -> Result<()> {
273 let mut artifacts = self.artifacts.write().unwrap();
274
275 let artifacts_clone = (*artifacts).clone();
276
277 // Safety: run_forked may not be called from a multi threaded process.
278 // This requirement is propagated to the public interface of this module through
279 // `ResidentHal::new`
280 *artifacts = run_forked(|| {
281 let new_artifacts =
282 artifacts_clone.with_artifacts(|a| ResidentArtifacts::new_from(a))?;
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800283 let new_artifacts = new_artifacts
Alice Wang93e6e372023-02-02 14:36:17 +0000284 .execute_steps(input_values)
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800285 .context("In ResidentHal::get_effective_artifacts:")?;
286 artifacts_clone.update(&new_artifacts)
287 })?;
288
289 Ok(())
290 }
291}
292
293/// Implements android.hardware.security.dice.IDiceDevice. Forwards public API calls
294/// to the given DiceHalImpl backend.
295pub struct DiceDevice {
296 hal_impl: Arc<dyn DiceHalImpl + Sync + Send>,
297}
298
299impl DiceDevice {
300 /// Constructs an instance of DiceDevice, wraps it with a BnDiceDevice object and
301 /// returns a strong pointer to the binder. The result can be used to register
302 /// the service with service manager.
303 pub fn new_as_binder(
304 hal_impl: Arc<dyn DiceHalImpl + Sync + Send>,
305 ) -> Result<Strong<dyn IDiceDevice>> {
306 let result = BnDiceDevice::new_binder(DiceDevice { hal_impl }, BinderFeatures::default());
307 Ok(result)
308 }
309}
310
311impl binder::Interface for DiceDevice {}
312
313impl IDiceDevice for DiceDevice {
314 fn sign(&self, input_values: &[BinderInputValues], message: &[u8]) -> BinderResult<Signature> {
315 map_or_log_err(self.hal_impl.sign(input_values, message), Ok)
316 }
317 fn getAttestationChain(&self, input_values: &[BinderInputValues]) -> BinderResult<Bcc> {
318 map_or_log_err(self.hal_impl.get_attestation_chain(input_values), Ok)
319 }
320 fn derive(&self, input_values: &[BinderInputValues]) -> BinderResult<BccHandover> {
321 map_or_log_err(self.hal_impl.derive(input_values), Ok)
322 }
323 fn demote(&self, input_values: &[BinderInputValues]) -> BinderResult<()> {
324 map_or_log_err(self.hal_impl.demote(input_values), Ok)
325 }
326}
327
328#[cfg(test)]
329mod test {
330 use super::*;
331 use android_hardware_security_dice::aidl::android::hardware::security::dice::{
332 BccHandover::BccHandover, Config::Config as BinderConfig,
333 InputValues::InputValues as BinderInputValues, Mode::Mode as BinderMode,
334 };
Alice Wang4d3059a2023-02-15 10:24:33 +0000335 use anyhow::{anyhow, Context, Result};
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800336 use diced_open_dice_cbor as dice;
337 use diced_sample_inputs;
338 use diced_utils as utils;
Alice Wang9c40eca2023-02-03 13:10:24 +0000339 use std::ffi::CStr;
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800340
341 #[derive(Debug, Serialize, Deserialize, Clone)]
342 struct InsecureSerializableArtifacts {
343 cdi_attest: [u8; dice::CDI_SIZE],
344 cdi_seal: [u8; dice::CDI_SIZE],
345 bcc: Vec<u8>,
346 }
347
Alice Wangf4bd1c62023-02-08 08:38:44 +0000348 impl From<dice::OwnedDiceArtifacts> for InsecureSerializableArtifacts {
349 fn from(dice_artifacts: dice::OwnedDiceArtifacts) -> Self {
Alice Wang4d3059a2023-02-15 10:24:33 +0000350 let mut cdi_attest = [0u8; dice::CDI_SIZE];
351 cdi_attest.copy_from_slice(dice_artifacts.cdi_attest());
352 let mut cdi_seal = [0u8; dice::CDI_SIZE];
353 cdi_seal.copy_from_slice(dice_artifacts.cdi_seal());
354 Self { cdi_attest, cdi_seal, bcc: dice_artifacts.bcc().expect("bcc is none").to_vec() }
Alice Wangf4bd1c62023-02-08 08:38:44 +0000355 }
356 }
357
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800358 impl DiceArtifacts for InsecureSerializableArtifacts {
359 fn cdi_attest(&self) -> &[u8; dice::CDI_SIZE] {
360 &self.cdi_attest
361 }
362 fn cdi_seal(&self) -> &[u8; dice::CDI_SIZE] {
363 &self.cdi_seal
364 }
Alice Wang4d3059a2023-02-15 10:24:33 +0000365 fn bcc(&self) -> Option<&[u8]> {
366 Some(&self.bcc)
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800367 }
368 }
369
370 impl UpdatableDiceArtifacts for InsecureSerializableArtifacts {
371 fn with_artifacts<F, T>(&self, f: F) -> Result<T>
372 where
373 F: FnOnce(&dyn DiceArtifacts) -> Result<T>,
374 {
375 f(self)
376 }
377 fn update(self, new_artifacts: &impl DiceArtifacts) -> Result<Self> {
378 Ok(Self {
379 cdi_attest: *new_artifacts.cdi_attest(),
380 cdi_seal: *new_artifacts.cdi_seal(),
Alice Wang4d3059a2023-02-15 10:24:33 +0000381 bcc: new_artifacts.bcc().ok_or_else(|| anyhow!("bcc is none"))?.to_vec(),
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800382 })
383 }
384 }
385
386 fn make_input_values(
387 code: &str,
Alice Wang9c40eca2023-02-03 13:10:24 +0000388 config_name: &CStr,
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800389 authority: &str,
390 ) -> Result<BinderInputValues> {
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800391 Ok(BinderInputValues {
Alice Wang24954b42023-02-06 10:03:45 +0000392 codeHash: dice::hash(code.as_bytes())
393 .context("In make_input_values: code hash failed.")?,
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800394 config: BinderConfig {
Alice Wang9c40eca2023-02-03 13:10:24 +0000395 desc: dice::retry_bcc_format_config_descriptor(Some(config_name), None, true)
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800396 .context("In make_input_values: Failed to format config descriptor.")?,
397 },
Alice Wang24954b42023-02-06 10:03:45 +0000398 authorityHash: dice::hash(authority.as_bytes())
399 .context("In make_input_values: authority hash failed.")?,
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800400 authorityDescriptor: None,
401 mode: BinderMode::NORMAL,
Janis Danisevskisd9513f42021-12-16 17:15:13 -0800402 hidden: [0; dice::HIDDEN_SIZE],
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800403 })
404 }
405
406 /// Test the resident artifact batched derivation in process.
407 #[test]
408 fn derive_with_resident_artifacts() -> Result<()> {
Alice Wangf4bd1c62023-02-08 08:38:44 +0000409 let artifacts: ResidentArtifacts =
410 diced_sample_inputs::make_sample_bcc_and_cdis()?.try_into()?;
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800411
412 let input_values = &[
Alice Wang9c40eca2023-02-03 13:10:24 +0000413 make_input_values(
414 "component 1 code",
415 CStr::from_bytes_with_nul(b"component 1\0").unwrap(),
416 "component 1 authority",
417 )?,
418 make_input_values(
419 "component 2 code",
420 CStr::from_bytes_with_nul(b"component 2\0").unwrap(),
421 "component 2 authority",
422 )?,
423 make_input_values(
424 "component 3 code",
425 CStr::from_bytes_with_nul(b"component 3\0").unwrap(),
426 "component 3 authority",
427 )?,
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800428 ];
Alice Wang93e6e372023-02-02 14:36:17 +0000429 let new_artifacts = artifacts.execute_steps(input_values)?;
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800430
431 let result = utils::make_bcc_handover(
432 new_artifacts.cdi_attest(),
433 new_artifacts.cdi_seal(),
Alice Wang4d3059a2023-02-15 10:24:33 +0000434 new_artifacts.bcc().unwrap(),
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800435 )?;
436
437 assert_eq!(result, make_derive_test_vector());
438 Ok(())
439 }
440
441 /// Test the ResidentHal hal implementation which performs the derivation in a separate
442 /// process and returns the result through a pipe. This test compares the result against
443 /// the same test vector as the in process test above.
444 #[test]
445 fn derive_with_insecure_artifacts() -> Result<()> {
Alice Wangf4bd1c62023-02-08 08:38:44 +0000446 let dice_artifacts = diced_sample_inputs::make_sample_bcc_and_cdis()?;
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800447
448 // Safety: ResidentHal can only be used in single threaded environments.
449 // On-device Rust tests run each test in a separate process.
Alice Wangf4bd1c62023-02-08 08:38:44 +0000450 let hal_impl =
451 unsafe { ResidentHal::new(InsecureSerializableArtifacts::from(dice_artifacts)) }
452 .expect("Failed to create ResidentHal.");
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800453
454 let bcc_handover = hal_impl
455 .derive(&[
Alice Wang9c40eca2023-02-03 13:10:24 +0000456 make_input_values(
457 "component 1 code",
458 CStr::from_bytes_with_nul(b"component 1\0").unwrap(),
459 "component 1 authority",
460 )?,
461 make_input_values(
462 "component 2 code",
463 CStr::from_bytes_with_nul(b"component 2\0").unwrap(),
464 "component 2 authority",
465 )?,
466 make_input_values(
467 "component 3 code",
468 CStr::from_bytes_with_nul(b"component 3\0").unwrap(),
469 "component 3 authority",
470 )?,
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800471 ])
472 .expect("Failed to derive artifacts.");
473
474 assert_eq!(bcc_handover, make_derive_test_vector());
475 Ok(())
476 }
477
478 /// Demoting the implementation two steps and then performing one step of child derivation
479 /// must yield the same outcome as three derivations with the same input values.
480 #[test]
481 fn demote() -> Result<()> {
Alice Wangf4bd1c62023-02-08 08:38:44 +0000482 let dice_artifacts = diced_sample_inputs::make_sample_bcc_and_cdis()?;
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800483
484 // Safety: ResidentHal can only be used in single threaded environments.
485 // On-device Rust tests run each test in a separate process.
Alice Wangf4bd1c62023-02-08 08:38:44 +0000486 let hal_impl =
487 unsafe { ResidentHal::new(InsecureSerializableArtifacts::from(dice_artifacts)) }
488 .expect("Failed to create ResidentHal.");
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800489
490 hal_impl
491 .demote(&[
Alice Wang9c40eca2023-02-03 13:10:24 +0000492 make_input_values(
493 "component 1 code",
494 CStr::from_bytes_with_nul(b"component 1\0").unwrap(),
495 "component 1 authority",
496 )?,
497 make_input_values(
498 "component 2 code",
499 CStr::from_bytes_with_nul(b"component 2\0").unwrap(),
500 "component 2 authority",
501 )?,
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800502 ])
503 .expect("Failed to demote implementation.");
504
505 let bcc_handover = hal_impl
506 .derive(&[make_input_values(
507 "component 3 code",
Alice Wang9c40eca2023-02-03 13:10:24 +0000508 CStr::from_bytes_with_nul(b"component 3\0").unwrap(),
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800509 "component 3 authority",
510 )?])
511 .expect("Failed to derive artifacts.");
512
513 assert_eq!(bcc_handover, make_derive_test_vector());
514 Ok(())
515 }
516
517 fn make_derive_test_vector() -> BccHandover {
518 utils::make_bcc_handover(
519 &[
520 // cdi_attest
521 0x8f, 0xdf, 0x93, 0x67, 0xd7, 0x0e, 0xf8, 0xb8, 0xd2, 0x9c, 0x30, 0xeb, 0x4e, 0x9b,
522 0x71, 0x5f, 0x9a, 0x5b, 0x67, 0xa6, 0x29, 0xe0, 0x00, 0x9b, 0x4d, 0xe6, 0x95, 0xcf,
523 0xf9, 0xed, 0x5e, 0x9b,
524 ],
525 &[
526 // cdi_seal
527 0x15, 0x3e, 0xd6, 0x30, 0x5a, 0x8d, 0x4b, 0x6f, 0x07, 0x3f, 0x5d, 0x89, 0xc5, 0x6e,
528 0x30, 0xba, 0x05, 0x56, 0xfc, 0x66, 0xf4, 0xae, 0xce, 0x7f, 0x81, 0xb9, 0xc5, 0x21,
529 0x9b, 0x49, 0x3d, 0xe1,
530 ],
531 &[
532 // bcc
Alan Stokes7cdcf992022-05-24 07:42:24 +0000533 0x87, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20,
534 0x3e, 0x85, 0xe5, 0x72, 0x75, 0x55, 0xe5, 0x1e, 0xe7, 0xf3, 0x35, 0x94, 0x8e, 0xbb,
535 0xbd, 0x74, 0x1e, 0x1d, 0xca, 0x49, 0x9c, 0x97, 0x39, 0x77, 0x06, 0xd3, 0xc8, 0x6e,
536 0x8b, 0xd7, 0x33, 0xf9, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9,
537 0x01, 0x78, 0x28, 0x34, 0x32, 0x64, 0x38, 0x38, 0x36, 0x34, 0x66, 0x39, 0x37, 0x62,
538 0x36, 0x35, 0x34, 0x37, 0x61, 0x35, 0x30, 0x63, 0x31, 0x65, 0x30, 0x61, 0x37, 0x34,
539 0x39, 0x66, 0x38, 0x65, 0x66, 0x38, 0x62, 0x38, 0x31, 0x65, 0x63, 0x36, 0x32, 0x61,
540 0x66, 0x02, 0x78, 0x28, 0x31, 0x66, 0x36, 0x39, 0x36, 0x66, 0x30, 0x37, 0x32, 0x35,
541 0x32, 0x66, 0x32, 0x39, 0x65, 0x39, 0x33, 0x66, 0x65, 0x34, 0x64, 0x65, 0x31, 0x39,
542 0x65, 0x65, 0x33, 0x32, 0x63, 0x64, 0x38, 0x31, 0x64, 0x63, 0x34, 0x30, 0x34, 0x65,
543 0x37, 0x36, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x16, 0x48, 0xf2, 0x55, 0x53,
544 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38, 0xc3, 0x64, 0x38, 0x63, 0x26, 0x0f, 0xcf, 0x5b,
545 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34, 0x4c, 0x6d, 0xa2, 0xbe, 0x25, 0x1c,
546 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2, 0xb3, 0x91, 0x4d, 0xd3,
547 0xfb, 0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba, 0x30, 0xf7,
548 0x15, 0x98, 0x14, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x56, 0xa3, 0x3a, 0x00, 0x01, 0x11,
549 0x71, 0x63, 0x41, 0x42, 0x4c, 0x3a, 0x00, 0x01, 0x11, 0x72, 0x01, 0x3a, 0x00, 0x01,
550 0x11, 0x73, 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0x47, 0xae, 0x42, 0x27,
551 0x4c, 0xcb, 0x65, 0x4d, 0xee, 0x74, 0x2d, 0x05, 0x78, 0x2a, 0x08, 0x2a, 0xa5, 0xf0,
552 0xcf, 0xea, 0x3e, 0x60, 0xee, 0x97, 0x11, 0x4b, 0x5b, 0xe6, 0x05, 0x0c, 0xe8, 0x90,
553 0xf5, 0x22, 0xc4, 0xc6, 0x67, 0x7a, 0x22, 0x27, 0x17, 0xb3, 0x79, 0xcc, 0x37, 0x64,
554 0x5e, 0x19, 0x4f, 0x96, 0x37, 0x67, 0x3c, 0xd0, 0xc5, 0xed, 0x0f, 0xdd, 0xe7, 0x2e,
555 0x4f, 0x70, 0x97, 0x30, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0xf9, 0x00, 0x9d,
556 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3, 0x97, 0x4a, 0xcb, 0x3c, 0xe7, 0x6b,
557 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59, 0x15, 0xb1, 0x23, 0xe6, 0xc8,
558 0xdf, 0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc, 0x5b, 0x37, 0x0e, 0x12,
559 0x12, 0xb2, 0xfd, 0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6, 0x29, 0x1b, 0x99,
560 0xea, 0xae, 0xfd, 0xaa, 0x0d, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00,
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800561 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20,
Alan Stokes7cdcf992022-05-24 07:42:24 +0000562 0x06, 0x21, 0x58, 0x20, 0xb1, 0x02, 0xcc, 0x2c, 0xb2, 0x6a, 0x3b, 0xe9, 0xc1, 0xd3,
563 0x95, 0x10, 0xa0, 0xe1, 0xff, 0x51, 0xde, 0x57, 0xd5, 0x65, 0x28, 0xfd, 0x7f, 0xeb,
564 0xd4, 0xca, 0x15, 0xf3, 0xca, 0xdf, 0x37, 0x88, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41,
565 0x20, 0x58, 0x40, 0x58, 0xd8, 0x03, 0x24, 0x53, 0x60, 0x57, 0xa9, 0x09, 0xfa, 0xab,
566 0xdc, 0x57, 0x1e, 0xf0, 0xe5, 0x1e, 0x51, 0x6f, 0x9e, 0xa3, 0x42, 0xe6, 0x6a, 0x8c,
567 0xaa, 0xad, 0x08, 0x48, 0xde, 0x7f, 0x4f, 0x6e, 0x2f, 0x7f, 0x39, 0x6c, 0xa1, 0xf8,
568 0x42, 0x71, 0xfe, 0x17, 0x3d, 0xca, 0x31, 0x83, 0x92, 0xed, 0xbb, 0x40, 0xb8, 0x10,
569 0xe0, 0xf2, 0x5a, 0x99, 0x53, 0x38, 0x46, 0x33, 0x97, 0x78, 0x05, 0x84, 0x43, 0xa1,
570 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8a, 0xa9, 0x01, 0x78, 0x28, 0x31, 0x66, 0x36, 0x39,
571 0x36, 0x66, 0x30, 0x37, 0x32, 0x35, 0x32, 0x66, 0x32, 0x39, 0x65, 0x39, 0x33, 0x66,
572 0x65, 0x34, 0x64, 0x65, 0x31, 0x39, 0x65, 0x65, 0x33, 0x32, 0x63, 0x64, 0x38, 0x31,
573 0x64, 0x63, 0x34, 0x30, 0x34, 0x65, 0x37, 0x36, 0x02, 0x78, 0x28, 0x32, 0x35, 0x39,
574 0x34, 0x38, 0x39, 0x65, 0x36, 0x39, 0x37, 0x34, 0x38, 0x37, 0x30, 0x35, 0x64, 0x65,
575 0x33, 0x65, 0x32, 0x66, 0x34, 0x34, 0x32, 0x36, 0x37, 0x65, 0x61, 0x34, 0x39, 0x33,
576 0x38, 0x66, 0x66, 0x36, 0x61, 0x35, 0x37, 0x32, 0x35, 0x3a, 0x00, 0x47, 0x44, 0x50,
577 0x58, 0x40, 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43,
578 0x83, 0x7f, 0x46, 0x8d, 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0,
579 0xd9, 0x56, 0xb3, 0xbf, 0x2f, 0xfa, 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9,
580 0x6b, 0x18, 0x28, 0xe8, 0x29, 0x20, 0x49, 0x0f, 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54,
581 0xe9, 0x71, 0xd2, 0x7e, 0xa4, 0xfe, 0x58, 0x7f, 0xd3, 0xc7, 0x3a, 0x00, 0x47, 0x44,
582 0x53, 0x56, 0xa3, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x63, 0x41, 0x56, 0x42, 0x3a, 0x00,
583 0x01, 0x11, 0x72, 0x01, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00, 0x47, 0x44,
584 0x52, 0x58, 0x40, 0x93, 0x17, 0xe1, 0x11, 0x27, 0x59, 0xd0, 0xef, 0x75, 0x0b, 0x2b,
585 0x1c, 0x0f, 0x5f, 0x52, 0xc3, 0x29, 0x23, 0xb5, 0x2a, 0xe6, 0x12, 0x72, 0x6f, 0x39,
586 0x86, 0x65, 0x2d, 0xf2, 0xe4, 0xe7, 0xd0, 0xaf, 0x0e, 0xa7, 0x99, 0x16, 0x89, 0x97,
587 0x21, 0xf7, 0xdc, 0x89, 0xdc, 0xde, 0xbb, 0x94, 0x88, 0x1f, 0xda, 0xe2, 0xf3, 0xe0,
588 0x54, 0xf9, 0x0e, 0x29, 0xb1, 0xbd, 0xe1, 0x0c, 0x0b, 0xd7, 0xf6, 0x3a, 0x00, 0x47,
589 0x44, 0x54, 0x58, 0x40, 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa, 0x55, 0x6f, 0xac,
590 0x56, 0xd9, 0x02, 0x35, 0x2b, 0xaa, 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a, 0x86, 0xf5,
591 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d, 0xe4, 0x43, 0x13, 0xbf, 0xfe, 0xd3, 0x36, 0xd8,
592 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6, 0x66, 0xef, 0xab, 0x3d, 0x0f, 0x89, 0xa4,
593 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a, 0xef, 0xbc, 0x05, 0x98, 0x3a, 0x00,
594 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01,
595 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x96, 0x6d, 0x96,
596 0x42, 0xda, 0x64, 0x51, 0xad, 0xfa, 0x00, 0xbc, 0xbc, 0x95, 0x8a, 0xb0, 0xb9, 0x76,
597 0x01, 0xe6, 0xbd, 0xc0, 0x26, 0x79, 0x26, 0xfc, 0x0f, 0x1d, 0x87, 0x65, 0xf1, 0xf3,
598 0x99, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40, 0x10, 0x7f, 0x77, 0xad,
599 0x70, 0xbd, 0x52, 0x81, 0x28, 0x8d, 0x24, 0x81, 0xb4, 0x3f, 0x21, 0x68, 0x9f, 0xc3,
600 0x80, 0x68, 0x86, 0x55, 0xfb, 0x2e, 0x6d, 0x96, 0xe1, 0xe1, 0xb7, 0x28, 0x8d, 0x63,
601 0x85, 0xba, 0x2a, 0x01, 0x33, 0x87, 0x60, 0x63, 0xbb, 0x16, 0x3f, 0x2f, 0x3d, 0xf4,
602 0x2d, 0x48, 0x5b, 0x87, 0xed, 0xda, 0x34, 0xeb, 0x9c, 0x4d, 0x14, 0xac, 0x65, 0xf4,
603 0xfa, 0xef, 0x45, 0x0b, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8f, 0xa9,
604 0x01, 0x78, 0x28, 0x32, 0x35, 0x39, 0x34, 0x38, 0x39, 0x65, 0x36, 0x39, 0x37, 0x34,
605 0x38, 0x37, 0x30, 0x35, 0x64, 0x65, 0x33, 0x65, 0x32, 0x66, 0x34, 0x34, 0x32, 0x36,
606 0x37, 0x65, 0x61, 0x34, 0x39, 0x33, 0x38, 0x66, 0x66, 0x36, 0x61, 0x35, 0x37, 0x32,
607 0x35, 0x02, 0x78, 0x28, 0x35, 0x64, 0x34, 0x65, 0x64, 0x37, 0x66, 0x34, 0x31, 0x37,
608 0x61, 0x39, 0x35, 0x34, 0x61, 0x31, 0x38, 0x31, 0x34, 0x30, 0x37, 0x62, 0x35, 0x38,
609 0x38, 0x35, 0x61, 0x66, 0x64, 0x37, 0x32, 0x61, 0x35, 0x62, 0x66, 0x34, 0x30, 0x64,
610 0x61, 0x36, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615 0x00, 0x00, 0x00, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x58, 0x1a, 0xa3, 0x3a, 0x00, 0x01,
616 0x11, 0x71, 0x67, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x3a, 0x00, 0x01, 0x11,
617 0x72, 0x0c, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58,
618 0x40, 0x26, 0x1a, 0xbd, 0x26, 0xd8, 0x37, 0x8f, 0x4a, 0xf2, 0x9e, 0x49, 0x4d, 0x93,
619 0x23, 0xc4, 0x6e, 0x02, 0xda, 0xe0, 0x00, 0x02, 0xe7, 0xed, 0x29, 0xdf, 0x2b, 0xb3,
620 0x69, 0xf3, 0x55, 0x0e, 0x4c, 0x22, 0xdc, 0xcf, 0xf5, 0x92, 0xc9, 0xfa, 0x78, 0x98,
621 0xf1, 0x0e, 0x55, 0x5f, 0xf4, 0x45, 0xed, 0xc0, 0x0a, 0x72, 0x2a, 0x7a, 0x3a, 0xd2,
622 0xb1, 0xf7, 0x76, 0xfe, 0x2a, 0x6b, 0x7b, 0x2a, 0x53, 0x3a, 0x00, 0x47, 0x44, 0x54,
623 0x58, 0x40, 0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99,
624 0x30, 0x03, 0xb8, 0xd6, 0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79,
625 0x1c, 0x37, 0x68, 0x4e, 0x1d, 0xc0, 0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44,
626 0xb1, 0x43, 0xd2, 0x9c, 0xfc, 0x12, 0x9e, 0x77, 0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e,
627 0xfa, 0xc7, 0x10, 0xd5, 0x73, 0xd4, 0xc6, 0xdf, 0x62, 0x9f, 0x3a, 0x00, 0x47, 0x44,
628 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03,
629 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0xdb, 0xe7, 0x5b, 0x3f, 0xa3,
630 0x42, 0xb0, 0x9c, 0xf8, 0x40, 0x8c, 0xb0, 0x9c, 0xf0, 0x0a, 0xaf, 0xdf, 0x6f, 0xe5,
631 0x09, 0x21, 0x11, 0x92, 0xe1, 0xf8, 0xc5, 0x09, 0x02, 0x3d, 0x1f, 0xb7, 0xc5, 0x3a,
632 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40, 0xc4, 0xc1, 0xd7, 0x1c, 0x2d, 0x26,
633 0x89, 0x22, 0xcf, 0xa6, 0x99, 0x77, 0x30, 0x84, 0x86, 0x27, 0x59, 0x8f, 0xd8, 0x08,
634 0x75, 0xe0, 0xb2, 0xef, 0xf9, 0xfa, 0xa5, 0x40, 0x8c, 0xd3, 0xeb, 0xbb, 0xda, 0xf2,
635 0xc8, 0xae, 0x41, 0x22, 0x50, 0x9c, 0xe8, 0xb2, 0x9c, 0x9b, 0x3f, 0x8a, 0x78, 0x76,
636 0xab, 0xd0, 0xbe, 0xfc, 0xe4, 0x79, 0xcb, 0x1b, 0x2b, 0xaa, 0x4d, 0xdd, 0x15, 0x61,
637 0x42, 0x06, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8d, 0xa9, 0x01, 0x78,
638 0x28, 0x35, 0x64, 0x34, 0x65, 0x64, 0x37, 0x66, 0x34, 0x31, 0x37, 0x61, 0x39, 0x35,
639 0x34, 0x61, 0x31, 0x38, 0x31, 0x34, 0x30, 0x37, 0x62, 0x35, 0x38, 0x38, 0x35, 0x61,
640 0x66, 0x64, 0x37, 0x32, 0x61, 0x35, 0x62, 0x66, 0x34, 0x30, 0x64, 0x61, 0x36, 0x02,
641 0x78, 0x28, 0x36, 0x39, 0x62, 0x31, 0x37, 0x36, 0x37, 0x35, 0x38, 0x61, 0x36, 0x66,
642 0x34, 0x34, 0x62, 0x35, 0x65, 0x38, 0x39, 0x39, 0x63, 0x64, 0x65, 0x33, 0x63, 0x66,
643 0x34, 0x35, 0x31, 0x39, 0x61, 0x39, 0x33, 0x35, 0x62, 0x63, 0x39, 0x66, 0x65, 0x34,
644 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0x31, 0x0d, 0x31, 0xfa, 0x78, 0x58, 0x33,
645 0xf2, 0xf8, 0x58, 0x6b, 0xe9, 0x68, 0x32, 0x44, 0xd0, 0xfc, 0x2d, 0xe1, 0xfc, 0xe1,
646 0xc2, 0x4e, 0x2b, 0xa8, 0x2c, 0xa1, 0xc1, 0x48, 0xc6, 0xaa, 0x91, 0x89, 0x4f, 0xb7,
647 0x9c, 0x40, 0x74, 0x21, 0x36, 0x31, 0x45, 0x09, 0xdf, 0x0c, 0xb4, 0xf9, 0x9a, 0x59,
648 0xae, 0x4f, 0x21, 0x10, 0xc1, 0x38, 0xa8, 0xa2, 0xbe, 0xc6, 0x36, 0xf0, 0x56, 0x58,
649 0xdb, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x58, 0x18, 0xa2, 0x3a, 0x00, 0x01, 0x11, 0x71,
650 0x6b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x20, 0x31, 0x3a, 0x00,
651 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0xce, 0x8a, 0x30,
652 0x4e, 0x31, 0x53, 0xea, 0xdd, 0x2f, 0xbd, 0x15, 0xbc, 0x6b, 0x0f, 0xe7, 0x43, 0x50,
653 0xef, 0x65, 0xec, 0x4e, 0x21, 0x64, 0x6e, 0x41, 0x22, 0xac, 0x87, 0xda, 0xf1, 0xf2,
654 0x80, 0xc6, 0x8a, 0xd8, 0x7b, 0xe8, 0xe2, 0x9b, 0x87, 0x21, 0x5e, 0x26, 0x23, 0x11,
655 0x89, 0x86, 0x57, 0x2d, 0x47, 0x73, 0x3f, 0x47, 0x87, 0xfa, 0x58, 0x5c, 0x78, 0x7b,
656 0xa3, 0xfc, 0x2b, 0x6c, 0xed, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0xd8, 0x40,
657 0xa0, 0x60, 0x45, 0x28, 0x5d, 0xd4, 0xc1, 0x08, 0x3c, 0xbc, 0x91, 0xf4, 0xa6, 0xa4,
658 0xde, 0xd3, 0x3d, 0xbb, 0x24, 0x46, 0xa3, 0x58, 0x49, 0x57, 0x4d, 0x2e, 0x6d, 0x7a,
659 0x78, 0x4b, 0x9d, 0x28, 0x9a, 0x4e, 0xf1, 0x23, 0x06, 0x35, 0xff, 0x8e, 0x1e, 0xb3,
660 0x02, 0x63, 0x62, 0x9a, 0x50, 0x6d, 0x18, 0x70, 0x8e, 0xe3, 0x2e, 0x29, 0xb4, 0x22,
661 0x71, 0x31, 0x39, 0x65, 0xd5, 0xb5, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a,
662 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02,
663 0x20, 0x06, 0x21, 0x58, 0x20, 0x51, 0x3c, 0x4b, 0x56, 0x0b, 0x49, 0x0b, 0xee, 0xc5,
664 0x71, 0xd4, 0xe7, 0xbc, 0x44, 0x27, 0x4f, 0x4e, 0x67, 0xfc, 0x3a, 0xb9, 0x47, 0x8c,
665 0x6f, 0x24, 0x29, 0xf8, 0xb8, 0x2f, 0xa7, 0xb3, 0x4d, 0x3a, 0x00, 0x47, 0x44, 0x58,
666 0x41, 0x20, 0x58, 0x40, 0x4e, 0x6d, 0x0e, 0x2b, 0x1d, 0x44, 0x99, 0xb6, 0x63, 0x07,
667 0x86, 0x1a, 0xce, 0x4b, 0xdc, 0xd1, 0x3a, 0xdc, 0xbf, 0xaa, 0xb3, 0x06, 0xd9, 0xb5,
668 0x5c, 0x75, 0xf0, 0x14, 0x63, 0xa9, 0x1e, 0x7c, 0x56, 0x62, 0x2c, 0xa5, 0xda, 0xc9,
669 0x81, 0xcb, 0x3d, 0x63, 0x32, 0x6b, 0x76, 0x81, 0xd2, 0x93, 0xeb, 0xac, 0xfe, 0x0c,
670 0x87, 0x66, 0x9e, 0x87, 0x82, 0xb4, 0x81, 0x6e, 0x33, 0xf1, 0x08, 0x01, 0x84, 0x43,
671 0xa1, 0x01, 0x27, 0xa0, 0x59, 0x01, 0x8d, 0xa9, 0x01, 0x78, 0x28, 0x36, 0x39, 0x62,
672 0x31, 0x37, 0x36, 0x37, 0x35, 0x38, 0x61, 0x36, 0x66, 0x34, 0x34, 0x62, 0x35, 0x65,
673 0x38, 0x39, 0x39, 0x63, 0x64, 0x65, 0x33, 0x63, 0x66, 0x34, 0x35, 0x31, 0x39, 0x61,
674 0x39, 0x33, 0x35, 0x62, 0x63, 0x39, 0x66, 0x65, 0x34, 0x02, 0x78, 0x28, 0x32, 0x39,
675 0x65, 0x34, 0x62, 0x61, 0x63, 0x33, 0x30, 0x31, 0x65, 0x66, 0x36, 0x35, 0x61, 0x38,
676 0x31, 0x31, 0x62, 0x39, 0x39, 0x62, 0x30, 0x33, 0x64, 0x65, 0x39, 0x35, 0x34, 0x65,
677 0x61, 0x37, 0x36, 0x61, 0x38, 0x39, 0x31, 0x37, 0x38, 0x35, 0x3a, 0x00, 0x47, 0x44,
678 0x50, 0x58, 0x40, 0xa4, 0x03, 0xe3, 0xde, 0x44, 0x96, 0xed, 0x31, 0x41, 0xa0, 0xba,
679 0x59, 0xee, 0x2b, 0x03, 0x65, 0xcb, 0x63, 0x14, 0x78, 0xbe, 0xad, 0x24, 0x33, 0xb8,
680 0x6b, 0x52, 0xd8, 0xab, 0xd5, 0x79, 0x84, 0x98, 0x6c, 0xc2, 0x66, 0xeb, 0x6c, 0x24,
681 0xa6, 0xfa, 0x32, 0xa8, 0x16, 0xb8, 0x64, 0x37, 0x2b, 0xd4, 0xc0, 0xc4, 0xc2, 0x63,
682 0x25, 0x10, 0xce, 0x47, 0xe3, 0x49, 0xad, 0x41, 0xf5, 0xc8, 0xf6, 0x3a, 0x00, 0x47,
683 0x44, 0x53, 0x58, 0x18, 0xa2, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x6b, 0x63, 0x6f, 0x6d,
684 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x20, 0x32, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6,
685 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x40, 0xc7, 0x50, 0x09, 0xd0, 0xe0, 0xdd, 0x80,
686 0x77, 0xae, 0xa7, 0xc8, 0x88, 0x1e, 0x88, 0xd0, 0xc7, 0x0d, 0x7c, 0x49, 0xc5, 0xb5,
687 0x64, 0x32, 0x28, 0x2c, 0x48, 0x94, 0xc0, 0xd6, 0x7d, 0x9c, 0x86, 0xda, 0xf7, 0x98,
688 0xc7, 0xae, 0xa4, 0x0e, 0x61, 0xc8, 0xb0, 0x8b, 0x8a, 0xe4, 0xad, 0xcf, 0xcf, 0x6d,
689 0x60, 0x60, 0x31, 0xdd, 0xa7, 0x24, 0x9b, 0x27, 0x16, 0x31, 0x90, 0x80, 0x70, 0xc3,
690 0xba, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x40, 0xf8, 0x86, 0xc6, 0x94, 0xf9, 0x3f,
691 0x66, 0x3c, 0x43, 0x01, 0x29, 0x27, 0x8d, 0x3c, 0xb2, 0x11, 0xf2, 0x04, 0xb6, 0x67,
692 0x4f, 0x5f, 0x90, 0xcb, 0xc6, 0x73, 0xe6, 0x25, 0x14, 0x63, 0xa7, 0x95, 0x11, 0x0e,
693 0xa0, 0x1d, 0x3f, 0x6a, 0x58, 0x0a, 0x53, 0xaa, 0x68, 0x3b, 0x92, 0x64, 0x2b, 0x2e,
694 0x79, 0x80, 0x70, 0x0e, 0x41, 0xf5, 0xe9, 0x2a, 0x36, 0x0a, 0xa4, 0xe8, 0xb4, 0xe5,
695 0xdd, 0xa6, 0x3a, 0x00, 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57,
696 0x58, 0x2d, 0xa5, 0x01, 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58,
697 0x20, 0x9e, 0x04, 0x11, 0x24, 0x34, 0xba, 0x40, 0xed, 0x86, 0xe9, 0x48, 0x70, 0x3b,
698 0xe7, 0x76, 0xfa, 0xc5, 0xf6, 0x6d, 0xab, 0x86, 0x12, 0x00, 0xbe, 0xc7, 0x00, 0x69,
699 0x0e, 0x97, 0x97, 0xa6, 0x12, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40,
700 0xb7, 0x31, 0xd5, 0x4c, 0x7d, 0xf5, 0xd7, 0xb8, 0xb4, 0x4f, 0x93, 0x47, 0x2c, 0x3d,
701 0x50, 0xcc, 0xad, 0x28, 0x23, 0x68, 0xcf, 0xc2, 0x90, 0xd7, 0x02, 0x00, 0xd8, 0xf1,
702 0x00, 0x14, 0x03, 0x90, 0x9e, 0x0b, 0x91, 0xa7, 0x22, 0x28, 0xfe, 0x55, 0x42, 0x30,
703 0x93, 0x05, 0x66, 0xcd, 0xce, 0xb8, 0x48, 0x07, 0x56, 0x54, 0x67, 0xa5, 0xd7, 0xe3,
704 0x16, 0xd6, 0x75, 0x7c, 0x94, 0x98, 0x1b, 0x0b, 0x84, 0x43, 0xa1, 0x01, 0x27, 0xa0,
705 0x59, 0x01, 0x8d, 0xa9, 0x01, 0x78, 0x28, 0x32, 0x39, 0x65, 0x34, 0x62, 0x61, 0x63,
706 0x33, 0x30, 0x31, 0x65, 0x66, 0x36, 0x35, 0x61, 0x38, 0x31, 0x31, 0x62, 0x39, 0x39,
707 0x62, 0x30, 0x33, 0x64, 0x65, 0x39, 0x35, 0x34, 0x65, 0x61, 0x37, 0x36, 0x61, 0x38,
708 0x39, 0x31, 0x37, 0x38, 0x35, 0x02, 0x78, 0x28, 0x31, 0x38, 0x37, 0x36, 0x63, 0x61,
709 0x63, 0x34, 0x32, 0x33, 0x39, 0x35, 0x37, 0x66, 0x33, 0x62, 0x66, 0x62, 0x32, 0x62,
710 0x32, 0x63, 0x39, 0x33, 0x37, 0x64, 0x31, 0x34, 0x62, 0x62, 0x38, 0x30, 0x64, 0x30,
711 0x36, 0x37, 0x33, 0x65, 0x66, 0x66, 0x3a, 0x00, 0x47, 0x44, 0x50, 0x58, 0x40, 0xf4,
712 0x7d, 0x11, 0x21, 0xc1, 0x19, 0x57, 0x23, 0x08, 0x6e, 0x5f, 0xe4, 0x55, 0xc5, 0x08,
713 0x16, 0x40, 0x5f, 0x2a, 0x6f, 0x04, 0x1e, 0x6f, 0x22, 0xde, 0x53, 0xbd, 0x37, 0xe2,
714 0xfb, 0xb4, 0x0b, 0x65, 0xf4, 0xdc, 0xc9, 0xf4, 0xce, 0x2d, 0x82, 0x2a, 0xbc, 0xaf,
715 0x37, 0x80, 0x0b, 0x7f, 0xff, 0x3a, 0x98, 0x9c, 0xa7, 0x70, 0x4f, 0xbc, 0x59, 0x4f,
716 0x4e, 0xb1, 0x6d, 0xdf, 0x60, 0x39, 0x11, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x58, 0x18,
717 0xa2, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x6b, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65,
718 0x6e, 0x74, 0x20, 0x33, 0x3a, 0x00, 0x01, 0x11, 0x73, 0xf6, 0x3a, 0x00, 0x47, 0x44,
719 0x52, 0x58, 0x40, 0xa4, 0xd5, 0x6f, 0xc8, 0xd6, 0xc7, 0xe4, 0x22, 0xb4, 0x7a, 0x26,
720 0x49, 0xd5, 0xb4, 0xc1, 0xc6, 0x1b, 0xfa, 0x14, 0x8c, 0x49, 0x72, 0x2f, 0xfe, 0xbc,
721 0xc1, 0xc8, 0xc6, 0x65, 0x62, 0x86, 0xf7, 0xf2, 0x74, 0x45, 0x9b, 0x1a, 0xa0, 0x2b,
722 0xc4, 0x27, 0x13, 0xc5, 0xc3, 0xe5, 0x28, 0xc2, 0x16, 0xcd, 0x90, 0x6d, 0xa0, 0xf7,
723 0x27, 0x04, 0xa8, 0xa2, 0x62, 0xaa, 0x2c, 0x0c, 0x75, 0xd5, 0x9d, 0x3a, 0x00, 0x47,
724 0x44, 0x54, 0x58, 0x40, 0x1d, 0x92, 0x34, 0xfb, 0xfe, 0x74, 0xb7, 0xce, 0x3a, 0x95,
725 0x45, 0xe5, 0x3e, 0x1f, 0x5f, 0x18, 0x53, 0x5f, 0xe1, 0x85, 0xb0, 0x1d, 0xe3, 0x8d,
726 0x53, 0x77, 0xdc, 0x86, 0x32, 0x3d, 0x9b, 0xf9, 0xa5, 0x51, 0x17, 0x51, 0x9a, 0xd8,
727 0xa6, 0x7d, 0x45, 0x98, 0x47, 0xa2, 0x73, 0x54, 0x66, 0x28, 0x66, 0x92, 0x1d, 0x28,
728 0x8a, 0xe7, 0x5d, 0xb8, 0x96, 0x4b, 0x6a, 0x9d, 0xee, 0xc2, 0xe9, 0x20, 0x3a, 0x00,
729 0x47, 0x44, 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x2d, 0xa5, 0x01,
730 0x01, 0x03, 0x27, 0x04, 0x81, 0x02, 0x20, 0x06, 0x21, 0x58, 0x20, 0x4d, 0xf5, 0x61,
731 0x1e, 0xa6, 0x64, 0x74, 0x0b, 0x6c, 0x99, 0x8b, 0x6d, 0x34, 0x42, 0x21, 0xdd, 0x82,
732 0x26, 0x13, 0xb4, 0xf0, 0xbc, 0x9a, 0x0b, 0xf6, 0x56, 0xbd, 0x5d, 0xea, 0xd5, 0x07,
733 0x7a, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40, 0x40, 0x4d, 0x09, 0x0d,
734 0x80, 0xba, 0x12, 0x94, 0x05, 0xfb, 0x1a, 0x23, 0xa3, 0xcb, 0x28, 0x6f, 0xd7, 0x29,
735 0x95, 0xda, 0x83, 0x07, 0x3c, 0xbe, 0x7c, 0x37, 0xeb, 0x9c, 0xb2, 0x77, 0x10, 0x3f,
736 0x6a, 0x41, 0x80, 0xce, 0x56, 0xb7, 0x55, 0x22, 0x81, 0x77, 0x2d, 0x3c, 0xf8, 0x16,
737 0x38, 0x49, 0xcc, 0x9a, 0xe8, 0x3a, 0x03, 0x33, 0x4c, 0xe6, 0x87, 0x72, 0xf6, 0x5a,
738 0x4a, 0x3f, 0x4e, 0x0a,
Janis Danisevskisaaba4af2021-11-18 14:25:07 -0800739 ],
740 )
741 .unwrap()
742 }
743}