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