1 /*
2 * Copyright (c) 2023-2024 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_client_service_util.h"
18
19 #include <stddef.h>
20
21 #include "hks_client_check.h"
22 #include "hks_client_service_common.h"
23 #include "hks_log.h"
24 #include "hks_param.h"
25 #include "hks_mem.h"
26 #include "hks_storage_manager.h"
27 #include "hks_template.h"
28
29 #ifdef HKS_SUPPORT_GET_BUNDLE_INFO
30 #include "hks_bms_api_wrap.h"
31 #endif
32
33 #ifdef HUKS_ENABLE_SKIP_UPGRADE_KEY_STORAGE_SECURE_LEVEL
34 #include "hks_config_parser.h"
35 #endif
36
37 #ifdef HKS_SUPPORT_USER_AUTH_ACCESS_CONTROL
38 #include "hks_useridm_api_wrap.h"
39 #endif
40
41 #include "securec.h"
42
43 #ifdef _STORAGE_LITE_
44 #include "hks_storage_adapter.h"
45 #endif
46
47 #ifndef _CUT_AUTHENTICATE_
48 #ifdef _STORAGE_LITE_
49
GetKeyParamSet(const struct HksBlob * key,struct HksParamSet * paramSet)50 int32_t GetKeyParamSet(const struct HksBlob *key, struct HksParamSet *paramSet)
51 {
52 struct HksParamSet *tmpParamSet = NULL;
53 int32_t ret = TranslateKeyInfoBlobToParamSet(NULL, key, &tmpParamSet);
54 HKS_IF_NOT_SUCC_RETURN(ret, ret)
55
56 if (paramSet->paramSetSize < tmpParamSet->paramSetSize) {
57 HksFreeParamSet(&tmpParamSet);
58 return HKS_ERROR_BUFFER_TOO_SMALL;
59 }
60 if (memcpy_s(paramSet, paramSet->paramSetSize, tmpParamSet, tmpParamSet->paramSetSize) != EOK) {
61 HKS_LOG_E("memcpy paramSet failed");
62 ret = HKS_ERROR_INSUFFICIENT_MEMORY;
63 } else {
64 ret = HksFreshParamSet(paramSet, false);
65 }
66
67 HksFreeParamSet(&tmpParamSet);
68 return ret;
69 }
70
71 #else /* _STORAGE_LITE_ */
72
73 static const uint32_t SENSITIVE_DELETE_TAG[] = {
74 HKS_TAG_KEY, HKS_TAG_ACCESS_TOKEN_ID, HKS_TAG_USER_AUTH_ENROLL_ID_INFO,
75 HKS_TAG_USER_AUTH_SECURE_UID, HKS_TAG_OWNER_ID, HKS_TAG_ACCOUNT_ID
76 };
77
GetKeyParamSet(const struct HksBlob * key,struct HksParamSet * paramSet)78 int32_t GetKeyParamSet(const struct HksBlob *key, struct HksParamSet *paramSet)
79 {
80 HKS_IF_TRUE_LOGE_RETURN(key->size < sizeof(struct HksParamSet), HKS_ERROR_INVALID_KEY_INFO,
81 "get key paramset: invalid key size: %" LOG_PUBLIC "u", key->size)
82
83 const struct HksParamSet *tmpParamSet = (const struct HksParamSet *)key->data;
84 struct HksParamSet *outParamSet = NULL;
85 int32_t ret = HksDeleteTagsFromParamSet(SENSITIVE_DELETE_TAG,
86 sizeof(SENSITIVE_DELETE_TAG) / sizeof(SENSITIVE_DELETE_TAG[0]), tmpParamSet, &outParamSet);
87 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "delete tag from paramSet failed, ret = %" LOG_PUBLIC "d.", ret)
88
89 if (paramSet->paramSetSize < outParamSet->paramSetSize) {
90 HksFreeParamSet(&outParamSet);
91 return HKS_ERROR_BUFFER_TOO_SMALL;
92 }
93 if (memcpy_s(paramSet, paramSet->paramSetSize, outParamSet, outParamSet->paramSetSize) != EOK) {
94 HksFreeParamSet(&outParamSet);
95 HKS_LOG_E("copy paramSet failed!");
96 return HKS_ERROR_INSUFFICIENT_MEMORY;
97 }
98
99 ret = HksFreshParamSet(paramSet, false);
100
101 HksFreeParamSet(&outParamSet);
102 return ret;
103 }
104
GetKeyFileData(const struct HksProcessInfo * processInfo,const struct HksParamSet * paramSet,const struct HksBlob * keyAlias,struct HksBlob * key,enum HksStorageType mode)105 int32_t GetKeyFileData(const struct HksProcessInfo *processInfo, const struct HksParamSet *paramSet,
106 const struct HksBlob *keyAlias, struct HksBlob *key, enum HksStorageType mode)
107 {
108 uint32_t size;
109 int32_t ret = HksManageStoreGetKeyBlobSize(processInfo, paramSet, keyAlias, &size, mode);
110 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get keyblob size from storage failed, ret = %" LOG_PUBLIC "d.", ret)
111
112 HKS_IF_TRUE_LOGE_RETURN(size > MAX_KEY_SIZE, HKS_ERROR_INVALID_KEY_FILE,
113 "invalid key size, size = %" LOG_PUBLIC "u", size)
114
115 key->data = (uint8_t *)HksMalloc(size);
116 HKS_IF_NULL_LOGE_RETURN(key->data, HKS_ERROR_MALLOC_FAIL, "get key data: malloc failed")
117
118 key->size = size;
119 ret = HksManageStoreGetKeyBlob(processInfo, paramSet, keyAlias, key, mode);
120 if (ret != HKS_SUCCESS) {
121 HKS_LOG_E("get keyblob from storage failed, ret = %" LOG_PUBLIC "d", ret);
122 HKS_FREE_BLOB(*key);
123 }
124 return ret;
125 }
126
127 #ifdef HKS_ENABLE_UPGRADE_KEY
ConstructUpgradeKeyParamSet(const struct HksProcessInfo * processInfo,const struct HksParamSet * srcParamSet,struct HksParamSet ** outParamSet)128 int32_t ConstructUpgradeKeyParamSet(const struct HksProcessInfo *processInfo, const struct HksParamSet *srcParamSet,
129 struct HksParamSet **outParamSet)
130 {
131 (void)srcParamSet;
132 struct HksParamSet *paramSet = NULL;
133 int32_t ret;
134 do {
135 ret = HksInitParamSet(¶mSet);
136 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "init param set failed!")
137
138 struct HksParam processNameParam;
139 processNameParam.tag = HKS_TAG_PROCESS_NAME;
140 processNameParam.blob = processInfo->processName;
141
142 ret = HksAddParams(paramSet, &processNameParam, 1);
143 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add param processNameParam failed!")
144
145 ret = HksBuildParamSet(¶mSet);
146 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "build param set failed!")
147
148 *outParamSet = paramSet;
149 return HKS_SUCCESS;
150 } while (0);
151 HksFreeParamSet(¶mSet);
152 return ret;
153 }
154 #endif
155
156 #endif /* _STORAGE_LITE_ */
157 #endif /* _CUT_AUTHENTICATE_ */
158
159 #ifdef L2_STANDARD
AddSpecificUserIdToParamSet(const struct HksOperation * operation,struct HksParamSet * paramSet)160 static int32_t AddSpecificUserIdToParamSet(const struct HksOperation *operation, struct HksParamSet *paramSet)
161 {
162 //when use HksUpdate, HksFinish, HksAbort, operation is not null
163 HKS_IF_NULL_RETURN(operation, HKS_SUCCESS)
164 struct HksParam *specificUserId = NULL;
165 int32_t ret = HksGetParam(paramSet, HKS_TAG_SPECIFIC_USER_ID, &specificUserId);
166 if (ret == HKS_ERROR_PARAM_NOT_EXIST) {
167 HKS_IF_NOT_TRUE_RETURN(operation->isUserIdPassedDuringInit, HKS_SUCCESS)
168 struct HksParam specificUserIdParam;
169 specificUserIdParam.tag = HKS_TAG_SPECIFIC_USER_ID;
170 specificUserIdParam.int32Param = operation->userIdPassedDuringInit;
171 ret = HksAddParams(paramSet, &specificUserIdParam, 1);
172 }
173 return ret;
174 }
175
176 #ifdef HUKS_ENABLE_SKIP_UPGRADE_KEY_STORAGE_SECURE_LEVEL
GetStorageLevelForSkipUpgradeApp(const struct HksProcessInfo * processInfo,struct HksParam * storageLevel)177 static int32_t GetStorageLevelForSkipUpgradeApp(const struct HksProcessInfo *processInfo, struct HksParam *storageLevel)
178 {
179 HKS_IF_NULL_RETURN(processInfo, HKS_SUCCESS)
180 struct HksUpgradeFileTransferInfo info = { 0 };
181 int32_t ret = HksMatchConfig("", processInfo->uidInt, processInfo->userIdInt, processInfo->accessTokenId, &info);
182 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "match skip upgarde config failed.")
183 if (info.skipTransfer) {
184 storageLevel->uint32Param = HKS_AUTH_STORAGE_LEVEL_OLD_DE_TMP;
185 }
186 return HKS_SUCCESS;
187 }
188 #endif
189
AddStorageLevelToParamSet(const struct HksProcessInfo * processInfo,struct HksParamSet * paramSet)190 static int32_t AddStorageLevelToParamSet(const struct HksProcessInfo *processInfo, struct HksParamSet *paramSet)
191 {
192 struct HksParam *storageLevel = NULL;
193 int32_t ret = HksGetParam(paramSet, HKS_TAG_AUTH_STORAGE_LEVEL, &storageLevel);
194 if (ret == HKS_ERROR_PARAM_NOT_EXIST) {
195 struct HksParam storageLevelParam;
196 storageLevelParam.tag = HKS_TAG_AUTH_STORAGE_LEVEL;
197 storageLevelParam.uint32Param = HKS_AUTH_STORAGE_LEVEL_CE;
198
199 #ifdef HUKS_ENABLE_SKIP_UPGRADE_KEY_STORAGE_SECURE_LEVEL
200 ret = GetStorageLevelForSkipUpgradeApp(processInfo, &storageLevelParam);
201 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get default storage level for skip upgrade app failed.")
202 #endif
203 ret = HksAddParams(paramSet, &storageLevelParam, 1);
204 }
205 return ret;
206 }
207
AppendStorageLevelAndSpecificUserIdToParamSet(const struct HksProcessInfo * processInfo,const struct HksOperation * operation,struct HksParamSet * paramSet)208 static int32_t AppendStorageLevelAndSpecificUserIdToParamSet(const struct HksProcessInfo *processInfo,
209 const struct HksOperation *operation, struct HksParamSet *paramSet)
210 {
211 int32_t ret = AddSpecificUserIdToParamSet(operation, paramSet);
212 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "add specific userid tag failed")
213
214 ret = AddStorageLevelToParamSet(processInfo, paramSet);
215 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "add storage level tag failed")
216
217 return HKS_SUCCESS;
218 }
219
AppendStorageLevelIfNotExistInner(const struct HksProcessInfo * processInfo,const struct HksParamSet * paramSet,struct HksParamSet ** outParamSet)220 int32_t AppendStorageLevelIfNotExistInner(const struct HksProcessInfo *processInfo,
221 const struct HksParamSet *paramSet, struct HksParamSet **outParamSet)
222 {
223 int32_t ret;
224 struct HksParamSet *newParamSet = NULL;
225 do {
226 if (paramSet != NULL) {
227 ret = AppendToNewParamSet(paramSet, &newParamSet);
228 } else {
229 ret = HksInitParamSet(&newParamSet);
230 }
231
232 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "append tag to new paramset failed")
233
234 ret = AppendStorageLevelAndSpecificUserIdToParamSet(processInfo, NULL, newParamSet);
235 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add default strategy failed")
236
237 ret = HksBuildParamSet(&newParamSet);
238 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "build paramset failed")
239 } while (0);
240 if (ret != HKS_SUCCESS) {
241 HksFreeParamSet(&newParamSet);
242 return ret;
243 }
244 *outParamSet = newParamSet;
245 return ret;
246 }
247
AppendStorageLevelIfNotExist(const struct HksParamSet * paramSet,struct HksParamSet ** outParamSet)248 int32_t AppendStorageLevelIfNotExist(const struct HksParamSet *paramSet, struct HksParamSet **outParamSet)
249 {
250 return AppendStorageLevelIfNotExistInner(NULL, paramSet, outParamSet);
251 }
252 #endif
253
CheckProcessNameTagExist(const struct HksParamSet * paramSet)254 bool CheckProcessNameTagExist(const struct HksParamSet *paramSet)
255 {
256 for (uint32_t i = 0; i < paramSet->paramsCnt; ++i) {
257 if (paramSet->params[i].tag == HKS_TAG_PROCESS_NAME) {
258 return true;
259 }
260 }
261 return false;
262 }
263
264 #ifdef HKS_SUPPORT_GET_BUNDLE_INFO
HksCheckIsAcrossDevices(const struct HksParamSet * paramSet)265 static bool HksCheckIsAcrossDevices(const struct HksParamSet *paramSet)
266 {
267 if (HksCheckIsAllowedWrap(paramSet)) {
268 return true;
269 }
270 struct HksParam *wrapTypeParam = NULL;
271 if (HksGetParam(paramSet, HKS_TAG_KEY_WRAP_TYPE, &wrapTypeParam) == HKS_SUCCESS) {
272 return true;
273 }
274 return false;
275 }
276
AppendOwnerInfoForAcrossDevicesIfNeed(const struct HksProcessInfo * processInfo,struct HksParamSet * newParamSet,struct HksBlob * appInfo)277 static int32_t AppendOwnerInfoForAcrossDevicesIfNeed(const struct HksProcessInfo *processInfo,
278 struct HksParamSet *newParamSet, struct HksBlob *appInfo)
279 {
280 HKS_IF_NOT_TRUE_RETURN(HksCheckIsAcrossDevices(newParamSet), HKS_SUCCESS)
281
282 int32_t ret;
283 do {
284 ret = GetCallerName(processInfo, appInfo);
285 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "GetCallerName failed")
286
287 struct HksParam paramArr[] = {
288 { .tag = HKS_TAG_OWNER_ID, .blob = *appInfo },
289 { .tag = HKS_TAG_OWNER_TYPE, .uint32Param = HksGetCallerType() },
290 };
291
292 ret = HksAddParams(newParamSet, paramArr, HKS_ARRAY_SIZE(paramArr));
293 } while (0);
294
295 return ret;
296 }
297 #endif
298
AppendProcessInfoAndDefaultStrategy(const struct HksParamSet * paramSet,const struct HksProcessInfo * processInfo,const struct HksOperation * operation,struct HksParamSet ** outParamSet)299 int32_t AppendProcessInfoAndDefaultStrategy(const struct HksParamSet *paramSet,
300 const struct HksProcessInfo *processInfo, const struct HksOperation *operation, struct HksParamSet **outParamSet)
301 {
302 int32_t ret;
303 (void)operation;
304 struct HksParamSet *newParamSet = NULL;
305 struct HksBlob appInfo = { 0, NULL };
306 do {
307 if (paramSet != NULL) {
308 ret = AppendToNewParamSet(paramSet, &newParamSet);
309 } else {
310 ret = HksInitParamSet(&newParamSet);
311 }
312
313 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "append client service tag failed")
314
315 // process name only can be inserted by service
316 if (CheckProcessNameTagExist(newParamSet)) {
317 ret = HKS_ERROR_INVALID_ARGUMENT;
318 break;
319 }
320
321 struct HksParam paramArr[] = {
322 { .tag = HKS_TAG_PROCESS_NAME, .blob = processInfo->processName },
323 { .tag = HKS_TAG_USER_ID, .uint32Param = processInfo->userIdInt },
324 { .tag = HKS_TAG_SCREEN_STATE, .boolParam = HksGetScreenState()},
325 #ifdef HKS_SUPPORT_ACCESS_TOKEN
326 { .tag = HKS_TAG_ACCESS_TOKEN_ID, .uint64Param = processInfo->accessTokenId },
327 #endif
328 };
329
330 ret = HksAddParams(newParamSet, paramArr, HKS_ARRAY_SIZE(paramArr));
331 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add processInfo failed")
332
333 #ifdef HKS_SUPPORT_GET_BUNDLE_INFO
334 ret = AppendOwnerInfoForAcrossDevicesIfNeed(processInfo, newParamSet, &appInfo);
335 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add ownerInfo failed")
336 #endif
337
338 #ifdef L2_STANDARD
339 ret = AppendStorageLevelAndSpecificUserIdToParamSet(processInfo, operation, newParamSet);
340 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add default strategy failed")
341 #endif
342 ret = HksBuildParamSet(&newParamSet);
343 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "build paramset failed")
344
345 *outParamSet = newParamSet;
346 HKS_FREE_BLOB(appInfo);
347 return ret;
348 } while (0);
349
350 HKS_FREE_BLOB(appInfo);
351 HksFreeParamSet(&newParamSet);
352 return ret;
353 }
354
AppendNewInfoForUseKeyInService(const struct HksParamSet * paramSet,const struct HksProcessInfo * processInfo,struct HksParamSet ** outParamSet)355 int32_t AppendNewInfoForUseKeyInService(const struct HksParamSet *paramSet,
356 const struct HksProcessInfo *processInfo, struct HksParamSet **outParamSet)
357 {
358 return AppendProcessInfoAndDefaultStrategy(paramSet, processInfo, NULL, outParamSet);
359 }
360
361 #ifndef _CUT_AUTHENTICATE_
362 #ifdef HKS_SUPPORT_USER_AUTH_ACCESS_CONTROL
AppendSecUid(struct HksParamSet * newParamSet,struct SecInfoWrap * secInfo)363 static int32_t AppendSecUid(struct HksParamSet *newParamSet, struct SecInfoWrap *secInfo)
364 {
365 struct HksParam secureUid;
366 secureUid.tag = HKS_TAG_USER_AUTH_SECURE_UID;
367 secureUid.blob.size = sizeof(uint64_t);
368 secureUid.blob.data = (uint8_t *)&secInfo->secureUid;
369 return HksAddParams(newParamSet, &secureUid, 1);
370 }
371
ConstructEnrolledInfoBlob(struct SecInfoWrap * secInfo,struct HksBlob * enrolledInfo,struct HksParam * outParam)372 static int32_t ConstructEnrolledInfoBlob(struct SecInfoWrap *secInfo, struct HksBlob *enrolledInfo,
373 struct HksParam *outParam)
374 {
375 (void)memset_s(enrolledInfo->data, enrolledInfo->size, 0, enrolledInfo->size);
376
377 uint32_t index = 0;
378 HKS_IF_NOT_EOK_LOGE_RETURN(memcpy_s(enrolledInfo->data, enrolledInfo->size, &secInfo->enrolledInfoLen,
379 sizeof(uint32_t)), HKS_ERROR_INSUFFICIENT_MEMORY, "copy enrolledInfoLen failed!")
380 index += sizeof(secInfo->enrolledInfoLen);
381 for (uint32_t i = 0; i < secInfo->enrolledInfoLen; ++i) {
382 uint32_t authTypeInt = (uint32_t)secInfo->enrolledInfo[i].authType;
383 HKS_IF_NOT_EOK_LOGE_RETURN(memcpy_s(enrolledInfo->data + index, enrolledInfo->size - index, &authTypeInt,
384 sizeof(uint32_t)), HKS_ERROR_INSUFFICIENT_MEMORY, "copy authType failed!")
385 index += sizeof(authTypeInt);
386 HKS_IF_NOT_EOK_LOGE_RETURN(memcpy_s(enrolledInfo->data + index, enrolledInfo->size - index,
387 &((secInfo->enrolledInfo[i]).enrolledId), sizeof(uint64_t)) != EOK, HKS_ERROR_INSUFFICIENT_MEMORY,
388 "copy enrolledId failed!")
389 index += sizeof(secInfo->enrolledInfo[i].enrolledId);
390 }
391
392 outParam->tag = HKS_TAG_USER_AUTH_ENROLL_ID_INFO;
393 outParam->blob = *enrolledInfo;
394 return HKS_SUCCESS;
395 }
396
ComputeEnrolledInfoLen(uint32_t enrolledInfoLen)397 static uint32_t ComputeEnrolledInfoLen(uint32_t enrolledInfoLen)
398 {
399 return sizeof(uint32_t) + (sizeof(uint32_t) + sizeof(uint64_t)) * enrolledInfoLen;
400 }
401
AddEnrolledInfoInParamSet(struct SecInfoWrap * secInfo,struct HksBlob * enrolledInfo,struct HksParamSet ** paramSet)402 static int32_t AddEnrolledInfoInParamSet(struct SecInfoWrap *secInfo, struct HksBlob *enrolledInfo,
403 struct HksParamSet **paramSet)
404 {
405 int32_t ret;
406 do {
407 struct HksParam tmpParam;
408 enrolledInfo->size = ComputeEnrolledInfoLen(secInfo->enrolledInfoLen);
409 enrolledInfo->data = (uint8_t *)HksMalloc(enrolledInfo->size);
410 if (enrolledInfo->data == NULL) {
411 HKS_LOG_E("malloc enrolledInfo blob failed");
412 ret = HKS_ERROR_MALLOC_FAIL;
413 break;
414 }
415
416 ret = ConstructEnrolledInfoBlob(secInfo, enrolledInfo, &tmpParam);
417 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "ConstructEnrolledInfoBlob failed!")
418
419 ret = HksAddParams(*paramSet, &tmpParam, 1);
420 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add params failed")
421
422 ret = HksBuildParamSet(paramSet);
423 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "build append info failed")
424 } while (0);
425 HKS_FREE(enrolledInfo->data);
426 return ret;
427 }
428
BuildUserAuthParamSet(const struct HksParamSet * paramSet,struct HksParamSet ** outParamSet)429 static int32_t BuildUserAuthParamSet(const struct HksParamSet *paramSet, struct HksParamSet **outParamSet)
430 {
431 struct HksParamSet *newParamSet = NULL;
432 int32_t ret;
433 do {
434 ret = (paramSet != NULL) ? AppendToNewParamSet(paramSet, &newParamSet) : HksInitParamSet(&newParamSet);
435 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "init param set failed")
436 ret = HksBuildParamSet(&newParamSet);
437 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "build append info failed")
438 *outParamSet = newParamSet;
439 } while (0);
440 if (ret != HKS_SUCCESS) {
441 HksFreeParamSet(&newParamSet);
442 *outParamSet = NULL;
443 }
444 return ret;
445 }
446
447 // callback
AppendUserAuthInfo(const struct HksParamSet * paramSet,int32_t userId,uint32_t authAccessType,struct HksParamSet ** outParamSet)448 static int32_t AppendUserAuthInfo(const struct HksParamSet *paramSet, int32_t userId, uint32_t authAccessType,
449 struct HksParamSet **outParamSet)
450 {
451 (void)authAccessType;
452 struct SecInfoWrap *secInfo = NULL;
453 struct HksParamSet *newParamSet = NULL;
454 int32_t ret;
455
456 struct HksBlob enrolledInfo = { 0, NULL };
457 do {
458 ret = HksUserIdmGetSecInfo(userId, &secInfo); // callback
459 if (ret != HKS_SUCCESS) {
460 HKS_LOG_E("get useriam sec info failed ret=%" LOG_PUBLIC "d", ret);
461 ret = HKS_ERROR_GET_USERIAM_SECINFO_FAILED;
462 break;
463 }
464
465 ret = (paramSet != NULL) ? AppendToNewParamSet(paramSet, &newParamSet) : HksInitParamSet(&newParamSet);
466 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "init param set failed")
467
468 ret = AppendSecUid(newParamSet, secInfo);
469 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "append sec uid failed")
470
471 ret = AddEnrolledInfoInParamSet(secInfo, &enrolledInfo, &newParamSet);
472 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "AddEnrolledInfoInParamSet failed!")
473
474 *outParamSet = newParamSet;
475 } while (0);
476 HKS_MEMSET_FREE_BLOB(enrolledInfo);
477 if (secInfo != NULL) {
478 HKS_MEMSET_FREE_PTR(secInfo->enrolledInfo, sizeof(struct EnrolledInfoWrap) * secInfo->enrolledInfoLen);
479 HKS_MEMSET_FREE_PTR(secInfo, sizeof(struct SecInfoWrap));
480 }
481 if (ret != HKS_SUCCESS) {
482 HksFreeParamSet(&newParamSet);
483 *outParamSet = NULL;
484 }
485 return ret;
486 }
487
488 // callback
CheckIfEnrollAuthInfo(int32_t userId,enum HksUserAuthType authType)489 static int32_t CheckIfEnrollAuthInfo(int32_t userId, enum HksUserAuthType authType)
490 {
491 uint32_t numOfAuthInfo = 0;
492 int32_t ret = HksUserIdmGetAuthInfoNum(userId, authType, &numOfAuthInfo); // callback
493 HKS_IF_TRUE_LOGE_RETURN(ret == HKS_ERROR_CREDENTIAL_NOT_EXIST || numOfAuthInfo == 0,
494 HKS_ERROR_CREDENTIAL_NOT_EXIST, "have not enroll the auth info.")
495
496 return ret;
497 }
498
499 // callback
CheckIfUserIamSupportCurType(int32_t userId,uint32_t userAuthType)500 static int32_t CheckIfUserIamSupportCurType(int32_t userId, uint32_t userAuthType)
501 {
502 const enum HksUserAuthType userAuthTypes[] = {
503 HKS_USER_AUTH_TYPE_FINGERPRINT,
504 HKS_USER_AUTH_TYPE_FACE,
505 HKS_USER_AUTH_TYPE_PIN
506 };
507 int32_t ret;
508 for (uint32_t i = 0; i < HKS_ARRAY_SIZE(userAuthTypes); ++i) {
509 HKS_IF_TRUE_CONTINUE((userAuthType & userAuthTypes[i]) == 0);
510 ret = CheckIfEnrollAuthInfo(userId, userAuthTypes[i]); // callback
511 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret,
512 "no enrolled info of the user auth type: %" LOG_PUBLIC "d.", userAuthTypes[i])
513 }
514 return HKS_SUCCESS;
515 }
516
517 // callback
AppendNewInfoForGenKeyInService(const struct HksProcessInfo * processInfo,const struct HksParamSet * paramSet,struct HksParamSet ** outParamSet)518 int32_t AppendNewInfoForGenKeyInService(const struct HksProcessInfo *processInfo,
519 const struct HksParamSet *paramSet, struct HksParamSet **outParamSet)
520 {
521 uint32_t userAuthType = 0;
522 uint32_t authAccessType = 0;
523 int32_t ret = HksCheckAndGetUserAuthInfo(paramSet, &userAuthType, &authAccessType);
524 if (ret == HKS_ERROR_NOT_SUPPORTED) {
525 struct HksParamSet *newParamSet = NULL;
526 ret = AppendProcessInfoAndDefaultStrategy(paramSet, processInfo, NULL, &newParamSet);
527 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret,
528 "append process info and default strategy failed, ret = %" LOG_PUBLIC "d", ret)
529 *outParamSet = newParamSet;
530 return HKS_SUCCESS;
531 }
532
533 if (ret == HKS_SUCCESS) {
534 HKS_LOG_I("support secure access");
535
536 // Fine-grained access control: only valid user auth key purpose allowed to be set.
537 ret = HksCheckUserAuthKeyPurposeValidity(paramSet);
538 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check user auth key purpose validity failed")
539
540 struct HksParamSet *userAuthParamSet = NULL;
541
542 if (authAccessType == HKS_AUTH_ACCESS_ALWAYS_VALID) {
543 HKS_LOG_I("authAccessType is always vaild, CheckIfUserIamSupportCurType pass.");
544 ret = BuildUserAuthParamSet(paramSet, &userAuthParamSet);
545 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "Build UserAuthParamSet failed!")
546 } else {
547 HKS_IF_TRUE_LOGE_RETURN(HksCheckIsAllowedWrap(paramSet), HKS_ERROR_KEY_NOT_ALLOW_WRAP,
548 "key with access control isn't allowed wrap!")
549
550 void *data = HksLockUserIdm();
551 HKS_IF_NULL_LOGE_RETURN(data, HKS_ERROR_SESSION_REACHED_LIMIT, "HksLockUserIdm fail")
552 do {
553 ret = CheckIfUserIamSupportCurType(processInfo->userIdInt, userAuthType); // callback
554 HKS_IF_NOT_SUCC_LOGE_BREAK(ret,
555 "UserIAM do not support current user auth or not enrolled cur auth info")
556
557 // callback
558 ret = AppendUserAuthInfo(paramSet, processInfo->userIdInt, authAccessType, &userAuthParamSet);
559 HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "append secure access info failed!")
560 } while (false);
561 HksUnlockUserIdm(data);
562 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "CheckIfUserIamSupportCurType or AppendUserAuthInfo fail")
563 }
564 struct HksParamSet *newInfoParamSet = NULL;
565 ret = AppendProcessInfoAndDefaultStrategy(userAuthParamSet, processInfo, NULL, &newInfoParamSet);
566 if (ret != HKS_SUCCESS) {
567 HksFreeParamSet(&userAuthParamSet);
568 HKS_LOG_E("append process info and default strategy failed, ret = %" LOG_PUBLIC "d", ret);
569 return ret;
570 }
571 HksFreeParamSet(&userAuthParamSet);
572 *outParamSet = newInfoParamSet;
573 return HKS_SUCCESS;
574 }
575 return ret;
576 }
577 #else
AppendNewInfoForGenKeyInService(const struct HksProcessInfo * processInfo,const struct HksParamSet * paramSet,struct HksParamSet ** outParamSet)578 int32_t AppendNewInfoForGenKeyInService(const struct HksProcessInfo *processInfo,
579 const struct HksParamSet *paramSet, struct HksParamSet **outParamSet)
580 {
581 return AppendProcessInfoAndDefaultStrategy(paramSet, processInfo, NULL, outParamSet);
582 }
583 #endif /* HKS_SUPPORT_USER_AUTH_ACCESS_CONTROL */
584 #endif /* _CUT_AUTHENTICATE_ */