Merge "Add SecurityLevel to key creation and operation logging."
diff --git a/fsverity_init/fsverity_init.cpp b/fsverity_init/fsverity_init.cpp
index b81fb22..7ab4097 100644
--- a/fsverity_init/fsverity_init.cpp
+++ b/fsverity_init/fsverity_init.cpp
@@ -49,6 +49,7 @@
 }
 
 void LoadKeyFromFile(key_serial_t keyring_id, const char* keyname, const std::string& path) {
+    LOG(INFO) << "LoadKeyFromFile path=" << path << " keyname=" << keyname;
     std::string content;
     if (!android::base::ReadFileToString(path, &content)) {
         LOG(ERROR) << "Failed to read key from " << path;
@@ -59,22 +60,24 @@
     }
 }
 
-void LoadKeyFromDirectory(key_serial_t keyring_id, const char* keyname, const char* dir) {
+void LoadKeyFromDirectory(key_serial_t keyring_id, const char* keyname_prefix, const char* dir) {
     if (!std::filesystem::exists(dir)) {
         return;
     }
+    int counter = 0;
     for (const auto& entry : std::filesystem::directory_iterator(dir)) {
         if (!android::base::EndsWithIgnoreCase(entry.path().c_str(), ".der")) continue;
-
-        LoadKeyFromFile(keyring_id, keyname, entry.path());
+        std::string keyname = keyname_prefix + std::to_string(counter);
+        counter++;
+        LoadKeyFromFile(keyring_id, keyname.c_str(), entry.path());
     }
 }
 
 void LoadKeyFromVerifiedPartitions(key_serial_t keyring_id) {
     // NB: Directories need to be synced with FileIntegrityService.java in
     // frameworks/base.
-    LoadKeyFromDirectory(keyring_id, "fsv_system", "/system/etc/security/fsverity");
-    LoadKeyFromDirectory(keyring_id, "fsv_product", "/product/etc/security/fsverity");
+    LoadKeyFromDirectory(keyring_id, "fsv_system_", "/system/etc/security/fsverity");
+    LoadKeyFromDirectory(keyring_id, "fsv_product_", "/product/etc/security/fsverity");
 }
 
 int main(int argc, const char** argv) {
diff --git a/identity/Credential.cpp b/identity/Credential.cpp
index 2e6b9c1..7c75d8a 100644
--- a/identity/Credential.cpp
+++ b/identity/Credential.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "Credential"
+#define LOG_TAG "credstore"
 
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
diff --git a/identity/CredentialData.cpp b/identity/CredentialData.cpp
index 96c436a..d95c1ac 100644
--- a/identity/CredentialData.cpp
+++ b/identity/CredentialData.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "CredentialData"
+#define LOG_TAG "credstore"
 
 #include <chrono>
 
diff --git a/identity/CredentialStore.cpp b/identity/CredentialStore.cpp
index 509e022..071cf24 100644
--- a/identity/CredentialStore.cpp
+++ b/identity/CredentialStore.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "CredentialStore"
+#define LOG_TAG "credstore"
 
 #include <algorithm>
 
diff --git a/identity/CredentialStoreFactory.cpp b/identity/CredentialStoreFactory.cpp
index 5c3bf36..0e901ba 100644
--- a/identity/CredentialStoreFactory.cpp
+++ b/identity/CredentialStoreFactory.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "CredentialStoreFactory"
+#define LOG_TAG "credstore"
 
 #include <android-base/logging.h>
 
diff --git a/identity/TEST_MAPPING b/identity/TEST_MAPPING
new file mode 100644
index 0000000..87707a8
--- /dev/null
+++ b/identity/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "CtsIdentityTestCases"
+    }
+  ]
+}
diff --git a/identity/Util.cpp b/identity/Util.cpp
index cd29017..3a46bca 100644
--- a/identity/Util.cpp
+++ b/identity/Util.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "Util"
+#define LOG_TAG "credstore"
 
 #include <fcntl.h>
 #include <stdlib.h>
diff --git a/identity/WritableCredential.cpp b/identity/WritableCredential.cpp
index a300e51..9827d75 100644
--- a/identity/WritableCredential.cpp
+++ b/identity/WritableCredential.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "WritableCredential"
+#define LOG_TAG "credstore"
 
 #include <android-base/logging.h>
 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
diff --git a/identity/main.cpp b/identity/main.cpp
index 9add73c..2559789 100644
--- a/identity/main.cpp
+++ b/identity/main.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "android.security.identity"
+#define LOG_TAG "credstore"
 
 #include <filesystem>
 
@@ -51,7 +51,7 @@
 
     auto ret = sm->addService(String16("android.security.identity"), factory);
     CHECK(ret == ::android::OK) << "Couldn't register binder service";
-    LOG(ERROR) << "Registered binder service";
+    LOG(INFO) << "Registered binder service";
 
     // Credstore is a single-threaded process. So devote the main thread
     // to handling binder messages.
