Keystore 2.0: Legacy key blobs
This patch adds support for reading legacy keystore blob files.
Test: keystore2_test
Bug: 159371296
Change-Id: I94ec556b2250a0ef7d55c317e13b3f3770a11bc7
diff --git a/keystore2/src/super_key.rs b/keystore2/src/super_key.rs
index d204ae7..4ffe897 100644
--- a/keystore2/src/super_key.rs
+++ b/keystore2/src/super_key.rs
@@ -16,7 +16,7 @@
use crate::{
database::EncryptedBy, database::KeyMetaData, database::KeyMetaEntry, database::KeystoreDB,
- error::Error, error::ResponseCode,
+ error::Error, error::ResponseCode, legacy_blob::LegacyBlobLoader,
};
use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain;
use anyhow::{Context, Result};
@@ -107,12 +107,31 @@
/// 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<()> {
+ pub fn unlock_user_key(
+ &self,
+ user: UserId,
+ pw: &[u8],
+ db: &mut KeystoreDB,
+ legacy_blob_loader: &LegacyBlobLoader,
+ ) -> 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.")?;
-
+ // 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)