Merge "Replace most references to Keymaster with Keystore" am: ec78a94586
am: 087a2952db
am: 23638cfcb3
Original change: https://android-review.googlesource.com/c/platform/system/vold/+/1737853 Change-Id: Iab08102098f80f2211f9b24e2e9b8b6a384f8ced
This commit is contained in:
commit
ef466e905e
9 changed files with 131 additions and 135 deletions
|
@ -123,7 +123,7 @@ cc_library_static {
|
|||
"KeyBuffer.cpp",
|
||||
"KeyStorage.cpp",
|
||||
"KeyUtil.cpp",
|
||||
"Keymaster.cpp",
|
||||
"Keystore.cpp",
|
||||
"Loop.cpp",
|
||||
"MetadataCrypt.cpp",
|
||||
"MoveStorage.cpp",
|
||||
|
@ -241,7 +241,7 @@ cc_binary {
|
|||
|
||||
srcs: [
|
||||
"wait_for_keymaster.cpp",
|
||||
"Keymaster.cpp",
|
||||
"Keystore.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbase",
|
||||
|
|
159
KeyStorage.cpp
159
KeyStorage.cpp
|
@ -17,7 +17,7 @@
|
|||
#include "KeyStorage.h"
|
||||
|
||||
#include "Checkpoint.h"
|
||||
#include "Keymaster.h"
|
||||
#include "Keystore.h"
|
||||
#include "ScryptParameters.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
@ -123,51 +123,49 @@ static void hashWithPrefix(char const* prefix, const std::string& tohash, std::s
|
|||
SHA512_Final(reinterpret_cast<uint8_t*>(&(*res)[0]), &c);
|
||||
}
|
||||
|
||||
// Generates a keymaster key, using rollback resistance if supported.
|
||||
static bool generateKeymasterKey(Keymaster& keymaster,
|
||||
const km::AuthorizationSetBuilder& paramBuilder,
|
||||
std::string* key) {
|
||||
// Generates a keystore key, using rollback resistance if supported.
|
||||
static bool generateKeystoreKey(Keystore& keystore, const km::AuthorizationSetBuilder& paramBuilder,
|
||||
std::string* key) {
|
||||
auto paramsWithRollback = paramBuilder;
|
||||
paramsWithRollback.Authorization(km::TAG_ROLLBACK_RESISTANCE);
|
||||
|
||||
if (!keymaster.generateKey(paramsWithRollback, key)) {
|
||||
LOG(WARNING) << "Failed to generate rollback-resistant key. This is expected if keymaster "
|
||||
if (!keystore.generateKey(paramsWithRollback, key)) {
|
||||
LOG(WARNING) << "Failed to generate rollback-resistant key. This is expected if keystore "
|
||||
"doesn't support rollback resistance. Falling back to "
|
||||
"non-rollback-resistant key.";
|
||||
if (!keymaster.generateKey(paramBuilder, key)) return false;
|
||||
if (!keystore.generateKey(paramBuilder, key)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool generateKeyStorageKey(Keymaster& keymaster, const std::string& appId,
|
||||
std::string* key) {
|
||||
static bool generateKeyStorageKey(Keystore& keystore, const std::string& appId, std::string* key) {
|
||||
auto paramBuilder = km::AuthorizationSetBuilder()
|
||||
.AesEncryptionKey(AES_KEY_BYTES * 8)
|
||||
.GcmModeMinMacLen(GCM_MAC_BYTES * 8)
|
||||
.Authorization(km::TAG_APPLICATION_ID, appId)
|
||||
.Authorization(km::TAG_NO_AUTH_REQUIRED);
|
||||
LOG(DEBUG) << "Generating \"key storage\" key";
|
||||
return generateKeymasterKey(keymaster, paramBuilder, key);
|
||||
return generateKeystoreKey(keystore, paramBuilder, key);
|
||||
}
|
||||
|
||||
bool generateWrappedStorageKey(KeyBuffer* key) {
|
||||
Keymaster keymaster;
|
||||
if (!keymaster) return false;
|
||||
Keystore keystore;
|
||||
if (!keystore) return false;
|
||||
std::string key_temp;
|
||||
auto paramBuilder = km::AuthorizationSetBuilder().AesEncryptionKey(AES_KEY_BYTES * 8);
|
||||
paramBuilder.Authorization(km::TAG_STORAGE_KEY);
|
||||
if (!generateKeymasterKey(keymaster, paramBuilder, &key_temp)) return false;
|
||||
if (!generateKeystoreKey(keystore, paramBuilder, &key_temp)) return false;
|
||||
*key = KeyBuffer(key_temp.size());
|
||||
memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key) {
|
||||
Keymaster keymaster;
|
||||
if (!keymaster) return false;
|
||||
bool exportWrappedStorageKey(const KeyBuffer& ksKey, KeyBuffer* key) {
|
||||
Keystore keystore;
|
||||
if (!keystore) return false;
|
||||
std::string key_temp;
|
||||
|
||||
if (!keymaster.exportKey(kmKey, &key_temp)) return false;
|
||||
if (!keystore.exportKey(ksKey, &key_temp)) return false;
|
||||
*key = KeyBuffer(key_temp.size());
|
||||
memcpy(reinterpret_cast<void*>(key->data()), key_temp.c_str(), key->size());
|
||||
return true;
|
||||
|
@ -213,15 +211,15 @@ bool readSecdiscardable(const std::string& filename, std::string* hash) {
|
|||
|
||||
static std::mutex key_upgrade_lock;
|
||||
|
||||
// List of key directories that have had their Keymaster key upgraded during
|
||||
// List of key directories that have had their Keystore key upgraded during
|
||||
// this boot and written to "keymaster_key_blob_upgraded", but replacing the old
|
||||
// key was delayed due to an active checkpoint. Protected by key_upgrade_lock.
|
||||
// A directory can be in this list at most once.
|
||||
static std::vector<std::string> key_dirs_to_commit;
|
||||
|
||||
// Replaces |dir|/keymaster_key_blob with |dir|/keymaster_key_blob_upgraded and
|
||||
// deletes the old key from Keymaster.
|
||||
static bool CommitUpgradedKey(Keymaster& keymaster, const std::string& dir) {
|
||||
// deletes the old key from Keystore.
|
||||
static bool CommitUpgradedKey(Keystore& keystore, const std::string& dir) {
|
||||
auto blob_file = dir + "/" + kFn_keymaster_key_blob;
|
||||
auto upgraded_blob_file = dir + "/" + kFn_keymaster_key_blob_upgraded;
|
||||
|
||||
|
@ -232,13 +230,13 @@ static bool CommitUpgradedKey(Keymaster& keymaster, const std::string& dir) {
|
|||
PLOG(ERROR) << "Failed to rename " << upgraded_blob_file << " to " << blob_file;
|
||||
return false;
|
||||
}
|
||||
// Ensure that the rename is persisted before deleting the Keymaster key.
|
||||
// Ensure that the rename is persisted before deleting the Keystore key.
|
||||
if (!FsyncDirectory(dir)) return false;
|
||||
|
||||
if (!keymaster || !keymaster.deleteKey(blob)) {
|
||||
if (!keystore || !keystore.deleteKey(blob)) {
|
||||
LOG(WARNING) << "Failed to delete old key " << blob_file
|
||||
<< " from Keymaster; continuing anyway";
|
||||
// Continue on, but the space in Keymaster used by the old key won't be freed.
|
||||
<< " from Keystore; continuing anyway";
|
||||
// Continue on, but the space in Keystore used by the old key won't be freed.
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -246,20 +244,20 @@ static bool CommitUpgradedKey(Keymaster& keymaster, const std::string& dir) {
|
|||
static void DeferredCommitKeys() {
|
||||
android::base::WaitForProperty("vold.checkpoint_committed", "1");
|
||||
LOG(INFO) << "Committing upgraded keys";
|
||||
Keymaster keymaster;
|
||||
if (!keymaster) {
|
||||
LOG(ERROR) << "Failed to open Keymaster; old keys won't be deleted from Keymaster";
|
||||
// Continue on, but the space in Keymaster used by the old keys won't be freed.
|
||||
Keystore keystore;
|
||||
if (!keystore) {
|
||||
LOG(ERROR) << "Failed to open Keystore; old keys won't be deleted from Keystore";
|
||||
// Continue on, but the space in Keystore used by the old keys won't be freed.
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(key_upgrade_lock);
|
||||
for (auto& dir : key_dirs_to_commit) {
|
||||
LOG(INFO) << "Committing upgraded key " << dir;
|
||||
CommitUpgradedKey(keymaster, dir);
|
||||
CommitUpgradedKey(keystore, dir);
|
||||
}
|
||||
key_dirs_to_commit.clear();
|
||||
}
|
||||
|
||||
// Returns true if the Keymaster key in |dir| has already been upgraded and is
|
||||
// Returns true if the Keystore key in |dir| has already been upgraded and is
|
||||
// pending being committed. Assumes that key_upgrade_lock is held.
|
||||
static bool IsKeyCommitPending(const std::string& dir) {
|
||||
for (const auto& dir_to_commit : key_dirs_to_commit) {
|
||||
|
@ -268,7 +266,7 @@ static bool IsKeyCommitPending(const std::string& dir) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Schedules the upgraded Keymaster key in |dir| to be committed later. Assumes
|
||||
// Schedules the upgraded Keystore key in |dir| to be committed later. Assumes
|
||||
// that key_upgrade_lock is held and that a commit isn't already pending for the
|
||||
// directory.
|
||||
static void ScheduleKeyCommit(const std::string& dir) {
|
||||
|
@ -313,16 +311,16 @@ bool RenameKeyDir(const std::string& old_name, const std::string& new_name) {
|
|||
// Deletes a leftover upgraded key, if present. An upgraded key can be left
|
||||
// over if an update failed, or if we rebooted before committing the key in a
|
||||
// freak accident. Either way, we can re-upgrade the key if we need to.
|
||||
static void DeleteUpgradedKey(Keymaster& keymaster, const std::string& path) {
|
||||
static void DeleteUpgradedKey(Keystore& keystore, const std::string& path) {
|
||||
if (pathExists(path)) {
|
||||
LOG(DEBUG) << "Deleting leftover upgraded key " << path;
|
||||
std::string blob;
|
||||
if (!android::base::ReadFileToString(path, &blob)) {
|
||||
LOG(WARNING) << "Failed to read leftover upgraded key " << path
|
||||
<< "; continuing anyway";
|
||||
} else if (!keymaster.deleteKey(blob)) {
|
||||
} else if (!keystore.deleteKey(blob)) {
|
||||
LOG(WARNING) << "Failed to delete leftover upgraded key " << path
|
||||
<< " from Keymaster; continuing anyway";
|
||||
<< " from Keystore; continuing anyway";
|
||||
}
|
||||
if (unlink(path.c_str()) != 0) {
|
||||
LOG(WARNING) << "Failed to unlink leftover upgraded key " << path
|
||||
|
@ -331,11 +329,11 @@ static void DeleteUpgradedKey(Keymaster& keymaster, const std::string& path) {
|
|||
}
|
||||
}
|
||||
|
||||
// Begins a Keymaster operation using the key stored in |dir|.
|
||||
static KeymasterOperation BeginKeymasterOp(Keymaster& keymaster, const std::string& dir,
|
||||
const km::AuthorizationSet& keyParams,
|
||||
const km::AuthorizationSet& opParams,
|
||||
km::AuthorizationSet* outParams) {
|
||||
// Begins a Keystore operation using the key stored in |dir|.
|
||||
static KeystoreOperation BeginKeystoreOp(Keystore& keystore, const std::string& dir,
|
||||
const km::AuthorizationSet& keyParams,
|
||||
const km::AuthorizationSet& opParams,
|
||||
km::AuthorizationSet* outParams) {
|
||||
km::AuthorizationSet inParams(keyParams);
|
||||
inParams.append(opParams.begin(), opParams.end());
|
||||
|
||||
|
@ -350,13 +348,13 @@ static KeymasterOperation BeginKeymasterOp(Keymaster& keymaster, const std::stri
|
|||
LOG(DEBUG)
|
||||
<< blob_file
|
||||
<< " was already upgraded and is waiting to be committed; using the upgraded blob";
|
||||
if (!readFileToString(upgraded_blob_file, &blob)) return KeymasterOperation();
|
||||
if (!readFileToString(upgraded_blob_file, &blob)) return KeystoreOperation();
|
||||
} else {
|
||||
DeleteUpgradedKey(keymaster, upgraded_blob_file);
|
||||
if (!readFileToString(blob_file, &blob)) return KeymasterOperation();
|
||||
DeleteUpgradedKey(keystore, upgraded_blob_file);
|
||||
if (!readFileToString(blob_file, &blob)) return KeystoreOperation();
|
||||
}
|
||||
|
||||
auto opHandle = keymaster.begin(blob, inParams, outParams);
|
||||
auto opHandle = keystore.begin(blob, inParams, outParams);
|
||||
if (!opHandle) return opHandle;
|
||||
|
||||
// If key blob wasn't upgraded, nothing left to do.
|
||||
|
@ -365,29 +363,29 @@ static KeymasterOperation BeginKeymasterOp(Keymaster& keymaster, const std::stri
|
|||
if (already_upgraded) {
|
||||
LOG(ERROR) << "Unexpected case; already-upgraded key " << upgraded_blob_file
|
||||
<< " still requires upgrade";
|
||||
return KeymasterOperation();
|
||||
return KeystoreOperation();
|
||||
}
|
||||
LOG(INFO) << "Upgrading key: " << blob_file;
|
||||
if (!writeStringToFile(*opHandle.getUpgradedBlob(), upgraded_blob_file))
|
||||
return KeymasterOperation();
|
||||
return KeystoreOperation();
|
||||
if (cp_needsCheckpoint()) {
|
||||
LOG(INFO) << "Wrote upgraded key to " << upgraded_blob_file
|
||||
<< "; delaying commit due to checkpoint";
|
||||
ScheduleKeyCommit(dir);
|
||||
} else {
|
||||
if (!CommitUpgradedKey(keymaster, dir)) return KeymasterOperation();
|
||||
if (!CommitUpgradedKey(keystore, dir)) return KeystoreOperation();
|
||||
LOG(INFO) << "Key upgraded: " << blob_file;
|
||||
}
|
||||
return opHandle;
|
||||
}
|
||||
|
||||
static bool encryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
|
||||
const km::AuthorizationSet& keyParams,
|
||||
const KeyBuffer& message, std::string* ciphertext) {
|
||||
static bool encryptWithKeystoreKey(Keystore& keystore, const std::string& dir,
|
||||
const km::AuthorizationSet& keyParams, const KeyBuffer& message,
|
||||
std::string* ciphertext) {
|
||||
km::AuthorizationSet opParams =
|
||||
km::AuthorizationSetBuilder().Authorization(km::TAG_PURPOSE, km::KeyPurpose::ENCRYPT);
|
||||
km::AuthorizationSet outParams;
|
||||
auto opHandle = BeginKeymasterOp(keymaster, dir, keyParams, opParams, &outParams);
|
||||
auto opHandle = BeginKeystoreOp(keystore, dir, keyParams, opParams, &outParams);
|
||||
if (!opHandle) return false;
|
||||
auto nonceBlob = outParams.GetTagValue(km::TAG_NONCE);
|
||||
if (!nonceBlob) {
|
||||
|
@ -407,15 +405,15 @@ static bool encryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool decryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
|
||||
const km::AuthorizationSet& keyParams,
|
||||
const std::string& ciphertext, KeyBuffer* message) {
|
||||
static bool decryptWithKeystoreKey(Keystore& keystore, const std::string& dir,
|
||||
const km::AuthorizationSet& keyParams,
|
||||
const std::string& ciphertext, KeyBuffer* message) {
|
||||
const std::string nonce = ciphertext.substr(0, GCM_NONCE_BYTES);
|
||||
auto bodyAndMac = ciphertext.substr(GCM_NONCE_BYTES);
|
||||
auto opParams = km::AuthorizationSetBuilder()
|
||||
.Authorization(km::TAG_NONCE, nonce)
|
||||
.Authorization(km::TAG_PURPOSE, km::KeyPurpose::DECRYPT);
|
||||
auto opHandle = BeginKeymasterOp(keymaster, dir, keyParams, opParams, nullptr);
|
||||
auto opHandle = BeginKeystoreOp(keystore, dir, keyParams, opParams, nullptr);
|
||||
if (!opHandle) return false;
|
||||
if (!opHandle.updateCompletely(bodyAndMac, message)) return false;
|
||||
if (!opHandle.finish(nullptr)) return false;
|
||||
|
@ -423,7 +421,7 @@ static bool decryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir
|
|||
}
|
||||
|
||||
static std::string getStretching(const KeyAuthentication& auth) {
|
||||
if (auth.usesKeymaster()) {
|
||||
if (auth.usesKeystore()) {
|
||||
return kStretch_nopassword;
|
||||
} else {
|
||||
return kStretch_none;
|
||||
|
@ -473,8 +471,8 @@ static void logOpensslError() {
|
|||
LOG(ERROR) << "Openssl error: " << ERR_get_error();
|
||||
}
|
||||
|
||||
static bool encryptWithoutKeymaster(const std::string& preKey, const KeyBuffer& plaintext,
|
||||
std::string* ciphertext) {
|
||||
static bool encryptWithoutKeystore(const std::string& preKey, const KeyBuffer& plaintext,
|
||||
std::string* ciphertext) {
|
||||
std::string key;
|
||||
hashWithPrefix(kHashPrefix_keygen, preKey, &key);
|
||||
key.resize(AES_KEY_BYTES);
|
||||
|
@ -523,8 +521,8 @@ static bool encryptWithoutKeymaster(const std::string& preKey, const KeyBuffer&
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool decryptWithoutKeymaster(const std::string& preKey, const std::string& ciphertext,
|
||||
KeyBuffer* plaintext) {
|
||||
static bool decryptWithoutKeystore(const std::string& preKey, const std::string& ciphertext,
|
||||
KeyBuffer* plaintext) {
|
||||
if (ciphertext.size() < GCM_NONCE_BYTES + GCM_MAC_BYTES) {
|
||||
LOG(ERROR) << "GCM ciphertext too small: " << ciphertext.size();
|
||||
return false;
|
||||
|
@ -576,7 +574,7 @@ static bool decryptWithoutKeymaster(const std::string& preKey, const std::string
|
|||
}
|
||||
|
||||
// Creates a directory at the given path |dir| and stores |key| in it, in such a
|
||||
// way that it can only be retrieved via Keymaster (if no secret is given in
|
||||
// way that it can only be retrieved via Keystore (if no secret is given in
|
||||
// |auth|) or with the given secret (if a secret is given in |auth|), and can be
|
||||
// securely deleted. If a storage binding seed has been set, then the storage
|
||||
// binding seed will be required to retrieve the key as well.
|
||||
|
@ -593,16 +591,16 @@ static bool storeKey(const std::string& dir, const KeyAuthentication& auth, cons
|
|||
std::string appId;
|
||||
if (!generateAppId(auth, stretching, secdiscardable_hash, &appId)) return false;
|
||||
std::string encryptedKey;
|
||||
if (auth.usesKeymaster()) {
|
||||
Keymaster keymaster;
|
||||
if (!keymaster) return false;
|
||||
std::string kmKey;
|
||||
if (!generateKeyStorageKey(keymaster, appId, &kmKey)) return false;
|
||||
if (!writeStringToFile(kmKey, dir + "/" + kFn_keymaster_key_blob)) return false;
|
||||
if (auth.usesKeystore()) {
|
||||
Keystore keystore;
|
||||
if (!keystore) return false;
|
||||
std::string ksKey;
|
||||
if (!generateKeyStorageKey(keystore, appId, &ksKey)) return false;
|
||||
if (!writeStringToFile(ksKey, dir + "/" + kFn_keymaster_key_blob)) return false;
|
||||
km::AuthorizationSet keyParams = beginParams(appId);
|
||||
if (!encryptWithKeymasterKey(keymaster, dir, keyParams, key, &encryptedKey)) return false;
|
||||
if (!encryptWithKeystoreKey(keystore, dir, keyParams, key, &encryptedKey)) return false;
|
||||
} else {
|
||||
if (!encryptWithoutKeymaster(appId, key, &encryptedKey)) return false;
|
||||
if (!encryptWithoutKeystore(appId, key, &encryptedKey)) return false;
|
||||
}
|
||||
if (!writeStringToFile(encryptedKey, dir + "/" + kFn_encrypted_key)) return false;
|
||||
if (!FsyncDirectory(dir)) return false;
|
||||
|
@ -643,25 +641,24 @@ bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, KeyBuffe
|
|||
if (!generateAppId(auth, stretching, secdiscardable_hash, &appId)) return false;
|
||||
std::string encryptedMessage;
|
||||
if (!readFileToString(dir + "/" + kFn_encrypted_key, &encryptedMessage)) return false;
|
||||
if (auth.usesKeymaster()) {
|
||||
Keymaster keymaster;
|
||||
if (!keymaster) return false;
|
||||
if (auth.usesKeystore()) {
|
||||
Keystore keystore;
|
||||
if (!keystore) return false;
|
||||
km::AuthorizationSet keyParams = beginParams(appId);
|
||||
if (!decryptWithKeymasterKey(keymaster, dir, keyParams, encryptedMessage, key))
|
||||
return false;
|
||||
if (!decryptWithKeystoreKey(keystore, dir, keyParams, encryptedMessage, key)) return false;
|
||||
} else {
|
||||
if (!decryptWithoutKeymaster(appId, encryptedMessage, key)) return false;
|
||||
if (!decryptWithoutKeystore(appId, encryptedMessage, key)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool DeleteKeymasterKey(const std::string& blob_file) {
|
||||
static bool DeleteKeystoreKey(const std::string& blob_file) {
|
||||
std::string blob;
|
||||
if (!readFileToString(blob_file, &blob)) return false;
|
||||
Keymaster keymaster;
|
||||
if (!keymaster) return false;
|
||||
LOG(DEBUG) << "Deleting key " << blob_file << " from Keymaster";
|
||||
if (!keymaster.deleteKey(blob)) return false;
|
||||
Keystore keystore;
|
||||
if (!keystore) return false;
|
||||
LOG(DEBUG) << "Deleting key " << blob_file << " from Keystore";
|
||||
if (!keystore.deleteKey(blob)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -697,7 +694,7 @@ bool destroyKey(const std::string& dir) {
|
|||
for (auto& fn : {kFn_keymaster_key_blob, kFn_keymaster_key_blob_upgraded}) {
|
||||
auto blob_file = dir + "/" + fn;
|
||||
if (pathExists(blob_file)) {
|
||||
success &= DeleteKeymasterKey(blob_file);
|
||||
success &= DeleteKeystoreKey(blob_file);
|
||||
secdiscard_cmd.push_back(blob_file);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class KeyAuthentication {
|
|||
public:
|
||||
KeyAuthentication(const std::string& s) : secret{s} {};
|
||||
|
||||
bool usesKeymaster() const { return secret.empty(); };
|
||||
bool usesKeystore() const { return secret.empty(); };
|
||||
|
||||
const std::string secret;
|
||||
};
|
||||
|
@ -61,10 +61,10 @@ bool destroyKey(const std::string& dir);
|
|||
|
||||
bool runSecdiscardSingle(const std::string& file);
|
||||
|
||||
// Generate wrapped storage key using keymaster. Uses STORAGE_KEY tag in keymaster.
|
||||
// Generate wrapped storage key using keystore. Uses STORAGE_KEY tag in keystore.
|
||||
bool generateWrappedStorageKey(KeyBuffer* key);
|
||||
// Export the per-boot boot wrapped storage key using keymaster.
|
||||
bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key);
|
||||
// Export the per-boot boot wrapped storage key using keystore.
|
||||
bool exportWrappedStorageKey(const KeyBuffer& ksKey, KeyBuffer* key);
|
||||
|
||||
// Set a seed to be mixed into all key storage encryption keys.
|
||||
bool setKeyStorageBindingSeed(const std::vector<uint8_t>& seed);
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "Keymaster.h"
|
||||
#include "Keystore.h"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
|
@ -43,7 +43,7 @@ namespace vold {
|
|||
|
||||
namespace ks2_maint = ::aidl::android::security::maintenance;
|
||||
|
||||
KeymasterOperation::~KeymasterOperation() {
|
||||
KeystoreOperation::~KeystoreOperation() {
|
||||
if (ks2Operation) ks2Operation->abort();
|
||||
}
|
||||
|
||||
|
@ -65,8 +65,8 @@ static bool logKeystore2ExceptionIfPresent(::ndk::ScopedAStatus& rc, const std::
|
|||
return true;
|
||||
}
|
||||
|
||||
bool KeymasterOperation::updateCompletely(const char* input, size_t inputLen,
|
||||
const std::function<void(const char*, size_t)> consumer) {
|
||||
bool KeystoreOperation::updateCompletely(const char* input, size_t inputLen,
|
||||
const std::function<void(const char*, size_t)> consumer) {
|
||||
if (!ks2Operation) return false;
|
||||
|
||||
while (inputLen != 0) {
|
||||
|
@ -87,7 +87,7 @@ bool KeymasterOperation::updateCompletely(const char* input, size_t inputLen,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool KeymasterOperation::finish(std::string* output) {
|
||||
bool KeystoreOperation::finish(std::string* output) {
|
||||
std::optional<std::vector<uint8_t>> out_vec;
|
||||
|
||||
if (!ks2Operation) return false;
|
||||
|
@ -103,7 +103,7 @@ bool KeymasterOperation::finish(std::string* output) {
|
|||
return true;
|
||||
}
|
||||
|
||||
Keymaster::Keymaster() {
|
||||
Keystore::Keystore() {
|
||||
::ndk::SpAIBinder binder(AServiceManager_waitForService(keystore2_service_name));
|
||||
auto keystore2Service = ks2::IKeystoreService::fromBinder(binder);
|
||||
|
||||
|
@ -127,7 +127,7 @@ Keymaster::Keymaster() {
|
|||
LOG(ERROR) << "Vold unable to get security level from keystore2.";
|
||||
}
|
||||
|
||||
bool Keymaster::generateKey(const km::AuthorizationSet& inParams, std::string* key) {
|
||||
bool Keystore::generateKey(const km::AuthorizationSet& inParams, std::string* key) {
|
||||
ks2::KeyDescriptor in_key = {
|
||||
.domain = ks2::Domain::BLOB,
|
||||
.alias = std::nullopt,
|
||||
|
@ -150,14 +150,14 @@ bool Keymaster::generateKey(const km::AuthorizationSet& inParams, std::string* k
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Keymaster::exportKey(const KeyBuffer& kmKey, std::string* key) {
|
||||
bool Keystore::exportKey(const KeyBuffer& ksKey, std::string* key) {
|
||||
bool ret = false;
|
||||
ks2::KeyDescriptor storageKey = {
|
||||
.domain = ks2::Domain::BLOB,
|
||||
.alias = std::nullopt,
|
||||
.nspace = VOLD_NAMESPACE,
|
||||
};
|
||||
storageKey.blob = std::make_optional<std::vector<uint8_t>>(kmKey.begin(), kmKey.end());
|
||||
storageKey.blob = std::make_optional<std::vector<uint8_t>>(ksKey.begin(), ksKey.end());
|
||||
ks2::EphemeralStorageKeyResponse ephemeral_key_response;
|
||||
auto rc = securityLevel->convertStorageKeyToEphemeral(storageKey, &ephemeral_key_response);
|
||||
|
||||
|
@ -175,7 +175,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool Keymaster::deleteKey(const std::string& key) {
|
||||
bool Keystore::deleteKey(const std::string& key) {
|
||||
ks2::KeyDescriptor keyDesc = {
|
||||
.domain = ks2::Domain::BLOB,
|
||||
.alias = std::nullopt,
|
||||
|
@ -188,8 +188,8 @@ bool Keymaster::deleteKey(const std::string& key) {
|
|||
return !logKeystore2ExceptionIfPresent(rc, "deleteKey");
|
||||
}
|
||||
|
||||
KeymasterOperation Keymaster::begin(const std::string& key, const km::AuthorizationSet& inParams,
|
||||
km::AuthorizationSet* outParams) {
|
||||
KeystoreOperation Keystore::begin(const std::string& key, const km::AuthorizationSet& inParams,
|
||||
km::AuthorizationSet* outParams) {
|
||||
ks2::KeyDescriptor keyDesc = {
|
||||
.domain = ks2::Domain::BLOB,
|
||||
.alias = std::nullopt,
|
||||
|
@ -202,22 +202,22 @@ KeymasterOperation Keymaster::begin(const std::string& key, const km::Authorizat
|
|||
auto rc = securityLevel->createOperation(keyDesc, inParams.vector_data(), true, &cor);
|
||||
if (logKeystore2ExceptionIfPresent(rc, "createOperation")) {
|
||||
if (rc.getExceptionCode() == EX_SERVICE_SPECIFIC)
|
||||
return KeymasterOperation((km::ErrorCode)rc.getServiceSpecificError());
|
||||
return KeystoreOperation((km::ErrorCode)rc.getServiceSpecificError());
|
||||
else
|
||||
return KeymasterOperation();
|
||||
return KeystoreOperation();
|
||||
}
|
||||
|
||||
if (!cor.iOperation) {
|
||||
LOG(ERROR) << "keystore2 createOperation didn't return an operation";
|
||||
return KeymasterOperation();
|
||||
return KeystoreOperation();
|
||||
}
|
||||
|
||||
if (outParams && cor.parameters) *outParams = cor.parameters->keyParameter;
|
||||
|
||||
return KeymasterOperation(cor.iOperation, cor.upgradedBlob);
|
||||
return KeystoreOperation(cor.iOperation, cor.upgradedBlob);
|
||||
}
|
||||
|
||||
void Keymaster::earlyBootEnded() {
|
||||
void Keystore::earlyBootEnded() {
|
||||
::ndk::SpAIBinder binder(AServiceManager_getService(maintenance_service_name));
|
||||
auto maint_service = ks2_maint::IKeystoreMaintenance::fromBinder(binder);
|
||||
|
|
@ -13,9 +13,8 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// TODO: Maybe "Keymaster" should be replaced with Keystore2 everywhere?
|
||||
#ifndef ANDROID_VOLD_KEYMASTER_H
|
||||
#define ANDROID_VOLD_KEYMASTER_H
|
||||
#ifndef ANDROID_VOLD_KEYSTORE_H
|
||||
#define ANDROID_VOLD_KEYSTORE_H
|
||||
|
||||
#include "KeyBuffer.h"
|
||||
|
||||
|
@ -45,9 +44,9 @@ namespace km = ::aidl::android::hardware::security::keymint;
|
|||
// ongoing Keystore2 operation. Aborts the operation
|
||||
// in the destructor if it is unfinished. Methods log failures
|
||||
// to LOG(ERROR).
|
||||
class KeymasterOperation {
|
||||
class KeystoreOperation {
|
||||
public:
|
||||
~KeymasterOperation();
|
||||
~KeystoreOperation();
|
||||
// Is this instance valid? This is false if creation fails, and becomes
|
||||
// false on finish or if an update fails.
|
||||
explicit operator bool() const { return (bool)ks2Operation; }
|
||||
|
@ -66,11 +65,11 @@ class KeymasterOperation {
|
|||
// Finish and write the output to this string, unless pointer is null.
|
||||
bool finish(std::string* output);
|
||||
// Move constructor
|
||||
KeymasterOperation(KeymasterOperation&& rhs) { *this = std::move(rhs); }
|
||||
KeystoreOperation(KeystoreOperation&& rhs) { *this = std::move(rhs); }
|
||||
// Construct an object in an error state for error returns
|
||||
KeymasterOperation() { errorCode = km::ErrorCode::UNKNOWN_ERROR; }
|
||||
KeystoreOperation() { errorCode = km::ErrorCode::UNKNOWN_ERROR; }
|
||||
// Move Assignment
|
||||
KeymasterOperation& operator=(KeymasterOperation&& rhs) {
|
||||
KeystoreOperation& operator=(KeystoreOperation&& rhs) {
|
||||
ks2Operation = rhs.ks2Operation;
|
||||
rhs.ks2Operation = nullptr;
|
||||
|
||||
|
@ -84,8 +83,8 @@ class KeymasterOperation {
|
|||
}
|
||||
|
||||
private:
|
||||
KeymasterOperation(std::shared_ptr<ks2::IKeystoreOperation> ks2Op,
|
||||
std::optional<std::vector<uint8_t>> blob)
|
||||
KeystoreOperation(std::shared_ptr<ks2::IKeystoreOperation> ks2Op,
|
||||
std::optional<std::vector<uint8_t>> blob)
|
||||
: ks2Operation{ks2Op}, errorCode{km::ErrorCode::OK} {
|
||||
if (blob)
|
||||
upgradedBlob = std::optional(std::string(blob->begin(), blob->end()));
|
||||
|
@ -93,7 +92,7 @@ class KeymasterOperation {
|
|||
upgradedBlob = std::nullopt;
|
||||
}
|
||||
|
||||
KeymasterOperation(km::ErrorCode errCode) : errorCode{errCode} {}
|
||||
KeystoreOperation(km::ErrorCode errCode) : errorCode{errCode} {}
|
||||
|
||||
bool updateCompletely(const char* input, size_t inputLen,
|
||||
const std::function<void(const char*, size_t)> consumer);
|
||||
|
@ -101,27 +100,27 @@ class KeymasterOperation {
|
|||
std::shared_ptr<ks2::IKeystoreOperation> ks2Operation;
|
||||
std::optional<std::string> upgradedBlob;
|
||||
km::ErrorCode errorCode;
|
||||
DISALLOW_COPY_AND_ASSIGN(KeymasterOperation);
|
||||
friend class Keymaster;
|
||||
DISALLOW_COPY_AND_ASSIGN(KeystoreOperation);
|
||||
friend class Keystore;
|
||||
};
|
||||
|
||||
// Wrapper for keystore2 methods that vold uses.
|
||||
class Keymaster {
|
||||
class Keystore {
|
||||
public:
|
||||
Keymaster();
|
||||
Keystore();
|
||||
// false if we failed to get a keystore2 security level.
|
||||
explicit operator bool() { return (bool)securityLevel; }
|
||||
// Generate a key using keystore2 from the given params.
|
||||
bool generateKey(const km::AuthorizationSet& inParams, std::string* key);
|
||||
// Exports a keystore2 key with STORAGE_KEY tag wrapped with a per-boot ephemeral key
|
||||
bool exportKey(const KeyBuffer& kmKey, std::string* key);
|
||||
bool exportKey(const KeyBuffer& ksKey, std::string* key);
|
||||
// If supported, permanently delete a key from the keymint device it belongs to.
|
||||
bool deleteKey(const std::string& key);
|
||||
// Begin a new cryptographic operation, collecting output parameters if pointer is non-null
|
||||
// If the key was upgraded as a result of a call to this method, the returned KeymasterOperation
|
||||
// If the key was upgraded as a result of a call to this method, the returned KeystoreOperation
|
||||
// also stores the upgraded key blob.
|
||||
KeymasterOperation begin(const std::string& key, const km::AuthorizationSet& inParams,
|
||||
km::AuthorizationSet* outParams);
|
||||
KeystoreOperation begin(const std::string& key, const km::AuthorizationSet& inParams,
|
||||
km::AuthorizationSet* outParams);
|
||||
|
||||
// Tell all Keymint devices that early boot has ended and early boot-only keys can no longer
|
||||
// be created or used.
|
||||
|
@ -129,7 +128,7 @@ class Keymaster {
|
|||
|
||||
private:
|
||||
std::shared_ptr<ks2::IKeystoreSecurityLevel> securityLevel;
|
||||
DISALLOW_COPY_AND_ASSIGN(Keymaster);
|
||||
DISALLOW_COPY_AND_ASSIGN(Keystore);
|
||||
};
|
||||
|
||||
} // namespace vold
|
|
@ -38,7 +38,7 @@
|
|||
#include "EncryptInplace.h"
|
||||
#include "KeyStorage.h"
|
||||
#include "KeyUtil.h"
|
||||
#include "Keymaster.h"
|
||||
#include "Keystore.h"
|
||||
#include "Utils.h"
|
||||
#include "VoldUtil.h"
|
||||
#include "fs/Ext4.h"
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "FsCrypt.h"
|
||||
#include "IdleMaint.h"
|
||||
#include "KeyStorage.h"
|
||||
#include "Keymaster.h"
|
||||
#include "Keystore.h"
|
||||
#include "MetadataCrypt.h"
|
||||
#include "MoveStorage.h"
|
||||
#include "Process.h"
|
||||
|
@ -944,7 +944,7 @@ binder::Status VoldNativeService::earlyBootEnded() {
|
|||
ACQUIRE_LOCK;
|
||||
|
||||
initializeIncFs();
|
||||
Keymaster::earlyBootEnded();
|
||||
Keystore::earlyBootEnded();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "CryptoType.h"
|
||||
#include "EncryptInplace.h"
|
||||
#include "FsCrypt.h"
|
||||
#include "Keymaster.h"
|
||||
#include "Keystore.h"
|
||||
#include "Process.h"
|
||||
#include "ScryptParameters.h"
|
||||
#include "Utils.h"
|
||||
|
@ -349,7 +349,7 @@ static int keymaster_create_key_for_cryptfs_scrypt(uint32_t rsa_key_size, uint64
|
|||
if (key_out_size) {
|
||||
*key_out_size = 0;
|
||||
}
|
||||
Keymaster dev;
|
||||
Keystore dev;
|
||||
if (!dev) {
|
||||
LOG(ERROR) << "Failed to initiate keymaster session";
|
||||
return -1;
|
||||
|
@ -395,7 +395,7 @@ static int keymaster_sign_object_for_cryptfs_scrypt(struct crypt_mnt_ftr* ftr, u
|
|||
return -1;
|
||||
}
|
||||
|
||||
Keymaster dev;
|
||||
Keystore dev;
|
||||
if (!dev) {
|
||||
LOG(ERROR) << "Failed to initiate keymaster session";
|
||||
return -1;
|
||||
|
@ -405,7 +405,7 @@ static int keymaster_sign_object_for_cryptfs_scrypt(struct crypt_mnt_ftr* ftr, u
|
|||
std::string key(reinterpret_cast<const char*>(ftr->keymaster_blob), ftr->keymaster_blob_size);
|
||||
std::string input(reinterpret_cast<const char*>(object), object_size);
|
||||
std::string output;
|
||||
KeymasterOperation op;
|
||||
KeystoreOperation op;
|
||||
|
||||
auto paramBuilder = km::AuthorizationSetBuilder().NoDigestOrPadding().Authorization(
|
||||
km::TAG_PURPOSE, km::KeyPurpose::SIGN);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include "Keymaster.h"
|
||||
#include "Keystore.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
setenv("ANDROID_LOG_TAGS", "*:v", 1);
|
||||
|
@ -26,8 +26,8 @@ int main(int argc, char** argv) {
|
|||
} else {
|
||||
android::base::InitLogging(argv, &android::base::StderrLogger);
|
||||
}
|
||||
LOG(INFO) << "Waiting for Keymaster device";
|
||||
android::vold::Keymaster keymaster;
|
||||
LOG(INFO) << "Keymaster device ready";
|
||||
LOG(INFO) << "Waiting for Keystore to be ready";
|
||||
android::vold::Keystore keystore;
|
||||
LOG(INFO) << "Keystore ready";
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue