Key upgrading for FDE.
Correctly handle a key upgrade error from keymaster by upgrading the
FDE RSA key and writing the new key blob to disk.
Bug: 69792304
Test: Roll back PLATFORM_SECURITY_PATCH a month, wipe and reboot, roll
forwards again, check logs with and without this patch.
Change-Id: I220d2dd4e3d791f636e9bc5f063064cecbf1b88a
diff --git a/cryptfs.cpp b/cryptfs.cpp
index 5b863ba..1e08c8f 100644
--- a/cryptfs.cpp
+++ b/cryptfs.cpp
@@ -96,6 +96,8 @@
#define RETRY_MOUNT_ATTEMPTS 10
#define RETRY_MOUNT_DELAY_SECONDS 1
+static int put_crypt_ftr_and_key(struct crypt_mnt_ftr* crypt_ftr);
+
static unsigned char saved_master_key[KEY_LEN_BYTES];
static char *saved_mount_point;
static int master_key_saved = 0;
@@ -120,7 +122,7 @@
&ftr->keymaster_blob_size);
if (rc) {
if (ftr->keymaster_blob_size > KEYMASTER_BLOB_SIZE) {
- SLOGE("Keymaster key blob to large)");
+ SLOGE("Keymaster key blob too large");
ftr->keymaster_blob_size = 0;
}
SLOGE("Failed to generate keypair");
@@ -169,8 +171,31 @@
SLOGE("Unknown KDF type %d", ftr->kdf_type);
return -1;
}
- return keymaster_sign_object_for_cryptfs_scrypt(ftr->keymaster_blob, ftr->keymaster_blob_size,
- KEYMASTER_CRYPTFS_RATE_LIMIT, to_sign, to_sign_size, signature, signature_size);
+ for (;;) {
+ auto result = keymaster_sign_object_for_cryptfs_scrypt(
+ ftr->keymaster_blob, ftr->keymaster_blob_size, KEYMASTER_CRYPTFS_RATE_LIMIT, to_sign,
+ to_sign_size, signature, signature_size);
+ switch (result) {
+ case KeymasterSignResult::ok:
+ return 0;
+ case KeymasterSignResult::upgrade:
+ break;
+ default:
+ return -1;
+ }
+ SLOGD("Upgrading key");
+ if (keymaster_upgrade_key_for_cryptfs_scrypt(
+ RSA_KEY_SIZE, RSA_EXPONENT, KEYMASTER_CRYPTFS_RATE_LIMIT, ftr->keymaster_blob,
+ ftr->keymaster_blob_size, ftr->keymaster_blob, KEYMASTER_BLOB_SIZE,
+ &ftr->keymaster_blob_size) != 0) {
+ SLOGE("Failed to upgrade key");
+ return -1;
+ }
+ if (put_crypt_ftr_and_key(ftr) != 0) {
+ SLOGE("Failed to write upgraded key to disk");
+ }
+ SLOGD("Key upgraded successfully");
+ }
}
/* Store password when userdata is successfully decrypted and mounted.