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