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_ */