• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&paramSet);
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(&paramSet);
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(&paramSet);
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_ */