blob: 05533270f64820177bdc4a4edbe7288a9f3ea471 [file] [log] [blame]
Janis Danisevskisc51dff82021-10-20 09:51:16 -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//! This module provides a set of sample input values for a DICE chain, a sample UDS,
16//! as well as tuple of CDIs and BCC derived thereof.
17
18use android_hardware_security_dice::aidl::android::hardware::security::dice::{
19 Config::Config as BinderConfig, InputValues::InputValues as BinderInputValues, Mode::Mode,
20};
21use anyhow::{Context, Result};
22use dice::ContextImpl;
23use diced_open_dice_cbor as dice;
Alice Wangb68814b2023-02-02 13:15:32 +000024use diced_utils::{cbor, to_dice_input_values};
Janis Danisevskisc51dff82021-10-20 09:51:16 -070025use keystore2_crypto::ZVec;
Alice Wange3318902023-02-02 13:58:24 +000026use std::convert::TryInto;
Janis Danisevskisc51dff82021-10-20 09:51:16 -070027use std::io::Write;
28
29/// Sample UDS used to perform the root dice flow by `make_sample_bcc_and_cdis`.
30pub static UDS: &[u8; dice::CDI_SIZE] = &[
31 0x65, 0x4f, 0xab, 0xa9, 0xa5, 0xad, 0x0f, 0x5e, 0x15, 0xc3, 0x12, 0xf7, 0x77, 0x45, 0xfa, 0x55,
32 0x18, 0x6a, 0xa6, 0x34, 0xb6, 0x7c, 0x82, 0x7b, 0x89, 0x4c, 0xc5, 0x52, 0xd3, 0x27, 0x35, 0x8e,
33];
34
35fn encode_pub_key_ed25519(pub_key: &[u8], stream: &mut dyn Write) -> Result<()> {
36 cbor::encode_header(5 /* CBOR MAP */, 5, stream)
37 .context("In encode_pub_key_ed25519: Trying to encode map header.")?;
38 cbor::encode_number(1, stream)
39 .context("In encode_pub_key_ed25519: Trying to encode Key type tag.")?;
40 cbor::encode_number(1, stream)
41 .context("In encode_pub_key_ed25519: Trying to encode Key type.")?;
42 cbor::encode_number(3, stream)
43 .context("In encode_pub_key_ed25519: Trying to encode algorithm tag.")?;
44 // Encoding a -8 for AlgorithmEdDSA. The encoded number is -1 - <header argument>,
45 // the an argument of 7 below.
46 cbor::encode_header(1 /* CBOR NEGATIVE INT */, 7 /* -1 -7 = -8*/, stream)
47 .context("In encode_pub_key_ed25519: Trying to encode algorithm.")?;
48 cbor::encode_number(4, stream)
49 .context("In encode_pub_key_ed25519: Trying to encode ops tag.")?;
Alan Stokes7cdcf992022-05-24 07:42:24 +000050 // Encoding a single-element array for key ops
51 cbor::encode_header(4 /* CBOR ARRAY */, 1, stream)
52 .context("In encode_pub_key_ed25519: Trying to encode ops array header.")?;
Janis Danisevskisc51dff82021-10-20 09:51:16 -070053 // Ops 2 for verify.
54 cbor::encode_number(2, stream).context("In encode_pub_key_ed25519: Trying to encode ops.")?;
55 cbor::encode_header(1 /* CBOR NEGATIVE INT */, 0 /* -1 -0 = -1*/, stream)
56 .context("In encode_pub_key_ed25519: Trying to encode curve tag.")?;
57 // Curve 6 for Ed25519
58 cbor::encode_number(6, stream).context("In encode_pub_key_ed25519: Trying to encode curve.")?;
59 cbor::encode_header(1 /* CBOR NEGATIVE INT */, 1 /* -1 -1 = -2*/, stream)
60 .context("In encode_pub_key_ed25519: Trying to encode X coordinate tag.")?;
61 cbor::encode_bstr(pub_key, stream)
62 .context("In encode_pub_key_ed25519: Trying to encode X coordinate.")?;
63 Ok(())
64}
65
66/// Derives a tuple of (CDI_ATTEST, CDI_SEAL, BCC) derived of the vector of input values returned
67/// by `get_input_values_vector`.
68pub fn make_sample_bcc_and_cdis() -> Result<(ZVec, ZVec, Vec<u8>)> {
69 let mut dice_ctx = dice::OpenDiceCborContext::new();
70 let private_key_seed = dice_ctx
71 .derive_cdi_private_key_seed(UDS)
72 .context("In make_sample_bcc_and_cdis: Trying to derive private key seed.")?;
73
74 let (public_key, _) =
75 dice_ctx
76 .keypair_from_seed(&private_key_seed[..].try_into().context(
77 "In make_sample_bcc_and_cids: Failed to convert seed to array reference.",
78 )?)
79 .context("In make_sample_bcc_and_cids: Failed to generate key pair.")?;
80
81 let input_values_vector = get_input_values_vector();
82
83 let (cdi_attest, cdi_seal, mut cert) = dice_ctx
Alice Wangb68814b2023-02-02 13:15:32 +000084 .main_flow(UDS, UDS, &to_dice_input_values(&input_values_vector[0]))
Janis Danisevskisc51dff82021-10-20 09:51:16 -070085 .context("In make_sample_bcc_and_cdis: Trying to run first main flow.")?;
86
87 let mut bcc: Vec<u8> = vec![];
88
89 cbor::encode_header(4 /* CBOR ARRAY */, 2, &mut bcc)
90 .context("In make_sample_bcc_and_cdis: Trying to encode array header.")?;
91 encode_pub_key_ed25519(&public_key, &mut bcc)
92 .context("In make_sample_bcc_and_cdis: Trying encode pub_key.")?;
93
94 bcc.append(&mut cert);
95
96 let (cdi_attest, cdi_seal, bcc) = dice_ctx
97 .bcc_main_flow(
98 &cdi_attest[..].try_into().context(
99 "In make_sample_bcc_and_cdis: Failed to convert cdi_attest to array reference. (1)",
100 )?,
101 &cdi_seal[..].try_into().context(
102 "In make_sample_bcc_and_cdis: Failed to convert cdi_seal to array reference. (1)",
103 )?,
104 &bcc,
Alice Wangb68814b2023-02-02 13:15:32 +0000105 &to_dice_input_values(&input_values_vector[1]),
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700106 )
107 .context("In make_sample_bcc_and_cdis: Trying to run first bcc main flow.")?;
108 dice_ctx
109 .bcc_main_flow(
110 &cdi_attest[..].try_into().context(
111 "In make_sample_bcc_and_cdis: Failed to convert cdi_attest to array reference. (2)",
112 )?,
113 &cdi_seal[..].try_into().context(
114 "In make_sample_bcc_and_cdis: Failed to convert cdi_seal to array reference. (2)",
115 )?,
116 &bcc,
Alice Wangb68814b2023-02-02 13:15:32 +0000117 &to_dice_input_values(&input_values_vector[2]),
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700118 )
119 .context("In make_sample_bcc_and_cdis: Trying to run second bcc main flow.")
120}
121
122fn make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000123 code_hash: dice::Hash,
124 authority_hash: dice::Hash,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700125 config_name: &str,
126 config_version: u64,
127 config_resettable: bool,
128 mode: Mode,
Alice Wang98f58ec2023-02-06 09:36:19 +0000129 hidden: dice::Hidden,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700130) -> Result<BinderInputValues> {
131 Ok(BinderInputValues {
Alice Wang98f58ec2023-02-06 09:36:19 +0000132 codeHash: code_hash,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700133 config: BinderConfig {
134 desc: dice::bcc::format_config_descriptor(
135 Some(config_name),
136 Some(config_version),
137 config_resettable,
138 )
139 .context("In make_input_values: Failed to format config descriptor.")?,
140 },
Alice Wang98f58ec2023-02-06 09:36:19 +0000141 authorityHash: authority_hash,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700142 authorityDescriptor: None,
Alice Wang98f58ec2023-02-06 09:36:19 +0000143 hidden,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700144 mode,
145 })
146}
147
148/// Returns a set of sample input for a dice chain comprising the android boot loader ABL,
149/// the verified boot information AVB, and Android S.
150pub fn get_input_values_vector() -> Vec<BinderInputValues> {
Alice Wang98f58ec2023-02-06 09:36:19 +0000151 const CODE_HASH1: [u8; dice::HASH_SIZE] = [
152 0x16, 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38, 0xc3, 0x64, 0x38, 0x63,
153 0x26, 0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34, 0x4c, 0x6d, 0xa2,
154 0xbe, 0x25, 0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2, 0xb3, 0x91,
155 0x4d, 0xd3, 0xfb, 0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba, 0x30,
156 0xf7, 0x15, 0x98, 0x14,
157 ];
158 const AUTHORITY_HASH1: [u8; dice::HASH_SIZE] = [
159 0xf9, 0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3, 0x97, 0x4a, 0xcb, 0x3c,
160 0xe7, 0x6b, 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59, 0x15, 0xb1, 0x23, 0xe6,
161 0xc8, 0xdf, 0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc, 0x5b, 0x37, 0x0e, 0x12,
162 0x12, 0xb2, 0xfd, 0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6, 0x29, 0x1b, 0x99, 0xea,
163 0xae, 0xfd, 0xaa, 0x0d,
164 ];
165 const HIDDEN1: [u8; dice::HIDDEN_SIZE] = [
166 0xa2, 0x01, 0xd0, 0xc0, 0xaa, 0x75, 0x3c, 0x06, 0x43, 0x98, 0x6c, 0xc3, 0x5a, 0xb5, 0x5f,
167 0x1f, 0x0f, 0x92, 0x44, 0x3b, 0x0e, 0xd4, 0x29, 0x75, 0xe3, 0xdb, 0x36, 0xda, 0xc8, 0x07,
168 0x97, 0x4d, 0xff, 0xbc, 0x6a, 0xa4, 0x8a, 0xef, 0xc4, 0x7f, 0xf8, 0x61, 0x7d, 0x51, 0x4d,
169 0x2f, 0xdf, 0x7e, 0x8c, 0x3d, 0xa3, 0xfc, 0x63, 0xd4, 0xd4, 0x74, 0x8a, 0xc4, 0x14, 0x45,
170 0x83, 0x6b, 0x12, 0x7e,
171 ];
172 const CODE_HASH2: [u8; dice::HASH_SIZE] = [
173 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43, 0x83, 0x7f, 0x46,
174 0x8d, 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0, 0xd9, 0x56, 0xb3, 0xbf,
175 0x2f, 0xfa, 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9, 0x6b, 0x18, 0x28, 0xe8, 0x29,
176 0x20, 0x49, 0x0f, 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54, 0xe9, 0x71, 0xd2, 0x7e, 0xa4, 0xfe,
177 0x58, 0x7f, 0xd3, 0xc7,
178 ];
179 const AUTHORITY_HASH2: [u8; dice::HASH_SIZE] = [
180 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa, 0x55, 0x6f, 0xac, 0x56, 0xd9, 0x02, 0x35, 0x2b,
181 0xaa, 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a, 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d,
182 0xe4, 0x43, 0x13, 0xbf, 0xfe, 0xd3, 0x36, 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6,
183 0x66, 0xef, 0xab, 0x3d, 0x0f, 0x89, 0xa4, 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a,
184 0xef, 0xbc, 0x05, 0x98,
185 ];
186 const HIDDEN2: [u8; dice::HIDDEN_SIZE] = [
187 0x5b, 0x3f, 0xc9, 0x6b, 0xe3, 0x95, 0x59, 0x40, 0x5e, 0x64, 0xe5, 0x64, 0x3f, 0xfd, 0x21,
188 0x09, 0x9d, 0xf3, 0xcd, 0xc7, 0xa4, 0x2a, 0xe2, 0x97, 0xdd, 0xe2, 0x4f, 0xb0, 0x7d, 0x7e,
189 0xf5, 0x8e, 0xd6, 0x4d, 0x84, 0x25, 0x54, 0x41, 0x3f, 0x8f, 0x78, 0x64, 0x1a, 0x51, 0x27,
190 0x9d, 0x55, 0x8a, 0xe9, 0x90, 0x35, 0xab, 0x39, 0x80, 0x4b, 0x94, 0x40, 0x84, 0xa2, 0xfd,
191 0x73, 0xeb, 0x35, 0x7a,
192 ];
193 const AUTHORITY_HASH3: [u8; dice::HASH_SIZE] = [
194 0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30, 0x03, 0xb8,
195 0xd6, 0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37, 0x68, 0x4e,
196 0x1d, 0xc0, 0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2, 0x9c, 0xfc,
197 0x12, 0x9e, 0x77, 0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5, 0x73, 0xd4,
198 0xc6, 0xdf, 0x62, 0x9f,
199 ];
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700200 vec![
201 make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000202 CODE_HASH1,
203 AUTHORITY_HASH1,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700204 "ABL", // config name
205 1, // config version
206 true, // resettable
207 Mode::NORMAL,
Alice Wang98f58ec2023-02-06 09:36:19 +0000208 HIDDEN1,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700209 )
210 .unwrap(),
211 make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000212 CODE_HASH2,
213 AUTHORITY_HASH2,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700214 "AVB", // config name
215 1, // config version
216 true, // resettable
217 Mode::NORMAL,
Alice Wang98f58ec2023-02-06 09:36:19 +0000218 HIDDEN2,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700219 )
220 .unwrap(),
221 make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000222 [0; dice::HASH_SIZE], // code hash
223 AUTHORITY_HASH3,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700224 "Android", // config name
225 12, // config version
226 true, // resettable
227 Mode::NORMAL,
Alice Wang98f58ec2023-02-06 09:36:19 +0000228 [0; dice::HIDDEN_SIZE], // hidden,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700229 )
230 .unwrap(),
231 ]
232}
233
234#[cfg(test)]
235mod test {
236 use super::*;
237
238 // This simple test checks if the invocation succeeds, essentially it tests
239 // if the initial bcc is accepted by `DiceContext::bcc_main_flow`.
240 #[test]
241 fn make_sample_bcc_and_cdis_test() {
242 make_sample_bcc_and_cdis().unwrap();
243 }
244}