• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&paramSet);
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(&paramSet);
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(&paramSet);
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(&paramSet);
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(&paramSet);
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(&paramSet);
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(&paramSet);
444         return nullptr;
445     }
446 
447     ret = HksBuildParamSet(&paramSet);
448     if (ret != HKS_SUCCESS) {
449         LOGE("HksBuildParamSet failed ret %{public}d", ret);
450         HksFreeParamSet(&paramSet);
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(&paramSet2);
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(&paramSet2);
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(&paramSet);
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(&paramSet);
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(&paramSet);
621     return ret;
622 }
623 
624 } // namespace StorageDaemon
625 } // namespace OHOS
626