Secretkeeper: add AuthGraph key exchange

Add `ISecretkeeper::getAuthGraphKe()` method to the Secretkeeper HAL.

Align the AIDL targets between AuthGraph and Secretkeeper, and add
some defaults that automatically link to the current version of the
Secretkeeper AIDL targets.

Move the non-secure implementation of AuthGraph to run the TA in a
separate thread.

Alter the nonsecure implementation of Secretkeeper so that it no longer
directly implements Secretkeeper functionality, but instead re-uses
common code from the Secretkeeper reference implementation.  This
involves re-using the common implementation of the HAL service (from
`authgraph_hal`), but also involves using the reference implementation
of the the TA code that would normally run in a separate secure
environment.  The latter code expects to run in a single-threaded
environment, so run it in a single local thread.

Note that the negotiated session keys emitted by AuthGraph are not yet
used by Secretkeeper (coming in a subsequent CL).

Extend the Secretkeeper VTS tests to invoke the AuthGraph VTS inner
tests on the returned IAuthGraphKeyExchange instance, exercising the
instance as an AuthGraph sink.

Bug: 291228560
Test: VtsSecretkeeperTargetTest
Change-Id: Ia2c97976edc4530b2c902d95a74f3c340d342174
diff --git a/security/authgraph/default/src/fuzzer.rs b/security/authgraph/default/src/fuzzer.rs
index d401777..387d72f 100644
--- a/security/authgraph/default/src/fuzzer.rs
+++ b/security/authgraph/default/src/fuzzer.rs
@@ -22,10 +22,9 @@
 use authgraph_nonsecure::LocalTa;
 use binder_random_parcel_rs::fuzz_service;
 use libfuzzer_sys::fuzz_target;
-use std::sync::{Arc, Mutex};
 
 fuzz_target!(|data: &[u8]| {
     let local_ta = LocalTa::new().expect("Failed to create an AuthGraph local TA.");
-    let service = AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
+    let service = AuthGraphService::new_as_binder(local_ta);
     fuzz_service(&mut service.as_binder(), data);
 });
diff --git a/security/authgraph/default/src/lib.rs b/security/authgraph/default/src/lib.rs
index 14741aa..1f851b2 100644
--- a/security/authgraph/default/src/lib.rs
+++ b/security/authgraph/default/src/lib.rs
@@ -22,36 +22,62 @@
     ta::{AuthGraphTa, Role},
 };
 use authgraph_hal::channel::SerializedChannel;
-use std::sync::{Arc, Mutex};
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::sync::{mpsc, Mutex};
 
 /// Implementation of the AuthGraph TA that runs locally in-process (and which is therefore
 /// insecure).
 pub struct LocalTa {
-    ta: Arc<Mutex<AuthGraphTa>>,
+    channels: Mutex<Channels>,
+}
+
+struct Channels {
+    in_tx: mpsc::Sender<Vec<u8>>,
+    out_rx: mpsc::Receiver<Vec<u8>>,
 }
 
 impl LocalTa {
     /// Create a new instance.
     pub fn new() -> Result<Self, error::Error> {
-        Ok(Self {
-            ta: Arc::new(Mutex::new(AuthGraphTa::new(
+        // Create a pair of channels to communicate with the TA thread.
+        let (in_tx, in_rx) = mpsc::channel();
+        let (out_tx, out_rx) = mpsc::channel();
+
+        // The TA code expects to run single threaded, so spawn a thread to run it in.
+        std::thread::spawn(move || {
+            let mut ta = AuthGraphTa::new(
                 keyexchange::AuthGraphParticipant::new(
                     boring::crypto_trait_impls(),
-                    Box::<boring::test_device::AgDevice>::default(),
+                    Rc::new(RefCell::new(boring::test_device::AgDevice::default())),
                     keyexchange::MAX_OPENED_SESSIONS,
-                )?,
+                )
+                .expect("failed to create AG participant"),
                 Role::Both,
-            ))),
+            );
+            // Loop forever processing request messages.
+            loop {
+                let req_data: Vec<u8> = in_rx.recv().expect("failed to receive next req");
+                let rsp_data = ta.process(&req_data);
+                out_tx.send(rsp_data).expect("failed to send out rsp");
+            }
+        });
+        Ok(Self {
+            channels: Mutex::new(Channels { in_tx, out_rx }),
         })
     }
 }
 
-/// Pretend to be a serialized channel to the TA, but actually just directly invoke the TA with
-/// incoming requests.
 impl SerializedChannel for LocalTa {
     const MAX_SIZE: usize = usize::MAX;
 
-    fn execute(&mut self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
-        Ok(self.ta.lock().unwrap().process(req_data))
+    fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
+        // Serialize across both request and response.
+        let channels = self.channels.lock().unwrap();
+        channels
+            .in_tx
+            .send(req_data.to_vec())
+            .expect("failed to send in request");
+        Ok(channels.out_rx.recv().expect("failed to receive response"))
     }
 }
diff --git a/security/authgraph/default/src/main.rs b/security/authgraph/default/src/main.rs
index 81f2dd6..ced7567 100644
--- a/security/authgraph/default/src/main.rs
+++ b/security/authgraph/default/src/main.rs
@@ -25,7 +25,6 @@
 use authgraph_hal::service;
 use authgraph_nonsecure::LocalTa;
 use log::{error, info};
-use std::sync::{Arc, Mutex};
 
 static SERVICE_NAME: &str = "android.hardware.security.authgraph.IAuthGraphKeyExchange";
 static SERVICE_INSTANCE: &str = "nonsecure";
@@ -65,9 +64,8 @@
     binder::ProcessState::start_thread_pool();
 
     // Register the service
-    let local_ta =
-        LocalTa::new().map_err(|e| format!("Failed to create the TA because: {e:?}"))?;
-    let service = service::AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
+    let local_ta = LocalTa::new().map_err(|e| format!("Failed to create the TA because: {e:?}"))?;
+    let service = service::AuthGraphService::new_as_binder(local_ta);
     let service_name = format!("{}/{}", SERVICE_NAME, SERVICE_INSTANCE);
     binder::add_service(&service_name, service.as_binder()).map_err(|e| {
         format!(