Remove HardwareAuthToken support from vold::Keymaster
HardwareAuthTokens are no longer used by vold since Android P. So remove
the auth token parameter from vold. This patch doesn't remove the token
from IVold.aidl, and the methods in VoldNativeService.cpp return an
error if a non-empty auth token is passed to them.
Bug: 181910578
Test: cuttlefish and bramble boot with patch
Change-Id: I1a9f54e10f9efdda9973906afd0a5de5a699ada5
diff --git a/FsCrypt.cpp b/FsCrypt.cpp
index a56d196..cfa74e0 100644
--- a/FsCrypt.cpp
+++ b/FsCrypt.cpp
@@ -490,7 +490,7 @@
// If this is a non-FBE device that recently left an emulated mode,
// restore user data directories to known-good state.
if (!fscrypt_is_native() && !fscrypt_is_emulated()) {
- fscrypt_unlock_user_key(0, 0, "!", "!");
+ fscrypt_unlock_user_key(0, 0, "!");
}
// In some scenarios (e.g. userspace reboot) we might unmount userdata
@@ -625,14 +625,13 @@
}
static std::optional<android::vold::KeyAuthentication> authentication_from_hex(
- const std::string& token_hex, const std::string& secret_hex) {
- std::string token, secret;
- if (!parse_hex(token_hex, &token)) return std::optional<android::vold::KeyAuthentication>();
+ const std::string& secret_hex) {
+ std::string secret;
if (!parse_hex(secret_hex, &secret)) return std::optional<android::vold::KeyAuthentication>();
if (secret.empty()) {
return kEmptyAuthentication;
} else {
- return android::vold::KeyAuthentication(token, secret);
+ return android::vold::KeyAuthentication(secret);
}
}
@@ -658,7 +657,7 @@
}
auto key_path = volkey_path(misc_path, volume_uuid);
if (!android::vold::MkdirsSync(key_path, 0700)) return false;
- android::vold::KeyAuthentication auth("", secdiscardable_hash);
+ android::vold::KeyAuthentication auth(secdiscardable_hash);
EncryptionOptions options;
if (!get_volume_file_encryption_options(&options)) return false;
@@ -701,22 +700,18 @@
return true;
}
-bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
- const std::string& secret_hex) {
- LOG(DEBUG) << "fscrypt_add_user_key_auth " << user_id << " serial=" << serial
- << " token_present=" << (token_hex != "!");
+bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& secret_hex) {
+ LOG(DEBUG) << "fscrypt_add_user_key_auth " << user_id << " serial=" << serial;
if (!fscrypt_is_native()) return true;
- auto auth = authentication_from_hex(token_hex, secret_hex);
+ auto auth = authentication_from_hex(secret_hex);
if (!auth) return false;
return fscrypt_rewrap_user_key(user_id, serial, kEmptyAuthentication, *auth);
}
-bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token_hex,
- const std::string& secret_hex) {
- LOG(DEBUG) << "fscrypt_clear_user_key_auth " << user_id << " serial=" << serial
- << " token_present=" << (token_hex != "!");
+bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& secret_hex) {
+ LOG(DEBUG) << "fscrypt_clear_user_key_auth " << user_id << " serial=" << serial;
if (!fscrypt_is_native()) return true;
- auto auth = authentication_from_hex(token_hex, secret_hex);
+ auto auth = authentication_from_hex(secret_hex);
if (!auth) return false;
return fscrypt_rewrap_user_key(user_id, serial, *auth, kEmptyAuthentication);
}
@@ -736,16 +731,14 @@
}
// TODO: rename to 'install' for consistency, and take flags to know which keys to install
-bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& token_hex,
- const std::string& secret_hex) {
- LOG(DEBUG) << "fscrypt_unlock_user_key " << user_id << " serial=" << serial
- << " token_present=" << (token_hex != "!");
+bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& secret_hex) {
+ LOG(DEBUG) << "fscrypt_unlock_user_key " << user_id << " serial=" << serial;
if (fscrypt_is_native()) {
if (s_ce_policies.count(user_id) != 0) {
LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
return true;
}
- auto auth = authentication_from_hex(token_hex, secret_hex);
+ auto auth = authentication_from_hex(secret_hex);
if (!auth) return false;
if (!read_and_install_user_ce_key(user_id, *auth)) {
LOG(ERROR) << "Couldn't read key for " << user_id;
diff --git a/FsCrypt.h b/FsCrypt.h
index 641991a..96159d5 100644
--- a/FsCrypt.h
+++ b/FsCrypt.h
@@ -23,14 +23,11 @@
bool fscrypt_init_user0();
bool fscrypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral);
bool fscrypt_destroy_user_key(userid_t user_id);
-bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& token,
- const std::string& secret);
-bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& token,
- const std::string& secret);
+bool fscrypt_add_user_key_auth(userid_t user_id, int serial, const std::string& secret);
+bool fscrypt_clear_user_key_auth(userid_t user_id, int serial, const std::string& secret);
bool fscrypt_fixate_newest_user_key_auth(userid_t user_id);
-bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& token,
- const std::string& secret);
+bool fscrypt_unlock_user_key(userid_t user_id, int serial, const std::string& secret);
bool fscrypt_lock_user_key(userid_t user_id);
bool fscrypt_prepare_user_storage(const std::string& volume_uuid, userid_t user_id, int serial,
diff --git a/KeyStorage.cpp b/KeyStorage.cpp
index 356d556..11e85fd 100644
--- a/KeyStorage.cpp
+++ b/KeyStorage.cpp
@@ -57,7 +57,7 @@
namespace android {
namespace vold {
-const KeyAuthentication kEmptyAuthentication{"", ""};
+const KeyAuthentication kEmptyAuthentication{""};
static constexpr size_t AES_KEY_BYTES = 32;
static constexpr size_t GCM_NONCE_BYTES = 12;
@@ -149,28 +149,15 @@
return true;
}
-static bool generateKeyStorageKey(Keymaster& keymaster, const KeyAuthentication& auth,
- 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, km::support::blob2hidlVec(appId));
- if (auth.token.empty()) {
- LOG(DEBUG) << "Generating \"key storage\" key that doesn't need auth token";
- paramBuilder.Authorization(km::TAG_NO_AUTH_REQUIRED);
- } else {
- LOG(DEBUG) << "Generating \"key storage\" key that needs auth token";
- if (auth.token.size() != sizeof(hw_auth_token_t)) {
- LOG(ERROR) << "Auth token should be " << sizeof(hw_auth_token_t) << " bytes, was "
- << auth.token.size() << " bytes";
- return false;
- }
- const hw_auth_token_t* at = reinterpret_cast<const hw_auth_token_t*>(auth.token.data());
- auto user_id = at->user_id; // Make a copy because at->user_id is unaligned.
- paramBuilder.Authorization(km::TAG_USER_SECURE_ID, user_id);
- paramBuilder.Authorization(km::TAG_USER_AUTH_TYPE, km::HardwareAuthenticatorType::PASSWORD);
- paramBuilder.Authorization(km::TAG_AUTH_TIMEOUT, AUTH_TIMEOUT);
- }
+static bool generateKeyStorageKey(Keymaster& keymaster, 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, km::support::blob2hidlVec(appId))
+ .Authorization(km::TAG_NO_AUTH_REQUIRED);
+ LOG(DEBUG) << "Generating \"key storage\" key that doesn't need auth token";
return generateKeymasterKey(keymaster, paramBuilder, key);
}
@@ -197,17 +184,10 @@
return true;
}
-static std::pair<km::AuthorizationSet, km::HardwareAuthToken> beginParams(
- const KeyAuthentication& auth, const std::string& appId) {
- auto paramBuilder = km::AuthorizationSetBuilder()
- .GcmModeMacLen(GCM_MAC_BYTES * 8)
- .Authorization(km::TAG_APPLICATION_ID, km::support::blob2hidlVec(appId));
- km::HardwareAuthToken authToken;
- if (!auth.token.empty()) {
- LOG(DEBUG) << "Supplying auth token to Keymaster";
- authToken = km::support::hidlVec2AuthToken(km::support::blob2hidlVec(auth.token));
- }
- return {paramBuilder, authToken};
+static km::AuthorizationSet beginParams(const std::string& appId) {
+ return km::AuthorizationSetBuilder()
+ .GcmModeMacLen(GCM_MAC_BYTES * 8)
+ .Authorization(km::TAG_APPLICATION_ID, km::support::blob2hidlVec(appId));
}
static bool readFileToString(const std::string& filename, std::string* result) {
@@ -343,7 +323,6 @@
km::KeyPurpose purpose,
const km::AuthorizationSet& keyParams,
const km::AuthorizationSet& opParams,
- const km::HardwareAuthToken& authToken,
km::AuthorizationSet* outParams) {
km::AuthorizationSet inParams(keyParams);
inParams.append(opParams.begin(), opParams.end());
@@ -365,7 +344,7 @@
if (!readFileToString(blob_file, &blob)) return KeymasterOperation();
}
- auto opHandle = keymaster.begin(purpose, blob, inParams, authToken, outParams);
+ auto opHandle = keymaster.begin(purpose, blob, inParams, outParams);
if (opHandle) return opHandle;
if (opHandle.errorCode() != km::ErrorCode::KEY_REQUIRES_UPGRADE) return opHandle;
@@ -386,17 +365,16 @@
LOG(INFO) << "Key upgraded: " << blob_file;
}
- return keymaster.begin(purpose, blob, inParams, authToken, outParams);
+ return keymaster.begin(purpose, blob, inParams, outParams);
}
static bool encryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
const km::AuthorizationSet& keyParams,
- const km::HardwareAuthToken& authToken,
const KeyBuffer& message, std::string* ciphertext) {
km::AuthorizationSet opParams;
km::AuthorizationSet outParams;
auto opHandle = BeginKeymasterOp(keymaster, dir, km::KeyPurpose::ENCRYPT, keyParams, opParams,
- authToken, &outParams);
+ &outParams);
if (!opHandle) return false;
auto nonceBlob = outParams.GetTagValue(km::TAG_NONCE);
if (!nonceBlob.isOk()) {
@@ -419,14 +397,13 @@
static bool decryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir,
const km::AuthorizationSet& keyParams,
- const km::HardwareAuthToken& authToken,
const std::string& ciphertext, KeyBuffer* message) {
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 = BeginKeymasterOp(keymaster, dir, km::KeyPurpose::DECRYPT, keyParams, opParams,
- authToken, nullptr);
+ auto opHandle =
+ BeginKeymasterOp(keymaster, dir, km::KeyPurpose::DECRYPT, keyParams, opParams, nullptr);
if (!opHandle) return false;
if (!opHandle.updateCompletely(bodyAndMac, message)) return false;
if (!opHandle.finish(nullptr)) return false;
@@ -434,22 +411,13 @@
}
static std::string getStretching(const KeyAuthentication& auth) {
- if (!auth.usesKeymaster()) {
- return kStretch_none;
- } else if (auth.secret.empty()) {
+ if (auth.usesKeymaster()) {
return kStretch_nopassword;
} else {
- char paramstr[PROPERTY_VALUE_MAX];
-
- property_get(SCRYPT_PROP, paramstr, SCRYPT_DEFAULTS);
- return std::string() + kStretchPrefix_scrypt + paramstr;
+ return kStretch_none;
}
}
-static bool stretchingNeedsSalt(const std::string& stretching) {
- return stretching != kStretch_nopassword && stretching != kStretch_none;
-}
-
static bool stretchSecret(const std::string& stretching, const std::string& secret,
const std::string& salt, std::string* stretched) {
if (stretching == kStretch_nopassword) {
@@ -460,22 +428,6 @@
stretched->clear();
} else if (stretching == kStretch_none) {
*stretched = secret;
- } else if (std::equal(kStretchPrefix_scrypt.begin(), kStretchPrefix_scrypt.end(),
- stretching.begin())) {
- int Nf, rf, pf;
- if (!parse_scrypt_parameters(stretching.substr(kStretchPrefix_scrypt.size()).c_str(), &Nf,
- &rf, &pf)) {
- LOG(ERROR) << "Unable to parse scrypt params in stretching: " << stretching;
- return false;
- }
- stretched->assign(STRETCHED_BYTES, '\0');
- if (crypto_scrypt(reinterpret_cast<const uint8_t*>(secret.data()), secret.size(),
- reinterpret_cast<const uint8_t*>(salt.data()), salt.size(), 1 << Nf,
- 1 << rf, 1 << pf, reinterpret_cast<uint8_t*>(&(*stretched)[0]),
- stretched->size()) != 0) {
- LOG(ERROR) << "scrypt failed with params: " << stretching;
- return false;
- }
} else {
LOG(ERROR) << "Unknown stretching type: " << stretching;
return false;
@@ -623,13 +575,6 @@
std::string stretching = getStretching(auth);
if (!writeStringToFile(stretching, dir + "/" + kFn_stretching)) return false;
std::string salt;
- if (stretchingNeedsSalt(stretching)) {
- if (ReadRandomBytes(SALT_BYTES, salt) != OK) {
- LOG(ERROR) << "Random read failed";
- return false;
- }
- if (!writeStringToFile(salt, dir + "/" + kFn_salt)) return false;
- }
std::string appId;
if (!generateAppId(auth, stretching, salt, secdiscardable_hash, &appId)) return false;
std::string encryptedKey;
@@ -637,13 +582,10 @@
Keymaster keymaster;
if (!keymaster) return false;
std::string kmKey;
- if (!generateKeyStorageKey(keymaster, auth, appId, &kmKey)) return false;
+ if (!generateKeyStorageKey(keymaster, appId, &kmKey)) return false;
if (!writeStringToFile(kmKey, dir + "/" + kFn_keymaster_key_blob)) return false;
- km::AuthorizationSet keyParams;
- km::HardwareAuthToken authToken;
- std::tie(keyParams, authToken) = beginParams(auth, appId);
- if (!encryptWithKeymasterKey(keymaster, dir, keyParams, authToken, key, &encryptedKey))
- return false;
+ km::AuthorizationSet keyParams = beginParams(appId);
+ if (!encryptWithKeymasterKey(keymaster, dir, keyParams, key, &encryptedKey)) return false;
} else {
if (!encryptWithoutKeymaster(appId, key, &encryptedKey)) return false;
}
@@ -684,9 +626,6 @@
std::string stretching;
if (!readFileToString(dir + "/" + kFn_stretching, &stretching)) return false;
std::string salt;
- if (stretchingNeedsSalt(stretching)) {
- if (!readFileToString(dir + "/" + kFn_salt, &salt)) return false;
- }
std::string appId;
if (!generateAppId(auth, stretching, salt, secdiscardable_hash, &appId)) return false;
std::string encryptedMessage;
@@ -694,10 +633,8 @@
if (auth.usesKeymaster()) {
Keymaster keymaster;
if (!keymaster) return false;
- km::AuthorizationSet keyParams;
- km::HardwareAuthToken authToken;
- std::tie(keyParams, authToken) = beginParams(auth, appId);
- if (!decryptWithKeymasterKey(keymaster, dir, keyParams, authToken, encryptedMessage, key))
+ km::AuthorizationSet keyParams = beginParams(appId);
+ if (!decryptWithKeymasterKey(keymaster, dir, keyParams, encryptedMessage, key))
return false;
} else {
if (!decryptWithoutKeymaster(appId, encryptedMessage, key)) return false;
diff --git a/KeyStorage.h b/KeyStorage.h
index 5fded41..09d0aac 100644
--- a/KeyStorage.h
+++ b/KeyStorage.h
@@ -33,11 +33,10 @@
// If only "secret" is nonempty, it is used to decrypt in a non-Keymaster process.
class KeyAuthentication {
public:
- KeyAuthentication(const std::string& t, const std::string& s) : token{t}, secret{s} {};
+ KeyAuthentication(const std::string& s) : secret{s} {};
- bool usesKeymaster() const { return !token.empty() || secret.empty(); };
+ bool usesKeymaster() const { return secret.empty(); };
- const std::string token;
const std::string secret;
};
diff --git a/Keymaster.cpp b/Keymaster.cpp
index 786cdb5..e217ad4 100644
--- a/Keymaster.cpp
+++ b/Keymaster.cpp
@@ -198,7 +198,6 @@
KeymasterOperation Keymaster::begin(km::KeyPurpose purpose, const std::string& key,
const km::AuthorizationSet& inParams,
- const km::HardwareAuthToken& authToken,
km::AuthorizationSet* outParams) {
auto keyBlob = km::support::blob2hidlVec(key);
uint64_t mOpHandle;
@@ -212,7 +211,8 @@
mOpHandle = operationHandle;
};
- auto error = mDevice->begin(purpose, keyBlob, inParams.hidl_data(), authToken, hidlCb);
+ auto error =
+ mDevice->begin(purpose, keyBlob, inParams.hidl_data(), km::HardwareAuthToken(), hidlCb);
if (!error.isOk()) {
LOG(ERROR) << "begin failed: " << error.description();
return KeymasterOperation(km::ErrorCode::UNKNOWN_ERROR);
@@ -343,7 +343,7 @@
auto paramBuilder = km::AuthorizationSetBuilder().NoDigestOrPadding();
while (true) {
- op = dev.begin(km::KeyPurpose::SIGN, key, paramBuilder, km::HardwareAuthToken(), &outParams);
+ op = dev.begin(km::KeyPurpose::SIGN, key, paramBuilder, &outParams);
if (op.errorCode() == km::ErrorCode::KEY_RATE_LIMIT_EXCEEDED) {
sleep(ratelimit);
continue;
diff --git a/Keymaster.h b/Keymaster.h
index d9ced91..ccf018e 100644
--- a/Keymaster.h
+++ b/Keymaster.h
@@ -124,7 +124,6 @@
// Begin a new cryptographic operation, collecting output parameters if pointer is non-null
KeymasterOperation begin(km::KeyPurpose purpose, const std::string& key,
const km::AuthorizationSet& inParams,
- const km::HardwareAuthToken& authToken,
km::AuthorizationSet* outParams);
bool isSecure();
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index b6224da..938e7db 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -724,13 +724,22 @@
return translateBool(fscrypt_destroy_user_key(userId));
}
+static bool token_empty(const std::string& token) {
+ return token.size() == 0 || token == "!";
+}
+
binder::Status VoldNativeService::addUserKeyAuth(int32_t userId, int32_t userSerial,
const std::string& token,
const std::string& secret) {
ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_CRYPT_LOCK;
- return translateBool(fscrypt_add_user_key_auth(userId, userSerial, token, secret));
+ if (!token_empty(token)) {
+ LOG(ERROR) << "Vold doesn't use auth tokens, but non-empty token passed to addUserKeyAuth.";
+ return binder::Status::fromServiceSpecificError(-EINVAL);
+ }
+
+ return translateBool(fscrypt_add_user_key_auth(userId, userSerial, secret));
}
binder::Status VoldNativeService::clearUserKeyAuth(int32_t userId, int32_t userSerial,
@@ -739,7 +748,13 @@
ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_CRYPT_LOCK;
- return translateBool(fscrypt_clear_user_key_auth(userId, userSerial, token, secret));
+ if (!token_empty(token)) {
+ LOG(ERROR)
+ << "Vold doesn't use auth tokens, but non-empty token passed to clearUserKeyAuth.";
+ return binder::Status::fromServiceSpecificError(-EINVAL);
+ }
+
+ return translateBool(fscrypt_clear_user_key_auth(userId, userSerial, secret));
}
binder::Status VoldNativeService::fixateNewestUserKeyAuth(int32_t userId) {
@@ -755,7 +770,12 @@
ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_CRYPT_LOCK;
- return translateBool(fscrypt_unlock_user_key(userId, userSerial, token, secret));
+ if (!token_empty(token)) {
+ LOG(ERROR) << "Vold doesn't use auth tokens, but non-empty token passed to unlockUserKey.";
+ return binder::Status::fromServiceSpecificError(-EINVAL);
+ }
+
+ return translateBool(fscrypt_unlock_user_key(userId, userSerial, secret));
}
binder::Status VoldNativeService::lockUserKey(int32_t userId) {