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