blob: 054b2d18f53c8c36853797d612cd524db8f2deff [file] [log] [blame]
Janis Danisevskisda092a12021-11-17 22:58:16 -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
15use android_hardware_security_dice::aidl::android::hardware::security::dice::{
16 Config::Config as BinderConfig, InputValues::InputValues as BinderInputValues,
17 Mode::Mode as BinderMode,
18};
19use android_security_dice::aidl::android::security::dice::IDiceMaintenance::IDiceMaintenance;
20use android_security_dice::aidl::android::security::dice::IDiceNode::IDiceNode;
Janis Danisevskisda092a12021-11-17 22:58:16 -080021use binder::Strong;
22use diced_open_dice_cbor as dice;
23use nix::libc::uid_t;
24use std::convert::TryInto;
Alice Wang9c40eca2023-02-03 13:10:24 +000025use std::ffi::CString;
Janis Danisevskisda092a12021-11-17 22:58:16 -080026
27static DICE_NODE_SERVICE_NAME: &str = "android.security.dice.IDiceNode";
28static DICE_MAINTENANCE_SERVICE_NAME: &str = "android.security.dice.IDiceMaintenance";
29
30fn get_dice_node() -> Strong<dyn IDiceNode> {
31 binder::get_interface(DICE_NODE_SERVICE_NAME).unwrap()
32}
33
34fn get_dice_maintenance() -> Strong<dyn IDiceMaintenance> {
35 binder::get_interface(DICE_MAINTENANCE_SERVICE_NAME).unwrap()
36}
37
38static TEST_MESSAGE: &[u8] = &[
39 // "My test message!"
40 0x4d, 0x79, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x21,
41 0x0a,
42];
43
44// This test calls derive with an empty argument vector and with a set of three input values.
45// It then performs the same three derivation steps on the result of the former and compares
46// the result to the result of the latter.
47fn equivalence_test() {
48 let node = get_dice_node();
49 let input_values = diced_sample_inputs::get_input_values_vector();
50 let former = node.derive(&[]).expect("Trying to call derive.");
51 let latter = node.derive(&input_values).expect("Trying to call derive with input values.");
Janis Danisevskisd9513f42021-12-16 17:15:13 -080052 let artifacts =
53 diced_utils::ResidentArtifacts::new(&former.cdiAttest, &former.cdiSeal, &former.bcc.data)
54 .unwrap();
Janis Danisevskisda092a12021-11-17 22:58:16 -080055
Alice Wang93e6e372023-02-02 14:36:17 +000056 let artifacts = artifacts.execute_steps(input_values.iter()).unwrap();
Janis Danisevskisda092a12021-11-17 22:58:16 -080057 let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
58 let from_former = diced_utils::make_bcc_handover(
59 cdi_attest[..].try_into().unwrap(),
60 cdi_seal[..].try_into().unwrap(),
61 &bcc,
62 )
63 .unwrap();
64 // TODO when we have a parser/verifier, check equivalence rather
65 // than bit by bit equality.
66 assert_eq!(latter, from_former);
67}
68
69fn sign_and_verify() {
70 let node = get_dice_node();
71 let _signature = node.sign(&[], TEST_MESSAGE).expect("Trying to call sign.");
72
73 let _bcc = node.getAttestationChain(&[]).expect("Trying to call getAttestationChain.");
74 // TODO b/204938506 check the signature with the bcc when the verifier is available.
75}
76
77// This test calls derive with an empty argument vector, then demotes the itself using
78// a set of three input values, and then calls derive with empty argument vector again.
79// It then performs the same three derivation steps on the result of the former and compares
80// the result to the result of the latter.
81fn demote_test() {
82 let node = get_dice_node();
83 let input_values = diced_sample_inputs::get_input_values_vector();
84 let former = node.derive(&[]).expect("Trying to call derive.");
85 node.demote(&input_values).expect("Trying to call demote with input values.");
86
87 let latter = node.derive(&[]).expect("Trying to call derive after demote.");
88
89 let artifacts = diced_utils::ResidentArtifacts::new(
90 former.cdiAttest[..].try_into().unwrap(),
91 former.cdiSeal[..].try_into().unwrap(),
92 &former.bcc.data,
93 )
94 .unwrap();
95
Alice Wang93e6e372023-02-02 14:36:17 +000096 let artifacts = artifacts.execute_steps(input_values.iter()).unwrap();
Janis Danisevskisda092a12021-11-17 22:58:16 -080097 let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
98 let from_former = diced_utils::make_bcc_handover(
99 cdi_attest[..].try_into().unwrap(),
100 cdi_seal[..].try_into().unwrap(),
101 &bcc,
102 )
103 .unwrap();
104 // TODO b/204938506 when we have a parser/verifier, check equivalence rather
105 // than bit by bit equality.
106 assert_eq!(latter, from_former);
107}
108
109fn client_input_values(uid: uid_t) -> BinderInputValues {
Alice Wang9c40eca2023-02-03 13:10:24 +0000110 let desc = CString::new(format!("{}", uid)).unwrap();
Janis Danisevskisda092a12021-11-17 22:58:16 -0800111 BinderInputValues {
Janis Danisevskisd9513f42021-12-16 17:15:13 -0800112 codeHash: [0; dice::HASH_SIZE],
Janis Danisevskisda092a12021-11-17 22:58:16 -0800113 config: BinderConfig {
Alice Wang9c40eca2023-02-03 13:10:24 +0000114 desc: dice::retry_bcc_format_config_descriptor(Some(desc.as_c_str()), None, true)
Janis Danisevskisda092a12021-11-17 22:58:16 -0800115 .unwrap(),
116 },
Janis Danisevskisd9513f42021-12-16 17:15:13 -0800117 authorityHash: [0; dice::HASH_SIZE],
Janis Danisevskisda092a12021-11-17 22:58:16 -0800118 authorityDescriptor: None,
119 mode: BinderMode::NORMAL,
Janis Danisevskisd9513f42021-12-16 17:15:13 -0800120 hidden: [0; dice::HIDDEN_SIZE],
Janis Danisevskisda092a12021-11-17 22:58:16 -0800121 }
122}
123
124// This test calls derive with an empty argument vector `former` which look like this:
125// <common root> | <caller>
126// It then demotes diced using a set of three input values prefixed with the uid based input
127// values that diced would add to any call. It then calls derive with empty argument vector
128// again which will add another step using the identity of the caller. If diced was demoted
129// correctly the chain of `latter` will
130// look as follows:
131// <common root> | <caller> | <the three sample inputs> | <caller>
132//
133// It then performs the same three derivation steps followed by a set of caller input values
134// on `former` and compares it to `latter`.
135fn demote_self_test() {
136 let maintenance = get_dice_maintenance();
137 let node = get_dice_node();
138 let input_values = diced_sample_inputs::get_input_values_vector();
139 let former = node.derive(&[]).expect("Trying to call derive.");
140
141 let client = client_input_values(nix::unistd::getuid().into());
142
143 let mut demote_vector = vec![client.clone()];
144 demote_vector.append(&mut input_values.clone());
145 maintenance.demoteSelf(&demote_vector).expect("Trying to call demote_self with input values.");
146
147 let latter = node.derive(&[]).expect("Trying to call derive after demote.");
148
149 let artifacts = diced_utils::ResidentArtifacts::new(
150 former.cdiAttest[..].try_into().unwrap(),
151 former.cdiSeal[..].try_into().unwrap(),
152 &former.bcc.data,
153 )
154 .unwrap();
155
156 let client = [client];
Janis Danisevskisda092a12021-11-17 22:58:16 -0800157
Alice Wang93e6e372023-02-02 14:36:17 +0000158 let artifacts = artifacts.execute_steps(input_values.iter().chain(client.iter())).unwrap();
Janis Danisevskisda092a12021-11-17 22:58:16 -0800159 let (cdi_attest, cdi_seal, bcc) = artifacts.into_tuple();
160 let from_former = diced_utils::make_bcc_handover(
161 cdi_attest[..].try_into().unwrap(),
162 cdi_seal[..].try_into().unwrap(),
163 &bcc,
164 )
165 .unwrap();
166 // TODO b/204938506 when we have a parser/verifier, check equivalence rather
167 // than bit by bit equality.
168 assert_eq!(latter, from_former);
169}
170
171#[test]
172fn run_serialized_test() {
173 equivalence_test();
174 sign_and_verify();
175 // The demote self test must run before the demote test or the test fails.
176 // And since demotion is not reversible the test can only pass once per boot.
177 demote_self_test();
178 demote_test();
179}