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