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(¶mSet);
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(¶mSet);
66 return HAL_ERR_ADD_PARAM_FAILED;
67 }
68
69 ret = HksBuildParamSet(¶mSet);
70 if (ret != HKS_SUCCESS) {
71 LOGE("build param set failed, ret = %d", ret);
72 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
113 return HAL_FAILED;
114 }
115
116 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
208 return HAL_FAILED;
209 }
210
211 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
266 return HAL_FAILED;
267 }
268
269 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
341 return HAL_FAILED;
342 }
343
344 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
416 return HAL_FAILED;
417 }
418
419 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
627 return HAL_FAILED;
628 }
629
630 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
679 return HAL_FAILED;
680 }
681
682 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
788 return HAL_FAILED;
789 }
790
791 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
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(¶mSet, 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(¶mSet);
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(¶mSet, 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(¶mSet);
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(¶mSet, 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(¶mSet);
1150 return HAL_FAILED;
1151 }
1152
1153 HksFreeParamSet(¶mSet);
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(¶mSet, 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(¶mSet);
1354 return ret;
1355 }
1356
1357 HksFreeParamSet(¶mSet);
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