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