diff --git a/security/authgraph/default/Android.bp b/security/authgraph/default/Android.bp
index c0f2106..ac67136 100644
--- a/security/authgraph/default/Android.bp
+++ b/security/authgraph/default/Android.bp
@@ -22,6 +22,26 @@
     default_applicable_licenses: ["hardware_interfaces_license"],
 }
 
+rust_library {
+    name: "libauthgraph_nonsecure",
+    crate_name: "authgraph_nonsecure",
+    defaults: [
+        "authgraph_use_latest_hal_aidl_rust",
+    ],
+    vendor_available: true,
+    rustlibs: [
+        "libandroid_logger",
+        "libauthgraph_boringssl",
+        "libauthgraph_core",
+        "libauthgraph_hal",
+        "libbinder_rs",
+        "liblibc",
+        "liblog_rust",
+    ],
+    srcs: ["src/lib.rs"],
+
+}
+
 rust_binary {
     name: "android.hardware.security.authgraph-service.nonsecure",
     relative_install_path: "hw",
@@ -33,10 +53,8 @@
     ],
     rustlibs: [
         "libandroid_logger",
-        "libauthgraph_core",
-        "libauthgraph_boringssl",
         "libauthgraph_hal",
-        "libauthgraph_wire",
+        "libauthgraph_nonsecure",
         "libbinder_rs",
         "liblibc",
         "liblog_rust",
diff --git a/security/authgraph/default/src/lib.rs b/security/authgraph/default/src/lib.rs
new file mode 100644
index 0000000..4cd0cb7
--- /dev/null
+++ b/security/authgraph/default/src/lib.rs
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Common functionality for non-secure/testing instance of AuthGraph.
+
+use authgraph_boringssl as boring;
+use authgraph_core::{
+    key::MillisecondsSinceEpoch,
+    ta::{AuthGraphTa, Role},
+    traits,
+};
+use authgraph_hal::channel::SerializedChannel;
+use std::sync::{Arc, Mutex};
+use std::time::Instant;
+
+/// Monotonic clock with an epoch that starts at the point of construction.
+/// (This makes it unsuitable for use outside of testing, because the epoch
+/// will not match that of any other component.)
+pub struct StdClock(Instant);
+
+impl Default for StdClock {
+    fn default() -> Self {
+        Self(Instant::now())
+    }
+}
+
+impl traits::MonotonicClock for StdClock {
+    fn now(&self) -> MillisecondsSinceEpoch {
+        let millis: i64 = self
+            .0
+            .elapsed()
+            .as_millis()
+            .try_into()
+            .expect("failed to fit timestamp in i64");
+        MillisecondsSinceEpoch(millis)
+    }
+}
+
+/// Implementation of the AuthGraph TA that runs locally in-process (and which is therefore
+/// insecure).
+pub struct LocalTa {
+    ta: Arc<Mutex<AuthGraphTa>>,
+}
+
+impl LocalTa {
+    /// Create a new instance.
+    pub fn new() -> Self {
+        Self {
+            ta: Arc::new(Mutex::new(AuthGraphTa::new(
+                boring::trait_impls(
+                    Box::<boring::test_device::AgDevice>::default(),
+                    Some(Box::new(StdClock::default())),
+                ),
+                Role::Both,
+            ))),
+        }
+    }
+}
+
+/// 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))
+    }
+}
diff --git a/security/authgraph/default/src/main.rs b/security/authgraph/default/src/main.rs
index dc4a8e4..873eb4e 100644
--- a/security/authgraph/default/src/main.rs
+++ b/security/authgraph/default/src/main.rs
@@ -22,18 +22,10 @@
 //! expose an entrypoint that allowed retrieval of the specific IAuthGraphKeyExchange instance that
 //! is correlated with the component).
 
-use android_hardware_security_authgraph::aidl::android::hardware::security::authgraph::{
-    Arc::Arc, IAuthGraphKeyExchange::BnAuthGraphKeyExchange,
-    IAuthGraphKeyExchange::IAuthGraphKeyExchange, Identity::Identity, KeInitResult::KeInitResult,
-    Key::Key, PubKey::PubKey, SessionIdSignature::SessionIdSignature, SessionInfo::SessionInfo,
-    SessionInitiationInfo::SessionInitiationInfo,
-};
-use authgraph_boringssl as boring;
-use authgraph_core::{key::MillisecondsSinceEpoch, keyexchange as ke, traits};
-use authgraph_hal::{errcode_to_binder, Innto, TryInnto};
+use authgraph_hal::service;
+use authgraph_nonsecure::LocalTa;
 use log::{error, info};
-use std::ffi::CString;
-use std::sync::Mutex;
+use std::sync::{Arc, Mutex};
 
 static SERVICE_NAME: &str = "android.hardware.security.authgraph.IAuthGraphKeyExchange";
 static SERVICE_INSTANCE: &str = "nonsecure";
@@ -73,7 +65,8 @@
     binder::ProcessState::start_thread_pool();
 
     // Register the service