diff --git a/keystore2/TEST_MAPPING b/keystore2/TEST_MAPPING
index 99a1e60..16b6f85 100644
--- a/keystore2/TEST_MAPPING
+++ b/keystore2/TEST_MAPPING
@@ -8,6 +8,9 @@
     },
     {
       "name": "keystore2_test"
+    },
+    {
+      "name": "CtsIdentityTestCases"
     }
   ]
 }
diff --git a/keystore2/src/crypto/zvec.rs b/keystore2/src/crypto/zvec.rs
index 4af7b5a..78b474e 100644
--- a/keystore2/src/crypto/zvec.rs
+++ b/keystore2/src/crypto/zvec.rs
@@ -104,12 +104,16 @@
 impl TryFrom<Vec<u8>> for ZVec {
     type Error = Error;
 
-    fn try_from(v: Vec<u8>) -> Result<Self, Self::Error> {
+    fn try_from(mut v: Vec<u8>) -> Result<Self, Self::Error> {
+        let len = v.len();
+        // into_boxed_slice calls shrink_to_fit, which may move the pointer.
+        // But sometimes the contents of the Vec are already sensitive and
+        // mustn't be copied. So ensure the shrink_to_fit call is a NOP.
+        v.resize(v.capacity(), 0);
         let b = v.into_boxed_slice();
         if !b.is_empty() {
             unsafe { mlock(b.as_ptr() as *const std::ffi::c_void, b.len()) }?;
         }
-        let len = b.len();
         Ok(Self { elems: b, len })
     }
 }
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 174a928..6a07716 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -3025,7 +3025,7 @@
     where
         F: Fn(&Uuid, &[u8]) -> Result<()> + Send + 'static,
     {
-        let super_key = Arc::new(SuperKeyManager::new());
+        let super_key: Arc<SuperKeyManager> = Default::default();
 
         let gc_db = KeystoreDB::new(path, None).expect("Failed to open test gc db_connection.");
         let gc = Gc::new_init_with(Default::default(), move || (Box::new(cb), gc_db, super_key));
diff --git a/keystore2/src/key_parameter.rs b/keystore2/src/key_parameter.rs
index c10da95..e536e45 100644
--- a/keystore2/src/key_parameter.rs
+++ b/keystore2/src/key_parameter.rs
@@ -776,7 +776,7 @@
 
 implement_key_parameter_value! {
 /// KeyParameterValue holds a value corresponding to one of the Tags defined in
-/// the AIDL spec at hardware/interfaces/keymint
+/// the AIDL spec at hardware/interfaces/security/keymint
 #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
 pub enum KeyParameterValue {
     /// Associated with Tag:INVALID
diff --git a/keystore2/src/legacy_blob.rs b/keystore2/src/legacy_blob.rs
index 7c8a909..c108b32 100644
--- a/keystore2/src/legacy_blob.rs
+++ b/keystore2/src/legacy_blob.rs
@@ -1285,7 +1285,7 @@
             CACERT_NON_AUTHBOUND,
         )?;
 
-        let key_manager = crate::super_key::SuperKeyManager::new();
+        let key_manager: SuperKeyManager = Default::default();
         let mut db = crate::database::KeystoreDB::new(temp_dir.path(), None)?;
         let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
 
diff --git a/keystore2/src/super_key.rs b/keystore2/src/super_key.rs
index d490354..3fa4cf0 100644
--- a/keystore2/src/super_key.rs
+++ b/keystore2/src/super_key.rs
@@ -92,22 +92,6 @@
     ScreenLockBound,
 }
 
-#[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<SuperKey>>,
-    /// 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.
-    screen_lock_bound: Option<Arc<SuperKey>>,
-    /// When the device is locked, screen-lock-bound keys can still be encrypted, using
-    /// ECDH public-key encryption. This field holds the decryption private key.
-    screen_lock_bound_private: Option<Arc<SuperKey>>,
-}
-
 pub struct SuperKey {
     algorithm: SuperEncryptionAlgorithm,
     key: ZVec,
@@ -130,10 +114,22 @@
             Err(Error::sys()).context("In aes_gcm_decrypt: Key is not an AES key")
         }
     }
+}
 
-    pub fn get_id(&self) -> i64 {
-        self.id
-    }
+#[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<SuperKey>>,
+    /// 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.
+    screen_lock_bound: Option<Arc<SuperKey>>,
+    /// When the device is locked, screen-lock-bound keys can still be encrypted, using
+    /// ECDH public-key encryption. This field holds the decryption private key.
+    screen_lock_bound_private: Option<Arc<SuperKey>>,
 }
 
 #[derive(Default)]
