From f78e6bcf76a3dc403de57f592b064ee40144ee9a Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Wed, 26 Feb 2020 15:59:27 +0530 Subject: [PATCH] system: vold: Upgrade the FBE key During OTA upgrades if security state or ROT changes then Keymaster keys requires upgrade. So for such usescases, if the FBE ephemeral key export fails, check whether KM key requires upgrade and try for exporting ephemeral key again. CRs-Fixed: 2632902 Change-Id: I3ee2fcd97a56b628dc4304867c8f2b8da875f883 Signed-off-by: Neeraj Soni --- KeyStorage.cpp | 15 ++++++++++++++- Keymaster.cpp | 8 ++++---- Keymaster.h | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/KeyStorage.cpp b/KeyStorage.cpp index 951536b..3fab96a 100644 --- a/KeyStorage.cpp +++ b/KeyStorage.cpp @@ -154,7 +154,20 @@ bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key) { if (!keymaster) return false; std::string key_temp; - if (!keymaster.exportKey(kmKey, &key_temp)) return false; + auto ret = keymaster.exportKey(kmKey, &key_temp); + if (ret != km::ErrorCode::OK) { + if (ret == km::ErrorCode::KEY_REQUIRES_UPGRADE) { + std::string kmKeyStr(reinterpret_cast(kmKey.data()), kmKey.size()); + std::string Keystr; + if (!keymaster.upgradeKey(kmKeyStr, km::AuthorizationSet(), &Keystr)) return false; + KeyBuffer upgradedKey = KeyBuffer(Keystr.size()); + memcpy(reinterpret_cast(upgradedKey.data()), Keystr.c_str(), upgradedKey.size()); + ret = keymaster.exportKey(upgradedKey, &key_temp); + if (ret != km::ErrorCode::OK) return false; + } else { + return false; + } + } *key = KeyBuffer(key_temp.size()); memcpy(reinterpret_cast(key->data()), key_temp.c_str(), key->size()); return true; diff --git a/Keymaster.cpp b/Keymaster.cpp index 786cdb5..edba836 100644 --- a/Keymaster.cpp +++ b/Keymaster.cpp @@ -138,7 +138,7 @@ bool Keymaster::generateKey(const km::AuthorizationSet& inParams, std::string* k return true; } -bool Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) { +km::ErrorCode Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) { auto kmKeyBlob = km::support::blob2hidlVec(std::string(kmKey.data(), kmKey.size())); km::ErrorCode km_error; auto hidlCb = [&](km::ErrorCode ret, const hidl_vec& exportedKeyBlob) { @@ -150,13 +150,13 @@ bool Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) { auto error = mDevice->exportKey(km::KeyFormat::RAW, kmKeyBlob, {}, {}, hidlCb); if (!error.isOk()) { LOG(ERROR) << "export_key failed: " << error.description(); - return false; + return km::ErrorCode::UNKNOWN_ERROR; } if (km_error != km::ErrorCode::OK) { LOG(ERROR) << "export_key failed, code " << int32_t(km_error); - return false; + return km_error; } - return true; + return km::ErrorCode::OK; } bool Keymaster::deleteKey(const std::string& key) { diff --git a/Keymaster.h b/Keymaster.h index d9ced91..f8af564 100644 --- a/Keymaster.h +++ b/Keymaster.h @@ -115,7 +115,7 @@ class Keymaster { // Generate a key in the keymaster from the given params. bool generateKey(const km::AuthorizationSet& inParams, std::string* key); // Exports a keymaster key with STORAGE_KEY tag wrapped with a per-boot ephemeral key - bool exportKey(const KeyBuffer& kmKey, std::string* key); + km::ErrorCode exportKey(const KeyBuffer& kmKey, std::string* key); // If the keymaster supports it, permanently delete a key. bool deleteKey(const std::string& key); // Replace stored key blob in response to KM_ERROR_KEY_REQUIRES_UPGRADE.