xref: /aosp_15_r20/hardware/interfaces/security/authgraph/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 //! Common functionality for non-secure/testing instance of AuthGraph.
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker use authgraph_boringssl as boring;
20*4d7e907cSAndroid Build Coastguard Worker use authgraph_core::{
21*4d7e907cSAndroid Build Coastguard Worker     error, keyexchange,
22*4d7e907cSAndroid Build Coastguard Worker     ta::{AuthGraphTa, Role},
23*4d7e907cSAndroid Build Coastguard Worker };
24*4d7e907cSAndroid Build Coastguard Worker use authgraph_hal::channel::SerializedChannel;
25*4d7e907cSAndroid Build Coastguard Worker use log::error;
26*4d7e907cSAndroid Build Coastguard Worker use std::cell::RefCell;
27*4d7e907cSAndroid Build Coastguard Worker use std::rc::Rc;
28*4d7e907cSAndroid Build Coastguard Worker use std::sync::{mpsc, Mutex};
29*4d7e907cSAndroid Build Coastguard Worker 
30*4d7e907cSAndroid Build Coastguard Worker /// Implementation of the AuthGraph TA that runs locally in-process (and which is therefore
31*4d7e907cSAndroid Build Coastguard Worker /// insecure).
32*4d7e907cSAndroid Build Coastguard Worker pub struct LocalTa {
33*4d7e907cSAndroid Build Coastguard Worker     channels: Mutex<Channels>,
34*4d7e907cSAndroid Build Coastguard Worker }
35*4d7e907cSAndroid Build Coastguard Worker 
36*4d7e907cSAndroid Build Coastguard Worker struct Channels {
37*4d7e907cSAndroid Build Coastguard Worker     in_tx: mpsc::Sender<Vec<u8>>,
38*4d7e907cSAndroid Build Coastguard Worker     out_rx: mpsc::Receiver<Vec<u8>>,
39*4d7e907cSAndroid Build Coastguard Worker }
40*4d7e907cSAndroid Build Coastguard Worker 
41*4d7e907cSAndroid Build Coastguard Worker impl LocalTa {
42*4d7e907cSAndroid Build Coastguard Worker     /// Create a new instance.
new() -> Result<Self, error::Error>43*4d7e907cSAndroid Build Coastguard Worker     pub fn new() -> Result<Self, error::Error> {
44*4d7e907cSAndroid Build Coastguard Worker         // Create a pair of channels to communicate with the TA thread.
45*4d7e907cSAndroid Build Coastguard Worker         let (in_tx, in_rx) = mpsc::channel();
46*4d7e907cSAndroid Build Coastguard Worker         let (out_tx, out_rx) = mpsc::channel();
47*4d7e907cSAndroid Build Coastguard Worker 
48*4d7e907cSAndroid Build Coastguard Worker         // The TA code expects to run single threaded, so spawn a thread to run it in.
49*4d7e907cSAndroid Build Coastguard Worker         std::thread::spawn(move || {
50*4d7e907cSAndroid Build Coastguard Worker             let mut ta = AuthGraphTa::new(
51*4d7e907cSAndroid Build Coastguard Worker                 keyexchange::AuthGraphParticipant::new(
52*4d7e907cSAndroid Build Coastguard Worker                     boring::crypto_trait_impls(),
53*4d7e907cSAndroid Build Coastguard Worker                     Rc::new(RefCell::new(boring::test_device::AgDevice::default())),
54*4d7e907cSAndroid Build Coastguard Worker                     keyexchange::MAX_OPENED_SESSIONS,
55*4d7e907cSAndroid Build Coastguard Worker                 )
56*4d7e907cSAndroid Build Coastguard Worker                 .expect("failed to create AG participant"),
57*4d7e907cSAndroid Build Coastguard Worker                 Role::Both,
58*4d7e907cSAndroid Build Coastguard Worker             );
59*4d7e907cSAndroid Build Coastguard Worker             // Loop forever processing request messages.
60*4d7e907cSAndroid Build Coastguard Worker             loop {
61*4d7e907cSAndroid Build Coastguard Worker                 let req_data: Vec<u8> = match in_rx.recv() {
62*4d7e907cSAndroid Build Coastguard Worker                     Ok(data) => data,
63*4d7e907cSAndroid Build Coastguard Worker                     Err(_) => {
64*4d7e907cSAndroid Build Coastguard Worker                         error!("local TA failed to receive request!");
65*4d7e907cSAndroid Build Coastguard Worker                         break;
66*4d7e907cSAndroid Build Coastguard Worker                     }
67*4d7e907cSAndroid Build Coastguard Worker                 };
68*4d7e907cSAndroid Build Coastguard Worker                 let rsp_data = ta.process(&req_data);
69*4d7e907cSAndroid Build Coastguard Worker                 match out_tx.send(rsp_data) {
70*4d7e907cSAndroid Build Coastguard Worker                     Ok(_) => {}
71*4d7e907cSAndroid Build Coastguard Worker                     Err(_) => {
72*4d7e907cSAndroid Build Coastguard Worker                         error!("local TA failed to send out response");
73*4d7e907cSAndroid Build Coastguard Worker                         break;
74*4d7e907cSAndroid Build Coastguard Worker                     }
75*4d7e907cSAndroid Build Coastguard Worker                 }
76*4d7e907cSAndroid Build Coastguard Worker             }
77*4d7e907cSAndroid Build Coastguard Worker             error!("local TA terminating!");
78*4d7e907cSAndroid Build Coastguard Worker         });
79*4d7e907cSAndroid Build Coastguard Worker         Ok(Self {
80*4d7e907cSAndroid Build Coastguard Worker             channels: Mutex::new(Channels { in_tx, out_rx }),
81*4d7e907cSAndroid Build Coastguard Worker         })
82*4d7e907cSAndroid Build Coastguard Worker     }
83*4d7e907cSAndroid Build Coastguard Worker }
84*4d7e907cSAndroid Build Coastguard Worker 
85*4d7e907cSAndroid Build Coastguard Worker impl SerializedChannel for LocalTa {
86*4d7e907cSAndroid Build Coastguard Worker     const MAX_SIZE: usize = usize::MAX;
87*4d7e907cSAndroid Build Coastguard Worker 
execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>>88*4d7e907cSAndroid Build Coastguard Worker     fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
89*4d7e907cSAndroid Build Coastguard Worker         // Serialize across both request and response.
90*4d7e907cSAndroid Build Coastguard Worker         let channels = self.channels.lock().unwrap();
91*4d7e907cSAndroid Build Coastguard Worker         channels
92*4d7e907cSAndroid Build Coastguard Worker             .in_tx
93*4d7e907cSAndroid Build Coastguard Worker             .send(req_data.to_vec())
94*4d7e907cSAndroid Build Coastguard Worker             .expect("failed to send in request");
95*4d7e907cSAndroid Build Coastguard Worker         Ok(channels.out_rx.recv().expect("failed to receive response"))
96*4d7e907cSAndroid Build Coastguard Worker     }
97*4d7e907cSAndroid Build Coastguard Worker }
98