1 /*
2 * Copyright (c) 2021-2022 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 "huks_master.h"
17
18 #include <dlfcn.h>
19 #include <openssl/err.h>
20 #include <openssl/rand.h>
21 #include <openssl/sha.h>
22
23 #include "hks_param.h"
24
25 #include "storage_service_log.h"
26
27 namespace OHOS {
28 namespace StorageDaemon {
HuksMaster()29 HuksMaster::HuksMaster()
30 {
31 LOGD("enter");
32 HdiCreate();
33 HdiModuleInit();
34 LOGD("finish");
35 }
36
~HuksMaster()37 HuksMaster::~HuksMaster()
38 {
39 LOGD("enter");
40 HdiModuleDestroy();
41 HdiDestroy();
42 LOGD("finish");
43 }
44
HdiCreate()45 bool HuksMaster::HdiCreate()
46 {
47 LOGD("enter");
48 if (hdiHandle_ != nullptr || halDevice_ != nullptr) {
49 return true;
50 }
51
52 hdiHandle_ = dlopen("libhuks_engine_core_standard.z.so", RTLD_LAZY);
53 if (hdiHandle_ == nullptr) {
54 LOGE("dlopen failed %{public}s", dlerror());
55 return false;
56 }
57
58 auto createHdi = reinterpret_cast<HkmHalCreateHandle>(dlsym(hdiHandle_, "HuksCreateHdiDevicePtr"));
59 if (createHdi == nullptr) {
60 LOGE("dlsym failed %{public}s", dlerror());
61 dlclose(hdiHandle_);
62 hdiHandle_ = nullptr;
63 return false;
64 }
65
66 halDevice_ = (*createHdi)();
67 if (halDevice_ == nullptr) {
68 LOGE("HuksHdiCreate failed");
69 dlclose(hdiHandle_);
70 hdiHandle_ = nullptr;
71 return false;
72 }
73 LOGD("success");
74 return true;
75 }
76
HdiDestroy()77 void HuksMaster::HdiDestroy()
78 {
79 LOGD("enter");
80 if (hdiHandle_ == nullptr) {
81 LOGI("hdiHandle_ is nullptr, already destroyed");
82 return;
83 }
84
85 auto destroyHdi = reinterpret_cast<HkmHalDestroyHandle>(dlsym(hdiHandle_, "HuksDestoryHdiDevicePtr"));
86 if ((destroyHdi != nullptr) && (halDevice_ != nullptr)) {
87 (*destroyHdi)(halDevice_);
88 }
89
90 dlclose(hdiHandle_);
91 hdiHandle_ = nullptr;
92 halDevice_ = nullptr;
93 LOGD("finish");
94 }
95
HdiModuleInit()96 int HuksMaster::HdiModuleInit()
97 {
98 LOGD("enter");
99 if (halDevice_ == nullptr) {
100 LOGE("halDevice_ is nullptr");
101 return HKS_ERROR_NULL_POINTER;
102 }
103 if (halDevice_->HuksHdiModuleInit == nullptr) {
104 LOGE("HuksHdiModuleInit is nullptr");
105 return HKS_ERROR_NULL_POINTER;
106 }
107
108 int ret = halDevice_->HuksHdiModuleInit();
109 if (ret != HKS_SUCCESS) {
110 LOGE("HuksHdiModuleInit failed, ret %{public}d", ret);
111 }
112 return ret;
113 }
114
HdiModuleDestroy()115 int HuksMaster::HdiModuleDestroy()
116 {
117 LOGD("enter");
118 if (halDevice_ == nullptr) {
119 LOGE("halDevice_ is nullptr");
120 return HKS_ERROR_NULL_POINTER;
121 }
122 if (halDevice_->HuksHdiModuleDestroy == nullptr) {
123 LOGE("HuksHdiModuleDestroy is nullptr");
124 return HKS_ERROR_NULL_POINTER;
125 }
126
127 int ret = halDevice_->HuksHdiModuleDestroy();
128 if (ret != HKS_SUCCESS) {
129 LOGE("HuksHdiModuleDestroy failed, ret %{public}d", ret);
130 }
131 return ret;
132 }
133
HdiGenerateKey(const HksBlob & keyAlias,const HksParamSet * paramSetIn,HksBlob & keyOut)134 int HuksMaster::HdiGenerateKey(const HksBlob &keyAlias, const HksParamSet *paramSetIn,
135 HksBlob &keyOut)
136 {
137 LOGD("enter");
138 if (halDevice_ == nullptr) {
139 LOGE("halDevice_ is nullptr");
140 return HKS_ERROR_NULL_POINTER;
141 }
142 if (halDevice_->HuksHdiGenerateKey == nullptr) {
143 LOGE("HuksHdiAccessGenerateKey is nullptr");
144 return HKS_ERROR_NULL_POINTER;
145 }
146
147 uint8_t d = 0;
148 HksBlob keyIn = {1, &d};
149 auto ret = halDevice_->HuksHdiGenerateKey(&keyAlias, paramSetIn, &keyIn, &keyOut);
150 if (ret != HKS_SUCCESS) {
151 LOGE("HuksHdiGenerateKey failed, ret %{public}d", ret);
152 }
153 return ret;
154 }
155
HdiAccessInit(const HksBlob & key,const HksParamSet * paramSet,HksBlob & handle,HksBlob & token)156 int HuksMaster::HdiAccessInit(const HksBlob &key, const HksParamSet *paramSet,
157 HksBlob &handle, HksBlob &token)
158 {
159 LOGD("enter");
160 if (halDevice_ == nullptr) {
161 LOGE("halDevice_ is nullptr");
162 return HKS_ERROR_NULL_POINTER;
163 }
164 if (halDevice_->HuksHdiInit == nullptr) {
165 LOGE("HuksHdiAccessInit is nullptr");
166 return HKS_ERROR_NULL_POINTER;
167 }
168
169 auto ret = halDevice_->HuksHdiInit(&key, paramSet, &handle, &token);
170 if (ret != HKS_SUCCESS) {
171 LOGE("HuksHdiInit failed, ret %{public}d", ret);
172 }
173 return ret;
174 }
175
HdiAccessFinish(const HksBlob & handle,const HksParamSet * paramSet,const HksBlob & inData,HksBlob & outData)176 int HuksMaster::HdiAccessFinish(const HksBlob &handle, const HksParamSet *paramSet,
177 const HksBlob &inData, HksBlob &outData)
178 {
179 LOGD("enter");
180 if (halDevice_ == nullptr) {
181 LOGE("halDevice_ is nullptr");
182 return HKS_ERROR_NULL_POINTER;
183 }
184 if (halDevice_->HuksHdiFinish == nullptr) {
185 LOGE("HuksHdiAccessFinish is nullptr");
186 return HKS_ERROR_NULL_POINTER;
187 }
188
189 auto ret = halDevice_->HuksHdiFinish(&handle, paramSet, &inData, &outData);
190 if (ret != HKS_SUCCESS) {
191 LOGE("HuksHdiFinish failed, ret %{public}d", ret);
192 }
193 return ret;
194 }
195
HdiAccessUpgradeKey(const HksBlob & oldKey,const HksParamSet * paramSet,struct HksBlob & newKey)196 int HuksMaster::HdiAccessUpgradeKey(const HksBlob &oldKey, const HksParamSet *paramSet, struct HksBlob &newKey)
197 {
198 LOGD("enter");
199 if (halDevice_ == nullptr) {
200 LOGE("halDevice_ is nullptr");
201 return HKS_ERROR_NULL_POINTER;
202 }
203 if (halDevice_->HuksHdiUpgradeKey == nullptr) {
204 LOGE("HuksHdiUpgradeKey is nullptr");
205 return HKS_ERROR_NULL_POINTER;
206 }
207
208 auto ret = halDevice_->HuksHdiUpgradeKey(&oldKey, paramSet, &newKey);
209 if (ret != HKS_SUCCESS) {
210 LOGI("HuksHdiUpgradeKey ret %{public}d", ret);
211 }
212 return ret;
213 }
214
GenerateRandomKey(uint32_t keyLen)215 KeyBlob HuksMaster::GenerateRandomKey(uint32_t keyLen)
216 {
217 LOGD("enter, size %{public}d", keyLen);
218 KeyBlob out(keyLen);
219 if (out.IsEmpty()) {
220 return out;
221 }
222
223 auto ret = RAND_bytes(out.data.get(), out.size);
224 if (ret <= 0) {
225 LOGE("RAND_bytes failed return %{public}d, errno %{public}lu", ret, ERR_get_error());
226 out.Clear();
227 }
228 return out;
229 }
230
AppendSecureAccessParams(const UserAuth & auth,HksParamSet * paramSet)231 static int AppendSecureAccessParams(const UserAuth &auth, HksParamSet *paramSet)
232 {
233 if (auth.secret.IsEmpty() || auth.token.IsEmpty()) {
234 LOGI("auth is empty, not to enable secure access for the key");
235 return HKS_SUCCESS;
236 }
237
238 LOGI("append the secure access params when generate key");
239 uint64_t secureUid = auth.secureUid;
240
241 HksParam param[] = {
242 { .tag = HKS_TAG_USER_AUTH_TYPE, .uint32Param = HKS_USER_AUTH_TYPE_PIN },
243 { .tag = HKS_TAG_KEY_AUTH_ACCESS_TYPE, .uint32Param = HKS_AUTH_ACCESS_INVALID_CLEAR_PASSWORD },
244 { .tag = HKS_TAG_CHALLENGE_TYPE, .uint32Param = HKS_CHALLENGE_TYPE_NONE },
245 { .tag = HKS_TAG_USER_AUTH_SECURE_UID,
246 .blob =
247 { sizeof(secureUid), (uint8_t *)&secureUid }
248 },
249 { .tag = HKS_TAG_AUTH_TIMEOUT,
250 .uint32Param = 30 // token timeout is 30 seconds when no challenge
251 }
252 };
253 return HksAddParams(paramSet, param, HKS_ARRAY_SIZE(param));
254 }
255
256 static uint8_t g_processName[sizeof(uint32_t)] = {0};
257 static const HksParam g_generateKeyParam[] = {
258 { .tag = HKS_TAG_KEY_GENERATE_TYPE, .uint32Param = HKS_KEY_GENERATE_TYPE_DEFAULT },
259 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
260 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
261 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
262 { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256 },
263 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
264 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
265 { .tag = HKS_TAG_PROCESS_NAME,
266 .blob =
267 { sizeof(g_processName), g_processName }
268 },
269 };
270
GenerateKey(const UserAuth & auth,KeyBlob & keyOut)271 bool HuksMaster::GenerateKey(const UserAuth &auth, KeyBlob &keyOut)
272 {
273 LOGD("enter");
274
275 HksParamSet *paramSet = nullptr;
276 int ret = HKS_SUCCESS;
277 do {
278 ret = HksInitParamSet(¶mSet);
279 if (ret != HKS_SUCCESS) {
280 LOGE("HksInitParamSet failed ret %{public}d", ret);
281 break;
282 }
283 ret = HksAddParams(paramSet, g_generateKeyParam, HKS_ARRAY_SIZE(g_generateKeyParam));
284 if (ret != HKS_SUCCESS) {
285 LOGE("HksAddParams failed ret %{public}d", ret);
286 break;
287 }
288 ret = AppendSecureAccessParams(auth, paramSet);
289 if (ret != HKS_SUCCESS) {
290 LOGE("AppendSecureAccessParams failed ret %{public}d", ret);
291 break;
292 }
293 ret = HksBuildParamSet(¶mSet);
294 if (ret != HKS_SUCCESS) {
295 LOGE("HksBuildParamSet failed ret %{public}d", ret);
296 break;
297 }
298 KeyBlob alias = GenerateRandomKey(CRYPTO_KEY_ALIAS_SIZE);
299 HksBlob hksAlias = alias.ToHksBlob();
300 keyOut.Alloc(CRYPTO_KEY_SHIELD_MAX_SIZE);
301 HksBlob hksKeyOut = keyOut.ToHksBlob();
302 ret = HdiGenerateKey(hksAlias, paramSet, hksKeyOut);
303 if (ret != HKS_SUCCESS) {
304 LOGE("HdiGenerateKey failed ret %{public}d", ret);
305 break;
306 }
307 keyOut.size = hksKeyOut.size;
308 LOGI("HdiGenerateKey success, out size %{public}d", keyOut.size);
309 } while (0);
310
311 HksFreeParamSet(¶mSet);
312 return ret == HKS_SUCCESS;
313 }
314
HashAndClip(const std::string & prefix,const KeyBlob & payload,uint32_t length)315 static KeyBlob HashAndClip(const std::string &prefix, const KeyBlob &payload, uint32_t length)
316 {
317 KeyBlob res(SHA512_DIGEST_LENGTH);
318 std::string header = prefix;
319 if (header.empty()) {
320 header = "dummy SHA512 header";
321 }
322
323 SHA512_CTX c;
324 SHA512_Init(&c);
325 SHA512_Update(&c, header.data(), header.size());
326 if (!payload.IsEmpty()) {
327 SHA512_Update(&c, payload.data.get(), payload.size);
328 }
329 SHA512_Final(res.data.get(), &c);
330
331 res.size = length;
332 return res;
333 }
334
GenHuksKeyBlobParam(KeyContext & ctx)335 static HksParamSet *GenHuksKeyBlobParam(KeyContext &ctx)
336 {
337 return reinterpret_cast<HksParamSet *>(ctx.shield.data.get());
338 }
339
AppendAeTag(KeyBlob & cipherText,HksParamSet * paramSet)340 static int AppendAeTag(KeyBlob &cipherText, HksParamSet *paramSet)
341 {
342 if (cipherText.size <= HKS_AE_TAG_LEN) {
343 LOGE("cipherText size %{public}d is too small", cipherText.size);
344 return HKS_ERROR_INVALID_KEY_INFO;
345 }
346
347 HksParam param[] = {
348 { .tag = HKS_TAG_AE_TAG,
349 .blob =
350 { HKS_AE_TAG_LEN, cipherText.data.get() + cipherText.size - HKS_AE_TAG_LEN }
351 },
352 };
353 cipherText.size -= HKS_AE_TAG_LEN;
354 return HksAddParams(paramSet, param, HKS_ARRAY_SIZE(param));
355 }
356
AppendNonceAad(KeyContext & ctx,HksParamSet * paramSet)357 static int AppendNonceAad(KeyContext &ctx, HksParamSet *paramSet)
358 {
359 ctx.nonce = HashAndClip("NONCE SHA512 prefix", ctx.secDiscard, CRYPTO_AES_NONCE_LEN);
360 ctx.aad = HashAndClip("AAD SHA512 prefix", ctx.secDiscard, CRYPTO_AES_AAD_LEN);
361 HksParam addParam[] = {
362 { .tag = HKS_TAG_NONCE,
363 .blob =
364 { ctx.nonce.size, ctx.nonce.data.get() }
365 },
366 { .tag = HKS_TAG_ASSOCIATED_DATA,
367 .blob =
368 { ctx.aad.size, ctx.aad.data.get() }
369 }
370 };
371 return HksAddParams(paramSet, addParam, HKS_ARRAY_SIZE(addParam));
372 }
373
AppendNonceAadToken(KeyContext & ctx,const UserAuth & auth,HksParamSet * paramSet)374 static int AppendNonceAadToken(KeyContext &ctx, const UserAuth &auth, HksParamSet *paramSet)
375 {
376 if (auth.secret.IsEmpty() || auth.token.IsEmpty()) {
377 LOGI("auth is empty, not to use secure access tag");
378 return AppendNonceAad(ctx, paramSet);
379 }
380
381 LOGI("append the secure access params when encrypt/decrypt");
382 ctx.nonce = HashAndClip("NONCE SHA512 prefix", auth.secret, CRYPTO_AES_NONCE_LEN);
383 ctx.aad = HashAndClip("AAD SHA512 prefix", ctx.secDiscard, CRYPTO_AES_AAD_LEN);
384 HksParam addParam[] = {
385 { .tag = HKS_TAG_USER_AUTH_TYPE, .uint32Param = HKS_USER_AUTH_TYPE_PIN },
386 { .tag = HKS_TAG_KEY_AUTH_ACCESS_TYPE, .uint32Param = HKS_AUTH_ACCESS_INVALID_CLEAR_PASSWORD },
387 { .tag = HKS_TAG_NONCE,
388 .blob =
389 { ctx.nonce.size, ctx.nonce.data.get() }
390 },
391 { .tag = HKS_TAG_ASSOCIATED_DATA,
392 .blob =
393 { ctx.aad.size, ctx.aad.data.get() }
394 },
395 { .tag = HKS_TAG_AUTH_TOKEN,
396 .blob =
397 { auth.token.size, auth.token.data.get() }
398 }
399 };
400 return HksAddParams(paramSet, addParam, HKS_ARRAY_SIZE(addParam));
401 }
402
GenHuksOptionParam(KeyContext & ctx,const UserAuth & auth,const bool isEncrypt)403 static HksParamSet *GenHuksOptionParam(KeyContext &ctx, const UserAuth &auth, const bool isEncrypt)
404 {
405 HksParam encryptParam[] = {
406 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
407 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
408 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
409 { .tag = HKS_TAG_IS_KEY_ALIAS, .boolParam = false },
410 { .tag = HKS_TAG_PURPOSE, .uint32Param = isEncrypt ? HKS_KEY_PURPOSE_ENCRYPT : HKS_KEY_PURPOSE_DECRYPT},
411 { .tag = HKS_TAG_CHALLENGE_TYPE, .uint32Param = HKS_CHALLENGE_TYPE_NONE },
412 { .tag = HKS_TAG_PROCESS_NAME,
413 .blob =
414 { sizeof(g_processName), g_processName }
415 }
416 };
417
418 HksParamSet *paramSet = nullptr;
419 auto ret = HksInitParamSet(¶mSet);
420 if (ret != HKS_SUCCESS) {
421 LOGE("HksInitParamSet failed ret %{public}d", ret);
422 return nullptr;
423 }
424 ret = HksAddParams(paramSet, encryptParam, HKS_ARRAY_SIZE(encryptParam));
425 if (ret != HKS_SUCCESS) {
426 LOGE("HksAddParams failed ret %{public}d", ret);
427 HksFreeParamSet(¶mSet);
428 return nullptr;
429 }
430
431 if (!isEncrypt) {
432 ret = AppendAeTag(ctx.encrypted, paramSet);
433 if (ret != HKS_SUCCESS) {
434 LOGE("AppendAeTag failed ret %{public}d", ret);
435 HksFreeParamSet(¶mSet);
436 return nullptr;
437 }
438 }
439
440 ret = AppendNonceAadToken(ctx, auth, paramSet);
441 if (ret != HKS_SUCCESS) {
442 LOGE("AppendNonceAad failed ret %{public}d", ret);
443 HksFreeParamSet(¶mSet);
444 return nullptr;
445 }
446
447 ret = HksBuildParamSet(¶mSet);
448 if (ret != HKS_SUCCESS) {
449 LOGE("HksBuildParamSet failed ret %{public}d", ret);
450 HksFreeParamSet(¶mSet);
451 return nullptr;
452 }
453
454 return paramSet;
455 }
456
HuksHalTripleStage(HksParamSet * paramSet1,const HksParamSet * paramSet2,const KeyBlob & keyIn,KeyBlob & keyOut)457 bool HuksMaster::HuksHalTripleStage(HksParamSet *paramSet1, const HksParamSet *paramSet2,
458 const KeyBlob &keyIn, KeyBlob &keyOut)
459 {
460 LOGD("enter");
461 HksBlob hksKey = { paramSet1->paramSetSize, reinterpret_cast<uint8_t *>(paramSet1) };
462 HksBlob hksIn = keyIn.ToHksBlob();
463 HksBlob hksOut = keyOut.ToHksBlob();
464 uint8_t h[sizeof(uint64_t)] = {0};
465 HksBlob hksHandle = { sizeof(uint64_t), h };
466 uint8_t t[CRYPTO_TOKEN_SIZE] = {0};
467 HksBlob hksToken = { sizeof(t), t }; // would not use the challenge here
468
469 int ret = HdiAccessInit(hksKey, paramSet2, hksHandle, hksToken);
470 if (ret != HKS_SUCCESS) {
471 LOGE("HdiAccessInit failed ret %{public}d", ret);
472 return false;
473 }
474
475 ret = HdiAccessFinish(hksHandle, paramSet2, hksIn, hksOut);
476 if (ret != HKS_SUCCESS) {
477 LOGE("HdiAccessFinish failed ret %{public}d", ret);
478 return false;
479 }
480
481 keyOut.size = hksOut.size;
482 return true;
483 }
484
EncryptKey(KeyContext & ctx,const UserAuth & auth,const KeyInfo & key)485 bool HuksMaster::EncryptKey(KeyContext &ctx, const UserAuth &auth, const KeyInfo &key)
486 {
487 LOGD("enter");
488 if (ctx.shield.IsEmpty()) {
489 LOGE("bad shield input, size %{public}d", ctx.shield.size);
490 return false;
491 }
492 if (key.key.IsEmpty()) {
493 LOGE("bad rawKey input, size %{public}d", key.key.size);
494 return false;
495 }
496
497 HksParamSet *paramSet1 = GenHuksKeyBlobParam(ctx);
498 if (paramSet1 == nullptr) {
499 LOGE("GenHuksKeyBlobParam failed");
500 return false;
501 }
502 HksParamSet *paramSet2 = GenHuksOptionParam(ctx, auth, true);
503 if (paramSet2 == nullptr) {
504 LOGE("GenHuksOptionParam failed");
505 return false;
506 }
507
508 ctx.encrypted.Alloc(CRYPTO_AES_256_KEY_ENCRYPTED_SIZE);
509 auto ret = HuksHalTripleStage(paramSet1, paramSet2, key.key, ctx.encrypted);
510 if (!ret) {
511 LOGE("HuksHalTripleStage failed");
512 }
513
514 HksFreeParamSet(¶mSet2);
515 LOGD("finish");
516 return ret;
517 }
518
DecryptKey(KeyContext & ctx,const UserAuth & auth,KeyInfo & key)519 bool HuksMaster::DecryptKey(KeyContext &ctx, const UserAuth &auth, KeyInfo &key)
520 {
521 LOGD("enter");
522 if (ctx.shield.IsEmpty()) {
523 LOGE("bad shield input, size %{public}d", ctx.shield.size);
524 return false;
525 }
526 if (ctx.encrypted.IsEmpty()) {
527 LOGE("bad encrypted input, size %{public}d", ctx.encrypted.size);
528 return false;
529 }
530
531 HksParamSet *paramSet1 = GenHuksKeyBlobParam(ctx);
532 if (paramSet1 == nullptr) {
533 LOGE("GenHuksKeyBlobParam failed");
534 return false;
535 }
536 HksParamSet *paramSet2 = GenHuksOptionParam(ctx, auth, false);
537 if (paramSet2 == nullptr) {
538 LOGE("GenHuksOptionParam failed");
539 return false;
540 }
541
542 key.key.Alloc(CRYPTO_AES_256_XTS_KEY_SIZE);
543 auto ret = HuksHalTripleStage(paramSet1, paramSet2, ctx.encrypted, key.key);
544 if (!ret) {
545 LOGE("HuksHalTripleStage failed");
546 }
547
548 HksFreeParamSet(¶mSet2);
549 LOGD("finish");
550 return ret;
551 }
552
CheckNeedUpgrade(KeyBlob & inData)553 static bool CheckNeedUpgrade(KeyBlob &inData)
554 {
555 constexpr uint32_t HKS_KEY_VERSION = 3;
556 HksParamSet *keyBlobParamSet = NULL;
557 int ret = HksGetParamSet(reinterpret_cast<HksParamSet *>(inData.data.get()), inData.size, &keyBlobParamSet);
558 if (ret != HKS_SUCCESS) {
559 LOGE("HksGetParamSet failed %{public}d", ret);
560 return false;
561 }
562
563 struct HksParam *keyVersion = nullptr;
564 ret = HksGetParam(keyBlobParamSet, HKS_TAG_KEY_VERSION, &keyVersion);
565 if (ret != HKS_SUCCESS) {
566 LOGE("version get key param failed!");
567 HksFreeParamSet(&keyBlobParamSet);
568 return false;
569 }
570
571 if (keyVersion->uint32Param >= HKS_KEY_VERSION) {
572 HksFreeParamSet(&keyBlobParamSet);
573 return false;
574 }
575 HksFreeParamSet(&keyBlobParamSet);
576 return true;
577 }
578
UpgradeKey(KeyContext & ctx)579 bool HuksMaster::UpgradeKey(KeyContext &ctx)
580 {
581 struct HksParamSet *paramSet = NULL;
582 bool ret = false;
583
584 if (!CheckNeedUpgrade(ctx.shield)) {
585 LOGI("no need to upgrade");
586 return false;
587 }
588
589 LOGI("Do upgradekey");
590 do {
591 int err = HksInitParamSet(¶mSet);
592 if (err != HKS_SUCCESS) {
593 LOGE("HksInitParamSet failed ret %{public}d", err);
594 break;
595 }
596 err = HksAddParams(paramSet, g_generateKeyParam, HKS_ARRAY_SIZE(g_generateKeyParam));
597 if (err != HKS_SUCCESS) {
598 LOGE("HksAddParams failed ret %{public}d", err);
599 break;
600 }
601 err = HksBuildParamSet(¶mSet);
602 if (err != HKS_SUCCESS) {
603 LOGE("HksBuildParamSet failed ret %{public}d", err);
604 break;
605 }
606
607 KeyBlob keyOut(CRYPTO_KEY_SHIELD_MAX_SIZE);
608 HksBlob hksIn = ctx.shield.ToHksBlob();
609 HksBlob hksOut = keyOut.ToHksBlob();
610
611 err = HdiAccessUpgradeKey(hksIn, paramSet, hksOut);
612 if (err == HKS_SUCCESS) {
613 LOGI("Shield upgraded successfully");
614 keyOut.size = hksOut.size;
615 ctx.shield.Clear();
616 ctx.shield = std::move(keyOut);
617 ret = true;
618 }
619 } while (0);
620 HksFreeParamSet(¶mSet);
621 return ret;
622 }
623
624 } // namespace StorageDaemon
625 } // namespace OHOS
626