blob: 3f361192d97f1d599f172d283c9fb24a9e53f3f0 [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;
Alice Wang9c40eca2023-02-03 13:10:24 +000027use std::ffi::CStr;
Janis Danisevskisc51dff82021-10-20 09:51:16 -070028use std::io::Write;
29
30/// Sample UDS used to perform the root dice flow by `make_sample_bcc_and_cdis`.
31pub static UDS: &[u8; dice::CDI_SIZE] = &[
32 0x65, 0x4f, 0xab, 0xa9, 0xa5, 0xad, 0x0f, 0x5e, 0x15, 0xc3, 0x12, 0xf7, 0x77, 0x45, 0xfa, 0x55,
33 0x18, 0x6a, 0xa6, 0x34, 0xb6, 0x7c, 0x82, 0x7b, 0x89, 0x4c, 0xc5, 0x52, 0xd3, 0x27, 0x35, 0x8e,
34];
35
36fn encode_pub_key_ed25519(pub_key: &[u8], stream: &mut dyn Write) -> Result<()> {
37 cbor::encode_header(5 /* CBOR MAP */, 5, stream)
38 .context("In encode_pub_key_ed25519: Trying to encode map header.")?;
39 cbor::encode_number(1, stream)
40 .context("In encode_pub_key_ed25519: Trying to encode Key type tag.")?;
41 cbor::encode_number(1, stream)
42 .context("In encode_pub_key_ed25519: Trying to encode Key type.")?;
43 cbor::encode_number(3, stream)
44 .context("In encode_pub_key_ed25519: Trying to encode algorithm tag.")?;
45 // Encoding a -8 for AlgorithmEdDSA. The encoded number is -1 - <header argument>,
46 // the an argument of 7 below.
47 cbor::encode_header(1 /* CBOR NEGATIVE INT */, 7 /* -1 -7 = -8*/, stream)
48 .context("In encode_pub_key_ed25519: Trying to encode algorithm.")?;
49 cbor::encode_number(4, stream)
50 .context("In encode_pub_key_ed25519: Trying to encode ops tag.")?;
Alan Stokes7cdcf992022-05-24 07:42:24 +000051 // Encoding a single-element array for key ops
52 cbor::encode_header(4 /* CBOR ARRAY */, 1, stream)
53 .context("In encode_pub_key_ed25519: Trying to encode ops array header.")?;
Janis Danisevskisc51dff82021-10-20 09:51:16 -070054 // Ops 2 for verify.
55 cbor::encode_number(2, stream).context("In encode_pub_key_ed25519: Trying to encode ops.")?;
56 cbor::encode_header(1 /* CBOR NEGATIVE INT */, 0 /* -1 -0 = -1*/, stream)
57 .context("In encode_pub_key_ed25519: Trying to encode curve tag.")?;
58 // Curve 6 for Ed25519
59 cbor::encode_number(6, stream).context("In encode_pub_key_ed25519: Trying to encode curve.")?;
60 cbor::encode_header(1 /* CBOR NEGATIVE INT */, 1 /* -1 -1 = -2*/, stream)
61 .context("In encode_pub_key_ed25519: Trying to encode X coordinate tag.")?;
62 cbor::encode_bstr(pub_key, stream)
63 .context("In encode_pub_key_ed25519: Trying to encode X coordinate.")?;
64 Ok(())
65}
66
67/// Derives a tuple of (CDI_ATTEST, CDI_SEAL, BCC) derived of the vector of input values returned
68/// by `get_input_values_vector`.
69pub fn make_sample_bcc_and_cdis() -> Result<(ZVec, ZVec, Vec<u8>)> {
70 let mut dice_ctx = dice::OpenDiceCborContext::new();
71 let private_key_seed = dice_ctx
72 .derive_cdi_private_key_seed(UDS)
73 .context("In make_sample_bcc_and_cdis: Trying to derive private key seed.")?;
74
75 let (public_key, _) =
76 dice_ctx
77 .keypair_from_seed(&private_key_seed[..].try_into().context(
78 "In make_sample_bcc_and_cids: Failed to convert seed to array reference.",
79 )?)
80 .context("In make_sample_bcc_and_cids: Failed to generate key pair.")?;
81
82 let input_values_vector = get_input_values_vector();
83
84 let (cdi_attest, cdi_seal, mut cert) = dice_ctx
Alice Wangb68814b2023-02-02 13:15:32 +000085 .main_flow(UDS, UDS, &to_dice_input_values(&input_values_vector[0]))
Janis Danisevskisc51dff82021-10-20 09:51:16 -070086 .context("In make_sample_bcc_and_cdis: Trying to run first main flow.")?;
87
88 let mut bcc: Vec<u8> = vec![];
89
90 cbor::encode_header(4 /* CBOR ARRAY */, 2, &mut bcc)
91 .context("In make_sample_bcc_and_cdis: Trying to encode array header.")?;
92 encode_pub_key_ed25519(&public_key, &mut bcc)
93 .context("In make_sample_bcc_and_cdis: Trying encode pub_key.")?;
94
95 bcc.append(&mut cert);
96
97 let (cdi_attest, cdi_seal, bcc) = dice_ctx
98 .bcc_main_flow(
99 &cdi_attest[..].try_into().context(
100 "In make_sample_bcc_and_cdis: Failed to convert cdi_attest to array reference. (1)",
101 )?,
102 &cdi_seal[..].try_into().context(
103 "In make_sample_bcc_and_cdis: Failed to convert cdi_seal to array reference. (1)",
104 )?,
105 &bcc,
Alice Wangb68814b2023-02-02 13:15:32 +0000106 &to_dice_input_values(&input_values_vector[1]),
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700107 )
108 .context("In make_sample_bcc_and_cdis: Trying to run first bcc main flow.")?;
109 dice_ctx
110 .bcc_main_flow(
111 &cdi_attest[..].try_into().context(
112 "In make_sample_bcc_and_cdis: Failed to convert cdi_attest to array reference. (2)",
113 )?,
114 &cdi_seal[..].try_into().context(
115 "In make_sample_bcc_and_cdis: Failed to convert cdi_seal to array reference. (2)",
116 )?,
117 &bcc,
Alice Wangb68814b2023-02-02 13:15:32 +0000118 &to_dice_input_values(&input_values_vector[2]),
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700119 )
120 .context("In make_sample_bcc_and_cdis: Trying to run second bcc main flow.")
121}
122
123fn make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000124 code_hash: dice::Hash,
125 authority_hash: dice::Hash,
Alice Wang9c40eca2023-02-03 13:10:24 +0000126 config_name: &CStr,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700127 config_version: u64,
128 config_resettable: bool,
129 mode: Mode,
Alice Wang98f58ec2023-02-06 09:36:19 +0000130 hidden: dice::Hidden,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700131) -> Result<BinderInputValues> {
132 Ok(BinderInputValues {
Alice Wang98f58ec2023-02-06 09:36:19 +0000133 codeHash: code_hash,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700134 config: BinderConfig {
Alice Wang9c40eca2023-02-03 13:10:24 +0000135 desc: dice::retry_bcc_format_config_descriptor(
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700136 Some(config_name),
137 Some(config_version),
138 config_resettable,
139 )
140 .context("In make_input_values: Failed to format config descriptor.")?,
141 },
Alice Wang98f58ec2023-02-06 09:36:19 +0000142 authorityHash: authority_hash,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700143 authorityDescriptor: None,
Alice Wang98f58ec2023-02-06 09:36:19 +0000144 hidden,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700145 mode,
146 })
147}
148
149/// Returns a set of sample input for a dice chain comprising the android boot loader ABL,
150/// the verified boot information AVB, and Android S.
151pub fn get_input_values_vector() -> Vec<BinderInputValues> {
Alice Wang98f58ec2023-02-06 09:36:19 +0000152 const CODE_HASH1: [u8; dice::HASH_SIZE] = [
153 0x16, 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38, 0xc3, 0x64, 0x38, 0x63,
154 0x26, 0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34, 0x4c, 0x6d, 0xa2,
155 0xbe, 0x25, 0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2, 0xb3, 0x91,
156 0x4d, 0xd3, 0xfb, 0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba, 0x30,
157 0xf7, 0x15, 0x98, 0x14,
158 ];
159 const AUTHORITY_HASH1: [u8; dice::HASH_SIZE] = [
160 0xf9, 0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3, 0x97, 0x4a, 0xcb, 0x3c,
161 0xe7, 0x6b, 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59, 0x15, 0xb1, 0x23, 0xe6,
162 0xc8, 0xdf, 0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc, 0x5b, 0x37, 0x0e, 0x12,
163 0x12, 0xb2, 0xfd, 0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6, 0x29, 0x1b, 0x99, 0xea,
164 0xae, 0xfd, 0xaa, 0x0d,
165 ];
166 const HIDDEN1: [u8; dice::HIDDEN_SIZE] = [
167 0xa2, 0x01, 0xd0, 0xc0, 0xaa, 0x75, 0x3c, 0x06, 0x43, 0x98, 0x6c, 0xc3, 0x5a, 0xb5, 0x5f,
168 0x1f, 0x0f, 0x92, 0x44, 0x3b, 0x0e, 0xd4, 0x29, 0x75, 0xe3, 0xdb, 0x36, 0xda, 0xc8, 0x07,
169 0x97, 0x4d, 0xff, 0xbc, 0x6a, 0xa4, 0x8a, 0xef, 0xc4, 0x7f, 0xf8, 0x61, 0x7d, 0x51, 0x4d,
170 0x2f, 0xdf, 0x7e, 0x8c, 0x3d, 0xa3, 0xfc, 0x63, 0xd4, 0xd4, 0x74, 0x8a, 0xc4, 0x14, 0x45,
171 0x83, 0x6b, 0x12, 0x7e,
172 ];
173 const CODE_HASH2: [u8; dice::HASH_SIZE] = [
174 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43, 0x83, 0x7f, 0x46,
175 0x8d, 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0, 0xd9, 0x56, 0xb3, 0xbf,
176 0x2f, 0xfa, 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9, 0x6b, 0x18, 0x28, 0xe8, 0x29,
177 0x20, 0x49, 0x0f, 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54, 0xe9, 0x71, 0xd2, 0x7e, 0xa4, 0xfe,
178 0x58, 0x7f, 0xd3, 0xc7,
179 ];
180 const AUTHORITY_HASH2: [u8; dice::HASH_SIZE] = [
181 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa, 0x55, 0x6f, 0xac, 0x56, 0xd9, 0x02, 0x35, 0x2b,
182 0xaa, 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a, 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d,
183 0xe4, 0x43, 0x13, 0xbf, 0xfe, 0xd3, 0x36, 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6,
184 0x66, 0xef, 0xab, 0x3d, 0x0f, 0x89, 0xa4, 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a,
185 0xef, 0xbc, 0x05, 0x98,
186 ];
187 const HIDDEN2: [u8; dice::HIDDEN_SIZE] = [
188 0x5b, 0x3f, 0xc9, 0x6b, 0xe3, 0x95, 0x59, 0x40, 0x5e, 0x64, 0xe5, 0x64, 0x3f, 0xfd, 0x21,
189 0x09, 0x9d, 0xf3, 0xcd, 0xc7, 0xa4, 0x2a, 0xe2, 0x97, 0xdd, 0xe2, 0x4f, 0xb0, 0x7d, 0x7e,
190 0xf5, 0x8e, 0xd6, 0x4d, 0x84, 0x25, 0x54, 0x41, 0x3f, 0x8f, 0x78, 0x64, 0x1a, 0x51, 0x27,
191 0x9d, 0x55, 0x8a, 0xe9, 0x90, 0x35, 0xab, 0x39, 0x80, 0x4b, 0x94, 0x40, 0x84, 0xa2, 0xfd,
192 0x73, 0xeb, 0x35, 0x7a,
193 ];
194 const AUTHORITY_HASH3: [u8; dice::HASH_SIZE] = [
195 0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30, 0x03, 0xb8,
196 0xd6, 0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37, 0x68, 0x4e,
197 0x1d, 0xc0, 0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2, 0x9c, 0xfc,
198 0x12, 0x9e, 0x77, 0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5, 0x73, 0xd4,
199 0xc6, 0xdf, 0x62, 0x9f,
200 ];
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700201 vec![
202 make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000203 CODE_HASH1,
204 AUTHORITY_HASH1,
Alice Wang9c40eca2023-02-03 13:10:24 +0000205 CStr::from_bytes_with_nul(b"ABL\0").unwrap(), // config name
206 1, // config version
207 true, // resettable
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700208 Mode::NORMAL,
Alice Wang98f58ec2023-02-06 09:36:19 +0000209 HIDDEN1,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700210 )
211 .unwrap(),
212 make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000213 CODE_HASH2,
214 AUTHORITY_HASH2,
Alice Wang9c40eca2023-02-03 13:10:24 +0000215 CStr::from_bytes_with_nul(b"AVB\0").unwrap(), // config name
216 1, // config version
217 true, // resettable
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700218 Mode::NORMAL,
Alice Wang98f58ec2023-02-06 09:36:19 +0000219 HIDDEN2,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700220 )
221 .unwrap(),
222 make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000223 [0; dice::HASH_SIZE], // code hash
224 AUTHORITY_HASH3,
Alice Wang9c40eca2023-02-03 13:10:24 +0000225 CStr::from_bytes_with_nul(b"Android\0").unwrap(), // config name
226 12, // config version
227 true, // resettable
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700228 Mode::NORMAL,
Alice Wang98f58ec2023-02-06 09:36:19 +0000229 [0; dice::HIDDEN_SIZE], // hidden,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700230 )
231 .unwrap(),
232 ]
233}
234
235#[cfg(test)]
236mod test {
237 use super::*;
238
239 // This simple test checks if the invocation succeeds, essentially it tests
240 // if the initial bcc is accepted by `DiceContext::bcc_main_flow`.
241 #[test]
242 fn make_sample_bcc_and_cdis_test() {
243 make_sample_bcc_and_cdis().unwrap();
244 }
245}