• 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 "hc_log.h"
18 #include "hks_api.h"
19 #include "hks_param.h"
20 #include "hks_type.h"
21 #include "mbedtls_ec_adapter.h"
22 #include "string_util.h"
23 
24 static enum HksKeyAlg g_algToHksAlgorithm[] = {
25     HKS_ALG_ED25519,
26     HKS_ALG_X25519,
27     HKS_ALG_ECC
28 };
29 
BaseCheckParams(const Uint8Buff ** inParams,const char ** paramTags,uint32_t len)30 static int32_t BaseCheckParams(const Uint8Buff **inParams, const char **paramTags, uint32_t len)
31 {
32     for (uint32_t i = 0; i < len; i++) {
33         CHECK_PTR_RETURN_HAL_ERROR_CODE(inParams[i], paramTags[i]);
34         CHECK_PTR_RETURN_HAL_ERROR_CODE(inParams[i]->val, paramTags[i]);
35         CHECK_LEN_ZERO_RETURN_ERROR_CODE(inParams[i]->length, paramTags[i]);
36     }
37     return HAL_SUCCESS;
38 }
39 
ConstructParamSet(struct HksParamSet ** out,const struct HksParam * inParam,const uint32_t inParamNum)40 static int32_t ConstructParamSet(struct HksParamSet **out, const struct HksParam *inParam,
41     const uint32_t inParamNum)
42 {
43     struct HksParamSet *paramSet = NULL;
44     int32_t ret = HksInitParamSet(&paramSet);
45     if (ret != HKS_SUCCESS) {
46         LOGE("init param set failed, ret = %d", ret);
47         return HAL_ERR_INIT_PARAM_SET_FAILED;
48     }
49 
50     ret = HksAddParams(paramSet, inParam, inParamNum);
51     if (ret != HKS_SUCCESS) {
52         LOGE("add param failed, ret = %d", ret);
53         HksFreeParamSet(&paramSet);
54         return HAL_ERR_ADD_PARAM_FAILED;
55     }
56 
57     ret = HksBuildParamSet(&paramSet);
58     if (ret != HKS_SUCCESS) {
59         LOGE("build param set failed, ret = %d", ret);
60         HksFreeParamSet(&paramSet);
61         return HAL_ERR_BUILD_PARAM_SET_FAILED;
62     }
63 
64     *out = paramSet;
65     return HAL_SUCCESS;
66 }
67 
InitHks(void)68 static int32_t InitHks(void)
69 {
70     return HksInitialize();
71 }
72 
Sha256(const Uint8Buff * message,Uint8Buff * hash)73 static int32_t Sha256(const Uint8Buff *message, Uint8Buff *hash)
74 {
75     CHECK_PTR_RETURN_HAL_ERROR_CODE(message, "message");
76     CHECK_PTR_RETURN_HAL_ERROR_CODE(message->val, "message->val");
77     CHECK_LEN_ZERO_RETURN_ERROR_CODE(message->length, "message->length");
78 
79     CHECK_PTR_RETURN_HAL_ERROR_CODE(hash, "hash");
80     CHECK_PTR_RETURN_HAL_ERROR_CODE(hash->val, "hash->val");
81     CHECK_LEN_EQUAL_RETURN(hash->length, SHA256_LEN, "hash->length");
82 
83     struct HksBlob srcBlob = { message->length, message->val };
84     struct HksBlob hashBlob = { hash->length, hash->val };
85     struct HksParamSet *paramSet = NULL;
86     struct HksParam digestParam[] = {
87         {
88             .tag = HKS_TAG_DIGEST,
89             .uint32Param = HKS_DIGEST_SHA256
90         }
91     };
92     int32_t ret = ConstructParamSet(&paramSet, digestParam, CAL_ARRAY_SIZE(digestParam));
93     if (ret != HAL_SUCCESS) {
94         LOGE("construct param set failed, ret = %d", ret);
95         return ret;
96     }
97 
98     ret = HksHash(paramSet, &srcBlob, &hashBlob);
99     if (ret != HKS_SUCCESS || hashBlob.size != SHA256_LEN) {
100         HksFreeParamSet(&paramSet);
101         return HAL_FAILED;
102     }
103 
104     HksFreeParamSet(&paramSet);
105     return HAL_SUCCESS;
106 }
107 
GenerateRandom(Uint8Buff * rand)108 static int32_t GenerateRandom(Uint8Buff *rand)
109 {
110     CHECK_PTR_RETURN_HAL_ERROR_CODE(rand, "rand");
111     CHECK_PTR_RETURN_HAL_ERROR_CODE(rand->val, "rand->val");
112     CHECK_LEN_ZERO_RETURN_ERROR_CODE(rand->length, "rand->length");
113 
114     struct HksBlob randBlob = { rand->length, rand->val };
115     int32_t ret = HksGenerateRandom(NULL, &randBlob);
116     if (ret != HKS_SUCCESS) {
117         LOGE("Generate random failed, ret: %d", ret);
118         return HAL_FAILED;
119     }
120 
121     return HAL_SUCCESS;
122 }
123 
CheckKeyExist(const Uint8Buff * keyAlias)124 static int32_t CheckKeyExist(const Uint8Buff *keyAlias)
125 {
126     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias, "keyAlias");
127     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias->val, "keyAlias->val");
128     CHECK_LEN_ZERO_RETURN_ERROR_CODE(keyAlias->length, "keyAlias->length");
129 
130     struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
131     int32_t ret = HksKeyExist(&keyAliasBlob, NULL);
132     if (ret != HKS_SUCCESS) {
133         LOGI("Hks check key exist or not, ret = %d", ret);
134         return HAL_FAILED;
135     }
136 
137     return HAL_SUCCESS;
138 }
139 
DeleteKey(const Uint8Buff * keyAlias)140 static int32_t DeleteKey(const Uint8Buff *keyAlias)
141 {
142     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias, "keyAlias");
143     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias->val, "keyAlias->val");
144     CHECK_LEN_ZERO_RETURN_ERROR_CODE(keyAlias->length, "keyAlias->length");
145 
146     struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
147     int32_t ret = HksDeleteKey(&keyAliasBlob, NULL);
148     if (ret == HKS_ERROR_NOT_EXIST) {
149         LOGI("Key not exists.");
150         return HAL_SUCCESS;
151     }
152     if (ret != HKS_SUCCESS) {
153         LOGE("Delete key failed, ret = %d", ret);
154         return HAL_FAILED;
155     }
156 
157     return HAL_SUCCESS;
158 }
159 
ComputeHmac(const Uint8Buff * key,const Uint8Buff * message,Uint8Buff * outHmac,bool isAlias)160 static int32_t ComputeHmac(const Uint8Buff *key, const Uint8Buff *message, Uint8Buff *outHmac, bool isAlias)
161 {
162     const Uint8Buff *inParams[] = { key, message, outHmac };
163     const char *paramTags[] = {"key", "message", "outHmac"};
164     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
165     if (ret != HAL_SUCCESS) {
166         return ret;
167     }
168     CHECK_LEN_EQUAL_RETURN(outHmac->length, HMAC_LEN, "outHmac->length");
169 
170     struct HksBlob keyBlob = { key->length, key->val };
171     struct HksBlob srcBlob = { message->length, message->val };
172     struct HksBlob hmacBlob = { outHmac->length, outHmac->val };
173     struct HksParamSet *paramSet = NULL;
174     struct HksParam hmacParam[] = {
175         {
176             .tag = HKS_TAG_PURPOSE,
177             .uint32Param = HKS_KEY_PURPOSE_MAC
178         }, {
179             .tag = HKS_TAG_DIGEST,
180             .uint32Param = HKS_DIGEST_SHA256
181         }, {
182             .tag = HKS_TAG_IS_KEY_ALIAS,
183             .boolParam = isAlias
184         }
185     };
186     ret = ConstructParamSet(&paramSet, hmacParam, CAL_ARRAY_SIZE(hmacParam));
187     if (ret != HAL_SUCCESS) {
188         LOGE("construct param set failed, ret = %d", ret);
189         return ret;
190     }
191 
192     ret = HksMac(&keyBlob, paramSet, &srcBlob, &hmacBlob);
193     if (ret != HKS_SUCCESS  || hmacBlob.size != HMAC_LEN) {
194         LOGE("Hmac failed, ret: %d", ret);
195         HksFreeParamSet(&paramSet);
196         return HAL_FAILED;
197     }
198 
199     HksFreeParamSet(&paramSet);
200     return HAL_SUCCESS;
201 }
202 
ComputeHkdf(const Uint8Buff * baseKey,const Uint8Buff * salt,const Uint8Buff * keyInfo,Uint8Buff * outHkdf,bool isAlias)203 static int32_t ComputeHkdf(const Uint8Buff *baseKey, const Uint8Buff *salt, const Uint8Buff *keyInfo,
204     Uint8Buff *outHkdf, bool isAlias)
205 {
206     const Uint8Buff *inParams[] = { baseKey, salt, outHkdf };
207     const char *paramTags[] = { "baseKey", "salt", "outHkdf" };
208     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
209     if (ret != HAL_SUCCESS) {
210         return ret;
211     }
212 
213     struct HksBlob srcKeyBlob = { baseKey->length, baseKey->val };
214     struct HksBlob saltBlob = { salt->length, salt->val };
215     struct HksBlob keyInfoBlob = { 0, NULL };
216     if (keyInfo != NULL) {
217         keyInfoBlob.size = keyInfo->length;
218         keyInfoBlob.data = keyInfo->val;
219     }
220     struct HksBlob derivedKeyBlob = { outHkdf->length, outHkdf->val };
221 
222     struct HksParamSet *paramSet = NULL;
223     struct HksParam hkdfParam[] = {
224         {
225             .tag = HKS_TAG_PURPOSE,
226             .uint32Param = HKS_KEY_PURPOSE_DERIVE
227         }, {
228             .tag = HKS_TAG_ALGORITHM,
229             .uint32Param = HKS_ALG_HKDF
230         }, {
231             .tag = HKS_TAG_DIGEST,
232             .uint32Param = HKS_DIGEST_SHA256
233         }, {
234             .tag = HKS_TAG_SALT,
235             .blob = saltBlob
236         }, {
237             .tag = HKS_TAG_INFO,
238             .blob = keyInfoBlob
239         }, {
240             .tag = HKS_TAG_IS_KEY_ALIAS,
241             .boolParam = isAlias
242         }
243     };
244 
245     ret = ConstructParamSet(&paramSet, hkdfParam, CAL_ARRAY_SIZE(hkdfParam));
246     if (ret != HAL_SUCCESS) {
247         return ret;
248     }
249 
250     ret = HksDeriveKey(paramSet, &srcKeyBlob, &derivedKeyBlob);
251     if (ret != HKS_SUCCESS) {
252         LOGE("Key derivation failed, ret: %d", ret);
253         HksFreeParamSet(&paramSet);
254         return HAL_FAILED;
255     }
256 
257     HksFreeParamSet(&paramSet);
258     return HAL_SUCCESS;
259 }
260 
CheckAesGcmEncryptParam(const Uint8Buff * key,const Uint8Buff * plain,const GcmParam * encryptInfo,Uint8Buff * outCipher)261 static int32_t CheckAesGcmEncryptParam(const Uint8Buff *key, const Uint8Buff *plain, const GcmParam *encryptInfo,
262     Uint8Buff *outCipher)
263 {
264     const Uint8Buff *inParams[] = { key, plain, outCipher };
265     const char* paramTags[] = { "key", "plain", "outCipher" };
266     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
267     if (ret != HAL_SUCCESS) {
268         return ret;
269     }
270 
271     CHECK_PTR_RETURN_HAL_ERROR_CODE(encryptInfo, "encryptInfo");
272     CHECK_PTR_RETURN_HAL_ERROR_CODE(encryptInfo->aad, "aad");
273     CHECK_LEN_ZERO_RETURN_ERROR_CODE(encryptInfo->aadLen, "aadLen");
274     CHECK_PTR_RETURN_HAL_ERROR_CODE(encryptInfo->nonce, "nonce");
275     CHECK_LEN_LOWER_RETURN(encryptInfo->nonceLen, HKS_AE_NONCE_LEN, "nonceLen");
276     CHECK_LEN_LOWER_RETURN(outCipher->length, plain->length + HKS_AE_TAG_LEN, "outCipher");
277 
278     return HAL_SUCCESS;
279 }
280 
AesGcmEncrypt(const Uint8Buff * key,const Uint8Buff * plain,const GcmParam * encryptInfo,bool isAlias,Uint8Buff * outCipher)281 static int32_t AesGcmEncrypt(const Uint8Buff *key, const Uint8Buff *plain,
282     const GcmParam *encryptInfo, bool isAlias, Uint8Buff *outCipher)
283 {
284     int32_t ret = CheckAesGcmEncryptParam(key, plain, encryptInfo, outCipher);
285     if (ret != HAL_SUCCESS) {
286         return ret;
287     }
288 
289     struct HksBlob keyBlob = { key->length, key->val };
290     struct HksBlob plainBlob = { plain->length, plain->val };
291     struct HksBlob cipherBlob = { outCipher->length, outCipher->val };
292 
293     struct HksParamSet *paramSet = NULL;
294     struct HksParam encryptParam[] = {
295         {
296             .tag = HKS_TAG_PURPOSE,
297             .uint32Param = HKS_KEY_PURPOSE_ENCRYPT
298         }, {
299             .tag = HKS_TAG_ALGORITHM,
300             .uint32Param = HKS_ALG_AES
301         }, {
302             .tag = HKS_TAG_BLOCK_MODE,
303             .uint32Param = HKS_MODE_GCM
304         }, {
305             .tag = HKS_TAG_PADDING,
306             .uint32Param = HKS_PADDING_NONE
307         }, {
308             .tag = HKS_TAG_NONCE,
309             .blob = { encryptInfo->nonceLen, encryptInfo->nonce }
310         }, {
311             .tag = HKS_TAG_ASSOCIATED_DATA,
312             .blob = { encryptInfo->aadLen, encryptInfo->aad }
313         }, {
314             .tag = HKS_TAG_IS_KEY_ALIAS,
315             .boolParam = isAlias
316         }
317     };
318 
319     ret = ConstructParamSet(&paramSet, encryptParam, CAL_ARRAY_SIZE(encryptParam));
320     if (ret != HAL_SUCCESS) {
321         LOGE("construct param set failed, ret = %d", ret);
322         return ret;
323     }
324 
325     ret = HksEncrypt(&keyBlob, paramSet, &plainBlob, &cipherBlob);
326     if (ret != HKS_SUCCESS) {
327         LOGE("Aes-gcm encrypt failed, ret: %d", ret);
328         HksFreeParamSet(&paramSet);
329         return HAL_FAILED;
330     }
331 
332     HksFreeParamSet(&paramSet);
333     return HAL_SUCCESS;
334 }
335 
CheckAesGcmDecryptParam(const Uint8Buff * key,const Uint8Buff * cipher,const GcmParam * decryptInfo,Uint8Buff * outPlain)336 static int32_t CheckAesGcmDecryptParam(const Uint8Buff *key, const Uint8Buff *cipher, const GcmParam *decryptInfo,
337     Uint8Buff *outPlain)
338 {
339     const Uint8Buff *inParams[] = { key, cipher, outPlain };
340     const char *paramTags[] = { "key", "cipher", "outPlain" };
341     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
342     if (ret != HAL_SUCCESS) {
343         return ret;
344     }
345 
346     CHECK_PTR_RETURN_HAL_ERROR_CODE(decryptInfo, "decryptInfo");
347     CHECK_PTR_RETURN_HAL_ERROR_CODE(decryptInfo->aad, "aad");
348     CHECK_LEN_ZERO_RETURN_ERROR_CODE(decryptInfo->aadLen, "aadLen");
349     CHECK_PTR_RETURN_HAL_ERROR_CODE(decryptInfo->nonce, "nonce");
350     CHECK_LEN_LOWER_RETURN(decryptInfo->nonceLen, HKS_AE_NONCE_LEN, "nonceLen");
351     CHECK_LEN_LOWER_RETURN(outPlain->length, cipher->length - HKS_AE_TAG_LEN, "outPlain");
352 
353     return HAL_SUCCESS;
354 }
355 
AesGcmDecrypt(const Uint8Buff * key,const Uint8Buff * cipher,const GcmParam * decryptInfo,bool isAlias,Uint8Buff * outPlain)356 static int32_t AesGcmDecrypt(const Uint8Buff *key, const Uint8Buff *cipher,
357     const GcmParam *decryptInfo, bool isAlias, Uint8Buff *outPlain)
358 {
359     int32_t ret = CheckAesGcmDecryptParam(key, cipher, decryptInfo, outPlain);
360     if (ret != HAL_SUCCESS) {
361         return ret;
362     }
363 
364     struct HksBlob keyBlob = { key->length, key->val };
365     struct HksBlob cipherBlob = { cipher->length, cipher->val };
366     struct HksBlob plainBlob = { outPlain->length, outPlain->val };
367 
368     struct HksParamSet *paramSet = NULL;
369     struct HksParam decryptParam[] = {
370         {
371             .tag = HKS_TAG_PURPOSE,
372             .uint32Param = HKS_KEY_PURPOSE_DECRYPT
373         }, {
374             .tag = HKS_TAG_ALGORITHM,
375             .uint32Param = HKS_ALG_AES
376         }, {
377             .tag = HKS_TAG_BLOCK_MODE,
378             .uint32Param = HKS_MODE_GCM
379         }, {
380             .tag = HKS_TAG_PADDING,
381             .uint32Param = HKS_PADDING_NONE
382         }, {
383             .tag = HKS_TAG_NONCE,
384             .blob = { decryptInfo->nonceLen, decryptInfo->nonce }
385         }, {
386             .tag = HKS_TAG_ASSOCIATED_DATA,
387             .blob = { decryptInfo->aadLen, decryptInfo->aad }
388         }, {
389             .tag = HKS_TAG_IS_KEY_ALIAS,
390             .boolParam = isAlias
391         }
392     };
393 
394     ret = ConstructParamSet(&paramSet, decryptParam, CAL_ARRAY_SIZE(decryptParam));
395     if (ret != HAL_SUCCESS) {
396         LOGE("construct param set failed, ret = %d", ret);
397         return ret;
398     }
399 
400     ret = HksDecrypt(&keyBlob, paramSet, &cipherBlob, &plainBlob);
401     if (ret != HKS_SUCCESS) {
402         LOGE("Aes-gcm decrypt failed, ret: %d", ret);
403         HksFreeParamSet(&paramSet);
404         return HAL_FAILED;
405     }
406 
407     HksFreeParamSet(&paramSet);
408     return HAL_SUCCESS;
409 }
410 
HashToPoint(const Uint8Buff * hash,Algorithm algo,Uint8Buff * outEcPoint)411 static int32_t HashToPoint(const Uint8Buff *hash, Algorithm algo, Uint8Buff *outEcPoint)
412 {
413     CHECK_PTR_RETURN_HAL_ERROR_CODE(hash, "hash");
414     CHECK_PTR_RETURN_HAL_ERROR_CODE(hash->val, "hash->va");
415     CHECK_LEN_EQUAL_RETURN(hash->length, SHA256_LEN, "hash->length");
416     CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint, "outEcPoint");
417     CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint->val, "outEcPoint->va");
418     CHECK_LEN_EQUAL_RETURN(outEcPoint->length, SHA256_LEN, "outEcPoint->length");
419 
420     if (algo != X25519) {
421         LOGE("Invalid algo: %d.", algo);
422         return HAL_ERR_INVALID_PARAM;
423     }
424 
425     int32_t ret = MbedtlsHashToPoint(hash, outEcPoint);
426     if (ret != 0) {
427         LOGE("Hks hashToPoint failed, ret: %d", ret);
428         return HAL_FAILED;
429     }
430 
431     return HAL_SUCCESS;
432 }
433 
ConstructAgreeWithStorageParams(struct HksParamSet ** paramSet,uint32_t keyLen,Algorithm algo,const KeyBuff * priKey,const KeyBuff * pubKey)434 static int32_t ConstructAgreeWithStorageParams(struct HksParamSet **paramSet, uint32_t keyLen, Algorithm algo,
435     const KeyBuff *priKey, const KeyBuff *pubKey)
436 {
437     struct HksBlob priKeyBlob = { priKey->keyLen, priKey->key };
438     struct HksBlob pubKeyBlob = { pubKey->keyLen, pubKey->key };
439     struct HksParam agreeParam[] = {
440         {
441             .tag = HKS_TAG_ALGORITHM,
442             .uint32Param = HKS_ALG_AES
443         }, {
444             .tag = HKS_TAG_KEY_SIZE,
445             .uint32Param = keyLen * BITS_PER_BYTE
446         }, {
447             .tag = HKS_TAG_PURPOSE,
448             .uint32Param = HKS_KEY_PURPOSE_DERIVE
449         }, {
450             .tag = HKS_TAG_DIGEST,
451             .uint32Param = HKS_DIGEST_SHA256
452         }, {
453             .tag = HKS_TAG_KEY_GENERATE_TYPE,
454             .uint32Param = HKS_KEY_GENERATE_TYPE_AGREE
455         }, {
456             .tag = HKS_TAG_AGREE_ALG,
457             .uint32Param = g_algToHksAlgorithm[algo]
458         }, {
459             .tag = HKS_TAG_AGREE_PRIVATE_KEY_ALIAS,
460             .blob = priKeyBlob
461         }, {
462             .tag = HKS_TAG_AGREE_PUBLIC_KEY,
463             .blob = pubKeyBlob
464         }, {
465             .tag = HKS_TAG_AGREE_PUBLIC_KEY_IS_KEY_ALIAS,
466             .boolParam = pubKey->isAlias
467         }
468     };
469 
470     int32_t ret = ConstructParamSet(paramSet, agreeParam, CAL_ARRAY_SIZE(agreeParam));
471     if (ret != HAL_SUCCESS) {
472         LOGE("Construct param set failed, ret = %d", ret);
473         return ret;
474     }
475     return ret;
476 }
477 
AgreeSharedSecretWithStorage(const KeyBuff * priKey,const KeyBuff * pubKey,Algorithm algo,uint32_t sharedKeyLen,const Uint8Buff * sharedKeyAlias)478 static int32_t AgreeSharedSecretWithStorage(const KeyBuff *priKey, const KeyBuff *pubKey, Algorithm algo,
479     uint32_t sharedKeyLen, const Uint8Buff *sharedKeyAlias)
480 {
481     CHECK_PTR_RETURN_HAL_ERROR_CODE(priKey, "priKey");
482     CHECK_PTR_RETURN_HAL_ERROR_CODE(priKey->key, "priKey->key");
483     CHECK_LEN_ZERO_RETURN_ERROR_CODE(priKey->keyLen, "priKey->keyLen");
484     CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey, "pubKey");
485     CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey->key, "pubKey->key");
486     CHECK_LEN_ZERO_RETURN_ERROR_CODE(pubKey->keyLen, "pubKey->keyLen");
487     CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKeyAlias, "sharedKeyAlias");
488     CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKeyAlias->val, "sharedKeyAlias->val");
489     CHECK_LEN_ZERO_RETURN_ERROR_CODE(sharedKeyAlias->length, "sharedKeyAlias->length");
490     CHECK_LEN_ZERO_RETURN_ERROR_CODE(sharedKeyLen, "sharedKeyLen");
491 
492     struct HksBlob sharedKeyAliasBlob = { sharedKeyAlias->length, sharedKeyAlias->val };
493     struct HksParamSet *paramSet = NULL;
494     int32_t ret = ConstructAgreeWithStorageParams(&paramSet, sharedKeyLen, algo, priKey, pubKey);
495     if (ret != HAL_SUCCESS) {
496         return ret;
497     }
498 
499     ret = HksGenerateKey(&sharedKeyAliasBlob, paramSet, NULL);
500     if (ret != HKS_SUCCESS) {
501         LOGE("Hks agree key with storage failed, ret = %d", ret);
502         HksFreeParamSet(&paramSet);
503         return HAL_FAILED;
504     }
505 
506     HksFreeParamSet(&paramSet);
507     return HAL_SUCCESS;
508 }
509 
AgreeSharedSecret(const KeyBuff * priKey,const KeyBuff * pubKey,Algorithm algo,Uint8Buff * sharedKey)510 static int32_t AgreeSharedSecret(const KeyBuff *priKey, const KeyBuff *pubKey, Algorithm algo, Uint8Buff *sharedKey)
511 {
512     CHECK_PTR_RETURN_HAL_ERROR_CODE(priKey, "priKey");
513     CHECK_PTR_RETURN_HAL_ERROR_CODE(priKey->key, "priKey->key");
514     CHECK_LEN_ZERO_RETURN_ERROR_CODE(priKey->keyLen, "priKey->keyLen");
515     CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey, "pubKey");
516     CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey->key, "pubKey->key");
517     CHECK_LEN_ZERO_RETURN_ERROR_CODE(pubKey->keyLen, "pubKey->keyLen");
518     CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKey, "sharedKey");
519     CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKey->val, "sharedKey->val");
520     CHECK_LEN_ZERO_RETURN_ERROR_CODE(sharedKey->length, "sharedKey->length");
521 
522     struct HksBlob priKeyBlob = { priKey->keyLen, priKey->key };
523     struct HksBlob pubKeyBlob = { pubKey->keyLen, pubKey->key };
524     struct HksBlob sharedKeyBlob = { sharedKey->length, sharedKey->val };
525 
526     struct HksParamSet *paramSet = NULL;
527     struct HksParam agreeParam[] = {
528         {
529             .tag = HKS_TAG_ALGORITHM,
530             .uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_X25519 now
531         }, {
532             .tag = HKS_TAG_KEY_SIZE,
533             .uint32Param = sharedKey->length * BITS_PER_BYTE
534         }, {
535             .tag = HKS_TAG_IS_KEY_ALIAS,
536             .boolParam = priKey->isAlias
537         }
538     };
539 
540     int32_t ret = ConstructParamSet(&paramSet, agreeParam, CAL_ARRAY_SIZE(agreeParam));
541     if (ret != HAL_SUCCESS) {
542         LOGE("Construct param set failed, ret = %d", ret);
543         return ret;
544     }
545 
546     ret = HksAgreeKey(paramSet, &priKeyBlob, &pubKeyBlob, &sharedKeyBlob);
547     if (ret != HKS_SUCCESS) {
548         LOGE("Agree key failed, ret = %d", ret);
549         HksFreeParamSet(&paramSet);
550         return HAL_FAILED;
551     }
552 
553     HksFreeParamSet(&paramSet);
554     return HAL_SUCCESS;
555 }
556 
BigNumExpMod(const Uint8Buff * base,const Uint8Buff * exp,const char * bigNumHex,Uint8Buff * outNum)557 static int32_t BigNumExpMod(const Uint8Buff *base, const Uint8Buff *exp, const char *bigNumHex, Uint8Buff *outNum)
558 {
559     const Uint8Buff *inParams[] = { base, exp, outNum };
560     const char *paramTags[] = { "base", "exp", "outNum" };
561     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
562     if (ret != HAL_SUCCESS) {
563         return ret;
564     }
565 
566     CHECK_PTR_RETURN_HAL_ERROR_CODE(bigNumHex, "bigNumHex");
567     uint32_t primeLen = strlen(bigNumHex) / BYTE_TO_HEX_OPER_LENGTH;
568     if ((primeLen != BIG_PRIME_LEN_384) && (primeLen != BIG_PRIME_LEN_256)) {
569         LOGE("Not support big number len %d", outNum->length);
570         return HAL_FAILED;
571     }
572     CHECK_LEN_EQUAL_RETURN(outNum->length, primeLen, "outNum->length");
573 
574     struct HksBlob baseBlob = { base->length, base->val };
575     struct HksBlob expBlob = { exp->length, exp->val };
576     struct HksBlob outNumBlob = { outNum->length, outNum->val };
577     struct HksBlob bigNumBlob = { 0, NULL };
578     bigNumBlob.size = outNum->length;
579     bigNumBlob.data = (uint8_t *)HcMalloc(bigNumBlob.size, 0);
580     if (bigNumBlob.data == NULL) {
581         LOGE("malloc bigNumBlob.data failed.");
582         return HAL_ERR_BAD_ALLOC;
583     }
584     ret = HexStringToByte(bigNumHex, bigNumBlob.data, bigNumBlob.size);
585     if (ret != HAL_SUCCESS) {
586         LOGE("HexStringToByte for bigNumHex failed.");
587         HcFree(bigNumBlob.data);
588         return ret;
589     }
590 
591     ret = HksBnExpMod(&outNumBlob, &baseBlob, &expBlob, &bigNumBlob);
592     if (ret != HKS_SUCCESS) {
593         LOGE("Huks calculate big number exp mod failed, ret = %d", ret);
594         HcFree(bigNumBlob.data);
595         return HAL_FAILED;
596     }
597     outNum->length = outNumBlob.size;
598 
599     HcFree(bigNumBlob.data);
600     return HAL_SUCCESS;
601 }
602 
ConstructGenerateKeyPairWithStorageParams(struct HksParamSet ** paramSet,Algorithm algo,uint32_t keyLen,const struct HksBlob * authIdBlob)603 static int32_t ConstructGenerateKeyPairWithStorageParams(struct HksParamSet **paramSet, Algorithm algo,
604     uint32_t keyLen, const struct HksBlob *authIdBlob)
605 {
606     struct HksParam keyParam[] = {
607         {
608             .tag = HKS_TAG_ALGORITHM,
609             .uint32Param = g_algToHksAlgorithm[algo]
610         }, {
611             .tag = HKS_TAG_KEY_STORAGE_FLAG,
612             .uint32Param = HKS_STORAGE_PERSISTENT
613         }, {
614             .tag = HKS_TAG_PURPOSE,
615             .uint32Param = HKS_KEY_PURPOSE_SIGN | HKS_KEY_PURPOSE_VERIFY
616         }, {
617             .tag = HKS_TAG_KEY_SIZE,
618             .uint32Param = keyLen * BITS_PER_BYTE
619         }, {
620             .tag = HKS_TAG_KEY_AUTH_ID,
621             .blob = *authIdBlob
622         }, {
623             .tag = HKS_TAG_DIGEST,
624             .uint32Param = HKS_DIGEST_SHA256
625         }
626     };
627 
628     int32_t ret = ConstructParamSet(paramSet, keyParam, CAL_ARRAY_SIZE(keyParam));
629     if (ret != HAL_SUCCESS) {
630         LOGE("Construct param set failed, ret = %d", ret);
631         return ret;
632     }
633     return ret;
634 }
635 
GenerateKeyPairWithStorage(const Uint8Buff * keyAlias,uint32_t keyLen,Algorithm algo,KeyPurpose purpose,const ExtraInfo * exInfo)636 static int32_t GenerateKeyPairWithStorage(const Uint8Buff *keyAlias, uint32_t keyLen, Algorithm algo,
637     KeyPurpose purpose, const ExtraInfo *exInfo)
638 {
639     (void)purpose;
640     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias, "keyAlias");
641     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias->val, "keyAlias->val");
642     CHECK_LEN_ZERO_RETURN_ERROR_CODE(keyAlias->length, "keyAlias->length");
643     CHECK_PTR_RETURN_HAL_ERROR_CODE(exInfo, "exInfo");
644     CHECK_PTR_RETURN_HAL_ERROR_CODE(exInfo->authId.val, "authId->val");
645     CHECK_LEN_ZERO_RETURN_ERROR_CODE(exInfo->authId.length, "authId->length");
646     CHECK_LEN_ZERO_RETURN_ERROR_CODE(keyLen, "keyLen");
647 
648     struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
649     struct HksBlob authIdBlob = { exInfo->authId.length, exInfo->authId.val };
650     struct HksParamSet *paramSet = NULL;
651     int32_t ret = ConstructGenerateKeyPairWithStorageParams(&paramSet, algo, keyLen, &authIdBlob);
652     if (ret != HAL_SUCCESS) {
653         return ret;
654     }
655 
656     ret = HksGenerateKey(&keyAliasBlob, paramSet, NULL);
657     if (ret != HKS_SUCCESS) {
658         LOGE("Hks generate failed, ret=%d", ret);
659         HksFreeParamSet(&paramSet);
660         return HAL_FAILED;
661     }
662 
663     HksFreeParamSet(&paramSet);
664     return HAL_SUCCESS;
665 }
666 
GetKeyPair(struct HksParamSet * outParamSet,Uint8Buff * outPriKey,Uint8Buff * outPubKey)667 static int32_t GetKeyPair(struct HksParamSet *outParamSet, Uint8Buff *outPriKey, Uint8Buff *outPubKey)
668 {
669     int32_t ret = HksFreshParamSet(outParamSet, false); /* false means fresh by local, not through IPC */
670     if (ret != HKS_SUCCESS) {
671         LOGE("fresh param set failed, ret:%d", ret);
672         return HAL_ERR_FRESH_PARAM_SET_FAILED;
673     }
674 
675     struct HksParam *pubKeyParam = NULL;
676     ret = HksGetParam(outParamSet, HKS_TAG_ASYMMETRIC_PUBLIC_KEY_DATA, &pubKeyParam);
677     if (ret != HKS_SUCCESS) {
678         LOGE("get pub key from param set failed, ret:%d", ret);
679         return HAL_ERR_GET_PARAM_FAILED;
680     }
681 
682     struct HksParam *priKeyParam = NULL;
683     ret = HksGetParam(outParamSet, HKS_TAG_ASYMMETRIC_PRIVATE_KEY_DATA, &priKeyParam);
684     if (ret != HKS_SUCCESS) {
685         LOGE("get priv key from param set failed, ret:%d", ret);
686         return HAL_ERR_GET_PARAM_FAILED;
687     }
688 
689     if (memcpy_s(outPubKey->val, outPubKey->length, pubKeyParam->blob.data, pubKeyParam->blob.size) != EOK) {
690         LOGE("parse x25519 output param set memcpy public key failed!");
691         return HAL_ERR_MEMORY_COPY;
692     }
693     outPubKey->length = pubKeyParam->blob.size;
694 
695     if (memcpy_s(outPriKey->val, outPriKey->length, priKeyParam->blob.data, priKeyParam->blob.size) != EOK) {
696         LOGE("parse x25519 output param set memcpy private key failed!");
697         return HAL_ERR_MEMORY_COPY;
698     }
699     outPriKey->length = priKeyParam->blob.size;
700 
701     return HAL_SUCCESS;
702 }
703 
ConstructGenerateKeyPairParams(struct HksParamSet ** paramSet,Algorithm algo,uint32_t keyLen)704 static int32_t ConstructGenerateKeyPairParams(struct HksParamSet **paramSet, Algorithm algo, uint32_t keyLen)
705 {
706     struct HksParam keyParam[] = {
707         {
708             .tag = HKS_TAG_KEY_STORAGE_FLAG,
709             .uint32Param = HKS_STORAGE_TEMP
710         }, {
711             .tag = HKS_TAG_ALGORITHM,
712             .uint32Param = g_algToHksAlgorithm[algo]
713         }, {
714             .tag = HKS_TAG_KEY_SIZE,
715             .uint32Param = keyLen * BITS_PER_BYTE
716         }, {
717             .tag = HKS_TAG_IS_KEY_ALIAS,
718             .uint32Param = false
719         }
720     };
721 
722     int32_t ret = ConstructParamSet(paramSet, keyParam, CAL_ARRAY_SIZE(keyParam));
723     if (ret != HAL_SUCCESS) {
724         LOGE("Construct param set failed, ret = %d", ret);
725         return ret;
726     }
727     return ret;
728 }
729 
GenerateKeyPair(Algorithm algo,Uint8Buff * outPriKey,Uint8Buff * outPubKey)730 static int32_t GenerateKeyPair(Algorithm algo, Uint8Buff *outPriKey, Uint8Buff *outPubKey)
731 {
732     CHECK_PTR_RETURN_HAL_ERROR_CODE(outPriKey, "outPriKey");
733     CHECK_PTR_RETURN_HAL_ERROR_CODE(outPriKey->val, "outPriKey->key");
734     CHECK_LEN_ZERO_RETURN_ERROR_CODE(outPriKey->length, "outPriKey->keyLen");
735     CHECK_PTR_RETURN_HAL_ERROR_CODE(outPubKey, "outPubKey");
736     CHECK_PTR_RETURN_HAL_ERROR_CODE(outPubKey->val, "outPubKey->key");
737     CHECK_LEN_ZERO_RETURN_ERROR_CODE(outPubKey->length, "outPubKey->keyLen");
738 
739     if (outPriKey->length != outPubKey->length) {
740         LOGE("key len not equal.");
741         return HAL_ERR_INVALID_LEN;
742     }
743     uint32_t keyLen = outPriKey->length;
744 
745     struct HksParamSet *paramSet = NULL;
746     struct HksParamSet *outParamSet = NULL;
747     int32_t ret = ConstructGenerateKeyPairParams(&paramSet, algo, keyLen);
748     if (ret != HAL_SUCCESS) {
749         return ret;
750     }
751 
752     /* need 2 HksParam struct for outPriKey and outPubKey */
753     uint32_t outParamSetSize = sizeof(struct HksParamSet) +
754         2 * (sizeof(struct HksParam)) + outPriKey->length + outPubKey->length;
755     outParamSet = (struct HksParamSet *)HcMalloc(outParamSetSize, 0);
756     if (outParamSet == NULL) {
757         LOGE("allocate buffer for output param set failed");
758         ret = HAL_ERR_BAD_ALLOC;
759         goto ERR;
760     }
761     outParamSet->paramSetSize = outParamSetSize;
762 
763     ret = HksGenerateKey(NULL, paramSet, outParamSet);
764     if (ret != HKS_SUCCESS) {
765         LOGE("generate x25519 key failed, ret:%d", ret);
766         ret = HAL_FAILED;
767         goto ERR;
768     }
769 
770     ret = GetKeyPair(outParamSet, outPriKey, outPubKey);
771     if (ret != HAL_SUCCESS) {
772         LOGE("parse x25519 output param set failed, ret:%d", ret);
773         goto ERR;
774     }
775 ERR:
776     HksFreeParamSet(&paramSet);
777     HcFree(outParamSet);
778     return ret;
779 }
780 
ExportPublicKey(const Uint8Buff * keyAlias,Uint8Buff * outPubKey)781 static int32_t ExportPublicKey(const Uint8Buff *keyAlias, Uint8Buff *outPubKey)
782 {
783     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias, "keyAlias");
784     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias->val, "keyAlias->val");
785     CHECK_LEN_ZERO_RETURN_ERROR_CODE(keyAlias->length, "keyAlias->length");
786     CHECK_PTR_RETURN_HAL_ERROR_CODE(outPubKey, "outPubKey");
787     CHECK_PTR_RETURN_HAL_ERROR_CODE(outPubKey->val, "outPubKey->val");
788     CHECK_LEN_ZERO_RETURN_ERROR_CODE(outPubKey->length, "outPubKey->length");
789 
790     struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
791     struct HksBlob keyBlob = { outPubKey->length, outPubKey->val };
792 
793     int32_t ret = HksExportPublicKey(&keyAliasBlob, NULL, &keyBlob);
794     if (ret != HKS_SUCCESS) {
795         LOGE("Export public key failed, ret=%d", ret);
796         return HAL_FAILED;
797     }
798     outPubKey->length = keyBlob.size;
799 
800     return HAL_SUCCESS;
801 }
802 
ConstructSignParams(struct HksParamSet ** paramSet,Algorithm algo)803 static int32_t ConstructSignParams(struct HksParamSet **paramSet, Algorithm algo)
804 {
805     struct HksParam signParam[] = {
806         {
807             .tag = HKS_TAG_PURPOSE,
808             .uint32Param = HKS_KEY_PURPOSE_SIGN
809         }, {
810             .tag = HKS_TAG_ALGORITHM,
811             .uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519 and HKS_ALG_ECC.
812         }, {
813             .tag = HKS_TAG_DIGEST,
814             .uint32Param = HKS_DIGEST_SHA256
815         }
816     };
817 
818     int32_t ret = ConstructParamSet(paramSet, signParam, CAL_ARRAY_SIZE(signParam));
819     if (ret != HAL_SUCCESS) {
820         LOGE("Construct param set failed, ret = %d", ret);
821         return ret;
822     }
823     return ret;
824 }
825 
Sign(const Uint8Buff * keyAlias,const Uint8Buff * message,Algorithm algo,Uint8Buff * outSignature,bool isAlias)826 static int32_t Sign(const Uint8Buff *keyAlias, const Uint8Buff *message, Algorithm algo,
827     Uint8Buff *outSignature, bool isAlias)
828 {
829     struct HksParamSet *paramSet = NULL;
830     const Uint8Buff *inParams[] = { keyAlias, message, outSignature };
831     const char *paramTags[] = { "keyAlias", "message", "outSignature" };
832     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
833     if (ret != HAL_SUCCESS) {
834         return ret;
835     }
836 
837     struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
838     Uint8Buff messageHash = { NULL, 0 };
839     messageHash.length = SHA256_LEN;
840     messageHash.val = (uint8_t *)HcMalloc(messageHash.length, 0);
841     if (messageHash.val == NULL) {
842         LOGE("malloc messageHash.data failed.");
843         ret = HAL_ERR_BAD_ALLOC;
844         goto ERR;
845     }
846     ret = Sha256(message, &messageHash);
847     if (ret != HAL_SUCCESS) {
848         LOGE("Sha256 failed.");
849         goto ERR;
850     }
851     struct HksBlob messageBlob = { messageHash.length, messageHash.val };
852     struct HksBlob signatureBlob = { outSignature->length, outSignature->val };
853 
854     ret = ConstructSignParams(&paramSet, algo);
855     if (ret != HAL_SUCCESS) {
856         goto ERR;
857     }
858 
859     ret = HksSign(&keyAliasBlob, paramSet, &messageBlob, &signatureBlob);
860     if (ret != HKS_SUCCESS) {
861         LOGE("Hks sign failed.");
862         ret = HAL_FAILED;
863         goto ERR;
864     }
865     outSignature->length = signatureBlob.size;
866     ret = HAL_SUCCESS;
867 ERR:
868     HksFreeParamSet(&paramSet);
869     HcFree(messageHash.val);
870     return ret;
871 }
872 
ConstructVerifyParams(struct HksParamSet ** paramSet,Algorithm algo,bool isAlias)873 static int32_t ConstructVerifyParams(struct HksParamSet **paramSet, Algorithm algo, bool isAlias)
874 {
875     struct HksParam verifyParam[] = {
876         {
877             .tag = HKS_TAG_PURPOSE,
878             .uint32Param = HKS_KEY_PURPOSE_VERIFY
879         }, {
880             .tag = HKS_TAG_ALGORITHM,
881             .uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519 and HKS_ALG_ECC.
882         }, {
883             .tag = HKS_TAG_IS_KEY_ALIAS,
884             .boolParam = isAlias
885         }, {
886             .tag = HKS_TAG_DIGEST,
887             .uint32Param = HKS_DIGEST_SHA256
888         }
889     };
890 
891     int32_t ret = ConstructParamSet(paramSet, verifyParam, CAL_ARRAY_SIZE(verifyParam));
892     if (ret != HAL_SUCCESS) {
893         LOGE("Construct param set failed, ret = %d", ret);
894         return ret;
895     }
896     return ret;
897 }
898 
Verify(const Uint8Buff * key,const Uint8Buff * message,Algorithm algo,const Uint8Buff * signature,bool isAlias)899 static int32_t Verify(const Uint8Buff *key, const Uint8Buff *message, Algorithm algo,
900     const Uint8Buff *signature, bool isAlias)
901 {
902     struct HksParamSet *paramSet = NULL;
903     const Uint8Buff *inParams[] = { key, message, signature };
904     const char *paramTags[] = { "key", "message", "signature" };
905     int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
906     if (ret != HAL_SUCCESS) {
907         return ret;
908     }
909 
910     struct HksBlob keyAliasBlob = { key->length, key->val };
911     Uint8Buff messageHash = { NULL, 0 };
912     messageHash.length = SHA256_LEN;
913     messageHash.val = (uint8_t *)HcMalloc(messageHash.length, 0);
914     if (messageHash.val == NULL) {
915         LOGE("malloc messageHash.data failed.");
916         ret = HAL_ERR_BAD_ALLOC;
917         goto ERR;
918     }
919     ret = Sha256(message, &messageHash);
920     if (ret != HAL_SUCCESS) {
921         LOGE("Sha256 failed.");
922         goto ERR;
923     }
924     struct HksBlob messageBlob = { messageHash.length, messageHash.val };
925     struct HksBlob signatureBlob = { signature->length, signature->val };
926 
927     ret = ConstructVerifyParams(&paramSet, algo, isAlias);
928     if (ret != HAL_SUCCESS) {
929         goto ERR;
930     }
931 
932     ret = HksVerify(&keyAliasBlob, paramSet, &messageBlob, &signatureBlob);
933     if ((ret != HKS_SUCCESS)) {
934         LOGE("HksVerify failed, ret: %d", ret);
935         ret = HAL_FAILED;
936         goto ERR;
937     }
938     ret = HAL_SUCCESS;
939 ERR:
940     HksFreeParamSet(&paramSet);
941     HcFree(messageHash.val);
942     return ret;
943 }
944 
ConstructImportPublicKeyParams(struct HksParamSet ** paramSet,Algorithm algo,uint32_t keyLen,const struct HksBlob * authIdBlob,const union KeyRoleInfoUnion * roleInfoUnion)945 static int32_t ConstructImportPublicKeyParams(struct HksParamSet **paramSet, Algorithm algo, uint32_t keyLen,
946     const struct HksBlob *authIdBlob, const union KeyRoleInfoUnion *roleInfoUnion)
947 {
948     if (g_algToHksAlgorithm[algo] == HKS_ALG_ECC) {
949         keyLen = ECC_PK_LEN;
950     }
951     struct HksParam importParam[] = {
952         {
953             .tag = HKS_TAG_ALGORITHM,
954             .uint32Param = g_algToHksAlgorithm[algo]
955         }, {
956             .tag = HKS_TAG_KEY_SIZE,
957             .uint32Param = keyLen * BITS_PER_BYTE
958         }, {
959             .tag = HKS_TAG_PADDING,
960             .uint32Param = HKS_PADDING_NONE
961         }, {
962             .tag = HKS_TAG_KEY_AUTH_ID,
963             .blob = *authIdBlob
964         }, {
965             .tag = HKS_TAG_IS_ALLOWED_WRAP,
966             .boolParam = true
967         }, {
968             .tag = HKS_TAG_PURPOSE,
969             .uint32Param = HKS_KEY_PURPOSE_VERIFY
970         }, {
971             .tag = HKS_TAG_KEY_ROLE,
972             .uint32Param = roleInfoUnion->roleInfo
973         }, {
974             .tag = HKS_TAG_DIGEST,
975             .uint32Param = HKS_DIGEST_SHA256
976         }
977     };
978 
979     int32_t ret = ConstructParamSet(paramSet, importParam, CAL_ARRAY_SIZE(importParam));
980     if (ret != HAL_SUCCESS) {
981         LOGE("Construct param set failed, ret = %d", ret);
982         return ret;
983     }
984     return ret;
985 }
986 
ImportPublicKey(const Uint8Buff * keyAlias,const Uint8Buff * pubKey,Algorithm algo,const ExtraInfo * exInfo)987 static int32_t ImportPublicKey(const Uint8Buff *keyAlias, const Uint8Buff *pubKey, Algorithm algo,
988     const ExtraInfo *exInfo)
989 {
990     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias, "keyAlias");
991     CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias->val, "keyAlias->val");
992     CHECK_LEN_ZERO_RETURN_ERROR_CODE(keyAlias->length, "keyAlias->length");
993     CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey, "pubKey");
994     CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey->val, "pubKey->val");
995     CHECK_LEN_ZERO_RETURN_ERROR_CODE(pubKey->length, "pubKey->length");
996     CHECK_PTR_RETURN_HAL_ERROR_CODE(exInfo, "exInfo");
997     CHECK_PTR_RETURN_HAL_ERROR_CODE(exInfo->authId.val, "authId->val");
998     CHECK_LEN_ZERO_RETURN_ERROR_CODE(exInfo->authId.length, "authId->length");
999     CHECK_LEN_HIGHER_RETURN(exInfo->pairType, PAIR_TYPE_END - 1, "pairType");
1000 
1001     struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
1002     struct HksBlob pubKeyBlob = { pubKey->length, pubKey->val };
1003 
1004     struct HksBlob authIdBlob = { exInfo->authId.length, exInfo->authId.val };
1005     union KeyRoleInfoUnion roleInfoUnion;
1006     roleInfoUnion.roleInfoStruct.userType = (uint8_t)exInfo->userType;
1007     roleInfoUnion.roleInfoStruct.pairType = (uint8_t)exInfo->pairType;
1008     roleInfoUnion.roleInfoStruct.reserved1 = (uint8_t)0;
1009     roleInfoUnion.roleInfoStruct.reserved2 = (uint8_t)0;
1010 
1011     struct HksParamSet *paramSet = NULL;
1012 
1013     int32_t ret = ConstructImportPublicKeyParams(&paramSet, algo, pubKey->length, &authIdBlob, &roleInfoUnion);
1014     if (ret != HAL_SUCCESS) {
1015         return ret;
1016     }
1017 
1018     ret = HksImportKey(&keyAliasBlob, paramSet, &pubKeyBlob);
1019     if (ret != HKS_SUCCESS) {
1020         LOGE("Hks importKey failed, ret: %d", ret);
1021         HksFreeParamSet(&paramSet);
1022         return HAL_FAILED;
1023     }
1024 
1025     HksFreeParamSet(&paramSet);
1026     return HAL_SUCCESS;
1027 }
1028 
CheckBigNumCompareParams(const Uint8Buff * a,const Uint8Buff * b,int * res)1029 static bool CheckBigNumCompareParams(const Uint8Buff *a, const Uint8Buff *b, int *res)
1030 {
1031     if ((a == NULL || a->val == NULL) && (b == NULL || b->val == NULL)) {
1032         *res = 0; // a = b
1033         return false;
1034     }
1035     if ((a == NULL || a->val == NULL) && (b != NULL && b->val != NULL)) {
1036         *res = 1; // a < b
1037         return false;
1038     }
1039     if ((a != NULL && a->val != NULL) && (b == NULL || b->val == NULL)) {
1040         *res = -1; // a > b
1041         return false;
1042     }
1043     return true;
1044 }
1045 
BigNumCompare(const Uint8Buff * a,const Uint8Buff * b)1046 static int32_t BigNumCompare(const Uint8Buff *a, const Uint8Buff *b)
1047 {
1048     int res = 0;
1049     if (!CheckBigNumCompareParams(a, b, &res)) {
1050         return res;
1051     }
1052     const uint8_t *tmpA = a->val;
1053     const uint8_t *tmpB = b->val;
1054     uint32_t len = a->length;
1055     if (a->length < b->length) {
1056         for (uint32_t i = 0; i < b->length - a->length; i++) {
1057             if (b->val[i] > 0) {
1058                 return 1; // a < b
1059             }
1060         }
1061         tmpA = a->val;
1062         tmpB = b->val + b->length - a->length;
1063         len = a->length;
1064     }
1065     if (a->length > b->length) {
1066         for (uint32_t i = 0; i < a->length - b->length; i++) {
1067             if (a->val[i] > 0) {
1068                 return -1; // a > b
1069             }
1070         }
1071         tmpA = a->val + a->length - b->length;
1072         tmpB = b->val;
1073         len = b->length;
1074     }
1075     for (uint32_t i = 0; i < len; i++) {
1076         if (*(tmpA + i) > *(tmpB + i)) {
1077             return -1; // a > b
1078         }
1079         if (*(tmpA + i) < *(tmpB + i)) {
1080             return 1; // a < b
1081         }
1082     }
1083     return 0; // a == b
1084 }
1085 
CheckDlPublicKey(const Uint8Buff * key,const char * primeHex)1086 static bool CheckDlPublicKey(const Uint8Buff *key, const char *primeHex)
1087 {
1088     if (key == NULL || key->val == NULL || primeHex == NULL) {
1089         LOGE("Params is null.");
1090         return false;
1091     }
1092     uint8_t min = 1;
1093 
1094     uint32_t innerKeyLen = HcStrlen(primeHex) / BYTE_TO_HEX_OPER_LENGTH;
1095     if (key->length > innerKeyLen) {
1096         LOGE("Key length > prime number length.");
1097         return false;
1098     }
1099     uint8_t *primeByte = (uint8_t *)HcMalloc(innerKeyLen, 0);
1100     if (primeByte == NULL) {
1101         LOGE("Malloc for primeByte failed.");
1102         return false;
1103     }
1104     if (HexStringToByte(primeHex, primeByte, innerKeyLen) != HAL_SUCCESS) {
1105         LOGE("Convert prime number from hex string to byte failed.");
1106         HcFree(primeByte);
1107         return false;
1108     }
1109     /*
1110      * P - 1, since the last byte of large prime number must be greater than 1,
1111      * needn't to think about borrowing forward
1112      */
1113     primeByte[innerKeyLen - 1] -= 1;
1114 
1115     Uint8Buff minBuff = { &min, sizeof(uint8_t) };
1116     if (BigNumCompare(key, &minBuff) >= 0) {
1117         LOGE("Pubkey is invalid, key <= 1.");
1118         HcFree(primeByte);
1119         return false;
1120     }
1121 
1122     Uint8Buff primeBuff = { primeByte, innerKeyLen };
1123     if (BigNumCompare(key, &primeBuff) <= 0) {
1124         LOGE("Pubkey is invalid, key >= p - 1.");
1125         HcFree(primeByte);
1126         return false;
1127     }
1128 
1129     HcFree(primeByte);
1130     return true;
1131 }
1132 
ImportSymmetricKey(const Uint8Buff * keyAlias,const Uint8Buff * authToken,KeyPurpose purpose,const ExtraInfo * exInfo)1133 static int32_t ImportSymmetricKey(const Uint8Buff *keyAlias, const Uint8Buff *authToken, KeyPurpose purpose,
1134     const ExtraInfo *exInfo)
1135 {
1136     (void)keyAlias;
1137     (void)authToken;
1138     (void)purpose;
1139     (void)exInfo;
1140     return HAL_ERR_NOT_SUPPORTED;
1141 }
1142 
CheckEcPublicKey(const Uint8Buff * pubKey,Algorithm algo)1143 static bool CheckEcPublicKey(const Uint8Buff *pubKey, Algorithm algo)
1144 {
1145     (void)pubKey;
1146     (void)algo;
1147     return true;
1148 }
1149 
1150 static const AlgLoader g_huksLoader = {
1151     .initAlg = InitHks,
1152     .sha256 = Sha256,
1153     .generateRandom = GenerateRandom,
1154     .computeHmac = ComputeHmac,
1155     .computeHkdf = ComputeHkdf,
1156     .importSymmetricKey = ImportSymmetricKey,
1157     .checkKeyExist = CheckKeyExist,
1158     .deleteKey = DeleteKey,
1159     .aesGcmEncrypt = AesGcmEncrypt,
1160     .aesGcmDecrypt = AesGcmDecrypt,
1161     .hashToPoint = HashToPoint,
1162     .agreeSharedSecretWithStorage = AgreeSharedSecretWithStorage,
1163     .agreeSharedSecret = AgreeSharedSecret,
1164     .bigNumExpMod = BigNumExpMod,
1165     .generateKeyPairWithStorage = GenerateKeyPairWithStorage,
1166     .generateKeyPair = GenerateKeyPair,
1167     .exportPublicKey = ExportPublicKey,
1168     .sign = Sign,
1169     .verify = Verify,
1170     .importPublicKey = ImportPublicKey,
1171     .checkDlPublicKey = CheckDlPublicKey,
1172     .checkEcPublicKey = CheckEcPublicKey,
1173     .bigNumCompare = BigNumCompare
1174 };
1175 
GetRealLoaderInstance()1176 const AlgLoader *GetRealLoaderInstance()
1177 {
1178     return &g_huksLoader;
1179 }