blob: 6ad8ca931a1a6dfd73d425b074f4e1083800ee21 [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};
Alice Wang4d3059a2023-02-15 10:24:33 +000021use anyhow::{anyhow, Context, Result};
Alice Wangf59662d2023-02-10 16:07:56 +000022use diced_open_dice as dice;
Alice Wang4d3059a2023-02-15 10:24:33 +000023use diced_open_dice::DiceArtifacts;
Alice Wangb68814b2023-02-02 13:15:32 +000024use diced_utils::{cbor, to_dice_input_values};
Alice Wang9c40eca2023-02-03 13:10:24 +000025use std::ffi::CStr;
Janis Danisevskisc51dff82021-10-20 09:51:16 -070026use std::io::Write;
27
28/// Sample UDS used to perform the root dice flow by `make_sample_bcc_and_cdis`.
29pub static UDS: &[u8; dice::CDI_SIZE] = &[
30 0x65, 0x4f, 0xab, 0xa9, 0xa5, 0xad, 0x0f, 0x5e, 0x15, 0xc3, 0x12, 0xf7, 0x77, 0x45, 0xfa, 0x55,
31 0x18, 0x6a, 0xa6, 0x34, 0xb6, 0x7c, 0x82, 0x7b, 0x89, 0x4c, 0xc5, 0x52, 0xd3, 0x27, 0x35, 0x8e,
32];
33
34fn encode_pub_key_ed25519(pub_key: &[u8], stream: &mut dyn Write) -> Result<()> {
35 cbor::encode_header(5 /* CBOR MAP */, 5, stream)
36 .context("In encode_pub_key_ed25519: Trying to encode map header.")?;
37 cbor::encode_number(1, stream)
38 .context("In encode_pub_key_ed25519: Trying to encode Key type tag.")?;
39 cbor::encode_number(1, stream)
40 .context("In encode_pub_key_ed25519: Trying to encode Key type.")?;
41 cbor::encode_number(3, stream)
42 .context("In encode_pub_key_ed25519: Trying to encode algorithm tag.")?;
43 // Encoding a -8 for AlgorithmEdDSA. The encoded number is -1 - <header argument>,
44 // the an argument of 7 below.
45 cbor::encode_header(1 /* CBOR NEGATIVE INT */, 7 /* -1 -7 = -8*/, stream)
46 .context("In encode_pub_key_ed25519: Trying to encode algorithm.")?;
47 cbor::encode_number(4, stream)
48 .context("In encode_pub_key_ed25519: Trying to encode ops tag.")?;
Alan Stokes7cdcf992022-05-24 07:42:24 +000049 // Encoding a single-element array for key ops
50 cbor::encode_header(4 /* CBOR ARRAY */, 1, stream)
51 .context("In encode_pub_key_ed25519: Trying to encode ops array header.")?;
Janis Danisevskisc51dff82021-10-20 09:51:16 -070052 // Ops 2 for verify.
53 cbor::encode_number(2, stream).context("In encode_pub_key_ed25519: Trying to encode ops.")?;
54 cbor::encode_header(1 /* CBOR NEGATIVE INT */, 0 /* -1 -0 = -1*/, stream)
55 .context("In encode_pub_key_ed25519: Trying to encode curve tag.")?;
56 // Curve 6 for Ed25519
57 cbor::encode_number(6, stream).context("In encode_pub_key_ed25519: Trying to encode curve.")?;
58 cbor::encode_header(1 /* CBOR NEGATIVE INT */, 1 /* -1 -1 = -2*/, stream)
59 .context("In encode_pub_key_ed25519: Trying to encode X coordinate tag.")?;
60 cbor::encode_bstr(pub_key, stream)
61 .context("In encode_pub_key_ed25519: Trying to encode X coordinate.")?;
62 Ok(())
63}
64
65/// Derives a tuple of (CDI_ATTEST, CDI_SEAL, BCC) derived of the vector of input values returned
66/// by `get_input_values_vector`.
Alice Wangf4bd1c62023-02-08 08:38:44 +000067pub fn make_sample_bcc_and_cdis() -> Result<dice::OwnedDiceArtifacts> {
Alice Wang7cc59562023-02-08 13:17:10 +000068 let private_key_seed = dice::derive_cdi_private_key_seed(UDS)
Janis Danisevskisc51dff82021-10-20 09:51:16 -070069 .context("In make_sample_bcc_and_cdis: Trying to derive private key seed.")?;
70
Alice Wangf59662d2023-02-10 16:07:56 +000071 let (public_key, _) = dice::keypair_from_seed(private_key_seed.as_array())
72 .context("In make_sample_bcc_and_cids: Failed to generate key pair.")?;
Janis Danisevskisc51dff82021-10-20 09:51:16 -070073
74 let input_values_vector = get_input_values_vector();
75
Alice Wang44f48b22023-02-09 09:51:22 +000076 let (cdi_values, mut cert) =
77 dice::retry_dice_main_flow(UDS, UDS, &to_dice_input_values(&input_values_vector[0]))
78 .context("In make_sample_bcc_and_cdis: Trying to run first main flow.")?;
Janis Danisevskisc51dff82021-10-20 09:51:16 -070079
80 let mut bcc: Vec<u8> = vec![];
81
82 cbor::encode_header(4 /* CBOR ARRAY */, 2, &mut bcc)
83 .context("In make_sample_bcc_and_cdis: Trying to encode array header.")?;
84 encode_pub_key_ed25519(&public_key, &mut bcc)
85 .context("In make_sample_bcc_and_cdis: Trying encode pub_key.")?;
86
87 bcc.append(&mut cert);
88
Alice Wangf4bd1c62023-02-08 08:38:44 +000089 let dice_artifacts = dice::retry_bcc_main_flow(
Alice Wang44f48b22023-02-09 09:51:22 +000090 &cdi_values.cdi_attest,
91 &cdi_values.cdi_seal,
Alice Wangf4bd1c62023-02-08 08:38:44 +000092 &bcc,
93 &to_dice_input_values(&input_values_vector[1]),
94 )
95 .context("In make_sample_bcc_and_cdis: Trying to run first bcc main flow.")?;
96 dice::retry_bcc_main_flow(
Alice Wang4d3059a2023-02-15 10:24:33 +000097 dice_artifacts.cdi_attest(),
98 dice_artifacts.cdi_seal(),
99 dice_artifacts.bcc().ok_or_else(|| anyhow!("bcc is none"))?,
Alice Wangf4bd1c62023-02-08 08:38:44 +0000100 &to_dice_input_values(&input_values_vector[2]),
101 )
102 .context("In make_sample_bcc_and_cdis: Trying to run second bcc main flow.")
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700103}
104
105fn make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000106 code_hash: dice::Hash,
107 authority_hash: dice::Hash,
Alice Wang9c40eca2023-02-03 13:10:24 +0000108 config_name: &CStr,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700109 config_version: u64,
110 config_resettable: bool,
111 mode: Mode,
Alice Wang98f58ec2023-02-06 09:36:19 +0000112 hidden: dice::Hidden,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700113) -> Result<BinderInputValues> {
114 Ok(BinderInputValues {
Alice Wang98f58ec2023-02-06 09:36:19 +0000115 codeHash: code_hash,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700116 config: BinderConfig {
Alice Wang9c40eca2023-02-03 13:10:24 +0000117 desc: dice::retry_bcc_format_config_descriptor(
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700118 Some(config_name),
119 Some(config_version),
120 config_resettable,
121 )
122 .context("In make_input_values: Failed to format config descriptor.")?,
123 },
Alice Wang98f58ec2023-02-06 09:36:19 +0000124 authorityHash: authority_hash,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700125 authorityDescriptor: None,
Alice Wang98f58ec2023-02-06 09:36:19 +0000126 hidden,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700127 mode,
128 })
129}
130
131/// Returns a set of sample input for a dice chain comprising the android boot loader ABL,
132/// the verified boot information AVB, and Android S.
133pub fn get_input_values_vector() -> Vec<BinderInputValues> {
Alice Wang98f58ec2023-02-06 09:36:19 +0000134 const CODE_HASH1: [u8; dice::HASH_SIZE] = [
135 0x16, 0x48, 0xf2, 0x55, 0x53, 0x23, 0xdd, 0x15, 0x2e, 0x83, 0x38, 0xc3, 0x64, 0x38, 0x63,
136 0x26, 0x0f, 0xcf, 0x5b, 0xd1, 0x3a, 0xd3, 0x40, 0x3e, 0x23, 0xf8, 0x34, 0x4c, 0x6d, 0xa2,
137 0xbe, 0x25, 0x1c, 0xb0, 0x29, 0xe8, 0xc3, 0xfb, 0xb8, 0x80, 0xdc, 0xb1, 0xd2, 0xb3, 0x91,
138 0x4d, 0xd3, 0xfb, 0x01, 0x0f, 0xe4, 0xe9, 0x46, 0xa2, 0xc0, 0x26, 0x57, 0x5a, 0xba, 0x30,
139 0xf7, 0x15, 0x98, 0x14,
140 ];
141 const AUTHORITY_HASH1: [u8; dice::HASH_SIZE] = [
142 0xf9, 0x00, 0x9d, 0xc2, 0x59, 0x09, 0xe0, 0xb6, 0x98, 0xbd, 0xe3, 0x97, 0x4a, 0xcb, 0x3c,
143 0xe7, 0x6b, 0x24, 0xc3, 0xe4, 0x98, 0xdd, 0xa9, 0x6a, 0x41, 0x59, 0x15, 0xb1, 0x23, 0xe6,
144 0xc8, 0xdf, 0xfb, 0x52, 0xb4, 0x52, 0xc1, 0xb9, 0x61, 0xdd, 0xbc, 0x5b, 0x37, 0x0e, 0x12,
145 0x12, 0xb2, 0xfd, 0xc1, 0x09, 0xb0, 0xcf, 0x33, 0x81, 0x4c, 0xc6, 0x29, 0x1b, 0x99, 0xea,
146 0xae, 0xfd, 0xaa, 0x0d,
147 ];
148 const HIDDEN1: [u8; dice::HIDDEN_SIZE] = [
149 0xa2, 0x01, 0xd0, 0xc0, 0xaa, 0x75, 0x3c, 0x06, 0x43, 0x98, 0x6c, 0xc3, 0x5a, 0xb5, 0x5f,
150 0x1f, 0x0f, 0x92, 0x44, 0x3b, 0x0e, 0xd4, 0x29, 0x75, 0xe3, 0xdb, 0x36, 0xda, 0xc8, 0x07,
151 0x97, 0x4d, 0xff, 0xbc, 0x6a, 0xa4, 0x8a, 0xef, 0xc4, 0x7f, 0xf8, 0x61, 0x7d, 0x51, 0x4d,
152 0x2f, 0xdf, 0x7e, 0x8c, 0x3d, 0xa3, 0xfc, 0x63, 0xd4, 0xd4, 0x74, 0x8a, 0xc4, 0x14, 0x45,
153 0x83, 0x6b, 0x12, 0x7e,
154 ];
155 const CODE_HASH2: [u8; dice::HASH_SIZE] = [
156 0xa4, 0x0c, 0xcb, 0xc1, 0xbf, 0xfa, 0xcc, 0xfd, 0xeb, 0xf4, 0xfc, 0x43, 0x83, 0x7f, 0x46,
157 0x8d, 0xd8, 0xd8, 0x14, 0xc1, 0x96, 0x14, 0x1f, 0x6e, 0xb3, 0xa0, 0xd9, 0x56, 0xb3, 0xbf,
158 0x2f, 0xfa, 0x88, 0x70, 0x11, 0x07, 0x39, 0xa4, 0xd2, 0xa9, 0x6b, 0x18, 0x28, 0xe8, 0x29,
159 0x20, 0x49, 0x0f, 0xbb, 0x8d, 0x08, 0x8c, 0xc6, 0x54, 0xe9, 0x71, 0xd2, 0x7e, 0xa4, 0xfe,
160 0x58, 0x7f, 0xd3, 0xc7,
161 ];
162 const AUTHORITY_HASH2: [u8; dice::HASH_SIZE] = [
163 0xb2, 0x69, 0x05, 0x48, 0x56, 0xb5, 0xfa, 0x55, 0x6f, 0xac, 0x56, 0xd9, 0x02, 0x35, 0x2b,
164 0xaa, 0x4c, 0xba, 0x28, 0xdd, 0x82, 0x3a, 0x86, 0xf5, 0xd4, 0xc2, 0xf1, 0xf9, 0x35, 0x7d,
165 0xe4, 0x43, 0x13, 0xbf, 0xfe, 0xd3, 0x36, 0xd8, 0x1c, 0x12, 0x78, 0x5c, 0x9c, 0x3e, 0xf6,
166 0x66, 0xef, 0xab, 0x3d, 0x0f, 0x89, 0xa4, 0x6f, 0xc9, 0x72, 0xee, 0x73, 0x43, 0x02, 0x8a,
167 0xef, 0xbc, 0x05, 0x98,
168 ];
169 const HIDDEN2: [u8; dice::HIDDEN_SIZE] = [
170 0x5b, 0x3f, 0xc9, 0x6b, 0xe3, 0x95, 0x59, 0x40, 0x5e, 0x64, 0xe5, 0x64, 0x3f, 0xfd, 0x21,
171 0x09, 0x9d, 0xf3, 0xcd, 0xc7, 0xa4, 0x2a, 0xe2, 0x97, 0xdd, 0xe2, 0x4f, 0xb0, 0x7d, 0x7e,
172 0xf5, 0x8e, 0xd6, 0x4d, 0x84, 0x25, 0x54, 0x41, 0x3f, 0x8f, 0x78, 0x64, 0x1a, 0x51, 0x27,
173 0x9d, 0x55, 0x8a, 0xe9, 0x90, 0x35, 0xab, 0x39, 0x80, 0x4b, 0x94, 0x40, 0x84, 0xa2, 0xfd,
174 0x73, 0xeb, 0x35, 0x7a,
175 ];
176 const AUTHORITY_HASH3: [u8; dice::HASH_SIZE] = [
177 0x04, 0x25, 0x5d, 0x60, 0x5f, 0x5c, 0x45, 0x0d, 0xf2, 0x9a, 0x6e, 0x99, 0x30, 0x03, 0xb8,
178 0xd6, 0xe1, 0x99, 0x71, 0x1b, 0xf8, 0x44, 0xfa, 0xb5, 0x31, 0x79, 0x1c, 0x37, 0x68, 0x4e,
179 0x1d, 0xc0, 0x24, 0x74, 0x68, 0xf8, 0x80, 0x20, 0x3e, 0x44, 0xb1, 0x43, 0xd2, 0x9c, 0xfc,
180 0x12, 0x9e, 0x77, 0x0a, 0xde, 0x29, 0x24, 0xff, 0x2e, 0xfa, 0xc7, 0x10, 0xd5, 0x73, 0xd4,
181 0xc6, 0xdf, 0x62, 0x9f,
182 ];
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700183 vec![
184 make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000185 CODE_HASH1,
186 AUTHORITY_HASH1,
Alice Wang9c40eca2023-02-03 13:10:24 +0000187 CStr::from_bytes_with_nul(b"ABL\0").unwrap(), // config name
188 1, // config version
189 true, // resettable
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700190 Mode::NORMAL,
Alice Wang98f58ec2023-02-06 09:36:19 +0000191 HIDDEN1,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700192 )
193 .unwrap(),
194 make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000195 CODE_HASH2,
196 AUTHORITY_HASH2,
Alice Wang9c40eca2023-02-03 13:10:24 +0000197 CStr::from_bytes_with_nul(b"AVB\0").unwrap(), // config name
198 1, // config version
199 true, // resettable
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700200 Mode::NORMAL,
Alice Wang98f58ec2023-02-06 09:36:19 +0000201 HIDDEN2,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700202 )
203 .unwrap(),
204 make_input_values(
Alice Wang98f58ec2023-02-06 09:36:19 +0000205 [0; dice::HASH_SIZE], // code hash
206 AUTHORITY_HASH3,
Alice Wang9c40eca2023-02-03 13:10:24 +0000207 CStr::from_bytes_with_nul(b"Android\0").unwrap(), // config name
208 12, // config version
209 true, // resettable
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700210 Mode::NORMAL,
Alice Wang98f58ec2023-02-06 09:36:19 +0000211 [0; dice::HIDDEN_SIZE], // hidden,
Janis Danisevskisc51dff82021-10-20 09:51:16 -0700212 )
213 .unwrap(),
214 ]
215}
216
217#[cfg(test)]
218mod test {
219 use super::*;
220
221 // This simple test checks if the invocation succeeds, essentially it tests
222 // if the initial bcc is accepted by `DiceContext::bcc_main_flow`.
223 #[test]
224 fn make_sample_bcc_and_cdis_test() {
225 make_sample_bcc_and_cdis().unwrap();
226 }
227}