• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 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 <stdio.h>
18 #include "securec.h"
19 #include "commonutil.h"
20 #include "hks_api.h"
21 #include "hks_param.h"
22 #include "log.h"
23 #include "mem_stat.h"
24 
25 #define X25519_KEY_LEN 256
26 #define ED25519_KEY_LEN 256
27 #define X25519_KEY_PARAM_SET_SIZE 128 /* priv key size: 32, pub key size: 32, add two tag, no larger than 128 */
28 #define DEFAULT_PARAM_SET_OUT_SIZE 1024
29 #define HC_PARAM_CHAIN_LEN 255
30 #define HC_PARAM_KEY_LEN 256
31 #define BITS_PER_BYTE 8
32 #define HC_CCM_NONCE_LEN 7
33 
34 #if (defined(_SUPPORT_SEC_CLONE_) || defined(_SUPPORT_SEC_CLONE_SERVER_))
35 static const uint8_t g_factor[] = "hichain_key_enc_key";
36 static const int32_t g_cert_chain_cnt = 4;
37 #endif
38 
39 union huks_key_type_union {
40     struct huks_key_type type_struct;
41     uint32_t key_type;
42 };
43 
44 #define CREATE_STRUCT(T) \
45     struct T *create_struct_##T(void) \
46     { \
47         struct T *val = (struct T *)MALLOC(sizeof(struct T)); \
48         if (val == NULL) { \
49             return NULL; \
50         } \
51         (void)memset_s(val, sizeof(*val), 0, sizeof(*val)); \
52         return val; \
53     }
54 
55 #define CONVERT_TO_BLOB(T, field_name) \
56     struct HksBlob convert_to_blob_from_##T(struct T *val) \
57     { \
58         struct HksBlob hks_blob_val; \
59         (void)memset_s(&hks_blob_val, sizeof(hks_blob_val), 0, sizeof(hks_blob_val)); \
60         check_ptr_return_val(val->field_name, hks_blob_val); \
61         check_num_return_val(val->length, hks_blob_val); \
62         hks_blob_val.data = val->field_name; \
63         hks_blob_val.size = val->length; \
64         return hks_blob_val; \
65     }
66 
67 CREATE_STRUCT(hc_key_alias)
68 CREATE_STRUCT(sha256_value)
69 CREATE_STRUCT(uint8_buff)
70 
71 CONVERT_TO_BLOB(hc_key_alias, key_alias)
72 CONVERT_TO_BLOB(ltpk, ltpk)
73 CONVERT_TO_BLOB(sha256_value, sha256_value)
74 CONVERT_TO_BLOB(sha512_value, sha512_value)
75 CONVERT_TO_BLOB(signature, signature)
76 CONVERT_TO_BLOB(stpk, stpk)
77 CONVERT_TO_BLOB(stsk, stsk)
78 CONVERT_TO_BLOB(hc_auth_id, auth_id)
79 
80 static const uint8_t g_key_type_pairs[HC_MAX_KEY_TYPE_NUM][HC_KEY_TYPE_PAIR_LEN] = {
81     { 0x00, 0x00 }, /* ACCESSOR_PK */
82     { 0x00, 0x01 }, /* CONTROLLER_PK */
83     { 0x00, 0x02 }, /* ed25519 KEYPAIR */
84     { 0x00, 0x03 }, /* KEK, key encryption key, used only by DeviceAuthService */
85     { 0x00, 0x04 }, /* DEK, data encryption key, used only by upper apps */
86     { 0x00, 0x05 }, /* key tmp */
87     { 0x00, 0x06 }  /* PSK, preshared key index */
88 };
89 
90 static const char *g_large_prime_number_hex_384 =
91     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74"\
92     "020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437"\
93     "4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"\
94     "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05"\
95     "98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB"\
96     "9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"\
97     "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"\
98     "3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33"\
99     "A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"\
100     "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864"\
101     "D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2"\
102     "08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF";
103 
104 static const char *g_large_prime_number_hex_256 =
105     "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74"\
106     "020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437"\
107     "4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"\
108     "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05"\
109     "98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB"\
110     "9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"\
111     "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718"\
112     "3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF";
113 
hks_hex_string_to_byte(const char * src,uint8_t * dst,uint32_t dst_size)114 static int32_t hks_hex_string_to_byte(const char *src, uint8_t *dst, uint32_t dst_size)
115 {
116     size_t length = strlen(src);
117     if (length % 2 != 0) { /* odd number or not */
118         LOGE("Invalid hex_string length: %zu, even num is expected", length);
119         return ERROR_CODE_FAILED;
120     }
121 
122     uint32_t hex_length = length / BYTE_TO_HEX_OPER_LENGTH; /* Calculate hexadecimal length */
123     if (dst_size < hex_length) {
124         LOGE("Invalid dst_size: %u is smaller than hex_length: %u", dst_size, hex_length);
125         return ERROR_CODE_FAILED;
126     }
127 
128     uint8_t nibble[2]; /* create an array of two elements */
129     for (uint32_t i = 0; i < hex_length; i++) {
130         nibble[0] = src[i * BYTE_TO_HEX_OPER_LENGTH];
131         nibble[1] = src[i * BYTE_TO_HEX_OPER_LENGTH + 1];
132         for (uint32_t j = 0; j < BYTE_TO_HEX_OPER_LENGTH; j++) { /* iterate through array */
133             if ((nibble[j] <= 'F') && (nibble[j] >= 'A')) {
134                 nibble[j] = nibble[j] - 'A' + 10; /* hex conversion */
135             } else if ((nibble[j] <= 'f') && (nibble[j] >= 'a')) {
136                 nibble[j] = nibble[j] - 'a' + 10; /* hex conversion */
137             } else if ((nibble[j] >= '0') && (nibble[j] <= '9')) {
138                 nibble[j] = nibble[j] - '0';
139             } else {
140                 LOGE("Invalid char: [%c] in hex string, [0-9]|[A-F]|[a-f] expected", (char)nibble[j]);
141                 return ERROR_CODE_FAILED;
142             }
143         }
144         dst[i] = nibble[0] << 4; /* shift left for filling */
145         dst[i] |= nibble[1];
146     }
147     return ERROR_CODE_SUCCESS;
148 }
149 
construct_param_set(struct HksParamSet ** out,const struct HksParam * in_param,const uint32_t in_param_num)150 static int32_t construct_param_set(struct HksParamSet **out, const struct HksParam *in_param,
151     const uint32_t in_param_num)
152 {
153     struct HksParamSet *param_set = NULL;
154     int32_t status = HksInitParamSet(&param_set);
155     if (status != ERROR_CODE_SUCCESS) {
156         LOGE("init param set failed, status=%d", status);
157         return ERROR_CODE_INIT_PARAM_SET;
158     }
159 
160     status = HksAddParams(param_set, in_param, in_param_num);
161     if (status != ERROR_CODE_SUCCESS) {
162         LOGE("add digest param failed, status=%d", status);
163         HksFreeParamSet(&param_set);
164         return ERROR_CODE_ADD_PARAM;
165     }
166 
167     status = HksBuildParamSet(&param_set);
168     if (status != ERROR_CODE_SUCCESS) {
169         LOGE("build param set failed, status=%d", status);
170         HksFreeParamSet(&param_set);
171         return ERROR_CODE_BUILD_PARAM_SET;
172     }
173 
174     *out = param_set;
175     return ERROR_CODE_SUCCESS;
176 }
177 
sha256(const struct uint8_buff * message)178 static struct sha256_value sha256(const struct uint8_buff *message)
179 {
180     struct sha256_value sha256_value;
181     (void)memset_s(&sha256_value, sizeof(sha256_value), 0, sizeof(sha256_value));
182 
183     struct HksBlob src_data = { message->length, message->val };
184 
185     struct HksBlob hash = { 0, NULL };
186     hash.data = (uint8_t *)MALLOC(HC_SHA256_LEN * sizeof(uint8_t));
187     if (hash.data == NULL) {
188         LOGE("SHA256 malloc failed");
189         return sha256_value;
190     }
191     hash.size = HC_SHA256_LEN;
192 
193     struct HksParamSet *param_set = NULL;
194     struct HksParam digest_param[] = {
195         {
196             .tag = HKS_TAG_DIGEST,
197             .uint32Param = HKS_DIGEST_SHA256
198         }
199     };
200     int32_t status = construct_param_set(&param_set, digest_param, array_size(digest_param));
201     if (status != ERROR_CODE_SUCCESS) {
202         safe_free(hash.data);
203         LOGE("construct param set in the sha256 failed, status=%d", status);
204         return sha256_value;
205     }
206     status = HksHash(param_set, &src_data, &hash);
207     if ((status == 0) && (hash.size == HC_SHA256_LEN)) {
208         (void)memcpy_s(sha256_value.sha256_value, sizeof(sha256_value.sha256_value), hash.data, HC_SHA256_LEN);
209         sha256_value.length = HC_SHA256_LEN;
210     } else {
211         LOGE("SHA256 failed, status=%d", status);
212         sha256_value.length = 0;
213     }
214     safe_free(hash.data);
215     HksFreeParamSet(&param_set);
216     return sha256_value;
217 }
218 
Compare(const uint8_t * a,uint32_t lenA,const uint8_t * b,uint32_t lenB)219 static int32_t Compare(const uint8_t *a, uint32_t lenA, const uint8_t *b, uint32_t lenB)
220 {
221     const uint8_t *tmpA = a;
222     const uint8_t *tmpB = b;
223     uint32_t len = lenA;
224     if (lenA < lenB) {
225         for (uint32_t i = 0; i < lenB - lenA; i++) {
226             if (b[i] > 0) {
227                 return 1; // a < b: 1
228             }
229         }
230         tmpA = a;
231         tmpB = b + lenB - lenA;
232         len = lenA;
233     }
234     if (lenA > lenB) {
235         for (uint32_t i = 0; i < lenA - lenB; i++) {
236             if (a[i] > 0) {
237                 return -1; // a > b: -1
238             }
239         }
240         tmpA = a + lenA - lenB;
241         tmpB = b;
242         len = lenB;
243     }
244     for (uint32_t i = 0; i < len; i++) {
245         if (*(tmpA + i) > *(tmpB + i)) {
246             return -1;
247         }
248         if (*(tmpA + i) < *(tmpB + i)) {
249             return 1;
250         }
251     }
252     return 0;
253 }
254 
CheckDlSpekePublicKey(const struct var_buffer * key,uint32_t bigNumLen)255 int32_t CheckDlSpekePublicKey(const struct var_buffer *key, uint32_t bigNumLen)
256 {
257     if (key == NULL) {
258         LOGE("Param is null.");
259         return HC_INPUT_PTR_NULL;
260     }
261     const char *primeHex = NULL;
262     if (bigNumLen == HC_BIG_PRIME_MAX_LEN_384) {
263         primeHex = g_large_prime_number_hex_384;
264     } else {
265         primeHex = g_large_prime_number_hex_256;
266     }
267     uint8_t min = 1;
268     uint32_t primeLen = strlen(primeHex) / BYTE_TO_HEX_OPER_LENGTH;
269     if (key->length > primeLen) {
270         LOGE("key->length > primeLen.");
271         return HC_INPUT_ERROR;
272     }
273     uint8_t *primeVal = (uint8_t *)MALLOC(primeLen);
274     if (primeVal == NULL) {
275         LOGE("Malloc primeVal failed.");
276         return HC_MALLOC_FAILED;
277     }
278     if (hex_string_to_byte(primeHex, strlen(primeHex), primeVal) != ERROR_CODE_SUCCESS) {
279         LOGE("hex_string_to_byte for prime num failed");
280         FREE(primeVal);
281         return HC_INPUT_ERROR;
282     }
283     /*
284      * P - 1, since the last byte of large prime number must be greater than 1,
285      * do not need to think about borrowing forward
286      */
287     primeVal[primeLen - 1] -= 1;
288     if (Compare(key->data, key->length, &min, sizeof(uint8_t)) >= 0) {
289         LOGE("key <= 1, invalid.");
290         FREE(primeVal);
291         return HC_MEMCPY_ERROR;
292     }
293     if (Compare(key->data, key->length, primeVal, primeLen) <= 0) {
294         LOGE("key >= p - 1, invalid.");
295         FREE(primeVal);
296         return HC_MEMCPY_ERROR;
297     }
298     FREE(primeVal);
299     return HC_OK;
300 }
301 
cal_bignum_exp(struct var_buffer * base,struct var_buffer * exp,const uint32_t big_num_len,struct big_num * out_result)302 int32_t cal_bignum_exp(struct var_buffer *base, struct var_buffer *exp,
303     const uint32_t big_num_len, struct big_num *out_result)
304 {
305     check_ptr_return_val(base, HC_INPUT_ERROR);
306     check_ptr_return_val(exp, HC_INPUT_ERROR);
307     check_ptr_return_val(out_result, HC_INPUT_ERROR);
308 
309     if ((big_num_len != HC_BIG_PRIME_MAX_LEN_384) && (big_num_len != HC_BIG_PRIME_MAX_LEN_256)) {
310         LOGE("Not support big number len %d", big_num_len);
311         return HC_LARGE_PRIME_NUMBER_LEN_UNSUPPORT;
312     }
313 
314     struct HksBlob big_num_a = { base->length, base->data };
315     struct HksBlob big_num_e = { exp->length, exp->data };
316 
317     uint8_t *large_num = (uint8_t *)MALLOC(big_num_len);
318     if (large_num == NULL) {
319         LOGE("Malloc big num buff fail");
320         return ERROR_CODE_FAILED;
321     }
322 
323     (void)memset_s(large_num, big_num_len, 0, big_num_len);
324     int32_t status;
325 
326     if (big_num_len == HC_BIG_PRIME_MAX_LEN_384) {
327         status = hks_hex_string_to_byte(g_large_prime_number_hex_384, large_num, big_num_len);
328     } else {
329         status = hks_hex_string_to_byte(g_large_prime_number_hex_256, large_num, big_num_len);
330     }
331     if (status != ERROR_CODE_SUCCESS) {
332         FREE(large_num);
333         return ERROR_CODE_FAILED;
334     }
335 
336     struct HksBlob big_num_n = { big_num_len, large_num };
337     struct HksBlob big_num_x = { big_num_len, out_result->big_num };
338     if (big_num_len > sizeof(out_result->big_num)) {
339         LOGE("The big num array is shorter than the expected output len.");
340         FREE(large_num);
341         return ERROR_CODE_FAILED;
342     }
343 
344     status = HksBnExpMod(&big_num_x, &big_num_a, &big_num_e, &big_num_n);
345     FREE(large_num);
346     if (status != ERROR_CODE_SUCCESS) {
347         LOGE("Huks bn exp mod error, status=%d", status);
348         return ERROR_CODE_FAILED;
349     }
350     out_result->length = big_num_x.size;
351 
352     return ERROR_CODE_SUCCESS;
353 }
354 
generate_random(uint32_t length)355 struct random_value generate_random(uint32_t length)
356 {
357     struct random_value rand;
358     (void)memset_s(&rand, sizeof(rand), 0, sizeof(rand));
359     if ((length == 0) || (length > HC_RAMDOM_MAX_LEN)) {
360         LOGE("Generate random failed, invalid param length: %d", length);
361         return rand;
362     }
363 
364     struct HksBlob hks_rand = { length, rand.random_value };
365     int32_t status = HksGenerateRandom(NULL, &hks_rand);
366     if (status == ERROR_CODE_SUCCESS) {
367         rand.length = hks_rand.size;
368     } else {
369         LOGE("Huks generate random failed, status: %d", status);
370     }
371 
372     return rand;
373 }
374 
compute_hmac(struct var_buffer * key,const struct uint8_buff * message,struct hmac * out_hmac)375 int32_t compute_hmac(struct var_buffer *key, const struct uint8_buff *message, struct hmac *out_hmac)
376 {
377     check_ptr_return_val(key, HC_INPUT_ERROR);
378     check_ptr_return_val(message, HC_INPUT_ERROR);
379     check_ptr_return_val(out_hmac, HC_INPUT_ERROR);
380 
381     struct HksBlob hks_key = { key->length, key->data };
382     struct HksBlob src_data = { message->length, message->val };
383     struct HksBlob output = { HC_HMAC_LEN, out_hmac->hmac };
384     struct HksParamSet *param_set = NULL;
385 
386     struct HksParam hmac_param[] = {
387         {
388             .tag = HKS_TAG_PURPOSE,
389             .uint32Param = HKS_KEY_PURPOSE_MAC
390         }, {
391             .tag = HKS_TAG_DIGEST,
392             .uint32Param = HKS_DIGEST_SHA256
393         }, {
394             .tag = HKS_TAG_IS_KEY_ALIAS, /* temporary key, is_key_alias is set to false determined using REE for MAC */
395             .boolParam = false
396         }
397     };
398     int32_t status = construct_param_set(&param_set, hmac_param, array_size(hmac_param));
399     if (status != ERROR_CODE_SUCCESS) {
400         LOGE("construct HMAC param set failed, status=%d", status);
401         return ERROR_CODE_BUILD_PARAM_SET;
402     }
403 
404     /* make hmac */
405     status = HksMac(&hks_key, param_set, &src_data, &output);
406     if (status != ERROR_CODE_SUCCESS) {
407         LOGE("Huks hmac failed, status: %d", status);
408         HksFreeParamSet(&param_set);
409         return ERROR_CODE_FAILED;
410     }
411     out_hmac->length = output.size;
412     HksFreeParamSet(&param_set);
413 
414     return ERROR_CODE_SUCCESS;
415 }
416 
compute_hkdf(struct var_buffer * shared_secret,struct hc_salt * salt,char * key_info,uint32_t hkdf_len,struct var_buffer * out_hkdf)417 int32_t compute_hkdf(struct var_buffer *shared_secret, struct hc_salt *salt,
418     char *key_info, uint32_t hkdf_len, struct var_buffer *out_hkdf)
419 {
420     check_ptr_return_val(shared_secret, HC_INPUT_ERROR);
421     check_ptr_return_val(salt, HC_INPUT_ERROR);
422     check_ptr_return_val(out_hkdf, HC_INPUT_ERROR);
423     check_ptr_return_val(key_info, HC_INPUT_ERROR);
424 
425     struct HksBlob derived_key = { hkdf_len, out_hkdf->data };
426     struct HksBlob hks_salt = { salt->length, salt->salt };
427     struct HksBlob hks_key_info = { (uint32_t)strlen(key_info), (uint8_t *)key_info };
428 
429     /* original key */
430     struct HksBlob kdf_key = { shared_secret->length, shared_secret->data };
431 
432     /* derived key param */
433     struct HksParamSet *param_set = NULL;
434     struct HksParam hkdf_param[] = {
435         {
436             .tag = HKS_TAG_PURPOSE,
437             .uint32Param = HKS_KEY_PURPOSE_DERIVE
438         }, {
439             .tag = HKS_TAG_ALGORITHM,
440             .uint32Param = HKS_ALG_HKDF
441         }, {
442             .tag = HKS_TAG_DIGEST,
443             .uint32Param = HKS_DIGEST_SHA256
444         }, {
445             .tag = HKS_TAG_SALT,
446             .blob = hks_salt
447         }, {
448             .tag = HKS_TAG_INFO,
449             .blob = hks_key_info
450         }, {
451             .tag = HKS_TAG_IS_KEY_ALIAS,
452             .boolParam = false
453         }
454     };
455     int32_t status = construct_param_set(&param_set, hkdf_param, array_size(hkdf_param));
456     if (status != ERROR_CODE_SUCCESS) {
457         LOGE("construct hkdf param set failed, status=%d", status);
458         return ERROR_CODE_BUILD_PARAM_SET;
459     }
460 
461     /* make hkdf */
462     status = HksDeriveKey(param_set, &kdf_key, &derived_key);
463     if (status != ERROR_CODE_SUCCESS) {
464         LOGE("Huks key derivation failed, status: %d", status);
465         HksFreeParamSet(&param_set);
466         return ERROR_CODE_FAILED;
467     }
468     out_hkdf->length = derived_key.size;
469 
470     HksFreeParamSet(&param_set);
471     return ERROR_CODE_SUCCESS;
472 }
473 
init_aes_gcm_encrypt_param_set(struct HksParamSet ** param_set,struct random_value * nonce,struct aes_aad * aad,uint32_t key_byte_size)474 static int32_t init_aes_gcm_encrypt_param_set(struct HksParamSet **param_set,
475     struct random_value *nonce, struct aes_aad *aad, uint32_t key_byte_size)
476 {
477     struct HksParam encrypt_param[] = {
478         {
479             .tag = HKS_TAG_PURPOSE,
480             .uint32Param = HKS_KEY_PURPOSE_ENCRYPT
481         }, {
482             .tag = HKS_TAG_ALGORITHM,
483             .uint32Param = HKS_ALG_AES
484         }, {
485             .tag = HKS_TAG_BLOCK_MODE,
486             .uint32Param = HKS_MODE_GCM
487         }, {
488             .tag = HKS_TAG_PADDING,
489             .uint32Param = HKS_PADDING_NONE
490         }, {
491             .tag = HKS_TAG_NONCE,
492             .blob = { nonce->length, nonce->random_value }
493         }, {
494             .tag = HKS_TAG_ASSOCIATED_DATA,
495             .blob = { aad->length, aad->aad }
496         }, {
497             .tag = HKS_TAG_IS_KEY_ALIAS,
498             .boolParam = false
499         }, {
500             .tag = HKS_TAG_KEY_SIZE,
501             .uint32Param = key_byte_size * BITS_PER_BYTE
502         }
503     };
504 
505     return construct_param_set(param_set, encrypt_param, array_size(encrypt_param));
506 }
507 
aes_gcm_encrypt(struct var_buffer * key,const struct uint8_buff * plain,struct aes_aad * aad,struct uint8_buff * out_cipher)508 int32_t aes_gcm_encrypt(struct var_buffer *key, const struct uint8_buff *plain,
509     struct aes_aad *aad, struct uint8_buff *out_cipher)
510 {
511     check_ptr_return_val(key, HC_INPUT_ERROR);
512     check_ptr_return_val(plain, HC_INPUT_ERROR);
513     check_ptr_return_val(aad, HC_INPUT_ERROR);
514     check_ptr_return_val(out_cipher, HC_INPUT_ERROR);
515     struct random_value nonce = generate_random(HC_AES_GCM_NONCE_LEN);
516     if (nonce.length == 0) {
517         LOGE("Generate random to make nonce failed");
518         return HC_GEN_RANDOM_FAILED;
519     }
520 
521     struct HksBlob hks_key = { key->length, key->data };
522     struct HksBlob hks_plain_text = { plain->length, plain->val };
523 
524     if (memcpy_s(out_cipher->val, out_cipher->size, nonce.random_value, nonce.length) != EOK) {
525         LOGE("memcpy nonce fail");
526         return ERROR_CODE_FAILED;
527     }
528 
529     struct HksBlob tag_cipher = { out_cipher->size - nonce.length, out_cipher->val + nonce.length };
530     struct HksParamSet *param_set = NULL;
531     int32_t status = init_aes_gcm_encrypt_param_set(&param_set, &nonce, aad, hks_key.size);
532     if (status != ERROR_CODE_SUCCESS) {
533         LOGE("init encrypt param set failed, status=%d", status);
534         return ERROR_CODE_BUILD_PARAM_SET;
535     }
536 
537     status = HksEncrypt(&hks_key, param_set, &hks_plain_text, &tag_cipher);
538     if (status != ERROR_CODE_SUCCESS) {
539         LOGE("Huks aead encrypt error, status: %d", status);
540         HksFreeParamSet(&param_set);
541         return ERROR_CODE_FAILED;
542     }
543 
544     out_cipher->length = tag_cipher.size + nonce.length;
545     HksFreeParamSet(&param_set);
546     return ERROR_CODE_SUCCESS;
547 }
548 
init_aes_gcm_decrypt_param_set(struct HksParamSet ** param_set,const struct uint8_buff * cipher,struct aes_aad * aad,uint32_t key_byte_size)549 static int32_t init_aes_gcm_decrypt_param_set(struct HksParamSet **param_set,
550     const struct uint8_buff *cipher, struct aes_aad *aad, uint32_t key_byte_size)
551 {
552     struct HksParam decrypt_param[] = {
553         {
554             .tag = HKS_TAG_PURPOSE,
555             .uint32Param = HKS_KEY_PURPOSE_DECRYPT
556         }, {
557             .tag = HKS_TAG_ALGORITHM,
558             .uint32Param = HKS_ALG_AES
559         }, {
560             .tag = HKS_TAG_BLOCK_MODE,
561             .uint32Param = HKS_MODE_GCM
562         }, {
563             .tag = HKS_TAG_PADDING,
564             .uint32Param = HKS_PADDING_NONE
565         }, {
566             .tag = HKS_TAG_NONCE,
567             .blob = { HC_AES_GCM_NONCE_LEN, cipher->val }
568         }, {
569             .tag = HKS_TAG_ASSOCIATED_DATA,
570             .blob = { aad->length, aad->aad }
571         }, {
572             .tag = HKS_TAG_IS_KEY_ALIAS,
573             .boolParam = false
574         }, {
575             .tag = HKS_TAG_KEY_SIZE,
576             .uint32Param = key_byte_size * BITS_PER_BYTE
577         }
578     };
579 
580     return construct_param_set(param_set, decrypt_param, array_size(decrypt_param));
581 }
582 
aes_gcm_decrypt(struct var_buffer * key,const struct uint8_buff * cipher,struct aes_aad * aad,struct uint8_buff * out_plain)583 int32_t aes_gcm_decrypt(struct var_buffer *key, const struct uint8_buff *cipher,
584     struct aes_aad *aad, struct uint8_buff *out_plain)
585 {
586     check_ptr_return_val(key, HC_INPUT_ERROR);
587     check_ptr_return_val(cipher, HC_INPUT_ERROR);
588     check_ptr_return_val(aad, HC_INPUT_ERROR);
589     check_ptr_return_val(out_plain, HC_INPUT_ERROR);
590 
591     if (cipher->length < HC_AES_GCM_NONCE_LEN) {
592         LOGE("Cipher length is short than nonce max length");
593         return ERROR_CODE_FAILED;
594     }
595 
596     struct HksBlob hks_key = { key->length, key->data };
597     struct HksBlob nonce_blob = { HC_AES_GCM_NONCE_LEN, cipher->val };
598     struct HksBlob cipher_text_with_tag = { cipher->length - nonce_blob.size, cipher->val + nonce_blob.size };
599     struct HksBlob plain_text = { 0, NULL };
600 
601     plain_text.data = (uint8_t *)MALLOC(cipher_text_with_tag.size - HKS_AE_TAG_LEN);
602     check_ptr_return_val(plain_text.data, ERROR_CODE_FAILED);
603     plain_text.size = cipher_text_with_tag.size - HKS_AE_TAG_LEN;
604 
605     struct HksParamSet *param_set = NULL;
606     int32_t status = init_aes_gcm_decrypt_param_set(&param_set, cipher, aad, hks_key.size);
607     if (status != ERROR_CODE_SUCCESS) {
608         LOGE("init encrypt param set failed, status=%d", status);
609         safe_free(plain_text.data);
610         return ERROR_CODE_BUILD_PARAM_SET;
611     }
612 
613     status = HksDecrypt(&hks_key, param_set, &cipher_text_with_tag, &plain_text);
614     if (status != ERROR_CODE_SUCCESS) {
615         LOGE("Huks aead decrypt failed, status: %d", status);
616         safe_free(plain_text.data);
617         HksFreeParamSet(&param_set);
618         return ERROR_CODE_FAILED;
619     }
620 
621     if (memcpy_s(out_plain->val, out_plain->size, plain_text.data, plain_text.size) != EOK) {
622         safe_free(plain_text.data);
623         HksFreeParamSet(&param_set);
624         return ERROR_CODE_FAILED;
625     }
626     out_plain->length = plain_text.size;
627 
628     safe_free(plain_text.data);
629     HksFreeParamSet(&param_set);
630     return status;
631 }
632 
generate_service_id(const struct session_identity * identity)633 struct service_id generate_service_id(const struct session_identity *identity)
634 {
635     struct service_id service_id;
636     (void)memset_s(&service_id, sizeof(service_id), 0, sizeof(service_id));
637     if (identity == NULL) {
638         LOGE("Input is null");
639         return service_id;
640     }
641 
642     uint32_t pack_name_len = identity->package_name.length;
643     if ((pack_name_len == 0) || (pack_name_len > HC_PACKAGE_NAME_BUFF_LEN)) {
644         LOGE("Pack name length is: %u", pack_name_len);
645         return service_id;
646     }
647     uint32_t type_len = identity->service_type.length;
648     if ((type_len == 0) || (type_len > HC_SERVICE_TYPE_BUFF_LEN)) {
649         LOGE("Service type length is: %u", type_len);
650         return service_id;
651     }
652     uint32_t srv_len = type_len + pack_name_len;
653     struct uint8_buff id_buff = {
654         .length = srv_len,
655         .size = srv_len
656     };
657 
658     id_buff.val = (uint8_t *)MALLOC(srv_len);
659     if (id_buff.val == NULL) {
660         LOGE("Malloc mem failed");
661         return service_id;
662     }
663 
664     if (memcpy_s(id_buff.val, srv_len, identity->package_name.name, pack_name_len) != EOK) {
665         LOGE("Copy service id buff failed");
666         safe_free(id_buff.val);
667         return service_id;
668     }
669     if (memcpy_s(id_buff.val + pack_name_len, srv_len - pack_name_len, identity->service_type.type, type_len) != EOK) {
670         LOGE("Copy service id buff failed");
671         safe_free(id_buff.val);
672         return service_id;
673     }
674 
675     struct sha256_value srv_sha256 = sha256(&id_buff);
676     safe_free(id_buff.val);
677     id_buff.val = NULL;
678 
679     if (srv_sha256.length > 0) {
680         if (memcpy_s(service_id.service_id, HC_SERVICE_ID_BUFF_LEN, srv_sha256.sha256_value, HC_SHA256_LEN) == EOK) {
681             service_id.length = srv_sha256.length;
682         } else {
683             LOGE("Copy hash value failed");
684         }
685     }
686 
687     return service_id;
688 }
689 
convert_byte_to_hex_string(const uint8_t * byte_array,uint32_t byte_array_size,uint8_t * hex_string,uint32_t out_size)690 static int32_t convert_byte_to_hex_string(const uint8_t *byte_array, uint32_t byte_array_size,
691     uint8_t *hex_string, uint32_t out_size)
692 {
693     int32_t length = 0;
694 
695     check_num_return_val(byte_array_size, length);
696     if (out_size < (byte_array_size * BYTE_TO_HEX_OPER_LENGTH)) { /* doubleword, length*2 */
697         return length;
698     }
699     uint32_t hex_str_arr_len = (uint32_t)(out_size + 1);
700     char *hex_str_arr = (char *)MALLOC(hex_str_arr_len);
701     if (hex_str_arr == NULL) {
702         LOGE("Copy hex arr to string failed");
703         return 0;
704     }
705     (void)memset_s(hex_str_arr, hex_str_arr_len, 0, hex_str_arr_len);
706     for (uint32_t i = 0; i < byte_array_size; i++) {
707         if (sprintf_s((char *)(hex_str_arr + length), hex_str_arr_len - length, "%02x", byte_array[i]) < 0) {
708             LOGE("What happened was that the probability was zero"); /* caller perceives memery error, no return */
709         }
710         length += BYTE_TO_HEX_OPER_LENGTH; /* doubleword, length increases 2 each time */
711     }
712     if (memcpy_s(hex_string, out_size, hex_str_arr, length) != EOK) {
713         LOGE("Copy hex arr to string failed");
714         length = 0;
715     }
716 
717     safe_free(hex_str_arr);
718     hex_str_arr = NULL;
719     return length;
720 }
721 
generate_key_alias(const struct service_id * service_id,const struct hc_auth_id * auth_id,enum huks_key_alias_type key_type)722 struct hc_key_alias generate_key_alias(const struct service_id *service_id,
723     const struct hc_auth_id *auth_id, enum huks_key_alias_type key_type)
724 {
725     struct hc_key_alias temp_alias;
726     (void)memset_s(&temp_alias, sizeof(temp_alias), 0, sizeof(temp_alias));
727     check_ptr_return_val(service_id, temp_alias);
728     check_ptr_return_val(auth_id, temp_alias);
729     if (key_type >= HC_MAX_KEY_TYPE_NUM) {
730         LOGE("Invalid user type");
731         return temp_alias;
732     }
733     if (service_id->length > HC_SERVICE_ID_BUFF_LEN) {
734         LOGE("service_id length is error");
735         return temp_alias;
736     }
737     if (auth_id->length > HC_AUTH_ID_BUFF_LEN) {
738         LOGE("auth_id length is error");
739         return temp_alias;
740     }
741 
742     uint32_t key_type_pair_size = HC_KEY_TYPE_PAIR_LEN;
743     const uint8_t *key_type_pair = g_key_type_pairs[key_type];
744     uint32_t total_len = service_id->length + auth_id->length + key_type_pair_size;
745     struct uint8_buff key_alias_buff;
746 
747     (void)memset_s(&key_alias_buff, sizeof(key_alias_buff), 0, sizeof(key_alias_buff));
748     key_alias_buff.val = (uint8_t *)MALLOC(total_len + 1);
749     if (key_alias_buff.val == NULL) {
750         LOGE("Malloc key alias buff failed");
751         return temp_alias;
752     }
753 
754     key_alias_buff.size = total_len + 1; /* one character longer for terminator */
755     key_alias_buff.length = total_len;
756     (void)memset_s(key_alias_buff.val, key_alias_buff.size, 0, key_alias_buff.size);
757     (void)memcpy_s(key_alias_buff.val, key_alias_buff.size, service_id->service_id, service_id->length);
758     (void)memcpy_s(key_alias_buff.val + service_id->length, key_alias_buff.size - service_id->length,
759                    key_type_pair, key_type_pair_size);
760     (void)memcpy_s(key_alias_buff.val + service_id->length + key_type_pair_size,
761                    key_alias_buff.size - service_id->length - key_type_pair_size,
762                    auth_id->auth_id, auth_id->length);
763 
764     struct hc_key_alias key_alias;
765     (void)memset_s(&key_alias, sizeof(key_alias), 0, sizeof(key_alias));
766     struct sha256_value alias_sha256 = sha256(&key_alias_buff);
767 
768     safe_free(key_alias_buff.val);
769     key_alias_buff.val = NULL;
770     if (alias_sha256.length > 0) {
771         int32_t length = convert_byte_to_hex_string(alias_sha256.sha256_value, alias_sha256.length,
772                                                     key_alias.key_alias, HC_KEY_ALIAS_MAX_LEN);
773         key_alias.length = length;
774     }
775     return key_alias;
776 }
777 
init_x25519_generate_key_input_param_set(struct HksParamSet ** input_param_set)778 static int32_t init_x25519_generate_key_input_param_set(struct HksParamSet **input_param_set)
779 {
780     struct HksParam key_param[] = {
781         {
782             .tag = HKS_TAG_KEY_STORAGE_FLAG,
783             .uint32Param = HKS_STORAGE_TEMP
784         }, {
785             .tag = HKS_TAG_PURPOSE,
786             .uint32Param = HKS_KEY_PURPOSE_SIGN | HKS_KEY_PURPOSE_VERIFY
787         }, {
788             .tag = HKS_TAG_ALGORITHM,
789             .uint32Param = HKS_ALG_X25519
790         }, {
791             .tag = HKS_TAG_KEY_SIZE,
792             .uint32Param = X25519_KEY_LEN
793         }, {
794             .tag = HKS_TAG_IS_ALLOWED_WRAP,
795             .boolParam = true
796         }
797     };
798 
799     int32_t status = construct_param_set(input_param_set, key_param, array_size(key_param));
800     if (status != ERROR_CODE_SUCCESS) {
801         LOGE("construct encrypt param set failed, status=%d", status);
802         return ERROR_CODE_BUILD_PARAM_SET;
803     }
804 
805     return ERROR_CODE_SUCCESS;
806 }
807 
parse_x25519_output_param_set(struct HksParamSet * output_param_set,struct st_key_pair * out_key_pair)808 static int32_t parse_x25519_output_param_set(struct HksParamSet *output_param_set,
809     struct st_key_pair *out_key_pair)
810 {
811     int32_t status = HksFreshParamSet(output_param_set, false); /* false means fresh by local, not though IPC */
812     if (status != ERROR_CODE_SUCCESS) {
813         LOGE("fresh param set failed, status:%d", status);
814         return ERROR_CODE_FRESH_PARAM_SET;
815     }
816 
817     struct HksParam *pub_key_param = NULL;
818     status = HksGetParam(output_param_set, HKS_TAG_ASYMMETRIC_PUBLIC_KEY_DATA, &pub_key_param);
819     if (status != ERROR_CODE_SUCCESS) {
820         LOGE("get pub key from param set failed, status:%d", status);
821         return ERROR_CODE_GET_PUB_KEY_FROM_PARAM_SET;
822     }
823 
824     struct HksParam *priv_key_param = NULL;
825     status = HksGetParam(output_param_set, HKS_TAG_ASYMMETRIC_PRIVATE_KEY_DATA, &priv_key_param);
826     if (status != ERROR_CODE_SUCCESS) {
827         LOGE("get priv key from param set failed, status:%d", status);
828         return ERROR_CODE_GET_PRIV_KEY_FROM_PARAM_SET;
829     }
830 
831     if (memcpy_s(out_key_pair->st_public_key.stpk, HC_ST_PUBLIC_KEY_LEN,
832         pub_key_param->blob.data, pub_key_param->blob.size) != EOK) {
833         LOGE("parse x25519 output param set memcpy public key failed!");
834         return ERROR_CODE_FAILED;
835     }
836     out_key_pair->st_public_key.length = pub_key_param->blob.size;
837 
838     if (memcpy_s(out_key_pair->st_private_key.stsk, HC_ST_PRIVATE_KEY_LEN,
839         priv_key_param->blob.data, priv_key_param->blob.size) != EOK) {
840         LOGE("parse x25519 output param set memcpy private key failed!");
841         return ERROR_CODE_FAILED;
842     }
843     out_key_pair->st_private_key.length = priv_key_param->blob.size;
844 
845     return ERROR_CODE_SUCCESS;
846 }
847 
generate_st_key_pair(struct st_key_pair * out_key_pair)848 int32_t generate_st_key_pair(struct st_key_pair *out_key_pair)
849 {
850     check_ptr_return_val(out_key_pair, HC_INPUT_ERROR);
851     (void)memset_s(out_key_pair, sizeof(*out_key_pair), 0, sizeof(*out_key_pair));
852 
853     struct HksParamSet *input_param_set = NULL;
854     int32_t status = init_x25519_generate_key_input_param_set(&input_param_set);
855     if (status != ERROR_CODE_SUCCESS) {
856         LOGE("init x25519 generate key input param set failed! status:%d", status);
857         return status;
858     }
859 
860     struct HksParamSet *output_param_set = (struct HksParamSet *)MALLOC(X25519_KEY_PARAM_SET_SIZE);
861     if (output_param_set == NULL) {
862         LOGE("allocate buffer for output param set failed");
863         HksFreeParamSet(&input_param_set);
864         return ERROR_CODE_FAILED;
865     }
866 
867     (void)memset_s(output_param_set, X25519_KEY_PARAM_SET_SIZE, 0, X25519_KEY_PARAM_SET_SIZE);
868     output_param_set->paramSetSize = X25519_KEY_PARAM_SET_SIZE;
869 
870     do {
871         status = HksGenerateKey(NULL, input_param_set, output_param_set);
872         if (status != ERROR_CODE_SUCCESS) {
873             LOGE("generate x25519 key failed! status:%d", status);
874             status = ERROR_CODE_GENERATE_KEY;
875             break;
876         }
877 
878         status = parse_x25519_output_param_set(output_param_set, out_key_pair);
879         if (status != ERROR_CODE_SUCCESS) {
880             LOGE("parse x25519 output param set failed! status:%d", status);
881             break;
882         }
883     } while (0);
884 
885     HksFreeParamSet(&input_param_set);
886     safe_free(output_param_set);
887     return status;
888 }
889 
generate_lt_key_pair(struct hc_key_alias * key_alias,const struct hc_auth_id * auth_id)890 int32_t generate_lt_key_pair(struct hc_key_alias *key_alias, const struct hc_auth_id *auth_id)
891 {
892     check_ptr_return_val(key_alias, HC_INPUT_ERROR);
893     check_ptr_return_val(auth_id, HC_INPUT_ERROR);
894 
895     struct HksBlob key_alias_blob = convert_to_blob_from_hc_key_alias(key_alias);
896     check_num_return_val(key_alias_blob.size, ERROR_CODE_FAILED);
897 
898     struct hc_auth_id tmp_id = *auth_id;
899     struct HksParamSet *param_set = NULL;
900     struct HksParam key_param[] = {
901         {
902             .tag = HKS_TAG_ALGORITHM,
903             .uint32Param = HKS_ALG_ED25519
904         }, {
905             .tag = HKS_TAG_KEY_STORAGE_FLAG,
906             .uint32Param = HKS_STORAGE_PERSISTENT
907         }, {
908             .tag = HKS_TAG_PURPOSE,
909             .uint32Param = HKS_KEY_PURPOSE_SIGN | HKS_KEY_PURPOSE_VERIFY
910         }, {
911             .tag = HKS_TAG_KEY_SIZE,
912             .uint32Param = ED25519_KEY_LEN
913         }, {
914             .tag = HKS_TAG_PADDING,
915             .uint32Param = HKS_PADDING_NONE
916         }, {
917             .tag = HKS_TAG_DIGEST,
918             .uint32Param = HKS_DIGEST_SHA256
919         }, {
920             .tag = HKS_TAG_KEY_AUTH_ID,
921             .blob = convert_to_blob_from_hc_auth_id(&tmp_id)
922         }, {
923             .tag = HKS_TAG_IS_ALLOWED_WRAP,
924             .boolParam = true
925         }
926     };
927 
928     int32_t status = construct_param_set(&param_set, key_param, array_size(key_param));
929     if (status != ERROR_CODE_SUCCESS) {
930         LOGE("construct encrypt param set failed, status=%d", status);
931         return ERROR_CODE_BUILD_PARAM_SET;
932     }
933 
934     status = HksGenerateKey(&key_alias_blob, param_set, NULL);
935     if (status != ERROR_CODE_SUCCESS) {
936         LOGE("Hks generate failed, status=%d", status);
937         HksFreeParamSet(&param_set);
938         return ERROR_CODE_GENERATE_KEY;
939     }
940 
941     HksFreeParamSet(&param_set);
942     return ERROR_CODE_SUCCESS;
943 }
944 
export_lt_public_key(struct hc_key_alias * key_alias,struct ltpk * out_public_key)945 int32_t export_lt_public_key(struct hc_key_alias *key_alias, struct ltpk *out_public_key)
946 {
947     check_ptr_return_val(key_alias, HC_INPUT_ERROR);
948     check_ptr_return_val(out_public_key, HC_INPUT_ERROR);
949 
950     struct HksBlob key_alias_blob = convert_to_blob_from_hc_key_alias(key_alias);
951     check_num_return_val(key_alias_blob.size, ERROR_CODE_FAILED);
952 
953     struct HksBlob key = { HC_LT_PUBLIC_KEY_LEN, out_public_key->ltpk };
954     int32_t hks_status = HksExportPublicKey(&key_alias_blob, NULL, &key);
955     if (hks_status != ERROR_CODE_SUCCESS) {
956         LOGE("Export public key failed, status=%d", hks_status);
957         return ERROR_CODE_FAILED;
958     }
959     out_public_key->length = key.size;
960 
961     return ERROR_CODE_SUCCESS;
962 }
963 
delete_key(struct hc_key_alias * key_alias)964 int32_t delete_key(struct hc_key_alias *key_alias)
965 {
966     check_ptr_return_val(key_alias, HC_INPUT_ERROR);
967 
968     struct HksBlob key_alias_blob = convert_to_blob_from_hc_key_alias(key_alias);
969     check_num_return_val(key_alias_blob.size, ERROR_CODE_FAILED);
970 
971     int32_t hks_status = HksDeleteKey(&key_alias_blob, NULL);
972     if (hks_status != ERROR_CODE_SUCCESS) {
973         LOGE("Delete key failed, status=%d", hks_status);
974         return ERROR_CODE_FAILED;
975     }
976 
977     return ERROR_CODE_SUCCESS;
978 }
979 
980 /*
981  * delete long time public key
982  *
983  * @key_alias: long time public key alias
984  * @return 0 -- success, others -- failed
985  */
delete_lt_public_key(struct hc_key_alias * key_alias)986 int32_t delete_lt_public_key(struct hc_key_alias *key_alias)
987 {
988     int32_t hks_status = delete_key(key_alias);
989     if (hks_status != ERROR_CODE_SUCCESS) {
990         LOGE("Delete lt public key failed, status=%d", hks_status);
991     }
992 
993     return hks_status;
994 }
995 
init_import_lt_public_key_param_set(struct HksParamSet ** param_set,const int32_t user_type,const int32_t pair_type,struct hc_auth_id * auth_id)996 static int32_t init_import_lt_public_key_param_set(struct HksParamSet **param_set,
997     const int32_t user_type, const int32_t pair_type, struct hc_auth_id *auth_id)
998 {
999 #if !(defined(_SUPPORT_SEC_CLONE_) || defined(_SUPPORT_SEC_CLONE_SERVER_))
1000     union huks_key_type_union huks_key_type;
1001     huks_key_type.type_struct.user_type = (uint8_t)user_type;
1002     huks_key_type.type_struct.pair_type = (uint8_t)pair_type;
1003     huks_key_type.type_struct.reserved1 = (uint8_t)0;
1004     huks_key_type.type_struct.reserved2 = (uint8_t)0;
1005 #endif
1006 
1007     (void)pair_type;
1008     struct HksParam key_param[] = {
1009         {
1010             .tag = HKS_TAG_ALGORITHM,
1011             .uint32Param = HKS_ALG_ED25519
1012         }, {
1013             .tag = HKS_TAG_KEY_SIZE,
1014             .uint32Param = ED25519_KEY_LEN
1015         }, {
1016             .tag = HKS_TAG_PADDING,
1017             .uint32Param = HKS_PADDING_NONE
1018         }, {
1019             .tag = HKS_TAG_DIGEST,
1020             .uint32Param = HKS_DIGEST_SHA256
1021         }, {
1022             .tag = HKS_TAG_KEY_AUTH_ID,
1023             .blob = convert_to_blob_from_hc_auth_id(auth_id)
1024         }, {
1025             .tag = HKS_TAG_IS_ALLOWED_WRAP,
1026             .boolParam = true
1027         },
1028 #if (defined(_SUPPORT_SEC_CLONE_) || defined(_SUPPORT_SEC_CLONE_SERVER_))
1029         {
1030             .tag = HKS_TAG_PURPOSE,
1031             .uint32Param = HKS_KEY_PURPOSE_VERIFY
1032         }, {
1033             .tag = HKS_TAG_KEY_ROLE,
1034             .uint32Param = user_type
1035         }
1036 #else
1037         {
1038             .tag = HKS_TAG_PURPOSE,
1039             .uint32Param = HKS_KEY_PURPOSE_VERIFY
1040         }, {
1041             .tag = HKS_TAG_KEY_ROLE,
1042             .uint32Param = (uint32_t)huks_key_type.key_type
1043         }
1044 #endif
1045     };
1046 
1047     return construct_param_set(param_set, key_param, array_size(key_param));
1048 }
1049 
import_lt_public_key(struct hc_key_alias * key_alias,struct ltpk * peer_public_key,const int32_t user_type,const int32_t pair_type,struct hc_auth_id * auth_id)1050 int32_t import_lt_public_key(struct hc_key_alias *key_alias, struct ltpk *peer_public_key,
1051     const int32_t user_type, const int32_t pair_type, struct hc_auth_id *auth_id)
1052 {
1053     if ((pair_type < 0) || (pair_type >= HC_MAX_PAIR_TYPE_NUM)) {
1054         return HC_INPUT_ERROR;
1055     }
1056     if ((user_type < 0) || (user_type >= HC_MAX_KEY_TYPE_NUM)) {
1057         return HC_INPUT_ERROR;
1058     }
1059     check_ptr_return_val(key_alias, HC_INPUT_ERROR);
1060     check_ptr_return_val(peer_public_key, HC_INPUT_ERROR);
1061     check_ptr_return_val(auth_id, HC_INPUT_ERROR);
1062 
1063     struct HksBlob key_alias_blob = convert_to_blob_from_hc_key_alias(key_alias);
1064     if (key_alias_blob.size == 0) {
1065         LOGE("Convert key alias to blob failed");
1066         return ERROR_CODE_FAILED;
1067     }
1068 
1069     struct HksBlob ltpk_key_blob = convert_to_blob_from_ltpk(peer_public_key);
1070     if (ltpk_key_blob.size == 0) {
1071         LOGE("Convert ltpk key to blob failed");
1072         return ERROR_CODE_FAILED;
1073     }
1074 
1075     struct HksParamSet *param_set = NULL;
1076     int32_t status = init_import_lt_public_key_param_set(&param_set, user_type, pair_type, auth_id);
1077     if (status != ERROR_CODE_SUCCESS) {
1078         LOGE("init import lt public key input param set failed! status:%d", status);
1079         return status;
1080     }
1081 
1082     status = HksImportKey(&key_alias_blob, param_set, &ltpk_key_blob);
1083 
1084     HksFreeParamSet(&param_set);
1085     return status;
1086 }
1087 
check_lt_public_key_exist(struct hc_key_alias * key_alias)1088 int32_t check_lt_public_key_exist(struct hc_key_alias *key_alias)
1089 {
1090     check_ptr_return_val(key_alias, HC_INPUT_ERROR);
1091     check_num_return_val(key_alias->length, HC_INPUT_ERROR);
1092     struct HksBlob key_alias_blob = convert_to_blob_from_hc_key_alias(key_alias);
1093     int32_t hks_status = HksKeyExist(&key_alias_blob, NULL);
1094     if (hks_status == 0) {
1095         return ERROR_CODE_SUCCESS;
1096     } else {
1097         LOGI("Check lt public key exist failed, status = %d", hks_status);
1098         return ERROR_CODE_FAILED;
1099     }
1100 }
1101 
check_key_exist(struct hc_key_alias * key_alias)1102 int32_t check_key_exist(struct hc_key_alias *key_alias)
1103 {
1104     check_ptr_return_val(key_alias, HC_INPUT_ERROR);
1105     check_num_return_val(key_alias->length, HC_INPUT_ERROR);
1106     struct HksBlob key_alias_blob = convert_to_blob_from_hc_key_alias(key_alias);
1107     int32_t hks_status = HksKeyExist(&key_alias_blob, NULL);
1108     if (hks_status == 0) {
1109         return ERROR_CODE_SUCCESS;
1110     } else {
1111         LOGI("Check key exist failed, status = %d", hks_status);
1112         return ERROR_CODE_FAILED;
1113     }
1114 }
1115 
init_key_info_list(struct HksKeyInfo * key_info_list,int32_t len)1116 static int32_t init_key_info_list(struct HksKeyInfo *key_info_list, int32_t len)
1117 {
1118     (void)memset_s(key_info_list, sizeof(struct HksKeyInfo) * len, 0, sizeof(struct HksKeyInfo) * len);
1119     for (int32_t i = 0; i < len; ++i) {
1120         struct HksKeyInfo key_info_tmp;
1121 
1122         key_info_tmp.alias.data = (uint8_t *)MALLOC(HC_KEY_ALIAS_MAX_LEN);
1123         if (key_info_tmp.alias.data == NULL) {
1124             LOGE("allocate space for key info alias data failed");
1125             return ERROR_CODE_NO_SPACE;
1126         }
1127         (void)memset_s(key_info_tmp.alias.data, HC_KEY_ALIAS_MAX_LEN, 0, HC_KEY_ALIAS_MAX_LEN);
1128         key_info_tmp.alias.size = HC_KEY_ALIAS_MAX_LEN;
1129 
1130         key_info_tmp.paramSet = (struct HksParamSet *)MALLOC(DEFAULT_PARAM_SET_OUT_SIZE);
1131         if (key_info_tmp.paramSet == NULL) {
1132             safe_free(key_info_tmp.alias.data);
1133             key_info_tmp.alias.data = NULL;
1134             LOGE("allocate space for key param set failed");
1135             return ERROR_CODE_NO_SPACE;
1136         }
1137         (void)memset_s(key_info_tmp.paramSet, DEFAULT_PARAM_SET_OUT_SIZE, 0, DEFAULT_PARAM_SET_OUT_SIZE);
1138         key_info_tmp.paramSet->paramSetSize = DEFAULT_PARAM_SET_OUT_SIZE;
1139 
1140         key_info_list[i] = key_info_tmp;
1141     }
1142     return 0;
1143 }
1144 
inner_get_lt_info_by_key_info(struct HksKeyInfo * key_info,struct huks_key_type * out_key_type,struct hc_auth_id * out_auth_id)1145 static int32_t inner_get_lt_info_by_key_info(struct HksKeyInfo *key_info,
1146     struct huks_key_type *out_key_type, struct hc_auth_id *out_auth_id)
1147 {
1148     union huks_key_type_union key_type_union;
1149     struct HksParam *key_role = NULL;
1150     int32_t status = HksGetParam(key_info->paramSet, HKS_TAG_KEY_ROLE, &key_role);
1151     if (status != ERROR_CODE_SUCCESS) {
1152         LOGE("get key role from param set failed, status:%d", status);
1153         return ERROR_CODE_FAILED;
1154     }
1155 
1156     key_type_union.key_type = key_role->uint32Param;
1157     out_key_type->user_type = key_type_union.type_struct.user_type;
1158     out_key_type->pair_type = key_type_union.type_struct.pair_type;
1159     out_key_type->reserved1 = key_type_union.type_struct.reserved1;
1160     out_key_type->reserved2 = key_type_union.type_struct.reserved2;
1161 
1162     struct HksParam *auth_id = NULL;
1163     status = HksGetParam(key_info->paramSet, HKS_TAG_KEY_AUTH_ID, &auth_id);
1164     if (status != ERROR_CODE_SUCCESS) {
1165         LOGE("get auth id from param set failed, status:%d", status);
1166         return ERROR_CODE_FAILED;
1167     }
1168 
1169     if (memcpy_s(out_auth_id->auth_id, HC_AUTH_ID_BUFF_LEN,
1170         auth_id->blob.data, auth_id->blob.size) != EOK) {
1171         LOGE("Copy key param failed");
1172         return ERROR_CODE_FAILED;
1173     }
1174     out_auth_id->length = auth_id->blob.size;
1175 
1176     return status;
1177 }
1178 
inner_get_lt_info_by_key_alias(struct HksBlob * key_alias,struct huks_key_type * out_key_type,struct hc_auth_id * out_auth_id)1179 static int32_t inner_get_lt_info_by_key_alias(struct HksBlob *key_alias,
1180     struct huks_key_type *out_key_type, struct hc_auth_id *out_auth_id)
1181 {
1182     struct HksParamSet *output_param_set = (struct HksParamSet *)MALLOC(DEFAULT_PARAM_SET_OUT_SIZE);
1183     if (output_param_set == NULL) {
1184         LOGE("allocate space for param set out failed");
1185         return ERROR_CODE_FAILED;
1186     }
1187     (void)memset_s(output_param_set, DEFAULT_PARAM_SET_OUT_SIZE, 0, DEFAULT_PARAM_SET_OUT_SIZE);
1188     output_param_set->paramSetSize = DEFAULT_PARAM_SET_OUT_SIZE;
1189 
1190     int32_t status = HksGetKeyParamSet(key_alias, NULL, output_param_set);
1191     if (status != ERROR_CODE_SUCCESS) {
1192         LOGE("Get huks key param set failed");
1193         goto get_key_info_free;
1194     }
1195 
1196     status = HksFreshParamSet(output_param_set, false);
1197     if (status != ERROR_CODE_SUCCESS) {
1198         LOGE("fresh param set failed, status:%d", status);
1199         goto get_key_info_free;
1200     }
1201 
1202     struct HksParam *key_role = NULL;
1203     status = HksGetParam(output_param_set, HKS_TAG_KEY_ROLE, &key_role);
1204     if (status != ERROR_CODE_SUCCESS) {
1205         LOGE("get key role from param set failed, status:%d", status);
1206         goto get_key_info_free;
1207     }
1208 
1209     union huks_key_type_union key_type_union;
1210     key_type_union.key_type = key_role->uint32Param;
1211     out_key_type->user_type = key_type_union.type_struct.user_type;
1212     out_key_type->pair_type = key_type_union.type_struct.pair_type;
1213     out_key_type->reserved1 = key_type_union.type_struct.reserved1;
1214     out_key_type->reserved2 = key_type_union.type_struct.reserved2;
1215 
1216     struct HksParam *auth_id = NULL;
1217     status = HksGetParam(output_param_set, HKS_TAG_KEY_AUTH_ID, &auth_id);
1218     if (status != ERROR_CODE_SUCCESS) {
1219         LOGE("get auth id from param set failed, status:%d", status);
1220         goto get_key_info_free;
1221     }
1222 
1223     if (memcpy_s(out_auth_id->auth_id, HC_AUTH_ID_BUFF_LEN, auth_id->blob.data, auth_id->blob.size) != EOK) {
1224         LOGE("Copy key param failed");
1225         goto get_key_info_free;
1226     }
1227     out_auth_id->length = auth_id->blob.size;
1228 
1229 get_key_info_free:
1230     safe_free(output_param_set);
1231     return status;
1232 }
1233 
get_lt_key_info(struct hc_key_alias * alias,struct huks_key_type * out_key_type,struct hc_auth_id * out_auth_id)1234 int32_t get_lt_key_info(struct hc_key_alias *alias, struct huks_key_type *out_key_type, struct hc_auth_id *out_auth_id)
1235 {
1236     check_ptr_return_val(alias, HC_INPUT_ERROR);
1237     check_ptr_return_val(out_key_type, HC_INPUT_ERROR);
1238     check_ptr_return_val(out_auth_id, HC_INPUT_ERROR);
1239 
1240     struct HksBlob alias_blob = convert_to_blob_from_hc_key_alias(alias);
1241     return inner_get_lt_info_by_key_alias(&alias_blob, out_key_type, out_auth_id);
1242 }
1243 
check_key_alias_is_owner(struct hc_key_alias * key_alias)1244 int32_t check_key_alias_is_owner(struct hc_key_alias *key_alias)
1245 {
1246     check_ptr_return_val(key_alias, HC_INPUT_ERROR);
1247     check_num_return_val(key_alias->length, HC_INPUT_ERROR);
1248 
1249     int32_t error_code = check_lt_public_key_exist(key_alias);
1250     if (error_code != ERROR_CODE_SUCCESS) {
1251         LOGE("Key is not exist");
1252         return error_code;
1253     }
1254 
1255     struct huks_key_type key_type;
1256     struct hc_auth_id auth_id;
1257 
1258     struct HksBlob key_alias_blob = convert_to_blob_from_hc_key_alias(key_alias);
1259     error_code = inner_get_lt_info_by_key_alias(&key_alias_blob, &key_type, &auth_id);
1260     if (error_code != ERROR_CODE_SUCCESS) {
1261         LOGE("Get key info failed");
1262         return error_code;
1263     }
1264 
1265     if (key_type.user_type != (uint8_t)HC_USER_TYPE_CONTROLLER) {
1266         return ERROR_CODE_FAILED;
1267     }
1268     if (key_type.pair_type == (uint8_t)HC_PAIR_TYPE_BIND) {
1269         return ERROR_CODE_SUCCESS;
1270     } else {
1271         return ERROR_CODE_FAILED;
1272     }
1273 }
1274 
load_lt_public_key_list(const struct hc_auth_id * owner_id,int32_t trust_user_type,struct HksKeyInfo * key_info_list,uint32_t list_count,struct hc_auth_id * out_auth_list)1275 static uint32_t load_lt_public_key_list(const struct hc_auth_id *owner_id, int32_t trust_user_type,
1276     struct HksKeyInfo *key_info_list, uint32_t list_count, struct hc_auth_id *out_auth_list)
1277 {
1278     uint8_t pair_type = owner_id == NULL ? (uint8_t)HC_PAIR_TYPE_BIND : (uint8_t)HC_PAIR_TYPE_AUTH;
1279     uint8_t user_type = (uint8_t)trust_user_type;
1280     int32_t err_code;
1281     struct huks_key_type key_type;
1282     struct hc_auth_id auth_id;
1283     uint32_t effect_count = 0;
1284 
1285     if ((trust_user_type < 0) || (trust_user_type >= HC_MAX_KEY_TYPE_NUM)) {
1286         return effect_count;
1287     }
1288     for (uint32_t i = 0; i < list_count; i++) {
1289         struct HksParam *key_flag_param = NULL;
1290         int32_t status = HksGetParam(key_info_list[i].paramSet, HKS_TAG_KEY_FLAG, &key_flag_param);
1291         if (status != ERROR_CODE_SUCCESS) {
1292             LOGE("get key flag from param set failed, status:%d", status);
1293             return ERROR_CODE_FAILED;
1294         }
1295         if (key_flag_param->uint32Param == HKS_KEY_FLAG_GENERATE_KEY) {
1296             continue;
1297         }
1298         err_code = inner_get_lt_info_by_key_info(&key_info_list[i], &key_type, &auth_id);
1299         if (err_code != ERROR_CODE_SUCCESS) {
1300             continue;
1301         }
1302         if (key_type.user_type != user_type) {
1303             continue;
1304         }
1305         if (user_type == (uint8_t)HC_USER_TYPE_CONTROLLER) {
1306             if (key_type.pair_type != pair_type) {
1307                 continue;
1308             }
1309         }
1310         if (memcpy_s(out_auth_list[effect_count].auth_id, HC_AUTH_ID_BUFF_LEN,
1311                      auth_id.auth_id, auth_id.length) != EOK) {
1312             LOGE("Copy from temp hc_auth_id to out_auth_list failed");
1313             continue;
1314         }
1315         out_auth_list[effect_count].length = auth_id.length;
1316         effect_count++;
1317     }
1318     return effect_count;
1319 }
1320 
get_lt_public_key_list(const struct hc_auth_id * owner_auth_id,int32_t trust_user_type,struct hc_auth_id * out_auth_list,uint32_t * out_count)1321 int32_t get_lt_public_key_list(const struct hc_auth_id *owner_auth_id, int32_t trust_user_type,
1322     struct hc_auth_id *out_auth_list, uint32_t *out_count)
1323 {
1324     check_ptr_return_val(out_auth_list, HC_INPUT_ERROR);
1325     check_ptr_return_val(out_count, HC_INPUT_ERROR);
1326 
1327     int32_t error_code = ERROR_CODE_SUCCESS;
1328     struct HksKeyInfo key_info_list[HC_PUB_KEY_ALIAS_MAX_NUM];
1329     int32_t status = init_key_info_list(key_info_list, HC_PUB_KEY_ALIAS_MAX_NUM);
1330     if (status != ERROR_CODE_SUCCESS) {
1331         LOGE("Init key info list failed, status=%d", status);
1332         error_code = ERROR_CODE_FAILED;
1333         goto exit;
1334     }
1335 
1336     uint32_t list_count = HC_PUB_KEY_ALIAS_MAX_NUM;
1337     status = HksGetKeyInfoList(NULL, key_info_list, &list_count);
1338     if (status != ERROR_CODE_SUCCESS) {
1339         LOGE("Huks get pub key info list failed, status=%d", status);
1340         error_code = ERROR_CODE_FAILED;
1341         goto exit;
1342     }
1343 
1344     /* filter with trust_user_type */
1345     uint32_t effect_count = load_lt_public_key_list(owner_auth_id, trust_user_type, key_info_list,
1346                                                     list_count, out_auth_list);
1347     /* output param */
1348     *out_count = effect_count;
1349 
1350 exit:
1351     for (int32_t i = 0; i < HC_PUB_KEY_ALIAS_MAX_NUM; ++i) {
1352         safe_free(key_info_list[i].alias.data);
1353         safe_free(key_info_list[i].paramSet);
1354     }
1355     return error_code;
1356 }
1357 
gen_sign_key_param_set(struct HksParamSet ** param_set)1358 static int32_t gen_sign_key_param_set(struct HksParamSet **param_set)
1359 {
1360     struct HksParam params[] = {
1361         {
1362             .tag = HKS_TAG_PURPOSE,
1363             .uint32Param = HKS_KEY_PURPOSE_SIGN /* correspond to old key usage */
1364         }, {
1365             .tag = HKS_TAG_ALGORITHM,
1366             .uint32Param = HKS_ALG_ED25519 /* alg, correspond to old key type */
1367         }, {
1368             .tag = HKS_TAG_PADDING,
1369             .uint32Param = HKS_PADDING_NONE
1370         }, {
1371             .tag = HKS_TAG_DIGEST,
1372             .uint32Param = HKS_DIGEST_SHA256
1373         }
1374     };
1375 
1376     int32_t status = construct_param_set(param_set, params, array_size(params));
1377     if (status != ERROR_CODE_SUCCESS) {
1378         LOGE("construct param set for sign failed, status:%d", status);
1379     }
1380 
1381     return status;
1382 }
1383 
sign(struct hc_key_alias * key_alias,const struct uint8_buff * message,struct signature * out_signature)1384 int32_t sign(struct hc_key_alias *key_alias, const struct uint8_buff *message, struct signature *out_signature)
1385 {
1386     check_ptr_return_val(key_alias, HC_INPUT_ERROR);
1387     check_ptr_return_val(message, HC_INPUT_ERROR);
1388     check_ptr_return_val(out_signature, HC_INPUT_ERROR);
1389     check_num_return_val(key_alias->length, HC_INPUT_ERROR);
1390 
1391     struct HksBlob key_alias_blob = convert_to_blob_from_hc_key_alias(key_alias);
1392     if (key_alias_blob.size == 0) {
1393         LOGE("Convert hks key alias to blob failed");
1394         return ERROR_CODE_FAILED;
1395     }
1396 
1397     struct sha256_value sha256_value = sha256(message);
1398     if (sha256_value.length == 0) {
1399         LOGE("Get sha256 hash failed");
1400         return ERROR_CODE_FAILED;
1401     }
1402 
1403     struct HksBlob hash = convert_to_blob_from_sha256_value(&sha256_value);
1404     if (hash.size == 0) {
1405         LOGE("Convert sha256 hash to blob failed");
1406         return ERROR_CODE_FAILED;
1407     }
1408 
1409     struct HksParamSet *key_param_set = NULL;
1410     int32_t hks_status = gen_sign_key_param_set(&key_param_set);
1411     if (hks_status != ERROR_CODE_SUCCESS) {
1412         LOGE("gen sign key param set failed, status:%d", hks_status);
1413         return ERROR_CODE_FAILED;
1414     }
1415 
1416     struct HksBlob signature = { HC_SIGNATURE_LEN, out_signature->signature };
1417     hks_status = HksSign(&key_alias_blob, key_param_set, &hash, &signature);
1418     if ((hks_status == ERROR_CODE_SUCCESS) && (signature.size == HC_SIGNATURE_LEN)) {
1419         out_signature->length = HC_SIGNATURE_LEN;
1420     } else {
1421         LOGE("Sign failed, status=%d", hks_status);
1422         hks_status = ERROR_CODE_FAILED;
1423     }
1424 
1425     HksFreeParamSet(&key_param_set);
1426     return hks_status;
1427 }
1428 
gen_verify_key_param_set(const bool is_keyalias,const uint32_t key_size,const int32_t user_type,struct HksParamSet ** param_set)1429 static int gen_verify_key_param_set(const bool is_keyalias, const uint32_t key_size,
1430     const int32_t user_type, struct HksParamSet **param_set)
1431 {
1432     struct HksParam params[] = {
1433         {
1434             .tag = HKS_TAG_PURPOSE,
1435             .uint32Param = HKS_KEY_PURPOSE_VERIFY
1436         }, {
1437             .tag = HKS_TAG_ALGORITHM,
1438             .uint32Param = HKS_ALG_ED25519
1439         }, {
1440             .tag = HKS_TAG_DIGEST,
1441             .uint32Param = HKS_DIGEST_SHA256
1442         }, {
1443             .tag = HKS_TAG_PADDING,
1444             .uint32Param = HKS_PADDING_NONE
1445         }, {
1446             .tag = HKS_TAG_KEY_ROLE,
1447             .uint32Param = (uint32_t)user_type
1448         }, {
1449             .tag = HKS_TAG_IS_KEY_ALIAS,
1450             .boolParam = is_keyalias
1451         }, {
1452             .tag = HKS_TAG_KEY_SIZE,
1453             .uint32Param = (is_keyalias ? 0 : key_size)
1454         }
1455     };
1456 
1457     int32_t status = construct_param_set(param_set, params, array_size(params));
1458     if (status != ERROR_CODE_SUCCESS) {
1459         LOGE("construct param set for verify failed, status:%d", status);
1460     }
1461 
1462     return status;
1463 }
1464 
verify(struct hc_key_alias * key_alias,const int32_t user_type,const struct uint8_buff * message,struct signature * signature)1465 int32_t verify(struct hc_key_alias *key_alias, const int32_t user_type,
1466     const struct uint8_buff *message, struct signature *signature)
1467 {
1468     check_ptr_return_val(key_alias, HC_INPUT_ERROR);
1469     check_ptr_return_val(message, HC_INPUT_ERROR);
1470     check_ptr_return_val(signature, HC_INPUT_ERROR);
1471     check_num_return_val(key_alias->length, HC_INPUT_ERROR);
1472 
1473     int32_t error_code = ERROR_CODE_FAILED;
1474     struct HksBlob key_alias_blob = convert_to_blob_from_hc_key_alias(key_alias);
1475     if (key_alias_blob.size == 0) {
1476         LOGE("Convert hks key alias to blob failed");
1477         return error_code;
1478     }
1479 
1480     struct HksBlob signature_blob = convert_to_blob_from_signature(signature);
1481     if (signature_blob.size == 0) {
1482         LOGE("Convert hks signature to blob failed");
1483         return error_code;
1484     }
1485 
1486     struct sha256_value sha256_value = sha256(message);
1487     if (sha256_value.length == 0) {
1488         LOGE("Get sha256 hash failed. message val:%s, message length:%d", message->val, message->length);
1489         return error_code;
1490     }
1491 
1492     struct HksBlob hash = convert_to_blob_from_sha256_value(&sha256_value);
1493     if (hash.size == 0) {
1494         LOGE("Convert sha256 hash to blob failed");
1495         return error_code;
1496     }
1497 
1498     /* true: is key alias, 0: key alias have not key size */
1499     struct HksParamSet *key_param_set = NULL;
1500     int32_t hks_status = gen_verify_key_param_set(true, 0, user_type, &key_param_set);
1501     if (hks_status != ERROR_CODE_SUCCESS) {
1502         LOGE("failed to gen verify key param set, status:%d", hks_status);
1503         return error_code;
1504     }
1505 
1506     hks_status = HksVerify(&key_alias_blob, key_param_set, &hash, &signature_blob);
1507     if (hks_status == 0) {
1508         error_code = ERROR_CODE_SUCCESS;
1509     } else {
1510         LOGE("Verify failed. status=%d", hks_status);
1511         if (check_lt_public_key_exist(key_alias) != ERROR_CODE_SUCCESS) {
1512             error_code = ERROR_CODE_NO_PEER_PUBLIC_KEY;
1513         }
1514     }
1515 
1516     HksFreeParamSet(&key_param_set);
1517     return error_code;
1518 }
1519 
verify_with_public_key(const int32_t user_type,const struct uint8_buff * message,struct var_buffer * public_key,struct signature * signature)1520 int32_t verify_with_public_key(const int32_t user_type, const struct uint8_buff *message,
1521     struct var_buffer *public_key, struct signature *signature)
1522 {
1523     check_ptr_return_val(message, HC_INPUT_ERROR);
1524     check_ptr_return_val(public_key, HC_INPUT_ERROR);
1525     check_ptr_return_val(signature, HC_INPUT_ERROR);
1526 
1527     int32_t error_code = ERROR_CODE_FAILED;
1528     struct sha256_value sha256_value = sha256(message);
1529     if (sha256_value.length == 0) {
1530         LOGE("Get sha256 hash failed");
1531         return error_code;
1532     }
1533 
1534     struct HksBlob hash = convert_to_blob_from_sha256_value(&sha256_value);
1535     if (hash.size == 0) {
1536         LOGE("Convert sha256 hash to blob failed");
1537         return error_code;
1538     }
1539 
1540     struct HksBlob signature_blob = convert_to_blob_from_signature(signature);
1541     if (signature_blob.size == 0) {
1542         LOGE("Convert hks signature to blob failed");
1543         return error_code;
1544     }
1545 
1546     struct HksParamSet *key_param_set = NULL;
1547     int32_t hks_status = gen_verify_key_param_set(false, /* false: is public key */
1548         public_key->length * BITS_PER_BYTE, user_type, &key_param_set);
1549     if (hks_status != ERROR_CODE_SUCCESS) {
1550         LOGE("gen verify with public key param set failed, status:%d", hks_status);
1551         return error_code;
1552     }
1553 
1554     struct HksBlob public_key_blob = { public_key->length, public_key->data };
1555     hks_status = HksVerify(&public_key_blob, key_param_set, &hash, &signature_blob);
1556     if (hks_status == 0) {
1557         error_code = ERROR_CODE_SUCCESS;
1558     } else {
1559         LOGE("Verify failed, status=%d", hks_status);
1560         error_code = ERROR_CODE_FAILED;
1561     }
1562 
1563     HksFreeParamSet(&key_param_set);
1564     return error_code;
1565 }
1566 
gen_agreed_key_param_set(struct HksParamSet ** param_set)1567 static int32_t gen_agreed_key_param_set(struct HksParamSet **param_set)
1568 {
1569     struct HksParam params[] = {
1570         {
1571             .tag = HKS_TAG_PURPOSE,
1572             .uint32Param = HKS_KEY_PURPOSE_DERIVE
1573         }, {
1574             .tag = HKS_TAG_ALGORITHM,
1575             .uint32Param = HKS_ALG_X25519
1576         }, {
1577             .tag = HKS_TAG_KEY_SIZE,
1578             .uint32Param = HC_ST_PUBLIC_KEY_LEN * BITS_PER_BYTE
1579         }, {
1580             .tag = HKS_TAG_IS_KEY_ALIAS,
1581             .boolParam = false
1582         }
1583     };
1584 
1585     int32_t status = construct_param_set(param_set, params, array_size(params));
1586     if (status != ERROR_CODE_SUCCESS) {
1587         LOGE("construct param set for agreed key failed, status:%d", status);
1588     }
1589 
1590     return status;
1591 }
1592 
compute_sts_shared_secret(struct stsk * self_private_key,struct stpk * peer_public_key,struct sts_shared_secret * out_shared_key)1593 int32_t compute_sts_shared_secret(struct stsk *self_private_key, struct stpk *peer_public_key,
1594     struct sts_shared_secret *out_shared_key)
1595 {
1596     check_ptr_return_val(self_private_key, HC_INPUT_ERROR);
1597     check_num_return_val(self_private_key->length, HC_INPUT_ERROR);
1598     check_ptr_return_val(peer_public_key, HC_INPUT_ERROR);
1599     check_num_return_val(peer_public_key->length, HC_INPUT_ERROR);
1600     check_ptr_return_val(out_shared_key, HC_INPUT_ERROR);
1601 
1602     (void)memset_s(out_shared_key, sizeof(*out_shared_key), 0, sizeof(*out_shared_key));
1603     int32_t error_code = ERROR_CODE_FAILED;
1604     struct HksBlob self_private_key_blob = convert_to_blob_from_stsk(self_private_key);
1605     if (self_private_key_blob.size == 0) {
1606         LOGE("Convert key alias for private key to blob failed");
1607         return error_code;
1608     }
1609 
1610     struct HksBlob peer_public_key_blob = convert_to_blob_from_stpk(peer_public_key);
1611     if (peer_public_key_blob.size == 0) {
1612         LOGE("Convert key alias for peer public key to blob failed");
1613         return error_code;
1614     }
1615 
1616     struct HksParamSet *param_set = NULL;
1617     int32_t hks_status = gen_agreed_key_param_set(&param_set);
1618     if (hks_status != ERROR_CODE_SUCCESS) {
1619         LOGE("gen agreed key param set failed! status:%d", hks_status);
1620         return error_code;
1621     }
1622 
1623     struct HksBlob key_alias_for_agreed_key = { HC_STS_SHARED_SECRET_LENGTH, out_shared_key->sts_shared_secret };
1624     hks_status = HksAgreeKey(param_set, &self_private_key_blob, &peer_public_key_blob, &key_alias_for_agreed_key);
1625     if ((hks_status == 0) && (key_alias_for_agreed_key.size == HC_STS_SHARED_SECRET_LENGTH)) {
1626         out_shared_key->length = key_alias_for_agreed_key.size;
1627         error_code = ERROR_CODE_SUCCESS;
1628     } else {
1629         LOGE("Key agreement by alias failed, status:%d", hks_status);
1630     }
1631     return error_code;
1632 }
1633 
key_info_init(void)1634 int32_t key_info_init(void)
1635 {
1636     int32_t ret = HksInitialize();
1637     if (ret == HKS_SUCCESS) {
1638         return ERROR_CODE_SUCCESS;
1639     }
1640 
1641     if ((ret != HKS_ERROR_INVALID_KEY_FILE) && (ret != HKS_ERROR_CRYPTO_ENGINE_ERROR) &&
1642         (ret != HKS_ERROR_UPDATE_ROOT_KEY_MATERIAL_FAIL)) {
1643         LOGE("Hks: Init hks failed, ret: %d", ret);
1644         return ERROR_CODE_FAILED;
1645     }
1646 
1647     DBG_OUT("Hks: The local hks file needs to be refreshed!");
1648     LOGI("Start to delete local database file!");
1649     ret = HksRefreshKeyInfo();
1650     if (ret != HKS_SUCCESS) {
1651         LOGE("Hks: HksRefreshKeyInfo failed, ret:%d", ret);
1652         return ERROR_CODE_FAILED;
1653     }
1654     ret = HksInitialize();
1655     if (ret != HKS_SUCCESS) {
1656         LOGE("Hks: Init hks failed, ret:%d", ret);
1657         return ERROR_CODE_FAILED;
1658     }
1659     return ERROR_CODE_SUCCESS;
1660 }
1661 
1662 #if (defined(_SUPPORT_SEC_CLONE_) || defined(_SUPPORT_SEC_CLONE_SERVER_))
init_aes_ccm_decrypt_key_params(struct HksParamSet ** param_set,const struct uint8_buff * cipher,const struct aes_aad * aad)1663 static int32_t init_aes_ccm_decrypt_key_params(struct HksParamSet **param_set,
1664     const struct uint8_buff *cipher, const struct aes_aad *aad)
1665 {
1666     struct HksBlob hks_nonce = { HC_CCM_NONCE_LEN, cipher->val };
1667     struct uint8_buff aad_data = { (uint8_t *)aad->aad, aad->length, aad->length };
1668     struct sha256_value aad_sha = sha256(&aad_data);
1669     struct HksBlob hks_aad = { aad_sha.length, aad_sha.sha256_value };
1670 
1671     struct HksParam params[] = {
1672         {
1673             .tag = HKS_TAG_PURPOSE,
1674             .uint32Param = HKS_KEY_PURPOSE_DECRYPT
1675         }, {
1676             .tag = HKS_TAG_ALGORITHM,
1677             .uint32Param = HKS_ALG_AES
1678         }, {
1679             .tag = HKS_TAG_BLOCK_MODE,
1680             .uint32Param = HKS_MODE_CCM
1681         }, {
1682             .tag = HKS_TAG_PADDING,
1683             .uint32Param = HKS_PADDING_NONE
1684         }, {
1685             .tag = HKS_TAG_DIGEST,
1686             .uint32Param = HKS_DIGEST_SHA256
1687         }, {
1688             .tag = HKS_TAG_KEY_SIZE,
1689             .uint32Param = HKS_AES_KEY_SIZE_256
1690         }, {
1691             .tag = HKS_TAG_NONCE,
1692             .blob = hks_nonce
1693         }, {
1694             .tag = HKS_TAG_ASSOCIATED_DATA,
1695             .blob = hks_aad
1696         }
1697     };
1698 
1699     int32_t status = construct_param_set(param_set, params, array_size(params));
1700     if (status != ERROR_CODE_SUCCESS) {
1701         LOGE("construct param set for AES CCM decrypt key failed");
1702     }
1703 
1704     return status;
1705 }
1706 
aes_ccm_decrypt(struct var_buffer * key,const struct uint8_buff * cipher,struct aes_aad * aad,struct uint8_buff * out_plain)1707 int32_t aes_ccm_decrypt(struct var_buffer *key, const struct uint8_buff *cipher,
1708     struct aes_aad *aad, struct uint8_buff *out_plain)
1709 {
1710     check_ptr_return_val(key, HC_INPUT_ERROR);
1711     check_ptr_return_val(cipher, HC_INPUT_ERROR);
1712     check_ptr_return_val(aad, HC_INPUT_ERROR);
1713     check_ptr_return_val(out_plain, HC_INPUT_ERROR);
1714     if (cipher->length < HC_AES_GCM_NONCE_LEN) {
1715         LOGE("cipher length is no larger than salt size");
1716         return ERROR_CODE_FAILED;
1717     }
1718 
1719     struct HksParamSet *key_param_set = NULL;
1720     int32_t hks_status = init_aes_ccm_decrypt_key_params(&key_param_set, cipher, aad);
1721     if (hks_status != ERROR_CODE_SUCCESS) {
1722         LOGE("init aes ccm decrypt key param set failed, status:%d", hks_status);
1723         return ERROR_CODE_FAILED;
1724     }
1725 
1726     struct HksBlob hks_key = { key->length, key->data };
1727     struct HksBlob cipher_text_with_tag = { cipher->length - HC_CCM_NONCE_LEN, cipher->val + HC_CCM_NONCE_LEN };
1728     struct HksBlob plain_text = { out_plain->size, out_plain->val };
1729 
1730     hks_status = HksDecrypt(&hks_key, key_param_set, &cipher_text_with_tag, &plain_text);
1731     if (hks_status != ERROR_CODE_SUCCESS) {
1732         LOGE("Huks aead decrypt failed, status:%d", hks_status);
1733         HksFreeParamSet(&key_param_set);
1734         return ERROR_CODE_FAILED;
1735     }
1736     out_plain->length = plain_text.size;
1737 
1738     HksFreeParamSet(&key_param_set);
1739     return hks_status;
1740 }
1741 
gen_lt_x25519_key_param_set(struct HksParamSet ** param_set,const struct hc_auth_id * auth_id)1742 static int32_t gen_lt_x25519_key_param_set(struct HksParamSet **param_set, const struct hc_auth_id *auth_id)
1743 {
1744     struct hc_auth_id tmp_id = *auth_id;
1745     struct HksParam params[] = {
1746         {
1747             .tag = HKS_TAG_PURPOSE,
1748             .uint32Param = HKS_KEY_PURPOSE_SIGN | HKS_KEY_PURPOSE_VERIFY
1749         }, {
1750             .tag = HKS_TAG_KEY_STORAGE_FLAG,
1751             .uint32Param = HKS_STORAGE_PERSISTENT
1752         }, {
1753             .tag = HKS_TAG_ALGORITHM,
1754             .uint32Param = HKS_ALG_X25519
1755         }, {
1756             .tag = HKS_TAG_PADDING,
1757             .uint32Param = HKS_PADDING_NONE
1758         }, {
1759             .tag = HKS_TAG_DIGEST,
1760             .uint32Param = HKS_DIGEST_SHA256
1761         }, {
1762             .tag = HKS_TAG_KEY_SIZE,
1763             .uint32Param = HC_PARAM_KEY_LEN
1764         }, {
1765             .tag = HKS_TAG_KEY_AUTH_ID,
1766             .blob = convert_to_blob_from_hc_auth_id(&tmp_id)
1767         }
1768     };
1769 
1770     int32_t status = construct_param_set(param_set, params, array_size(params));
1771     if (status != ERROR_CODE_SUCCESS) {
1772         LOGE("construct param set for lt x25519 key failed");
1773     }
1774 
1775     return status;
1776 }
1777 
generate_lt_X25519_key_pair(struct hc_key_alias * key_alias,const struct hc_auth_id * auth_id)1778 int32_t generate_lt_X25519_key_pair(struct hc_key_alias *key_alias, const struct hc_auth_id *auth_id)
1779 {
1780     check_ptr_return_val(key_alias, HC_INPUT_ERROR);
1781     check_ptr_return_val(auth_id, HC_INPUT_ERROR);
1782 
1783     struct HksBlob key_alias_blob = convert_to_blob_from_hc_key_alias(key_alias);
1784     check_num_return_val(key_alias_blob.size, ERROR_CODE_FAILED);
1785 
1786     struct HksParamSet *key_param_set = NULL;
1787     int32_t status = gen_lt_x25519_key_param_set(&key_param_set, auth_id);
1788     if (status != ERROR_CODE_SUCCESS) {
1789         LOGE("init lt x25519 key pair param set failed, status:%d", status);
1790         return ERROR_CODE_FAILED;
1791     }
1792 
1793     status = HksGenerateKey(&key_alias_blob, key_param_set, NULL);
1794     if (status != ERROR_CODE_SUCCESS) {
1795         LOGE("Hks generate failed, status:%d", status);
1796     }
1797 
1798     if (HksKeyExist(&key_alias_blob, NULL) == 0) {
1799         LOGI("Generate key success, key exist");
1800     }
1801 
1802     HksFreeParamSet(&key_param_set);
1803     return status;
1804 }
1805 
gen_key_attestation_param_set(struct HksParamSet ** param_set,const struct uint8_buff * challenge,struct HksBlob * key_alias_blob)1806 static int32_t gen_key_attestation_param_set(struct HksParamSet **param_set,
1807     const struct uint8_buff *challenge, struct HksBlob *key_alias_blob)
1808 {
1809     struct HksBlob hks_challenge = { challenge->length, challenge->val };
1810     struct HksBlob temp_key_alias = { key_alias_blob->size, key_alias_blob->data };
1811     struct HksParam params[] = {
1812         {
1813             .tag = HKS_TAG_PURPOSE,
1814             .uint32Param = HKS_KEY_PURPOSE_SIGN | HKS_KEY_PURPOSE_VERIFY
1815         }, {
1816             .tag = HKS_TAG_ALGORITHM,
1817             .uint32Param = HKS_ALG_X25519
1818         }, {
1819             .tag = HKS_TAG_PADDING, /* interface regulations */
1820             .uint32Param = HKS_PADDING_NONE
1821         }, {
1822             .tag = HKS_TAG_KEY_SIZE,
1823             .uint32Param = HC_PARAM_CHAIN_LEN
1824         }, {
1825             .tag = HKS_TAG_ATTESTATION_CHALLENGE,
1826             .blob = hks_challenge
1827         }, {
1828             .tag = HKS_TAG_KEY_STORAGE_FLAG,
1829             .uint32Param = HKS_STORAGE_PERSISTENT
1830         }, {
1831             .tag = HKS_TAG_ATTESTATION_ID_ALIAS,
1832             .blob = temp_key_alias
1833         }
1834     };
1835 
1836     int32_t status = construct_param_set(param_set, params, array_size(params));
1837     if (status != ERROR_CODE_SUCCESS) {
1838         LOGE("construct param set for attestation key failed");
1839     }
1840 
1841     return status;
1842 }
1843 
get_key_attestation(const struct uint8_buff * challenge,struct hc_key_alias * sk_alias,struct uint8_buff * out_cert_chain)1844 int32_t get_key_attestation(const struct uint8_buff *challenge, struct hc_key_alias *sk_alias,
1845     struct uint8_buff *out_cert_chain)
1846 {
1847     int32_t error_code = HC_INPUT_ERROR;
1848 
1849     check_ptr_return_val(challenge, error_code);
1850     check_ptr_return_val(sk_alias, error_code);
1851     check_ptr_return_val(out_cert_chain, error_code);
1852 
1853     struct HksBlob sk_alias_blob = { sk_alias->length, sk_alias->key_alias };
1854     struct HksParamSet *key_param_set = NULL;
1855     int32_t hks_status = gen_key_attestation_param_set(&key_param_set, challenge, &sk_alias_blob);
1856     if (hks_status != ERROR_CODE_SUCCESS) {
1857         LOGE("gen key attestation param set failed, status:%d", hks_status);
1858         return ERROR_CODE_FAILED;
1859     }
1860 
1861     struct HksBlob cert[g_cert_chain_cnt];
1862     for (int32_t i = 0; i < g_cert_chain_cnt; ++i) {
1863         struct HksBlob certBlob;
1864         certBlob.data = out_cert_chain[i].val;
1865         certBlob.size = out_cert_chain[i].length;
1866         cert[i] = certBlob;
1867     }
1868 
1869     struct HksCertChain hks_cert_chains = { cert, g_cert_chain_cnt };
1870 
1871     hks_status = HksAttestKey(&sk_alias_blob, key_param_set, &hks_cert_chains);
1872     if (hks_status != ERROR_CODE_SUCCESS) {
1873         LOGE("Key attestaion failed, errCode is %d", hks_status);
1874     }
1875 
1876     LOGI("hks_key_attestation finish");
1877 
1878     for (int32_t i = 0; i < g_cert_chain_cnt; ++i) {
1879         out_cert_chain[i].length = hks_cert_chains.certs[i].size;
1880     }
1881 
1882     HksFreeParamSet(&key_param_set);
1883     return hks_status;
1884 }
1885 
gen_get_cert_chain_param_set(struct HksParamSet ** param_set)1886 static int32_t gen_get_cert_chain_param_set(struct HksParamSet **param_set)
1887 {
1888     struct HksParam params[] = {
1889         {
1890             .tag = HKS_TAG_PURPOSE,
1891             .uint32Param = HKS_KEY_PURPOSE_SIGN | HKS_KEY_PURPOSE_VERIFY
1892         }, {
1893             .tag = HKS_TAG_ALGORITHM,
1894             .uint32Param = HKS_ALG_ECC
1895         }, {
1896             .tag = HKS_TAG_PADDING, /* interface regulations */
1897             .uint32Param = HKS_PADDING_NONE
1898         }, {
1899             .tag = HKS_TAG_KEY_SIZE,
1900             .uint32Param = HC_PARAM_CHAIN_LEN
1901         }
1902     };
1903 
1904     int32_t status = construct_param_set(param_set, params, array_size(params));
1905     if (status != ERROR_CODE_SUCCESS) {
1906         LOGE("construct param set for attestation key failed");
1907     }
1908 
1909     return status;
1910 }
1911 
get_cert_chain(const struct uint8_buff * challenge,struct hc_key_alias * sk_alias,struct uint8_buff * out_cert_chain)1912 int32_t get_cert_chain(const struct uint8_buff *challenge,
1913     struct hc_key_alias *sk_alias, struct uint8_buff *out_cert_chain)
1914 {
1915     int32_t error_code = HC_INPUT_ERROR;
1916 
1917     check_ptr_return_val(challenge, error_code);
1918     check_ptr_return_val(sk_alias, error_code);
1919     check_ptr_return_val(out_cert_chain, error_code);
1920 
1921     struct HksBlob hks_key_alias = { sk_alias->length, sk_alias->key_alias };
1922     struct HksParamSet *key_param_set = NULL;
1923     int32_t hks_status = gen_get_cert_chain_param_set(&key_param_set);
1924     if (hks_status != ERROR_CODE_SUCCESS) {
1925         LOGE("gen get cert chain param set failed, status:%d", hks_status);
1926         return ERROR_CODE_FAILED;
1927     }
1928 
1929     int8_t malloc_flag = 1; /* malloc ok */
1930     struct HksBlob cert[g_cert_chain_cnt];
1931     (void)memset_s(cert, sizeof(cert), 0, sizeof(cert));
1932     const uint32_t cert_buff_size = 8192; /* each certificate buff max size */
1933     for (int32_t i = 0; i < g_cert_chain_cnt; ++i) {
1934         cert[i].data = (uint8_t *)MALLOC(cert_buff_size);
1935         if (cert[i].data == NULL) {
1936             malloc_flag = 0;
1937             break;
1938         }
1939         (void)memset_s(cert[i].data, cert_buff_size, 0, cert_buff_size);
1940         cert[i].size = cert_buff_size;
1941     }
1942 
1943     if (malloc_flag == 0) {
1944         for (int32_t i = 0; i < g_cert_chain_cnt; ++i) {
1945             if (cert[i].data != NULL) {
1946                 FREE(cert[i].data);
1947             }
1948         }
1949         HksFreeParamSet(&key_param_set);
1950         return HC_MALLOC_FAILED;
1951     }
1952 
1953     struct HksCertChain hks_cert_chains = { cert, g_cert_chain_cnt };
1954 
1955     hks_status = HksGetCertificateChain(&hks_key_alias, key_param_set, &hks_cert_chains);
1956     if (hks_status != ERROR_CODE_SUCCESS) {
1957         LOGE("Get cert chain failed, errCode is %d", hks_status);
1958     }
1959 
1960     out_cert_chain->length = hks_cert_chains.certs[0].size;
1961     (void)memset_s(out_cert_chain->val, out_cert_chain->length, 0, out_cert_chain->length);
1962     if (memcpy_s(out_cert_chain->val, out_cert_chain->length, hks_cert_chains.certs[0].data,
1963         hks_cert_chains.certs[0].size) != EOK) {
1964         LOGE("Copy cert chain failed!");
1965     }
1966 
1967     for (int32_t i = 0; i < g_cert_chain_cnt; ++i) {
1968         FREE(hks_cert_chains.certs[i].data);
1969     }
1970 
1971     HksFreeParamSet(&key_param_set);
1972     return hks_status;
1973 }
1974 
gen_asset_unwrap_param_set(struct HksParamSet ** param_set,struct HksBlob * aad)1975 static int32_t gen_asset_unwrap_param_set(struct HksParamSet **param_set, struct HksBlob *aad)
1976 {
1977     struct HksParam params[] = {
1978         {
1979             .tag = HKS_TAG_PURPOSE,
1980             .uint32Param = HKS_KEY_PURPOSE_UNWRAP
1981         }, {
1982             .tag = HKS_TAG_ALGORITHM,
1983             .uint32Param = HKS_KEY_TYPE_AES
1984         }, {
1985             .tag = HKS_TAG_PADDING, /* interface regulations */
1986             .uint32Param = HKS_PADDING_PKCS7
1987         }, {
1988             .tag = HKS_TAG_KEY_SIZE,
1989             .uint32Param = HC_PARAM_KEY_LEN
1990         }, {
1991             .tag = HKS_TAG_ASSOCIATED_DATA,
1992             .blob = *aad
1993         }
1994     };
1995 
1996     int32_t status = construct_param_set(param_set, params, array_size(params));
1997     if (status != ERROR_CODE_SUCCESS) {
1998         LOGE("construct param set for attestation key failed");
1999     }
2000 
2001     return status;
2002 }
2003 
get_asset_aad_wrap(struct uint8_buff * sec_data,struct HksBlob * aad,struct HksBlob * wrap_data)2004 static int32_t get_asset_aad_wrap(struct uint8_buff *sec_data, struct HksBlob *aad, struct HksBlob *wrap_data)
2005 {
2006     /* sec_data = asset_len + asset_data + wrap_data_len + wrap_data */
2007     if (sec_data->length < sizeof(unsigned int)) {
2008         return ERROR_CODE_FAILED;
2009     }
2010 
2011     unsigned int asset_len = *(uint32_t *)(sec_data->val);
2012 
2013     uint32_t offset = sizeof(asset_len);
2014     if (sec_data->length < (offset + asset_len)) {
2015         return ERROR_CODE_FAILED;
2016     }
2017 
2018     struct uint8_buff asset_data = { sec_data->val + offset, asset_len, asset_len };
2019     struct sha256_value asset_sha = sha256(&asset_data);
2020     if (memcpy_s(aad->data, aad->size, asset_sha.sha256_value, asset_sha.length) != EOK) {
2021         return ERROR_CODE_FAILED;
2022     }
2023     aad->size = asset_sha.length;
2024 
2025     offset += asset_len;
2026     if (sec_data->length < (offset + sizeof(unsigned int))) {
2027         return ERROR_CODE_FAILED;
2028     }
2029 
2030     unsigned int wrap_len = *(uint32_t *)(sec_data->val + offset);
2031 
2032     offset += sizeof(wrap_len);
2033     if (sec_data->length < (offset + wrap_len)) {
2034         return ERROR_CODE_FAILED;
2035     }
2036 
2037     wrap_data->size = wrap_len;
2038     wrap_data->data = sec_data->val + offset;
2039 
2040     return ERROR_CODE_SUCCESS;
2041 }
2042 
asset_unwrap(struct uint8_buff * sec_data,struct hc_key_alias * dec_alias,struct hc_key_alias * target_alias)2043 int32_t asset_unwrap(struct uint8_buff *sec_data, struct hc_key_alias *dec_alias,
2044     struct hc_key_alias *target_alias)
2045 {
2046     int32_t error_code = HC_INPUT_ERROR;
2047 
2048     check_ptr_return_val(sec_data, error_code);
2049     check_ptr_return_val(dec_alias, error_code);
2050     check_ptr_return_val(target_alias, error_code);
2051 
2052     struct HksBlob aad = { HC_SHA256_LEN, NULL };
2053     struct HksBlob wrap_data = { 0, NULL };
2054 
2055     aad.data = (uint8_t *)MALLOC(HC_SHA256_LEN);
2056     if (aad.data == NULL) {
2057         return ERROR_CODE_FAILED;
2058     }
2059     (void)memset_s(aad.data, HC_SHA256_LEN, 0, HC_SHA256_LEN);
2060 
2061     int32_t status = get_asset_aad_wrap(sec_data, &aad, &wrap_data);
2062     if (status != ERROR_CODE_SUCCESS) {
2063         LOGE("get asset aad and wrap data failed, status:%d", status);
2064         safe_free(aad.data);
2065         return ERROR_CODE_FAILED;
2066     }
2067 
2068     struct HksBlob hks_dec_alias = { dec_alias->length, dec_alias->key_alias };
2069     struct HksBlob hks_target_alias = { target_alias->length, target_alias->key_alias };
2070     struct HksParamSet *key_param_set = NULL;
2071     status = gen_asset_unwrap_param_set(&key_param_set, &aad);
2072     if (status != ERROR_CODE_SUCCESS) {
2073         LOGE("gen asset unwrap param set failed, status:%d", status);
2074         safe_free(aad.data);
2075         HksFreeParamSet(&key_param_set);
2076         return ERROR_CODE_FAILED;
2077     }
2078 
2079     status = HksUnwrapKey(&hks_dec_alias, &hks_target_alias, &wrap_data, key_param_set);
2080     if (status != ERROR_CODE_SUCCESS) {
2081         LOGE("Hks unwrap failed, errCode is %d", status);
2082     }
2083 
2084     safe_free(aad.data);
2085     HksFreeParamSet(&key_param_set);
2086     return status;
2087 }
2088 
gen_derived_key_param_set(struct HksParamSet ** hks_param_set,struct hc_key_alias * base_alias,struct HksBlob derive_factor)2089 static int32_t gen_derived_key_param_set(struct HksParamSet **hks_param_set,
2090     struct hc_key_alias *base_alias, struct HksBlob derive_factor)
2091 {
2092     struct hc_auth_id temp_auth_id = { HC_AUTH_ID_BUFF_LEN, { 0 } };
2093 
2094     struct HksParam params[] = {
2095         {
2096             .tag = HKS_TAG_PURPOSE,
2097             .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT
2098         }, {
2099             .tag = HKS_TAG_ALGORITHM,
2100             .uint32Param = HKS_ALG_AES
2101         }, {
2102             .tag = HKS_TAG_BLOCK_MODE,
2103             .uint32Param = HKS_MODE_CCM
2104         }, {
2105             .tag = HKS_TAG_PADDING,
2106             .uint32Param = HKS_PADDING_NONE
2107         }, {
2108             .tag = HKS_TAG_KEY_SIZE,
2109             .uint32Param = HC_PARAM_KEY_LEN
2110         }, {
2111             .tag = HKS_TAG_DIGEST,
2112             .uint32Param = HKS_DIGEST_SHA256
2113         }, {
2114             .tag = HKS_TAG_KEY_AUTH_ID,
2115             .blob = { temp_auth_id.length, temp_auth_id.auth_id }
2116         }, {
2117             .tag = HKS_TAG_KEY_STORAGE_FLAG,
2118             .uint32Param = HKS_STORAGE_PERSISTENT
2119         }, {
2120             .tag = HKS_TAG_DERIVE_MAIN_KEY,
2121             .blob = { base_alias->length, base_alias->key_alias }
2122         }, {
2123             .tag = HKS_TAG_DERIVE_FACTOR,
2124             .blob = derive_factor
2125         }, {
2126             .tag = HKS_TAG_KEY_GENERATE_TYPE,
2127             .uint32Param = HKS_KEY_GENERATE_TYPE_DERIVE
2128         }
2129     };
2130 
2131     int32_t status = construct_param_set(hks_param_set, params, array_size(params));
2132     if (status != ERROR_CODE_SUCCESS) {
2133         LOGE("construct param set for attestation key failed");
2134     }
2135 
2136     return status;
2137 }
2138 
gen_derived_key(struct hc_key_alias * base_alias,struct hc_key_alias * to_save_alias)2139 int32_t gen_derived_key(struct hc_key_alias *base_alias, struct hc_key_alias *to_save_alias)
2140 {
2141     check_ptr_return_val(base_alias, HC_INPUT_ERROR);
2142     check_num_return_val(to_save_alias, HC_INPUT_ERROR);
2143     if (check_lt_public_key_exist(base_alias) != HC_OK) {
2144         LOGE("Base key is not exist");
2145         return HC_INPUT_ERROR;
2146     }
2147 
2148     if (check_lt_public_key_exist(to_save_alias) == HC_OK) {
2149         LOGW("Derive key exists, will be genetate again");
2150     }
2151 
2152     struct HksBlob hks_target_alias = { to_save_alias->length, to_save_alias->key_alias };
2153 
2154     struct HksParamSet *key_param_set = NULL;
2155 
2156     uint32_t factor_size = strlen((char *)g_factor);
2157     struct HksBlob derive_factor = { factor_size, NULL };
2158 
2159     derive_factor.data = (uint8_t *)MALLOC(factor_size + 1);
2160     if (derive_factor.data == NULL) {
2161         return HC_MALLOC_FAILED;
2162     }
2163     if (memcpy_s(derive_factor.data, factor_size, g_factor, factor_size) != EOK) {
2164         safe_free(derive_factor.data);
2165         return memory_copy_error(__func__, __LINE__);
2166     }
2167 
2168     derive_factor.data[factor_size] = '\0';
2169 
2170     int32_t hks_status = gen_derived_key_param_set(&key_param_set, base_alias, derive_factor);
2171     if (hks_status != ERROR_CODE_SUCCESS) {
2172         HksFreeParamSet(&key_param_set);
2173         safe_free(derive_factor.data);
2174         LOGE("gen asset unwrap param set failed, status:%d", hks_status);
2175         return hks_status;
2176     }
2177 
2178     hks_status = HksGenerateKey(&hks_target_alias, key_param_set, NULL);
2179     if (hks_status != ERROR_CODE_SUCCESS) {
2180         LOGE("generate symmetric key failed, status:%d", hks_status);
2181     }
2182 
2183     HksFreeParamSet(&key_param_set);
2184     safe_free(derive_factor.data);
2185     return hks_status;
2186 }
2187 #endif
2188