• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define HUKS_DISABLE_LOG_AT_FILE_TO_REDUCE_ROM_SIZE
16 
17 #include "hks_keyblob.h"
18 
19 #include <stdatomic.h>
20 #include <stdbool.h>
21 #include <stddef.h>
22 
23 #include "securec.h"
24 
25 #ifdef HKS_CONFIG_FILE
26 #include HKS_CONFIG_FILE
27 #else
28 #include "hks_config.h"
29 #endif
30 
31 #include "hks_crypto_adapter.h"
32 #include "hks_log.h"
33 #include "hks_mem.h"
34 #include "hks_param.h"
35 #include "hks_template.h"
36 #include "hks_mutex.h"
37 
38 
39 #ifndef _CUT_AUTHENTICATE_
40 
41 #define HKS_KEY_BLOB_DUMMY_KEY_VERSION 1
42 #define HKS_KEY_BLOB_DUMMY_OS_VERSION 1
43 #define HKS_KEY_BLOB_DUMMY_OS_PATCHLEVEL 1
44 
45 struct HksKeyBlobInfo {
46     uint8_t salt[HKS_KEY_BLOB_DERIVE_SALT_SIZE];
47     uint8_t nonce[HKS_KEY_BLOB_NONCE_SIZE];
48     uint8_t tag[HKS_KEY_BLOB_TAG_SIZE];
49     uint32_t keySize;
50 };
51 
CleanKey(const struct HksParamSet * paramSet)52 static void CleanKey(const struct HksParamSet *paramSet)
53 {
54     struct HksParam *keyParam = NULL;
55     int32_t ret = HksGetParam(paramSet, HKS_TAG_KEY, &keyParam);
56     if (ret != HKS_SUCCESS) {
57         HKS_LOG_E("get key param failed!");
58         return;
59     }
60     (void)memset_s(keyParam->blob.data, keyParam->blob.size, 0, keyParam->blob.size);
61 }
62 
HksFreeKeyNode(struct HksKeyNode ** keyNode)63 void HksFreeKeyNode(struct HksKeyNode **keyNode)
64 {
65     if ((keyNode == NULL) || (*keyNode == NULL) || ((*keyNode)->refCnt == 0)) {
66         return;
67     }
68 
69     (*keyNode)->refCnt--;
70     if (((*keyNode)->status == HKS_KEYNODE_INACTIVE) && ((*keyNode)->refCnt == 0)) {
71         CleanKey((*keyNode)->paramSet);
72         HksFreeParamSet(&(*keyNode)->paramSet);
73         HKS_FREE(*keyNode);
74         *keyNode = NULL;
75     }
76 }
77 
78 #ifndef _STORAGE_LITE_
79 
GetEncryptKey(struct HksBlob * mainKey)80 static int32_t GetEncryptKey(struct HksBlob *mainKey)
81 {
82     return HksCryptoHalGetMainKey(NULL, mainKey);
83 }
84 
GetSalt(const struct HksParamSet * paramSet,const struct HksKeyBlobInfo * keyBlobInfo,struct HksBlob * salt)85 static int32_t GetSalt(const struct HksParamSet *paramSet, const struct HksKeyBlobInfo *keyBlobInfo,
86     struct HksBlob *salt)
87 {
88     struct HksParam *appIdParam = NULL;
89     int32_t ret = HksGetParam(paramSet, HKS_TAG_PROCESS_NAME, &appIdParam);
90     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get app id param failed!")
91 
92     if (appIdParam->blob.size > HKS_MAX_PROCESS_NAME_LEN) {
93         HKS_LOG_E("invalid app id size: %" LOG_PUBLIC "u", appIdParam->blob.size);
94         return HKS_ERROR_INVALID_ARGUMENT;
95     }
96 
97     salt->size = appIdParam->blob.size + HKS_KEY_BLOB_DERIVE_SALT_SIZE;
98     salt->data = (uint8_t *)HksMalloc(salt->size);
99     HKS_IF_NULL_LOGE_RETURN(salt->data, HKS_ERROR_MALLOC_FAIL, "malloc failed")
100 
101     (void)memcpy_s(salt->data, salt->size, appIdParam->blob.data, appIdParam->blob.size);
102 
103     (void)memcpy_s(salt->data + appIdParam->blob.size, salt->size - appIdParam->blob.size,
104         keyBlobInfo->salt, HKS_KEY_BLOB_DERIVE_SALT_SIZE);
105     return ret;
106 }
107 
GetDeriveKeyAlg(const struct HksParamSet * paramSet,uint32_t * algType)108 static void GetDeriveKeyAlg(const struct HksParamSet *paramSet, uint32_t *algType)
109 {
110     *algType = HKS_ALG_HKDF;
111 #ifdef HKS_CHANGE_DERIVE_KEY_ALG_TO_HKDF
112     struct HksParam *keyVersion = NULL;
113     int32_t ret = HksGetParam(paramSet, HKS_TAG_KEY_VERSION, &keyVersion);
114     if (ret != HKS_SUCCESS) {
115         HKS_LOG_W("Get key version failed! Use the default derive algorithm.");
116         return;
117     }
118     const uint32_t hkdfStartVersion = 3;
119     if (keyVersion->uint32Param < hkdfStartVersion) {
120         *algType = HKS_ALG_PBKDF2;
121     }
122 #endif
123 }
124 
GetDeriveKey(const struct HksParamSet * paramSet,const struct HksKeyBlobInfo * keyBlobInfo,struct HksBlob * derivedKey)125 static int32_t GetDeriveKey(const struct HksParamSet *paramSet, const struct HksKeyBlobInfo *keyBlobInfo,
126     struct HksBlob *derivedKey)
127 {
128     struct HksBlob salt = { 0, NULL };
129     int32_t ret = GetSalt(paramSet, keyBlobInfo, &salt);
130     HKS_IF_NOT_SUCC_RETURN(ret, ret)
131 
132     struct HksKeyDerivationParam derParam = {
133         .salt = salt,
134         .iterations = HKS_KEY_BLOB_DERIVE_CNT,
135         .digestAlg = HKS_DIGEST_SHA256,
136     };
137 
138     struct HksKeySpec derivationSpec = { HKS_ALG_HKDF, HKS_KEY_BYTES(HKS_AES_KEY_SIZE_256), &derParam };
139     GetDeriveKeyAlg(paramSet, &derivationSpec.algType);
140 
141     uint8_t encryptKeyData[HKS_KEY_BLOB_MAIN_KEY_SIZE] = {0};
142     struct HksBlob encryptKey = { HKS_KEY_BLOB_MAIN_KEY_SIZE, encryptKeyData };
143     ret = GetEncryptKey(&encryptKey);
144     if (ret != HKS_SUCCESS) {
145         HKS_LOG_E("Hks get encrypt key failed! ret = 0x%" LOG_PUBLIC "X", ret);
146         HKS_FREE_BLOB(salt);
147         return ret;
148     }
149 
150     derivedKey->size = HKS_KEY_BYTES(HKS_AES_KEY_SIZE_256);
151     derivedKey->data = (uint8_t *)HksMalloc(derivedKey->size);
152     if (derivedKey->data == NULL) {
153         HKS_LOG_E("malloc failed");
154         HKS_FREE_BLOB(salt);
155         (void)memset_s(encryptKeyData, HKS_KEY_BLOB_MAIN_KEY_SIZE, 0, HKS_KEY_BLOB_MAIN_KEY_SIZE);
156         return HKS_ERROR_MALLOC_FAIL;
157     }
158 
159     ret = HksCryptoHalDeriveKey(&encryptKey, &derivationSpec, derivedKey);
160     if (ret != HKS_SUCCESS) {
161         HKS_LOG_E("get keyblob derived key failed!");
162         HKS_FREE(derivedKey->data);
163     }
164 
165     (void)memset_s(encryptKeyData, HKS_KEY_BLOB_MAIN_KEY_SIZE, 0, HKS_KEY_BLOB_MAIN_KEY_SIZE);
166     HKS_FREE_BLOB(salt);
167 
168     return ret;
169 }
170 
BuildKeyBlobUsageSpec(const struct HksBlob * aad,const struct HksParam * keyParam,bool isEncrypt,struct HksUsageSpec * usageSpec)171 static int32_t BuildKeyBlobUsageSpec(const struct HksBlob *aad, const struct HksParam *keyParam,
172     bool isEncrypt, struct HksUsageSpec *usageSpec)
173 {
174     usageSpec->mode = HKS_MODE_GCM;
175     usageSpec->padding = HKS_PADDING_NONE;
176     usageSpec->digest = HKS_DIGEST_NONE;
177     usageSpec->algType = HKS_ALG_AES;
178 
179     struct HksAeadParam *aeadParam = (struct HksAeadParam *)HksMalloc(sizeof(struct HksAeadParam));
180     HKS_IF_NULL_LOGE_RETURN(aeadParam, HKS_ERROR_MALLOC_FAIL, "aeadParam malloc failed!")
181 
182     struct HksKeyBlobInfo *keyBlobInfo = (struct HksKeyBlobInfo *)keyParam->blob.data;
183     uint32_t keySize;
184     (void)memcpy_s(&keySize, sizeof(keySize), &(keyBlobInfo->keySize), sizeof(keyBlobInfo->keySize));
185     aeadParam->aad = *aad;
186     aeadParam->payloadLen = keySize;
187     aeadParam->nonce.data = keyBlobInfo->nonce;
188     aeadParam->nonce.size = HKS_KEY_BLOB_NONCE_SIZE;
189     if (isEncrypt) {
190         aeadParam->tagLenEnc = HKS_AE_TAG_LEN;
191     } else {
192         aeadParam->tagDec.data = keyBlobInfo->tag;
193         aeadParam->tagDec.size = HKS_KEY_BLOB_TAG_SIZE;
194     }
195     usageSpec->algParam = aeadParam;
196     return HKS_SUCCESS;
197 }
198 
EncryptAndDecryptKeyBlob(const struct HksBlob * aad,struct HksParamSet * paramSet,bool isEncrypt)199 static int32_t EncryptAndDecryptKeyBlob(const struct HksBlob *aad, struct HksParamSet *paramSet, bool isEncrypt)
200 {
201     struct HksParam *keyParam = NULL;
202     int32_t ret = HksGetParam(paramSet, HKS_TAG_KEY, &keyParam);
203     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher keyBlob get key param failed!")
204 
205     if (keyParam->blob.size <= sizeof(struct HksKeyBlobInfo)) {
206         return HKS_ERROR_INVALID_KEY_INFO;
207     }
208 
209     struct HksUsageSpec *usageSpec = (struct HksUsageSpec *)HksMalloc(sizeof(struct HksUsageSpec));
210     HKS_IF_NULL_RETURN(usageSpec, HKS_ERROR_MALLOC_FAIL)
211 
212     (void)memset_s(usageSpec, sizeof(struct HksUsageSpec), 0, sizeof(struct HksUsageSpec));
213     ret = BuildKeyBlobUsageSpec(aad, keyParam, isEncrypt, usageSpec);
214     if (ret != HKS_SUCCESS) {
215         HksFreeUsageSpec(&usageSpec);
216         return ret;
217     }
218 
219     struct HksKeyBlobInfo *keyBlobInfo = (struct HksKeyBlobInfo *)keyParam->blob.data;
220     uint32_t keySize;
221     (void)memcpy_s(&keySize, sizeof(keySize), &(keyBlobInfo->keySize), sizeof(keySize));
222     if ((keyParam->blob.size - sizeof(*keyBlobInfo)) != keySize) {
223         HKS_LOG_E("invalid key size in keyBlob, keySize: %" LOG_PUBLIC "u, blobSize: %" LOG_PUBLIC "u",
224             keySize, keyParam->blob.size);
225         HksFreeUsageSpec(&usageSpec);
226         return HKS_ERROR_INVALID_KEY_INFO;
227     }
228 
229     /* encrypt/decrypt will override the srcData, so encKey and decKey point to the same buffer */
230     struct HksBlob srcKey = { keySize, keyParam->blob.data + sizeof(*keyBlobInfo) };
231     struct HksBlob encKey = srcKey;
232 
233     struct HksBlob derivedKey = { 0, NULL };
234     ret = GetDeriveKey(paramSet, keyBlobInfo, &derivedKey);
235     if (ret != HKS_SUCCESS) {
236         HksFreeUsageSpec(&usageSpec);
237         return ret;
238     }
239 
240     if (isEncrypt) {
241         struct HksBlob tag = { HKS_KEY_BLOB_TAG_SIZE, keyBlobInfo->tag };
242         ret = HksCryptoHalEncrypt(&derivedKey, usageSpec, &srcKey, &encKey, &tag);
243     } else {
244         ret = HksCryptoHalDecrypt(&derivedKey, usageSpec, &encKey, &srcKey);
245     }
246 
247     HKS_IF_NOT_SUCC_LOGE(ret, "cipher key[0x%" LOG_PUBLIC "x] failed!", isEncrypt)
248 
249     (void)memset_s(derivedKey.data, derivedKey.size, 0, derivedKey.size);
250     HKS_FREE_BLOB(derivedKey);
251     HksFreeUsageSpec(&usageSpec);
252     return ret;
253 }
254 
255 /*
256  * [input]
257  * paramSet: |-inParamSet-|-version-|-osVersion-|-patchLevel-|-struct HksKeyBlobInfo-|-srcKey-|,
258  * which use |-inParamSet-|-version-|-osVersion-|-patchLevel-| as aad
259  *
260  * [output]
261  * paramSet: |-inParamSet-|-version-|-osVersion-|-patchLevel-|-struct HksKeyBlobInfo-|-encKey-|
262  */
EncryptKeyBlob(const struct HksBlob * aad,struct HksParamSet * paramSet)263 static int32_t EncryptKeyBlob(const struct HksBlob *aad, struct HksParamSet *paramSet)
264 {
265     return EncryptAndDecryptKeyBlob(aad, paramSet, true);
266 }
267 
268 /*
269  * [input]
270  * paramSet: |-inParamSet-|-version-|-osVersion-|-patchLevel-|-struct HksKeyBlobInfo-|-encKey-|,
271  * which use |-inParamSet-|-version-|-osVersion-|-patchLevel-| as aad
272  *
273  * [output]
274  * paramSet: |-inParamSet-|-version-|-osVersion-|-patchLevel-|-struct HksKeyBlobInfo-|-srcKey-|
275  */
DecryptKeyBlob(const struct HksBlob * aad,struct HksParamSet * paramSet)276 static int32_t DecryptKeyBlob(const struct HksBlob *aad, struct HksParamSet *paramSet)
277 {
278     return EncryptAndDecryptKeyBlob(aad, paramSet, false);
279 }
280 
InitKeyBlobInfo(const struct HksBlob * key,struct HksBlob * keyInfo)281 static int32_t InitKeyBlobInfo(const struct HksBlob *key, struct HksBlob *keyInfo)
282 {
283     keyInfo->size = key->size + sizeof(struct HksKeyBlobInfo);
284     keyInfo->data = (uint8_t *)HksMalloc(keyInfo->size);
285     HKS_IF_NULL_LOGE_RETURN(keyInfo->data, HKS_ERROR_MALLOC_FAIL, "malloc failed")
286 
287     int32_t ret;
288     do {
289         struct HksKeyBlobInfo *keyBlobInfo = (struct HksKeyBlobInfo *)keyInfo->data;
290         keyBlobInfo->keySize = key->size;
291 
292         struct HksBlob salt = { HKS_KEY_BLOB_DERIVE_SALT_SIZE, keyBlobInfo->salt };
293         ret = HksCryptoHalFillRandom(&salt);
294         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get salt randomly failed, ret = %" LOG_PUBLIC "d", ret)
295 
296         struct HksBlob nonce = { HKS_KEY_BLOB_NONCE_SIZE, keyBlobInfo->nonce };
297         ret = HksCryptoHalFillRandom(&nonce);
298         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get nonce randomly failed, ret = %" LOG_PUBLIC "d", ret)
299 
300         (void)memcpy_s(keyInfo->data + sizeof(*keyBlobInfo), keyInfo->size - sizeof(*keyBlobInfo),
301             key->data, key->size);
302     } while (0);
303 
304     if (ret != HKS_SUCCESS) {
305         HKS_FREE(keyInfo->data);
306     }
307     return ret;
308 }
309 
AddCoreServiceParams(const struct HksBlob * keyInfo,enum HksKeyFlag keyFlag,struct HksParamSet * paramSet)310 static int32_t AddCoreServiceParams(const struct HksBlob *keyInfo, enum HksKeyFlag keyFlag,
311     struct HksParamSet *paramSet)
312 {
313     struct HksParam tmpParam[] = {
314         {
315             .tag = HKS_TAG_KEY_VERSION,
316             .uint32Param = HKS_KEY_VERSION
317         }, {
318             .tag = HKS_TAG_OS_VERSION,
319             .uint32Param = HKS_KEY_BLOB_DUMMY_OS_VERSION
320         }, {
321             .tag = HKS_TAG_OS_PATCHLEVEL,
322             .uint32Param = HKS_KEY_BLOB_DUMMY_OS_PATCHLEVEL
323         }, {
324             .tag = HKS_TAG_KEY_FLAG,
325             .uint32Param = keyFlag
326         }, {
327             .tag = HKS_TAG_KEY,
328             .blob = *keyInfo
329         },
330     };
331 
332     int32_t ret = HksCheckIsTagAlreadyExist(tmpParam, HKS_ARRAY_SIZE(tmpParam), paramSet);
333     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "add in params fail")
334 
335     ret = HksAddParams(paramSet, tmpParam, sizeof(tmpParam) / sizeof(tmpParam[0]));
336     HKS_IF_NOT_SUCC_LOGE(ret, "add sys params failed")
337 
338     return ret;
339 }
340 
BuildKeyBlobWithKeyParam(const struct HksBlob * key,enum HksKeyFlag keyFlag,const struct HksParamSet * inParamSet,struct HksParamSet ** outParamSet)341 static int32_t BuildKeyBlobWithKeyParam(const struct HksBlob *key, enum HksKeyFlag keyFlag,
342     const struct HksParamSet *inParamSet, struct HksParamSet **outParamSet)
343 {
344     struct HksParamSet *newParamSet = NULL;
345     struct HksBlob tmpKey = { 0, NULL };
346 
347     int32_t ret = HksInitParamSet(&newParamSet);
348     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init param set failed")
349 
350     do {
351         ret = HksAddParamsWithFilter(newParamSet, inParamSet->params, inParamSet->paramsCnt);
352         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add in params failed")
353 
354         ret = InitKeyBlobInfo(key, &tmpKey);
355         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "InitKeyBlobInfo failed")
356 
357         ret = AddCoreServiceParams(&tmpKey, keyFlag, newParamSet);
358         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add Params failed")
359 
360         /* need not clean key here */
361         ret = HksBuildParamSet(&newParamSet);
362         HKS_IF_NOT_SUCC_LOGE(ret, "build paramset failed!")
363     } while (0);
364 
365     if (tmpKey.data != NULL) {
366         (void)memset_s(tmpKey.data, tmpKey.size, 0, tmpKey.size);
367         HKS_FREE(tmpKey.data);
368     }
369     if (ret != HKS_SUCCESS) {
370         HksFreeParamSet(&newParamSet);
371         return ret;
372     }
373 
374     *outParamSet = newParamSet;
375     return HKS_SUCCESS;
376 }
377 
GetAadAndParamSet(const struct HksBlob * inData,struct HksBlob * aad,struct HksParamSet ** paramSet)378 static int32_t GetAadAndParamSet(const struct HksBlob *inData, struct HksBlob *aad, struct HksParamSet **paramSet)
379 {
380     uint8_t *keyBlob = (uint8_t *)HksMalloc(inData->size);
381     HKS_IF_NULL_LOGE_RETURN(keyBlob, HKS_ERROR_MALLOC_FAIL, "malloc keyBlob failed")
382 
383     (void)memcpy_s(keyBlob, inData->size, inData->data, inData->size);
384 
385     struct HksParamSet *keyBlobParamSet = NULL;
386     int32_t ret = HksGetParamSet((const struct HksParamSet *)keyBlob, inData->size, &keyBlobParamSet);
387     if (ret != HKS_SUCCESS) {
388         HKS_FREE(keyBlob);
389         HKS_LOG_E("get keyBlobParamSet failed");
390         return ret;
391     }
392 
393     struct HksParam *keyParam = NULL;
394     ret = HksGetParam(keyBlobParamSet, HKS_TAG_KEY, &keyParam);
395     if (ret != HKS_SUCCESS) {
396         HKS_FREE(keyBlob);
397         HksFreeParamSet(&keyBlobParamSet);
398         HKS_LOG_E("aad get key param failed!");
399         return ret;
400     }
401 
402     if (keyParam->blob.data + keyParam->blob.size != (uint8_t *)keyBlobParamSet + keyBlobParamSet->paramSetSize) {
403         HKS_FREE(keyBlob);
404         HksFreeParamSet(&keyBlobParamSet);
405         HKS_LOG_E("invalid keyblob, keyParam should be the last param!");
406         return HKS_ERROR_INVALID_ARGUMENT;
407     }
408 
409     *paramSet = keyBlobParamSet;
410     /* the aad is the whole keyBlob content without the keyParam blob part */
411     aad->data = keyBlob;
412     aad->size = keyBlobParamSet->paramSetSize - keyParam->blob.size;
413     return HKS_SUCCESS;
414 }
415 
HksGenerateKeyNode(const struct HksBlob * key)416 struct HksKeyNode *HksGenerateKeyNode(const struct HksBlob *key)
417 {
418     if (key->size > MAX_KEY_SIZE) {
419         HKS_LOG_E("invalid key blob size %" LOG_PUBLIC "x", key->size);
420         return NULL;
421     }
422 
423     struct HksBlob aad = { 0, NULL };
424     struct HksParamSet *keyBlobParamSet = NULL;
425     int32_t ret = GetAadAndParamSet(key, &aad, &keyBlobParamSet);
426     HKS_IF_NOT_SUCC_RETURN(ret, NULL)
427 
428     ret = DecryptKeyBlob(&aad, keyBlobParamSet);
429     HKS_FREE_BLOB(aad);
430     if (ret != HKS_SUCCESS) {
431         HksFreeParamSet(&keyBlobParamSet);
432         HKS_LOG_E("decrypt keyBlob failed");
433         return NULL;
434     }
435 
436     struct HksKeyNode *keyNode = (struct HksKeyNode *)HksMalloc(sizeof(struct HksKeyNode));
437     if (keyNode == NULL) {
438         CleanKey(keyBlobParamSet);
439         HksFreeParamSet(&keyBlobParamSet);
440         HKS_LOG_E("malloc keynode failed");
441         return NULL;
442     }
443 
444     keyNode->refCnt = 1;
445     keyNode->status = HKS_KEYNODE_INACTIVE;
446     keyNode->handle = 0;
447     keyNode->paramSet = keyBlobParamSet;
448     return keyNode;
449 }
450 
HksGetRawKey(const struct HksParamSet * paramSet,struct HksBlob * rawKey)451 int32_t HksGetRawKey(const struct HksParamSet *paramSet, struct HksBlob *rawKey)
452 {
453     struct HksParam *keyParam = NULL;
454     int32_t ret = HksGetParam(paramSet, HKS_TAG_KEY, &keyParam);
455     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get key param failed!")
456 
457     if (keyParam->blob.size <= sizeof(struct HksKeyBlobInfo)) {
458         HKS_LOG_E("invalid key size in keyBlob!");
459         return HKS_ERROR_INVALID_KEY_INFO;
460     }
461 
462     struct HksKeyBlobInfo *keyBlobInfo = (struct HksKeyBlobInfo *)keyParam->blob.data;
463     uint32_t keySize;
464     (void)memcpy_s(&keySize, sizeof(keySize), &(keyBlobInfo->keySize), sizeof(keySize));
465     if ((keyParam->blob.size - sizeof(*keyBlobInfo)) != keySize) {
466         HKS_LOG_E("invalid key size in keyBlob, keySize: %" LOG_PUBLIC "u, blobSize: %" LOG_PUBLIC "u",
467             keySize, keyParam->blob.size);
468         return HKS_ERROR_INVALID_KEY_INFO;
469     }
470 
471     uint8_t *data = (uint8_t *)HksMalloc(keySize);
472     HKS_IF_NULL_LOGE_RETURN(data, HKS_ERROR_MALLOC_FAIL, "fail to malloc raw key")
473 
474     (void)memcpy_s(data, keySize, keyParam->blob.data + sizeof(*keyBlobInfo), keySize);
475     rawKey->size = keySize;
476     rawKey->data = data;
477     return HKS_SUCCESS;
478 }
479 
HksVerifyAuthTokenSign(const struct HksUserAuthToken * authToken)480 int32_t HksVerifyAuthTokenSign(const struct HksUserAuthToken *authToken)
481 {
482     HKS_IF_NULL_LOGE_RETURN(authToken, HKS_ERROR_NULL_POINTER, "authToken params is null!")
483 
484     struct HksAuthTokenKey authTokenKey;
485     int32_t ret = HksGetAuthTokenKey(&authTokenKey);
486     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get authtoken key failed!")
487 
488     struct HksBlob macKeyBlob = { HKS_KEY_BLOB_AT_KEY_BYTES, authTokenKey.macKey };
489     uint32_t authTokenDataSize = sizeof(struct HksUserAuthToken) - SHA256_SIGN_LEN;
490     struct HksBlob srcDataBlob = { authTokenDataSize, (uint8_t *)authToken };
491 
492     uint8_t computedMac[SHA256_SIGN_LEN] = {0};
493     struct HksBlob macBlob = { SHA256_SIGN_LEN, computedMac };
494     ret = HksCryptoHalHmac(&macKeyBlob, HKS_DIGEST_SHA256, &srcDataBlob, &macBlob);
495     (void)memset_s(&authTokenKey, sizeof(struct HksAuthTokenKey), 0, sizeof(struct HksAuthTokenKey));
496     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "compute authtoken data mac failed!")
497 
498     ret = HksMemCmp(computedMac, (uint8_t *)authToken + authTokenDataSize, SHA256_SIGN_LEN);
499     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_KEY_AUTH_VERIFY_FAILED, "compare authtoken data mac failed!")
500 
501     return HKS_SUCCESS;
502 }
503 
HksDecryptAuthToken(struct HksUserAuthToken * authToken)504 int32_t HksDecryptAuthToken(struct HksUserAuthToken *authToken)
505 {
506     HKS_IF_NULL_LOGE_RETURN(authToken, HKS_ERROR_NULL_POINTER, "authToken params is null!")
507 
508     struct HksAuthTokenKey authTokenKey;
509     int32_t ret = HksGetAuthTokenKey(&authTokenKey);
510     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get authtoken key failed!")
511 
512     const char *aadValue = "OH_authToken";
513     struct HksBlob cipherKeyBlob = { HKS_KEY_BLOB_AT_KEY_BYTES, authTokenKey.cipherKey };
514     struct HksBlob srcDataBlob = { sizeof(struct HksCiphertextData), (uint8_t *)&authToken->ciphertextData };
515     struct HksUsageSpec usageSpec = { HKS_ALG_AES, HKS_MODE_GCM, HKS_PADDING_NONE,
516         HKS_DIGEST_NONE, HKS_DIGEST_NONE, HKS_KEY_PURPOSE_DECRYPT, 0, NULL };
517 
518     struct HksAeadParam *aeadParam = (struct HksAeadParam *)HksMalloc(sizeof(struct HksAeadParam));
519     HKS_IF_NULL_LOGE_RETURN(aeadParam, HKS_ERROR_MALLOC_FAIL, "aeadParam malloc failed!")
520 
521     aeadParam->nonce.data = authToken->iv;
522     aeadParam->nonce.size = sizeof(authToken->iv);
523     aeadParam->aad.data = (uint8_t *)(unsigned long)aadValue;
524     aeadParam->aad.size = (uint32_t)strlen(aadValue);
525     aeadParam->tagDec.data = authToken->tag;
526     aeadParam->tagDec.size = sizeof(authToken->tag);
527     aeadParam->payloadLen = srcDataBlob.size;
528     usageSpec.algParam = aeadParam;
529 
530     ret = HksCryptoHalDecrypt(&cipherKeyBlob, &usageSpec, &srcDataBlob, &srcDataBlob);
531     (void)memset_s(&authTokenKey, sizeof(struct HksAuthTokenKey), 0, sizeof(struct HksAuthTokenKey));
532     HKS_IF_NOT_SUCC_LOGE(ret, "decrypt authtoken data failed!");
533     HKS_FREE(aeadParam);
534     return ret;
535 }
536 
HksBuildKeyBlob2(struct HksParamSet * keyBlobParamSet,struct HksBlob * keyOut)537 static int32_t HksBuildKeyBlob2(struct HksParamSet *keyBlobParamSet, struct HksBlob *keyOut)
538 {
539     struct HksParam *keyParam = NULL;
540     int32_t ret = HksGetParam(keyBlobParamSet, HKS_TAG_KEY, &keyParam);
541     if (ret != HKS_SUCCESS) {
542         HKS_LOG_E("get key param when building keyBlob failed!");
543         return ret;
544     }
545 
546     /* the aad is the whole keyBlob content without the keyParam blob part */
547     struct HksBlob aad = { keyBlobParamSet->paramSetSize - keyParam->blob.size, (uint8_t *)keyBlobParamSet };
548     ret = EncryptKeyBlob(&aad, keyBlobParamSet);
549     if (ret != HKS_SUCCESS) {
550         /* should clean the clear key if fail to encrypt key */
551         (void)memset_s(keyParam->blob.data, keyParam->blob.size, 0, keyParam->blob.size);
552         return ret;
553     }
554 
555     if (memcpy_s(keyOut->data, keyOut->size, keyBlobParamSet, keyBlobParamSet->paramSetSize) != EOK) {
556         HKS_LOG_E("copy keyblob out failed!");
557         return HKS_ERROR_BUFFER_TOO_SMALL;
558     }
559 
560     keyOut->size = keyBlobParamSet->paramSetSize;
561     return HKS_SUCCESS;
562 }
563 
HksBuildKeyBlob(const struct HksBlob * keyAlias,uint8_t keyFlag,const struct HksBlob * key,const struct HksParamSet * paramSet,struct HksBlob * keyOut)564 int32_t HksBuildKeyBlob(const struct HksBlob *keyAlias, uint8_t keyFlag, const struct HksBlob *key,
565     const struct HksParamSet *paramSet, struct HksBlob *keyOut)
566 {
567     (void)keyAlias;
568     struct HksParamSet *keyBlobParamSet = NULL;
569     int32_t ret;
570     do {
571         ret = BuildKeyBlobWithKeyParam(key, (enum HksKeyFlag)keyFlag, paramSet, &keyBlobParamSet);
572         HKS_IF_NOT_SUCC_BREAK(ret)
573 
574         ret = HksBuildKeyBlob2(keyBlobParamSet, keyOut);
575     } while (0);
576     HksFreeParamSet(&keyBlobParamSet);
577     return ret;
578 }
579 
580 #ifdef HKS_ENABLE_UPGRADE_KEY
HksBuildKeyBlobWithOutAddKeyParam(const struct HksParamSet * paramSet,struct HksBlob * keyOut)581 int32_t HksBuildKeyBlobWithOutAddKeyParam(const struct HksParamSet *paramSet, struct HksBlob *keyOut)
582 {
583     struct HksParamSet *keyBlobParamSet = NULL;
584     int32_t ret;
585     do {
586         ret = HksGetParamSet(paramSet, paramSet->paramSetSize, &keyBlobParamSet);
587         HKS_IF_NOT_SUCC_BREAK(ret)
588 
589         ret = HksBuildKeyBlob2(keyBlobParamSet, keyOut);
590     } while (0);
591 
592     HksFreeParamSet(&keyBlobParamSet);
593     return ret;
594 }
595 #endif
596 
HksGetAadAndParamSet(const struct HksBlob * inData,struct HksBlob * aad,struct HksParamSet ** paramSet)597 int32_t HksGetAadAndParamSet(const struct HksBlob *inData, struct HksBlob *aad, struct HksParamSet **paramSet)
598 {
599     return GetAadAndParamSet(inData, aad, paramSet);
600 }
601 
HksDecryptKeyBlob(const struct HksBlob * aad,struct HksParamSet * paramSet)602 int32_t HksDecryptKeyBlob(const struct HksBlob *aad, struct HksParamSet *paramSet)
603 {
604     return DecryptKeyBlob(aad, paramSet);
605 }
606 
607 #endif /* STORAGE_LITE */
608 
609 static HksMutex *g_genAtKeyMutex = NULL;
610 static struct HksAuthTokenKey g_cachedAuthTokenKey;
611 static volatile atomic_bool g_isInitAuthTokenKey = false;
612 
613 /* temporarily use default hard-coded AT key by disable HKS_SUPPORT_GET_AT_KEY.
614  * while in real scenario,it will generate random only in memory(in TEE)
615  * at every start after enable HKS_SUPPORT_GET_AT_KEY
616  */
617 #ifndef HKS_SUPPORT_GET_AT_KEY
618 #define HKS_DEFAULT_USER_AT_MAC_KEY "huks_default_user_auth_token_mac"
619 #define HKS_DEFAULT_USER_AT_CIPHER_KEY "huks_default_user_auth_cipherkey"
620 #define HKS_DEFAULT_USER_AT_KEY_LEN 32
GenerateAuthTokenKey(void)621 static int32_t GenerateAuthTokenKey(void)
622 {
623     (void)memcpy_s(g_cachedAuthTokenKey.macKey, HKS_KEY_BLOB_AT_KEY_BYTES,
624         HKS_DEFAULT_USER_AT_MAC_KEY, HKS_DEFAULT_USER_AT_KEY_LEN);
625     (void)memcpy_s(g_cachedAuthTokenKey.cipherKey, HKS_KEY_BLOB_AT_KEY_BYTES,
626         HKS_DEFAULT_USER_AT_CIPHER_KEY, HKS_DEFAULT_USER_AT_KEY_LEN);
627     HKS_LOG_I("generate At key success!");
628     return HKS_SUCCESS;
629 }
630 
631 #else
GenerateAuthTokenKey(void)632 static int32_t GenerateAuthTokenKey(void)
633 {
634     struct HksKeySpec macSpec = { HKS_ALG_HMAC, HKS_KEY_BLOB_AT_KEY_SIZE, NULL };
635     struct HksBlob macKey = { 0, NULL };
636     int32_t ret = HksCryptoHalGenerateKey(&macSpec, &macKey);
637     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "generate hmac key failed!")
638 
639     struct HksKeySpec cipherSpec = { HKS_ALG_AES, HKS_KEY_BLOB_AT_KEY_SIZE, NULL };
640     struct HksBlob cipherKey = { 0, NULL };
641     ret = HksCryptoHalGenerateKey(&cipherSpec, &cipherKey);
642     if (ret != HKS_SUCCESS) {
643         HKS_LOG_E("generate cipher key failed!");
644         HKS_MEMSET_FREE_BLOB(macKey);
645         return ret;
646     }
647 
648     (void)memcpy_s(g_cachedAuthTokenKey.macKey, HKS_KEY_BLOB_AT_KEY_BYTES, macKey.data, macKey.size);
649     (void)memcpy_s(g_cachedAuthTokenKey.cipherKey, HKS_KEY_BLOB_AT_KEY_BYTES, cipherKey.data, cipherKey.size);
650     HKS_MEMSET_FREE_BLOB(macKey);
651     HKS_MEMSET_FREE_BLOB(cipherKey);
652     return ret;
653 }
654 
655 #endif /* HKS_SUPPORT_GET_AT_KEY */
656 
HksCoreInitAuthTokenKey(void)657 int32_t HksCoreInitAuthTokenKey(void)
658 {
659     if (atomic_load(&g_isInitAuthTokenKey) == false) {
660         if (GenerateAuthTokenKey() == HKS_SUCCESS) {
661             HKS_LOG_I("generate At key success!");
662             atomic_store(&g_isInitAuthTokenKey, true);
663             return HKS_SUCCESS;
664         }
665     }
666 
667     HKS_LOG_E("generate auth token key failed at core init stage");
668     atomic_store(&g_isInitAuthTokenKey, false);
669 
670     if (g_genAtKeyMutex == NULL) {
671         g_genAtKeyMutex = HksMutexCreate();
672     }
673 
674     HKS_IF_NULL_LOGE_RETURN(g_genAtKeyMutex, HKS_ERROR_BAD_STATE, "create mutex failed!")
675 
676     // here we return success for we could generate later at usage stage
677     return HKS_SUCCESS;
678 }
679 
HksCoreDestroyAuthTokenKey(void)680 void HksCoreDestroyAuthTokenKey(void)
681 {
682     if (g_genAtKeyMutex != NULL) {
683         HksMutexClose(g_genAtKeyMutex);
684         g_genAtKeyMutex = NULL;
685     }
686     atomic_store(&g_isInitAuthTokenKey, false);
687     (void)memset_s(&g_cachedAuthTokenKey, sizeof(struct HksAuthTokenKey), 0, sizeof(struct HksAuthTokenKey));
688 }
689 
HksGetAuthTokenKey(struct HksAuthTokenKey * authTokenKey)690 int32_t HksGetAuthTokenKey(struct HksAuthTokenKey *authTokenKey)
691 {
692     HKS_IF_NULL_LOGE_RETURN(authTokenKey, HKS_ERROR_NULL_POINTER, "authTokenKey param is null!")
693 
694     if (atomic_load(&g_isInitAuthTokenKey) == false) {
695         (void)HksMutexLock(g_genAtKeyMutex);
696 
697         // double check for avoid duplicate create in multi thread case
698         if (atomic_load(&g_isInitAuthTokenKey) == false) {
699             if (GenerateAuthTokenKey() != HKS_SUCCESS) {
700                 HKS_LOG_E("generate auth token key failed");
701                 (void)HksMutexUnlock(g_genAtKeyMutex);
702                 return HKS_FAILURE;
703             }
704             HKS_LOG_I("generate At key success!");
705             atomic_store(&g_isInitAuthTokenKey, true);
706         }
707         (void)HksMutexUnlock(g_genAtKeyMutex);
708     }
709 
710     (void)memcpy_s(authTokenKey, sizeof(struct HksAuthTokenKey), &g_cachedAuthTokenKey, sizeof(struct HksAuthTokenKey));
711     return HKS_SUCCESS;
712 }
713 
714 #endif /* _CUT_AUTHENTICATE_ */