@@ -154,10 +150,6 @@
 }
 
 impl SuperKeyManager {
-    pub fn new() -> Self {
-        Default::default()
-    }
-
     pub fn forget_all_keys_for_user(&self, user: UserId) {
         let mut data = self.data.lock().unwrap();
         data.user_keys.remove(&user);
@@ -169,7 +161,7 @@
         data.user_keys.entry(user).or_default().per_boot = Some(super_key);
     }
 
-    fn get_key(&self, key_id: &i64) -> Option<Arc<SuperKey>> {
+    fn lookup_key(&self, key_id: &i64) -> Option<Arc<SuperKey>> {
         self.data.lock().unwrap().key_index.get(key_id).and_then(|k| k.upgrade())
     }
 
@@ -225,23 +217,25 @@
 
     /// 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
+    /// It then checks if the required key is memory resident, and if so decrypts the
     /// blob.
     pub fn unwrap_key<'a>(&self, blob: &'a [u8], metadata: &BlobMetaData) -> Result<KeyBlob<'a>> {
-        match metadata.encrypted_by() {
-            Some(EncryptedBy::KeyId(key_id)) => match self.get_key(key_id) {
-                Some(super_key) => Ok(KeyBlob::Sensitive {
-                    key: Self::unwrap_key_with_key(blob, metadata, &super_key)
-                        .context("In unwrap_key: unwrap_key_with_key failed")?,
-                    reencrypt_with: super_key.reencrypt_with.as_ref().unwrap_or(&super_key).clone(),
-                    force_reencrypt: super_key.reencrypt_with.is_some(),
-                }),
-                None => Err(Error::Rc(ResponseCode::LOCKED))
-                    .context("In unwrap_key: Required super decryption key is not in memory."),
-            },
-            _ => Err(Error::Rc(ResponseCode::VALUE_CORRUPTED))
-                .context("In unwrap_key: Cannot determined wrapping key."),
-        }
+        let key_id = if let Some(EncryptedBy::KeyId(key_id)) = metadata.encrypted_by() {
+            key_id
+        } else {
+            return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED))
+                .context("In unwrap_key: Cannot determine wrapping key.");
+        };
+        let super_key = self
+            .lookup_key(&key_id)
+            .ok_or(Error::Rc(ResponseCode::LOCKED))
+            .context("In unwrap_key: Required super decryption key is not in memory.")?;
+        Ok(KeyBlob::Sensitive {
+            key: Self::unwrap_key_with_key(blob, metadata, &super_key)
+                .context("In unwrap_key: unwrap_key_with_key failed")?,
+            reencrypt_with: super_key.reencrypt_with.as_ref().unwrap_or(&super_key).clone(),
+            force_reencrypt: super_key.reencrypt_with.is_some(),
+        })
     }
 
     /// Unwraps an encrypted key blob given an encryption key.
@@ -427,9 +421,9 @@
                     return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
                         concat!(
                         "In extract_super_key_from_key_entry: Super key has incomplete metadata.",
-                        "Present: encrypted_by: {}, salt: {}, iv: {}, aead_tag: {}."
+                        "encrypted_by: {:?}; Present: salt: {}, iv: {}, aead_tag: {}."
                     ),
-                        enc_by.is_some(),
+                        enc_by,
                         salt.is_some(),
                         iv.is_some(),
                         tag.is_some()
@@ -523,19 +517,19 @@
     ) -> Result<(Vec<u8>, BlobMetaData)> {
         match Enforcements::super_encryption_required(domain, key_parameters, flags) {
             SuperEncryptionType::None => Ok((key_blob.to_vec(), BlobMetaData::new())),
-            SuperEncryptionType::LskfBound => {
-                self.super_encrypt_on_key_init(db, legacy_migrator, user_id, &key_blob).context(
-                    "In handle_super_encryption_on_key_init.
-                         Failed to super encrypt the key.",
-                )
-            }
+            SuperEncryptionType::LskfBound => self
+                .super_encrypt_on_key_init(db, legacy_migrator, user_id, &key_blob)
+                .context(concat!(
+                    "In handle_super_encryption_on_key_init. ",
+                    "Failed to super encrypt with LskfBound key."
+                )),
             SuperEncryptionType::ScreenLockBound => {
                 let mut data = self.data.lock().unwrap();
                 let entry = data.user_keys.entry(user_id).or_default();
                 if let Some(super_key) = entry.screen_lock_bound.as_ref() {
                     Self::encrypt_with_aes_super_key(key_blob, &super_key).context(concat!(
                         "In handle_super_encryption_on_key_init. ",
-                        "Failed to encrypt the key with screen_lock_bound key."
+                        "Failed to encrypt with ScreenLockBound key."
                     ))
                 } else {
                     // Symmetric key is not available, use public key encryption
diff --git a/ondevice-signing/TEST_MAPPING b/ondevice-signing/TEST_MAPPING
new file mode 100644
index 0000000..03b9b95
--- /dev/null
+++ b/ondevice-signing/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "odsign_e2e_tests"
+    }
+  ]
+}