Diced: Implement HAL proxy node and initialize it in diced_main.
Still using sample artifacts if no HAL was found.
Test: diced_client_test
Bug: 198197213
Change-Id: I2d218f04cd53a6177dddd3e984879832287bd4dc
diff --git a/diced/src/proxy_node_hal.rs b/diced/src/proxy_node_hal.rs
new file mode 100644
index 0000000..3f31419
--- /dev/null
+++ b/diced/src/proxy_node_hal.rs
@@ -0,0 +1,119 @@
+// Copyright 2021, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! A proxy dice node delegates all accesses to CDI_attest and CDI_seal to a parent
+//! node, here an implementation of android.hardware.security.dice.IDiceDevice.
+
+#![allow(dead_code)]
+
+use crate::DiceNodeImpl;
+use android_hardware_security_dice::aidl::android::hardware::security::dice::{
+ Bcc::Bcc, BccHandover::BccHandover, IDiceDevice::IDiceDevice,
+ InputValues::InputValues as BinderInputValues, Signature::Signature,
+};
+use anyhow::{Context, Result};
+use binder::public_api::Strong;
+use std::collections::HashMap;
+use std::sync::RwLock;
+
+/// The ProxyNodeHal implements a IDiceNode backend delegating crypto operations
+/// to the corresponding HAL.
+pub struct ProxyNodeHal {
+ parent: Strong<dyn IDiceDevice>,
+ demotion_db: RwLock<HashMap<BinderInputValues, Vec<BinderInputValues>>>,
+}
+
+impl ProxyNodeHal {
+ /// Creates a new proxy node with a reference to the parent service.
+ pub fn new(parent: Strong<dyn IDiceDevice>) -> Result<Self> {
+ Ok(ProxyNodeHal { parent, demotion_db: Default::default() })
+ }
+
+ fn get_effective_input_values(
+ &self,
+ client: BinderInputValues,
+ input_values: &[BinderInputValues],
+ ) -> Vec<BinderInputValues> {
+ let demotion_db = self.demotion_db.read().unwrap();
+
+ let client_arr = [client];
+
+ demotion_db
+ .get(&client_arr[0])
+ .map(|v| v.iter())
+ .unwrap_or_else(|| client_arr.iter())
+ .chain(input_values.iter())
+ .cloned()
+ .collect()
+ }
+}
+
+impl DiceNodeImpl for ProxyNodeHal {
+ fn sign(
+ &self,
+ client: BinderInputValues,
+ input_values: &[BinderInputValues],
+ message: &[u8],
+ ) -> Result<Signature> {
+ self.parent
+ .sign(&self.get_effective_input_values(client, input_values), message)
+ .context("In ProxyNodeHal::sign:")
+ }
+
+ fn get_attestation_chain(
+ &self,
+ client: BinderInputValues,
+ input_values: &[BinderInputValues],
+ ) -> Result<Bcc> {
+ self.parent
+ .getAttestationChain(&self.get_effective_input_values(client, input_values))
+ .context("In ProxyNodeHal::get_attestation_chain:")
+ }
+
+ fn derive(
+ &self,
+ client: BinderInputValues,
+ input_values: &[BinderInputValues],
+ ) -> Result<BccHandover> {
+ self.parent
+ .derive(&self.get_effective_input_values(client, input_values))
+ .context("In ProxyNodeHal::derive:")
+ }
+
+ fn demote(&self, client: BinderInputValues, input_values: &[BinderInputValues]) -> Result<()> {
+ let mut demotion_db = self.demotion_db.write().unwrap();
+
+ let client_arr = [client];
+
+ // The following statement consults demotion database which yields an optional demotion
+ // path. It then constructs an iterator over the following elements, then clones and
+ // collects them into a new vector:
+ // [ demotion path | client ], input_values
+ let new_path: Vec<BinderInputValues> = demotion_db
+ .get(&client_arr[0])
+ .map(|v| v.iter())
+ .unwrap_or_else(|| client_arr.iter())
+ .chain(input_values)
+ .cloned()
+ .collect();
+
+ let [client] = client_arr;
+ demotion_db.insert(client, new_path);
+ Ok(())
+ }
+
+ fn demote_self(&self, input_values: &[BinderInputValues]) -> Result<()> {
+ self.parent.demote(input_values).context("In ProxyNodeHal::demote_self:")
+ }
+}