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