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