From a09ecaa8d509ce3ee4f65148f54a3775f48ac9c6 Mon Sep 17 00:00:00 2001 From: zhaoshuyuan Date: Fri, 15 Nov 2024 16:41:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=95=E6=A1=86=E6=9E=B6=E9=80=82=E5=BA=94?= =?UTF-8?q?=E5=8F=8C=E6=A1=86=E6=9E=B6=E5=AE=89=E5=85=A8=E5=8A=A0=E5=9B=BA?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhaoshuyuan --- .../storage_daemon/crypto/src/base_key.cpp | 52 ++++++++++-- .../crypto/src/fscrypt_key_v1_ext.cpp | 3 +- .../storage_daemon/crypto/src/key_manager.cpp | 15 ++++ .../storage_daemon/include/crypto/base_key.h | 6 ++ .../include/ipc/storage_daemon.h | 8 ++ .../storage_daemon/ipc/src/storage_daemon.cpp | 79 +++++++++++++++++-- 6 files changed, 151 insertions(+), 12 deletions(-) diff --git a/services/storage_daemon/crypto/src/base_key.cpp b/services/storage_daemon/crypto/src/base_key.cpp index 81e005a5..4b919d3d 100644 --- a/services/storage_daemon/crypto/src/base_key.cpp +++ b/services/storage_daemon/crypto/src/base_key.cpp @@ -317,14 +317,14 @@ bool BaseKey::SaveAndCleanKeyBuff(const std::string &keyPath, KeyContext &keyCtx return false; } + storeKey.Clear(); + ClearKeyContext(keyCtx); const std::string NEED_UPDATE_PATH = keyPath + SUFFIX_NEED_UPDATE; if (!SaveStringToFile(NEED_UPDATE_PATH, KeyEncryptTypeToString(keyEncryptType_))) { LOGE("Save key type file failed"); return false; } - storeKey.Clear(); - ClearKeyContext(keyCtx); return true; } @@ -691,10 +691,24 @@ bool BaseKey::DoRestoreKey(const UserAuth &auth, const std::string &path) if (encryptType == KeyEncryptTypeToString(KeyEncryptType::KEY_CRYPT_HUKS_OPENSSL)) { LOGI("Restore ce ece sece key."); ret = DoRestoreKeyCeEceSece(auth, path, keyType); - } else { - ret = DoUpdateRestore(auth, path); } - LOGI("end ret %{public}u", ret); + std::error_code errCode; + std::string need_restore; + LoadStringFromFile(path + SUFFIX_NEED_RESTORE, need_restore); + uint32_t restore_version = std::atoi(need_restore.c_str()); + UpdateVersion update_version = static_cast(std::atoi(need_restore.c_str()) + 1); + LOGI("NeedRestore Path is: %{public}s, restore_version: %{public}u", path.c_str(), restore_version); + if (std::filesystem::exists(path + SUFFIX_NEED_RESTORE, errCode)) { + if (restore_version < 3) { + LOGI("Old DOUBLE_2_SINGLE."); + ret = DoUpdateRestore(auth, path); + } + else { + LOGI("New DOUBLE_2_SINGLE."); + ret = DoUpdateRestoreVx(auth, path, update_version); + } + } + LOGI("end ret %{public}u, filepath isExist: %{public}u", ret, errCode.value()); return ret != 0; } @@ -725,6 +739,33 @@ bool BaseKey::DoUpdateRestore(const UserAuth &auth, const std::string &keyPath) LOGI("finish"); return true; } +bool BaseKey::DoUpdateRestoreVx(const UserAuth &auth, const std::string &keyPath, UpdateVersion update_version) +{ + LOGI("enter"); + LOGI("Restore version %{public}u", update_version); + if (!DoRestoreKeyCeEceSece(auth, keyPath, GetTypeFromDir())) { + LOGE("Restore ce ece sece failed !"); + return false; + } + uint64_t secureUid = { 0 }; + + if (IamClient::GetInstance().HasPinProtect(GetIdFromDir())) { + if (!IamClient::GetInstance().GetSecureUid(GetIdFromDir(), secureUid)) { + LOGE("Get secure uid form iam failed, use default value."); + } + LOGI("PIN protect exist."); + } + if (!StoreKey({ auth.token, auth.secret, secureUid })) { + LOGE("Store old failed !"); + return false; + } + if (!UpdateKey()) { + LOGE("Update old failed !"); + return false; + } + LOGI("finish"); + return true; +} bool BaseKey::DecryptReal(const UserAuth &auth, const uint32_t keyType, KeyContext &keyCtx) { @@ -1164,6 +1205,7 @@ uint32_t BaseKey::GetIdFromDir() bool BaseKey::KeyDescIsEmpty() { + LOGI("The keyBlob is null? %{public}d", keyInfo_.keyDesc.IsEmpty()); return keyInfo_.keyDesc.IsEmpty(); } } // namespace StorageDaemon diff --git a/services/storage_daemon/crypto/src/fscrypt_key_v1_ext.cpp b/services/storage_daemon/crypto/src/fscrypt_key_v1_ext.cpp index f59e2717..97627e80 100644 --- a/services/storage_daemon/crypto/src/fscrypt_key_v1_ext.cpp +++ b/services/storage_daemon/crypto/src/fscrypt_key_v1_ext.cpp @@ -88,9 +88,10 @@ bool FscryptKeyV1Ext::ActiveKeyExt(uint32_t flag, uint8_t *iv, uint32_t size, ui std::error_code errCode; std::string updateVersion; int ret = OHOS::LoadStringFromFile(NEED_RESTORE_PATH, updateVersion); + const int BASE = 2; LOGI("restore version: %{public}s, ret: %{public}d", updateVersion.c_str(), ret); if (type_ == TYPE_EL1 && std::filesystem::exists(NEED_RESTORE_PATH, errCode) && - updateVersion == NEW_DOUBLE_2_SINGLE) { + std::atoi(updateVersion.c_str()) % BASE == 0) { LOGI("restore path exists, deal double DE, errCode = %{public}d", errCode.value()); return ActiveDoubleKeyExt(flag, iv, size, elType); } diff --git a/services/storage_daemon/crypto/src/key_manager.cpp b/services/storage_daemon/crypto/src/key_manager.cpp index de903a5a..3f1be7c9 100644 --- a/services/storage_daemon/crypto/src/key_manager.cpp +++ b/services/storage_daemon/crypto/src/key_manager.cpp @@ -1100,6 +1100,15 @@ int KeyManager::ActiveCeSceSeceUserKey(unsigned int user, if (!KeyCtrlHasFscryptSyspara()) { return 0; } + std::string need_restore_path = GetKeyDirByUserAndType(user, type) = RESTORE_DIR; + std::error_code errCode; + std::string restore_version; + (void)OHOS::LoadStringFromFile(need_restore_path, restore_version); + if (std::filesystem::exists(need_restore_path, errCode) && std::atoi(restore_version.c_str()) == 3) { + LOGI("NEED_RESTORE path exist: %{public}s, errorcode: %{public}d", need_restore_path.c_str(), + errCode.value()); + return type == EL5_KEY ? -ENONET : -EFAULT; + } if (CheckUserPinProtect(user, token, secret) != E_OK) { LOGE("IAM & Storage mismatch, wait user input pin."); return -EFAULT; @@ -1172,9 +1181,15 @@ bool KeyManager::HasElxDesc(std::map> &us KeyType type, unsigned int user) { + LOGI("Enter."); auto it = userElKey_.find(user); if (it != userElKey_.end()) { auto elKey = it->second; + if (elKey == nullptr) { + LOGI("The ElKey is nullptr: %{public}d", elKey == nullptr); + return false; + } + if (it != userElKey_.end() && !elKey->KeyDescIsEmpty()) { LOGI("user el%{public}u key desc has existed", type); return true; diff --git a/services/storage_daemon/include/crypto/base_key.h b/services/storage_daemon/include/crypto/base_key.h index 7e07e33e..8f5f64d2 100644 --- a/services/storage_daemon/include/crypto/base_key.h +++ b/services/storage_daemon/include/crypto/base_key.h @@ -32,6 +32,11 @@ const uint32_t USER_CHANGE_AUTH = 0x1; const std::string SUFFIX_NEED_UPDATE = "/need_update"; const std::string SUFFIX_NEED_RESTORE = "/need_restore"; const std::vector NULL_SECRET = { '!' }; +enum UpdateVersion { + UPDATE_V2 = 2, + UPDATE_V4 = 4 +}; + class BaseKey : public std::enable_shared_from_this { public: BaseKey() = delete; @@ -103,6 +108,7 @@ private: bool DoRestoreKeyDe(const UserAuth &auth, const std::string &path); bool DoRestoreKeyOld(const UserAuth &auth, const std::string &keypath); bool DoUpdateRestore(const UserAuth &auth, const std::string &keyPath); + bool DoUpdateRestoreVx(const UserAuth &auth, const std::string &KeyPath, UpdateVersion update_version); static bool GenerateAndSaveKeyBlob(KeyBlob &blob, const std::string &path, const uint32_t size); static bool GenerateKeyBlob(KeyBlob &blob, const uint32_t size); bool EncryptDe(const UserAuth &auth, const std::string &path); diff --git a/services/storage_daemon/include/ipc/storage_daemon.h b/services/storage_daemon/include/ipc/storage_daemon.h index 61758895..40425ce4 100644 --- a/services/storage_daemon/include/ipc/storage_daemon.h +++ b/services/storage_daemon/include/ipc/storage_daemon.h @@ -113,9 +113,17 @@ private: #ifdef USER_CRYPTO_MIGRATE_KEY std::string GetNeedRestoreFilePath(int32_t userId, const std::string &user_dir); std::string GetNeedRestoreFilePathByType(int32_t userId, KeyType type); + std::string GetNeedRestoreVersion(uint32_t userId, KeyType type); int32_t PrepareUserDirsAndUpdateUserAuth(uint32_t userId, KeyType type, const std::vector &token, const std::vector &secret); + int32_t PrepareUserDirsAndUpdateUserAuthOld(uint32_t userId, KeyType type, + const std::vector &token, + const std::vector &secret); + int32_t PrepareUserDirsAndUpdateUserAuthVx(uint32_t userId, KeyType type, + const std::vector &token, + const std::vector &secret, + const std::string needRestoreVersion); int32_t PrepareUeceDir(uint32_t userId); int32_t RestoreUserKey(int32_t userId, uint32_t flags); bool IsNeedRestorePathExist(uint32_t userId, bool needCheckEl1); diff --git a/services/storage_daemon/ipc/src/storage_daemon.cpp b/services/storage_daemon/ipc/src/storage_daemon.cpp index 2910a49f..4a6fa8bc 100644 --- a/services/storage_daemon/ipc/src/storage_daemon.cpp +++ b/services/storage_daemon/ipc/src/storage_daemon.cpp @@ -73,8 +73,7 @@ const std::string DATA_SERVICE_EL4 = "/data/service/el4/"; const std::string DATA_SERVICE_EL1_PUBLIC_STORAGE_DAEMON_SD = "/data/service/el1/public/storage_daemon/sd"; const std::string DATA_SERVICE_EL0_STORAGE_DAEMON_SD = "/data/service/el0/storage_daemon/sd"; const std::string NEED_RESTORE_SUFFIX = "/latest/need_restore"; -const std::string NEW_DOUBLE_2_SINGELE = "2"; - +const std::string NEW_DOUBLE_2_SINGLE = "2"; typedef int32_t (*CreateShareFileFunc)(const std::vector &, uint32_t, uint32_t, std::vector &); typedef int32_t (*DeleteShareFileFunc)(uint32_t, const std::vector &); @@ -261,7 +260,10 @@ int32_t StorageDaemon::RestoreOneUserKey(int32_t userId, KeyType type) if (!std::filesystem::exists(elNeedRestorePath)) { return E_OK; } - LOGI("start restore User %{public}u el%{public}u", userId, type); + std::string SINGLE_RESTORE_VERSION; + (void) OHOS::LoadStringFromFile(elNeedRestorePath, SINGLE_RESTORE_VERSION); + LOGI("start restore User %{public}u el%{public}u, restore version = %{public}s", userId, type, + SINGLE_RESTORE_VERSION.c_str()); ret = KeyManager::GetInstance()->RestoreUserKey(userId, type); if (ret != E_OK) { if (type != EL1_KEY) { @@ -458,8 +460,13 @@ int32_t StorageDaemon::InitGlobalUserKeys(void) std::string el2NeedRestorePath = GetNeedRestoreFilePath(START_USER_ID, USER_EL2_DIR); if (std::filesystem::exists(el2NeedRestorePath)) { LOGE("USER_EL2_DIR is exist, update NEW_DOUBLE_2_SINGLE"); - std::string EL0_NEED_RESTORE = DATA_SERVICE_EL0_STORAGE_DAEMON_SD + NEED_RESTORE_SUFFIX; - if (!SaveStringToFile(EL0_NEED_RESTORE, NEW_DOUBLE_2_SINGELE)) { + std::string DOUBLE_VERSION; + std::string EL0_NEED_RESTORE_PATH = DATA_SERVICE_EL0_STORAGE_DAEMON_SD + NEED_RESTORE_SUFFIX; + bool isRead = OHOS::LoadStringFromFile(EL0_NEED_RESTORE_PATH, DOUBLE_VERSION); + int NEW_SINGLE_VERSION = std::atoi(DOUBLE_VERSION.c_str()) + 1; + LOGI("Process NEW_DOUBLE(version:%{public}s}) ——> SINGLE Frame(version:%{public}d), ret: %{public}d", + DOUBLE_VERSION.c_str(), NEW_SINGLE_VERSION, isRead); + if (!SaveStringToFile(EL0_NEED_RESTORE_PATH, std::to_string(NEW_SINGLE_VERSION))) { LOGE("Save NEW_DOUBLE_2_SINGELE file failed"); return false; } @@ -591,8 +598,32 @@ int32_t StorageDaemon::UpdateUseAuthWithRecoveryKey(const std::vector & } #ifdef USER_CRYPTO_MIGRATE_KEY +std::string StorageDaemon::GetNeedRestoreVersion(uint32_t userId, KeyType type) +{ + std::string need_restore_path = KeyManager::GetInstance()->GetKeyDirByUserAndType(userId, type) + RESTORE_DIR; + std::string need_restore_version; + OHOS::LoadStringFromFile(need_restore_path, need_restore_version); + return need_restore_version; +} + int32_t StorageDaemon::PrepareUserDirsAndUpdateUserAuth(uint32_t userId, KeyType type, const std::vector &token, const std::vector &secret) +{ + int32_t ret = E_OK; + std::string need_restore_version = GetNeedRestoreVersion(userId, type); + int32_t OLD_UPDATE_VERSION_MAXLIMIT = std::atoi(NEW_DOUBLE_2_SINGLE.c_str()); + if (std::atoi(need_restore_version.c_str()) <= OLD_UPDATE_VERSION_MAXLIMIT) { + LOGI("Old DOUBLE_2_SINGLE::PrepareUserDirsAndUpdateUserAuth."); + ret = PrepareUserDirsAndUpdateUserAuthOld(userId, type, token, secret); + } else { + LOGI("New DOUBLE_2_SINGLE::PrepareUserDirsAndUpdateUserAuth."); + ret = PrepareUserDirsAndUpdateUserAuthVx(userId, type, token, secret, need_restore_version); + } + return ret; +} + +int32_t StorageDaemon::PrepareUserDirsAndUpdateUserAuthOld(uint32_t userId, KeyType type, + const std::vector &token, const std::vector &secret) { LOGI("start userId %{public}u KeyType %{public}u", userId, type); int32_t ret = E_OK; @@ -638,6 +669,42 @@ int32_t StorageDaemon::PrepareUserDirsAndUpdateUserAuth(uint32_t userId, KeyType return E_OK; } +int32_t StorageDaemon::PrepareUserDirsAndUpdateUserAuthVx(uint32_t userId, KeyType type, + const std::vector &token, const std::vector &secret, + const std::string needRestoreVersion) +{ + LOGI("start userId %{public}u KeyType %{public}u", userId, type); + int32_t ret = E_OK; + uint32_t flags = 0; + + ret = GetCryptoFlag(type, flags); + if (ret != E_OK) { + return ret; + } + std::string need_restore_path = KeyManager::GetInstance()->GetKeyDirByUserAndType(userId, type) + RESTORE_DIR; + uint32_t new_need_restore = std::atoi(needRestoreVersion.c_str()) + 1; + if (!SaveStringToFileSync(need_restore_path, std::to_string(new_need_restore))) { + LOGE("Write userId: %{public}d, El%{public}d need_restore failed.", userId, type); + } + LOGI("New DOUBLE_2_SINGLE::ActiveCeSceSeceUserKey."); + ret = KeyManager::GetInstance()->ActiveCeSceSeceUserKey(userId, type, token, {'!'}); + if (ret != E_OK) { + LOGE("Active user %{public}u key fail, type %{public}u, flags %{public}u", userId, type, flags); + return ret; + } + LOGI("try to destory dir first, user %{public}u, flags %{public}u", userId, flags); + (void)UserManager::GetInstance()->DestroyUserDirs(userId, flags); + ret = UserManager::GetInstance()->PrepareUserDirs(userId, flags); + if (ret != E_OK) { + return ret; + } + if (flags == IStorageDaemon::CRYPTO_FLAG_EL2) { + PrepareUeceDir(userId); + } + LOGI("userId %{public}u type %{public}u sucess", userId, type); + return E_OK; +} + bool StorageDaemon::IsNeedRestorePathExist(uint32_t userId, bool needCheckEl1) { std::string el2NeedRestorePath = GetNeedRestoreFilePath(userId, USER_EL2_DIR); @@ -790,7 +857,7 @@ int32_t StorageDaemon::ActiveUserKey(uint32_t userId, updateFlag = true; ret = PrepareUserDirsAndUpdateUserAuth(userId, EL2_KEY, token, secret); std::string EL0_NEED_RESTORE = DATA_SERVICE_EL0_STORAGE_DAEMON_SD + NEED_RESTORE_SUFFIX; - if (!SaveStringToFile(EL0_NEED_RESTORE, NEW_DOUBLE_2_SINGELE)) { + if (!SaveStringToFile(EL0_NEED_RESTORE, NEW_DOUBLE_2_SINGLE)) { LOGE("Save key type file failed"); return false; } -- Gitee