1 /*
2 * Copyright (c) 2024-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 "recover_manager.h"
17
18 #include <bitset>
19 #include <openssl/sha.h>
20 #include <unistd.h>
21 #include "key_manager_ext.h"
22 #include "storage_service_errno.h"
23 #include "storage_service_log.h"
24 #include "utils/storage_radar.h"
25
26 using namespace OHOS::StorageService;
27 namespace OHOS {
28 namespace StorageDaemon {
29 static const std::string CRYPTO_NAME_PREFIXES[] = {"ext4", "f2fs", "fscrypt"};
30 #ifdef RECOVER_KEY_TEE_ENVIRONMENT
31 constexpr uint32_t ELX_TYPE_ARR[] = { TYPE_GLOBAL_EL1, USERID_GLOBAL_EL1, TYPE_EL1, TYPE_EL2, TYPE_EL3, TYPE_EL4 };
32 constexpr static uint32_t TEE_PARAM_INDEX_0 = 0;
33 constexpr static uint32_t TEE_PARAM_INDEX_1 = 1;
34 constexpr static uint32_t TEE_PARAM_INDEX_2 = 2;
35 constexpr static int SESSION_START_DEFAULT = 1;
36 constexpr int MAX_RETRY_COUNT = 3;
37 constexpr int RETRY_INTERVAL = 100 * 1000; // 100ms
38 constexpr static uint32_t RECOVERY_USER_ID = 300;
39 #endif
40
RecoveryManager()41 RecoveryManager::RecoveryManager()
42 {
43 LOGI("enter");
44 isSessionOpened = false;
45 }
46
~RecoveryManager()47 RecoveryManager::~RecoveryManager()
48 {
49 LOGI("enter");
50 }
51
IsEncryptionEnabled()52 bool RecoveryManager::IsEncryptionEnabled()
53 {
54 LOGI("enter");
55 #ifdef RECOVER_KEY_TEE_ENVIRONMENT
56 TEEC_Context createKeyContext = {};
57 TEEC_Session createKeySession = {};
58 if (!OpenSession(createKeyContext, createKeySession)) {
59 LOGE("Open session failed !");
60 return true;
61 }
62
63 TEEC_Operation operation = { 0 };
64 operation.started = SESSION_START_DEFAULT;
65 operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_OUTPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
66 operation.params[TEE_PARAM_INDEX_0].value.a = 1;
67
68 uint32_t origin = 0;
69 TEEC_Result result = TEEC_InvokeCommand(&createKeySession, TaCmdId::RK_CMD_ID_GET_FULL_DISK_ENCRYPTION_POLICY,
70 &operation, &origin);
71 LOGI("InvokeCmd ret: %{public}d, origin: %{public}d", result, origin);
72 if (result != TEEC_SUCCESS) {
73 LOGE("InvokeCmd failed, ret: %{public}d, origin: %{public}d", result, origin);
74 CloseSession(createKeyContext, createKeySession);
75 std::string extraData = "cmd=RK_CMD_ID_GET_FULL_DISK_ENCRYPTION_POLICY,ret=" + std::to_string(result) +
76 ",origin=" + std::to_string(origin);
77 StorageRadar::ReportTEEClientResult("TEEC_InvokeCommand", E_TEEC_GEN_RECOVERY_KEY_ERR, 0, extraData);
78 return true;
79 }
80 CloseSession(createKeyContext, createKeySession);
81
82 auto policy = std::bitset<sizeof(uint32_t)>(operation.params[TEE_PARAM_INDEX_0].value.a);
83 return policy.test(0);
84 #endif
85 LOGI("success");
86 return true;
87 }
88
CreateRecoverKey(uint32_t userId,uint32_t userType,const std::vector<uint8_t> & token,const std::vector<uint8_t> & secret,const std::vector<KeyBlob> & originIv)89 int RecoveryManager::CreateRecoverKey(uint32_t userId,
90 uint32_t userType,
91 const std::vector<uint8_t> &token,
92 const std::vector<uint8_t> &secret,
93 const std::vector<KeyBlob> &originIv)
94 {
95 LOGI("enter");
96 #ifdef RECOVER_KEY_TEE_ENVIRONMENT
97 TEEC_Context createKeyContext = {};
98 TEEC_Session createKeySession = {};
99 if (!OpenSession(createKeyContext, createKeySession)) {
100 LOGE("Open session failed !");
101 return E_RECOVERY_KEY_OPEN_SESSION_ERR;
102 }
103 uint32_t createKeyOrigin = 0;
104 TEEC_Operation operation = { 0 };
105 operation.started = SESSION_START_DEFAULT;
106 operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
107 CreateRecoverKeyStr recoverKeyStr = { .userType = userType, .userId = userId,
108 .authTokenLen = static_cast<uint32_t>(token.size()) };
109 if (!token.empty()) {
110 auto err = memcpy_s(recoverKeyStr.authToken, AUTH_TOKEN_LEN, token.data(), token.size());
111 if (err != EOK) {
112 CloseSession(createKeyContext, createKeySession);
113 return E_MEMORY_OPERATION_ERR;
114 }
115 }
116 for (size_t i = 0; i < originIv.size(); ++i) {
117 auto err = memcpy_s(recoverKeyStr.rndToTee[i], RND_AND_KEY2_LEN, originIv[i].data.get(), originIv[i].size);
118 if (err != EOK) {
119 CloseSession(createKeyContext, createKeySession);
120 return E_MEMORY_OPERATION_ERR;
121 }
122 }
123 auto startTime = StorageService::StorageRadar::RecordCurrentTime();
124 operation.params[TEE_PARAM_INDEX_0].tmpref.buffer = static_cast<void *>(&recoverKeyStr);
125 operation.params[TEE_PARAM_INDEX_0].tmpref.size = sizeof(recoverKeyStr);
126 TEEC_Result ret = TEEC_InvokeCommand(&createKeySession, TaCmdId::RK_CMD_ID_GEN_RECOVERY_KEY,
127 &operation, &createKeyOrigin);
128 LOGW("SD_DURATION: InvokeCmd ret: %{public}d, origin: %{public}d, token size: %{public}zu, delay = %{public}s",
129 ret, createKeyOrigin, token.size(), StorageService::StorageRadar::ReportDuration("CREATE RECOVERY KEY",
130 startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId).c_str());
131 if (ret != TEEC_SUCCESS) {
132 LOGE("InvokeCmd failed, ret: %{public}d, origin: %{public}d", ret, createKeyOrigin);
133 CloseSession(createKeyContext, createKeySession);
134 std::string extraData = "cmd=RK_CMD_ID_GEN_RECOVERY_KEY,ret=" + std::to_string(ret) +
135 ",origin=" + std::to_string(createKeyOrigin);
136 StorageRadar::ReportTEEClientResult("TEEC_InvokeCommand", E_TEEC_GEN_RECOVERY_KEY_ERR, userId, extraData);
137 return E_TEEC_GEN_RECOVERY_KEY_ERR;
138 }
139 CloseSession(createKeyContext, createKeySession);
140 #endif
141 LOGI("success");
142 return 0;
143 }
144
SetRecoverKey(const std::vector<uint8_t> & key)145 int RecoveryManager::SetRecoverKey(const std::vector<uint8_t> &key)
146 {
147 #ifdef RECOVER_KEY_TEE_ENVIRONMENT
148 SetRecoverKeyStr setRecoverKeyStr;
149 int ret = SetRecoverKeyToTee(key, setRecoverKeyStr);
150 if (ret != 0) {
151 LOGE("Set recover key to tee failed !");
152 return ret;
153 }
154 if (sizeof(setRecoverKeyStr.key2FromTee) != sizeof(setRecoverKeyStr.rndFromTee)) {
155 LOGE("key2 size dose not match iv size !");
156 return E_PARAMS_INVALID;
157 }
158 int rndNum = sizeof(setRecoverKeyStr.rndFromTee) / RND_AND_KEY2_LEN;
159 int key2Num = sizeof(setRecoverKeyStr.key2FromTee) / RND_AND_KEY2_LEN;
160 if (rndNum != RND_AND_KEY2_NUMS || key2Num != RND_AND_KEY2_NUMS) {
161 LOGE("rnd and key2 num is not match ! rndNum: %{public}d, key2Num: %{public}d", rndNum, key2Num);
162 return E_PARAMS_INVALID;
163 }
164
165 for (int i = 0; i < rndNum; ++i) {
166 uint8_t *key2 = setRecoverKeyStr.key2FromTee[i];
167 uint8_t *originIv = setRecoverKeyStr.rndFromTee[i];
168 std::vector<uint8_t> key2Data(key2, key2 + RND_AND_KEY2_LEN);
169 std::vector<uint8_t> ivData(originIv, originIv + RND_AND_KEY2_LEN);
170 KeyBlob ivBlob(ivData);
171 KeyBlob key2Blob(key2Data);
172 KeyBlob keyDesc;
173 auto errNo = GenerateKeyDesc(ivBlob, keyDesc);
174 if (errNo != E_OK) {
175 LOGE("Generate key desc failed !");
176 return errNo;
177 }
178 auto startTime = StorageService::StorageRadar::RecordCurrentTime();
179 ret = InstallKeyDescToKeyring(ELX_TYPE_ARR[i], key2Blob, keyDesc);
180 if (ret != E_OK) {
181 ivBlob.Clear();
182 keyDesc.Clear();
183 key2Blob.Clear();
184 LOGE("install type %{public}d to keyring failed !", ELX_TYPE_ARR[i]);
185 return ret;
186 }
187 (void)KeyManagerExt::GetInstance().SetRecoverKey(RECOVERY_USER_ID, ELX_TYPE_ARR[i], ivBlob);
188 auto delay = StorageService::StorageRadar::ReportDuration("INSTALL KEY DESC TO KEYRING", startTime);
189 LOGI("SD_DURATION: INSTALL KEY DESC TO KEYRING, delayTime = %{public}s", delay.c_str());
190 ivBlob.Clear();
191 keyDesc.Clear();
192 key2Blob.Clear();
193 }
194 #endif
195 return 0;
196 }
197
SetRecoverKeyToTee(const std::vector<uint8_t> & key,SetRecoverKeyStr & setRecoverKeyStr)198 int RecoveryManager::SetRecoverKeyToTee(const std::vector<uint8_t> &key, SetRecoverKeyStr &setRecoverKeyStr)
199 {
200 LOGI("enter");
201 #ifdef RECOVER_KEY_TEE_ENVIRONMENT
202 TEEC_Context setKeyContext = {};
203 TEEC_Session setKeySession = {};
204 if (!OpenSession(setKeyContext, setKeySession)) {
205 LOGE("Open session failed !");
206 return E_RECOVERY_KEY_OPEN_SESSION_ERR;
207 }
208 auto startTime = StorageService::StorageRadar::RecordCurrentTime();
209 TEEC_Operation operation = { 0 };
210 operation.started = SESSION_START_DEFAULT;
211 operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE, TEEC_NONE);
212 uint32_t setKeyOrigin;
213 operation.params[TEE_PARAM_INDEX_0].tmpref.buffer = static_cast<void *>(const_cast<unsigned char *>(key.data()));
214 operation.params[TEE_PARAM_INDEX_0].tmpref.size = key.size();
215 operation.params[TEE_PARAM_INDEX_1].tmpref.buffer = static_cast<void *>(&setRecoverKeyStr);
216 operation.params[TEE_PARAM_INDEX_1].tmpref.size = sizeof(setRecoverKeyStr);
217 TEEC_Result ret = TEEC_InvokeCommand(&setKeySession, TaCmdId::RK_CMD_ID_DECRYPT_CLASS_KEY, &operation,
218 &setKeyOrigin);
219 LOGI("InvokeCmd ret: %{public}d, origin: %{public}d", ret, setKeyOrigin);
220 if (ret != TEEC_SUCCESS) {
221 LOGE("InvokeCmd failed, ret: %{public}d, origin: %{public}d", ret, setKeyOrigin);
222 CloseSession(setKeyContext, setKeySession);
223 std::string extraData = "cmd=RK_CMD_ID_DECRYPT_CLASS_KEY,ret=" + std::to_string(ret) +
224 ",origin=" + std::to_string(setKeyOrigin);
225 StorageRadar::ReportTEEClientResult("SetRecoverKeyToTee::TEEC_InvokeCommand", E_TEEC_DECRYPT_CLASS_KEY_ERR,
226 DEFAULT_USERID, extraData);
227 return E_TEEC_DECRYPT_CLASS_KEY_ERR;
228 }
229 auto delay = StorageService::StorageRadar::ReportDuration("SET RECOVERY KEY",
230 startTime, StorageService::DELAY_TIME_THRESH_HIGH, StorageService::DEFAULT_USERID);
231 LOGI("SD_DURATION: SET RECOVERY KEY, delayTime = %{public}s", delay.c_str());
232 CloseSession(setKeyContext, setKeySession);
233 #endif
234 return 0;
235 }
236
ResetSecretWithRecoveryKey(uint32_t userId,uint32_t rkType,const std::vector<uint8_t> & key,std::vector<KeyBlob> & originIvs)237 int32_t RecoveryManager::ResetSecretWithRecoveryKey(uint32_t userId, uint32_t rkType,
238 const std::vector<uint8_t> &key, std::vector<KeyBlob> &originIvs)
239 {
240 LOGI("reset secret userId: %{public}d", userId);
241 #ifdef RECOVER_KEY_TEE_ENVIRONMENT
242 SetRecoverKeyStr setRecoverKeyStr;
243 int ret = ResetSecretWithRecoveryKeyToTee(userId, rkType, key, setRecoverKeyStr);
244 if (ret != 0) {
245 LOGE("Set recover key to tee failed !");
246 return ret;
247 }
248
249 if (sizeof(setRecoverKeyStr.key2FromTee) != sizeof(setRecoverKeyStr.rndFromTee)) {
250 LOGE("key2 size dose not match iv size !");
251 return E_PARAMS_INVALID;
252 }
253 int rndNum = sizeof(setRecoverKeyStr.rndFromTee) / RND_AND_KEY2_LEN;
254 int key2Num = sizeof(setRecoverKeyStr.key2FromTee) / RND_AND_KEY2_LEN;
255 if (rndNum != RND_AND_KEY2_NUMS || key2Num != RND_AND_KEY2_NUMS) {
256 LOGE("rnd and key2 num is not match ! rndNum: %{public}d, key2Num: %{public}d", rndNum, key2Num);
257 return E_PARAMS_INVALID;
258 }
259
260 for (int i = 0; i < rndNum; ++i) {
261 uint8_t *key2 = setRecoverKeyStr.key2FromTee[i];
262 uint8_t *originIv = setRecoverKeyStr.rndFromTee[i];
263 std::vector<uint8_t> key2Data(key2, key2 + RND_AND_KEY2_LEN);
264 std::vector<uint8_t> ivData(originIv, originIv + RND_AND_KEY2_LEN);
265 KeyBlob ivBlob(ivData);
266 KeyBlob key2Blob(key2Data);
267 KeyBlob keyDesc;
268 auto errNo = GenerateKeyDesc(ivBlob, keyDesc);
269 if (errNo != E_OK) {
270 LOGE("Generate key desc failed !");
271 return errNo;
272 }
273 auto startTime = StorageService::StorageRadar::RecordCurrentTime();
274 ret = InstallKeyDescToKeyring(ELX_TYPE_ARR[i], key2Blob, keyDesc);
275 if (ret != E_OK) {
276 LOGE("install type %{public}d to keyring failed !", ELX_TYPE_ARR[i]);
277 return ret;
278 }
279 (void)KeyManagerExt::GetInstance().SetRecoverKey(userId, ELX_TYPE_ARR[i], ivBlob);
280 auto delay = StorageService::StorageRadar::ReportDuration("INSTALL KEY DESC TO KEYRING",
281 startTime, StorageService::DEFAULT_DELAY_TIME_THRESH, userId);
282 LOGI("SD_DURATION: INSTALL KEY DESC TO KEYRING, delayTime = %{public}s", delay.c_str());
283 originIvs.emplace_back(ivBlob);
284 }
285 #endif
286 return E_OK;
287 }
288
ResetSecretWithRecoveryKeyToTee(uint32_t userId,uint32_t rkType,const std::vector<uint8_t> & key,SetRecoverKeyStr & setRecoverKeyStr)289 int32_t RecoveryManager::ResetSecretWithRecoveryKeyToTee(uint32_t userId, uint32_t rkType,
290 const std::vector<uint8_t> &key, SetRecoverKeyStr &setRecoverKeyStr)
291 {
292 LOGI("reset secret with recovery key");
293 #ifdef RECOVER_KEY_TEE_ENVIRONMENT
294 TEEC_Context setKeyContext = {};
295 TEEC_Session setKeySession = {};
296 if (!OpenSession(setKeyContext, setKeySession)) {
297 LOGE("Open session failed !");
298 return E_RECOVERY_KEY_OPEN_SESSION_ERR;
299 }
300
301 auto startTime = StorageService::StorageRadar::RecordCurrentTime();
302 TEEC_Operation operation = { 0 };
303 operation.started = SESSION_START_DEFAULT;
304 operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,
305 TEEC_VALUE_INPUT, TEEC_MEMREF_TEMP_OUTPUT, TEEC_NONE);
306 uint32_t setKeyOrigin;
307 operation.params[TEE_PARAM_INDEX_0].tmpref.buffer = static_cast<void *>(const_cast<unsigned char *>(key.data()));
308 operation.params[TEE_PARAM_INDEX_0].tmpref.size = key.size();
309 operation.params[TEE_PARAM_INDEX_1].value.a = userId;
310 operation.params[TEE_PARAM_INDEX_1].value.b = rkType;
311 operation.params[TEE_PARAM_INDEX_2].tmpref.buffer = static_cast<void *>(&setRecoverKeyStr);
312 operation.params[TEE_PARAM_INDEX_2].tmpref.size = sizeof(setRecoverKeyStr);
313 TEEC_Result ret = TEEC_InvokeCommand(&setKeySession, TaCmdId::RK_CMD_ID_SET_RK_FOR_PLUGGED_IN_SSD, &operation,
314 &setKeyOrigin);
315 LOGI("InvokeCmd ret: %{public}d, origin: %{public}d", ret, setKeyOrigin);
316 if (ret != TEEC_SUCCESS) {
317 LOGE("InvokeCmd failed, ret: %{public}d, origin: %{public}d", ret, setKeyOrigin);
318 CloseSession(setKeyContext, setKeySession);
319 std::string extraData = "cmd=RK_CMD_ID_SET_RK_FOR_PLUGGED_IN_SSD,ret=" + std::to_string(ret) +
320 ",origin=" + std::to_string(setKeyOrigin);
321 StorageRadar::ReportTEEClientResult("ResetSecretWithRecoveryKeyToTee::TEEC_InvokeCommand",
322 E_TEEC_SET_RK_FOR_PLUGGED_IN_SSD_ERR, userId, extraData);
323 return E_TEEC_SET_RK_FOR_PLUGGED_IN_SSD_ERR;
324 }
325 auto delay = StorageService::StorageRadar::ReportDuration("RESET SECRET WITH RECOVERY KEY",
326 startTime, StorageService::DELAY_TIME_THRESH_HIGH, userId);
327 LOGI("SD_DURATION: RESET SECRET WITH RECOVERY KEY, delayTime = %{public}s", delay.c_str());
328 CloseSession(setKeyContext, setKeySession);
329 #endif
330 return E_OK;
331 }
332
333 #ifdef RECOVER_KEY_TEE_ENVIRONMENT
OpenSession(TEEC_Context & context,TEEC_Session & session)334 bool RecoveryManager::OpenSession(TEEC_Context &context, TEEC_Session &session)
335 {
336 LOGI("enter");
337 if (isSessionOpened) {
338 LOGE("Tee session has Opened !");
339 return true;
340 }
341 TEEC_Result ret = TEEC_InitializeContext(NULL, &context);
342 if (ret != TEEC_SUCCESS) {
343 LOGE("recovery tee ctx init failed !");
344 TEEC_FinalizeContext(&context);
345 isSessionOpened = false;
346 StorageRadar::ReportTEEClientResult("OpenSession::TEEC_InitializeContext", ret, DEFAULT_USERID, "");
347 return false;
348 }
349 TEEC_Operation operation;
350 LOGI("Prepare session operation.");
351 operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
352 if (memset_s(&operation, sizeof(TEEC_Operation), 0, sizeof(TEEC_Operation)) != EOK) {
353 LOGE("[OpenSession] memset_s failed !");
354 TEEC_FinalizeContext(&context);
355 isSessionOpened = false;
356 return false;
357 }
358 LOGI("Prepare open session.");
359 operation.started = SESSION_START_DEFAULT;
360 operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
361 uint32_t retErr = 0;
362 uint32_t retryCount = 0;
363 while (retryCount < MAX_RETRY_COUNT) {
364 ret = TEEC_OpenSession(&context, &session, recoverUuid_, TEEC_LOGIN_IDENTIFY, nullptr, &operation, &retErr);
365 if (ret == TEEC_SUCCESS) {
366 LOGI("Open session success, has try %{public}u times.", retryCount);
367 break;
368 }
369 retryCount++;
370 LOGE("has retry %{public}d times, ret: %{public}d", retryCount, ret);
371 usleep(RETRY_INTERVAL);
372 }
373
374 if (ret != TEEC_SUCCESS) {
375 LOGE("open session failed !");
376 CloseSession(context, session);
377 StorageRadar::ReportTEEClientResult("OpenSession::TEEC_OpenSession", ret, DEFAULT_USERID, "");
378 return false;
379 }
380 isSessionOpened = true;
381 LOGI("open session success");
382 return true;
383 }
384
CloseSession(TEEC_Context & context,TEEC_Session & session)385 void RecoveryManager::CloseSession(TEEC_Context &context, TEEC_Session &session)
386 {
387 TEEC_CloseSession(&session);
388 TEEC_FinalizeContext(&context);
389 isSessionOpened = false;
390 LOGI("close session success");
391 }
392 #endif
393
GenerateKeyDesc(const KeyBlob & ivBlob,KeyBlob & keyDesc)394 int32_t RecoveryManager::GenerateKeyDesc(const KeyBlob &ivBlob, KeyBlob &keyDesc)
395 {
396 LOGI("enter");
397 if (ivBlob.IsEmpty()) {
398 LOGE("key is empty");
399 return E_KEY_BLOB_ERROR;
400 }
401 SHA512_CTX c;
402
403 SHA512_Init(&c);
404 SHA512_Update(&c, ivBlob.data.get(), ivBlob.size);
405 uint8_t keyRef1[SHA512_DIGEST_LENGTH] = { 0 };
406 SHA512_Final(keyRef1, &c);
407
408 SHA512_Init(&c);
409 SHA512_Update(&c, keyRef1, SHA512_DIGEST_LENGTH);
410 uint8_t keyRef2[SHA512_DIGEST_LENGTH] = { 0 };
411 SHA512_Final(keyRef2, &c);
412
413 static_assert(SHA512_DIGEST_LENGTH >= CRYPTO_KEY_DESC_SIZE, "Hash too short for descriptor");
414 keyDesc.Alloc(CRYPTO_KEY_DESC_SIZE);
415 auto err = memcpy_s(keyDesc.data.get(), keyDesc.size, keyRef2, CRYPTO_KEY_DESC_SIZE);
416 if (err != EOK) {
417 LOGE("memcpy failed ret %{public}d", err);
418 return err;
419 }
420 LOGI("succeed");
421 return E_OK;
422 }
423
InstallKeyDescToKeyring(size_t keyType,const KeyBlob & key2Blob,const KeyBlob & keyDesc)424 int32_t RecoveryManager::InstallKeyDescToKeyring(size_t keyType, const KeyBlob &key2Blob, const KeyBlob &keyDesc)
425 {
426 int ret = E_OK;
427 if (keyType == TYPE_EL3 || keyType == TYPE_EL4) {
428 uint32_t sdpClass;
429 if (keyType == TYPE_EL3) {
430 sdpClass = FSCRYPT_SDP_SECE_CLASS;
431 } else {
432 sdpClass = FSCRYPT_SDP_ECE_CLASS;
433 }
434 ret = InstallEceSece(sdpClass, key2Blob, keyDesc);
435 if (ret != E_OK) {
436 LOGE("InstallKeyDescToKeyring failed");
437 return ret;
438 }
439 } else {
440 ret = InstallDeCe(key2Blob, keyDesc);
441 if (ret != E_OK) {
442 LOGE("InstallKeyToKeyring failed");
443 return ret;
444 }
445 }
446 return E_OK;
447 }
448
449
InstallDeCe(const KeyBlob & key2Blob,const KeyBlob & keyDesc)450 int32_t RecoveryManager::InstallDeCe(const KeyBlob &key2Blob, const KeyBlob &keyDesc)
451 {
452 fscrypt_key fskey;
453 fskey.mode = FS_ENCRYPTION_MODE_AES_256_XTS;
454 fskey.size = key2Blob.size;
455 auto err = memcpy_s(fskey.raw, FS_MAX_KEY_SIZE, key2Blob.data.get(), key2Blob.size);
456 if (err != EOK) {
457 LOGE("memcpy failed ret %{public}d", err);
458 return err;
459 }
460
461 key_serial_t krid = KeyCtrlSearch(KEY_SPEC_SESSION_KEYRING, "keyring", "fscrypt", 0);
462 if (krid == -1) {
463 LOGI("no session keyring for fscrypt");
464 krid = KeyCtrlAddKey("keyring", "fscrypt", KEY_SPEC_SESSION_KEYRING);
465 if (krid == -1) {
466 LOGE("failed to add session keyring");
467 return E_ADD_SESSION_KEYRING_ERROR;
468 }
469 }
470 for (auto prefix : CRYPTO_NAME_PREFIXES) {
471 std::string keyref = prefix + ":" + keyDesc.ToString();
472 LOGI("InstallDeCe: prefix: %{public}s", prefix.c_str());
473 key_serial_t ks = KeyCtrlAddKeyEx("logon", keyref.c_str(), &fskey, krid);
474 if (ks == -1) {
475 // Addkey failed, need to process the error
476 LOGE("Failed to AddKey %{public}s to keyring, errno %{public}d", prefix.c_str(), errno);
477 }
478 }
479 LOGI("success");
480 return E_OK;
481 }
482
InstallEceSece(uint32_t sdpClass,const KeyBlob & key2Blob,const KeyBlob & keyDesc)483 int32_t RecoveryManager::InstallEceSece(uint32_t sdpClass, const KeyBlob &key2Blob, const KeyBlob &keyDesc)
484 {
485 EncryptionKeySdp fskey;
486 if (key2Blob.size != sizeof(fskey.raw)) {
487 LOGE("Wrong key size is %{public}d", key2Blob.size);
488 return E_KEY_BLOB_ERROR;
489 }
490 fskey.mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
491 auto err = memcpy_s(fskey.raw, sizeof(fskey.raw), key2Blob.data.get(), key2Blob.size);
492 if (err != EOK) {
493 LOGE("memcpy failed ret %{public}d", err);
494 return err;
495 }
496 fskey.size = EXT4_AES_256_XTS_KEY_SIZE_TO_KEYRING;
497 fskey.sdpClass = sdpClass;
498 fskey.version = 0;
499 key_serial_t krid = KeyCtrlSearch(KEY_SPEC_SESSION_KEYRING, "keyring", "fscrypt", 0);
500 if (krid == -1) {
501 LOGI("no session keyring for fscrypt");
502 krid = KeyCtrlAddKey("keyring", "fscrypt", KEY_SPEC_SESSION_KEYRING);
503 if (krid == -1) {
504 LOGE("failed to add session keyring");
505 return E_ADD_SESSION_KEYRING_ERROR;
506 }
507 }
508 for (auto prefix : CRYPTO_NAME_PREFIXES) {
509 std::string keyref = prefix + ":" + keyDesc.ToString();
510 key_serial_t ks = KeyCtrlAddKeySdp("logon", keyref.c_str(), &fskey, krid);
511 if (ks == -1) {
512 // Addkey failed, need to process the error
513 LOGE("Failed to AddKey %{public}s into keyring, errno %{public}d", prefix.c_str(), errno);
514 }
515 }
516 LOGI("success");
517 return E_OK;
518 }
519 } // namespace StorageDaemon
520 } // namespace HOHS