diff --git a/keystore2/src/legacy_blob.rs b/keystore2/src/legacy_blob.rs
index 2bb7f27..c27a050 100644
--- a/keystore2/src/legacy_blob.rs
+++ b/keystore2/src/legacy_blob.rs
@@ -36,6 +36,9 @@
 
 const SUPPORTED_LEGACY_BLOB_VERSION: u8 = 3;
 
+#[cfg(test)]
+mod tests;
+
 mod flags {
     /// This flag is deprecated. It is here to support keys that have been written with this flag
     /// set, but we don't create any new keys with this flag.
@@ -1645,675 +1648,3 @@
         Ok(())
     }
 }
-
-#[cfg(test)]
-mod test {
-    #![allow(dead_code)]
-    use super::*;
-    use crate::legacy_blob::test_utils::legacy_blob_test_vectors::*;
-    use crate::legacy_blob::test_utils::*;
-    use anyhow::{anyhow, Result};
-    use keystore2_crypto::aes_gcm_decrypt;
-    use keystore2_test_utils::TempDir;
-    use rand::Rng;
-    use std::convert::TryInto;
-    use std::ops::Deref;
-    use std::string::FromUtf8Error;
-
-    #[test]
-    fn decode_encode_alias_test() {
-        static ALIAS: &str = "#({}test[])😗";
-        static ENCODED_ALIAS: &str = "+S+X{}test[]+Y.`-O-H-G";
-        // Second multi byte out of range ------v
-        static ENCODED_ALIAS_ERROR1: &str = "+S+{}test[]+Y";
-        // Incomplete multi byte ------------------------v
-        static ENCODED_ALIAS_ERROR2: &str = "+S+X{}test[]+";
-        // Our encoding: ".`-O-H-G"
-        // is UTF-8: 0xF0 0x9F 0x98 0x97
-        // is UNICODE: U+1F617
-        // is 😗
-        // But +H below is a valid encoding for 0x18 making this sequence invalid UTF-8.
-        static ENCODED_ALIAS_ERROR_UTF8: &str = ".`-O+H-G";
-
-        assert_eq!(ENCODED_ALIAS, &LegacyBlobLoader::encode_alias(ALIAS));
-        assert_eq!(ALIAS, &LegacyBlobLoader::decode_alias(ENCODED_ALIAS).unwrap());
-        assert_eq!(
-            Some(&Error::BadEncoding),
-            LegacyBlobLoader::decode_alias(ENCODED_ALIAS_ERROR1)
-                .unwrap_err()
-                .root_cause()
-                .downcast_ref::<Error>()
-        );
-        assert_eq!(
-            Some(&Error::BadEncoding),
-            LegacyBlobLoader::decode_alias(ENCODED_ALIAS_ERROR2)
-                .unwrap_err()
-                .root_cause()
-                .downcast_ref::<Error>()
-        );
-        assert!(LegacyBlobLoader::decode_alias(ENCODED_ALIAS_ERROR_UTF8)
-            .unwrap_err()
-            .root_cause()
-            .downcast_ref::<FromUtf8Error>()
-            .is_some());
-
-        for _i in 0..100 {
-            // Any valid UTF-8 string should be en- and decoded without loss.
-            let alias_str = rand::thread_rng().gen::<[char; 20]>().iter().collect::<String>();
-            let random_alias = alias_str.as_bytes();
-            let encoded = LegacyBlobLoader::encode_alias(&alias_str);
-            let decoded = match LegacyBlobLoader::decode_alias(&encoded) {
-                Ok(d) => d,
-                Err(_) => panic!("random_alias: {:x?}\nencoded {}", random_alias, encoded),
-            };
-            assert_eq!(random_alias.to_vec(), decoded.bytes().collect::<Vec<u8>>());
-        }
-    }
-
-    #[test]
-    fn read_golden_key_blob_test() -> anyhow::Result<()> {
-        let blob = LegacyBlobLoader::new_from_stream_decrypt_with(&mut &*BLOB, |_, _, _, _, _| {
-            Err(anyhow!("should not be called"))
-        })
-        .unwrap();
-        assert!(!blob.is_encrypted());
-        assert!(!blob.is_fallback());
-        assert!(!blob.is_strongbox());
-        assert!(!blob.is_critical_to_device_encryption());
-        assert_eq!(blob.value(), &BlobValue::Generic([0xde, 0xed, 0xbe, 0xef].to_vec()));
-
-        let blob = LegacyBlobLoader::new_from_stream_decrypt_with(
-            &mut &*REAL_LEGACY_BLOB,
-            |_, _, _, _, _| Err(anyhow!("should not be called")),
-        )
-        .unwrap();
-        assert!(!blob.is_encrypted());
-        assert!(!blob.is_fallback());
-        assert!(!blob.is_strongbox());
-        assert!(!blob.is_critical_to_device_encryption());
-        assert_eq!(
-            blob.value(),
-            &BlobValue::Decrypted(REAL_LEGACY_BLOB_PAYLOAD.try_into().unwrap())
-        );
-        Ok(())
-    }
-
-    #[test]
-    fn read_aes_gcm_encrypted_key_blob_test() {
-        let blob = LegacyBlobLoader::new_from_stream_decrypt_with(
-            &mut &*AES_GCM_ENCRYPTED_BLOB,
-            |d, iv, tag, salt, key_size| {
-                assert_eq!(salt, None);
-                assert_eq!(key_size, None);
-                assert_eq!(
-                    iv,
-                    &[
-                        0xbd, 0xdb, 0x8d, 0x69, 0x72, 0x56, 0xf0, 0xf5, 0xa4, 0x02, 0x88, 0x7f,
-                        0x00, 0x00, 0x00, 0x00,
-                    ]
-                );
-                assert_eq!(
-                    tag,
-                    &[
-                        0x50, 0xd9, 0x97, 0x95, 0x37, 0x6e, 0x28, 0x6a, 0x28, 0x9d, 0x51, 0xb9,
-                        0xb9, 0xe0, 0x0b, 0xc3
-                    ][..]
-                );
-                aes_gcm_decrypt(d, iv, tag, AES_KEY).context("Trying to decrypt blob.")
-            },
-        )
-        .unwrap();
-        assert!(blob.is_encrypted());
-        assert!(!blob.is_fallback());
-        assert!(!blob.is_strongbox());
-        assert!(!blob.is_critical_to_device_encryption());
-
-        assert_eq!(blob.value(), &BlobValue::Decrypted(DECRYPTED_PAYLOAD.try_into().unwrap()));
-    }
-
-    #[test]
-    fn read_golden_key_blob_too_short_test() {
-        let error =
-            LegacyBlobLoader::new_from_stream_decrypt_with(&mut &BLOB[0..15], |_, _, _, _, _| {
-                Err(anyhow!("should not be called"))
-            })
-            .unwrap_err();
-        assert_eq!(Some(&Error::BadLen), error.root_cause().downcast_ref::<Error>());
-    }
-
-    #[test]
-    fn test_is_empty() {
-        let temp_dir = TempDir::new("test_is_empty").expect("Failed to create temp dir.");
-        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
-
-        assert!(legacy_blob_loader.is_empty().expect("Should succeed and be empty."));
-
-        let _db = crate::database::KeystoreDB::new(temp_dir.path(), None)
-            .expect("Failed to open database.");
-
-        assert!(legacy_blob_loader.is_empty().expect("Should succeed and still be empty."));
-
-        std::fs::create_dir(&*temp_dir.build().push("user_0")).expect("Failed to create user_0.");
-
-        assert!(!legacy_blob_loader.is_empty().expect("Should succeed but not be empty."));
-
-        std::fs::create_dir(&*temp_dir.build().push("user_10")).expect("Failed to create user_10.");
-
-        assert!(!legacy_blob_loader.is_empty().expect("Should succeed but still not be empty."));
-
-        std::fs::remove_dir_all(&*temp_dir.build().push("user_0"))
-            .expect("Failed to remove user_0.");
-
-        assert!(!legacy_blob_loader.is_empty().expect("Should succeed but still not be empty."));
-
-        std::fs::remove_dir_all(&*temp_dir.build().push("user_10"))
-            .expect("Failed to remove user_10.");
-
-        assert!(legacy_blob_loader.is_empty().expect("Should succeed and be empty again."));
-    }
-
-    #[test]
-    fn test_legacy_blobs() -> anyhow::Result<()> {
-        let temp_dir = TempDir::new("legacy_blob_test").unwrap();
-        std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
-
-        std::fs::write(&*temp_dir.build().push("user_0").push(".masterkey"), SUPERKEY).unwrap();
-
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_USRPKEY_authbound"),
-            USRPKEY_AUTHBOUND,
-        )
-        .unwrap();
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_authbound"),
-            USRPKEY_AUTHBOUND_CHR,
-        )
-        .unwrap();
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
-            USRCERT_AUTHBOUND,
-        )
-        .unwrap();
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
-            CACERT_AUTHBOUND,
-        )
-        .unwrap();
-
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_USRPKEY_non_authbound"),
-            USRPKEY_NON_AUTHBOUND,
-        )
-        .unwrap();
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_non_authbound"),
-            USRPKEY_NON_AUTHBOUND_CHR,
-        )
-        .unwrap();
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_USRCERT_non_authbound"),
-            USRCERT_NON_AUTHBOUND,
-        )
-        .unwrap();
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_CACERT_non_authbound"),
-            CACERT_NON_AUTHBOUND,
-        )
-        .unwrap();
-
-        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
-
-        if let (Some((Blob { flags, value }, _params)), Some(cert), Some(chain)) =
-            legacy_blob_loader.load_by_uid_alias(10223, "authbound", &None)?
-        {
-            assert_eq!(flags, 4);
-            assert_eq!(
-                value,
-                BlobValue::Encrypted {
-                    data: USRPKEY_AUTHBOUND_ENC_PAYLOAD.to_vec(),
-                    iv: USRPKEY_AUTHBOUND_IV.to_vec(),
-                    tag: USRPKEY_AUTHBOUND_TAG.to_vec()
-                }
-            );
-            assert_eq!(&cert[..], LOADED_CERT_AUTHBOUND);
-            assert_eq!(&chain[..], LOADED_CACERT_AUTHBOUND);
-        } else {
-            panic!("");
-        }
-
-        if let (Some((Blob { flags, value: _ }, _params)), Some(cert), Some(chain)) =
-            legacy_blob_loader.load_by_uid_alias(10223, "authbound", &None)?
-        {
-            assert_eq!(flags, 4);
-            //assert_eq!(value, BlobValue::Encrypted(..));
-            assert_eq!(&cert[..], LOADED_CERT_AUTHBOUND);
-            assert_eq!(&chain[..], LOADED_CACERT_AUTHBOUND);
-        } else {
-            panic!("");
-        }
-        if let (Some((Blob { flags, value }, _params)), Some(cert), Some(chain)) =
-            legacy_blob_loader.load_by_uid_alias(10223, "non_authbound", &None)?
-        {
-            assert_eq!(flags, 0);
-            assert_eq!(value, BlobValue::Decrypted(LOADED_USRPKEY_NON_AUTHBOUND.try_into()?));
-            assert_eq!(&cert[..], LOADED_CERT_NON_AUTHBOUND);
-            assert_eq!(&chain[..], LOADED_CACERT_NON_AUTHBOUND);
-        } else {
-            panic!("");
-        }
-
-        legacy_blob_loader.remove_keystore_entry(10223, "authbound").expect("This should succeed.");
-        legacy_blob_loader
-            .remove_keystore_entry(10223, "non_authbound")
-            .expect("This should succeed.");
-
-        assert_eq!(
-            (None, None, None),
-            legacy_blob_loader.load_by_uid_alias(10223, "authbound", &None)?
-        );
-        assert_eq!(
-            (None, None, None),
-            legacy_blob_loader.load_by_uid_alias(10223, "non_authbound", &None)?
-        );
-
-        // The database should not be empty due to the super key.
-        assert!(!legacy_blob_loader.is_empty()?);
-        assert!(!legacy_blob_loader.is_empty_user(0)?);
-
-        // The database should be considered empty for user 1.
-        assert!(legacy_blob_loader.is_empty_user(1)?);
-
-        legacy_blob_loader.remove_super_key(0);
-
-        // Now it should be empty.
-        assert!(legacy_blob_loader.is_empty_user(0)?);
-        assert!(legacy_blob_loader.is_empty()?);
-
-        Ok(())
-    }
-
-    struct TestKey(ZVec);
-
-    impl crate::utils::AesGcmKey for TestKey {
-        fn key(&self) -> &[u8] {
-            &self.0
-        }
-    }
-
-    impl Deref for TestKey {
-        type Target = [u8];
-        fn deref(&self) -> &Self::Target {
-            &self.0
-        }
-    }
-
-    #[test]
-    fn test_with_encrypted_characteristics() -> anyhow::Result<()> {
-        let temp_dir = TempDir::new("test_with_encrypted_characteristics").unwrap();
-        std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
-
-        let pw: Password = PASSWORD.into();
-        let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
-        let super_key =
-            Arc::new(TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap()));
-
-        std::fs::write(&*temp_dir.build().push("user_0").push(".masterkey"), SUPERKEY).unwrap();
-
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_USRPKEY_authbound"),
-            USRPKEY_AUTHBOUND,
-        )
-        .unwrap();
-        make_encrypted_characteristics_file(
-            &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_authbound"),
-            &super_key,
-            KEY_PARAMETERS,
-        )
-        .unwrap();
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
-            USRCERT_AUTHBOUND,
-        )
-        .unwrap();
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
-            CACERT_AUTHBOUND,
-        )
-        .unwrap();
-
-        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
-
-        assert_eq!(
-            legacy_blob_loader
-                .load_by_uid_alias(10223, "authbound", &None)
-                .unwrap_err()
-                .root_cause()
-                .downcast_ref::<Error>(),
-            Some(&Error::LockedComponent)
-        );
-
-        assert_eq!(
-            legacy_blob_loader.load_by_uid_alias(10223, "authbound", &Some(super_key)).unwrap(),
-            (
-                Some((
-                    Blob {
-                        flags: 4,
-                        value: BlobValue::Encrypted {
-                            data: USRPKEY_AUTHBOUND_ENC_PAYLOAD.to_vec(),
-                            iv: USRPKEY_AUTHBOUND_IV.to_vec(),
-                            tag: USRPKEY_AUTHBOUND_TAG.to_vec()
-                        }
-                    },
-                    structured_test_params()
-                )),
-                Some(LOADED_CERT_AUTHBOUND.to_vec()),
-                Some(LOADED_CACERT_AUTHBOUND.to_vec())
-            )
-        );
-
-        legacy_blob_loader.remove_keystore_entry(10223, "authbound").expect("This should succeed.");
-
-        assert_eq!(
-            (None, None, None),
-            legacy_blob_loader.load_by_uid_alias(10223, "authbound", &None).unwrap()
-        );
-
-        // The database should not be empty due to the super key.
-        assert!(!legacy_blob_loader.is_empty().unwrap());
-        assert!(!legacy_blob_loader.is_empty_user(0).unwrap());
-
-        // The database should be considered empty for user 1.
-        assert!(legacy_blob_loader.is_empty_user(1).unwrap());
-
-        legacy_blob_loader.remove_super_key(0);
-
-        // Now it should be empty.
-        assert!(legacy_blob_loader.is_empty_user(0).unwrap());
-        assert!(legacy_blob_loader.is_empty().unwrap());
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_with_encrypted_certificates() -> anyhow::Result<()> {
-        let temp_dir = TempDir::new("test_with_encrypted_certificates").unwrap();
-        std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
-
-        let pw: Password = PASSWORD.into();
-        let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
-        let super_key =
-            Arc::new(TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap()));
-
-        std::fs::write(&*temp_dir.build().push("user_0").push(".masterkey"), SUPERKEY).unwrap();
-
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_USRPKEY_authbound"),
-            USRPKEY_AUTHBOUND,
-        )
-        .unwrap();
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_authbound"),
-            USRPKEY_AUTHBOUND_CHR,
-        )
-        .unwrap();
-        make_encrypted_usr_cert_file(
-            &*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
-            &super_key,
-            LOADED_CERT_AUTHBOUND,
-        )
-        .unwrap();
-        make_encrypted_ca_cert_file(
-            &*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
-            &super_key,
-            LOADED_CACERT_AUTHBOUND,
-        )
-        .unwrap();
-
-        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
-
-        assert_eq!(
-            legacy_blob_loader
-                .load_by_uid_alias(10223, "authbound", &None)
-                .unwrap_err()
-                .root_cause()
-                .downcast_ref::<Error>(),
-            Some(&Error::LockedComponent)
-        );
-
-        assert_eq!(
-            legacy_blob_loader.load_by_uid_alias(10223, "authbound", &Some(super_key)).unwrap(),
-            (
-                Some((
-                    Blob {
-                        flags: 4,
-                        value: BlobValue::Encrypted {
-                            data: USRPKEY_AUTHBOUND_ENC_PAYLOAD.to_vec(),
-                            iv: USRPKEY_AUTHBOUND_IV.to_vec(),
-                            tag: USRPKEY_AUTHBOUND_TAG.to_vec()
-                        }
-                    },
-                    structured_test_params_cache()
-                )),
-                Some(LOADED_CERT_AUTHBOUND.to_vec()),
-                Some(LOADED_CACERT_AUTHBOUND.to_vec())
-            )
-        );
-
-        legacy_blob_loader.remove_keystore_entry(10223, "authbound").expect("This should succeed.");
-
-        assert_eq!(
-            (None, None, None),
-            legacy_blob_loader.load_by_uid_alias(10223, "authbound", &None).unwrap()
-        );
-
-        // The database should not be empty due to the super key.
-        assert!(!legacy_blob_loader.is_empty().unwrap());
-        assert!(!legacy_blob_loader.is_empty_user(0).unwrap());
-
-        // The database should be considered empty for user 1.
-        assert!(legacy_blob_loader.is_empty_user(1).unwrap());
-
-        legacy_blob_loader.remove_super_key(0);
-
-        // Now it should be empty.
-        assert!(legacy_blob_loader.is_empty_user(0).unwrap());
-        assert!(legacy_blob_loader.is_empty().unwrap());
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_in_place_key_migration() -> anyhow::Result<()> {
-        let temp_dir = TempDir::new("test_in_place_key_migration").unwrap();
-        std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
-
-        let pw: Password = PASSWORD.into();
-        let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
-        let super_key =
-            Arc::new(TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap()));
-
-        std::fs::write(&*temp_dir.build().push("user_0").push(".masterkey"), SUPERKEY).unwrap();
-
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push("10223_USRPKEY_authbound"),
-            USRPKEY_AUTHBOUND,
-        )
-        .unwrap();
-        std::fs::write(
-            &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_authbound"),
-            USRPKEY_AUTHBOUND_CHR,
-        )
-        .unwrap();
-        make_encrypted_usr_cert_file(
-            &*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
-            &super_key,
-            LOADED_CERT_AUTHBOUND,
-        )
-        .unwrap();
-        make_encrypted_ca_cert_file(
-            &*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
-            &super_key,
-            LOADED_CACERT_AUTHBOUND,
-        )
-        .unwrap();
-
-        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
-
-        assert_eq!(
-            legacy_blob_loader
-                .load_by_uid_alias(10223, "authbound", &None)
-                .unwrap_err()
-                .root_cause()
-                .downcast_ref::<Error>(),
-            Some(&Error::LockedComponent)
-        );
-
-        let super_key: Option<Arc<dyn AesGcm>> = Some(super_key);
-
-        assert_eq!(
-            legacy_blob_loader.load_by_uid_alias(10223, "authbound", &super_key).unwrap(),
-            (
-                Some((
-                    Blob {
-                        flags: 4,
-                        value: BlobValue::Encrypted {
-                            data: USRPKEY_AUTHBOUND_ENC_PAYLOAD.to_vec(),
-                            iv: USRPKEY_AUTHBOUND_IV.to_vec(),
-                            tag: USRPKEY_AUTHBOUND_TAG.to_vec()
-                        }
-                    },
-                    structured_test_params_cache()
-                )),
-                Some(LOADED_CERT_AUTHBOUND.to_vec()),
-                Some(LOADED_CACERT_AUTHBOUND.to_vec())
-            )
-        );
-
-        legacy_blob_loader.move_keystore_entry(10223, 10224, "authbound", "boundauth").unwrap();
-
-        assert_eq!(
-            legacy_blob_loader
-                .load_by_uid_alias(10224, "boundauth", &None)
-                .unwrap_err()
-                .root_cause()
-                .downcast_ref::<Error>(),
-            Some(&Error::LockedComponent)
-        );
-
-        assert_eq!(
-            legacy_blob_loader.load_by_uid_alias(10224, "boundauth", &super_key).unwrap(),
-            (
-                Some((
-                    Blob {
-                        flags: 4,
-                        value: BlobValue::Encrypted {
-                            data: USRPKEY_AUTHBOUND_ENC_PAYLOAD.to_vec(),
-                            iv: USRPKEY_AUTHBOUND_IV.to_vec(),
-                            tag: USRPKEY_AUTHBOUND_TAG.to_vec()
-                        }
-                    },
-                    structured_test_params_cache()
-                )),
-                Some(LOADED_CERT_AUTHBOUND.to_vec()),
-                Some(LOADED_CACERT_AUTHBOUND.to_vec())
-            )
-        );
-
-        legacy_blob_loader.remove_keystore_entry(10224, "boundauth").expect("This should succeed.");
-
-        assert_eq!(
-            (None, None, None),
-            legacy_blob_loader.load_by_uid_alias(10224, "boundauth", &None).unwrap()
-        );
-
-        // The database should not be empty due to the super key.
-        assert!(!legacy_blob_loader.is_empty().unwrap());
-        assert!(!legacy_blob_loader.is_empty_user(0).unwrap());
-
-        // The database should be considered empty for user 1.
-        assert!(legacy_blob_loader.is_empty_user(1).unwrap());
-
-        legacy_blob_loader.remove_super_key(0);
-
-        // Now it should be empty.
-        assert!(legacy_blob_loader.is_empty_user(0).unwrap());
-        assert!(legacy_blob_loader.is_empty().unwrap());
-
-        Ok(())
-    }
-
-    #[test]
-    fn list_non_existing_user() -> Result<()> {
-        let temp_dir = TempDir::new("list_non_existing_user").unwrap();
-        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
-
-        assert!(legacy_blob_loader.list_user(20)?.is_empty());
-
-        Ok(())
-    }
-
-    #[test]
-    fn list_legacy_keystore_entries_on_non_existing_user() -> Result<()> {
-        let temp_dir = TempDir::new("list_legacy_keystore_entries_on_non_existing_user").unwrap();
-        let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
-
-        assert!(legacy_blob_loader.list_legacy_keystore_entries_for_user(20)?.is_empty());
-
-        Ok(())
-    }
-
-    #[test]
-    fn test_move_keystore_entry() {
-        let temp_dir = TempDir::new("test_move_keystore_entry").unwrap();
-        std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
-
-        const SOME_CONTENT: &[u8] = b"some content";
-        const ANOTHER_CONTENT: &[u8] = b"another content";
-        const SOME_FILENAME: &str = "some_file";
-        const ANOTHER_FILENAME: &str = "another_file";
-
-        std::fs::write(&*temp_dir.build().push("user_0").push(SOME_FILENAME), SOME_CONTENT)
-            .unwrap();
-
-        std::fs::write(&*temp_dir.build().push("user_0").push(ANOTHER_FILENAME), ANOTHER_CONTENT)
-            .unwrap();
-
-        // Non existent source id silently ignored.
-        assert!(LegacyBlobLoader::move_keystore_file_if_exists(
-            1,
-            2,
-            "non_existent",
-            ANOTHER_FILENAME,
-            "ignored",
-            |_, alias, _| temp_dir.build().push("user_0").push(alias).to_path_buf()
-        )
-        .is_ok());
-
-        // Content of another_file has not changed.
-        let another_content =
-            std::fs::read(&*temp_dir.build().push("user_0").push(ANOTHER_FILENAME)).unwrap();
-        assert_eq!(&another_content, ANOTHER_CONTENT);
-
-        // Check that some_file still exists.
-        assert!(temp_dir.build().push("user_0").push(SOME_FILENAME).exists());
-        // Existing target files are silently overwritten.
-
-        assert!(LegacyBlobLoader::move_keystore_file_if_exists(
-            1,
-            2,
-            SOME_FILENAME,
-            ANOTHER_FILENAME,
-            "ignored",
-            |_, alias, _| temp_dir.build().push("user_0").push(alias).to_path_buf()
-        )
-        .is_ok());
-
-        // Content of another_file is now "some content".
-        let another_content =
-            std::fs::read(&*temp_dir.build().push("user_0").push(ANOTHER_FILENAME)).unwrap();
-        assert_eq!(&another_content, SOME_CONTENT);
-
-        // Check that some_file no longer exists.
-        assert!(!temp_dir.build().push("user_0").push(SOME_FILENAME).exists());
-    }
-}
diff --git a/keystore2/src/legacy_blob/tests.rs b/keystore2/src/legacy_blob/tests.rs
new file mode 100644
index 0000000..53fe03f
--- /dev/null
+++ b/keystore2/src/legacy_blob/tests.rs
@@ -0,0 +1,676 @@
+// 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.
+
+//! Tests for legacy keyblob processing.
+
+#![allow(dead_code)]
+use super::*;
+use crate::legacy_blob::test_utils::legacy_blob_test_vectors::*;
+use crate::legacy_blob::test_utils::*;
+use anyhow::{anyhow, Result};
+use keystore2_crypto::aes_gcm_decrypt;
+use keystore2_test_utils::TempDir;
+use rand::Rng;
+use std::convert::TryInto;
+use std::ops::Deref;
+use std::string::FromUtf8Error;
+
+#[test]
+fn decode_encode_alias_test() {
+    static ALIAS: &str = "#({}test[])😗";
+    static ENCODED_ALIAS: &str = "+S+X{}test[]+Y.`-O-H-G";
+    // Second multi byte out of range ------v
+    static ENCODED_ALIAS_ERROR1: &str = "+S+{}test[]+Y";
+    // Incomplete multi byte ------------------------v
+    static ENCODED_ALIAS_ERROR2: &str = "+S+X{}test[]+";
+    // Our encoding: ".`-O-H-G"
+    // is UTF-8: 0xF0 0x9F 0x98 0x97
+    // is UNICODE: U+1F617
+    // is 😗
+    // But +H below is a valid encoding for 0x18 making this sequence invalid UTF-8.
+    static ENCODED_ALIAS_ERROR_UTF8: &str = ".`-O+H-G";
+
+    assert_eq!(ENCODED_ALIAS, &LegacyBlobLoader::encode_alias(ALIAS));
+    assert_eq!(ALIAS, &LegacyBlobLoader::decode_alias(ENCODED_ALIAS).unwrap());
+    assert_eq!(
+        Some(&Error::BadEncoding),
+        LegacyBlobLoader::decode_alias(ENCODED_ALIAS_ERROR1)
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<Error>()
+    );
+    assert_eq!(
+        Some(&Error::BadEncoding),
+        LegacyBlobLoader::decode_alias(ENCODED_ALIAS_ERROR2)
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<Error>()
+    );
+    assert!(LegacyBlobLoader::decode_alias(ENCODED_ALIAS_ERROR_UTF8)
+        .unwrap_err()
+        .root_cause()
+        .downcast_ref::<FromUtf8Error>()
+        .is_some());
+
+    for _i in 0..100 {
+        // Any valid UTF-8 string should be en- and decoded without loss.
+        let alias_str = rand::thread_rng().gen::<[char; 20]>().iter().collect::<String>();
+        let random_alias = alias_str.as_bytes();
+        let encoded = LegacyBlobLoader::encode_alias(&alias_str);
+        let decoded = match LegacyBlobLoader::decode_alias(&encoded) {
+            Ok(d) => d,
+            Err(_) => panic!("random_alias: {:x?}\nencoded {}", random_alias, encoded),
+        };
+        assert_eq!(random_alias.to_vec(), decoded.bytes().collect::<Vec<u8>>());
+    }
+}
+
+#[test]
+fn read_golden_key_blob_test() -> anyhow::Result<()> {
+    let blob = LegacyBlobLoader::new_from_stream_decrypt_with(&mut &*BLOB, |_, _, _, _, _| {
+        Err(anyhow!("should not be called"))
+    })
+    .unwrap();
+    assert!(!blob.is_encrypted());
+    assert!(!blob.is_fallback());
+    assert!(!blob.is_strongbox());
+    assert!(!blob.is_critical_to_device_encryption());
+    assert_eq!(blob.value(), &BlobValue::Generic([0xde, 0xed, 0xbe, 0xef].to_vec()));
+
+    let blob =
+        LegacyBlobLoader::new_from_stream_decrypt_with(&mut &*REAL_LEGACY_BLOB, |_, _, _, _, _| {
+            Err(anyhow!("should not be called"))
+        })
+        .unwrap();
+    assert!(!blob.is_encrypted());
+    assert!(!blob.is_fallback());
+    assert!(!blob.is_strongbox());
+    assert!(!blob.is_critical_to_device_encryption());
+    assert_eq!(blob.value(), &BlobValue::Decrypted(REAL_LEGACY_BLOB_PAYLOAD.try_into().unwrap()));
+    Ok(())
+}
+
+#[test]
+fn read_aes_gcm_encrypted_key_blob_test() {
+    let blob = LegacyBlobLoader::new_from_stream_decrypt_with(
+        &mut &*AES_GCM_ENCRYPTED_BLOB,
+        |d, iv, tag, salt, key_size| {
+            assert_eq!(salt, None);
+            assert_eq!(key_size, None);
+            assert_eq!(
+                iv,
+                &[
+                    0xbd, 0xdb, 0x8d, 0x69, 0x72, 0x56, 0xf0, 0xf5, 0xa4, 0x02, 0x88, 0x7f, 0x00,
+                    0x00, 0x00, 0x00,
+                ]
+            );
+            assert_eq!(
+                tag,
+                &[
+                    0x50, 0xd9, 0x97, 0x95, 0x37, 0x6e, 0x28, 0x6a, 0x28, 0x9d, 0x51, 0xb9, 0xb9,
+                    0xe0, 0x0b, 0xc3
+                ][..]
+            );
+            aes_gcm_decrypt(d, iv, tag, AES_KEY).context("Trying to decrypt blob.")
+        },
+    )
+    .unwrap();
+    assert!(blob.is_encrypted());
+    assert!(!blob.is_fallback());
+    assert!(!blob.is_strongbox());
+    assert!(!blob.is_critical_to_device_encryption());
+
+    assert_eq!(blob.value(), &BlobValue::Decrypted(DECRYPTED_PAYLOAD.try_into().unwrap()));
+}
+
+#[test]
+fn read_golden_key_blob_too_short_test() {
+    let error =
+        LegacyBlobLoader::new_from_stream_decrypt_with(&mut &BLOB[0..15], |_, _, _, _, _| {
+            Err(anyhow!("should not be called"))
+        })
+        .unwrap_err();
+    assert_eq!(Some(&Error::BadLen), error.root_cause().downcast_ref::<Error>());
+}
+
+#[test]
+fn test_is_empty() {
+    let temp_dir = TempDir::new("test_is_empty").expect("Failed to create temp dir.");
+    let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+    assert!(legacy_blob_loader.is_empty().expect("Should succeed and be empty."));
+
+    let _db =
+        crate::database::KeystoreDB::new(temp_dir.path(), None).expect("Failed to open database.");
+
+    assert!(legacy_blob_loader.is_empty().expect("Should succeed and still be empty."));
+
+    std::fs::create_dir(&*temp_dir.build().push("user_0")).expect("Failed to create user_0.");
+
+    assert!(!legacy_blob_loader.is_empty().expect("Should succeed but not be empty."));
+
+    std::fs::create_dir(&*temp_dir.build().push("user_10")).expect("Failed to create user_10.");
+
+    assert!(!legacy_blob_loader.is_empty().expect("Should succeed but still not be empty."));
+
+    std::fs::remove_dir_all(&*temp_dir.build().push("user_0")).expect("Failed to remove user_0.");
+
+    assert!(!legacy_blob_loader.is_empty().expect("Should succeed but still not be empty."));
+
+    std::fs::remove_dir_all(&*temp_dir.build().push("user_10")).expect("Failed to remove user_10.");
+
+    assert!(legacy_blob_loader.is_empty().expect("Should succeed and be empty again."));
+}
+
+#[test]
+fn test_legacy_blobs() -> anyhow::Result<()> {
+    let temp_dir = TempDir::new("legacy_blob_test").unwrap();
+    std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
+
+    std::fs::write(&*temp_dir.build().push("user_0").push(".masterkey"), SUPERKEY).unwrap();
+
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_USRPKEY_authbound"),
+        USRPKEY_AUTHBOUND,
+    )
+    .unwrap();
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_authbound"),
+        USRPKEY_AUTHBOUND_CHR,
+    )
+    .unwrap();
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
+        USRCERT_AUTHBOUND,
+    )
+    .unwrap();
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
+        CACERT_AUTHBOUND,
+    )
+    .unwrap();
+
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_USRPKEY_non_authbound"),
+        USRPKEY_NON_AUTHBOUND,
+    )
+    .unwrap();
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_non_authbound"),
+        USRPKEY_NON_AUTHBOUND_CHR,
+    )
+    .unwrap();
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_USRCERT_non_authbound"),
+        USRCERT_NON_AUTHBOUND,
+    )
+    .unwrap();
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_CACERT_non_authbound"),
+        CACERT_NON_AUTHBOUND,
+    )
+    .unwrap();
+
+    let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+    if let (Some((Blob { flags, value }, _params)), Some(cert), Some(chain)) =
+        legacy_blob_loader.load_by_uid_alias(10223, "authbound", &None)?
+    {
+        assert_eq!(flags, 4);
+        assert_eq!(
+            value,
+            BlobValue::Encrypted {
+                data: USRPKEY_AUTHBOUND_ENC_PAYLOAD.to_vec(),
+                iv: USRPKEY_AUTHBOUND_IV.to_vec(),
+                tag: USRPKEY_AUTHBOUND_TAG.to_vec()
+            }
+        );
+        assert_eq!(&cert[..], LOADED_CERT_AUTHBOUND);
+        assert_eq!(&chain[..], LOADED_CACERT_AUTHBOUND);
+    } else {
+        panic!("");
+    }
+
+    if let (Some((Blob { flags, value: _ }, _params)), Some(cert), Some(chain)) =
+        legacy_blob_loader.load_by_uid_alias(10223, "authbound", &None)?
+    {
+        assert_eq!(flags, 4);
+        //assert_eq!(value, BlobValue::Encrypted(..));
+        assert_eq!(&cert[..], LOADED_CERT_AUTHBOUND);
+        assert_eq!(&chain[..], LOADED_CACERT_AUTHBOUND);
+    } else {
+        panic!("");
+    }
+    if let (Some((Blob { flags, value }, _params)), Some(cert), Some(chain)) =
+        legacy_blob_loader.load_by_uid_alias(10223, "non_authbound", &None)?
+    {
+        assert_eq!(flags, 0);
+        assert_eq!(value, BlobValue::Decrypted(LOADED_USRPKEY_NON_AUTHBOUND.try_into()?));
+        assert_eq!(&cert[..], LOADED_CERT_NON_AUTHBOUND);
+        assert_eq!(&chain[..], LOADED_CACERT_NON_AUTHBOUND);
+    } else {
+        panic!("");
+    }
+
+    legacy_blob_loader.remove_keystore_entry(10223, "authbound").expect("This should succeed.");
+    legacy_blob_loader.remove_keystore_entry(10223, "non_authbound").expect("This should succeed.");
+
+    assert_eq!(
+        (None, None, None),
+        legacy_blob_loader.load_by_uid_alias(10223, "authbound", &None)?
+    );
+    assert_eq!(
+        (None, None, None),
+        legacy_blob_loader.load_by_uid_alias(10223, "non_authbound", &None)?
+    );
+
+    // The database should not be empty due to the super key.
+    assert!(!legacy_blob_loader.is_empty()?);
+    assert!(!legacy_blob_loader.is_empty_user(0)?);
+
+    // The database should be considered empty for user 1.
+    assert!(legacy_blob_loader.is_empty_user(1)?);
+
+    legacy_blob_loader.remove_super_key(0);
+
+    // Now it should be empty.
+    assert!(legacy_blob_loader.is_empty_user(0)?);
+    assert!(legacy_blob_loader.is_empty()?);
+
+    Ok(())
+}
+
+struct TestKey(ZVec);
+
+impl crate::utils::AesGcmKey for TestKey {
+    fn key(&self) -> &[u8] {
+        &self.0
+    }
+}
+
+impl Deref for TestKey {
+    type Target = [u8];
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+#[test]
+fn test_with_encrypted_characteristics() -> anyhow::Result<()> {
+    let temp_dir = TempDir::new("test_with_encrypted_characteristics").unwrap();
+    std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
+
+    let pw: Password = PASSWORD.into();
+    let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
+    let super_key =
+        Arc::new(TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap()));
+
+    std::fs::write(&*temp_dir.build().push("user_0").push(".masterkey"), SUPERKEY).unwrap();
+
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_USRPKEY_authbound"),
+        USRPKEY_AUTHBOUND,
+    )
+    .unwrap();
+    make_encrypted_characteristics_file(
+        &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_authbound"),
+        &super_key,
+        KEY_PARAMETERS,
+    )
+    .unwrap();
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
+        USRCERT_AUTHBOUND,
+    )
+    .unwrap();
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
+        CACERT_AUTHBOUND,
+    )
+    .unwrap();
+
+    let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+    assert_eq!(
+        legacy_blob_loader
+            .load_by_uid_alias(10223, "authbound", &None)
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<Error>(),
+        Some(&Error::LockedComponent)
+    );
+
+    assert_eq!(
+        legacy_blob_loader.load_by_uid_alias(10223, "authbound", &Some(super_key)).unwrap(),
+        (
+            Some((
+                Blob {
+                    flags: 4,
+                    value: BlobValue::Encrypted {
+                        data: USRPKEY_AUTHBOUND_ENC_PAYLOAD.to_vec(),
+                        iv: USRPKEY_AUTHBOUND_IV.to_vec(),
+                        tag: USRPKEY_AUTHBOUND_TAG.to_vec()
+                    }
+                },
+                structured_test_params()
+            )),
+            Some(LOADED_CERT_AUTHBOUND.to_vec()),
+            Some(LOADED_CACERT_AUTHBOUND.to_vec())
+        )
+    );
+
+    legacy_blob_loader.remove_keystore_entry(10223, "authbound").expect("This should succeed.");
+
+    assert_eq!(
+        (None, None, None),
+        legacy_blob_loader.load_by_uid_alias(10223, "authbound", &None).unwrap()
+    );
+
+    // The database should not be empty due to the super key.
+    assert!(!legacy_blob_loader.is_empty().unwrap());
+    assert!(!legacy_blob_loader.is_empty_user(0).unwrap());
+
+    // The database should be considered empty for user 1.
+    assert!(legacy_blob_loader.is_empty_user(1).unwrap());
+
+    legacy_blob_loader.remove_super_key(0);
+
+    // Now it should be empty.
+    assert!(legacy_blob_loader.is_empty_user(0).unwrap());
+    assert!(legacy_blob_loader.is_empty().unwrap());
+
+    Ok(())
+}
+
+#[test]
+fn test_with_encrypted_certificates() -> anyhow::Result<()> {
+    let temp_dir = TempDir::new("test_with_encrypted_certificates").unwrap();
+    std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
+
+    let pw: Password = PASSWORD.into();
+    let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
+    let super_key =
+        Arc::new(TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap()));
+
+    std::fs::write(&*temp_dir.build().push("user_0").push(".masterkey"), SUPERKEY).unwrap();
+
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_USRPKEY_authbound"),
+        USRPKEY_AUTHBOUND,
+    )
+    .unwrap();
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_authbound"),
+        USRPKEY_AUTHBOUND_CHR,
+    )
+    .unwrap();
+    make_encrypted_usr_cert_file(
+        &*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
+        &super_key,
+        LOADED_CERT_AUTHBOUND,
+    )
+    .unwrap();
+    make_encrypted_ca_cert_file(
+        &*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
+        &super_key,
+        LOADED_CACERT_AUTHBOUND,
+    )
+    .unwrap();
+
+    let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+    assert_eq!(
+        legacy_blob_loader
+            .load_by_uid_alias(10223, "authbound", &None)
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<Error>(),
+        Some(&Error::LockedComponent)
+    );
+
+    assert_eq!(
+        legacy_blob_loader.load_by_uid_alias(10223, "authbound", &Some(super_key)).unwrap(),
+        (
+            Some((
+                Blob {
+                    flags: 4,
+                    value: BlobValue::Encrypted {
+                        data: USRPKEY_AUTHBOUND_ENC_PAYLOAD.to_vec(),
+                        iv: USRPKEY_AUTHBOUND_IV.to_vec(),
+                        tag: USRPKEY_AUTHBOUND_TAG.to_vec()
+                    }
+                },
+                structured_test_params_cache()
+            )),
+            Some(LOADED_CERT_AUTHBOUND.to_vec()),
+            Some(LOADED_CACERT_AUTHBOUND.to_vec())
+        )
+    );
+
+    legacy_blob_loader.remove_keystore_entry(10223, "authbound").expect("This should succeed.");
+
+    assert_eq!(
+        (None, None, None),
+        legacy_blob_loader.load_by_uid_alias(10223, "authbound", &None).unwrap()
+    );
+
+    // The database should not be empty due to the super key.
+    assert!(!legacy_blob_loader.is_empty().unwrap());
+    assert!(!legacy_blob_loader.is_empty_user(0).unwrap());
+
+    // The database should be considered empty for user 1.
+    assert!(legacy_blob_loader.is_empty_user(1).unwrap());
+
+    legacy_blob_loader.remove_super_key(0);
+
+    // Now it should be empty.
+    assert!(legacy_blob_loader.is_empty_user(0).unwrap());
+    assert!(legacy_blob_loader.is_empty().unwrap());
+
+    Ok(())
+}
+
+#[test]
+fn test_in_place_key_migration() -> anyhow::Result<()> {
+    let temp_dir = TempDir::new("test_in_place_key_migration").unwrap();
+    std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
+
+    let pw: Password = PASSWORD.into();
+    let pw_key = TestKey(pw.derive_key_pbkdf2(SUPERKEY_SALT, 32).unwrap());
+    let super_key =
+        Arc::new(TestKey(pw_key.decrypt(SUPERKEY_PAYLOAD, SUPERKEY_IV, SUPERKEY_TAG).unwrap()));
+
+    std::fs::write(&*temp_dir.build().push("user_0").push(".masterkey"), SUPERKEY).unwrap();
+
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push("10223_USRPKEY_authbound"),
+        USRPKEY_AUTHBOUND,
+    )
+    .unwrap();
+    std::fs::write(
+        &*temp_dir.build().push("user_0").push(".10223_chr_USRPKEY_authbound"),
+        USRPKEY_AUTHBOUND_CHR,
+    )
+    .unwrap();
+    make_encrypted_usr_cert_file(
+        &*temp_dir.build().push("user_0").push("10223_USRCERT_authbound"),
+        &super_key,
+        LOADED_CERT_AUTHBOUND,
+    )
+    .unwrap();
+    make_encrypted_ca_cert_file(
+        &*temp_dir.build().push("user_0").push("10223_CACERT_authbound"),
+        &super_key,
+        LOADED_CACERT_AUTHBOUND,
+    )
+    .unwrap();
+
+    let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+    assert_eq!(
+        legacy_blob_loader
+            .load_by_uid_alias(10223, "authbound", &None)
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<Error>(),
+        Some(&Error::LockedComponent)
+    );
+
+    let super_key: Option<Arc<dyn AesGcm>> = Some(super_key);
+
+    assert_eq!(
+        legacy_blob_loader.load_by_uid_alias(10223, "authbound", &super_key).unwrap(),
+        (
+            Some((
+                Blob {
+                    flags: 4,
+                    value: BlobValue::Encrypted {
+                        data: USRPKEY_AUTHBOUND_ENC_PAYLOAD.to_vec(),
+                        iv: USRPKEY_AUTHBOUND_IV.to_vec(),
+                        tag: USRPKEY_AUTHBOUND_TAG.to_vec()
+                    }
+                },
+                structured_test_params_cache()
+            )),
+            Some(LOADED_CERT_AUTHBOUND.to_vec()),
+            Some(LOADED_CACERT_AUTHBOUND.to_vec())
+        )
+    );
+
+    legacy_blob_loader.move_keystore_entry(10223, 10224, "authbound", "boundauth").unwrap();
+
+    assert_eq!(
+        legacy_blob_loader
+            .load_by_uid_alias(10224, "boundauth", &None)
+            .unwrap_err()
+            .root_cause()
+            .downcast_ref::<Error>(),
+        Some(&Error::LockedComponent)
+    );
+
+    assert_eq!(
+        legacy_blob_loader.load_by_uid_alias(10224, "boundauth", &super_key).unwrap(),
+        (
+            Some((
+                Blob {
+                    flags: 4,
+                    value: BlobValue::Encrypted {
+                        data: USRPKEY_AUTHBOUND_ENC_PAYLOAD.to_vec(),
+                        iv: USRPKEY_AUTHBOUND_IV.to_vec(),
+                        tag: USRPKEY_AUTHBOUND_TAG.to_vec()
+                    }
+                },
+                structured_test_params_cache()
+            )),
+            Some(LOADED_CERT_AUTHBOUND.to_vec()),
+            Some(LOADED_CACERT_AUTHBOUND.to_vec())
+        )
+    );
+
+    legacy_blob_loader.remove_keystore_entry(10224, "boundauth").expect("This should succeed.");
+
+    assert_eq!(
+        (None, None, None),
+        legacy_blob_loader.load_by_uid_alias(10224, "boundauth", &None).unwrap()
+    );
+
+    // The database should not be empty due to the super key.
+    assert!(!legacy_blob_loader.is_empty().unwrap());
+    assert!(!legacy_blob_loader.is_empty_user(0).unwrap());
+
+    // The database should be considered empty for user 1.
+    assert!(legacy_blob_loader.is_empty_user(1).unwrap());
+
+    legacy_blob_loader.remove_super_key(0);
+
+    // Now it should be empty.
+    assert!(legacy_blob_loader.is_empty_user(0).unwrap());
+    assert!(legacy_blob_loader.is_empty().unwrap());
+
+    Ok(())
+}
+
+#[test]
+fn list_non_existing_user() -> Result<()> {
+    let temp_dir = TempDir::new("list_non_existing_user").unwrap();
+    let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+    assert!(legacy_blob_loader.list_user(20)?.is_empty());
+
+    Ok(())
+}
+
+#[test]
+fn list_legacy_keystore_entries_on_non_existing_user() -> Result<()> {
+    let temp_dir = TempDir::new("list_legacy_keystore_entries_on_non_existing_user").unwrap();
+    let legacy_blob_loader = LegacyBlobLoader::new(temp_dir.path());
+
+    assert!(legacy_blob_loader.list_legacy_keystore_entries_for_user(20)?.is_empty());
+
+    Ok(())
+}
+
+#[test]
+fn test_move_keystore_entry() {
+    let temp_dir = TempDir::new("test_move_keystore_entry").unwrap();
+    std::fs::create_dir(&*temp_dir.build().push("user_0")).unwrap();
+
+    const SOME_CONTENT: &[u8] = b"some content";
+    const ANOTHER_CONTENT: &[u8] = b"another content";
+    const SOME_FILENAME: &str = "some_file";
+    const ANOTHER_FILENAME: &str = "another_file";
+
+    std::fs::write(&*temp_dir.build().push("user_0").push(SOME_FILENAME), SOME_CONTENT).unwrap();
+
+    std::fs::write(&*temp_dir.build().push("user_0").push(ANOTHER_FILENAME), ANOTHER_CONTENT)
+        .unwrap();
+
+    // Non existent source id silently ignored.
+    assert!(LegacyBlobLoader::move_keystore_file_if_exists(
+        1,
+        2,
+        "non_existent",
+        ANOTHER_FILENAME,
+        "ignored",
+        |_, alias, _| temp_dir.build().push("user_0").push(alias).to_path_buf()
+    )
+    .is_ok());
+
+    // Content of another_file has not changed.
+    let another_content =
+        std::fs::read(&*temp_dir.build().push("user_0").push(ANOTHER_FILENAME)).unwrap();
+    assert_eq!(&another_content, ANOTHER_CONTENT);
+
+    // Check that some_file still exists.
+    assert!(temp_dir.build().push("user_0").push(SOME_FILENAME).exists());
+    // Existing target files are silently overwritten.
+
+    assert!(LegacyBlobLoader::move_keystore_file_if_exists(
+        1,
+        2,
+        SOME_FILENAME,
+        ANOTHER_FILENAME,
+        "ignored",
+        |_, alias, _| temp_dir.build().push("user_0").push(alias).to_path_buf()
+    )
+    .is_ok());
+
+    // Content of another_file is now "some content".
+    let another_content =
+        std::fs::read(&*temp_dir.build().push("user_0").push(ANOTHER_FILENAME)).unwrap();
+    assert_eq!(&another_content, SOME_CONTENT);
+
+    // Check that some_file no longer exists.
+    assert!(!temp_dir.build().push("user_0").push(SOME_FILENAME).exists());
+}
