optimization for el3/el4 upgrade scene

Signed-off-by: gsl_1234 <gaoshunli@huawei.com>
This commit is contained in:
gsl_1234 2023-12-15 15:40:03 +00:00
parent 756d7032a9
commit 98da0186ac
5 changed files with 244 additions and 64 deletions

View File

@ -15,6 +15,7 @@
#include "key_manager.h"
#include <filesystem>
#include <string>
#include "base_key.h"
@ -32,6 +33,7 @@
namespace OHOS {
namespace StorageDaemon {
const UserAuth NULL_KEY_AUTH = {};
const std::string DEFAULT_NEED_RESTORE_VERSION = "1";
std::shared_ptr<BaseKey> KeyManager::GetBaseKey(const std::string& dir)
{
@ -271,6 +273,42 @@ bool KeyManager::HasElkey(uint32_t userId, KeyType type)
return false;
}
bool KeyManager::IsNeedClearKeyFile(std::string file)
{
LOGI("enter:");
if (!std::filesystem::exists(file)) {
LOGE("file not exist, file is %{private}s", file.c_str());
return false;
}
std::string version;
if (!OHOS::LoadStringFromFile(file, version)) {
LOGE("LoadStringFromFile return fail, file is %{private}s", file.c_str());
return false;
}
if (version != DEFAULT_NEED_RESTORE_VERSION) {
LOGE("need to clear, file is %{private}s, version is %{public}s.", file.c_str(), version.c_str());
return true;
}
LOGE("no need to clear, file is %{private}s, version is %{public}s", file.c_str(), version.c_str());
return false;
}
void KeyManager::ProcUpgradeKey(const std::vector<FileList> &dirInfo)
{
LOGI("enter:");
for (const auto &it : dirInfo) {
std::string needRestorePath = it.path + "/latest/need_restore";
if (IsNeedClearKeyFile(needRestorePath)) {
bool ret = RmDirRecurse(it.path);
if (!ret) {
LOGE("remove key dir fail, result is %{public}d, dir %{private}s", ret, it.path.c_str());
}
}
}
}
int KeyManager::LoadAllUsersEl1Key(void)
{
LOGI("enter");
@ -286,6 +324,13 @@ int KeyManager::LoadAllUsersEl1Key(void)
}
}
/* only for el3/el4 upgrade scene */
dirInfo.clear();
ReadDigitDir(USER_EL3_DIR, dirInfo);
ProcUpgradeKey(dirInfo);
dirInfo.clear();
ReadDigitDir(USER_EL4_DIR, dirInfo);
ProcUpgradeKey(dirInfo);
return 0;
}
@ -417,6 +462,38 @@ int KeyManager::GenerateUserKeys(unsigned int user, uint32_t flags)
return 0;
}
int KeyManager::GenerateUserKeyByType(unsigned int user, KeyType type,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret)
{
LOGI("start, user:%{public}u, type %{public}u", user, type);
if (!KeyCtrlHasFscryptSyspara()) {
return 0;
}
std::lock_guard<std::mutex> lock(keyMutex_);
std::string elPath = GetKeyDirByType(type);
if (!IsDir(elPath)) {
LOGI("El storage dir is not existed");
return -ENOENT;
}
std::string elUserKeyPath = elPath + + "/" + std::to_string(user);
if (IsDir(elUserKeyPath)) {
LOGE("user %{public}d el key have existed, create error", user);
return -EEXIST;
}
UserAuth auth = {.token = token, .secret = secret, .secureUid = 0};
int ret = GenerateAndInstallUserKey(user, elUserKeyPath, auth, type);
if (ret) {
LOGE("user el create error, user %{public}u, type %{public}u", user, type);
return ret;
}
LOGI("Create user el success, user %{public}u, type %{public}u", user, type);
return 0;
}
int KeyManager::DoDeleteUserCeEceSeceKeys(unsigned int user,
const std::string USER_DIR,
std::map<unsigned int, std::shared_ptr<BaseKey>> &userElKey_)
@ -615,6 +692,29 @@ std::string KeyManager::GetKeyDirByUserAndType(unsigned int user, KeyType type)
return keyDir;
}
std::string KeyManager::GetKeyDirByType(KeyType type)
{
std::string keyDir = "";
switch (type) {
case EL1_KEY:
keyDir = USER_EL1_DIR;
break;
case EL2_KEY:
keyDir = USER_EL2_DIR;
break;
case EL3_KEY:
keyDir = USER_EL3_DIR;
break;
case EL4_KEY:
keyDir = USER_EL4_DIR;
break;
default:
LOGE("GetKeyDirByType type %{public}u is invalid", type);
break;
}
return keyDir;
}
void KeyManager::SaveUserElKey(unsigned int user, KeyType type, std::shared_ptr<BaseKey> elKey)
{
switch (type) {
@ -804,6 +904,7 @@ int KeyManager::LockUserScreen(uint32_t user)
LOGI("LockUserScreen user %{public}u el3 and el4 success", user);
return 0;
}
int KeyManager::SetDirectoryElPolicy(unsigned int user, KeyType type, const std::vector<FileList> &vec)
{
LOGI("start");
@ -815,22 +916,22 @@ int KeyManager::SetDirectoryElPolicy(unsigned int user, KeyType type, const std:
std::lock_guard<std::mutex> lock(keyMutex_);
if (type == EL1_KEY) {
if (userEl1Key_.find(user) == userEl1Key_.end()) {
LOGD("Have not found user %{public}u el1 key, not enable el1", user);
LOGE("Have not found user %{public}u el1 key, not enable el1", user);
return -ENOENT;
}
keyPath = userEl1Key_[user]->GetDir();
} else if (type == EL2_KEY || type == EL3_KEY || type == EL4_KEY) {
if (userEl2Key_.find(user) == userEl2Key_.end()) {
LOGD("Have not found user %{public}u el2 key, not enable el2", user);
LOGE("Have not found user %{public}u el2 key, not enable el2", user);
return -ENOENT;
}
keyPath = userEl2Key_[user]->GetDir();
} else {
LOGD("Not specify el flags, no need to crypt");
LOGE("Not specify el flags, no need to crypt");
return 0;
}
if (getEceSeceKeyPath(user, type, eceSeceKeyPath) != 0) {
LOGD("method getEceSeceKeyPath fail");
LOGE("method getEceSeceKeyPath fail");
return -ENOENT;
}
for (auto item : vec) {

View File

@ -74,5 +74,19 @@ int32_t KeyManager::UpdateKeyContext(uint32_t userId)
{
return E_OK;
}
int KeyManager::GenerateUserKeyByType(unsigned int user, KeyType type,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret)
{
return E_OK;
}
int KeyManager::ActiveCeSceSeceUserKey(unsigned int user, KeyType type,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret)
{
return E_OK;
}
} // namespace StorageDaemon
} // namespace OHOS

View File

@ -74,6 +74,11 @@ public:
#ifdef USER_CRYPTO_MIGRATE_KEY
int RestoreUserKey(uint32_t userId, KeyType type);
#endif
std::string GetKeyDirByUserAndType(unsigned int user, KeyType type);
std::string GetKeyDirByType(KeyType type);
int GenerateUserKeyByType(unsigned int user, KeyType type,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret);
private:
KeyManager()
{
@ -94,7 +99,8 @@ private:
std::shared_ptr<BaseKey> GetBaseKey(const std::string& dir);
std::shared_ptr<BaseKey> GetUserElKey(unsigned int user, KeyType type);
void SaveUserElKey(unsigned int user, KeyType type, std::shared_ptr<BaseKey> elKey);
std::string GetKeyDirByUserAndType(unsigned int user, KeyType type);
bool IsNeedClearKeyFile(std::string file);
void ProcUpgradeKey(const std::vector<FileList> &dirInfo);
std::map<unsigned int, std::shared_ptr<BaseKey>> userEl1Key_;
std::map<unsigned int, std::shared_ptr<BaseKey>> userEl2Key_;

View File

@ -82,21 +82,25 @@ public:
void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override;
void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override;
};
#ifdef USER_CRYPTO_MIGRATE_KEY
private:
#ifdef USER_CRYPTO_MIGRATE_KEY
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);
std::string GetNeedRestoreFilePathByType(int32_t userId, KeyType type);
int32_t PrepareUserDirsAndUpdateUserAuth(uint32_t userId, KeyType type,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret);
int32_t GetCryptoFlag(KeyType type, uint32_t &flags);
std::string GetNeedRestoreFilePathByType(int32_t userId, KeyType type);
int32_t RestoreUserKey(int32_t userId, uint32_t flags);
bool IsNeedRestorePathExist(uint32_t userId, bool needCheckEl1);
int32_t RestoreUserOneKey(int32_t userId, KeyType type);
#endif
int32_t GetCryptoFlag(KeyType type, uint32_t &flags);
int32_t GenerateKeyAndPrepareUserDirs(uint32_t userId, KeyType type,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret);
int32_t ActiveUserKeyAndPrepare(uint32_t userId, KeyType type,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret);
};
} // StorageDaemon
} // OHOS

