xref: /aosp_15_r20/hardware/interfaces/security/secretkeeper/default/src/lib.rs (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2023 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker //! Non-secure implementation of a local Secretkeeper TA.
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker use authgraph_boringssl as boring;
20*4d7e907cSAndroid Build Coastguard Worker use authgraph_core::keyexchange::{AuthGraphParticipant, MAX_OPENED_SESSIONS};
21*4d7e907cSAndroid Build Coastguard Worker use authgraph_core::ta::{AuthGraphTa, Role};
22*4d7e907cSAndroid Build Coastguard Worker use authgraph_hal::channel::SerializedChannel;
23*4d7e907cSAndroid Build Coastguard Worker use log::error;
24*4d7e907cSAndroid Build Coastguard Worker use secretkeeper_core::ta::SecretkeeperTa;
25*4d7e907cSAndroid Build Coastguard Worker use std::cell::RefCell;
26*4d7e907cSAndroid Build Coastguard Worker use std::rc::Rc;
27*4d7e907cSAndroid Build Coastguard Worker use std::sync::mpsc;
28*4d7e907cSAndroid Build Coastguard Worker use std::sync::{Arc, Mutex};
29*4d7e907cSAndroid Build Coastguard Worker 
30*4d7e907cSAndroid Build Coastguard Worker mod store;
31*4d7e907cSAndroid Build Coastguard Worker 
32*4d7e907cSAndroid Build Coastguard Worker /// Implementation of the Secrekeeper TA that runs locally in-process (and which is therefore
33*4d7e907cSAndroid Build Coastguard Worker /// insecure).
34*4d7e907cSAndroid Build Coastguard Worker pub struct LocalTa {
35*4d7e907cSAndroid Build Coastguard Worker     in_tx: mpsc::Sender<Vec<u8>>,
36*4d7e907cSAndroid Build Coastguard Worker     out_rx: mpsc::Receiver<Vec<u8>>,
37*4d7e907cSAndroid Build Coastguard Worker }
38*4d7e907cSAndroid Build Coastguard Worker 
39*4d7e907cSAndroid Build Coastguard Worker /// Prefix byte for messages intended for the AuthGraph TA.
40*4d7e907cSAndroid Build Coastguard Worker const AG_MESSAGE_PREFIX: u8 = 0x00;
41*4d7e907cSAndroid Build Coastguard Worker /// Prefix byte for messages intended for the Secretkeeper TA.
42*4d7e907cSAndroid Build Coastguard Worker const SK_MESSAGE_PREFIX: u8 = 0x01;
43*4d7e907cSAndroid Build Coastguard Worker 
44*4d7e907cSAndroid Build Coastguard Worker impl LocalTa {
45*4d7e907cSAndroid Build Coastguard Worker     /// Create a new instance.
new() -> Self46*4d7e907cSAndroid Build Coastguard Worker     pub fn new() -> Self {
47*4d7e907cSAndroid Build Coastguard Worker         // Create a pair of channels to communicate with the TA thread.
48*4d7e907cSAndroid Build Coastguard Worker         let (in_tx, in_rx) = mpsc::channel();
49*4d7e907cSAndroid Build Coastguard Worker         let (out_tx, out_rx) = mpsc::channel();
50*4d7e907cSAndroid Build Coastguard Worker 
51*4d7e907cSAndroid Build Coastguard Worker         // The TA code expects to run single threaded, so spawn a thread to run it in.
52*4d7e907cSAndroid Build Coastguard Worker         std::thread::spawn(move || {
53*4d7e907cSAndroid Build Coastguard Worker             let mut crypto_impls = boring::crypto_trait_impls();
54*4d7e907cSAndroid Build Coastguard Worker             let storage_impl = Box::new(store::InMemoryStore::default());
55*4d7e907cSAndroid Build Coastguard Worker             let sk_ta = Rc::new(RefCell::new(
56*4d7e907cSAndroid Build Coastguard Worker                 SecretkeeperTa::new(
57*4d7e907cSAndroid Build Coastguard Worker                     &mut crypto_impls,
58*4d7e907cSAndroid Build Coastguard Worker                     storage_impl,
59*4d7e907cSAndroid Build Coastguard Worker                     coset::iana::EllipticCurve::Ed25519,
60*4d7e907cSAndroid Build Coastguard Worker                 )
61*4d7e907cSAndroid Build Coastguard Worker                 .expect("Failed to create local Secretkeeper TA"),
62*4d7e907cSAndroid Build Coastguard Worker             ));
63*4d7e907cSAndroid Build Coastguard Worker             let mut ag_ta = AuthGraphTa::new(
64*4d7e907cSAndroid Build Coastguard Worker                 AuthGraphParticipant::new(crypto_impls, sk_ta.clone(), MAX_OPENED_SESSIONS)
65*4d7e907cSAndroid Build Coastguard Worker                     .expect("Failed to create local AuthGraph TA"),
66*4d7e907cSAndroid Build Coastguard Worker                 Role::Sink,
67*4d7e907cSAndroid Build Coastguard Worker             );
68*4d7e907cSAndroid Build Coastguard Worker 
69*4d7e907cSAndroid Build Coastguard Worker             // Loop forever processing request messages.
70*4d7e907cSAndroid Build Coastguard Worker             loop {
71*4d7e907cSAndroid Build Coastguard Worker                 let req_data: Vec<u8> = match in_rx.recv() {
72*4d7e907cSAndroid Build Coastguard Worker                     Ok(data) => data,
73*4d7e907cSAndroid Build Coastguard Worker                     Err(_) => {
74*4d7e907cSAndroid Build Coastguard Worker                         error!("local TA failed to receive request!");
75*4d7e907cSAndroid Build Coastguard Worker                         break;
76*4d7e907cSAndroid Build Coastguard Worker                     }
77*4d7e907cSAndroid Build Coastguard Worker                 };
78*4d7e907cSAndroid Build Coastguard Worker                 let rsp_data = match req_data[0] {
79*4d7e907cSAndroid Build Coastguard Worker                     AG_MESSAGE_PREFIX => ag_ta.process(&req_data[1..]),
80*4d7e907cSAndroid Build Coastguard Worker                     SK_MESSAGE_PREFIX => {
81*4d7e907cSAndroid Build Coastguard Worker                         // It's safe to `borrow_mut()` because this code is not a callback
82*4d7e907cSAndroid Build Coastguard Worker                         // from AuthGraph (the only other holder of an `Rc`), and so there
83*4d7e907cSAndroid Build Coastguard Worker                         // can be no live `borrow()`s in this (single) thread.
84*4d7e907cSAndroid Build Coastguard Worker                         sk_ta.borrow_mut().process(&req_data[1..])
85*4d7e907cSAndroid Build Coastguard Worker                     }
86*4d7e907cSAndroid Build Coastguard Worker                     prefix => panic!("unexpected messageprefix {prefix}!"),
87*4d7e907cSAndroid Build Coastguard Worker                 };
88*4d7e907cSAndroid Build Coastguard Worker                 match out_tx.send(rsp_data) {
89*4d7e907cSAndroid Build Coastguard Worker                     Ok(_) => {}
90*4d7e907cSAndroid Build Coastguard Worker                     Err(_) => {
91*4d7e907cSAndroid Build Coastguard Worker                         error!("local TA failed to send out response");
92*4d7e907cSAndroid Build Coastguard Worker                         break;
93*4d7e907cSAndroid Build Coastguard Worker                     }
94*4d7e907cSAndroid Build Coastguard Worker                 }
95*4d7e907cSAndroid Build Coastguard Worker             }
96*4d7e907cSAndroid Build Coastguard Worker             error!("local TA terminating!");
97*4d7e907cSAndroid Build Coastguard Worker         });
98*4d7e907cSAndroid Build Coastguard Worker         Self { in_tx, out_rx }
99*4d7e907cSAndroid Build Coastguard Worker     }
100*4d7e907cSAndroid Build Coastguard Worker 
execute_for(&mut self, prefix: u8, req_data: &[u8]) -> Vec<u8>101*4d7e907cSAndroid Build Coastguard Worker     fn execute_for(&mut self, prefix: u8, req_data: &[u8]) -> Vec<u8> {
102*4d7e907cSAndroid Build Coastguard Worker         let mut prefixed_req = Vec::with_capacity(req_data.len() + 1);
103*4d7e907cSAndroid Build Coastguard Worker         prefixed_req.push(prefix);
104*4d7e907cSAndroid Build Coastguard Worker         prefixed_req.extend_from_slice(req_data);
105*4d7e907cSAndroid Build Coastguard Worker         self.in_tx
106*4d7e907cSAndroid Build Coastguard Worker             .send(prefixed_req)
107*4d7e907cSAndroid Build Coastguard Worker             .expect("failed to send in request");
108*4d7e907cSAndroid Build Coastguard Worker         self.out_rx.recv().expect("failed to receive response")
109*4d7e907cSAndroid Build Coastguard Worker     }
110*4d7e907cSAndroid Build Coastguard Worker }
111*4d7e907cSAndroid Build Coastguard Worker 
112*4d7e907cSAndroid Build Coastguard Worker pub struct AuthGraphChannel(pub Arc<Mutex<LocalTa>>);
113*4d7e907cSAndroid Build Coastguard Worker 
114*4d7e907cSAndroid Build Coastguard Worker impl SerializedChannel for AuthGraphChannel {
115*4d7e907cSAndroid Build Coastguard Worker     const MAX_SIZE: usize = usize::MAX;
execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>>116*4d7e907cSAndroid Build Coastguard Worker     fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
117*4d7e907cSAndroid Build Coastguard Worker         Ok(self
118*4d7e907cSAndroid Build Coastguard Worker             .0
119*4d7e907cSAndroid Build Coastguard Worker             .lock()
120*4d7e907cSAndroid Build Coastguard Worker             .unwrap()
121*4d7e907cSAndroid Build Coastguard Worker             .execute_for(AG_MESSAGE_PREFIX, req_data))
122*4d7e907cSAndroid Build Coastguard Worker     }
123*4d7e907cSAndroid Build Coastguard Worker }
124*4d7e907cSAndroid Build Coastguard Worker 
125*4d7e907cSAndroid Build Coastguard Worker pub struct SecretkeeperChannel(pub Arc<Mutex<LocalTa>>);
126*4d7e907cSAndroid Build Coastguard Worker 
127*4d7e907cSAndroid Build Coastguard Worker impl SerializedChannel for SecretkeeperChannel {
128*4d7e907cSAndroid Build Coastguard Worker     const MAX_SIZE: usize = usize::MAX;
execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>>129*4d7e907cSAndroid Build Coastguard Worker     fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
130*4d7e907cSAndroid Build Coastguard Worker         Ok(self
131*4d7e907cSAndroid Build Coastguard Worker             .0
132*4d7e907cSAndroid Build Coastguard Worker             .lock()
133*4d7e907cSAndroid Build Coastguard Worker             .unwrap()
134*4d7e907cSAndroid Build Coastguard Worker             .execute_for(SK_MESSAGE_PREFIX, req_data))
135*4d7e907cSAndroid Build Coastguard Worker     }
136*4d7e907cSAndroid Build Coastguard Worker }
137