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