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