Add Support for metadata key with rollback
This adds the ability to upgrade a key and retain the
old one for rollback purposes. We delete the old key
if we boot successfully and delete the new key if we
do not.
Test: Enable checkpointing and test rolling back
between two versions
Bug: 111020314
Change-Id: I19f31a1ac06a811c0644fc956e61b5ca84e7241a
diff --git a/KeyStorage.cpp b/KeyStorage.cpp
index 035c7b7..9dd4991 100644
--- a/KeyStorage.cpp
+++ b/KeyStorage.cpp
@@ -202,7 +202,7 @@
km::KeyPurpose purpose, const km::AuthorizationSet& keyParams,
const km::AuthorizationSet& opParams,
const km::HardwareAuthToken& authToken,
- km::AuthorizationSet* outParams) {
+ km::AuthorizationSet* outParams, bool keepOld) {
auto kmKeyPath = dir + "/" + kFn_keymaster_key_blob;
std::string kmKey;
if (!readFileToString(kmKeyPath, &kmKey)) return KeymasterOperation();
@@ -219,12 +219,14 @@
if (!keymaster.upgradeKey(kmKey, keyParams, &newKey)) return KeymasterOperation();
auto newKeyPath = dir + "/" + kFn_keymaster_key_blob_upgraded;
if (!writeStringToFile(newKey, newKeyPath)) return KeymasterOperation();
- if (rename(newKeyPath.c_str(), kmKeyPath.c_str()) != 0) {
- PLOG(ERROR) << "Unable to move upgraded key to location: " << kmKeyPath;
- return KeymasterOperation();
- }
- if (!keymaster.deleteKey(kmKey)) {
- LOG(ERROR) << "Key deletion failed during upgrade, continuing anyway: " << dir;
+ if (!keepOld) {
+ if (rename(newKeyPath.c_str(), kmKeyPath.c_str()) != 0) {
+ PLOG(ERROR) << "Unable to move upgraded key to location: " << kmKeyPath;
+ return KeymasterOperation();
+ }
+ if (!keymaster.deleteKey(kmKey)) {
+ LOG(ERROR) << "Key deletion failed during upgrade, continuing anyway: " << dir;
+ }
}
kmKey = newKey;
LOG(INFO) << "Key upgraded: " << dir;
@@ -233,12 +235,12 @@
static bool encryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
const km::AuthorizationSet& keyParams,
- const km::HardwareAuthToken& authToken,
- const KeyBuffer& message, std::string* ciphertext) {
+ const km::HardwareAuthToken& authToken, const KeyBuffer& message,
+ std::string* ciphertext, bool keepOld) {
km::AuthorizationSet opParams;
km::AuthorizationSet outParams;
- auto opHandle =
- begin(keymaster, dir, km::KeyPurpose::ENCRYPT, keyParams, opParams, authToken, &outParams);
+ auto opHandle = begin(keymaster, dir, km::KeyPurpose::ENCRYPT, keyParams, opParams, authToken,
+ &outParams, keepOld);
if (!opHandle) return false;
auto nonceBlob = outParams.GetTagValue(km::TAG_NONCE);
if (!nonceBlob.isOk()) {
@@ -262,13 +264,14 @@
static bool decryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
const km::AuthorizationSet& keyParams,
const km::HardwareAuthToken& authToken,
- const std::string& ciphertext, KeyBuffer* message) {
+ const std::string& ciphertext, KeyBuffer* message,
+ bool keepOld) {
auto nonce = ciphertext.substr(0, GCM_NONCE_BYTES);
auto bodyAndMac = ciphertext.substr(GCM_NONCE_BYTES);
auto opParams = km::AuthorizationSetBuilder().Authorization(km::TAG_NONCE,
km::support::blob2hidlVec(nonce));
- auto opHandle =
- begin(keymaster, dir, km::KeyPurpose::DECRYPT, keyParams, opParams, authToken, nullptr);
+ auto opHandle = begin(keymaster, dir, km::KeyPurpose::DECRYPT, keyParams, opParams, authToken,
+ nullptr, keepOld);
if (!opHandle) return false;
if (!opHandle.updateCompletely(bodyAndMac, message)) return false;
if (!opHandle.finish(nullptr)) return false;
@@ -474,7 +477,8 @@
km::AuthorizationSet keyParams;
km::HardwareAuthToken authToken;
std::tie(keyParams, authToken) = beginParams(auth, appId);
- if (!encryptWithKeymasterKey(keymaster, dir, keyParams, authToken, key, &encryptedKey))
+ if (!encryptWithKeymasterKey(keymaster, dir, keyParams, authToken, key, &encryptedKey,
+ false))
return false;
} else {
if (!encryptWithoutKeymaster(appId, key, &encryptedKey)) return false;
@@ -502,7 +506,8 @@
return true;
}
-bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, KeyBuffer* key) {
+bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, KeyBuffer* key,
+ bool keepOld) {
std::string version;
if (!readFileToString(dir + "/" + kFn_version, &version)) return false;
if (version != kCurrentVersion) {
@@ -527,7 +532,8 @@
km::AuthorizationSet keyParams;
km::HardwareAuthToken authToken;
std::tie(keyParams, authToken) = beginParams(auth, appId);
- if (!decryptWithKeymasterKey(keymaster, dir, keyParams, authToken, encryptedMessage, key))
+ if (!decryptWithKeymasterKey(keymaster, dir, keyParams, authToken, encryptedMessage, key,
+ keepOld))
return false;
} else {
if (!decryptWithoutKeymaster(appId, encryptedMessage, key)) return false;