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