1 /*
2 * Copyright (C) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "key_manager_ext.h"
17
18 #include "directory_ex.h"
19 #include "file_ex.h"
20 #include "key_manager.h"
21 #include "iam_client.h"
22 #include "libfscrypt/fscrypt_control.h"
23 #include "storage_service_errno.h"
24 #include "storage_service_log.h"
25 #include "utils/file_utils.h"
26 #include "utils/string_utils.h"
27
28 namespace OHOS {
29 namespace StorageDaemon {
30
31 namespace {
32 typedef UserkeyExtInterface* (*GetExtInstance)(void);
33 }
34
35 constexpr uint32_t TYPE_EL2 = 1;
36 const std::vector<uint8_t> DEFAULT_KEY = { 'D', 'o', 'c', 's' };
37
KeyManagerExt()38 KeyManagerExt::KeyManagerExt()
39 {
40 Init();
41 LOGI("Instance created.");
42 }
43
~KeyManagerExt()44 KeyManagerExt::~KeyManagerExt()
45 {
46 UnInit();
47 LOGI("Instance destroyed.");
48 }
49
Init()50 void KeyManagerExt::Init()
51 {
52 if (!KeyCtrlHasFscryptSyspara()) {
53 LOGE("FscryptSyspara has not enabled");
54 return;
55 }
56 handler_ = dlopen("/system/lib64/libspace_mgr_ext.z.so", RTLD_LAZY);
57 if (handler_ == nullptr) {
58 LOGE("Policy not exist, just start service.");
59 return;
60 }
61
62 GetExtInstance fnInstance = reinterpret_cast<GetExtInstance>(dlsym(handler_, "GetUserKeyExtInstance"));
63 if (fnInstance == nullptr) {
64 LOGE("GetExtInstance failed.");
65 return;
66 }
67
68 service_ = static_cast<UserkeyExtInterface*>(fnInstance());
69 if (service_ == nullptr) {
70 LOGE("User key Ext instance is null.");
71 }
72 }
73
UnInit()74 void KeyManagerExt::UnInit()
75 {
76 LOGI("UnInit start");
77 if (handler_) {
78 dlclose(handler_);
79 handler_ = nullptr;
80 }
81 service_ = nullptr;
82 }
83
GenerateUserKeys(uint32_t userId,uint32_t flags)84 int KeyManagerExt::GenerateUserKeys(uint32_t userId, uint32_t flags)
85 {
86 LOGI("start, user:%{public}u", userId);
87 if (!IsServiceExtSoLoaded()) {
88 LOGI("user key ext policy is disabled");
89 return E_OK;
90 }
91 if (!KeyCtrlHasFscryptSyspara()) {
92 return E_OK;
93 }
94 if ((flags & IStorageDaemonEnum::CRYPTO_FLAG_EL2) != IStorageDaemonEnum::CRYPTO_FLAG_EL2) {
95 LOGI("Not specify el2 flags");
96 return E_OK;
97 }
98
99 std::lock_guard<std::mutex> lock(keyMutex_);
100 int ret = GenerateAndInstallUserKey(userId);
101 if (ret != E_OK) {
102 return ret;
103 }
104
105 LOGI("Create user key success");
106 return ret;
107 }
108
DeleteUserKeys(uint32_t userId)109 int KeyManagerExt::DeleteUserKeys(uint32_t userId)
110 {
111 LOGI("start, user:%{public}d", userId);
112 if (!IsServiceExtSoLoaded()) {
113 LOGI("user key ext policy is disabled");
114 return E_OK;
115 }
116 if (!KeyCtrlHasFscryptSyspara()) {
117 return E_OK;
118 }
119
120 std::lock_guard<std::mutex> lock(keyMutex_);
121 int ret = DoDeleteUserKeys(userId);
122 if (ret != E_OK) {
123 return ret;
124 }
125 LOGI("delete user key success");
126 return ret;
127 }
128
ActiveUserKey(uint32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)129 int KeyManagerExt::ActiveUserKey(uint32_t userId,
130 const std::vector<uint8_t>& token,
131 const std::vector<uint8_t>& secret)
132 {
133 LOGI("start, user:%{public}u", userId);
134 if (!IsServiceExtSoLoaded()) {
135 LOGI("user key ext policy is disabled");
136 return E_OK;
137 }
138 if (!KeyCtrlHasFscryptSyspara()) {
139 return E_OK;
140 }
141 std::lock_guard<std::mutex> lock(keyMutex_);
142 int ret = DoActiveUserKey(userId, token, secret);
143 if (ret != E_OK) {
144 return ret;
145 }
146
147 LOGI("Active user %{public}u key success", userId);
148 return ret;
149 }
150
InActiveUserKey(uint32_t userId)151 int KeyManagerExt::InActiveUserKey(uint32_t userId)
152 {
153 LOGI("start, user:%{public}u", userId);
154 if (!IsServiceExtSoLoaded()) {
155 LOGI("user key ext policy is disabled");
156 return E_OK;
157 }
158 if (!KeyCtrlHasFscryptSyspara()) {
159 return E_OK;
160 }
161 std::lock_guard<std::mutex> lock(keyMutex_);
162 int ret = DoInactiveUserKey(userId);
163 if (ret != E_OK) {
164 return ret;
165 }
166 LOGI("Inactive user %{public}u key success", userId);
167 return E_OK;
168 }
169
SetRecoverKey(uint32_t userId,uint32_t keyType,const KeyBlob & ivBlob)170 int KeyManagerExt::SetRecoverKey(uint32_t userId, uint32_t keyType, const KeyBlob& ivBlob)
171 {
172 LOGI("start, user:%{public}u, keyType:%{public}u", userId, keyType);
173 if (!IsServiceExtSoLoaded()) {
174 LOGI("user key ext policy is disabled");
175 return E_OK;
176 }
177 if (!KeyCtrlHasFscryptSyspara()) {
178 return E_OK;
179 }
180 if (keyType != TYPE_EL2) {
181 return E_OK;
182 }
183 std::lock_guard<std::mutex> lock(keyMutex_);
184 KeyBlob preKey(DEFAULT_KEY);
185 KeyBlob hashKey = OpensslCrypto::HashWithPrefix(preKey, ivBlob, AES_256_HASH_RANDOM_SIZE);
186 std::vector<uint8_t> keyVec(hashKey.data.get(), hashKey.data.get() + hashKey.size);
187 int ret = service_->SetRecoverKey(userId, std::move(keyVec));
188 if (ret != E_OK) {
189 LOGE("set recover key error, ret: %{public}d", ret);
190 return ret;
191 }
192
193 hashKey.Clear();
194 LOGI("set recover key success");
195 return E_OK;
196 }
197
GetHashKey(uint32_t userId,KeyType type,KeyBlob & hashKey)198 int KeyManagerExt::GetHashKey(uint32_t userId, KeyType type, KeyBlob& hashKey)
199 {
200 if (!KeyManager::GetInstance().HasElkey(userId, type)) {
201 LOGE("user el%{public}u key is not existed", type);
202 return E_KEY_EMPTY_ERROR;
203 }
204 std::shared_ptr<BaseKey> elKey = KeyManager::GetInstance().GetUserElKey(userId, type);
205 if (elKey == nullptr) {
206 LOGE("Have not found user %{public}u, type el%{public}u", userId, type);
207 return E_KEY_EMPTY_ERROR;
208 }
209
210 if (!elKey->GetHashKey(hashKey) || hashKey.IsEmpty()) {
211 LOGE("get origin hash key failed !");
212 return E_KEY_EMPTY_ERROR;
213 }
214 return E_OK;
215 }
216
GenerateAndInstallUserKey(uint32_t userId)217 int KeyManagerExt::GenerateAndInstallUserKey(uint32_t userId)
218 {
219 KeyBlob hashKey;
220 int ret = GetHashKey(userId, EL2_KEY, hashKey);
221 if (ret != E_OK) {
222 LOGE("Generate user key error, ret: %{public}d", ret);
223 return ret;
224 }
225
226 LOGI("Generate user key for %{public}d.", userId);
227 std::vector<uint8_t> keyVec(hashKey.data.get(), hashKey.data.get() + hashKey.size);
228 ret = service_->GenerateUserKey(userId, std::move(keyVec));
229 if (ret != E_OK) {
230 LOGE("Generate user key error, ret: %{public}d", ret);
231 return ret;
232 }
233 hashKey.Clear();
234
235 ret = service_->SetFilePathPolicy(userId);
236 if (ret != E_OK) {
237 LOGE("Set directory policy error, ret: %{public}d", ret);
238 }
239 return ret;
240 }
241
DoInactiveUserKey(uint32_t userId)242 int KeyManagerExt::DoInactiveUserKey(uint32_t userId)
243 {
244 int ret = service_->InactiveUserKey(userId);
245 if (ret != E_OK) {
246 LOGE("Inactive user key error, ret: %{public}d", ret);
247 return ret;
248 }
249 return ret;
250 }
251
DoActiveUserKey(uint32_t userId,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret)252 int KeyManagerExt::DoActiveUserKey(uint32_t userId,
253 const std::vector<uint8_t> &token,
254 const std::vector<uint8_t> &secret)
255 {
256 KeyBlob hashKey;
257 int ret = GetHashKey(userId, EL2_KEY, hashKey);
258 if (ret != E_OK) {
259 LOGE("Generate user key error, ret: %{public}d", ret);
260 return ret;
261 }
262
263 std::vector<uint8_t> keyVec(hashKey.data.get(), hashKey.data.get() + hashKey.size);
264 ret = service_->ActiveUserKey(userId, std::move(keyVec), token);
265 if (ret != E_OK) {
266 LOGE("Active user key with token error, ret: %{public}d", ret);
267 }
268 hashKey.Clear();
269 return ret;
270 }
271
DoDeleteUserKeys(uint32_t userId)272 int KeyManagerExt::DoDeleteUserKeys(uint32_t userId)
273 {
274 int ret = service_->DeleteUserKey(userId);
275 if (ret != E_OK) {
276 LOGE("del user key error, ret: %{public}d", ret);
277 }
278 return ret;
279 }
280
281 } // namespace StorageDaemon
282 } // namespace OHOS
283