OSDN Git Service

Remove HardwareAuthToken support from vold::Keymaster
authorSatya Tangirala <satyat@google.com>
Mon, 15 Mar 2021 22:33:08 +0000 (15:33 -0700)
committerSatya Tangirala <satyat@google.com>
Wed, 7 Apr 2021 09:05:35 +0000 (02:05 -0700)
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

FsCrypt.cpp
FsCrypt.h
KeyStorage.cpp
KeyStorage.h
Keymaster.cpp
Keymaster.h
VoldNativeService.cpp

index a56d196..cfa74e0 100644 (file)
@@ -490,7 +490,7 @@ bool fscrypt_init_user0() {
     // 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 bool parse_hex(const std::string& hex, std::string* result) {
 }
 
 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 @@ static bool read_or_create_volkey(const std::string& misc_path, const std::strin
     }
     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 @@ static bool fscrypt_rewrap_user_key(userid_t user_id, int serial,
     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 @@ bool fscrypt_fixate_newest_user_key_auth(userid_t user_id) {
 }
 
 // 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;
index 641991a..96159d5 100644 (file)
--- a/FsCrypt.h
+++ b/FsCrypt.h
@@ -23,14 +23,11 @@ bool fscrypt_initialize_systemwide_keys();
 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,
index 356d556..11e85fd 100644 (file)
@@ -57,7 +57,7 @@ extern "C" {
 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 @@ static bool generateKeymasterKey(Keymaster& keymaster,
     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 @@ bool exportWrappedStorageKey(const KeyBuffer& kmKey, KeyBuffer* key) {
     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 @@ static KeymasterOperation BeginKeymasterOp(Keymaster& keymaster, const std::stri
                                            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 @@ static KeymasterOperation BeginKeymasterOp(Keymaster& keymaster, const std::stri
         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 @@ static KeymasterOperation BeginKeymasterOp(Keymaster& keymaster, const std::stri
         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 encryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir
 
 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 bool decryptWithKeymasterKey(Keymaster& keymaster, const std::string& dir
 }
 
 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 @@ static bool stretchSecret(const std::string& stretching, const std::string& secr
         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 @@ bool storeKey(const std::string& dir, const KeyAuthentication& auth, const KeyBu
     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 @@ bool storeKey(const std::string& dir, const KeyAuthentication& auth, const KeyBu
         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 @@ bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, KeyBuffe
     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 @@ bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, KeyBuffe
     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;
index 5fded41..09d0aac 100644 (file)
@@ -33,11 +33,10 @@ namespace vold {
 // 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;
 };
 
index 786cdb5..e217ad4 100644 (file)
@@ -198,7 +198,6 @@ bool Keymaster::upgradeKey(const std::string& oldKey, const km::AuthorizationSet
 
 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 @@ KeymasterOperation Keymaster::begin(km::KeyPurpose purpose, const std::string& k
         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 @@ KeymasterSignResult keymaster_sign_object_for_cryptfs_scrypt(
 
     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;
index d9ced91..ccf018e 100644 (file)
@@ -124,7 +124,6 @@ class Keymaster {
     // 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();
 
index b6224da..938e7db 100644 (file)
@@ -724,13 +724,22 @@ binder::Status VoldNativeService::destroyUserKey(int32_t userId) {
     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 @@ binder::Status VoldNativeService::clearUserKeyAuth(int32_t userId, int32_t userS
     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 @@ binder::Status VoldNativeService::unlockUserKey(int32_t userId, int32_t userSeri
     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) {