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