blob: eb7817c5583bb0d95bb43dd2d38e59d472abc681 [file] [log] [blame]
David Drysdalec3aa4422023-12-18 16:29:18 +00001/*
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
19use authgraph_boringssl as boring;
20use authgraph_core::keyexchange::{AuthGraphParticipant, MAX_OPENED_SESSIONS};
21use authgraph_core::ta::{AuthGraphTa, Role};
22use authgraph_hal::channel::SerializedChannel;
23use log::error;
24use secretkeeper_core::ta::SecretkeeperTa;
25use std::cell::RefCell;
26use std::rc::Rc;
27use std::sync::mpsc;
28use std::sync::{Arc, Mutex};
29
30mod store;
31
32/// Implementation of the Secrekeeper TA that runs locally in-process (and which is therefore
33/// insecure).
34pub 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.
40const AG_MESSAGE_PREFIX: u8 = 0x00;
41/// Prefix byte for messages intended for the Secretkeeper TA.
42const SK_MESSAGE_PREFIX: u8 = 0x01;
43
44impl LocalTa {
45 /// Create a new instance.
46 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(
David Drysdale38859772024-01-09 15:12:31 +000056 SecretkeeperTa::new(
57 &mut crypto_impls,
58 storage_impl,
59 coset::iana::EllipticCurve::Ed25519,
60 )
61 .expect("Failed to create local Secretkeeper TA"),
David Drysdalec3aa4422023-12-18 16:29:18 +000062 ));
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
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
112pub struct AuthGraphChannel(pub Arc<Mutex<LocalTa>>);
113
114impl SerializedChannel for AuthGraphChannel {
115 const MAX_SIZE: usize = usize::MAX;
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
125pub struct SecretkeeperChannel(pub Arc<Mutex<LocalTa>>);
126
127impl SerializedChannel for SecretkeeperChannel {
128 const MAX_SIZE: usize = usize::MAX;
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}