Add Keystore 2.0 service.

This patch adds a boilerplate Keystore 2.0 service. It is configured to
run on the device but does not provide any useful service yet.
It provides basic functionality for generating, importing and using
keys, but it still lacks full Keystore functionality.

Test: VtsKeystore2V1_0TargetTest (in followup CL)
Bug: 160623310
Bug: 160930114
Bug: 160930117
Bug: 160930331
Bug: 159465122
Change-Id: I7dfa2f2f63f4da3af620aff2ec99c0cba3bda6fd
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index f4b153c..a1ee969 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -53,6 +53,18 @@
     ],
 }
 
+rust_binary {
+    name: "keystore2",
+    srcs: ["src/keystore2_main.rs"],
+    rustlibs: [
+        "libandroid_logger",
+        "libbinder_rs",
+        "libkeystore2",
+        "liblog_rust",
+    ],
+    init_rc: ["keystore2.rc"],
+}
+
 // This is a placeholder for the libraries that will be generated from the AIDL specs
 // eventually.
 rust_library {
diff --git a/keystore2/keystore2.rc b/keystore2/keystore2.rc
new file mode 100644
index 0000000..139c94b
--- /dev/null
+++ b/keystore2/keystore2.rc
@@ -0,0 +1,12 @@
+# Start the keystore2 service.
+# Keystore 2.0 changes its working directory to the first positional
+# command line option, i.e., /data/misc/keystore, where it stores its
+# database.
+# Keystore shall run as user keystore and groups keystore, readproc, and log.
+#
+# See system/core/init/README.md for information on the init.rc language.
+service keystore2 /system/bin/keystore2 /data/misc/keystore
+    class main
+    user keystore
+    group keystore readproc log
+    writepid /dev/cpuset/foreground/tasks
diff --git a/keystore2/src/keystore2_main.rs b/keystore2/src/keystore2_main.rs
new file mode 100644
index 0000000..dea0a93
--- /dev/null
+++ b/keystore2/src/keystore2_main.rs
@@ -0,0 +1,59 @@
+// 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.
+
+//! This crate implements Keystore 2.0.
+
+use binder::Interface;
+use keystore2::service::KeystoreService;
+use log::{error, info};
+use std::panic;
+
+static KS2_SERVICE_NAME: &str = "android.system.keystore2";
+
+/// Keystore 2.0 takes one argument which is a path indicating its designated working directory.
+fn main() {
+    // Initialize android logging.
+    android_logger::init_once(
+        android_logger::Config::default().with_tag("keystore2").with_min_level(log::Level::Debug),
+    );
+    // Redirect panic messages to logcat.
+    panic::set_hook(Box::new(|panic_info| {
+        error!("{}", panic_info);
+    }));
+
+    // Saying hi.
+    info!("Keystore2 is starting.");
+
+    let mut args = std::env::args();
+    args.next().expect("That's odd. How is there not even a first argument?");
+    if let Some(dir) = args.next() {
+        if std::env::set_current_dir(dir.clone()).is_err() {
+            panic!("Failed to set working directory {}.", dir)
+        }
+    } else {
+        panic!("Must specify a working directory.");
+    }
+
+    let ks_service = KeystoreService::new_native_binder().unwrap_or_else(|e| {
+        panic!("Failed to create service {} because of {:?}.", KS2_SERVICE_NAME, e);
+    });
+    binder::add_service(KS2_SERVICE_NAME, ks_service.as_binder()).unwrap_or_else(|e| {
+        panic!("Failed to register service {} because of {:?}.", KS2_SERVICE_NAME, e);
+    });
+
+    info!("Successfully registered Keystore 2.0 service.");
+    info!("Joining threadpool now.");
+
+    binder::ProcessState::join_thread_pool();
+}
diff --git a/keystore2/src/lib.rs b/keystore2/src/lib.rs
index 7439a5b..067399e 100644
--- a/keystore2/src/lib.rs
+++ b/keystore2/src/lib.rs
@@ -19,5 +19,8 @@
 pub mod globals;
 /// Internal Representation of Key Parameter and convenience functions.
 pub mod key_parameter;
+pub mod operation;
 pub mod permission;
+pub mod security_level;
+pub mod service;
 pub mod utils;
diff --git a/keystore2/src/operation.rs b/keystore2/src/operation.rs
new file mode 100644
index 0000000..f987188
--- /dev/null
+++ b/keystore2/src/operation.rs
@@ -0,0 +1,768 @@
+// 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.
+
+//! This crate implements the `IKeystoreOperation` AIDL interface, which represents
+//! an ongoing key operation, as well as the operation database, which is mainly
+//! required for tracking operations for the purpose of pruning.
+//! This crate also implements an operation pruning strategy.
+//!
+//! Operations implement the API calls update, finish, and abort.
+//! Additionally, an operation can be dropped and pruned. The former
+//! happens if the client deletes a binder to the operation object.
+//! An existing operation may get pruned when running out of operation
+//! slots and a new operation takes precedence.
+//!
+//! ## Operation Lifecycle
+//! An operation gets created when the client calls `IKeystoreSecurityLevel::create`.
+//! It may receive zero or more update request. The lifecycle ends when:
+//!  * `update` yields an error.
+//!  * `finish` is called.
+//!  * `abort` is called.
+//!  * The operation gets dropped.
+//!  * The operation gets pruned.
+//! `Operation` has an `Outcome` member. While the outcome is `Outcome::Unknown`,
+//! the operation is active and in a good state. Any of the above conditions may
+//! change the outcome to one of the defined outcomes Success, Abort, Dropped,
+//! Pruned, or ErrorCode. The latter is chosen in the case of an unexpected error, during
+//! `update` or `finish`. `Success` is chosen iff `finish` completes without error.
+//! Note that all operations get dropped eventually in the sense that they lose
+//! their last reference and get destroyed. At that point, the fate of the operation
+//! gets logged. However, an operation will transition to `Outcome::Dropped` iff
+//! the operation was still active (`Outcome::Unknown`) at that time.
+//!
+//! ## Operation Dropping
+//! To observe the dropping of an operation, we have to make sure that there
+//! are no strong references to the IBinder representing this operation.
+//! This would be simple enough if the operation object would need to be accessed
+//! only by transactions. But to perform pruning, we have to retain a reference to the
+//! original operation object.
+//!
+//! ## Operation Pruning
+//! Pruning an operation happens during the creation of a new operation.
+//! We have to iterate through the operation database to find a suitable
+//! candidate. Then we abort and finalize this operation setting its outcome to
+//! `Outcome::Pruned`. The corresponding KeyMint operation slot will have been freed
+//! up at this point, but the `Operation` object lingers. When the client
+//! attempts to use the operation again they will receive
+//! ErrorCode::INVALID_OPERATION_HANDLE indicating that the operation no longer
+//! exits. This should be the cue for the client to destroy its binder.
+//! At that point the operation gets dropped.
+//!
+//! ## Architecture
+//! The `IKeystoreOperation` trait is implemented by `KeystoreOperation`.
+//! This acts as a proxy object holding a strong reference to actual operation
+//! implementation `Operation`.
+//!
+//! ```
+//! struct KeystoreOperation {
+//!     operation: Mutex<Option<Arc<Operation>>>,
+//! }
+//! ```
+//!
+//! The `Mutex` serves two purposes. It provides interior mutability allowing
+//! us to set the Option to None. We do this when the life cycle ends during
+//! a call to `update`, `finish`, or `abort`. As a result most of the Operation
+//! related resources are freed. The `KeystoreOperation` proxy object still
+//! lingers until dropped by the client.
+//! The second purpose is to protect operations against concurrent usage.
+//! Failing to lock this mutex yields `ResponseCode::OPERATION_BUSY` and indicates
+//! a programming error in the client.
+//!
+//! Note that the Mutex only protects the operation against concurrent client calls.
+//! We still retain weak references to the operation in the operation database:
+//!
+//! ```
+//! struct OperationDb {
+//!     operations: Mutex<Vec<Weak<Operation>>>
+//! }
+//! ```
+//!
+//! This allows us to access the operations for the purpose of pruning.
+//! We do this in three phases.
+//!  1. We gather the pruning information. Besides non mutable information,
+//!     we access `last_usage` which is protected by a mutex.
+//!     We only lock this mutex for single statements at a time. During
+//!     this phase we hold the operation db lock.
+//!  2. We choose a pruning candidate by computing the pruning resistance
+//!     of each operation. We do this entirely with information we now
+//!     have on the stack without holding any locks.
+//!     (See `OperationDb::prune` for more details on the pruning strategy.)
+//!  3. During pruning we briefly lock the operation database again to get the
+//!     the pruning candidate by index. We then attempt to abort the candidate.
+//!     If the candidate was touched in the meantime or is currently fulfilling
+//!     a request (i.e., the client calls update, finish, or abort),
+//!     we go back to 1 and try again.
+//!
+//! So the outer Mutex in `KeystoreOperation::operation` only protects
+//! operations against concurrent client calls but not against concurrent
+//! pruning attempts. This is what the `Operation::outcome` mutex is used for.
+//!
+//! ```
+//! struct Operation {
+//!     ...
+//!     outcome: Mutex<Outcome>,
+//!     ...
+//! }
+//! ```
+//!
+//! Any request that can change the outcome, i.e., `update`, `finish`, `abort`,
+//! `drop`, and `prune` has to take the outcome lock and check if the outcome
+//! is still `Outcome::Unknown` before entering. `prune` is special in that
+//! it will `try_lock`, because we don't want to be blocked on a potentially
+//! long running request at another operation. If it fails to get the lock
+//! the operation is either being touched, which changes its pruning resistance,
+//! or it transitions to its end-of-life, which means we may get a free slot.
+//! Either way, we have to revaluate the pruning scores.
+
+use std::{
+    collections::HashMap,
+    sync::{Arc, Mutex, MutexGuard, Weak},
+    time::Duration,
+    time::Instant,
+};
+
+use crate::error::{map_km_error, map_or_log_err, Error, ErrorCode, ResponseCode};
+use crate::utils::Asp;
+use android_hardware_keymint::aidl::android::hardware::keymint::{
+    IKeyMintOperation::IKeyMintOperation, KeyParameter::KeyParameter as KmParam, Tag::Tag,
+};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    IKeystoreOperation::BnKeystoreOperation, IKeystoreOperation::IKeystoreOperation,
+};
+use anyhow::{anyhow, Context, Result};
+use binder::{IBinder, Interface};
+
+/// Operations have `Outcome::Unknown` as long as they are active. They transition
+/// to one of the other variants exactly once. The distinction in outcome is mainly
+/// for the statistic.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
+enum Outcome {
+    Unknown,
+    Success,
+    Abort,
+    Dropped,
+    Pruned,
+    ErrorCode(ErrorCode),
+}
+
+/// Operation bundles all of the operation related resources and tracks the operation's
+/// outcome.
+#[derive(Debug)]
+pub struct Operation {
+    // The index of this operation in the OperationDb.
+    index: usize,
+    km_op: Asp,
+    last_usage: Mutex<Instant>,
+    outcome: Mutex<Outcome>,
+    owner: u32, // Uid of the operation's owner.
+}
+
+struct PruningInfo {
+    last_usage: Instant,
+    owner: u32,
+    index: usize,
+}
+
+static EMPTY_BLOB: &[u8] = &[];
+// We don't except more than 32KiB of data in `update`, `updateAad`, and `finish`.
+const MAX_RECEIVE_DATA: usize = 0x8000;
+
+impl Operation {
+    /// Constructor
+    pub fn new(index: usize, km_op: Box<dyn IKeyMintOperation>, owner: u32) -> Self {
+        Self {
+            index,
+            km_op: Asp::new(km_op.as_binder()),
+            last_usage: Mutex::new(Instant::now()),
+            outcome: Mutex::new(Outcome::Unknown),
+            owner,
+        }
+    }
+
+    fn get_pruning_info(&self) -> PruningInfo {
+        // Expect safety:
+        // `last_usage` is locked only for primitive single line statements.
+        // There is no chance to panic and poison the mutex.
+        PruningInfo {
+            last_usage: *self.last_usage.lock().expect("In get_pruning_info."),
+            owner: self.owner,
+            index: self.index,
+        }
+    }
+
+    fn prune(&self, last_usage: Instant) -> Result<(), Error> {
+        let mut locked_outcome = match self.outcome.try_lock() {
+            Ok(guard) => match *guard {
+                Outcome::Unknown => guard,
+                _ => return Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE)),
+            },
+            Err(_) => return Err(Error::Rc(ResponseCode::OPERATION_BUSY)),
+        };
+
+        // In `OperationDb::prune`, which is our caller, we first gather the pruning
+        // information including the last usage. When we select a candidate
+        // we call `prune` on that candidate passing the last_usage
+        // that we gathered earlier. If the actual last usage
+        // has changed since than, it means the operation was busy in the
+        // meantime, which means that we have to reevaluate the pruning score.
+        //
+        // Expect safety:
+        // `last_usage` is locked only for primitive single line statements.
+        // There is no chance to panic and poison the mutex.
+        if *self.last_usage.lock().expect("In Operation::prune()") != last_usage {
+            return Err(Error::Rc(ResponseCode::OPERATION_BUSY));
+        }
+        *locked_outcome = Outcome::Pruned;
+
+        let km_op: Box<dyn IKeyMintOperation> = match self.km_op.get_interface() {
+            Ok(km_op) => km_op,
+            Err(e) => {
+                log::error!("In prune: Failed to get KeyMintOperation interface.\n    {:?}", e);
+                return Err(Error::sys());
+            }
+        };
+
+        // We abort the operation. If there was an error we log it but ignore it.
+        if let Err(e) = map_km_error(km_op.abort()) {
+            log::error!("In prune: KeyMint::abort failed with {:?}.", e);
+        }
+
+        Ok(())
+    }
+
+    // This function takes a Result from a KeyMint call and inspects it for errors.
+    // If an error was found it updates the given `locked_outcome` accordingly.
+    // It forwards the Result unmodified.
+    // The precondition to this call must be *locked_outcome == Outcome::Unknown.
+    // Ideally the `locked_outcome` came from a successful call to `check_active`
+    // see below.
+    fn update_outcome<T>(
+        &self,
+        locked_outcome: &mut Outcome,
+        err: Result<T, Error>,
+    ) -> Result<T, Error> {
+        match &err {
+            Err(Error::Km(e)) => *locked_outcome = Outcome::ErrorCode(*e),
+            Err(_) => *locked_outcome = Outcome::ErrorCode(ErrorCode::UNKNOWN_ERROR),
+            Ok(_) => (),
+        }
+        err
+    }
+
+    // This function grabs the outcome lock and checks the current outcome state.
+    // If the outcome is still `Outcome::Unknown`, this function returns
+    // the locked outcome for further updates. In any other case it returns
+    // ErrorCode::INVALID_OPERATION_HANDLE indicating that this operation has
+    // been finalized and is no longer active.
+    fn check_active(&self) -> Result<MutexGuard<Outcome>> {
+        let guard = self.outcome.lock().expect("In check_active.");
+        match *guard {
+            Outcome::Unknown => Ok(guard),
+            _ => Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE)).context(format!(
+                "In check_active: Call on finalized operation with outcome: {:?}.",
+                *guard
+            )),
+        }
+    }
+
+    // This function checks the amount of input data sent to us. We reject any buffer
+    // exceeding MAX_RECEIVE_DATA bytes as input to `update`, `update_aad`, and `finish`
+    // in order to force clients into using reasonable limits.
+    fn check_input_length(data: &[u8]) -> Result<()> {
+        if data.len() > MAX_RECEIVE_DATA {
+            // This error code is unique, no context required here.
+            return Err(anyhow!(Error::Rc(ResponseCode::TOO_MUCH_DATA)));
+        }
+        Ok(())
+    }
+
+    // Update the last usage to now.
+    fn touch(&self) {
+        // Expect safety:
+        // `last_usage` is locked only for primitive single line statements.
+        // There is no chance to panic and poison the mutex.
+        *self.last_usage.lock().expect("In touch.") = Instant::now();
+    }
+
+    /// Implementation of `IKeystoreOperation::updateAad`.
+    /// Refer to the AIDL spec at system/hardware/interfaces/keystore2 for details.
+    fn update_aad(&self, aad_input: &[u8]) -> Result<()> {
+        let mut outcome = self.check_active().context("In update_aad")?;
+        Self::check_input_length(aad_input).context("In update_aad")?;
+        self.touch();
+
+        let params =
+            [KmParam { tag: Tag::ASSOCIATED_DATA, blob: aad_input.into(), ..Default::default() }];
+
+        let mut out_params: Vec<KmParam> = Vec::new();
+        let mut output: Vec<u8> = Vec::new();
+
+        let km_op: Box<dyn IKeyMintOperation> =
+            self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
+
+        self.update_outcome(
+            &mut *outcome,
+            map_km_error(km_op.update(
+                &params,
+                &[],
+                // TODO HardwareAuthtoken missing
+                &Default::default(),
+                &mut out_params,
+                &mut output,
+            )),
+        )
+        .context("In update_aad: KeyMint::update failed.")?;
+
+        Ok(())
+    }
+
+    /// Implementation of `IKeystoreOperation::update`.
+    /// Refer to the AIDL spec at system/hardware/interfaces/keystore2 for details.
+    fn update(&self, input: &[u8]) -> Result<Option<Vec<u8>>> {
+        let mut outcome = self.check_active().context("In update")?;
+        Self::check_input_length(input).context("In update")?;
+        self.touch();
+
+        let mut out_params: Vec<KmParam> = Vec::new();
+        let mut output: Vec<u8> = Vec::new();
+
+        let km_op: Box<dyn IKeyMintOperation> =
+            self.km_op.get_interface().context("In update: Failed to get KeyMintOperation.")?;
+
+        self.update_outcome(
+            &mut *outcome,
+            map_km_error(km_op.update(
+                &[],
+                input,
+                // TODO HardwareAuthtoken missing
+                &Default::default(),
+                &mut out_params,
+                &mut output,
+            )),
+        )
+        .context("In update: KeyMint::update failed.")?;
+
+        if output.is_empty() {
+            Ok(None)
+        } else {
+            Ok(Some(output))
+        }
+    }
+
+    /// Implementation of `IKeystoreOperation::finish`.
+    /// Refer to the AIDL spec at system/hardware/interfaces/keystore2 for details.
+    fn finish(&self, input: Option<&[u8]>, signature: Option<&[u8]>) -> Result<Option<Vec<u8>>> {
+        let mut outcome = self.check_active().context("In finish")?;
+        if let Some(input) = input {
+            Self::check_input_length(input).context("In finish")?;
+        }
+        self.touch();
+        let input = input.unwrap_or(EMPTY_BLOB);
+        let signature = signature.unwrap_or(EMPTY_BLOB);
+
+        let mut out_params: Vec<KmParam> = Vec::new();
+        let mut output: Vec<u8> = Vec::new();
+
+        let km_op: Box<dyn IKeyMintOperation> =
+            self.km_op.get_interface().context("In finish: Failed to get KeyMintOperation.")?;
+
+        self.update_outcome(
+            &mut *outcome,
+            map_km_error(km_op.finish(
+                &[],
+                &input,
+                &signature,
+                &Default::default(),
+                &Default::default(),
+                &mut out_params,
+                &mut output,
+            )),
+        )
+        .context("In finish: KeyMint::finish failed.")?;
+
+        // At this point the operation concluded successfully.
+        *outcome = Outcome::Success;
+
+        if output.is_empty() {
+            Ok(None)
+        } else {
+            Ok(Some(output))
+        }
+    }
+
+    /// Aborts the operation if it is active. IFF the operation is aborted the outcome is
+    /// set to `outcome`. `outcome` must reflect the reason for the abort. Since the operation
+    /// gets aborted `outcome` must not be `Operation::Success` or `Operation::Unknown`.
+    fn abort(&self, outcome: Outcome) -> Result<()> {
+        let mut locked_outcome = self.check_active().context("In abort")?;
+        *locked_outcome = outcome;
+        let km_op: Box<dyn IKeyMintOperation> =
+            self.km_op.get_interface().context("In abort: Failed to get KeyMintOperation.")?;
+
+        map_km_error(km_op.abort()).context("In abort: KeyMint::abort failed.")
+    }
+}
+
+impl Drop for Operation {
+    fn drop(&mut self) {
+        if let Ok(Outcome::Unknown) = self.outcome.get_mut() {
+            // If the operation was still active we call abort, setting
+            // the outcome to `Outcome::Dropped`
+            if let Err(e) = self.abort(Outcome::Dropped) {
+                log::error!("While dropping Operation: abort failed:\n    {:?}", e);
+            }
+        }
+    }
+}
+
+/// The OperationDb holds weak references to all ongoing operations.
+/// Its main purpose is to facilitate operation pruning.
+#[derive(Debug, Default)]
+pub struct OperationDb {
+    // TODO replace Vec with WeakTable when the weak_table crate becomes
+    // available.
+    operations: Mutex<Vec<Weak<Operation>>>,
+}
+
+impl OperationDb {
+    /// Creates a new OperationDb.
+    pub fn new() -> Self {
+        Self { operations: Mutex::new(Vec::new()) }
+    }
+
+    /// Creates a new operation.
+    /// This function takes a KeyMint operation and an associated
+    /// owner uid and returns a new Operation wrapped in a `std::sync::Arc`.
+    pub fn create_operation(
+        &self,
+        km_op: Box<dyn IKeyMintOperation>,
+        owner: u32,
+    ) -> Arc<Operation> {
+        // We use unwrap because we don't allow code that can panic while locked.
+        let mut operations = self.operations.lock().expect("In create_operation.");
+
+        let mut index: usize = 0;
+        // First we iterate through the operation slots to try and find an unused
+        // slot. If we don't find one, we append the new entry instead.
+        match (*operations).iter_mut().find(|s| {
+            index += 1;
+            s.upgrade().is_none()
+        }) {
+            Some(free_slot) => {
+                let new_op = Arc::new(Operation::new(index - 1, km_op, owner));
+                *free_slot = Arc::downgrade(&new_op);
+                new_op
+            }
+            None => {
+                let new_op = Arc::new(Operation::new(operations.len(), km_op, owner));
+                operations.push(Arc::downgrade(&new_op));
+                new_op
+            }
+        }
+    }
+
+    fn get(&self, index: usize) -> Option<Arc<Operation>> {
+        self.operations.lock().expect("In OperationDb::get.").get(index).and_then(|op| op.upgrade())
+    }
+
+    /// Attempts to prune an operation.
+    ///
+    /// This function is used during operation creation, i.e., by
+    /// `KeystoreSecurityLevel::create_operation`, to try and free up an operation slot
+    /// if it got `ErrorCode::TOO_MANY_OPERATIONS` from the KeyMint backend. It is not
+    /// guaranteed that an operation slot is available after this call successfully
+    /// returned for various reasons. E.g., another thread may have snatched up the newly
+    /// available slot. Callers may have to call prune multiple times before they get a
+    /// free operation slot. Prune may also return `Err(Error::Rc(ResponseCode::BACKEND_BUSY))`
+    /// which indicates that no prunable operation was found.
+    ///
+    /// To find a suitable candidate we compute the malus for the caller and each existing
+    /// operation. The malus is the inverse of the pruning power (caller) or pruning
+    /// resistance (existing operation).
+    /// The malus is based on the number of sibling operations and age. Sibling
+    /// operations are operations that have the same owner (UID).
+    /// Every operation, existing or new, starts with a malus of 1. Every sibling
+    /// increases the malus by one. The age is the time since an operation was last touched.
+    /// It increases the malus by log6(<age in seconds> + 1) rounded down to the next
+    /// integer. So the malus increases stepwise after 5s, 35s, 215s, ...
+    /// Of two operations with the same malus the least recently used one is considered
+    /// weaker.
+    /// For the caller to be able to prune an operation it must find an operation
+    /// with a malus higher than its own.
+    ///
+    /// The malus can be expressed as
+    /// ```
+    /// malus = 1 + no_of_siblings + floor(log6(age_in_seconds + 1))
+    /// ```
+    /// where the constant `1` accounts for the operation under consideration.
+    /// In reality we compute it as
+    /// ```
+    /// caller_malus = 1 + running_siblings
+    /// ```
+    /// because the new operation has no age and is not included in the `running_siblings`,
+    /// and
+    /// ```
+    /// running_malus = running_siblings + floor(log6(age_in_seconds + 1))
+    /// ```
+    /// because a running operation is included in the `running_siblings` and it has
+    /// an age.
+    ///
+    /// ## Example
+    /// A caller with no running operations has a malus of 1. Young (age < 5s) operations
+    /// also with no siblings have a malus of one and cannot be pruned by the caller.
+    /// We have to find an operation that has at least one sibling or is older than 5s.
+    ///
+    /// A caller with one running operation has a malus of 2. Now even young siblings
+    /// or single child aging (5s <= age < 35s) operations are off limit. An aging
+    /// sibling of two, however, would have a malus of 3 and would be fair game.
+    ///
+    /// ## Rationale
+    /// Due to the limitation of KeyMint operation slots, we cannot get around pruning or
+    /// a single app could easily DoS KeyMint.
+    /// Keystore 1.0 used to always prune the least recently used operation. This at least
+    /// guaranteed that new operations can always be started. With the increased usage
+    /// of Keystore we saw increased pruning activity which can lead to a livelock
+    /// situation in the worst case.
+    /// With the new pruning strategy we want to provide well behaved clients with
+    /// progress assurances while punishing DoS attempts. As a result of this
+    /// strategy we can be in the situation where no operation can be pruned and the
+    /// creation of a new operation fails. This allows single child operations which
+    /// are frequently updated to complete, thereby breaking up livelock situations
+    /// and facilitating system wide progress.
+    pub fn prune(&self, caller: u32) -> Result<(), Error> {
+        loop {
+            // Maps the uid of the owner to the number of operations that owner has
+            // (running_siblings). More operations per owner lowers the pruning
+            // resistance of the operations of that owner. Whereas the number of
+            // ongoing operations of the caller lowers the pruning power of the caller.
+            let mut owners: HashMap<u32, u64> = HashMap::new();
+            let mut pruning_info: Vec<PruningInfo> = Vec::new();
+
+            let now = Instant::now();
+            self.operations
+                .lock()
+                .expect("In OperationDb::prune: Trying to lock self.operations.")
+                .iter()
+                .for_each(|op| {
+                    if let Some(op) = op.upgrade() {
+                        let p_info = op.get_pruning_info();
+                        let owner = p_info.owner;
+                        pruning_info.push(p_info);
+                        // Count operations per owner.
+                        *owners.entry(owner).or_insert(0) += 1;
+                    }
+                });
+
+            let caller_malus = 1u64 + *owners.entry(caller).or_default();
+
+            // We iterate through all operations computing the malus and finding
+            // the candidate with the highest malus which must also be higher
+            // than the caller_malus.
+            struct CandidateInfo {
+                index: usize,
+                malus: u64,
+                last_usage: Instant,
+                age: Duration,
+            }
+            let candidate = pruning_info.iter().fold(
+                None,
+                |acc: Option<CandidateInfo>, &PruningInfo { last_usage, owner, index }| {
+                    // Compute the age of the current operation.
+                    let age = now
+                        .checked_duration_since(last_usage)
+                        .unwrap_or_else(|| Duration::new(0, 0));
+
+                    // Compute the malus of the current operation.
+                    // Expect safety: Every owner in pruning_info was counted in
+                    // the owners map. So this unwrap cannot panic.
+                    let malus = *owners
+                        .get(&owner)
+                        .expect("This is odd. We should have counted every owner in pruning_info.")
+                        + ((age.as_secs() + 1) as f64).log(6.0).floor() as u64;
+
+                    // Now check if the current operation is a viable/better candidate
+                    // the one currently stored in the accumulator.
+                    match acc {
+                        // First we have to find any operation that is prunable by the caller.
+                        None => {
+                            if caller_malus < malus {
+                                Some(CandidateInfo { index, malus, last_usage, age })
+                            } else {
+                                None
+                            }
+                        }
+                        // If we have found one we look for the operation with the worst score.
+                        // If there is a tie, the older operation is considered weaker.
+                        Some(CandidateInfo { index: i, malus: m, last_usage: l, age: a }) => {
+                            if malus > m || (malus == m && age > a) {
+                                Some(CandidateInfo { index, malus, last_usage, age })
+                            } else {
+                                Some(CandidateInfo { index: i, malus: m, last_usage: l, age: a })
+                            }
+                        }
+                    }
+                },
+            );
+
+            match candidate {
+                Some(CandidateInfo { index, malus: _, last_usage, age: _ }) => {
+                    match self.get(index) {
+                        Some(op) => {
+                            match op.prune(last_usage) {
+                                // We successfully freed up a slot.
+                                Ok(()) => break Ok(()),
+                                // This means the operation we tried to prune was on its way
+                                // out. It also means that the slot it had occupied was freed up.
+                                Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE)) => break Ok(()),
+                                // This means the operation we tried to prune was currently
+                                // servicing a request. There are two options.
+                                // * Assume that it was touched, which means that its
+                                //   pruning resistance increased. In that case we have
+                                //   to start over and find another candidate.
+                                // * Assume that the operation is transitioning to end-of-life.
+                                //   which means that we got a free slot for free.
+                                // If we assume the first but the second is true, we prune
+                                // a good operation without need (aggressive approach).
+                                // If we assume the second but the first is true, our
+                                // caller will attempt to create a new KeyMint operation,
+                                // fail with `ErrorCode::TOO_MANY_OPERATIONS`, and call
+                                // us again (conservative approach).
+                                Err(Error::Rc(ResponseCode::OPERATION_BUSY)) => {
+                                    // We choose the conservative approach, because
+                                    // every needlessly pruned operation can impact
+                                    // the user experience.
+                                    // To switch to the aggressive approach replace
+                                    // the following line with `continue`.
+                                    break Ok(());
+                                }
+
+                                // The candidate may have been touched so the score
+                                // has changed since our evaluation.
+                                _ => continue,
+                            }
+                        }
+                        // This index does not exist any more. The operation
+                        // in this slot was dropped. Good news, a slot
+                        // has freed up.
+                        None => break Ok(()),
+                    }
+                }
+                // We did not get a pruning candidate.
+                None => break Err(Error::Rc(ResponseCode::BACKEND_BUSY)),
+            }
+        }
+    }
+}
+
+/// Implementation of IKeystoreOperation.
+pub struct KeystoreOperation {
+    operation: Mutex<Option<Arc<Operation>>>,
+}
+
+impl KeystoreOperation {
+    /// Creates a new operation instance wrapped in a
+    /// BnKeystoreOperation proxy object. It also
+    /// calls `IBinder::set_requesting_sid` on the new interface, because
+    /// we need it for checking Keystore permissions.
+    pub fn new_native_binder(operation: Arc<Operation>) -> impl IKeystoreOperation + Send {
+        let result =
+            BnKeystoreOperation::new_binder(Self { operation: Mutex::new(Some(operation)) });
+        result.as_binder().set_requesting_sid(true);
+        result
+    }
+
+    /// Grabs the outer operation mutex and calls `f` on the locked operation.
+    /// The function also deletes the operation if it returns with an error or if
+    /// `delete_op` is true.
+    fn with_locked_operation<T, F>(&self, f: F, delete_op: bool) -> Result<T>
+    where
+        for<'a> F: FnOnce(&'a Operation) -> Result<T>,
+    {
+        let mut delete_op: bool = delete_op;
+        match self.operation.try_lock() {
+            Ok(mut mutex_guard) => {
+                let result = match &*mutex_guard {
+                    Some(op) => {
+                        let result = f(&*op);
+                        // Any error here means we can discard the operation.
+                        if result.is_err() {
+                            delete_op = true;
+                        }
+                        result
+                    }
+                    None => Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE))
+                        .context("In KeystoreOperation::with_locked_operation"),
+                };
+
+                if delete_op {
+                    // We give up our reference to the Operation, thereby freeing up our
+                    // internal resources and ending the wrapped KeyMint operation.
+                    // This KeystoreOperation object will still be owned by an SpIBinder
+                    // until the client drops its remote reference.
+                    *mutex_guard = None;
+                }
+                result
+            }
+            Err(_) => Err(Error::Rc(ResponseCode::OPERATION_BUSY))
+                .context("In KeystoreOperation::with_locked_operation"),
+        }
+    }
+}
+
+impl binder::Interface for KeystoreOperation {}
+
+impl IKeystoreOperation for KeystoreOperation {
+    fn updateAad(&self, aad_input: &[u8]) -> binder::public_api::Result<()> {
+        map_or_log_err(
+            self.with_locked_operation(
+                |op| op.update_aad(aad_input).context("In KeystoreOperation::updateAad"),
+                false,
+            ),
+            Ok,
+        )
+    }
+
+    fn update(&self, input: &[u8]) -> binder::public_api::Result<Option<Vec<u8>>> {
+        map_or_log_err(
+            self.with_locked_operation(
+                |op| op.update(input).context("In KeystoreOperation::update"),
+                false,
+            ),
+            Ok,
+        )
+    }
+    fn finish(
+        &self,
+        input: Option<&[u8]>,
+        signature: Option<&[u8]>,
+    ) -> binder::public_api::Result<Option<Vec<u8>>> {
+        map_or_log_err(
+            self.with_locked_operation(
+                |op| op.finish(input, signature).context("In KeystoreOperation::finish"),
+                true,
+            ),
+            Ok,
+        )
+    }
+
+    fn abort(&self) -> binder::public_api::Result<()> {
+        map_or_log_err(
+            self.with_locked_operation(
+                |op| op.abort(Outcome::Abort).context("In KeystoreOperation::abort"),
+                true,
+            ),
+            Ok,
+        )
+    }
+}
diff --git a/keystore2/src/security_level.rs b/keystore2/src/security_level.rs
new file mode 100644
index 0000000..287d626
--- /dev/null
+++ b/keystore2/src/security_level.rs
@@ -0,0 +1,553 @@
+// 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.
+
+#![allow(unused_variables)]
+
+//! This crate implements the IKeystoreSecurityLevel interface.
+
+use android_hardware_keymint::aidl::android::hardware::keymint::{
+    Algorithm::Algorithm, Certificate::Certificate as KmCertificate,
+    IKeyMintDevice::IKeyMintDevice, KeyCharacteristics::KeyCharacteristics, KeyFormat::KeyFormat,
+    KeyParameter::KeyParameter as KmParam, KeyPurpose::KeyPurpose, Tag::Tag,
+};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    AuthenticatorSpec::AuthenticatorSpec, AuthenticatorType::AuthenticatorType,
+    Certificate::Certificate, CertificateChain::CertificateChain, Domain::Domain,
+    IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::BnKeystoreSecurityLevel,
+    IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
+    KeyParameter::KeyParameter, OperationChallenge::OperationChallenge,
+    SecurityLevel::SecurityLevel,
+};
+
+use crate::error::{self, map_km_error, map_or_log_err, Error, ErrorCode};
+use crate::globals::DB;
+use crate::permission::KeyPerm;
+use crate::utils::{check_key_permission, keyparam_ks_to_km, Asp};
+use crate::{
+    database::{KeyEntry, KeyEntryLoadBits, SubComponentType},
+    operation::KeystoreOperation,
+    operation::OperationDb,
+};
+use anyhow::{anyhow, Context, Result};
+use binder::{IBinder, Interface, ThreadState};
+
+/// Implementation of the IKeystoreSecurityLevel Interface.
+pub struct KeystoreSecurityLevel {
+    security_level: SecurityLevel,
+    keymint: Asp,
+    operation_db: OperationDb,
+}
+
+static KEYMINT_SERVICE_NAME: &str = "android.hardware.keymint.IKeyMintDevice";
+
+// Blob of 32 zeroes used as empty masking key.
+static ZERO_BLOB_32: &[u8] = &[0; 32];
+
+impl KeystoreSecurityLevel {
+    /// Creates a new security level instance wrapped in a
+    /// BnKeystoreSecurityLevel proxy object. It also
+    /// calls `IBinder::set_requesting_sid` on the new interface, because
+    /// we need it for checking keystore permissions.
+    pub fn new_native_binder(
+        security_level: SecurityLevel,
+    ) -> Result<impl IKeystoreSecurityLevel + Send> {
+        let service_name = format!("{}/default", KEYMINT_SERVICE_NAME);
+        let keymint: Box<dyn IKeyMintDevice> =
+            binder::get_interface(&service_name).map_err(|e| {
+                anyhow!(format!(
+                    "Could not get KeyMint instance: {} failed with error code {:?}",
+                    service_name, e
+                ))
+            })?;
+
+        let result = BnKeystoreSecurityLevel::new_binder(Self {
+            security_level,
+            keymint: Asp::new(keymint.as_binder()),
+            operation_db: OperationDb::new(),
+        });
+        result.as_binder().set_requesting_sid(true);
+        Ok(result)
+    }
+
+    fn store_new_key(
+        &self,
+        key: KeyDescriptor,
+        km_cert_chain: Option<Vec<KmCertificate>>,
+        blob: Vec<u8>,
+    ) -> Result<(KeyDescriptor, Option<Certificate>, Option<CertificateChain>)> {
+        let (cert, cert_chain) = match km_cert_chain {
+            Some(mut chain) => (
+                match chain.len() {
+                    0 => None,
+                    _ => Some(Certificate { data: chain.remove(0).encodedCertificate }),
+                },
+                match chain.len() {
+                    0 => None,
+                    _ => Some(CertificateChain {
+                        data: chain
+                            .iter()
+                            .map(|c| c.encodedCertificate.iter())
+                            .flatten()
+                            .copied()
+                            .collect(),
+                    }),
+                },
+            ),
+            None => (None, None),
+        };
+
+        let key = match key.domain {
+            Domain::BLOB => {
+                KeyDescriptor { domain: Domain::BLOB, blob: Some(blob), ..Default::default() }
+            }
+            _ => DB
+                .with(|db| {
+                    let mut db = db.borrow_mut();
+                    let key_id = db
+                        .create_key_entry(key.domain, key.nspace)
+                        .context("Trying to create a key entry.")?;
+                    db.insert_blob(key_id, SubComponentType::KM_BLOB, &blob, self.security_level)
+                        .context("Trying to insert km blob.")?;
+                    if let Some(c) = &cert {
+                        db.insert_blob(
+                            key_id,
+                            SubComponentType::CERT,
+                            &c.data,
+                            self.security_level,
+                        )
+                        .context("Trying to insert cert blob.")?;
+                    }
+                    if let Some(c) = &cert_chain {
+                        db.insert_blob(
+                            key_id,
+                            SubComponentType::CERT_CHAIN,
+                            &c.data,
+                            self.security_level,
+                        )
+                        .context("Trying to insert cert chain blob.")?;
+                    }
+                    match &key.alias {
+                        Some(alias) => db
+                            .rebind_alias(key_id, alias, key.domain, key.nspace)
+                            .context("Failed to rebind alias.")?,
+                        None => {
+                            return Err(error::Error::sys()).context(
+                                "Alias must be specified. (This should have been checked earlier.)",
+                            )
+                        }
+                    }
+                    Ok(KeyDescriptor {
+                        domain: Domain::KEY_ID,
+                        nspace: key_id,
+                        ..Default::default()
+                    })
+                })
+                .context("In store_new_key.")?,
+        };
+
+        Ok((key, cert, cert_chain))
+    }
+
+    fn create(
+        &self,
+        key: &KeyDescriptor,
+        operation_parameters: &[KeyParameter],
+        forced: bool,
+    ) -> Result<(Box<dyn IKeystoreOperation>, Option<OperationChallenge>)> {
+        let caller_uid = ThreadState::get_calling_uid();
+        // We use `scoping_blob` to extend the life cycle of the blob loaded from the database,
+        // so that we can use it by reference like the blob provided by the key descriptor.
+        // Otherwise, we would have to clone the blob from the key descriptor.
+        let scoping_blob: Vec<u8>;
+        let (km_blob, key_id) =
+            match key.domain {
+                Domain::BLOB => {
+                    check_key_permission(KeyPerm::use_(), key, &None)
+                        .context("In create: checking use permission for Domain::BLOB.")?;
+                    (
+                        match &key.blob {
+                            Some(blob) => blob,
+                            None => return Err(Error::sys()).context(
+                                "In create: Key blob must be specified when using Domain::BLOB.",
+                            ),
+                        },
+                        None,
+                    )
+                }
+                _ => {
+                    let mut key_entry = DB
+                        .with::<_, Result<KeyEntry>>(|db| {
+                            db.borrow_mut().load_key_entry(
+                                key.clone(),
+                                KeyEntryLoadBits::KM,
+                                caller_uid,
+                                |k, av| check_key_permission(KeyPerm::use_(), k, &av),
+                            )
+                        })
+                        .context("In create: Failed to load key blob.")?;
+                    scoping_blob = match key_entry.take_km_blob() {
+                        Some(blob) => blob,
+                        None => return Err(Error::sys()).context(
+                            "In create: Successfully loaded key entry, but KM blob was missing.",
+                        ),
+                    };
+                    (&scoping_blob, Some(key_entry.id()))
+                }
+            };
+
+        // TODO Authorize begin operation.
+        // Check if we need an authorization token.
+        // Lookup authorization token and request VerificationToken if required.
+
+        let purpose = operation_parameters.iter().find(|p| p.tag == Tag::PURPOSE.0).map_or(
+            Err(Error::Km(ErrorCode::INVALID_ARGUMENT))
+                .context("In create: No operation purpose specified."),
+            |kp| Ok(KeyPurpose(kp.integer)),
+        )?;
+
+        let km_params =
+            operation_parameters.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>();
+
+        let km_dev: Box<dyn IKeyMintDevice> =
+            self.keymint.get_interface().context("In create: Failed to get KeyMint device")?;
+
+        let (begin_result, upgraded_blob) = loop {
+            match map_km_error(km_dev.begin(purpose, &km_blob, &km_params, &Default::default())) {
+                Ok(result) => break (result, None),
+                Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
+                    self.operation_db.prune(caller_uid).context("In create: Outer loop.")?;
+                    continue;
+                }
+                Err(Error::Km(ErrorCode::KEY_REQUIRES_UPGRADE)) => {
+                    let upgraded_blob = map_km_error(km_dev.upgradeKey(&km_blob, &km_params))
+                        .context("In create: Upgrade failed.")?;
+                    break loop {
+                        match map_km_error(km_dev.begin(
+                            purpose,
+                            &upgraded_blob,
+                            &km_params,
+                            &Default::default(),
+                        )) {
+                            Ok(result) => break (result, Some(upgraded_blob)),
+                            // If Keystore 2.0 is multi threaded another request may have
+                            // snatched up our previously pruned operation slot. So we might
+                            // need to prune again.
+                            Err(Error::Km(ErrorCode::TOO_MANY_OPERATIONS)) => {
+                                self.operation_db
+                                    .prune(caller_uid)
+                                    .context("In create: Inner loop.")?;
+                                continue;
+                            }
+                            Err(e) => {
+                                return Err(e)
+                                    .context("In create: Begin operation failed after upgrade.")
+                            }
+                        }
+                    };
+                }
+                Err(e) => return Err(e).context("In create: Begin operation failed."),
+            };
+        };
+
+        if let Some(upgraded_blob) = upgraded_blob {
+            if let Some(key_id) = key_id {
+                DB.with(|db| {
+                    db.borrow_mut().insert_blob(
+                        key_id,
+                        SubComponentType::KM_BLOB,
+                        &upgraded_blob,
+                        self.security_level,
+                    )
+                })
+                .context("In create: Failed to insert upgraded blob into the database.")?;
+            }
+        }
+
+        let operation = match begin_result.operation {
+            Some(km_op) => self.operation_db.create_operation(km_op, caller_uid),
+            None => return Err(Error::sys()).context("In create: Begin operation returned successfully, but did not return a valid operation."),
+        };
+
+        let op_binder: Box<dyn IKeystoreOperation> =
+            KeystoreOperation::new_native_binder(operation)
+                .as_binder()
+                .into_interface()
+                .context("In create: Failed to create IKeystoreOperation.")?;
+
+        // TODO find out what to do with the returned parameters.
+
+        // TODO we need to the enforcement module to determine if we need to return the challenge.
+        // We return None for now because we don't support auth bound keys yet.
+        Ok((op_binder, None))
+    }
+
+    fn generate_key(
+        &self,
+        key: &KeyDescriptor,
+        params: &[KeyParameter],
+        entropy: &[u8],
+    ) -> Result<(KeyDescriptor, Option<Certificate>, Option<CertificateChain>)> {
+        if key.domain != Domain::BLOB && key.alias.is_none() {
+            return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+                .context("In generate_key: Alias must be specified");
+        }
+
+        let key = match key.domain {
+            Domain::APP => KeyDescriptor {
+                domain: key.domain,
+                nspace: ThreadState::get_calling_uid() as i64,
+                alias: key.alias.clone(),
+                blob: None,
+            },
+            _ => key.clone(),
+        };
+
+        // generate_key requires the rebind permission.
+        check_key_permission(KeyPerm::rebind(), &key, &None).context("In generate_key.")?;
+
+        let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
+        map_km_error(km_dev.addRngEntropy(entropy))?;
+        let mut blob: Vec<u8> = Default::default();
+        let mut key_characteristics: KeyCharacteristics = Default::default();
+        let mut certificate_chain: Vec<KmCertificate> = Default::default();
+        map_km_error(km_dev.generateKey(
+            &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
+            &mut blob,
+            &mut key_characteristics,
+            &mut certificate_chain,
+        ))?;
+
+        self.store_new_key(key, Some(certificate_chain), blob).context("In generate_key.")
+    }
+
+    fn import_key(
+        &self,
+        key: &KeyDescriptor,
+        params: &[KeyParameter],
+        key_data: &[u8],
+    ) -> Result<(KeyDescriptor, Option<Certificate>, Option<CertificateChain>)> {
+        if key.domain != Domain::BLOB && key.alias.is_none() {
+            return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+                .context("In import_key: Alias must be specified");
+        }
+
+        let key = match key.domain {
+            Domain::APP => KeyDescriptor {
+                domain: key.domain,
+                nspace: ThreadState::get_calling_uid() as i64,
+                alias: key.alias.clone(),
+                blob: None,
+            },
+            _ => key.clone(),
+        };
+
+        // import_key requires the rebind permission.
+        check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_key.")?;
+
+        let mut blob: Vec<u8> = Default::default();
+        let mut key_characteristics: KeyCharacteristics = Default::default();
+        let mut certificate_chain: Vec<KmCertificate> = Default::default();
+
+        let format = params
+            .iter()
+            .find(|p| p.tag == Tag::ALGORITHM.0)
+            .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+            .context("No KeyParameter 'Algorithm'.")
+            .and_then(|p| match Algorithm(p.integer) {
+                Algorithm::AES | Algorithm::HMAC | Algorithm::TRIPLE_DES => Ok(KeyFormat::RAW),
+                Algorithm::RSA | Algorithm::EC => Ok(KeyFormat::PKCS8),
+                algorithm => Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+                    .context(format!("Unknown Algorithm {:?}.", algorithm)),
+            })
+            .context("In import_key.")?;
+
+        let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
+        map_km_error(km_dev.importKey(
+            &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
+            format,
+            key_data,
+            &mut blob,
+            &mut key_characteristics,
+            &mut certificate_chain,
+        ))?;
+
+        self.store_new_key(key, Some(certificate_chain), blob).context("In import_key.")
+    }
+
+    fn import_wrapped_key(
+        &self,
+        key: &KeyDescriptor,
+        wrapping_key: &KeyDescriptor,
+        masking_key: Option<&[u8]>,
+        params: &[KeyParameter],
+        authenticators: &[AuthenticatorSpec],
+    ) -> Result<(KeyDescriptor, Option<Certificate>, Option<CertificateChain>)> {
+        if key.domain != Domain::BLOB && key.alias.is_none() {
+            return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+                .context("In import_wrapped_key: Alias must be specified.");
+        }
+
+        let wrapped_data = match &key.blob {
+            Some(d) => d,
+            None => {
+                return Err(error::Error::Km(ErrorCode::INVALID_ARGUMENT)).context(
+                    "In import_wrapped_key: Blob must be specified and hold wrapped key data.",
+                )
+            }
+        };
+
+        let key = match key.domain {
+            Domain::APP => KeyDescriptor {
+                domain: key.domain,
+                nspace: ThreadState::get_calling_uid() as i64,
+                alias: key.alias.clone(),
+                blob: None,
+            },
+            _ => key.clone(),
+        };
+
+        // import_wrapped_key requires the rebind permission for the new key.
+        check_key_permission(KeyPerm::rebind(), &key, &None).context("In import_wrapped_key.")?;
+
+        let wrapping_key_entry = DB
+            .with(|db| {
+                db.borrow_mut().load_key_entry(
+                    wrapping_key.clone(),
+                    KeyEntryLoadBits::KM,
+                    ThreadState::get_calling_uid(),
+                    |k, av| check_key_permission(KeyPerm::use_(), k, &av),
+                )
+            })
+            .context("Failed to load wrapping key.")?;
+        let wrapping_key_blob = match wrapping_key_entry.km_blob() {
+            Some(blob) => blob,
+            None => {
+                return Err(error::Error::sys()).context(concat!(
+                    "No km_blob after successfully loading key.",
+                    " This should never happen."
+                ))
+            }
+        };
+
+        let mut blob: Vec<u8> = Default::default();
+        let mut key_characteristics: KeyCharacteristics = Default::default();
+        // km_dev.importWrappedKey does not return a certificate chain.
+        // TODO Do we assume that all wrapped keys are symmetric?
+        // let certificate_chain: Vec<KmCertificate> = Default::default();
+
+        let pw_sid = authenticators
+            .iter()
+            .find_map(|a| match a.authenticatorType {
+                AuthenticatorType::PASSWORD => Some(a.authenticatorId),
+                _ => None,
+            })
+            .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+            .context("A password authenticator SID must be specified.")?;
+
+        let fp_sid = authenticators
+            .iter()
+            .find_map(|a| match a.authenticatorType {
+                AuthenticatorType::FINGERPRINT => Some(a.authenticatorId),
+                _ => None,
+            })
+            .ok_or(error::Error::Km(ErrorCode::INVALID_ARGUMENT))
+            .context("A fingerprint authenticator SID must be specified.")?;
+
+        let masking_key = masking_key.unwrap_or(ZERO_BLOB_32);
+
+        let km_dev: Box<dyn IKeyMintDevice> = self.keymint.get_interface()?;
+        map_km_error(km_dev.importWrappedKey(
+            wrapped_data,
+            wrapping_key_blob,
+            masking_key,
+            &params.iter().map(|p| keyparam_ks_to_km(p)).collect::<Vec<KmParam>>(),
+            pw_sid,
+            fp_sid,
+            &mut blob,
+            &mut key_characteristics,
+        ))?;
+
+        self.store_new_key(key, None, blob).context("In import_wrapped_key.")
+    }
+}
+
+impl binder::Interface for KeystoreSecurityLevel {}
+
+impl IKeystoreSecurityLevel for KeystoreSecurityLevel {
+    fn create(
+        &self,
+        key: &KeyDescriptor,
+        operation_parameters: &[KeyParameter],
+        forced: bool,
+        challenge: &mut Option<OperationChallenge>,
+    ) -> binder::public_api::Result<Box<dyn IKeystoreOperation>> {
+        map_or_log_err(self.create(key, operation_parameters, forced), |v| {
+            *challenge = v.1;
+            Ok(v.0)
+        })
+    }
+    fn generateKey(
+        &self,
+        key: &KeyDescriptor,
+        params: &[KeyParameter],
+        entropy: &[u8],
+        result_key: &mut KeyDescriptor,
+        public_cert: &mut Option<Certificate>,
+        certificate_chain: &mut Option<CertificateChain>,
+    ) -> binder::public_api::Result<()> {
+        map_or_log_err(self.generate_key(key, params, entropy), |v| {
+            *result_key = v.0;
+            *public_cert = v.1;
+            *certificate_chain = v.2;
+            Ok(())
+        })
+    }
+    fn importKey(
+        &self,
+        key: &KeyDescriptor,
+        params: &[KeyParameter],
+        key_data: &[u8],
+        result_key: &mut KeyDescriptor,
+        public_cert: &mut Option<Certificate>,
+        certificate_chain: &mut Option<CertificateChain>,
+    ) -> binder::public_api::Result<()> {
+        map_or_log_err(self.import_key(key, params, key_data), |v| {
+            *result_key = v.0;
+            *public_cert = v.1;
+            *certificate_chain = v.2;
+            Ok(())
+        })
+    }
+    fn importWrappedKey(
+        &self,
+        key: &KeyDescriptor,
+        wrapping_key: &KeyDescriptor,
+        masking_key: Option<&[u8]>,
+        params: &[KeyParameter],
+        authenticators: &[AuthenticatorSpec],
+        result_key: &mut KeyDescriptor,
+        public_cert: &mut Option<Certificate>,
+        certificate_chain: &mut Option<CertificateChain>,
+    ) -> binder::public_api::Result<()> {
+        map_or_log_err(
+            self.import_wrapped_key(key, wrapping_key, masking_key, params, authenticators),
+            |v| {
+                *result_key = v.0;
+                *public_cert = v.1;
+                *certificate_chain = v.2;
+                Ok(())
+            },
+        )
+    }
+}
diff --git a/keystore2/src/service.rs b/keystore2/src/service.rs
new file mode 100644
index 0000000..ea17766
--- /dev/null
+++ b/keystore2/src/service.rs
@@ -0,0 +1,254 @@
+// 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 remove when fully implemented.
+#![allow(unused_variables)]
+
+//! This crate implement the core Keystore 2.0 service API as defined by the Keystore 2.0
+//! AIDL spec.
+
+use crate::database::{KeyEntry, KeyEntryLoadBits, SubComponentType};
+use crate::error::{self, map_or_log_err, ErrorCode};
+use crate::globals::DB;
+use crate::permission;
+use crate::permission::KeyPerm;
+use crate::security_level::KeystoreSecurityLevel;
+use crate::utils::{check_grant_permission, check_key_permission, Asp};
+use android_system_keystore2::aidl::android::system::keystore2::{
+    Certificate::Certificate, CertificateChain::CertificateChain, Domain::Domain,
+    IKeystoreSecurityLevel::IKeystoreSecurityLevel, IKeystoreService::BnKeystoreService,
+    IKeystoreService::IKeystoreService, KeyDescriptor::KeyDescriptor, KeyMetadata::KeyMetadata,
+    SecurityLevel::SecurityLevel,
+};
+use anyhow::{anyhow, Context, Result};
+use binder::{IBinder, Interface, ThreadState};
+
+/// Implementation of the IKeystoreService.
+pub struct KeystoreService {
+    sec_level: Asp,
+}
+
+impl KeystoreService {
+    /// Create a new instance of the Keystore 2.0 service.
+    pub fn new_native_binder() -> Result<impl IKeystoreService> {
+        let result = BnKeystoreService::new_binder(Self {
+            sec_level: Asp::new({
+                let sec_level =
+                    KeystoreSecurityLevel::new_native_binder(SecurityLevel::TRUSTED_ENVIRONMENT)
+                        .context("While trying to create IKeystoreSecurityLevel")?;
+                sec_level.as_binder()
+            }),
+        });
+        result.as_binder().set_requesting_sid(true);
+        Ok(result)
+    }
+
+    fn get_security_level(
+        &self,
+        security_level: SecurityLevel,
+    ) -> Result<Box<dyn IKeystoreSecurityLevel>> {
+        match security_level {
+            SecurityLevel::TRUSTED_ENVIRONMENT => self
+                .sec_level
+                .get_interface()
+                .context("In get_security_level: Failed to get IKeystoreSecurityLevel."),
+            _ => Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
+        }
+    }
+
+    fn get_key_entry(
+        &self,
+        key: &KeyDescriptor,
+    ) -> Result<(
+        KeyMetadata,
+        Option<Certificate>,
+        Option<CertificateChain>,
+        Box<dyn IKeystoreSecurityLevel>,
+    )> {
+        let mut key_entry: KeyEntry = DB
+            .with(|db| {
+                db.borrow_mut().load_key_entry(
+                    key.clone(),
+                    KeyEntryLoadBits::PUBLIC,
+                    ThreadState::get_calling_uid(),
+                    |k, av| check_key_permission(KeyPerm::get_info(), k, &av),
+                )
+            })
+            .context("In get_key_entry, while trying to load key info.")?;
+
+        let i_sec_level = match key_entry.sec_level() {
+            SecurityLevel::TRUSTED_ENVIRONMENT => self
+                .sec_level
+                .get_interface()
+                .context("In get_key_entry: Failed to get IKeystoreSecurityLevel.")?,
+            _ => return Err(anyhow!(error::Error::Km(ErrorCode::HARDWARE_TYPE_UNAVAILABLE))),
+        };
+
+        Ok((
+            KeyMetadata {
+                key: KeyDescriptor {
+                    domain: Domain::KEY_ID,
+                    nspace: key_entry.id(),
+                    ..Default::default()
+                },
+                securityLevel: key_entry.sec_level(),
+                // TODO add key characteristics here.
+                ..Default::default()
+            },
+            key_entry.take_cert().map(|v| Certificate { data: v }),
+            key_entry.take_cert_chain().map(|v| CertificateChain { data: v }),
+            i_sec_level,
+        ))
+    }
+
+    fn update_subcomponent(
+        &self,
+        key: &KeyDescriptor,
+        public_cert: Option<&Certificate>,
+        certificate_chain: Option<&CertificateChain>,
+    ) -> Result<()> {
+        DB.with::<_, Result<()>>(|db| {
+            let mut db = db.borrow_mut();
+            let key_entry = db
+                .load_key_entry(
+                    key.clone(),
+                    KeyEntryLoadBits::NONE,
+                    ThreadState::get_calling_uid(),
+                    |k, av| {
+                        check_key_permission(KeyPerm::update(), k, &av)
+                            .context("In update_subcomponent.")
+                    },
+                )
+                .context("Failed to load key_entry.")?;
+
+            if let Some(cert) = public_cert {
+                db.insert_blob(
+                    key_entry.id(),
+                    SubComponentType::CERT,
+                    &cert.data,
+                    key_entry.sec_level(),
+                )
+                .context("Failed to update cert subcomponent.")?;
+            }
+
+            if let Some(cert_chain) = certificate_chain {
+                db.insert_blob(
+                    key_entry.id(),
+                    SubComponentType::CERT_CHAIN,
+                    &cert_chain.data,
+                    key_entry.sec_level(),
+                )
+                .context("Failed to update cert chain subcomponent.")?;
+            }
+            Ok(())
+        })
+        .context("In update_subcomponent.")
+    }
+
+    fn list_entries(&self, domain: Domain, namespace: i64) -> Result<Vec<KeyDescriptor>> {
+        // TODO implement.
+        Err(anyhow!(error::Error::sys()))
+    }
+
+    fn delete_key(&self, key: &KeyDescriptor) -> Result<()> {
+        // TODO implement.
+        Err(anyhow!(error::Error::sys()))
+    }
+
+    fn grant(
+        &self,
+        key: &KeyDescriptor,
+        grantee_uid: i32,
+        access_vector: permission::KeyPermSet,
+    ) -> Result<KeyDescriptor> {
+        DB.with(|db| {
+            db.borrow_mut().grant(
+                key.clone(),
+                ThreadState::get_calling_uid(),
+                grantee_uid as u32,
+                access_vector,
+                |k, av| check_grant_permission(*av, k).context("During grant."),
+            )
+        })
+        .context("In KeystoreService::grant.")
+    }
+
+    fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> Result<()> {
+        DB.with(|db| {
+            db.borrow_mut().ungrant(
+                key.clone(),
+                ThreadState::get_calling_uid(),
+                grantee_uid as u32,
+                |k| check_key_permission(KeyPerm::grant(), k, &None),
+            )
+        })
+        .context("In KeystoreService::ungrant.")
+    }
+}
+
+impl binder::Interface for KeystoreService {}
+
+// Implementation of IKeystoreService. See AIDL spec at
+// system/security/keystore2/binder/android/security/keystore2/IKeystoreService.aidl
+impl IKeystoreService for KeystoreService {
+    fn getSecurityLevel(
+        &self,
+        security_level: SecurityLevel,
+    ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
+        map_or_log_err(self.get_security_level(security_level), Ok)
+    }
+    fn getKeyEntry(
+        &self,
+        key: &KeyDescriptor,
+        metadata: &mut KeyMetadata,
+        public_cert: &mut Option<Certificate>,
+        certificate_chain: &mut Option<CertificateChain>,
+    ) -> binder::public_api::Result<Box<dyn IKeystoreSecurityLevel>> {
+        map_or_log_err(self.get_key_entry(key), |v| {
+            *metadata = v.0;
+            *public_cert = v.1;
+            *certificate_chain = v.2;
+            Ok(v.3)
+        })
+    }
+    fn updateSubcomponent(
+        &self,
+        key: &KeyDescriptor,
+        public_cert: Option<&Certificate>,
+        certificate_chain: Option<&CertificateChain>,
+    ) -> binder::public_api::Result<()> {
+        map_or_log_err(self.update_subcomponent(key, public_cert, certificate_chain), Ok)
+    }
+    fn listEntries(
+        &self,
+        domain: Domain,
+        namespace: i64,
+    ) -> binder::public_api::Result<Vec<KeyDescriptor>> {
+        map_or_log_err(self.list_entries(domain, namespace), Ok)
+    }
+    fn deleteKey(&self, key: &KeyDescriptor) -> binder::public_api::Result<()> {
+        map_or_log_err(self.delete_key(key), Ok)
+    }
+    fn grant(
+        &self,
+        key: &KeyDescriptor,
+        grantee_uid: i32,
+        access_vector: i32,
+    ) -> binder::public_api::Result<KeyDescriptor> {
+        map_or_log_err(self.grant(key, grantee_uid, access_vector.into()), Ok)
+    }
+    fn ungrant(&self, key: &KeyDescriptor, grantee_uid: i32) -> binder::public_api::Result<()> {
+        map_or_log_err(self.ungrant(key, grantee_uid), Ok)
+    }
+}