!610 storage_daemon restore and update user CE and DE

Merge pull request !610 from 廖永煌/master
This commit is contained in:
openharmony_ci 2023-08-30 06:41:43 +00:00 committed by Gitee
commit 9b26eb880d
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
9 changed files with 199 additions and 8 deletions

View File

@ -111,7 +111,10 @@ ohos_executable("storage_daemon") {
] ]
if (storage_service_user_crypto_manager) { if (storage_service_user_crypto_manager) {
defines += [ "USER_CRYPTO_MANAGER" ] defines += [
"USER_CRYPTO_MANAGER",
"USER_CRYPTO_MIGRATE_KEY",
]
deps += [ deps += [
"crypto:libsdcrypto", "crypto:libsdcrypto",
"libfscrypt:libfscryptutils", "libfscrypt:libfscryptutils",

View File

@ -45,6 +45,7 @@ ohos_static_library("libsdcrypto") {
"STORAGE_LOG_TAG = \"StorageDaemon\"", "STORAGE_LOG_TAG = \"StorageDaemon\"",
"LOG_DOMAIN = 0xD004301", "LOG_DOMAIN = 0xD004301",
"OPENSSL_SUPPRESS_DEPRECATED", "OPENSSL_SUPPRESS_DEPRECATED",
"USER_CRYPTO_MIGRATE_KEY",
] ]
configs = [ ":storage_daemon_crypto_config" ] configs = [ ":storage_daemon_crypto_config" ]

View File

@ -148,11 +148,19 @@ std::string BaseKey::GetNextCandidateDir() const
return dir_ + PATH_KEY_VERSION + std::to_string(candidate + 1); return dir_ + PATH_KEY_VERSION + std::to_string(candidate + 1);
} }
#ifdef USER_CRYPTO_MIGRATE_KEY
bool BaseKey::StoreKey(const UserAuth &auth, bool needGenerateShield)
#else
bool BaseKey::StoreKey(const UserAuth &auth) bool BaseKey::StoreKey(const UserAuth &auth)
#endif
{ {
LOGD("enter"); LOGD("enter");
auto pathTemp = dir_ + PATH_KEY_TEMP; auto pathTemp = dir_ + PATH_KEY_TEMP;
#ifdef USER_CRYPTO_MIGRATE_KEY
if (DoStoreKey(auth, needGenerateShield)) {
#else
if (DoStoreKey(auth)) { if (DoStoreKey(auth)) {
#endif
// rename keypath/temp/ to keypath/version_xx/ // rename keypath/temp/ to keypath/version_xx/
auto candidate = GetNextCandidateDir(); auto candidate = GetNextCandidateDir();
LOGD("rename %{public}s to %{public}s", pathTemp.c_str(), candidate.c_str()); LOGD("rename %{public}s to %{public}s", pathTemp.c_str(), candidate.c_str());
@ -170,7 +178,11 @@ bool BaseKey::StoreKey(const UserAuth &auth)
} }
// All key files are saved under keypath/temp/ in this function. // All key files are saved under keypath/temp/ in this function.
#ifdef USER_CRYPTO_MIGRATE_KEY
bool BaseKey::DoStoreKey(const UserAuth &auth, bool needGenerateShield)
#else
bool BaseKey::DoStoreKey(const UserAuth &auth) bool BaseKey::DoStoreKey(const UserAuth &auth)
#endif
{ {
auto pathTemp = dir_ + PATH_KEY_TEMP; auto pathTemp = dir_ + PATH_KEY_TEMP;
MkDirRecurse(pathTemp, S_IRWXU); MkDirRecurse(pathTemp, S_IRWXU);
@ -188,10 +200,24 @@ bool BaseKey::DoStoreKey(const UserAuth &auth)
} }
ChMod(pathVersion, S_IREAD | S_IWRITE); ChMod(pathVersion, S_IREAD | S_IWRITE);
#ifdef USER_CRYPTO_MIGRATE_KEY
if (needGenerateShield) {
if (!HuksMaster::GetInstance().GenerateKey(auth, keyContext_.shield)) {
LOGE("GenerateKey of shield failed");
return false;
}
} else {
if (!LoadKeyBlob(keyContext_.shield, dir_ + PATH_LATEST + PATH_SHIELD)) {
keyContext_.encrypted.Clear();
return false;
}
}
#else
if (!HuksMaster::GetInstance().GenerateKey(auth, keyContext_.shield)) { if (!HuksMaster::GetInstance().GenerateKey(auth, keyContext_.shield)) {
LOGE("GenerateKey of shield failed"); LOGE("GenerateKey of shield failed");
return false; return false;
} }
#endif
if (!SaveKeyBlob(keyContext_.shield, pathTemp + PATH_SHIELD)) { if (!SaveKeyBlob(keyContext_.shield, pathTemp + PATH_SHIELD)) {
return false; return false;
} }

View File

@ -31,11 +31,6 @@
namespace OHOS { namespace OHOS {
namespace StorageDaemon { namespace StorageDaemon {
const UserAuth NULL_KEY_AUTH = {}; const UserAuth NULL_KEY_AUTH = {};
const std::string FSCRYPT_USER_EL1_PUBLIC = std::string() + "/data/service/el1/public";
const std::string SERVICE_STORAGE_DAEMON_DIR = FSCRYPT_USER_EL1_PUBLIC + "/storage_daemon";
const std::string FSCRYPT_EL_DIR = SERVICE_STORAGE_DAEMON_DIR + "/sd";
const std::string USER_EL1_DIR = FSCRYPT_EL_DIR + "/el1";
const std::string USER_EL2_DIR = FSCRYPT_EL_DIR + "/el2";
std::shared_ptr<BaseKey> KeyManager::GetBaseKey(const std::string& dir) std::shared_ptr<BaseKey> KeyManager::GetBaseKey(const std::string& dir)
{ {
@ -434,10 +429,18 @@ int KeyManager::DeleteUserKeys(unsigned int user)
return ret; return ret;
} }
#ifdef USER_CRYPTO_MIGRATE_KEY
int KeyManager::UpdateUserAuth(unsigned int user, uint64_t secureUid,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &oldSecret,
const std::vector<uint8_t> &newSecret,
bool needGenerateShield)
#else
int KeyManager::UpdateUserAuth(unsigned int user, uint64_t secureUid, int KeyManager::UpdateUserAuth(unsigned int user, uint64_t secureUid,
const std::vector<uint8_t> &token, const std::vector<uint8_t> &token,
const std::vector<uint8_t> &oldSecret, const std::vector<uint8_t> &oldSecret,
const std::vector<uint8_t> &newSecret) const std::vector<uint8_t> &newSecret)
#endif
{ {
LOGI("start, user:%{public}d", user); LOGI("start, user:%{public}d", user);
if (!KeyCtrlHasFscryptSyspara()) { if (!KeyCtrlHasFscryptSyspara()) {
@ -458,7 +461,11 @@ int KeyManager::UpdateUserAuth(unsigned int user, uint64_t secureUid,
} }
auth.secret = newSecret; auth.secret = newSecret;
#ifdef USER_CRYPTO_MIGRATE_KEY
if (item->StoreKey(auth, needGenerateShield) == false) {
#else
if (item->StoreKey(auth) == false) { if (item->StoreKey(auth) == false) {
#endif
LOGE("Store key error"); LOGE("Store key error");
return -EFAULT; return -EFAULT;
} }
@ -599,5 +606,26 @@ int KeyManager::UpgradeKeys(const std::vector<FileList> &dirInfo)
} }
return 0; return 0;
} }
#ifdef USER_CRYPTO_MIGRATE_KEY
int KeyManager::RestoreUserKey(uint32_t userId, KeyType type)
{
LOGI("start, user is %{public}u , type is %{public}d", userId, type);
std::string dir;
if (type == EL1_KEY) {
dir = USER_EL1_DIR + "/" + std::to_string(userId);
} else if (type == EL2_KEY) {
dir = USER_EL2_DIR + "/" + std::to_string(userId);
} else {
LOGE("type is invaild");
return -EFAULT;
}
if (!IsDir(dir)) {
LOGE("dir not exist");
return -ENOENT;
}
return RestoreUserKey(userId, dir, NULL_KEY_AUTH, type);
}
#endif
} // namespace StorageDaemon } // namespace StorageDaemon
} // namespace OHOS } // namespace OHOS

View File

@ -25,6 +25,7 @@ ohos_moduletest("CryptoSubTest") {
defines = [ defines = [
"STORAGE_LOG_TAG = \"StorageDaemon\"", "STORAGE_LOG_TAG = \"StorageDaemon\"",
"LOG_DOMAIN = 0xD004301", "LOG_DOMAIN = 0xD004301",
"USER_CRYPTO_MIGRATE_KEY",
] ]
include_dirs = [ include_dirs = [

View File

@ -34,7 +34,11 @@ public:
/* key operations */ /* key operations */
bool InitKey(); bool InitKey();
#ifdef USER_CRYPTO_MIGRATE_KEY
bool StoreKey(const UserAuth &auth, bool needGenerateShield = true);
#else
bool StoreKey(const UserAuth &auth); bool StoreKey(const UserAuth &auth);
#endif
bool UpdateKey(const std::string &keypath = ""); bool UpdateKey(const std::string &keypath = "");
bool RestoreKey(const UserAuth &auth); bool RestoreKey(const UserAuth &auth);
virtual bool ActiveKey(uint32_t flag, const std::string &mnt = MNT_DATA) = 0; virtual bool ActiveKey(uint32_t flag, const std::string &mnt = MNT_DATA) = 0;
@ -53,7 +57,11 @@ protected:
std::string dir_ {}; std::string dir_ {};
private: private:
#ifdef USER_CRYPTO_MIGRATE_KEY
bool DoStoreKey(const UserAuth &auth, bool needGenerateShield = true);
#else
bool DoStoreKey(const UserAuth &auth); bool DoStoreKey(const UserAuth &auth);
#endif
bool DoRestoreKey(const UserAuth &auth, const std::string &keypath); bool DoRestoreKey(const UserAuth &auth, const std::string &keypath);
static bool GenerateAndSaveKeyBlob(KeyBlob &blob, const std::string &path, const uint32_t size); static bool GenerateAndSaveKeyBlob(KeyBlob &blob, const std::string &path, const uint32_t size);
static bool GenerateKeyBlob(KeyBlob &blob, const uint32_t size); static bool GenerateKeyBlob(KeyBlob &blob, const uint32_t size);

View File

@ -28,6 +28,11 @@
namespace OHOS { namespace OHOS {
namespace StorageDaemon { namespace StorageDaemon {
const std::string FSCRYPT_USER_EL1_PUBLIC = std::string() + "/data/service/el1/public";
const std::string SERVICE_STORAGE_DAEMON_DIR = FSCRYPT_USER_EL1_PUBLIC + "/storage_daemon";
const std::string FSCRYPT_EL_DIR = SERVICE_STORAGE_DAEMON_DIR + "/sd";
const std::string USER_EL1_DIR = FSCRYPT_EL_DIR + "/el1";
const std::string USER_EL2_DIR = FSCRYPT_EL_DIR + "/el2";
class KeyManager { class KeyManager {
public: public:
static KeyManager *GetInstance(void) static KeyManager *GetInstance(void)
@ -39,17 +44,27 @@ public:
int InitGlobalUserKeys(void); int InitGlobalUserKeys(void);
int GenerateUserKeys(unsigned int user, uint32_t flags); int GenerateUserKeys(unsigned int user, uint32_t flags);
int DeleteUserKeys(unsigned int user); int DeleteUserKeys(unsigned int user);
#ifdef USER_CRYPTO_MIGRATE_KEY
int UpdateUserAuth(unsigned int user, uint64_t secureUid,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &oldSecret,
const std::vector<uint8_t> &newSecret,
bool needGenerateShield = true);
#else
int UpdateUserAuth(unsigned int user, uint64_t secureUid, int UpdateUserAuth(unsigned int user, uint64_t secureUid,
const std::vector<uint8_t> &token, const std::vector<uint8_t> &token,
const std::vector<uint8_t> &oldSecret, const std::vector<uint8_t> &oldSecret,
const std::vector<uint8_t> &newSecret); const std::vector<uint8_t> &newSecret);
#endif
int ActiveUserKey(unsigned int user, const std::vector<uint8_t> &token, int ActiveUserKey(unsigned int user, const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret); const std::vector<uint8_t> &secret);
int InActiveUserKey(unsigned int user); int InActiveUserKey(unsigned int user);
int SetDirectoryElPolicy(unsigned int user, KeyType type, int SetDirectoryElPolicy(unsigned int user, KeyType type,
const std::vector<FileList> &vec); const std::vector<FileList> &vec);
int UpdateKeyContext(uint32_t userId); int UpdateKeyContext(uint32_t userId);
#ifdef USER_CRYPTO_MIGRATE_KEY
int RestoreUserKey(uint32_t userId, KeyType type);
#endif
private: private:
KeyManager() KeyManager()
{ {

View File

@ -69,6 +69,14 @@ public:
void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override;
void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override;
}; };
#ifdef USER_CRYPTO_MIGRATE_KEY
private:
std::string GetNeedRestoreFilePath(int32_t userId, const std::string &user_dir);
int32_t RestoreUserKey(int32_t userId, uint32_t flags);
int32_t PrepareUserDirsAndUpdateUserAuth(uint32_t userId,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret);
#endif
}; };
} // StorageDaemon } // StorageDaemon
} // OHOS } // OHOS

View File

@ -35,6 +35,11 @@
#ifdef DFS_SERVICE #ifdef DFS_SERVICE
#include "cloud_daemon_manager.h" #include "cloud_daemon_manager.h"
#endif #endif
#ifdef USER_CRYPTO_MIGRATE_KEY
#include "string_ex.h"
#include "utils/file_utils.h"
#include <filesystem>
#endif
namespace OHOS { namespace OHOS {
namespace StorageDaemon { namespace StorageDaemon {
@ -109,10 +114,68 @@ int32_t StorageDaemon::SetVolumeDescription(std::string volId, std::string descr
#endif #endif
} }
#ifdef USER_CRYPTO_MIGRATE_KEY
std::string StorageDaemon::GetNeedRestoreFilePath(int32_t userId, const std::string &user_dir)
{
std::string path = user_dir + "/" + std::to_string(userId) + "/latest/need_restore";
return path;
}
int32_t StorageDaemon::RestoreUserKey(int32_t userId, uint32_t flags)
{
LOGI("prepare restore user dirs for %{public}d, flags %{public}u", userId, flags);
int32_t ret = E_OK;
std::string el1NeedRestorePath = GetNeedRestoreFilePath(userId, USER_EL1_DIR);
std::string el2NeedRestorePath = GetNeedRestoreFilePath(userId, USER_EL2_DIR);
if (!std::filesystem::exists(el1NeedRestorePath) && !std::filesystem::exists(el2NeedRestorePath)) {
LOGE("need_restore file is not existed");
return -EEXIST;
}
if (std::filesystem::exists(el1NeedRestorePath)) {
LOGI("start restore User DE");
ret = KeyManager::GetInstance()->RestoreUserKey(userId, EL1_KEY);
if (ret != E_OK) {
LOGE("RestoreUserKey EL1_KEY failed, error = %{public}d", ret);
return ret;
}
ret = UserManager::GetInstance()->PrepareUserDirs(userId, IStorageDaemon::CRYPTO_FLAG_EL1);
if (ret != E_OK) {
LOGE("PrepareUserDirs CRYPTO_FLAG_EL1 failed, error = %{public}d", ret);
return ret;
}
(void)remove(el1NeedRestorePath.c_str());
LOGI("restore User DE success");
}
if (std::filesystem::exists(el2NeedRestorePath)) {
LOGI("start restore User CE");
ret = KeyManager::GetInstance()->RestoreUserKey(userId, EL2_KEY);
if (ret != E_OK) {
LOGE("RestoreUserKey EL2_KEY failed, but return success, error = %{public}d", ret);
return E_OK; // mybe need user key, so return E_OK to continue
}
ret = UserManager::GetInstance()->PrepareUserDirs(userId, IStorageDaemon::CRYPTO_FLAG_EL2);
if (ret != E_OK) {
LOGE("PrepareUserDirs CRYPTO_FLAG_EL2 failed, error = %{public}d", ret);
return ret;
}
(void)remove(el2NeedRestorePath.c_str());
LOGI("restore User CE success");
}
return E_OK;
}
#endif
int32_t StorageDaemon::PrepareUserDirs(int32_t userId, uint32_t flags) int32_t StorageDaemon::PrepareUserDirs(int32_t userId, uint32_t flags)
{ {
#ifdef USER_CRYPTO_MANAGER #ifdef USER_CRYPTO_MANAGER
int32_t ret = KeyManager::GetInstance()->GenerateUserKeys(userId, flags); int32_t ret = KeyManager::GetInstance()->GenerateUserKeys(userId, flags);
#ifdef USER_CRYPTO_MIGRATE_KEY
if (ret == -EEXIST) {
return RestoreUserKey(userId, flags);
}
#endif
if (ret != E_OK) { if (ret != E_OK) {
LOGE("Generate user %{public}d key error", userId); LOGE("Generate user %{public}d key error", userId);
return ret; return ret;
@ -206,12 +269,50 @@ int32_t StorageDaemon::UpdateUserAuth(uint32_t userId, uint64_t secureUid,
#endif #endif
} }
#ifdef USER_CRYPTO_MIGRATE_KEY
int32_t StorageDaemon::PrepareUserDirsAndUpdateUserAuth(uint32_t userId, const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret)
{
LOGI("start userId %{public}u", userId);
int32_t ret = E_OK;
ret = KeyManager::GetInstance()->ActiveUserKey(userId, token, {'!'});
if (ret != E_OK) {
return ret;
}
ret = KeyManager::GetInstance()->UpdateUserAuth(userId, 0, token, {'!'}, secret, false);
if (ret != E_OK) {
return ret;
}
ret = KeyManager::GetInstance()->UpdateKeyContext(userId);
if (ret != E_OK) {
return ret;
}
LOGI("try to destory ce dir first");
(void)UserManager::GetInstance()->DestroyUserDirs(userId, IStorageDaemon::CRYPTO_FLAG_EL2);
ret = UserManager::GetInstance()->PrepareUserDirs(userId, IStorageDaemon::CRYPTO_FLAG_EL2);
if (ret != E_OK) {
return ret;
}
LOGI("userId %{public}u sucess", userId);
return E_OK;
}
#endif
int32_t StorageDaemon::ActiveUserKey(uint32_t userId, int32_t StorageDaemon::ActiveUserKey(uint32_t userId,
const std::vector<uint8_t> &token, const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret) const std::vector<uint8_t> &secret)
{ {
#ifdef USER_CRYPTO_MANAGER #ifdef USER_CRYPTO_MANAGER
return KeyManager::GetInstance()->ActiveUserKey(userId, token, secret); auto ret = KeyManager::GetInstance()->ActiveUserKey(userId, token, secret);
if (ret == E_OK) {
return E_OK;
}
#ifdef USER_CRYPTO_MIGRATE_KEY
std::string el2NeedRestorePath = GetNeedRestoreFilePath(userId, USER_EL2_DIR);
if (std::filesystem::exists(el2NeedRestorePath) && (!token.empty() || !secret.empty())) {
return PrepareUserDirsAndUpdateUserAuth(userId, token, secret);
}
#endif
return ret;
#else #else
return E_OK; return E_OK;
#endif #endif