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 "hal_error.h"
18 #include "hc_file.h"
19 #include "hc_log.h"
20 #include "hc_types.h"
21 #include "hc_dev_info.h"
22 #include "hks_api.h"
23 #include "hks_param.h"
24 #include "hks_type.h"
25 #include "string_util.h"
26
27 #define BASE_IMPORT_PARAMS_LEN 7
28 #define EXT_IMPORT_PARAMS_LEN 2
29
30 static enum HksKeyPurpose g_purposeToHksKeyPurpose[] = {
31 HKS_KEY_PURPOSE_MAC,
32 HKS_KEY_PURPOSE_DERIVE
33 };
34
BaseCheckParams(const Uint8Buff ** inParams,const char ** paramTags,uint32_t len)35 static int32_t BaseCheckParams(const Uint8Buff **inParams, const char **paramTags, uint32_t len)
36 {
37 for (uint32_t i = 0; i < len; i++) {
38 CHECK_PTR_RETURN_HAL_ERROR_CODE(inParams[i], paramTags[i]);
39 CHECK_PTR_RETURN_HAL_ERROR_CODE(inParams[i]->val, paramTags[i]);
40 CHECK_LEN_ZERO_RETURN_ERROR_CODE(inParams[i]->length, paramTags[i]);
41 }
42 return HAL_SUCCESS;
43 }
44
ConstructParamSet(struct HksParamSet ** out,const struct HksParam * inParam,const uint32_t inParamNum)45 static int32_t ConstructParamSet(struct HksParamSet **out, const struct HksParam *inParam,
46 const uint32_t inParamNum)
47 {
48 struct HksParamSet *paramSet = NULL;
49 int32_t ret = HksInitParamSet(¶mSet);
50 if (ret != HKS_SUCCESS) {
51 LOGE("init param set failed, ret = %d", ret);
52 return HAL_ERR_INIT_PARAM_SET_FAILED;
53 }
54
55 ret = HksAddParams(paramSet, inParam, inParamNum);
56 if (ret != HKS_SUCCESS) {
57 LOGE("add param failed, ret = %d", ret);
58 HksFreeParamSet(¶mSet);
59 return HAL_ERR_ADD_PARAM_FAILED;
60 }
61
62 ret = HksBuildParamSet(¶mSet);
63 if (ret != HKS_SUCCESS) {
64 LOGE("build param set failed, ret = %d", ret);
65 HksFreeParamSet(¶mSet);
66 return HAL_ERR_BUILD_PARAM_SET_FAILED;
67 }
68
69 *out = paramSet;
70 return HAL_SUCCESS;
71 }
72
InitHks(void)73 static int32_t InitHks(void)
74 {
75 int32_t res = HksInitialize();
76 if (res == HKS_SUCCESS) {
77 return HAL_SUCCESS;
78 }
79
80 if ((res != HKS_ERROR_INVALID_KEY_FILE) && (res != HKS_ERROR_CRYPTO_ENGINE_ERROR) &&
81 (res != HKS_ERROR_UPDATE_ROOT_KEY_MATERIAL_FAIL)) {
82 LOGE("Hks: Init hks failed, res: %d.", res);
83 return HAL_ERR_INIT_FAILED;
84 }
85
86 LOGD("Hks: The local hks file needs to be refreshed!");
87 LOGI("Start to delete local database file!");
88 HcFileRemove(GetStoragePath());
89 LOGI("Delete local database file successfully!");
90 res = HksRefreshKeyInfo();
91 if (res != HKS_SUCCESS) {
92 LOGE("Hks: HksRefreshKeyInfo failed, res: %d.", res);
93 return HAL_ERR_INIT_FAILED;
94 }
95 res = HksInitialize();
96 if (res != HKS_SUCCESS) {
97 LOGE("Hks: Init hks failed, res: %d.", res);
98 return HAL_ERR_INIT_FAILED;
99 }
100
101 return HAL_SUCCESS;
102 }
103
Sha256(const Uint8Buff * message,Uint8Buff * hash)104 static int32_t Sha256(const Uint8Buff *message, Uint8Buff *hash)
105 {
106 CHECK_PTR_RETURN_HAL_ERROR_CODE(message, "message");
107 CHECK_PTR_RETURN_HAL_ERROR_CODE(message->val, "message->val");
108 CHECK_LEN_ZERO_RETURN_ERROR_CODE(message->length, "message->length");
109
110 CHECK_PTR_RETURN_HAL_ERROR_CODE(hash, "hash");
111 CHECK_PTR_RETURN_HAL_ERROR_CODE(hash->val, "hash->val");
112 CHECK_LEN_EQUAL_RETURN(hash->length, SHA256_LEN, "hash->length");
113
114 struct HksBlob srcBlob = { message->length, message->val };
115 struct HksBlob hashBlob = { hash->length, hash->val };
116 struct HksParamSet *paramSet = NULL;
117 struct HksParam digestParam[] = {
118 {
119 .tag = HKS_TAG_DIGEST,
120 .uint32Param = HKS_DIGEST_SHA256
121 }
122 };
123 int32_t ret = ConstructParamSet(¶mSet, digestParam, CAL_ARRAY_SIZE(digestParam));
124 if (ret != HAL_SUCCESS) {
125 LOGE("construct param set failed, ret = %d", ret);
126 return ret;
127 }
128
129 ret = HksHash(paramSet, &srcBlob, &hashBlob);
130 if (ret != HKS_SUCCESS || hashBlob.size != SHA256_LEN) {
131 HksFreeParamSet(¶mSet);
132 return HAL_FAILED;
133 }
134
135 HksFreeParamSet(¶mSet);
136 return HAL_SUCCESS;
137 }
138
GenerateRandom(Uint8Buff * rand)139 static int32_t GenerateRandom(Uint8Buff *rand)
140 {
141 CHECK_PTR_RETURN_HAL_ERROR_CODE(rand, "rand");
142 CHECK_PTR_RETURN_HAL_ERROR_CODE(rand->val, "rand->val");
143 CHECK_LEN_ZERO_RETURN_ERROR_CODE(rand->length, "rand->length");
144
145 struct HksBlob randBlob = { rand->length, rand->val };
146 int32_t ret = HksGenerateRandom(NULL, &randBlob);
147 if (ret != HKS_SUCCESS) {
148 LOGE("Generate random failed, ret: %d", ret);
149 return HAL_FAILED;
150 }
151
152 return HAL_SUCCESS;
153 }
154
CheckKeyExist(const Uint8Buff * keyAlias)155 static int32_t CheckKeyExist(const Uint8Buff *keyAlias)
156 {
157 CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias, "keyAlias");
158 CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias->val, "keyAlias->val");
159 CHECK_LEN_ZERO_RETURN_ERROR_CODE(keyAlias->length, "keyAlias->length");
160
161 struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
162 int32_t ret = HksKeyExist(&keyAliasBlob, NULL);
163 if (ret != HKS_SUCCESS) {
164 LOGE("Check key exist failed, ret = %d", ret);
165 return HAL_FAILED;
166 }
167
168 return HAL_SUCCESS;
169 }
170
DeleteKey(const Uint8Buff * keyAlias)171 static int32_t DeleteKey(const Uint8Buff *keyAlias)
172 {
173 CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias, "keyAlias");
174 CHECK_PTR_RETURN_HAL_ERROR_CODE(keyAlias->val, "keyAlias->val");
175 CHECK_LEN_ZERO_RETURN_ERROR_CODE(keyAlias->length, "keyAlias->length");
176
177 struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
178 int32_t ret = HksDeleteKey(&keyAliasBlob, NULL);
179 if (ret == HKS_ERROR_NOT_EXIST) {
180 LOGI("Key not exists.");
181 return HAL_SUCCESS;
182 }
183 if (ret != HKS_SUCCESS) {
184 LOGE("Delete key failed, ret = %d", ret);
185 return HAL_FAILED;
186 }
187
188 return HAL_SUCCESS;
189 }
190
ComputeHmac(const Uint8Buff * key,const Uint8Buff * message,Uint8Buff * outHmac,bool isAlias)191 static int32_t ComputeHmac(const Uint8Buff *key, const Uint8Buff *message, Uint8Buff *outHmac, bool isAlias)
192 {
193 const Uint8Buff *inParams[] = { key, message, outHmac };
194 const char *paramTags[] = {"key", "message", "outHmac"};
195 int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
196 if (ret != HAL_SUCCESS) {
197 return ret;
198 }
199 CHECK_LEN_EQUAL_RETURN(outHmac->length, HMAC_LEN, "outHmac->length");
200
201 struct HksBlob keyBlob = { key->length, key->val };
202 struct HksBlob srcBlob = { message->length, message->val };
203 struct HksBlob hmacBlob = { outHmac->length, outHmac->val };
204 struct HksParamSet *paramSet = NULL;
205 struct HksParam hmacParam[] = {
206 {
207 .tag = HKS_TAG_PURPOSE,
208 .uint32Param = HKS_KEY_PURPOSE_MAC
209 }, {
210 .tag = HKS_TAG_DIGEST,
211 .uint32Param = HKS_DIGEST_SHA256
212 }, {
213 .tag = HKS_TAG_IS_KEY_ALIAS,
214 .boolParam = isAlias
215 }
216 };
217 ret = ConstructParamSet(¶mSet, hmacParam, CAL_ARRAY_SIZE(hmacParam));
218 if (ret != HAL_SUCCESS) {
219 LOGE("construct param set failed, ret = %d", ret);
220 return ret;
221 }
222
223 ret = HksMac(&keyBlob, paramSet, &srcBlob, &hmacBlob);
224 if (ret != HKS_SUCCESS || hmacBlob.size != HMAC_LEN) {
225 LOGE("Hmac failed, ret: %d", ret);
226 HksFreeParamSet(¶mSet);
227 return HAL_FAILED;
228 }
229
230 HksFreeParamSet(¶mSet);
231 return HAL_SUCCESS;
232 }
233
ComputeHkdf(const Uint8Buff * baseKey,const Uint8Buff * salt,const Uint8Buff * keyInfo,Uint8Buff * outHkdf,bool isAlias)234 static int32_t ComputeHkdf(const Uint8Buff *baseKey, const Uint8Buff *salt, const Uint8Buff *keyInfo,
235 Uint8Buff *outHkdf, bool isAlias)
236 {
237 const Uint8Buff *inParams[] = { baseKey, salt, outHkdf };
238 const char *paramTags[] = { "baseKey", "salt", "outHkdf" };
239 int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
240 if (ret != HAL_SUCCESS) {
241 return ret;
242 }
243
244 struct HksBlob srcKeyBlob = { baseKey->length, baseKey->val };
245 struct HksBlob saltBlob = { salt->length, salt->val };
246 struct HksBlob keyInfoBlob = { 0, NULL };
247 if (keyInfo != NULL) {
248 keyInfoBlob.size = keyInfo->length;
249 keyInfoBlob.data = keyInfo->val;
250 }
251 struct HksBlob derivedKeyBlob = { outHkdf->length, outHkdf->val };
252
253 struct HksParamSet *paramSet = NULL;
254 struct HksParam hkdfParam[] = {
255 {
256 .tag = HKS_TAG_PURPOSE,
257 .uint32Param = HKS_KEY_PURPOSE_DERIVE
258 }, {
259 .tag = HKS_TAG_ALGORITHM,
260 .uint32Param = HKS_ALG_HKDF
261 }, {
262 .tag = HKS_TAG_DIGEST,
263 .uint32Param = HKS_DIGEST_SHA256
264 }, {
265 .tag = HKS_TAG_SALT,
266 .blob = saltBlob
267 }, {
268 .tag = HKS_TAG_INFO,
269 .blob = keyInfoBlob
270 }, {
271 .tag = HKS_TAG_IS_KEY_ALIAS,
272 .boolParam = isAlias
273 }
274 };
275
276 ret = ConstructParamSet(¶mSet, hkdfParam, CAL_ARRAY_SIZE(hkdfParam));
277 if (ret != HAL_SUCCESS) {
278 return ret;
279 }
280
281 ret = HksDeriveKey(paramSet, &srcKeyBlob, &derivedKeyBlob);
282 if (ret != HKS_SUCCESS) {
283 LOGE("Key derivation failed, ret: %d", ret);
284 HksFreeParamSet(¶mSet);
285 return HAL_FAILED;
286 }
287
288 HksFreeParamSet(¶mSet);
289 return HAL_SUCCESS;
290 }
291
CheckAesGcmEncryptParam(const Uint8Buff * key,const Uint8Buff * plain,const GcmParam * encryptInfo,Uint8Buff * outCipher)292 static int32_t CheckAesGcmEncryptParam(const Uint8Buff *key, const Uint8Buff *plain, const GcmParam *encryptInfo,
293 Uint8Buff *outCipher)
294 {
295 const Uint8Buff *inParams[] = { key, plain, outCipher };
296 const char* paramTags[] = { "key", "plain", "outCipher" };
297 int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
298 if (ret != HAL_SUCCESS) {
299 return ret;
300 }
301
302 CHECK_PTR_RETURN_HAL_ERROR_CODE(encryptInfo, "encryptInfo");
303 CHECK_PTR_RETURN_HAL_ERROR_CODE(encryptInfo->aad, "aad");
304 CHECK_LEN_ZERO_RETURN_ERROR_CODE(encryptInfo->aadLen, "aadLen");
305 CHECK_PTR_RETURN_HAL_ERROR_CODE(encryptInfo->nonce, "nonce");
306 CHECK_LEN_LOWER_RETURN(encryptInfo->nonceLen, HKS_AE_NONCE_LEN, "nonceLen");
307 CHECK_LEN_LOWER_RETURN(outCipher->length, plain->length + HKS_AE_TAG_LEN, "outCipher");
308
309 return HAL_SUCCESS;
310 }
311
AesGcmEncrypt(const Uint8Buff * key,const Uint8Buff * plain,const GcmParam * encryptInfo,bool isAlias,Uint8Buff * outCipher)312 static int32_t AesGcmEncrypt(const Uint8Buff *key, const Uint8Buff *plain,
313 const GcmParam *encryptInfo, bool isAlias, Uint8Buff *outCipher)
314 {
315 int32_t ret = CheckAesGcmEncryptParam(key, plain, encryptInfo, outCipher);
316 if (ret != HAL_SUCCESS) {
317 return ret;
318 }
319
320 struct HksBlob keyBlob = { key->length, key->val };
321 struct HksBlob plainBlob = { plain->length, plain->val };
322 struct HksBlob cipherBlob = { outCipher->length, outCipher->val };
323
324 struct HksParamSet *paramSet = NULL;
325 struct HksParam encryptParam[] = {
326 {
327 .tag = HKS_TAG_PURPOSE,
328 .uint32Param = HKS_KEY_PURPOSE_ENCRYPT
329 }, {
330 .tag = HKS_TAG_ALGORITHM,
331 .uint32Param = HKS_ALG_AES
332 }, {
333 .tag = HKS_TAG_BLOCK_MODE,
334 .uint32Param = HKS_MODE_GCM
335 }, {
336 .tag = HKS_TAG_PADDING,
337 .uint32Param = HKS_PADDING_NONE
338 }, {
339 .tag = HKS_TAG_NONCE,
340 .blob = { encryptInfo->nonceLen, encryptInfo->nonce }
341 }, {
342 .tag = HKS_TAG_ASSOCIATED_DATA,
343 .blob = { encryptInfo->aadLen, encryptInfo->aad }
344 }, {
345 .tag = HKS_TAG_IS_KEY_ALIAS,
346 .boolParam = isAlias
347 }
348 };
349
350 ret = ConstructParamSet(¶mSet, encryptParam, CAL_ARRAY_SIZE(encryptParam));
351 if (ret != HAL_SUCCESS) {
352 LOGE("construct param set failed, ret = %d", ret);
353 return ret;
354 }
355
356 ret = HksEncrypt(&keyBlob, paramSet, &plainBlob, &cipherBlob);
357 if (ret != HKS_SUCCESS) {
358 LOGE("Aes-gcm encrypt failed, ret: %d", ret);
359 HksFreeParamSet(¶mSet);
360 return HAL_FAILED;
361 }
362
363 HksFreeParamSet(¶mSet);
364 return HAL_SUCCESS;
365 }
366
CheckAesGcmDecryptParam(const Uint8Buff * key,const Uint8Buff * cipher,const GcmParam * decryptInfo,Uint8Buff * outPlain)367 static int32_t CheckAesGcmDecryptParam(const Uint8Buff *key, const Uint8Buff *cipher, const GcmParam *decryptInfo,
368 Uint8Buff *outPlain)
369 {
370 const Uint8Buff *inParams[] = { key, cipher, outPlain };
371 const char *paramTags[] = { "key", "cipher", "outPlain" };
372 int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
373 if (ret != HAL_SUCCESS) {
374 return ret;
375 }
376
377 CHECK_PTR_RETURN_HAL_ERROR_CODE(decryptInfo, "decryptInfo");
378 CHECK_PTR_RETURN_HAL_ERROR_CODE(decryptInfo->aad, "aad");
379 CHECK_LEN_ZERO_RETURN_ERROR_CODE(decryptInfo->aadLen, "aadLen");
380 CHECK_PTR_RETURN_HAL_ERROR_CODE(decryptInfo->nonce, "nonce");
381 CHECK_LEN_LOWER_RETURN(decryptInfo->nonceLen, HKS_AE_NONCE_LEN, "nonceLen");
382 CHECK_LEN_LOWER_RETURN(outPlain->length, cipher->length - HKS_AE_TAG_LEN, "outPlain");
383
384 return HAL_SUCCESS;
385 }
386
AesGcmDecrypt(const Uint8Buff * key,const Uint8Buff * cipher,const GcmParam * decryptInfo,bool isAlias,Uint8Buff * outPlain)387 static int32_t AesGcmDecrypt(const Uint8Buff *key, const Uint8Buff *cipher,
388 const GcmParam *decryptInfo, bool isAlias, Uint8Buff *outPlain)
389 {
390 int32_t ret = CheckAesGcmDecryptParam(key, cipher, decryptInfo, outPlain);
391 if (ret != HAL_SUCCESS) {
392 return ret;
393 }
394
395 struct HksBlob keyBlob = { key->length, key->val };
396 struct HksBlob cipherBlob = { cipher->length, cipher->val };
397 struct HksBlob plainBlob = { outPlain->length, outPlain->val };
398
399 struct HksParamSet *paramSet = NULL;
400 struct HksParam decryptParam[] = {
401 {
402 .tag = HKS_TAG_PURPOSE,
403 .uint32Param = HKS_KEY_PURPOSE_DECRYPT
404 }, {
405 .tag = HKS_TAG_ALGORITHM,
406 .uint32Param = HKS_ALG_AES
407 }, {
408 .tag = HKS_TAG_BLOCK_MODE,
409 .uint32Param = HKS_MODE_GCM
410 }, {
411 .tag = HKS_TAG_PADDING,
412 .uint32Param = HKS_PADDING_NONE
413 }, {
414 .tag = HKS_TAG_NONCE,
415 .blob = { decryptInfo->nonceLen, decryptInfo->nonce }
416 }, {
417 .tag = HKS_TAG_ASSOCIATED_DATA,
418 .blob = { decryptInfo->aadLen, decryptInfo->aad }
419 }, {
420 .tag = HKS_TAG_IS_KEY_ALIAS,
421 .boolParam = isAlias
422 }
423 };
424
425 ret = ConstructParamSet(¶mSet, decryptParam, CAL_ARRAY_SIZE(decryptParam));
426 if (ret != HAL_SUCCESS) {
427 LOGE("construct param set failed, ret = %d", ret);
428 return ret;
429 }
430
431 ret = HksDecrypt(&keyBlob, paramSet, &cipherBlob, &plainBlob);
432 if (ret != HKS_SUCCESS) {
433 LOGE("Aes-gcm decrypt failed, ret: %d", ret);
434 HksFreeParamSet(¶mSet);
435 return HAL_FAILED;
436 }
437
438 HksFreeParamSet(¶mSet);
439 return HAL_SUCCESS;
440 }
441
CheckImportSymmetricKeyParam(const Uint8Buff * keyAlias,const Uint8Buff * authToken)442 static int32_t CheckImportSymmetricKeyParam(const Uint8Buff *keyAlias, const Uint8Buff *authToken)
443 {
444 const Uint8Buff *inParams[] = { keyAlias, authToken };
445 const char *paramTags[] = { "keyAlias", "authToken" };
446 return BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
447 }
448
ConstructImportSymmetricKeyParam(struct HksParamSet ** paramSet,uint32_t keyLen,KeyPurpose purpose,const ExtraInfo * exInfo)449 static int32_t ConstructImportSymmetricKeyParam(struct HksParamSet **paramSet, uint32_t keyLen, KeyPurpose purpose,
450 const ExtraInfo *exInfo)
451 {
452 struct HksParam *importParam = NULL;
453 struct HksBlob authIdBlob = { 0, NULL };
454 union KeyRoleInfoUnion roleInfoUnion;
455 (void)memset_s(&roleInfoUnion, sizeof(roleInfoUnion), 0, sizeof(roleInfoUnion));
456 uint32_t idx = 0;
457 if (exInfo != NULL) {
458 CHECK_PTR_RETURN_HAL_ERROR_CODE(exInfo->authId.val, "authId");
459 CHECK_LEN_ZERO_RETURN_ERROR_CODE(exInfo->authId.length, "authId");
460 CHECK_LEN_HIGHER_RETURN(exInfo->pairType, PAIR_TYPE_END - 1, "pairType");
461 importParam = (struct HksParam *)HcMalloc(sizeof(struct HksParam) *
462 (BASE_IMPORT_PARAMS_LEN + EXT_IMPORT_PARAMS_LEN), 0);
463 if (importParam == NULL) {
464 LOGE("Malloc for importParam failed.");
465 return HAL_ERR_BAD_ALLOC;
466 }
467 authIdBlob.size = exInfo->authId.length;
468 authIdBlob.data = exInfo->authId.val;
469 roleInfoUnion.roleInfoStruct.userType = (uint8_t)exInfo->userType;
470 roleInfoUnion.roleInfoStruct.pairType = (uint8_t)exInfo->pairType;
471 importParam[idx].tag = HKS_TAG_KEY_AUTH_ID;
472 importParam[idx++].blob = authIdBlob;
473 importParam[idx].tag = HKS_TAG_KEY_ROLE;
474 importParam[idx++].uint32Param = roleInfoUnion.roleInfo;
475 } else {
476 importParam = (struct HksParam *)HcMalloc(sizeof(struct HksParam) * BASE_IMPORT_PARAMS_LEN, 0);
477 if (importParam == NULL) {
478 LOGE("Malloc for importParam failed.");
479 return HAL_ERR_BAD_ALLOC;
480 }
481 }
482
483 importParam[idx].tag = HKS_TAG_ALGORITHM;
484 importParam[idx++].uint32Param = HKS_ALG_AES;
485 importParam[idx].tag = HKS_TAG_KEY_SIZE;
486 importParam[idx++].uint32Param = keyLen * BITS_PER_BYTE;
487 importParam[idx].tag = HKS_TAG_PADDING;
488 importParam[idx++].uint32Param = HKS_PADDING_NONE;
489 importParam[idx].tag = HKS_TAG_IS_ALLOWED_WRAP;
490 importParam[idx++].boolParam = false;
491 importParam[idx].tag = HKS_TAG_PURPOSE;
492 importParam[idx++].uint32Param = g_purposeToHksKeyPurpose[purpose];
493 importParam[idx].tag = HKS_TAG_BLOCK_MODE;
494 importParam[idx++].uint32Param = HKS_MODE_GCM;
495 importParam[idx].tag = HKS_TAG_DIGEST;
496 importParam[idx++].uint32Param = HKS_DIGEST_SHA256;
497
498 int ret = ConstructParamSet(paramSet, importParam, idx);
499 if (ret != HAL_SUCCESS) {
500 LOGE("Construct decrypt param set failed, ret = %d.", ret);
501 }
502
503 HcFree(importParam);
504 return ret;
505 }
506
ImportSymmetricKey(const Uint8Buff * keyAlias,const Uint8Buff * authToken,KeyPurpose purpose,const ExtraInfo * exInfo)507 static int32_t ImportSymmetricKey(const Uint8Buff *keyAlias, const Uint8Buff *authToken, KeyPurpose purpose,
508 const ExtraInfo *exInfo)
509 {
510 int32_t ret = CheckImportSymmetricKeyParam(keyAlias, authToken);
511 if (ret != HAL_SUCCESS) {
512 return ret;
513 }
514
515 struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
516 struct HksBlob symKeyBlob = { authToken->length, authToken->val };
517 struct HksParamSet *paramSet = NULL;
518 ret = ConstructImportSymmetricKeyParam(¶mSet, authToken->length, purpose, exInfo);
519 if (ret != HAL_SUCCESS) {
520 LOGE("construct param set failed, ret = %d", ret);
521 return ret;
522 }
523
524 ret = HksImportKey(&keyAliasBlob, paramSet, &symKeyBlob);
525 if (ret != HKS_SUCCESS) {
526 LOGE("HksImportKey failed, ret: %d", ret);
527 HksFreeParamSet(¶mSet);
528 return ret;
529 }
530
531 HksFreeParamSet(¶mSet);
532 return HAL_SUCCESS;
533 }
534
BigNumExpMod(const Uint8Buff * base,const Uint8Buff * exp,const char * bigNumHex,Uint8Buff * outNum)535 static int32_t BigNumExpMod(const Uint8Buff *base, const Uint8Buff *exp, const char *bigNumHex, Uint8Buff *outNum)
536 {
537 const Uint8Buff *inParams[] = { base, exp, outNum };
538 const char *paramTags[] = { "base", "exp", "outNum" };
539 int32_t ret = BaseCheckParams(inParams, paramTags, CAL_ARRAY_SIZE(inParams));
540 if (ret != HAL_SUCCESS) {
541 return ret;
542 }
543
544 CHECK_PTR_RETURN_HAL_ERROR_CODE(bigNumHex, "bigNumHex");
545 uint32_t primeLen = strlen(bigNumHex) / BYTE_TO_HEX_OPER_LENGTH;
546 if ((primeLen != BIG_PRIME_LEN_384) && (primeLen != BIG_PRIME_LEN_256)) {
547 LOGE("Not support big number len %d", outNum->length);
548 return HAL_FAILED;
549 }
550 CHECK_LEN_EQUAL_RETURN(outNum->length, primeLen, "outNum->length");
551
552 struct HksBlob baseBlob = { base->length, base->val };
553 struct HksBlob expBlob = { exp->length, exp->val };
554 struct HksBlob outNumBlob = { outNum->length, outNum->val };
555 struct HksBlob bigNumBlob = { 0, NULL };
556 bigNumBlob.size = outNum->length;
557 bigNumBlob.data = (uint8_t *)HcMalloc(bigNumBlob.size, 0);
558 if (bigNumBlob.data == NULL) {
559 LOGE("malloc bigNumBlob.data failed.");
560 return HAL_ERR_BAD_ALLOC;
561 }
562 ret = HexStringToByte(bigNumHex, bigNumBlob.data, bigNumBlob.size);
563 if (ret != HAL_SUCCESS) {
564 LOGE("HexStringToByte for bigNumHex failed.");
565 HcFree(bigNumBlob.data);
566 return ret;
567 }
568
569 ret = HksBnExpMod(&outNumBlob, &baseBlob, &expBlob, &bigNumBlob);
570 if (ret != HKS_SUCCESS) {
571 LOGE("Huks calculate big number exp mod failed, ret = %d", ret);
572 HcFree(bigNumBlob.data);
573 return HAL_FAILED;
574 }
575 outNum->length = outNumBlob.size;
576
577 HcFree(bigNumBlob.data);
578 return HAL_SUCCESS;
579 }
580
CheckBigNumCompareParams(const Uint8Buff * a,const Uint8Buff * b,int * res)581 static bool CheckBigNumCompareParams(const Uint8Buff *a, const Uint8Buff *b, int *res)
582 {
583 if ((a == NULL || a->val == NULL) && (b == NULL || b->val == NULL)) {
584 *res = 0; // a = b
585 return false;
586 }
587 if ((a == NULL || a->val == NULL) && (b != NULL && b->val != NULL)) {
588 *res = 1; // a < b
589 return false;
590 }
591 if ((a != NULL && a->val != NULL) && (b == NULL || b->val == NULL)) {
592 *res = -1; // a > b
593 return false;
594 }
595 return true;
596 }
597
BigNumCompare(const Uint8Buff * a,const Uint8Buff * b)598 static int32_t BigNumCompare(const Uint8Buff *a, const Uint8Buff *b)
599 {
600 int res = 0;
601 if (!CheckBigNumCompareParams(a, b, &res)) {
602 return res;
603 }
604 const uint8_t *tmpA = a->val;
605 const uint8_t *tmpB = b->val;
606 uint32_t len = a->length;
607 if (a->length < b->length) {
608 for (uint32_t i = 0; i < b->length - a->length; i++) {
609 if (b->val[i] > 0) {
610 return 1; // a < b
611 }
612 }
613 tmpA = a->val;
614 tmpB = b->val + b->length - a->length;
615 len = a->length;
616 }
617 if (a->length > b->length) {
618 for (uint32_t i = 0; i < a->length - b->length; i++) {
619 if (a->val[i] > 0) {
620 return -1; // a > b
621 }
622 }
623 tmpA = a->val + a->length - b->length;
624 tmpB = b->val;
625 len = b->length;
626 }
627 for (uint32_t i = 0; i < len; i++) {
628 if (*(tmpA + i) > *(tmpB + i)) {
629 return -1; // a > b
630 }
631 if (*(tmpA + i) < *(tmpB + i)) {
632 return 1; // a < b
633 }
634 }
635 return 0; // a == b
636 }
637
CheckDlPublicKey(const Uint8Buff * key,const char * primeHex)638 static bool CheckDlPublicKey(const Uint8Buff *key, const char *primeHex)
639 {
640 if (key == NULL || key->val == NULL || primeHex == NULL) {
641 LOGE("Params is null.");
642 return false;
643 }
644 uint8_t min = 1;
645
646 uint32_t innerKeyLen = HcStrlen(primeHex) / BYTE_TO_HEX_OPER_LENGTH;
647 if (key->length > innerKeyLen) {
648 LOGE("Key length > prime number length.");
649 return false;
650 }
651 uint8_t *primeByte = (uint8_t *)HcMalloc(innerKeyLen, 0);
652 if (primeByte == NULL) {
653 LOGE("Malloc for primeByte failed.");
654 return false;
655 }
656 if (HexStringToByte(primeHex, primeByte, innerKeyLen) != HAL_SUCCESS) {
657 LOGE("Convert prime number from hex string to byte failed.");
658 HcFree(primeByte);
659 return false;
660 }
661 /*
662 * P - 1, since the last byte of large prime number must be greater than 1,
663 * needn't to think about borrowing forward
664 */
665 primeByte[innerKeyLen - 1] -= 1;
666
667 Uint8Buff minBuff = { &min, sizeof(uint8_t) };
668 if (BigNumCompare(key, &minBuff) >= 0) {
669 LOGE("Pubkey is invalid, key <= 1.");
670 HcFree(primeByte);
671 return false;
672 }
673
674 Uint8Buff primeBuff = { primeByte, innerKeyLen };
675 if (BigNumCompare(key, &primeBuff) <= 0) {
676 LOGE("Pubkey is invalid, key >= p - 1.");
677 HcFree(primeByte);
678 return false;
679 }
680
681 HcFree(primeByte);
682 return true;
683 }
684
HashToPoint(const Uint8Buff * hash,Algorithm algo,Uint8Buff * outEcPoint)685 static int32_t HashToPoint(const Uint8Buff *hash, Algorithm algo, Uint8Buff *outEcPoint)
686 {
687 (void)hash;
688 (void)algo;
689 (void)outEcPoint;
690 return HAL_ERR_NOT_SUPPORTED;
691 }
692
AgreeSharedSecretWithStorage(const KeyBuff * priKey,const KeyBuff * pubKey,Algorithm algo,uint32_t sharedKeyLen,const Uint8Buff * sharedKeyAlias)693 static int32_t AgreeSharedSecretWithStorage(const KeyBuff *priKey, const KeyBuff *pubKey, Algorithm algo,
694 uint32_t sharedKeyLen, const Uint8Buff *sharedKeyAlias)
695 {
696 (void)priKey;
697 (void)pubKey;
698 (void)algo;
699 (void)sharedKeyLen;
700 (void)sharedKeyAlias;
701 return HAL_ERR_NOT_SUPPORTED;
702 }
703
AgreeSharedSecret(const KeyBuff * priKey,const KeyBuff * pubKey,Algorithm algo,Uint8Buff * sharedKey)704 static int32_t AgreeSharedSecret(const KeyBuff *priKey, const KeyBuff *pubKey, Algorithm algo, Uint8Buff *sharedKey)
705 {
706 (void)priKey;
707 (void)pubKey;
708 (void)algo;
709 (void)sharedKey;
710 return HAL_ERR_NOT_SUPPORTED;
711 }
712
GenerateKeyPairWithStorage(const Uint8Buff * keyAlias,uint32_t keyLen,Algorithm algo,KeyPurpose purpose,const ExtraInfo * exInfo)713 static int32_t GenerateKeyPairWithStorage(const Uint8Buff *keyAlias, uint32_t keyLen, Algorithm algo,
714 KeyPurpose purpose, const ExtraInfo *exInfo)
715 {
716 (void)keyAlias;
717 (void)keyLen;
718 (void)algo;
719 (void)purpose;
720 (void)exInfo;
721 return HAL_ERR_NOT_SUPPORTED;
722 }
723
GenerateKeyPair(Algorithm algo,Uint8Buff * outPriKey,Uint8Buff * outPubKey)724 static int32_t GenerateKeyPair(Algorithm algo, Uint8Buff *outPriKey, Uint8Buff *outPubKey)
725 {
726 (void)algo;
727 (void)outPriKey;
728 (void)outPubKey;
729 return HAL_ERR_NOT_SUPPORTED;
730 }
731
ExportPublicKey(const Uint8Buff * keyAlias,Uint8Buff * outPubKey)732 static int32_t ExportPublicKey(const Uint8Buff *keyAlias, Uint8Buff *outPubKey)
733 {
734 (void)keyAlias;
735 (void)outPubKey;
736 return HAL_ERR_NOT_SUPPORTED;
737 }
738
Sign(const Uint8Buff * keyAlias,const Uint8Buff * message,Algorithm algo,Uint8Buff * outSignature,bool isAlias)739 static int32_t Sign(const Uint8Buff *keyAlias, const Uint8Buff *message, Algorithm algo,
740 Uint8Buff *outSignature, bool isAlias)
741 {
742 (void)keyAlias;
743 (void)message;
744 (void)algo;
745 (void)outSignature;
746 (void)isAlias;
747 return HAL_ERR_NOT_SUPPORTED;
748 }
749
Verify(const Uint8Buff * key,const Uint8Buff * message,Algorithm algo,const Uint8Buff * signature,bool isAlias)750 static int32_t Verify(const Uint8Buff *key, const Uint8Buff *message, Algorithm algo,
751 const Uint8Buff *signature, bool isAlias)
752 {
753 (void)key;
754 (void)message;
755 (void)algo;
756 (void)signature;
757 (void)isAlias;
758 return HAL_ERR_NOT_SUPPORTED;
759 }
760
ImportPublicKey(const Uint8Buff * keyAlias,const Uint8Buff * pubKey,Algorithm algo,const ExtraInfo * exInfo)761 static int32_t ImportPublicKey(const Uint8Buff *keyAlias, const Uint8Buff *pubKey, Algorithm algo,
762 const ExtraInfo *exInfo)
763 {
764 (void)keyAlias;
765 (void)pubKey;
766 (void)algo;
767 (void)exInfo;
768 return HAL_ERR_NOT_SUPPORTED;
769 }
770
CheckEcPublicKey(const Uint8Buff * pubKey,Algorithm algo)771 static bool CheckEcPublicKey(const Uint8Buff *pubKey, Algorithm algo)
772 {
773 (void)pubKey;
774 (void)algo;
775 return true;
776 }
777
778 static const AlgLoader g_huksLoader = {
779 .initAlg = InitHks,
780 .sha256 = Sha256,
781 .generateRandom = GenerateRandom,
782 .computeHmac = ComputeHmac,
783 .computeHkdf = ComputeHkdf,
784 .importSymmetricKey = ImportSymmetricKey,
785 .checkKeyExist = CheckKeyExist,
786 .deleteKey = DeleteKey,
787 .aesGcmEncrypt = AesGcmEncrypt,
788 .aesGcmDecrypt = AesGcmDecrypt,
789 .hashToPoint = HashToPoint,
790 .agreeSharedSecretWithStorage = AgreeSharedSecretWithStorage,
791 .agreeSharedSecret = AgreeSharedSecret,
792 .bigNumExpMod = BigNumExpMod,
793 .generateKeyPairWithStorage = GenerateKeyPairWithStorage,
794 .generateKeyPair = GenerateKeyPair,
795 .exportPublicKey = ExportPublicKey,
796 .sign = Sign,
797 .verify = Verify,
798 .importPublicKey = ImportPublicKey,
799 .checkDlPublicKey = CheckDlPublicKey,
800 .checkEcPublicKey = CheckEcPublicKey,
801 .bigNumCompare = BigNumCompare
802 };
803
GetRealLoaderInstance()804 const AlgLoader *GetRealLoaderInstance()
805 {
806 return &g_huksLoader;
807 }