diff --git a/keystore2/src/apc.rs b/keystore2/src/apc.rs
new file mode 100644
index 0000000..105e071
--- /dev/null
+++ b/keystore2/src/apc.rs
@@ -0,0 +1,366 @@
+// Copyright 2020, 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.
+
+// TODO The confirmation token is yet unused.
+#![allow(unused_variables)]
+
+//! This module implements the Android Protected Confirmation (APC) service as defined
+//! in the android.security.apc AIDL spec.
+
+use std::{
+    cmp::PartialEq,
+    collections::HashMap,
+    sync::{Arc, Mutex},
+};
+
+use crate::utils::{compat_2_response_code, ui_opts_2_compat};
+use android_security_apc::aidl::android::security::apc::{
+    IConfirmationCallback::IConfirmationCallback,
+    IProtectedConfirmation::{BnProtectedConfirmation, IProtectedConfirmation},
+    ResponseCode::ResponseCode,
+};
+use android_security_apc::binder::{
+    ExceptionCode, Interface, Result as BinderResult, SpIBinder, Status as BinderStatus,
+};
+use anyhow::{Context, Result};
+use binder::{IBinder, ThreadState};
+use keystore2_apc_compat::ApcHal;
+use keystore2_selinux as selinux;
+use std::time::{Duration, Instant};
+
+/// This is the main APC error type, it wraps binder exceptions and the
+/// APC ResponseCode.
+#[derive(Debug, thiserror::Error, PartialEq)]
+pub enum Error {
+    /// Wraps an Android Protected Confirmation (APC) response code as defined by the
+    /// android.security.apc AIDL interface specification.
+    #[error("Error::Rc({0:?})")]
+    Rc(ResponseCode),
+    /// Wraps a Binder exception code other than a service specific exception.
+    #[error("Binder exception code {0:?}, {1:?}")]
+    Binder(ExceptionCode, i32),
+}
+
+impl Error {
+    /// Short hand for `Error::Rc(ResponseCode::SYSTEM_ERROR)`
+    pub fn sys() -> Self {
+        Error::Rc(ResponseCode::SYSTEM_ERROR)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::OPERATION_PENDING)`
+    pub fn pending() -> Self {
+        Error::Rc(ResponseCode::OPERATION_PENDING)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::CANCELLED)`
+    pub fn cancelled() -> Self {
+        Error::Rc(ResponseCode::CANCELLED)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::ABORTED)`
+    pub fn aborted() -> Self {
+        Error::Rc(ResponseCode::ABORTED)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::IGNORED)`
+    pub fn ignored() -> Self {
+        Error::Rc(ResponseCode::IGNORED)
+    }
+
+    /// Short hand for `Error::Rc(ResponseCode::UNIMPLEMENTED)`
+    pub fn unimplemented() -> Self {
+        Error::Rc(ResponseCode::UNIMPLEMENTED)
+    }
+}
+
+/// This function should be used by confirmation service calls to translate error conditions
+/// into service specific exceptions.
+///
+/// All error conditions get logged by this function.
+///
+/// `Error::Rc(x)` variants get mapped onto a service specific error code of `x`.
+/// `selinux::Error::perm()` is mapped on `ResponseCode::PERMISSION_DENIED`.
+///
+/// All non `Error` error conditions get mapped onto ResponseCode::SYSTEM_ERROR`.
+///
+/// `handle_ok` will be called if `result` is `Ok(value)` where `value` will be passed
+/// as argument to `handle_ok`. `handle_ok` must generate a `BinderResult<T>`, but it
+/// typically returns Ok(value).
+pub fn map_or_log_err<T, U, F>(result: Result<U>, handle_ok: F) -> BinderResult<T>
+where
+    F: FnOnce(U) -> BinderResult<T>,
+{
+    result.map_or_else(
+        |e| {
+            log::error!("{:#?}", e);
+            let root_cause = e.root_cause();
+            let rc = match root_cause.downcast_ref::<Error>() {
+                Some(Error::Rc(rcode)) => rcode.0,
+                Some(Error::Binder(_, _)) => ResponseCode::SYSTEM_ERROR.0,
+                None => match root_cause.downcast_ref::<selinux::Error>() {
+                    Some(selinux::Error::PermissionDenied) => ResponseCode::PERMISSION_DENIED.0,
+                    _ => ResponseCode::SYSTEM_ERROR.0,
+                },
+            };
+            Err(BinderStatus::new_service_specific_error(rc, None))
+        },
+        handle_ok,
+    )
+}
+
+/// Rate info records how many failed attempts a client has made to display a protected
+/// confirmation prompt. Clients are penalized for attempts that get declined by the user
+/// or attempts that get aborted by the client itself.
+///
+/// After the third failed attempt the client has to cool down for 30 seconds before it
+/// it can retry. After the sixth failed attempt, the time doubles with every failed attempt
+/// until it goes into saturation at 24h.
+///
+/// A successful user prompt resets the counter.
+#[derive(Debug, Clone)]
+struct RateInfo {
+    counter: u32,
+    timestamp: Instant,
+}
+
+impl RateInfo {
+    const ONE_DAY: Duration = Duration::from_secs(60u64 * 60u64 * 24u64);
+
+    fn get_remaining_back_off(&self) -> Option<Duration> {
+        let back_off = match self.counter {
+            // The first three attempts come without penalty.
+            0..=2 => return None,
+            // The next three attempts are are penalized with 30 seconds back off time.
+            3..=5 => Duration::from_secs(30),
+            // After that we double the back off time the with every additional attempt
+            // until we reach 1024m (~17h).
+            6..=16 => Duration::from_secs(60)
+                .checked_mul(1u32 << (self.counter - 6))
+                .unwrap_or(Self::ONE_DAY),
+            // After that we cap of at 24h between attempts.
+            _ => Self::ONE_DAY,
+        };
+        let elapsed = self.timestamp.elapsed();
+        // This does exactly what we want.
+        // `back_off - elapsed` is the remaining back off duration or None if elapsed is larger
+        // than back_off. Also, this operation cannot overflow as long as elapsed is less than
+        // back_off, which is all that we care about.
+        back_off.checked_sub(elapsed)
+    }
+}
+
+impl Default for RateInfo {
+    fn default() -> Self {
+        Self { counter: 0u32, timestamp: Instant::now() }
+    }
+}
+
+/// The APC session state represents the state of an APC session.
+struct ApcSessionState {
+    /// A reference to the APC HAL backend.
+    hal: Arc<ApcHal>,
+    /// The client callback object.
+    cb: SpIBinder,
+    /// The uid of the owner of this APC session.
+    uid: u32,
+    /// The time when this session was started.
+    start: Instant,
+    /// This is set when the client calls abort.
+    /// This is used by the rate limiting logic to determine
+    /// if the client needs to be penalized for this attempt.
+    client_aborted: bool,
+}
+
+#[derive(Default)]
+struct ApcState {
+    session: Option<ApcSessionState>,
+    rate_limiting: HashMap<u32, RateInfo>,
+}
+
+/// Implementation of the APC service.
+pub struct ApcManager {
+    state: Arc<Mutex<ApcState>>,
+}
+
+impl Interface for ApcManager {}
+
+impl ApcManager {
+    /// Create a new instance of the Android Protected Confirmation service.
+    pub fn new_native_binder() -> Result<impl IProtectedConfirmation> {
+        let result = BnProtectedConfirmation::new_binder(Self {
+            state: Arc::new(Mutex::new(Default::default())),
+        });
+        result.as_binder().set_requesting_sid(true);
+        Ok(result)
+    }
+
+    fn result(
+        state: Arc<Mutex<ApcState>>,
+        rc: u32,
+        data_confirmed: Option<&[u8]>,
+        confirmation_token: Option<&[u8]>,
+    ) {
+        let mut state = state.lock().unwrap();
+        let (callback, uid, start, client_aborted) = match state.session.take() {
+            None => return, // Nothing to do
+            Some(ApcSessionState { cb: callback, uid, start, client_aborted, .. }) => {
+                (callback, uid, start, client_aborted)
+            }
+        };
+
+        let rc = compat_2_response_code(rc);
+
+        // Update rate limiting information.
+        match (rc, client_aborted) {
+            // If the user confirmed the dialog.
+            (ResponseCode::OK, _) => {
+                // Reset counter.
+                state.rate_limiting.remove(&uid);
+                // TODO at this point we need to send the confirmation token to where keystore can
+                // use it.
+            }
+            // If cancelled by the user or if aborted by the client.
+            (ResponseCode::CANCELLED, _) | (ResponseCode::ABORTED, true) => {
+                // Penalize.
+                let mut rate_info = state.rate_limiting.entry(uid).or_default();
+                rate_info.counter += 1;
+                rate_info.timestamp = start;
+            }
+            // In any other case this try does not count at all.
+            _ => {}
+        }
+        drop(state);
+
+        if let Ok(listener) = callback.into_interface::<dyn IConfirmationCallback>() {
+            if let Err(e) = listener.onCompleted(rc, data_confirmed) {
+                log::error!(
+                    "In ApcManagerCallback::result: Reporting completion to client failed {:?}",
+                    e
+                )
+            }
+        } else {
+            log::error!("In ApcManagerCallback::result: SpIBinder is not a IConfirmationCallback.");
+        }
+    }
+
+    fn present_prompt(
+        &self,
+        listener: &dyn IConfirmationCallback,
+        prompt_text: &str,
+        extra_data: &[u8],
+        locale: &str,
+        ui_option_flags: i32,
+    ) -> Result<()> {
+        let mut state = self.state.lock().unwrap();
+        if state.session.is_some() {
+            return Err(Error::pending())
+                .context("In ApcManager::present_prompt: Session pending.");
+        }
+
+        // Perform rate limiting.
+        let uid = ThreadState::get_calling_uid();
+        match state.rate_limiting.get(&uid) {
+            None => {}
+            Some(rate_info) => {
+                if let Some(back_off) = rate_info.get_remaining_back_off() {
+                    return Err(Error::sys()).context(format!(
+                        "In ApcManager::present_prompt: Cooling down. Remaining back-off: {}s",
+                        back_off.as_secs()
+                    ));
+                }
+            }
+        }
+
+        let hal = ApcHal::try_get_service();
+        let hal = match hal {
+            None => {
+                return Err(Error::unimplemented())
+                    .context("In ApcManager::present_prompt: APC not supported.")
+            }
+            Some(h) => Arc::new(h),
+        };
+
+        let ui_opts = ui_opts_2_compat(ui_option_flags);
+
+        let state_clone = self.state.clone();
+        hal.prompt_user_confirmation(
+            prompt_text,
+            extra_data,
+            locale,
+            ui_opts,
+            |rc, data_confirmed, confirmation_token| {
+                Self::result(state_clone, rc, data_confirmed, confirmation_token)
+            },
+        )
+        .map_err(|rc| Error::Rc(compat_2_response_code(rc)))
+        .context("In present_prompt: Failed to present prompt.")?;
+        state.session = Some(ApcSessionState {
+            hal,
+            cb: listener.as_binder(),
+            uid,
+            start: Instant::now(),
+            client_aborted: false,
+        });
+        Ok(())
+    }
+
+    fn cancel_prompt(&self, listener: &dyn IConfirmationCallback) -> Result<()> {
+        let mut state = self.state.lock().unwrap();
+        let hal = match &mut state.session {
+            None => {
+                return Err(Error::ignored())
+                    .context("In cancel_prompt: Attempt to cancel non existing session. Ignoring.")
+            }
+            Some(session) => {
+                if session.cb != listener.as_binder() {
+                    return Err(Error::ignored()).context(concat!(
+                        "In cancel_prompt: Attempt to cancel session not belonging to caller. ",
+                        "Ignoring."
+                    ));
+                }
+                session.client_aborted = true;
+                session.hal.clone()
+            }
+        };
+        drop(state);
+        hal.abort();
+        Ok(())
+    }
+
+    fn is_supported() -> Result<bool> {
+        Ok(ApcHal::try_get_service().is_some())
+    }
+}
+
+impl IProtectedConfirmation for ApcManager {
+    fn presentPrompt(
+        &self,
+        listener: &dyn IConfirmationCallback,
+        prompt_text: &str,
+        extra_data: &[u8],
+        locale: &str,
+        ui_option_flags: i32,
+    ) -> BinderResult<()> {
+        map_or_log_err(
+            self.present_prompt(listener, prompt_text, extra_data, locale, ui_option_flags),
+            Ok,
+        )
+    }
+    fn cancelPrompt(&self, listener: &dyn IConfirmationCallback) -> BinderResult<()> {
+        map_or_log_err(self.cancel_prompt(listener), Ok)
+    }
+    fn isSupported(&self) -> BinderResult<bool> {
+        map_or_log_err(Self::is_supported(), Ok)
+    }
+}
