Keystore 2.0: Add super encryption infrastructure.

Add super_key.rs a runtime key database for credential based keys and
the relevant metadata fields to the database.

Also in this patch:
* Add DateTime type to represent database wall clock time.
* Move creation time to key metadata.
* Add KeyType field to the keyentry table to accommodate super keys
  and attestation keys.

Test: keystore2_test
Bug: 173545997
Change-Id: I670898174fb0223bf1c910051dfd7ead80b2c1a9
diff --git a/keystore2/src/super_key.rs b/keystore2/src/super_key.rs
new file mode 100644
index 0000000..d204ae7
--- /dev/null
+++ b/keystore2/src/super_key.rs
@@ -0,0 +1,199 @@
+// 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(dead_code)]
+
+use crate::{
+    database::EncryptedBy, database::KeyMetaData, database::KeyMetaEntry, database::KeystoreDB,
+    error::Error, error::ResponseCode,
+};
+use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain;
+use anyhow::{Context, Result};
+use keystore2_crypto::{
+    aes_gcm_decrypt, aes_gcm_encrypt, derive_key_from_password, generate_salt, ZVec,
+    AES_256_KEY_LENGTH,
+};
+use std::{
+    collections::HashMap,
+    sync::Arc,
+    sync::{Mutex, Weak},
+};
+
+type UserId = u32;
+
+#[derive(Default)]
+struct UserSuperKeys {
+    /// The per boot key is used for LSKF binding of authentication bound keys. There is one
+    /// key per android user. The key is stored on flash encrypted with a key derived from a
+    /// secret, that is itself derived from the user's lock screen knowledge factor (LSKF).
+    /// When the user unlocks the device for the first time, this key is unlocked, i.e., decrypted,
+    /// and stays memory resident until the device reboots.
+    per_boot: Option<Arc<ZVec>>,
+    /// The screen lock key works like the per boot key with the distinction that it is cleared
+    /// from memory when the screen lock is engaged.
+    /// TODO the life cycle is not fully implemented at this time.
+    screen_lock: Option<Arc<ZVec>>,
+}
+
+#[derive(Default)]
+struct SkmState {
+    user_keys: HashMap<UserId, UserSuperKeys>,
+    key_index: HashMap<i64, Weak<ZVec>>,
+}
+
+#[derive(Default)]
+pub struct SuperKeyManager {
+    data: Mutex<SkmState>,
+}
+
+impl SuperKeyManager {
+    pub fn new() -> Self {
+        Self { data: Mutex::new(Default::default()) }
+    }
+
+    pub fn forget_screen_lock_key_for_user(&self, user: UserId) {
+        let mut data = self.data.lock().unwrap();
+        if let Some(usk) = data.user_keys.get_mut(&user) {
+            usk.screen_lock = None;
+        }
+    }
+
+    pub fn forget_screen_lock_keys(&self) {
+        let mut data = self.data.lock().unwrap();
+        for (_, usk) in data.user_keys.iter_mut() {
+            usk.screen_lock = None;
+        }
+    }
+
+    pub fn forget_all_keys_for_user(&self, user: UserId) {
+        let mut data = self.data.lock().unwrap();
+        data.user_keys.remove(&user);
+    }
+
+    pub fn forget_all_keys(&self) {
+        let mut data = self.data.lock().unwrap();
+        data.user_keys.clear();
+        data.key_index.clear();
+    }
+
+    fn install_per_boot_key_for_user(&self, user: UserId, key_id: i64, key: ZVec) {
+        let mut data = self.data.lock().unwrap();
+        let key = Arc::new(key);
+        data.key_index.insert(key_id, Arc::downgrade(&key));
+        data.user_keys.entry(user).or_default().per_boot = Some(key);
+    }
+
+    fn get_key(&self, key_id: &i64) -> Option<Arc<ZVec>> {
+        self.data.lock().unwrap().key_index.get(key_id).and_then(|k| k.upgrade())
+    }
+
+    pub fn get_per_boot_key_by_user_id(&self, user_id: u32) -> Option<Arc<ZVec>> {
+        let data = self.data.lock().unwrap();
+        data.user_keys.get(&user_id).map(|e| e.per_boot.clone()).flatten()
+    }
+
+    /// This function unlocks the super keys for a given user.
+    /// This means the key is loaded from the database, decrypted and placed in the
+    /// super key cache. If there is no such key a new key is created, encrypted with
+    /// a key derived from the given password and stored in the database.
+    pub fn unlock_user_key(&self, user: UserId, pw: &[u8], db: &mut KeystoreDB) -> Result<()> {
+        let (_, entry) = db
+            .get_or_create_key_with(Domain::APP, user as u64 as i64, &"USER_SUPER_KEY", || {
+                let super_key = keystore2_crypto::generate_aes256_key()
+                    .context("In create_new_key: Failed to generate AES 256 key.")?;
+
+                let salt =
+                    generate_salt().context("In create_new_key: Failed to generate salt.")?;
+                let derived_key = derive_key_from_password(pw, Some(&salt), AES_256_KEY_LENGTH)
+                    .context("In create_new_key: Failed to derive password.")?;
+                let mut metadata = KeyMetaData::new();
+                metadata.add(KeyMetaEntry::EncryptedBy(EncryptedBy::Password));
+                metadata.add(KeyMetaEntry::Salt(salt));
+                let (encrypted_key, iv, tag) = aes_gcm_encrypt(&super_key, &derived_key)
+                    .context("In create_new_key: Failed to encrypt new super key.")?;
+                metadata.add(KeyMetaEntry::Iv(iv));
+                metadata.add(KeyMetaEntry::AeadTag(tag));
+                Ok((encrypted_key, metadata))
+            })
+            .context("In unlock_user_key: Failed to get key id.")?;
+
+        let metadata = entry.metadata();
+        let super_key = match (
+            metadata.encrypted_by(),
+            metadata.salt(),
+            metadata.iv(),
+            metadata.aead_tag(),
+            entry.km_blob(),
+        ) {
+            (Some(&EncryptedBy::Password), Some(salt), Some(iv), Some(tag), Some(blob)) => {
+                let key = derive_key_from_password(pw, Some(salt), AES_256_KEY_LENGTH)
+                    .context("In unlock_user_key: Failed to generate key from password.")?;
+
+                aes_gcm_decrypt(blob, iv, tag, &key)
+                    .context("In unlock_user_key: Failed to decrypt key blob.")?
+            }
+            (enc_by, salt, iv, tag, blob) => {
+                return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
+                    concat!(
+                        "In unlock_user_key: Super key has incomplete metadata.",
+                        "Present: encrypted_by: {}, salt: {}, iv: {}, aead_tag: {}, blob: {}."
+                    ),
+                    enc_by.is_some(),
+                    salt.is_some(),
+                    iv.is_some(),
+                    tag.is_some(),
+                    blob.is_some()
+                ));
+            }
+        };
+
+        self.install_per_boot_key_for_user(user, entry.id(), super_key);
+
+        Ok(())
+    }
+
+    /// Unwraps an encrypted key blob given metadata identifying the encryption key.
+    /// The function queries `metadata.encrypted_by()` to determine the encryption key.
+    /// It then check if the required key is memory resident, and if so decrypts the
+    /// blob.
+    pub fn unwrap_key(&self, blob: &[u8], metadata: &KeyMetaData) -> Result<ZVec> {
+        match metadata.encrypted_by() {
+            Some(EncryptedBy::KeyId(key_id)) => match self.get_key(key_id) {
+                Some(key) => {
+                    Self::unwrap_key_with_key(blob, metadata, &key).context("In unwrap_key.")
+                }
+                None => Err(Error::Rc(ResponseCode::LOCKED))
+                    .context("In unwrap_key: Key is not usable until the user entered their LSKF."),
+            },
+            _ => Err(Error::Rc(ResponseCode::VALUE_CORRUPTED))
+                .context("In unwrap_key: Cannot determined wrapping key."),
+        }
+    }
+
+    /// Unwraps an encrypted key blob given an encryption key.
+    fn unwrap_key_with_key(blob: &[u8], metadata: &KeyMetaData, key: &[u8]) -> Result<ZVec> {
+        match (metadata.iv(), metadata.aead_tag()) {
+            (Some(iv), Some(tag)) => aes_gcm_decrypt(blob, iv, tag, key)
+                .context("In unwrap_key_with_key: Failed to decrypt the key blob."),
+            (iv, tag) => Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
+                concat!(
+                    "In unwrap_key_with_key: Key has incomplete metadata.",
+                    "Present: iv: {}, aead_tag: {}."
+                ),
+                iv.is_some(),
+                tag.is_some(),
+            )),
+        }
+    }
+}