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