Keystore 2.0: Adding uuid field to persistent.keyentry
This change adds a uuid field to map keys to KM devices to the keyentry
table. For now, the security level reported by the KeyMint instance's
hardware info is uased as uuid until the hardware info returns an
actual uuid. This security level may differ from the security level
requested by keystore clients in some situations, e.g., when running a
pure software implementation or on chrome os.
Test: atest keystore2_test
Change-Id: I4b9556804eb6a435ac48d5929fc238e22c23d94d
diff --git a/keystore2/src/super_key.rs b/keystore2/src/super_key.rs
index 4ffe897..9872513 100644
--- a/keystore2/src/super_key.rs
+++ b/keystore2/src/super_key.rs
@@ -115,36 +115,42 @@
legacy_blob_loader: &LegacyBlobLoader,
) -> Result<()> {
let (_, entry) = db
- .get_or_create_key_with(Domain::APP, user as u64 as i64, &"USER_SUPER_KEY", || {
- // For backward compatibility we need to check if there is a super key present.
- let super_key = legacy_blob_loader
- .load_super_key(user, pw)
- .context("In create_new_key: Failed to load legacy key blob.")?;
- let super_key = match super_key {
- None => {
- // No legacy file was found. So we generate a new key.
- keystore2_crypto::generate_aes256_key()
- .context("In create_new_key: Failed to generate AES 256 key.")?
- }
- Some(key) => key,
- };
- // Regardless of whether we loaded an old AES128 key or a new AES256 key,
- // we derive a AES256 key and re-encrypt the key before we insert it in the
- // database. The length of the key is preserved by the encryption so we don't
- // need any extra flags to inform us which algorithm to use it with.
- 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))
- })
+ .get_or_create_key_with(
+ Domain::APP,
+ user as u64 as i64,
+ &"USER_SUPER_KEY",
+ crate::database::KEYSTORE_UUID,
+ || {
+ // For backward compatibility we need to check if there is a super key present.
+ let super_key = legacy_blob_loader
+ .load_super_key(user, pw)
+ .context("In create_new_key: Failed to load legacy key blob.")?;
+ let super_key = match super_key {
+ None => {
+ // No legacy file was found. So we generate a new key.
+ keystore2_crypto::generate_aes256_key()
+ .context("In create_new_key: Failed to generate AES 256 key.")?
+ }
+ Some(key) => key,
+ };
+ // Regardless of whether we loaded an old AES128 key or a new AES256 key,
+ // we derive a AES256 key and re-encrypt the key before we insert it in the
+ // database. The length of the key is preserved by the encryption so we don't
+ // need any extra flags to inform us which algorithm to use it with.
+ 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();