• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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_adapter.h"
17 #include "hal_error.h"
18 #include "hc_file.h"
19 #include "hc_log.h"
20 #include "hc_types.h"
21 #include "hc_dev_info.h"
22 #include "hks_api.h"
23 #include "hks_param.h"
24 #include "hks_type.h"
25 #include "string_util.h"
26 
27 #define BASE_IMPORT_PARAMS_LEN 7
28 #define EXT_IMPORT_PARAMS_LEN 2
29 
30 static enum HksKeyPurpose g_purposeToHksKeyPurpose[] = {
31     HKS_KEY_PURPOSE_MAC,
32     HKS_KEY_PURPOSE_DERIVE
33 };
34 
BaseCheckParams(const Uint8Buff ** inParams,const char ** paramTags,uint32_t len)35 static int32_t BaseCheckParams(const Uint8Buff **inParams, const char **paramTags, uint32_t len)
36 {
37     for (uint32_t i = 0; i < len; i++) {
38         CHECK_PTR_RETURN_HAL_ERROR_CODE(inParams[i], paramTags[i]);
39         CHECK_PTR_RETURN_HAL_ERROR_CODE(inParams[i]->val, paramTags[i]);
40         CHECK_LEN_ZERO_RETURN_ERROR_CODE(inParams[i]->length, paramTags[i]);
41     }
42     return HAL_SUCCESS;
43 }
44 
ConstructParamSet(struct HksParamSet ** out,const struct HksParam * inParam,const uint32_t inParamNum)45 static int32_t ConstructParamSet(struct HksParamSet **out, const struct HksParam *inParam,
46     const uint32_t inParamNum)
47 {
48     struct HksParamSet *paramSet = NULL;
49     int32_t ret = HksInitParamSet(&paramSet);
50     if (ret != HKS_SUCCESS) {
51         LOGE("init param set failed, ret = %d", ret);
52         return HAL_ERR_INIT_PARAM_SET_FAILED;
53     }
54 
55     ret = HksAddParams(paramSet, inParam, inParamNum);
56     if (ret != HKS_SUCCESS) {
57         LOGE("add param failed, ret = %d", ret);
58         HksFreeParamSet(&paramSet);
59         return HAL_ERR_ADD_PARAM_FAILED;
60     }
61 
62     ret = HksBuildParamSet(&paramSet);
63     if (ret != HKS_SUCCESS) {
64         LOGE("build param set failed, ret = %d", ret);
65         HksFreeParamSet(&paramSet);
66         return HAL_ERR_BUILD_PARAM_SET_FAILED;
67     }
68 
69     *out = paramSet;
70     return HAL_SUCCESS;
71 }
72 
InitHks(void)73 static int32_t InitHks(void)
74 {
75     int32_t res = HksInitialize();
76     if (res == HKS_SUCCESS) {
77         return HAL_SUCCESS;
78     }
79 
80     if ((res != HKS_ERROR_INVALID_KEY_FILE) && (res != HKS_ERROR_CRYPTO_ENGINE_ERROR) &&
81         (res != HKS_ERROR_UPDATE_ROOT_KEY_MATERIAL_FAIL)) {
82         LOGE("Hks: Init hks failed, res: %d.", res);
83         return HAL_ERR_INIT_FAILED;
84     }
85 
86     LOGD("Hks: The local hks file needs to be refreshed!");
87     LOGI("Start to delete local database file!");
88     HcFileRemove(GetStoragePath());
89     LOGI("Delete local database file successfully!");
90     res = HksRefreshKeyInfo();
91     if (res != HKS_SUCCESS) {
92         LOGE("Hks: HksRefreshKeyInfo failed, res: %d.", res);
93         return HAL_ERR_INIT_FAILED;
94     }
95     res = HksInitialize();
96     if (res != HKS_SUCCESS) {
97         LOGE("Hks: Init hks failed, res: %d.", res);
98         return HAL_ERR_INIT_FAILED;
99     }
100 
101     return HAL_SUCCESS;
102 }
103 
Sha256(const Uint8Buff * message,Uint8Buff * hash)104 static int32_t Sha256(const Uint8Buff *message, Uint8Buff *hash)
105 {
106     CHECK_PTR_RETURN_HAL_ERROR_CODE(message, "message");
107     CHECK_PTR_RETURN_HAL_ERROR_CODE(message->val, "message->val");
108     CHECK_LEN_ZERO_RETURN_ERROR_CODE(message->length, "message->length");
109 
110     CHECK_PTR_RETURN_HAL_ERROR_CODE(hash, "hash");
111     CHECK_PTR_RETURN_HAL_ERROR_CODE(hash->val, "hash->val");
112     CHECK_LEN_EQUAL_RETURN(hash->length, SHA256_LEN, "hash->length");
113 
114     struct HksBlob srcBlob = { message->length, message->val };
115     struct HksBlob hashBlob = { hash->length, hash->val };
116     struct HksParamSet *paramSet = NULL;
117     struct HksParam digestParam[] = {
118         {
119             .tag = HKS_TAG_DIGEST,
120             .uint32Param = HKS_DIGEST_SHA256
121         }
122     };
123     int32_t ret = ConstructParamSet(&paramSet, digestParam, CAL_ARRAY_SIZE(digestParam));
124     if (ret != HAL_SUCCESS) {
125         LOGE("construct param set failed, ret = %d", ret);
126         return ret;
127     }
128 
129     ret = HksHash(paramSet, &srcBlob, &hashBlob);
130     if (ret != HKS_SUCCESS || hashBlob.size != SHA256_LEN) {
131         HksFreeParamSet(&paramSet);
132         return HAL_FAILED;
133     }
134 
135     HksFreeParamSet(&paramSet);
136     return HAL_SUCCESS;
137 }
138 
GenerateRandom(Uint8Buff * rand)139 static int32_t GenerateRandom(Uint8Buff *rand)
140 {
141     CHECK_PTR_RETURN_HAL_ERROR_CODE(rand, "rand");
142     CHECK_PTR_RETURN_HAL_ERROR_CODE(rand->val, "rand->val");
143     CHECK_LEN_ZERO_RETURN_ERROR_CODE(rand->length, "rand->length");
144 
145     struct HksBlob randBlob = { rand->length, rand->val };
146     int32_t ret = HksGenerateRandom(NULL, &randBlob);
147     if (ret != HKS_SUCCESS) {
148         LOGE("Generate random failed, ret: %d", ret);
149         return HAL_FAILED;
150     }
151 
152     return HAL_SUCCESS;
153 }
154 
CheckKeyExist(const Uint8Buff * keyAlias)155 static int32_t CheckKeyExist(const Uint8Buff *keyAlias)
156 {
157     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias, "keyAlias");
158     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias->val, "keyAlias->val");
159     CHECK_LEN_ZERO_RETURN_ERROR_CODE(keyAlias->length, "keyAlias->length");
160 
161     struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
162     int32_t ret = HksKeyExist(&keyAliasBlob, NULL);
163     if (ret != HKS_SUCCESS) {
164         LOGE("Check key exist failed, ret = %d", ret);
165         return HAL_FAILED;
166     }
167 
168     return HAL_SUCCESS;
169 }
170 
DeleteKey(const Uint8Buff * keyAlias)171 static int32_t DeleteKey(const Uint8Buff *keyAlias)
172 {
173     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias, "keyAlias");
174     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias->val, "keyAlias->val");
175     CHECK_LEN_ZERO_RETURN_ERROR_CODE(keyAlias->length, "keyAlias->length");
176 
177     struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
178     int32_t ret = HksDeleteKey(&keyAliasBlob, NULL);
179     if (ret == HKS_ERROR_NOT_EXIST) {
180         LOGI("Key not exists.");
181         return HAL_SUCCESS;
182     }
183     if (ret != HKS_SUCCESS) {
184         LOGE("Delete key failed, ret = %d", ret);
185         return HAL_FAILED;
186     }
187 
188     return HAL_SUCCESS;
189 }
190 
ComputeHmac(const Uint8Buff * key,const Uint8Buff * message,Uint8Buff * outHmac,bool isAlias)191 static int32_t ComputeHmac(const Uint8Buff *key, const Uint8Buff *message, Uint8Buff *outHmac, bool isAlias)
192 {
193     const Uint8Buff *inParams[] = { key, message, outHmac };
194     const char *paramTags[] = {"key", "message", "outHmac"};
195     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
196     if (ret != HAL_SUCCESS) {
197         return ret;
198     }
199     CHECK_LEN_EQUAL_RETURN(outHmac->length, HMAC_LEN, "outHmac->length");
200 
201     struct HksBlob keyBlob = { key->length, key->val };
202     struct HksBlob srcBlob = { message->length, message->val };
203     struct HksBlob hmacBlob = { outHmac->length, outHmac->val };
204     struct HksParamSet *paramSet = NULL;
205     struct HksParam hmacParam[] = {
206         {
207             .tag = HKS_TAG_PURPOSE,
208             .uint32Param = HKS_KEY_PURPOSE_MAC
209         }, {
210             .tag = HKS_TAG_DIGEST,
211             .uint32Param = HKS_DIGEST_SHA256
212         }, {
213             .tag = HKS_TAG_IS_KEY_ALIAS,
214             .boolParam = isAlias
215         }
216     };
217     ret = ConstructParamSet(&paramSet, hmacParam, CAL_ARRAY_SIZE(hmacParam));
218     if (ret != HAL_SUCCESS) {
219         LOGE("construct param set failed, ret = %d", ret);
220         return ret;
221     }
222 
223     ret = HksMac(&keyBlob, paramSet, &srcBlob, &hmacBlob);
224     if (ret != HKS_SUCCESS  || hmacBlob.size != HMAC_LEN) {
225         LOGE("Hmac failed, ret: %d", ret);
226         HksFreeParamSet(&paramSet);
227         return HAL_FAILED;
228     }
229 
230     HksFreeParamSet(&paramSet);
231     return HAL_SUCCESS;
232 }
233 
ComputeHkdf(const Uint8Buff * baseKey,const Uint8Buff * salt,const Uint8Buff * keyInfo,Uint8Buff * outHkdf,bool isAlias)234 static int32_t ComputeHkdf(const Uint8Buff *baseKey, const Uint8Buff *salt, const Uint8Buff *keyInfo,
235     Uint8Buff *outHkdf, bool isAlias)
236 {
237     const Uint8Buff *inParams[] = { baseKey, salt, outHkdf };
238     const char *paramTags[] = { "baseKey", "salt", "outHkdf" };
239     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
240     if (ret != HAL_SUCCESS) {
241         return ret;
242     }
243 
244     struct HksBlob srcKeyBlob = { baseKey->length, baseKey->val };
245     struct HksBlob saltBlob = { salt->length, salt->val };
246     struct HksBlob keyInfoBlob = { 0, NULL };
247     if (keyInfo != NULL) {
248         keyInfoBlob.size = keyInfo->length;
249         keyInfoBlob.data = keyInfo->val;
250     }
251     struct HksBlob derivedKeyBlob = { outHkdf->length, outHkdf->val };
252 
253     struct HksParamSet *paramSet = NULL;
254     struct HksParam hkdfParam[] = {
255         {
256             .tag = HKS_TAG_PURPOSE,
257             .uint32Param = HKS_KEY_PURPOSE_DERIVE
258         }, {
259             .tag = HKS_TAG_ALGORITHM,
260             .uint32Param = HKS_ALG_HKDF
261         }, {
262             .tag = HKS_TAG_DIGEST,
263             .uint32Param = HKS_DIGEST_SHA256
264         }, {
265             .tag = HKS_TAG_SALT,
266             .blob = saltBlob
267         }, {
268             .tag = HKS_TAG_INFO,
269             .blob = keyInfoBlob
270         }, {
271             .tag = HKS_TAG_IS_KEY_ALIAS,
272             .boolParam = isAlias
273         }
274     };
275 
276     ret = ConstructParamSet(&paramSet, hkdfParam, CAL_ARRAY_SIZE(hkdfParam));
277     if (ret != HAL_SUCCESS) {
278         return ret;
279     }
280 
281     ret = HksDeriveKey(paramSet, &srcKeyBlob, &derivedKeyBlob);
282     if (ret != HKS_SUCCESS) {
283         LOGE("Key derivation failed, ret: %d", ret);
284         HksFreeParamSet(&paramSet);
285         return HAL_FAILED;
286     }
287 
288     HksFreeParamSet(&paramSet);
289     return HAL_SUCCESS;
290 }
291 
CheckAesGcmEncryptParam(const Uint8Buff * key,const Uint8Buff * plain,const GcmParam * encryptInfo,Uint8Buff * outCipher)292 static int32_t CheckAesGcmEncryptParam(const Uint8Buff *key, const Uint8Buff *plain, const GcmParam *encryptInfo,
293     Uint8Buff *outCipher)
294 {
295     const Uint8Buff *inParams[] = { key, plain, outCipher };
296     const char* paramTags[] = { "key", "plain", "outCipher" };
297     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
298     if (ret != HAL_SUCCESS) {
299         return ret;
300     }
301 
302     CHECK_PTR_RETURN_HAL_ERROR_CODE(encryptInfo, "encryptInfo");
303     CHECK_PTR_RETURN_HAL_ERROR_CODE(encryptInfo->aad, "aad");
304     CHECK_LEN_ZERO_RETURN_ERROR_CODE(encryptInfo->aadLen, "aadLen");
305     CHECK_PTR_RETURN_HAL_ERROR_CODE(encryptInfo->nonce, "nonce");
306     CHECK_LEN_LOWER_RETURN(encryptInfo->nonceLen, HKS_AE_NONCE_LEN, "nonceLen");
307     CHECK_LEN_LOWER_RETURN(outCipher->length, plain->length + HKS_AE_TAG_LEN, "outCipher");
308 
309     return HAL_SUCCESS;
310 }
311 
AesGcmEncrypt(const Uint8Buff * key,const Uint8Buff * plain,const GcmParam * encryptInfo,bool isAlias,Uint8Buff * outCipher)312 static int32_t AesGcmEncrypt(const Uint8Buff *key, const Uint8Buff *plain,
313     const GcmParam *encryptInfo, bool isAlias, Uint8Buff *outCipher)
314 {
315     int32_t ret = CheckAesGcmEncryptParam(key, plain, encryptInfo, outCipher);
316     if (ret != HAL_SUCCESS) {
317         return ret;
318     }
319 
320     struct HksBlob keyBlob = { key->length, key->val };
321     struct HksBlob plainBlob = { plain->length, plain->val };
322     struct HksBlob cipherBlob = { outCipher->length, outCipher->val };
323 
324     struct HksParamSet *paramSet = NULL;
325     struct HksParam encryptParam[] = {
326         {
327             .tag = HKS_TAG_PURPOSE,
328             .uint32Param = HKS_KEY_PURPOSE_ENCRYPT
329         }, {
330             .tag = HKS_TAG_ALGORITHM,
331             .uint32Param = HKS_ALG_AES
332         }, {
333             .tag = HKS_TAG_BLOCK_MODE,
334             .uint32Param = HKS_MODE_GCM
335         }, {
336             .tag = HKS_TAG_PADDING,
337             .uint32Param = HKS_PADDING_NONE
338         }, {
339             .tag = HKS_TAG_NONCE,
340             .blob = { encryptInfo->nonceLen, encryptInfo->nonce }
341         }, {
342             .tag = HKS_TAG_ASSOCIATED_DATA,
343             .blob = { encryptInfo->aadLen, encryptInfo->aad }
344         }, {
345             .tag = HKS_TAG_IS_KEY_ALIAS,
346             .boolParam = isAlias
347         }
348     };
349 
350     ret = ConstructParamSet(&paramSet, encryptParam, CAL_ARRAY_SIZE(encryptParam));
351     if (ret != HAL_SUCCESS) {
352         LOGE("construct param set failed, ret = %d", ret);
353         return ret;
354     }
355 
356     ret = HksEncrypt(&keyBlob, paramSet, &plainBlob, &cipherBlob);
357     if (ret != HKS_SUCCESS) {
358         LOGE("Aes-gcm encrypt failed, ret: %d", ret);
359         HksFreeParamSet(&paramSet);
360         return HAL_FAILED;
361     }
362 
363     HksFreeParamSet(&paramSet);
364     return HAL_SUCCESS;
365 }
366 
CheckAesGcmDecryptParam(const Uint8Buff * key,const Uint8Buff * cipher,const GcmParam * decryptInfo,Uint8Buff * outPlain)367 static int32_t CheckAesGcmDecryptParam(const Uint8Buff *key, const Uint8Buff *cipher, const GcmParam *decryptInfo,
368     Uint8Buff *outPlain)
369 {
370     const Uint8Buff *inParams[] = { key, cipher, outPlain };
371     const char *paramTags[] = { "key", "cipher", "outPlain" };
372     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
373     if (ret != HAL_SUCCESS) {
374         return ret;
375     }
376 
377     CHECK_PTR_RETURN_HAL_ERROR_CODE(decryptInfo, "decryptInfo");
378     CHECK_PTR_RETURN_HAL_ERROR_CODE(decryptInfo->aad, "aad");
379     CHECK_LEN_ZERO_RETURN_ERROR_CODE(decryptInfo->aadLen, "aadLen");
380     CHECK_PTR_RETURN_HAL_ERROR_CODE(decryptInfo->nonce, "nonce");
381     CHECK_LEN_LOWER_RETURN(decryptInfo->nonceLen, HKS_AE_NONCE_LEN, "nonceLen");
382     CHECK_LEN_LOWER_RETURN(outPlain->length, cipher->length - HKS_AE_TAG_LEN, "outPlain");
383 
384     return HAL_SUCCESS;
385 }
386 
AesGcmDecrypt(const Uint8Buff * key,const Uint8Buff * cipher,const GcmParam * decryptInfo,bool isAlias,Uint8Buff * outPlain)387 static int32_t AesGcmDecrypt(const Uint8Buff *key, const Uint8Buff *cipher,
388     const GcmParam *decryptInfo, bool isAlias, Uint8Buff *outPlain)
389 {
390     int32_t ret = CheckAesGcmDecryptParam(key, cipher, decryptInfo, outPlain);
391     if (ret != HAL_SUCCESS) {
392         return ret;
393     }
394 
395     struct HksBlob keyBlob = { key->length, key->val };
396     struct HksBlob cipherBlob = { cipher->length, cipher->val };
397     struct HksBlob plainBlob = { outPlain->length, outPlain->val };
398 
399     struct HksParamSet *paramSet = NULL;
400     struct HksParam decryptParam[] = {
401         {
402             .tag = HKS_TAG_PURPOSE,
403             .uint32Param = HKS_KEY_PURPOSE_DECRYPT
404         }, {
405             .tag = HKS_TAG_ALGORITHM,
406             .uint32Param = HKS_ALG_AES
407         }, {
408             .tag = HKS_TAG_BLOCK_MODE,
409             .uint32Param = HKS_MODE_GCM
410         }, {
411             .tag = HKS_TAG_PADDING,
412             .uint32Param = HKS_PADDING_NONE
413         }, {
414             .tag = HKS_TAG_NONCE,
415             .blob = { decryptInfo->nonceLen, decryptInfo->nonce }
416         }, {
417             .tag = HKS_TAG_ASSOCIATED_DATA,
418             .blob = { decryptInfo->aadLen, decryptInfo->aad }
419         }, {
420             .tag = HKS_TAG_IS_KEY_ALIAS,
421             .boolParam = isAlias
422         }
423     };
424 
425     ret = ConstructParamSet(&paramSet, decryptParam, CAL_ARRAY_SIZE(decryptParam));
426     if (ret != HAL_SUCCESS) {
427         LOGE("construct param set failed, ret = %d", ret);
428         return ret;
429     }
430 
431     ret = HksDecrypt(&keyBlob, paramSet, &cipherBlob, &plainBlob);
432     if (ret != HKS_SUCCESS) {
433         LOGE("Aes-gcm decrypt failed, ret: %d", ret);
434         HksFreeParamSet(&paramSet);
435         return HAL_FAILED;
436     }
437 
438     HksFreeParamSet(&paramSet);
439     return HAL_SUCCESS;
440 }
441 
CheckImportSymmetricKeyParam(const Uint8Buff * keyAlias,const Uint8Buff * authToken)442 static int32_t CheckImportSymmetricKeyParam(const Uint8Buff *keyAlias, const Uint8Buff *authToken)
443 {
444     const Uint8Buff *inParams[] = { keyAlias, authToken };
445     const char *paramTags[] = { "keyAlias", "authToken" };
446     return BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
447 }
448 
ConstructImportSymmetricKeyParam(struct HksParamSet ** paramSet,uint32_t keyLen,KeyPurpose purpose,const ExtraInfo * exInfo)449 static int32_t ConstructImportSymmetricKeyParam(struct HksParamSet **paramSet, uint32_t keyLen, KeyPurpose purpose,
450     const ExtraInfo *exInfo)
451 {
452     struct HksParam *importParam = NULL;
453     struct HksBlob authIdBlob = { 0, NULL };
454     union KeyRoleInfoUnion roleInfoUnion;
455     (void)memset_s(&roleInfoUnion, sizeof(roleInfoUnion), 0, sizeof(roleInfoUnion));
456     uint32_t idx = 0;
457     if (exInfo != NULL) {
458         CHECK_PTR_RETURN_HAL_ERROR_CODE(exInfo->authId.val, "authId");
459         CHECK_LEN_ZERO_RETURN_ERROR_CODE(exInfo->authId.length, "authId");
460         CHECK_LEN_HIGHER_RETURN(exInfo->pairType, PAIR_TYPE_END - 1, "pairType");
461         importParam = (struct HksParam *)HcMalloc(sizeof(struct HksParam) *
462             (BASE_IMPORT_PARAMS_LEN + EXT_IMPORT_PARAMS_LEN), 0);
463         if (importParam == NULL) {
464             LOGE("Malloc for importParam failed.");
465             return HAL_ERR_BAD_ALLOC;
466         }
467         authIdBlob.size = exInfo->authId.length;
468         authIdBlob.data = exInfo->authId.val;
469         roleInfoUnion.roleInfoStruct.userType = (uint8_t)exInfo->userType;
470         roleInfoUnion.roleInfoStruct.pairType = (uint8_t)exInfo->pairType;
471         importParam[idx].tag = HKS_TAG_KEY_AUTH_ID;
472         importParam[idx++].blob = authIdBlob;
473         importParam[idx].tag = HKS_TAG_KEY_ROLE;
474         importParam[idx++].uint32Param = roleInfoUnion.roleInfo;
475     } else {
476         importParam = (struct HksParam *)HcMalloc(sizeof(struct HksParam) * BASE_IMPORT_PARAMS_LEN, 0);
477         if (importParam == NULL) {
478             LOGE("Malloc for importParam failed.");
479             return HAL_ERR_BAD_ALLOC;
480         }
481     }
482 
483     importParam[idx].tag = HKS_TAG_ALGORITHM;
484     importParam[idx++].uint32Param = HKS_ALG_AES;
485     importParam[idx].tag = HKS_TAG_KEY_SIZE;
486     importParam[idx++].uint32Param = keyLen * BITS_PER_BYTE;
487     importParam[idx].tag = HKS_TAG_PADDING;
488     importParam[idx++].uint32Param = HKS_PADDING_NONE;
489     importParam[idx].tag = HKS_TAG_IS_ALLOWED_WRAP;
490     importParam[idx++].boolParam = false;
491     importParam[idx].tag = HKS_TAG_PURPOSE;
492     importParam[idx++].uint32Param = g_purposeToHksKeyPurpose[purpose];
493     importParam[idx].tag = HKS_TAG_BLOCK_MODE;
494     importParam[idx++].uint32Param = HKS_MODE_GCM;
495     importParam[idx].tag = HKS_TAG_DIGEST;
496     importParam[idx++].uint32Param = HKS_DIGEST_SHA256;
497 
498     int ret = ConstructParamSet(paramSet, importParam, idx);
499     if (ret != HAL_SUCCESS) {
500         LOGE("Construct decrypt param set failed, ret = %d.", ret);
501     }
502 
503     HcFree(importParam);
504     return ret;
505 }
506 
ImportSymmetricKey(const Uint8Buff * keyAlias,const Uint8Buff * authToken,KeyPurpose purpose,const ExtraInfo * exInfo)507 static int32_t ImportSymmetricKey(const Uint8Buff *keyAlias, const Uint8Buff *authToken, KeyPurpose purpose,
508     const ExtraInfo *exInfo)
509 {
510     int32_t ret = CheckImportSymmetricKeyParam(keyAlias, authToken);
511     if (ret != HAL_SUCCESS) {
512         return ret;
513     }
514 
515     struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
516     struct HksBlob symKeyBlob = { authToken->length, authToken->val };
517     struct HksParamSet *paramSet = NULL;
518     ret = ConstructImportSymmetricKeyParam(&paramSet, authToken->length, purpose, exInfo);
519     if (ret != HAL_SUCCESS) {
520         LOGE("construct param set failed, ret = %d", ret);
521         return ret;
522     }
523 
524     ret = HksImportKey(&keyAliasBlob, paramSet, &symKeyBlob);
525     if (ret != HKS_SUCCESS) {
526         LOGE("HksImportKey failed, ret: %d", ret);
527         HksFreeParamSet(&paramSet);
528         return ret;
529     }
530 
531     HksFreeParamSet(&paramSet);
532     return HAL_SUCCESS;
533 }
534 
BigNumExpMod(const Uint8Buff * base,const Uint8Buff * exp,const char * bigNumHex,Uint8Buff * outNum)535 static int32_t BigNumExpMod(const Uint8Buff *base, const Uint8Buff *exp, const char *bigNumHex, Uint8Buff *outNum)
536 {
537     const Uint8Buff *inParams[] = { base, exp, outNum };
538     const char *paramTags[] = { "base", "exp", "outNum" };
539     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
540     if (ret != HAL_SUCCESS) {
541         return ret;
542     }
543 
544     CHECK_PTR_RETURN_HAL_ERROR_CODE(bigNumHex, "bigNumHex");
545     uint32_t primeLen = strlen(bigNumHex) / BYTE_TO_HEX_OPER_LENGTH;
546     if ((primeLen != BIG_PRIME_LEN_384) && (primeLen != BIG_PRIME_LEN_256)) {
547         LOGE("Not support big number len %d", outNum->length);
548         return HAL_FAILED;
549     }
550     CHECK_LEN_EQUAL_RETURN(outNum->length, primeLen, "outNum->length");
551 
552     struct HksBlob baseBlob = { base->length, base->val };
553     struct HksBlob expBlob = { exp->length, exp->val };
554     struct HksBlob outNumBlob = { outNum->length, outNum->val };
555     struct HksBlob bigNumBlob = { 0, NULL };
556     bigNumBlob.size = outNum->length;
557     bigNumBlob.data = (uint8_t *)HcMalloc(bigNumBlob.size, 0);
558     if (bigNumBlob.data == NULL) {
559         LOGE("malloc bigNumBlob.data failed.");
560         return HAL_ERR_BAD_ALLOC;
561     }
562     ret = HexStringToByte(bigNumHex, bigNumBlob.data, bigNumBlob.size);
563     if (ret != HAL_SUCCESS) {
564         LOGE("HexStringToByte for bigNumHex failed.");
565         HcFree(bigNumBlob.data);
566         return ret;
567     }
568 
569     ret = HksBnExpMod(&outNumBlob, &baseBlob, &expBlob, &bigNumBlob);
570     if (ret != HKS_SUCCESS) {
571         LOGE("Huks calculate big number exp mod failed, ret = %d", ret);
572         HcFree(bigNumBlob.data);
573         return HAL_FAILED;
574     }
575     outNum->length = outNumBlob.size;
576 
577     HcFree(bigNumBlob.data);
578     return HAL_SUCCESS;
579 }
580 
CheckBigNumCompareParams(const Uint8Buff * a,const Uint8Buff * b,int * res)581 static bool CheckBigNumCompareParams(const Uint8Buff *a, const Uint8Buff *b, int *res)
582 {
583     if ((a == NULL || a->val == NULL) && (b == NULL || b->val == NULL)) {
584         *res = 0; // a = b
585         return false;
586     }
587     if ((a == NULL || a->val == NULL) && (b != NULL && b->val != NULL)) {
588         *res = 1; // a < b
589         return false;
590     }
591     if ((a != NULL && a->val != NULL) && (b == NULL || b->val == NULL)) {
592         *res = -1; // a > b
593         return false;
594     }
595     return true;
596 }
597 
BigNumCompare(const Uint8Buff * a,const Uint8Buff * b)598 static int32_t BigNumCompare(const Uint8Buff *a, const Uint8Buff *b)
599 {
600     int res = 0;
601     if (!CheckBigNumCompareParams(a, b, &res)) {
602         return res;
603     }
604     const uint8_t *tmpA = a->val;
605     const uint8_t *tmpB = b->val;
606     uint32_t len = a->length;
607     if (a->length < b->length) {
608         for (uint32_t i = 0; i < b->length - a->length; i++) {
609             if (b->val[i] > 0) {
610                 return 1; // a < b
611             }
612         }
613         tmpA = a->val;
614         tmpB = b->val + b->length - a->length;
615         len = a->length;
616     }
617     if (a->length > b->length) {
618         for (uint32_t i = 0; i < a->length - b->length; i++) {
619             if (a->val[i] > 0) {
620                 return -1; // a > b
621             }
622         }
623         tmpA = a->val + a->length - b->length;
624         tmpB = b->val;
625         len = b->length;
626     }
627     for (uint32_t i = 0; i < len; i++) {
628         if (*(tmpA + i) > *(tmpB + i)) {
629             return -1; // a > b
630         }
631         if (*(tmpA + i) < *(tmpB + i)) {
632             return 1; // a < b
633         }
634     }
635     return 0; // a == b
636 }
637 
CheckDlPublicKey(const Uint8Buff * key,const char * primeHex)638 static bool CheckDlPublicKey(const Uint8Buff *key, const char *primeHex)
639 {
640     if (key == NULL || key->val == NULL || primeHex == NULL) {
641         LOGE("Params is null.");
642         return false;
643     }
644     uint8_t min = 1;
645 
646     uint32_t innerKeyLen = HcStrlen(primeHex) / BYTE_TO_HEX_OPER_LENGTH;
647     if (key->length > innerKeyLen) {
648         LOGE("Key length > prime number length.");
649         return false;
650     }
651     uint8_t *primeByte = (uint8_t *)HcMalloc(innerKeyLen, 0);
652     if (primeByte == NULL) {
653         LOGE("Malloc for primeByte failed.");
654         return false;
655     }
656     if (HexStringToByte(primeHex, primeByte, innerKeyLen) != HAL_SUCCESS) {
657         LOGE("Convert prime number from hex string to byte failed.");
658         HcFree(primeByte);
659         return false;
660     }
661     /*
662      * P - 1, since the last byte of large prime number must be greater than 1,
663      * needn't to think about borrowing forward
664      */
665     primeByte[innerKeyLen - 1] -= 1;
666 
667     Uint8Buff minBuff = { &min, sizeof(uint8_t) };
668     if (BigNumCompare(key, &minBuff) >= 0) {
669         LOGE("Pubkey is invalid, key <= 1.");
670         HcFree(primeByte);
671         return false;
672     }
673 
674     Uint8Buff primeBuff = { primeByte, innerKeyLen };
675     if (BigNumCompare(key, &primeBuff) <= 0) {
676         LOGE("Pubkey is invalid, key >= p - 1.");
677         HcFree(primeByte);
678         return false;
679     }
680 
681     HcFree(primeByte);
682     return true;
683 }
684 
HashToPoint(const Uint8Buff * hash,Algorithm algo,Uint8Buff * outEcPoint)685 static int32_t HashToPoint(const Uint8Buff *hash, Algorithm algo, Uint8Buff *outEcPoint)
686 {
687     (void)hash;
688     (void)algo;
689     (void)outEcPoint;
690     return HAL_ERR_NOT_SUPPORTED;
691 }
692 
AgreeSharedSecretWithStorage(const KeyBuff * priKey,const KeyBuff * pubKey,Algorithm algo,uint32_t sharedKeyLen,const Uint8Buff * sharedKeyAlias)693 static int32_t AgreeSharedSecretWithStorage(const KeyBuff *priKey, const KeyBuff *pubKey, Algorithm algo,
694     uint32_t sharedKeyLen, const Uint8Buff *sharedKeyAlias)
695 {
696     (void)priKey;
697     (void)pubKey;
698     (void)algo;
699     (void)sharedKeyLen;
700     (void)sharedKeyAlias;
701     return HAL_ERR_NOT_SUPPORTED;
702 }
703 
AgreeSharedSecret(const KeyBuff * priKey,const KeyBuff * pubKey,Algorithm algo,Uint8Buff * sharedKey)704 static int32_t AgreeSharedSecret(const KeyBuff *priKey, const KeyBuff *pubKey, Algorithm algo, Uint8Buff *sharedKey)
705 {
706     (void)priKey;
707     (void)pubKey;
708     (void)algo;
709     (void)sharedKey;
710     return HAL_ERR_NOT_SUPPORTED;
711 }
712 
GenerateKeyPairWithStorage(const Uint8Buff * keyAlias,uint32_t keyLen,Algorithm algo,KeyPurpose purpose,const ExtraInfo * exInfo)713 static int32_t GenerateKeyPairWithStorage(const Uint8Buff *keyAlias, uint32_t keyLen, Algorithm algo,
714     KeyPurpose purpose, const ExtraInfo *exInfo)
715 {
716     (void)keyAlias;
717     (void)keyLen;
718     (void)algo;
719     (void)purpose;
720     (void)exInfo;
721     return HAL_ERR_NOT_SUPPORTED;
722 }
723 
GenerateKeyPair(Algorithm algo,Uint8Buff * outPriKey,Uint8Buff * outPubKey)724 static int32_t GenerateKeyPair(Algorithm algo, Uint8Buff *outPriKey, Uint8Buff *outPubKey)
725 {
726     (void)algo;
727     (void)outPriKey;
728     (void)outPubKey;
729     return HAL_ERR_NOT_SUPPORTED;
730 }
731 
ExportPublicKey(const Uint8Buff * keyAlias,Uint8Buff * outPubKey)732 static int32_t ExportPublicKey(const Uint8Buff *keyAlias, Uint8Buff *outPubKey)
733 {
734     (void)keyAlias;
735     (void)outPubKey;
736     return HAL_ERR_NOT_SUPPORTED;
737 }
738 
Sign(const Uint8Buff * keyAlias,const Uint8Buff * message,Algorithm algo,Uint8Buff * outSignature,bool isAlias)739 static int32_t Sign(const Uint8Buff *keyAlias, const Uint8Buff *message, Algorithm algo,
740     Uint8Buff *outSignature, bool isAlias)
741 {
742     (void)keyAlias;
743     (void)message;
744     (void)algo;
745     (void)outSignature;
746     (void)isAlias;
747     return HAL_ERR_NOT_SUPPORTED;
748 }
749 
Verify(const Uint8Buff * key,const Uint8Buff * message,Algorithm algo,const Uint8Buff * signature,bool isAlias)750 static int32_t Verify(const Uint8Buff *key, const Uint8Buff *message, Algorithm algo,
751     const Uint8Buff *signature, bool isAlias)
752 {
753     (void)key;
754     (void)message;
755     (void)algo;
756     (void)signature;
757     (void)isAlias;
758     return HAL_ERR_NOT_SUPPORTED;
759 }
760 
ImportPublicKey(const Uint8Buff * keyAlias,const Uint8Buff * pubKey,Algorithm algo,const ExtraInfo * exInfo)761 static int32_t ImportPublicKey(const Uint8Buff *keyAlias, const Uint8Buff *pubKey, Algorithm algo,
762     const ExtraInfo *exInfo)
763 {
764     (void)keyAlias;
765     (void)pubKey;
766     (void)algo;
767     (void)exInfo;
768     return HAL_ERR_NOT_SUPPORTED;
769 }
770 
CheckEcPublicKey(const Uint8Buff * pubKey,Algorithm algo)771 static bool CheckEcPublicKey(const Uint8Buff *pubKey, Algorithm algo)
772 {
773     (void)pubKey;
774     (void)algo;
775     return true;
776 }
777 
778 static const AlgLoader g_huksLoader = {
779     .initAlg = InitHks,
780     .sha256 = Sha256,
781     .generateRandom = GenerateRandom,
782     .computeHmac = ComputeHmac,
783     .computeHkdf = ComputeHkdf,
784     .importSymmetricKey = ImportSymmetricKey,
785     .checkKeyExist = CheckKeyExist,
786     .deleteKey = DeleteKey,
787     .aesGcmEncrypt = AesGcmEncrypt,
788     .aesGcmDecrypt = AesGcmDecrypt,
789     .hashToPoint = HashToPoint,
790     .agreeSharedSecretWithStorage = AgreeSharedSecretWithStorage,
791     .agreeSharedSecret = AgreeSharedSecret,
792     .bigNumExpMod = BigNumExpMod,
793     .generateKeyPairWithStorage = GenerateKeyPairWithStorage,
794     .generateKeyPair = GenerateKeyPair,
795     .exportPublicKey = ExportPublicKey,
796     .sign = Sign,
797     .verify = Verify,
798     .importPublicKey = ImportPublicKey,
799     .checkDlPublicKey = CheckDlPublicKey,
800     .checkEcPublicKey = CheckEcPublicKey,
801     .bigNumCompare = BigNumCompare
802 };
803 
GetRealLoaderInstance()804 const AlgLoader *GetRealLoaderInstance()
805 {
806     return &g_huksLoader;
807 }