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