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