View File

@ -115,13 +115,6 @@ int32_t StorageDaemon::SetVolumeDescription(std::string volId, std::string descr
#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::GetCryptoFlag(KeyType type, uint32_t &flags)
{
switch (type) {
@ -143,6 +136,13 @@ int32_t StorageDaemon::GetCryptoFlag(KeyType type, uint32_t &flags)
}
}
#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;
}
std::string StorageDaemon::GetNeedRestoreFilePathByType(int32_t userId, KeyType type)
{
switch (type) {
@ -210,7 +210,7 @@ int32_t StorageDaemon::RestoreUserKey(int32_t userId, uint32_t flags)
}
std::vector<KeyType> type = {EL1_KEY, EL2_KEY, EL3_KEY, EL4_KEY};
for (int i = 0; i < type.size(); i++) {
for (unsigned long i = 0; i < type.size(); i++) {
ret = RestoreUserOneKey(userId, type[i]);
if (ret != E_OK) {
return ret;
@ -333,7 +333,7 @@ int32_t StorageDaemon::UpdateUserAuth(uint32_t userId, uint64_t secureUid,
int32_t StorageDaemon::PrepareUserDirsAndUpdateUserAuth(uint32_t userId, KeyType type,
const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
{
LOGI("start userId %{public}u", userId);
LOGI("start userId %{public}u KeyType %{public}u", userId, type);
int32_t ret = E_OK;
uint32_t flags = 0;
@ -369,39 +369,6 @@ int32_t StorageDaemon::PrepareUserDirsAndUpdateUserAuth(uint32_t userId, KeyType
return E_OK;
}
int32_t StorageDaemon::PrepareUserDirsAndUpdateUserAuth(uint32_t userId,
const std::vector<uint8_t> &token, const std::vector<uint8_t> &secret)
{
int32_t ret;
LOGI("start userId %{public}u", userId);
std::string el2NeedRestorePath = GetNeedRestoreFilePath(userId, USER_EL2_DIR);
if (std::filesystem::exists(el2NeedRestorePath)) {
ret = PrepareUserDirsAndUpdateUserAuth(userId, EL2_KEY, token, secret);
if (ret != E_OK) {
return ret;
}
}
std::string el3NeedRestorePath = GetNeedRestoreFilePath(userId, USER_EL3_DIR);
if (std::filesystem::exists(el3NeedRestorePath)) {
ret = PrepareUserDirsAndUpdateUserAuth(userId, EL3_KEY, token, secret);
if (ret != E_OK) {
return ret;
}
}
std::string el4NeedRestorePath = GetNeedRestoreFilePath(userId, USER_EL4_DIR);
if (std::filesystem::exists(el4NeedRestorePath)) {
ret = PrepareUserDirsAndUpdateUserAuth(userId, EL4_KEY, token, secret);
if (ret != E_OK) {
return ret;
}
}
LOGI("userId %{public}u sucess", userId);
return E_OK;
}
bool StorageDaemon::IsNeedRestorePathExist(uint32_t userId, bool needCheckEl1)
{
std::string el2NeedRestorePath = GetNeedRestoreFilePath(userId, USER_EL2_DIR);
@ -417,23 +384,111 @@ bool StorageDaemon::IsNeedRestorePathExist(uint32_t userId, bool needCheckEl1)
return isExist;
}
#endif
int32_t StorageDaemon::GenerateKeyAndPrepareUserDirs(uint32_t userId, KeyType type,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret)
{
#ifdef USER_CRYPTO_MANAGER
int ret;
uint32_t flags = 0;
LOGI("enter:");
ret = KeyManager::GetInstance()->GenerateUserKeyByType(userId, type, token, secret);
if (ret != E_OK) {
LOGE("upgrade scene:generate user key fail, userId %{public}u, KeyType %{public}u, sec empty %{public}d",
userId, type, secret.empty());
return ret;
}
ret = GetCryptoFlag(type, flags);
if (ret != E_OK) {
return ret;
}
(void)UserManager::GetInstance()->DestroyUserDirs(userId, flags);
ret = UserManager::GetInstance()->PrepareUserDirs(userId, flags);
if (ret != E_OK) {
LOGE("upgrade scene:prepare user dirs fail, userId %{public}u, flags %{public}u, sec empty %{public}d",
userId, flags, secret.empty());
}
return ret;
#else
return E_OK;
#endif
}
int32_t StorageDaemon::ActiveUserKeyAndPrepare(uint32_t userId, KeyType type,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret)
{
#ifdef USER_CRYPTO_MANAGER
LOGI("ActiveUserKey with type %{public}u enter", type);
int ret = KeyManager::GetInstance()->ActiveCeSceSeceUserKey(userId, type, token, secret);
if (ret != E_OK && ret != -ENOENT) {
#ifdef USER_CRYPTO_MIGRATE_KEY
std::string elNeedRestorePath = GetNeedRestoreFilePathByType(userId, type);
if (std::filesystem::exists(elNeedRestorePath) && (!token.empty() || !secret.empty())) {
LOGI("start PrepareUserDirsAndUpdateUserAuth userId %{public}u, type %{public}u", userId, type);
ret = PrepareUserDirsAndUpdateUserAuth(userId, type, token, secret);
}
#endif
if (ret != E_OK) {
LOGE("active and restore fail, ret %{public}d, userId %{public}u, type %{public}u sec empty %{public}d",
ret, userId, type, secret.empty());
return ret;
}
} else if (ret == -ENOENT) {
LOGI("start GenerateKeyAndPrepareUserDirs userId %{public}u, type %{public}u sec empty %{public}d",
userId, type, secret.empty());
ret = GenerateKeyAndPrepareUserDirs(userId, type, token, secret);
if (ret != E_OK) {
LOGE("active and generate fail ret %{public}d, userId %{public}u, type %{public}u, sec empty %{public}d",
ret, userId, type, secret.empty());
return ret;
}
}
return ret;
#else
return E_OK;
#endif
}
int32_t StorageDaemon::ActiveUserKey(uint32_t userId,
const std::vector<uint8_t> &token,
const std::vector<uint8_t> &secret)
{
#ifdef USER_CRYPTO_MANAGER
LOGD("userId %{public}u, tok empty %{public}d sec empty %{public}d", userId, token.empty(), secret.empty());
auto ret = KeyManager::GetInstance()->ActiveUserKey(userId, token, secret);
if (ret == E_OK) {
return E_OK;
}
LOGI("userId %{public}u, tok empty %{public}d sec empty %{public}d", userId, token.empty(), secret.empty());
int ret = KeyManager::GetInstance()->ActiveCeSceSeceUserKey(userId, EL2_KEY, token, secret);
if (ret != E_OK) {
#ifdef USER_CRYPTO_MIGRATE_KEY
LOGI("migrate, userId %{public}u, tok empty %{public}d sec empty %{public}d",
userId, token.empty(), secret.empty());
if (IsNeedRestorePathExist(userId, false) && (!token.empty() || !secret.empty())) {
return PrepareUserDirsAndUpdateUserAuth(userId, token, secret);
}
LOGI("migrate, userId %{public}u, tok empty %{public}d sec empty %{public}d",
userId, token.empty(), secret.empty());
std::string el2NeedRestorePath = GetNeedRestoreFilePath(userId, USER_EL2_DIR);
if (std::filesystem::exists(el2NeedRestorePath) && (!token.empty() || !secret.empty())) {
ret = PrepareUserDirsAndUpdateUserAuth(userId, EL2_KEY, token, secret);
}
#endif
if (ret != E_OK) {
LOGE("ActiveUserKey fail, userId %{public}u, type %{public}u, tok empty %{public}d sec empty %{public}d",
userId, EL2_KEY, token.empty(), secret.empty());
return ret;
}
}
ret = ActiveUserKeyAndPrepare(userId, EL3_KEY, token, secret);
if (ret != E_OK) {
LOGE("ActiveUserKey fail, userId %{public}u, type %{public}u", userId, EL3_KEY);
return ret;
}
ret = ActiveUserKeyAndPrepare(userId, EL4_KEY, token, secret);
if (ret != E_OK) {
LOGE("ActiveUserKey fail, userId %{public}u, type %{public}u", userId, EL4_KEY);
return ret;
}
return ret;
#else
return E_OK;