-    let service = AuthGraphService::new_as_binder();
+    let local_ta = LocalTa::new();
+    let service = service::AuthGraphService::new_as_binder(Arc::new(Mutex::new(local_ta)));
     let service_name = format!("{}/{}", SERVICE_NAME, SERVICE_INSTANCE);
     binder::add_service(&service_name, service.as_binder()).map_err(|e| {
         format!(
@@ -87,148 +80,3 @@
     info!("AuthGraph HAL service is terminating."); // should not reach here
     Ok(())
 }
-
-/// Non-secure implementation of the AuthGraph key exchange service.
-struct AuthGraphService {
-    imp: Mutex<traits::TraitImpl>,
-}
-
-impl AuthGraphService {
-    /// Create a new instance.
-    fn new() -> Self {
-        Self {
-            imp: Mutex::new(traits::TraitImpl {
-                aes_gcm: Box::new(boring::BoringAes),
-                ecdh: Box::new(boring::BoringEcDh),
-                ecdsa: Box::new(boring::BoringEcDsa),
-                hmac: Box::new(boring::BoringHmac),
-                hkdf: Box::new(boring::BoringHkdf),
-                sha256: Box::new(boring::BoringSha256),
-                rng: Box::new(boring::BoringRng),
-                device: Box::<boring::test_device::AgDevice>::default(),
-                clock: Some(Box::new(StdClock)),
-            }),
-        }
-    }
-
-    /// Create a new instance wrapped in a proxy object.
-    pub fn new_as_binder() -> binder::Strong<dyn IAuthGraphKeyExchange> {
-        BnAuthGraphKeyExchange::new_binder(Self::new(), binder::BinderFeatures::default())
-    }
-}
-
-impl binder::Interface for AuthGraphService {}
-
-/// Extract (and require) an unsigned public key as bytes from a [`PubKey`].
-fn unsigned_pub_key(pub_key: &PubKey) -> binder::Result<&[u8]> {
-    match pub_key {
-        PubKey::PlainKey(key) => Ok(&key.plainPubKey),
-        PubKey::SignedKey(_) => Err(binder::Status::new_exception(
-            binder::ExceptionCode::ILLEGAL_ARGUMENT,
-            Some(&CString::new("expected unsigned public key").unwrap()),
-        )),
-    }
-}
-
-fn err_to_binder(err: authgraph_core::error::Error) -> binder::Status {
-    if err.0 != authgraph_wire::ErrorCode::Ok && !err.1.is_empty() {
-        error!("failure {:?} message: '{}'", err.0, err.1);
-    }
-    errcode_to_binder(err.0)
-}
-
-/// This nonsecure implementation of the AuthGraph HAL interface directly calls the AuthGraph
-/// reference implementation library code; a real implementation requires the AuthGraph
-/// code to run in a secure environment, not within Android.
-impl IAuthGraphKeyExchange for AuthGraphService {
-    fn create(&self) -> binder::Result<SessionInitiationInfo> {
-        info!("create()");
-        let mut imp = self.imp.lock().unwrap();
-        let info = ke::create(&mut *imp).map_err(err_to_binder)?;
-        Ok(info.innto())
-    }
-    fn init(
-        &self,
-        peer_pub_key: &PubKey,
-        peer_id: &Identity,
-        peer_nonce: &[u8],
-        peer_version: i32,
-    ) -> binder::Result<KeInitResult> {
-        info!("init(v={peer_version})");
-        let mut imp = self.imp.lock().unwrap();
-        let peer_pub_key = unsigned_pub_key(peer_pub_key)?;
-        let result = ke::init(
-            &mut *imp,
-            peer_pub_key,
-            &peer_id.identity,
-            &peer_nonce,
-            peer_version,
-        )
-        .map_err(err_to_binder)?;
-        Ok(result.innto())
-    }
-
-    fn finish(
-        &self,
-        peer_pub_key: &PubKey,
-        peer_id: &Identity,
-        peer_signature: &SessionIdSignature,
-        peer_nonce: &[u8],
-        peer_version: i32,
-        own_key: &Key,
-    ) -> binder::Result<SessionInfo> {
-        info!("finish(v={peer_version})");
-        let mut imp = self.imp.lock().unwrap();
-        let peer_pub_key = unsigned_pub_key(peer_pub_key)?;
-        let own_key: Key = own_key.clone();
-        let own_key: authgraph_core::key::Key = own_key.try_innto()?;
-        let session_info = ke::finish(
-            &mut *imp,
-            peer_pub_key,
-            &peer_id.identity,
-            &peer_signature.signature,
-            &peer_nonce,
-            peer_version,
-            own_key,
-        )
-        .map_err(err_to_binder)?;
-        Ok(session_info.innto())
-    }
-
-    fn authenticationComplete(
-        &self,
-        peer_signature: &SessionIdSignature,
-        shared_keys: &[Arc; 2],
-    ) -> binder::Result<[Arc; 2]> {
-        info!("authComplete()");
-        let mut imp = self.imp.lock().unwrap();
-        let shared_keys = [shared_keys[0].arc.clone(), shared_keys[1].arc.clone()];
-        let arcs = ke::authentication_complete(&mut *imp, &peer_signature.signature, shared_keys)
-            .map_err(err_to_binder)?;
-        Ok(arcs.map(|arc| Arc { arc }))
-    }
-}
-
-/// Monotonic clock.
-#[derive(Default)]
-pub struct StdClock;
-
-impl traits::MonotonicClock for StdClock {
-    fn now(&self) -> authgraph_core::key::MillisecondsSinceEpoch {
-        let mut time = libc::timespec {
-            tv_sec: 0,  // libc::time_t
-            tv_nsec: 0, // libc::c_long
-        };
-        let rc =
-        // Safety: `time` is a valid structure.
-            unsafe { libc::clock_gettime(libc::CLOCK_BOOTTIME, &mut time as *mut libc::timespec) };
-        if rc < 0 {
-            log::warn!("failed to get time!");
-            return MillisecondsSinceEpoch(0);
-        }
-        // The types in `libc::timespec` may be different on different architectures,
-        // so allow conversion to `i64`.
-        #[allow(clippy::unnecessary_cast)]
-        MillisecondsSinceEpoch((time.tv_sec as i64 * 1000) + (time.tv_nsec as i64 / 1000 / 1000))
-    }
-}
