• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 #ifdef HKS_CONFIG_FILE
18 #include HKS_CONFIG_FILE
19 #else
20 #include "hks_config.h"
21 #endif
22 
23 #include "hks_secure_access.h"
24 
25 #include "hks_base_check.h"
26 #include "hks_keyblob.h"
27 #include "hks_keynode.h"
28 #include "hks_log.h"
29 #include "hks_mem.h"
30 #include "hks_param.h"
31 #include "hks_type_inner.h"
32 #include "hks_template.h"
33 #include "hks_util.h"
34 
35 #ifdef HKS_ENABLE_IS_PASSWORD_SET
36 #include "hks_useridm_api_wrap.h"
37 #endif
38 
39 #include "securec.h"
40 
41 #ifdef HKS_SUPPORT_USER_AUTH_ACCESS_CONTROL
42 
43 #include "hks_crypto_hal.h"
44 #include "hks_core_useriam_wrap.h"
45 
46 #define BYTES_PER_POS 8
47 #define S_TO_MS 1000
48 #define DEFAULT_TIME_OUT 3
49 #define AUTH_INFO_LEN (sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint64_t))
50 
51 struct HksSecureAccessInnerParams {
52     const struct HksParamSet *initParamSet;
53     uint32_t challengePos;
54     bool isUserAuthAccess;
55     bool isSecureSign;
56     struct HksBlob *outToken;
57 };
58 
59 struct HksAppendDataInnerParams {
60     struct HuksKeyNode *keyNode;
61     const struct HksParamSet *inParamSet;
62     const struct HksBlob *inData;
63 };
64 
CheckChallengeTypeValidity(const struct HksParam * blobChallengeType,struct HksSecureAccessInnerParams * innerParams)65 static int32_t CheckChallengeTypeValidity(const struct HksParam *blobChallengeType,
66     struct HksSecureAccessInnerParams *innerParams)
67 {
68     if (blobChallengeType->uint32Param == HKS_CHALLENGE_TYPE_CUSTOM) {
69         struct HksParam *challengePosParam = NULL;
70         int32_t ret = HksGetParam(innerParams->initParamSet, HKS_TAG_CHALLENGE_POS, &challengePosParam);
71         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get init paramSet's challenge pos failed!")
72 
73         if (challengePosParam->uint32Param > HKS_CHALLENGE_POS_3) {
74             HKS_LOG_E("challenge position should in range of 0~3!");
75             return HKS_ERROR_INVALID_ARGUMENT;
76         }
77         innerParams->challengePos = challengePosParam->uint32Param;
78     } else {
79         innerParams->challengePos = 0;
80     }
81 
82     if (blobChallengeType->uint32Param == HKS_CHALLENGE_TYPE_NONE) {
83         // must set zero for ClientInit judgement
84         innerParams->outToken->size = 0;
85         return HKS_SUCCESS;
86     }
87 
88     if (innerParams->outToken->size < TOKEN_SIZE) {
89         return HKS_ERROR_INVALID_ARGUMENT;
90     }
91     return HKS_SUCCESS;
92 }
93 
IsNeedSkipUserAuthAccessControl(const struct HksParamSet * keyBlobParamSet,const struct HksParamSet * initParamSet)94 static int32_t IsNeedSkipUserAuthAccessControl(const struct HksParamSet *keyBlobParamSet,
95     const struct HksParamSet *initParamSet)
96 {
97     // step 1. Judge whether the user auth key purpose is set.
98     struct HksParam *userAuthKeyPurposeParam = NULL;
99     int32_t ret = HksGetParam(keyBlobParamSet, HKS_TAG_KEY_AUTH_PURPOSE, &userAuthKeyPurposeParam);
100     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_SUCCESS, "not set key auth purpose: default need user auth access control!")
101 
102     // step 2. Judge the validify of symmetric and asymmetric algorithm settings for purpose.
103     ret = HksCheckUserAuthKeyInfoValidity(initParamSet);
104     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksCheckUserAuthKeyInfoValidity failed!")
105 
106     // step 3. Determine if user auth access control needs to be skipped, and the keyPurpose is not 0.
107     struct HksParam *keyPurposeParam = NULL;
108     ret = HksGetParam(initParamSet, HKS_TAG_PURPOSE, &keyPurposeParam);
109     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get key purpose param failed!")
110 
111     if ((keyPurposeParam->uint32Param | userAuthKeyPurposeParam->uint32Param) !=
112         userAuthKeyPurposeParam->uint32Param) {
113         HKS_LOG_E("it needs to skip user auth access control base on the current value of key purpose!");
114         return HKS_ERROR_NEED_SKIP_ACCESS_CONTROL;
115     }
116 
117     return HKS_SUCCESS;
118 }
119 
CheckInitParamSetValidityAndGet(const struct HksParamSet * keyBlobParamSet,struct HksSecureAccessInnerParams * innerParams)120 static int32_t CheckInitParamSetValidityAndGet(const struct HksParamSet *keyBlobParamSet,
121     struct HksSecureAccessInnerParams *innerParams)
122 {
123     struct HksParam *blobUserAuthType = NULL;
124     int32_t ret = HksGetParam(keyBlobParamSet, HKS_TAG_USER_AUTH_TYPE, &blobUserAuthType);
125     if (ret == HKS_ERROR_PARAM_NOT_EXIST) {
126         innerParams->isUserAuthAccess = false;
127         innerParams->isSecureSign = false;
128         // must set zero for ClientInit judgement
129         innerParams->outToken->size = 0;
130         return HKS_SUCCESS;
131     }
132     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get blob user auth type failed!")
133 
134     // Fine-grained access control: determine if access to skip access control is necessary.
135     ret = IsNeedSkipUserAuthAccessControl(keyBlobParamSet, innerParams->initParamSet);
136     if (ret == HKS_ERROR_NEED_SKIP_ACCESS_CONTROL) {
137         innerParams->isUserAuthAccess = false;
138         innerParams->isSecureSign = false;
139         innerParams->outToken->size = 0;
140         return HKS_SUCCESS;
141     }
142     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "unable to judge whether access control is required!")
143 
144     struct HksParam *blobChallengeType = NULL;
145     ret = HksGetParam(keyBlobParamSet, HKS_TAG_CHALLENGE_TYPE, &blobChallengeType);
146     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get blob challenge type failed!")
147 
148     ret = CheckChallengeTypeValidity(blobChallengeType, innerParams);
149     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check init paramSet's challenge type related params failed!")
150 
151     struct HksParam *secureSignTag = NULL;
152     ret = HksGetParam(keyBlobParamSet, HKS_TAG_KEY_SECURE_SIGN_TYPE, &secureSignTag);
153     if (ret == HKS_SUCCESS) {
154         ret = HksCheckSecureSignParams(secureSignTag->uint32Param);
155         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "invalid key blob secure sign type!")
156 
157         innerParams->isSecureSign = true;
158     } else {
159         innerParams->isSecureSign = false;
160     }
161 
162     innerParams->isUserAuthAccess = true;
163     return HKS_SUCCESS;
164 }
165 
AddChallengeParams(struct HksParamSet * paramSet,struct HksBlob * challengeBlob)166 static int32_t AddChallengeParams(struct HksParamSet *paramSet, struct HksBlob *challengeBlob)
167 {
168     int32_t ret = HksCryptoHalFillRandom(challengeBlob);
169     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "generate challenge failed!")
170 
171     struct HksParam challengeParam;
172     challengeParam.tag = HKS_TAG_KEY_INIT_CHALLENGE;
173     challengeParam.blob = *challengeBlob;
174     ret = HksAddParams(paramSet, &challengeParam, 1);
175     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "add challenge params fail")
176 
177     return HKS_SUCCESS;
178 }
179 
AddKeyAccessTimeParams(struct HksParamSet * paramSet)180 static int32_t AddKeyAccessTimeParams(struct HksParamSet *paramSet)
181 {
182     uint64_t curTime = 0;
183     int32_t ret = HksElapsedRealTime(&curTime);
184     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get elapsed real time failed!")
185 
186     struct HksParam accessTimeParam;
187     accessTimeParam.tag = HKS_TAG_KEY_ACCESS_TIME;
188     accessTimeParam.uint64Param = curTime / S_TO_MS;
189     ret = HksAddParams(paramSet, &accessTimeParam, 1);
190     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "add access time param fail")
191 
192     return HKS_SUCCESS;
193 }
194 
AssignToken(struct HksBlob * token,const struct HksBlob * challenge)195 static int32_t AssignToken(struct HksBlob *token, const struct HksBlob *challenge)
196 {
197     if (token->size >= TOKEN_SIZE) {
198         if (memcpy_s(token->data, token->size, challenge->data, challenge->size) != EOK) {
199             HKS_LOG_E("copy token failed");
200             return HKS_ERROR_INSUFFICIENT_MEMORY;
201         }
202         token->size = challenge->size;
203         return HKS_SUCCESS;
204     } else if (token->size == 0) {
205         return HKS_SUCCESS;
206     } else {
207         HKS_LOG_E("token size is too small");
208         return HKS_ERROR_INVALID_ARGUMENT;
209     }
210 }
211 
AddAppendDataPlaceholder(struct HksParamSet * paramSet,uint8_t * appendDataPlaceholder,uint32_t placeholderSize)212 static int32_t AddAppendDataPlaceholder(struct HksParamSet *paramSet, uint8_t *appendDataPlaceholder,
213     uint32_t placeholderSize)
214 {
215     struct HksParam signAuthParam = {
216         .tag = HKS_TAG_APPENDED_DATA_PREFIX,
217         .blob = {
218             .size = placeholderSize,
219             .data = appendDataPlaceholder
220         }
221     };
222 
223     int32_t ret = HksAddParams(paramSet, &signAuthParam, 1);
224     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "add sign auth info params fail")
225 
226     return HKS_SUCCESS;
227 }
228 
AddDefaultAuthRuntimeParams(struct HksParamSet * paramSet,struct HksSecureAccessInnerParams * innerParams,bool isNeedAppendAuthInfo)229 static int32_t AddDefaultAuthRuntimeParams(struct HksParamSet *paramSet,
230     struct HksSecureAccessInnerParams *innerParams, bool isNeedAppendAuthInfo)
231 {
232     struct HksParam defineParams[] = {
233         { .tag = HKS_TAG_IS_USER_AUTH_ACCESS, .boolParam = innerParams->isUserAuthAccess },
234         { .tag = HKS_TAG_IF_NEED_APPEND_AUTH_INFO, .boolParam = isNeedAppendAuthInfo },
235         { .tag = HKS_TAG_IS_APPEND_UPDATE_DATA, .boolParam = false },
236         { .tag = HKS_TAG_KEY_AUTH_RESULT, .int32Param = HKS_AUTH_RESULT_INIT },
237         { .tag = HKS_TAG_CHALLENGE_POS, .uint32Param = innerParams->challengePos }
238     };
239 
240     int32_t ret = HksAddParams(paramSet, defineParams, sizeof(defineParams) / sizeof(defineParams[0]));
241     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "add runtime defineParams fail")
242 
243     return HKS_SUCCESS;
244 }
245 
BuildAuthRuntimeParamSet(struct HksSecureAccessInnerParams * innerParams,bool isNeedAppendAuthInfo,struct HksParamSet ** outParamSet)246 static int32_t BuildAuthRuntimeParamSet(struct HksSecureAccessInnerParams *innerParams, bool isNeedAppendAuthInfo,
247     struct HksParamSet **outParamSet)
248 {
249     struct HksParamSet *paramSet = NULL;
250     int32_t ret = HksInitParamSet(&paramSet);
251     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init keyNode auth runtime param set fail")
252 
253     do {
254         ret = AddDefaultAuthRuntimeParams(paramSet, innerParams, isNeedAppendAuthInfo);
255         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add auth runtime default params fail")
256 
257         ret = AddKeyAccessTimeParams(paramSet);
258         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add key access time params failed!")
259 
260         uint8_t challenge[TOKEN_SIZE] = {0};
261         struct HksBlob challengeBlob = { TOKEN_SIZE, challenge };
262         ret = AddChallengeParams(paramSet, &challengeBlob);
263         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add challenge params failed!")
264 
265         if (isNeedAppendAuthInfo) {
266             uint8_t appendPlaceholder[sizeof(struct HksSecureSignAuthInfo)] = {0};
267             ret = AddAppendDataPlaceholder(paramSet, appendPlaceholder, sizeof(appendPlaceholder));
268             HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "add append data info params fail")
269         }
270 
271         ret = HksBuildParamSet(&paramSet);
272         HKS_IF_NOT_SUCC_BREAK(ret)
273 
274         ret = AssignToken(innerParams->outToken, &challengeBlob);
275         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "assign out token failed")
276 
277         *outParamSet = paramSet;
278         return HKS_SUCCESS;
279     } while (0);
280 
281     HksFreeParamSet(&paramSet);
282     return ret;
283 }
284 
HksVerifyKeyChallenge(const struct HuksKeyNode * keyNode,const struct HksUserAuthToken * token,uint32_t challengePos,uint32_t checkLen)285 static int32_t HksVerifyKeyChallenge(const struct HuksKeyNode *keyNode, const struct HksUserAuthToken *token,
286     uint32_t challengePos, uint32_t checkLen)
287 {
288     struct HksParam *challenge = NULL;
289     int32_t ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_KEY_INIT_CHALLENGE, &challenge);
290     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get init challenge failed!")
291 
292     if (checkLen + challengePos * BYTES_PER_POS > challenge->blob.size) {
293         HKS_LOG_E("check challenge too long!");
294         return HKS_ERROR_INVALID_ARGUMENT;
295     }
296     if (HksMemCmp(challenge->blob.data + challengePos * BYTES_PER_POS,
297         token->plaintextData.challenge + challengePos * BYTES_PER_POS, checkLen) != 0) {
298         HKS_LOG_E("verify challenge failed!");
299         return HKS_ERROR_KEY_AUTH_FAILED;
300     }
301     return HKS_SUCCESS;
302 }
303 
HksVerifyKeyTimestamp(const struct HuksKeyNode * keyNode,const struct HksUserAuthToken * token)304 static int32_t HksVerifyKeyTimestamp(const struct HuksKeyNode *keyNode, const struct HksUserAuthToken *token)
305 {
306     uint32_t timeOutInt = DEFAULT_TIME_OUT;
307     struct HksParam *timeOut = NULL;
308     int32_t ret = HksGetParam(keyNode->keyBlobParamSet, HKS_TAG_AUTH_TIMEOUT, &timeOut);
309     if (ret == HKS_SUCCESS) {
310         timeOutInt = timeOut->uint32Param;
311     }
312 
313     struct HksParam *accessTime = NULL;
314     ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_KEY_ACCESS_TIME, &accessTime);
315     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get access time failed!")
316 
317     // ms to s
318     uint64_t authTokenTime = token->plaintextData.time / S_TO_MS;
319     if ((accessTime->uint64Param > authTokenTime && accessTime->uint64Param - authTokenTime > timeOutInt) ||
320         (authTokenTime > accessTime->uint64Param && authTokenTime - accessTime->uint64Param > timeOutInt)) {
321         HKS_LOG_E("auth token time out!");
322         return HKS_ERROR_KEY_AUTH_TIME_OUT;
323     }
324     return HKS_SUCCESS;
325 }
326 
CheckAuthToken(const struct HksBlob * authTokenParam)327 static int32_t CheckAuthToken(const struct HksBlob *authTokenParam)
328 {
329     if (authTokenParam->size != sizeof(struct HksUserAuthToken)) {
330         HKS_LOG_E("size of authTokenParam not match HksUserAuthToken!");
331         return HKS_ERROR_INVALID_ARGUMENT;
332     }
333     return HKS_SUCCESS;
334 }
335 
ParseAuthToken(const struct HksBlob * inAuthTokenParam,struct HksUserAuthToken ** outAuthToken)336 static int32_t ParseAuthToken(const struct HksBlob *inAuthTokenParam, struct HksUserAuthToken **outAuthToken)
337 {
338     int32_t ret = CheckAuthToken(inAuthTokenParam);
339     HKS_IF_NOT_SUCC_RETURN(ret, ret)
340 
341     struct HksUserAuthToken *authToken = NULL;
342     do {
343         authToken = (struct HksUserAuthToken *)HksMalloc(sizeof(struct HksUserAuthToken));
344         if (authToken == NULL) {
345             HKS_LOG_E("malloc for authToken failed!");
346             ret = HKS_ERROR_MALLOC_FAIL;
347             break;
348         }
349 
350         (void)memcpy_s(authToken, sizeof(struct HksUserAuthToken), inAuthTokenParam->data, inAuthTokenParam->size);
351         *outAuthToken = authToken;
352         return HKS_SUCCESS;
353     } while (0);
354 
355     HKS_FREE(authToken);
356     return ret;
357 }
358 
GetAuthToken(const struct HksParamSet * paramSet,struct HksUserAuthToken ** authToken)359 static int32_t GetAuthToken(const struct HksParamSet *paramSet, struct HksUserAuthToken **authToken)
360 {
361     struct HksParam *authTokenParam = NULL;
362     int32_t ret = HksGetParam(paramSet, HKS_TAG_AUTH_TOKEN, &authTokenParam);
363     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_AUTH_TOKEN_FAILED, "get auth token param failed!")
364 
365     ret = ParseAuthToken(&authTokenParam->blob, authToken);
366     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_AUTH_TOKEN, "parse auth token failed!")
367 
368     return HKS_SUCCESS;
369 }
370 
GetChallengePos(const struct HksParamSet * paramSet,uint32_t * pos)371 static int32_t GetChallengePos(const struct HksParamSet *paramSet, uint32_t *pos)
372 {
373     struct HksParam *posParam = NULL;
374     int32_t ret = HksGetParam(paramSet, HKS_TAG_CHALLENGE_POS, &posParam);
375     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT, "get challenge pos failed!")
376 
377     *pos = posParam->uint32Param;
378     return ret;
379 }
380 
GetChallengeType(const struct HksParamSet * paramSet,uint32_t * type)381 static int32_t GetChallengeType(const struct HksParamSet *paramSet, uint32_t *type)
382 {
383     struct HksParam *typeParam = NULL;
384     int32_t ret = HksGetParam(paramSet, HKS_TAG_CHALLENGE_TYPE, &typeParam);
385     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get challenge type failed!")
386 
387     *type = typeParam->uint32Param;
388     return HKS_SUCCESS;
389 }
390 
VerifyCustomChallenge(const struct HuksKeyNode * keyNode,const struct HksUserAuthToken * authToken)391 static int32_t VerifyCustomChallenge(const struct HuksKeyNode *keyNode, const struct HksUserAuthToken *authToken)
392 {
393     uint32_t pos = 0;
394     int32_t ret = GetChallengePos(keyNode->authRuntimeParamSet, &pos);
395     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_INVALID_ARGUMENT, "get challenge pos failed!")
396 
397     return HksVerifyKeyChallenge(keyNode, authToken, pos, BYTES_PER_POS);
398 }
399 
VerifyNormalChallenge(const struct HuksKeyNode * keyNode,const struct HksUserAuthToken * authToken)400 static int32_t VerifyNormalChallenge(const struct HuksKeyNode *keyNode, const struct HksUserAuthToken *authToken)
401 {
402     return HksVerifyKeyChallenge(keyNode, authToken, 0, TOKEN_SIZE);
403 }
404 
VerifyChallengeOrTimeStamp(const struct HuksKeyNode * keyNode,const struct HksUserAuthToken * authToken)405 static int32_t VerifyChallengeOrTimeStamp(const struct HuksKeyNode *keyNode, const struct HksUserAuthToken *authToken)
406 {
407     uint32_t blobChallengeType;
408     int32_t ret = GetChallengeType(keyNode->keyBlobParamSet, &blobChallengeType);
409     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get challenge type failed!")
410 
411     switch (blobChallengeType) {
412         case HKS_CHALLENGE_TYPE_NORMAL:
413             ret = VerifyNormalChallenge(keyNode, authToken);
414             break;
415         case HKS_CHALLENGE_TYPE_CUSTOM:
416             ret = VerifyCustomChallenge(keyNode, authToken);
417             break;
418         case HKS_CHALLENGE_TYPE_NONE:
419             ret = HksVerifyKeyTimestamp(keyNode, authToken);
420             break;
421         default:
422             ret = HKS_ERROR_BAD_STATE;
423             break;
424     }
425     return ret;
426 }
427 
VerifyFrontUserIdIfNeed(const struct HksParamSet * keyBlobParamSet,const struct HksUserAuthToken * authToken)428 static int32_t VerifyFrontUserIdIfNeed(const struct HksParamSet *keyBlobParamSet,
429     const struct HksUserAuthToken *authToken)
430 {
431     struct HksParam *frontUserIdParam = NULL;
432     int32_t ret = HksGetParam(keyBlobParamSet, HKS_TAG_FRONT_USER_ID, &frontUserIdParam);
433     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get frontUserIdParam failed!")
434 
435     HKS_LOG_I("Verify FrontUserId:  frontUserId = %" LOG_PUBLIC "d; UserId in authToken = %" LOG_PUBLIC "d",
436         frontUserIdParam->int32Param, authToken->ciphertextData.userId);
437 
438     if (frontUserIdParam->int32Param != authToken->ciphertextData.userId) {
439         HKS_LOG_E("check userId failed!");
440         return HKS_ERROR_KEY_AUTH_PERMANENTLY_INVALIDATED;
441     }
442     return HKS_SUCCESS;
443 }
444 
VerifySecureUidIfNeed(const struct HksParamSet * keyBlobParamSet,const struct HksUserAuthToken * authToken,uint32_t authAccessType)445 static int32_t VerifySecureUidIfNeed(const struct HksParamSet *keyBlobParamSet,
446     const struct HksUserAuthToken *authToken, uint32_t authAccessType)
447 {
448     if ((authAccessType & HKS_AUTH_ACCESS_INVALID_CLEAR_PASSWORD) == 0) {
449         return HKS_SUCCESS;
450     }
451 
452     struct HksParam *secUid = NULL;
453     int32_t ret = HksGetParam(keyBlobParamSet, HKS_TAG_USER_AUTH_SECURE_UID, &secUid);
454     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get sec uid failed!")
455 
456     if (secUid->blob.size != sizeof(uint64_t)) {
457         HKS_LOG_E("invalid sec uid param!");
458         return HKS_ERROR_BAD_STATE;
459     }
460 
461     if (HksMemCmp(secUid->blob.data, &authToken->ciphertextData.secureUid, sizeof(uint64_t)) != 0) {
462         HKS_LOG_E("check sec uid failed!");
463         return HKS_ERROR_KEY_AUTH_PERMANENTLY_INVALIDATED;
464     }
465     return HKS_SUCCESS;
466 }
467 
VerifyEnrolledIdInfoIfNeed(const struct HksParamSet * keyBlobParamSet,const struct HksUserAuthToken * authToken,uint32_t blobAuthType,uint32_t authAccessType,uint32_t authTokenAuthType)468 static int32_t VerifyEnrolledIdInfoIfNeed(const struct HksParamSet *keyBlobParamSet,
469     const struct HksUserAuthToken *authToken, uint32_t blobAuthType, uint32_t authAccessType,
470     uint32_t authTokenAuthType)
471 {
472     if ((blobAuthType & (HKS_USER_AUTH_TYPE_FACE | HKS_USER_AUTH_TYPE_FINGERPRINT)) == 0 ||
473         (authAccessType & HKS_AUTH_ACCESS_INVALID_NEW_BIO_ENROLL) == 0) {
474         return HKS_SUCCESS;
475     }
476 
477     struct HksParam *enrolledIdInfo = NULL;
478     int32_t ret = HksGetParam(keyBlobParamSet, HKS_TAG_USER_AUTH_ENROLL_ID_INFO, &enrolledIdInfo);
479     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get enrolled info param failed!")
480 
481     struct HksBlob enrolledIdInfoBlob = enrolledIdInfo->blob;
482     if (enrolledIdInfoBlob.size < ENROLLED_ID_INFO_MIN_LEN) {
483         HKS_LOG_E("get enrolled info param invalid!");
484         return HKS_ERROR_BAD_STATE;
485     }
486 
487     uint32_t enrolledIdNum = 0;
488     (void)memcpy_s(&enrolledIdNum, sizeof(uint32_t), enrolledIdInfoBlob.data, sizeof(uint32_t));
489     uint32_t index = sizeof(uint32_t);
490 
491     for (uint32_t i = 0; i < enrolledIdNum && index < enrolledIdInfoBlob.size; ++i) {
492         uint32_t authType = 0;
493         (void)memcpy_s(&authType, sizeof(uint32_t), enrolledIdInfoBlob.data + index, sizeof(uint32_t));
494         index += sizeof(uint32_t);
495 
496         uint64_t enrolledId = 0;
497         (void)memcpy_s(&enrolledId, sizeof(uint64_t), enrolledIdInfoBlob.data + index, sizeof(uint64_t));
498         index += sizeof(uint64_t);
499         if (authType == authTokenAuthType && enrolledId == authToken->ciphertextData.enrolledId) {
500             return HKS_SUCCESS;
501         }
502     }
503     HKS_LOG_E("match enrolled id failed!");
504     return HKS_ERROR_KEY_AUTH_PERMANENTLY_INVALIDATED;
505 }
506 
VerifyAuthTokenInfo(const struct HuksKeyNode * keyNode,const struct HksUserAuthToken * authToken)507 static int32_t VerifyAuthTokenInfo(const struct HuksKeyNode *keyNode, const struct HksUserAuthToken *authToken)
508 {
509     struct HksParamSet *keyBlobParamSet = keyNode->keyBlobParamSet;
510     struct HksParam *userAuthType = NULL;
511     int32_t ret = HksGetParam(keyBlobParamSet, HKS_TAG_USER_AUTH_TYPE, &userAuthType);
512     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get userAuthType type failed!")
513 
514     struct HksParam *authAccessType = NULL;
515     ret = HksGetParam(keyBlobParamSet, HKS_TAG_KEY_AUTH_ACCESS_TYPE, &authAccessType);
516     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get auth access type failed!")
517 
518     uint32_t authTokenAuthType = 0;
519     ret = HksCoreConvertUserIamTypeToHksType(HKS_AUTH_TYPE, authToken->plaintextData.authType, &authTokenAuthType);
520     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_NOT_SUPPORTED, "invalid user iam auth type:not support!")
521 
522     if ((authTokenAuthType & userAuthType->uint32Param) == 0) {
523         HKS_LOG_E("current keyblob auth do not support current auth token auth type!");
524         return HKS_ERROR_KEY_AUTH_VERIFY_FAILED;
525     }
526 
527     if (authAccessType->uint32Param == HKS_AUTH_ACCESS_ALWAYS_VALID) {
528         ret = VerifyFrontUserIdIfNeed(keyBlobParamSet, authToken);
529         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "verify Front User Id failed!")
530     } else {
531         ret = VerifySecureUidIfNeed(keyBlobParamSet, authToken, authAccessType->uint32Param);
532         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "verify sec uid failed!")
533 
534         ret = VerifyEnrolledIdInfoIfNeed(keyBlobParamSet, authToken, userAuthType->uint32Param,
535             authAccessType->uint32Param, authTokenAuthType);
536         HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "verify enrolled id info failed!")
537     }
538     return ret;
539 }
540 
HksAddVerifiedAuthTokenIfNeed(struct HuksKeyNode * keyNode,const struct HksUserAuthToken * verifiedAuthToken)541 static int32_t HksAddVerifiedAuthTokenIfNeed(struct HuksKeyNode *keyNode,
542     const struct HksUserAuthToken *verifiedAuthToken)
543 {
544     struct HksParam *isNeedSecureSignInfo = NULL;
545     int32_t ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_IF_NEED_APPEND_AUTH_INFO, &isNeedSecureSignInfo);
546     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get is secure sign failed!")
547 
548     if (isNeedSecureSignInfo->boolParam == false) {
549         return HKS_SUCCESS;
550     }
551 
552     struct HksParamSet *newAuthRuntimeParamSet = NULL;
553     ret = HksInitParamSet(&newAuthRuntimeParamSet);
554     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init new auth param set fail")
555 
556     struct HksParamSet *authRuntimeParamSet = keyNode->authRuntimeParamSet;
557     if (authRuntimeParamSet != NULL) {
558         ret = HksAddParams(newAuthRuntimeParamSet, authRuntimeParamSet->params, authRuntimeParamSet->paramsCnt);
559         if (ret != HKS_SUCCESS) {
560             HksFreeParamSet(&newAuthRuntimeParamSet);
561             HKS_LOG_E("add old auth runtime param set fail");
562             return ret;
563         }
564     }
565 
566     struct HksParam verifiedAuthTokenParam = {
567         .tag = HKS_TAG_VERIFIED_AUTH_TOKEN,
568         .blob = {
569             .size = sizeof(struct HksUserAuthToken),
570             .data = (uint8_t *)verifiedAuthToken
571         }
572     };
573 
574     ret = HksAddParams(newAuthRuntimeParamSet, &verifiedAuthTokenParam, 1);
575     if (ret != HKS_SUCCESS) {
576         HksFreeParamSet(&newAuthRuntimeParamSet);
577         HKS_LOG_E("add verified authtoken to auth runtime param set fail");
578         return ret;
579     }
580 
581     ret = HksBuildParamSet(&newAuthRuntimeParamSet);
582     if (ret != HKS_SUCCESS) {
583         HksFreeParamSet(&newAuthRuntimeParamSet);
584         HKS_LOG_E("build paramSet fail");
585         return ret;
586     }
587     HksFreeParamSet(&authRuntimeParamSet);
588     keyNode->authRuntimeParamSet = newAuthRuntimeParamSet;
589     return HKS_SUCCESS;
590 }
591 
CheckIfNeedVerifyParams(const struct HuksKeyNode * keyNode,bool * isNeedVerify,struct HksParam ** outAuthResult)592 static int32_t CheckIfNeedVerifyParams(const struct HuksKeyNode *keyNode, bool *isNeedVerify,
593     struct HksParam **outAuthResult)
594 {
595     struct HksParam *isNeedSecureAccess = NULL;
596     int32_t ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_IS_USER_AUTH_ACCESS, &isNeedSecureAccess);
597     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get isSecureAccess failed!")
598 
599     struct HksParam *authResult = NULL;
600     ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_KEY_AUTH_RESULT, &authResult);
601     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get authResult failed!")
602 
603     *outAuthResult = authResult;
604     if (isNeedSecureAccess->boolParam == false) {
605         *isNeedVerify = false;
606         return HKS_SUCCESS;
607     }
608     if (authResult->uint32Param == HKS_AUTH_RESULT_SUCCESS) {
609         *isNeedVerify = false;
610         return HKS_SUCCESS;
611     }
612 
613     *isNeedVerify = true;
614     return HKS_SUCCESS;
615 }
616 
AssignVerifyResultAndFree(int32_t outRet,struct HksParam * authResult,struct HuksKeyNode * keyNode,struct HksUserAuthToken * authToken)617 static int32_t AssignVerifyResultAndFree(int32_t outRet, struct HksParam *authResult, struct HuksKeyNode *keyNode,
618     struct HksUserAuthToken *authToken)
619 {
620     int32_t ret = outRet;
621     if (ret == HKS_SUCCESS) {
622         authResult->uint32Param = HKS_AUTH_RESULT_SUCCESS;
623         ret = HksAddVerifiedAuthTokenIfNeed(keyNode, authToken);
624         if (ret != HKS_SUCCESS) {
625             HKS_LOG_E("add verified auth token failed!");
626             HKS_FREE(authToken);
627             return HKS_ERROR_BAD_STATE;
628         }
629     } else {
630         authResult->uint32Param = HKS_AUTH_RESULT_FAILED;
631         HKS_FREE(authToken);
632     }
633     HKS_FREE(authToken);
634     return ret;
635 }
636 
GetUserAuthResult(const struct HuksKeyNode * keyNode,int32_t * authResult)637 static int32_t GetUserAuthResult(const struct HuksKeyNode *keyNode, int32_t *authResult)
638 {
639     struct HksParam *isSecureAccess = NULL;
640     int32_t ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_IS_USER_AUTH_ACCESS, &isSecureAccess);
641     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get isSecureAccess failed!")
642 
643     if (isSecureAccess->boolParam == false) {
644         *authResult = HKS_AUTH_RESULT_NONE;
645         return HKS_SUCCESS;
646     }
647 
648     struct HksParam *authResultParam = NULL;
649     ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_KEY_AUTH_RESULT, &authResultParam);
650     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get authResult failed!")
651 
652     *authResult = authResultParam->int32Param;
653     return HKS_SUCCESS;
654 }
655 
CheckParamsAndGetAppendState(const struct HuksKeyNode * keyNode,struct HksParam ** isAppendDataParam)656 static int32_t CheckParamsAndGetAppendState(const struct HuksKeyNode *keyNode, struct HksParam **isAppendDataParam)
657 {
658     HKS_IF_NULL_LOGE_RETURN(keyNode, HKS_ERROR_NULL_POINTER, "the pointer param is invalid")
659 
660     struct HksParam *isAppendData = NULL;
661     int32_t ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_IS_APPEND_UPDATE_DATA, &isAppendData);
662     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get is append update param failed")
663 
664     *isAppendDataParam = isAppendData;
665     return HKS_SUCCESS;
666 }
667 
GetSupportAppendAuthInfoParams(const struct HuksKeyNode * keyNode,bool * isNeedAppendAuthInfo,int32_t * authResultOut)668 static int32_t GetSupportAppendAuthInfoParams(const struct HuksKeyNode *keyNode, bool *isNeedAppendAuthInfo,
669     int32_t *authResultOut)
670 {
671     struct HksParam *isNeedAppendParam = NULL;
672     int32_t ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_IF_NEED_APPEND_AUTH_INFO, &isNeedAppendParam);
673     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get is need append param failed")
674 
675     int32_t authResult = (int32_t) HKS_AUTH_RESULT_NONE;
676     ret = GetUserAuthResult(keyNode, &authResult);
677     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get auth result failed")
678 
679     *isNeedAppendAuthInfo = isNeedAppendParam->boolParam;
680     *authResultOut = authResult;
681     return HKS_SUCCESS;
682 }
683 
CheckIfNeedAppendUpdateData(const struct HksAppendDataInnerParams * innerParams,bool * outIsNeedAppend,int32_t * outAuthResult,const struct HksBlob * appendedData,struct HksParam ** isAppendDataParam)684 static int32_t CheckIfNeedAppendUpdateData(const struct HksAppendDataInnerParams *innerParams, bool *outIsNeedAppend,
685     int32_t *outAuthResult, const struct HksBlob *appendedData, struct HksParam **isAppendDataParam)
686 {
687     bool isNeedAppend = false;
688     int32_t authResult = HKS_AUTH_RESULT_NONE;
689     int32_t ret = GetSupportAppendAuthInfoParams(innerParams->keyNode, &isNeedAppend, &authResult);
690     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get append auth support params failed")
691 
692     *outAuthResult = authResult;
693     if (isNeedAppend == false) {
694         *outIsNeedAppend = false;
695         return HKS_SUCCESS;
696     }
697 
698     struct HksParam *isAlreadyAppendData = NULL;
699     ret = CheckParamsAndGetAppendState(innerParams->keyNode, &isAlreadyAppendData);
700     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check is append data params failed")
701 
702     if (isAlreadyAppendData->boolParam == true) {
703         *outIsNeedAppend = false;
704         return HKS_SUCCESS;
705     }
706 
707     if (innerParams->inData == NULL || innerParams->inData->size == 0 || appendedData == NULL) {
708         HKS_LOG_E("the in data is invalid");
709         return HKS_ERROR_INVALID_ARGUMENT;
710     }
711 
712     if (UINT32_MAX - innerParams->inData->size < sizeof(struct HksSecureSignAuthInfo)) {
713         HKS_LOG_E("inData size is too large");
714         return HKS_ERROR_INVALID_ARGUMENT;
715     }
716     *outIsNeedAppend = true;
717     *isAppendDataParam = isAlreadyAppendData;
718     return HKS_SUCCESS;
719 }
720 
GetSecureSignAuthInfo(const struct HuksKeyNode * keyNode,struct HksSecureSignAuthInfo * secureSignInfo)721 static int32_t GetSecureSignAuthInfo(const struct HuksKeyNode *keyNode, struct HksSecureSignAuthInfo *secureSignInfo)
722 {
723     struct HksParam *authTokenParam = NULL;
724     int32_t ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_VERIFIED_AUTH_TOKEN, &authTokenParam);
725     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get verified auth token failed")
726 
727     if (authTokenParam->blob.size != sizeof(struct HksUserAuthToken)) {
728         return HKS_ERROR_BAD_STATE;
729     }
730 
731     struct HksUserAuthToken *authToken = (struct HksUserAuthToken *)authTokenParam->blob.data;
732     uint32_t hksAuthType;
733     ret = HksCoreConvertUserIamTypeToHksType(HKS_AUTH_TYPE, authToken->plaintextData.authType, &hksAuthType);
734     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "invalid user iam auth type")
735 
736     secureSignInfo->userAuthType = hksAuthType;
737     secureSignInfo->credentialId = authToken->ciphertextData.credentialId;
738     secureSignInfo->authenticatorId = authToken->ciphertextData.enrolledId;
739     return HKS_SUCCESS;
740 }
741 
DoAppendPrefixAuthInfoToUpdateInData(const struct HuksKeyNode * keyNode,struct HksSecureSignAuthInfo * secureSignInfo,const struct HksBlob * inData,struct HksBlob * outDataBlob)742 static int32_t DoAppendPrefixAuthInfoToUpdateInData(const struct HuksKeyNode *keyNode,
743     struct HksSecureSignAuthInfo *secureSignInfo, const struct HksBlob *inData, struct HksBlob *outDataBlob)
744 {
745     uint32_t outDataSize = sizeof(uint32_t) + sizeof(struct HksSecureSignAuthInfo) + inData->size;
746     uint8_t *outData = (uint8_t *)HksMalloc(outDataSize);
747     HKS_IF_NULL_LOGE_RETURN(outData, HKS_ERROR_MALLOC_FAIL, "malloc outData failed!")
748 
749     uint32_t version = SECURE_SIGN_VERSION;
750     (void)memcpy_s(outData, outDataSize, (uint8_t *)&version, sizeof(uint32_t));
751 
752     (void)memcpy_s(outData + sizeof(uint32_t), outDataSize - sizeof(uint32_t), secureSignInfo,
753         sizeof(struct HksSecureSignAuthInfo));
754 
755     (void)memcpy_s(outData + sizeof(uint32_t) + sizeof(struct HksSecureSignAuthInfo),
756         outDataSize - sizeof(uint32_t) - sizeof(struct HksSecureSignAuthInfo), inData->data, inData->size);
757 
758     struct HksParam *appendDataPrefixParam = NULL;
759     int32_t ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_APPENDED_DATA_PREFIX, &appendDataPrefixParam);
760     if (ret != HKS_SUCCESS) {
761         HKS_LOG_E("get append prefix data failed");
762         HKS_FREE(outData);
763         return HKS_ERROR_BAD_STATE;
764     }
765 
766     if (memcpy_s(appendDataPrefixParam->blob.data, appendDataPrefixParam->blob.size, secureSignInfo,
767         sizeof(struct HksSecureSignAuthInfo)) != EOK) {
768         HKS_LOG_E("get append prefix data failed");
769         HKS_FREE(outData);
770         return HKS_ERROR_INSUFFICIENT_MEMORY;
771     }
772     outDataBlob->data = outData;
773     outDataBlob->size = outDataSize;
774     return HKS_SUCCESS;
775 }
776 
CheckIfNeedAppendFinishData(const struct HksAppendDataInnerParams * innerParams,bool * outIsNeedAppend,int32_t * outAuthResult,uint32_t inOutDataOriginSize)777 static int32_t CheckIfNeedAppendFinishData(const struct HksAppendDataInnerParams *innerParams, bool *outIsNeedAppend,
778     int32_t *outAuthResult, uint32_t inOutDataOriginSize)
779 {
780     bool isNeedAppend = false;
781     int32_t authResult = HKS_AUTH_RESULT_NONE;
782     int32_t ret = GetSupportAppendAuthInfoParams(innerParams->keyNode, &isNeedAppend, &authResult);
783     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get append auth support params failed")
784 
785     *outAuthResult = authResult;
786     if (isNeedAppend == false) {
787         *outIsNeedAppend = false;
788         return HKS_SUCCESS;
789     }
790 
791     if (authResult != HKS_AUTH_RESULT_SUCCESS) {
792         HKS_LOG_E("key auth failed");
793         return HKS_ERROR_KEY_AUTH_FAILED;
794     }
795 
796     struct HksParam *isAlreadyAppendUpdateData = NULL;
797     ret = CheckParamsAndGetAppendState(innerParams->keyNode, &isAlreadyAppendUpdateData);
798     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check is already append update data params failed")
799 
800     if (isAlreadyAppendUpdateData->boolParam == false) {
801         HKS_LOG_E("did not append update data");
802         return HKS_ERROR_BAD_STATE;
803     }
804 
805     if (innerParams->inData == NULL || innerParams->inData->size == 0) {
806         HKS_LOG_E("the in data is invalid");
807         return HKS_ERROR_INVALID_ARGUMENT;
808     }
809 
810     if (inOutDataOriginSize < innerParams->inData->size ||
811         inOutDataOriginSize - innerParams->inData->size < sizeof(struct HksSecureSignAuthInfo)) {
812         HKS_LOG_E("outData origin buffer size is too small to append auth info");
813         return HKS_ERROR_BUFFER_TOO_SMALL;
814     }
815 
816     *outIsNeedAppend = true;
817     return HKS_SUCCESS;
818 }
819 
DoAppendPrefixDataToFinishData(const struct HuksKeyNode * keyNode,struct HksAppendDataInnerParams * innerParams,struct HksBlob * inOutData,uint32_t inOutDataOriginSize)820 static int32_t DoAppendPrefixDataToFinishData(const struct HuksKeyNode *keyNode,
821     struct HksAppendDataInnerParams *innerParams, struct HksBlob *inOutData, uint32_t inOutDataOriginSize)
822 {
823     struct HksParam *appendDataPrefixParam = NULL;
824     int32_t ret = HksGetParam(keyNode->authRuntimeParamSet, HKS_TAG_APPENDED_DATA_PREFIX, &appendDataPrefixParam);
825     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get append prefix data failed")
826 
827     uint32_t cacheOutDataSize = sizeof(uint32_t) + sizeof(struct HksSecureSignAuthInfo) + innerParams->inData->size;
828     uint8_t *cacheOutData = (uint8_t *)HksMalloc(cacheOutDataSize);
829     HKS_IF_NULL_LOGE_RETURN(cacheOutData, HKS_ERROR_MALLOC_FAIL, "malloc cacheOutData failed!")
830 
831     const uint32_t version = SECURE_SIGN_VERSION;
832     (void)memcpy_s(cacheOutData, cacheOutDataSize, &version, sizeof(uint32_t));
833 
834     (void)memcpy_s(cacheOutData + sizeof(uint32_t), cacheOutDataSize - sizeof(uint32_t),
835         appendDataPrefixParam->blob.data, appendDataPrefixParam->blob.size);
836 
837     (void)memcpy_s(cacheOutData + sizeof(uint32_t) + appendDataPrefixParam->blob.size,
838         cacheOutDataSize - appendDataPrefixParam->blob.size - sizeof(uint32_t), innerParams->inData->data,
839         innerParams->inData->size);
840 
841     if (memcpy_s(inOutData->data, inOutDataOriginSize, cacheOutData, cacheOutDataSize) != 0) {
842         HKS_LOG_E("memcpy cacheOutData to inOutData failed!");
843         HKS_FREE(cacheOutData);
844         return HKS_ERROR_INSUFFICIENT_MEMORY;
845     }
846     inOutData->size = cacheOutDataSize;
847     HKS_FREE(cacheOutData);
848     return HKS_SUCCESS;
849 }
850 
HksCoreSecureAccessInitParams(struct HuksKeyNode * keyNode,const struct HksParamSet * initParamSet,struct HksBlob * token)851 int32_t HksCoreSecureAccessInitParams(struct HuksKeyNode *keyNode, const struct HksParamSet *initParamSet,
852     struct HksBlob *token)
853 {
854     if (keyNode == NULL || initParamSet == NULL || token == NULL) {
855         HKS_LOG_E("the pointer param is invalid");
856         return HKS_ERROR_NULL_POINTER;
857     }
858     struct HksSecureAccessInnerParams innerParams;
859     (void)memset_s(&innerParams, sizeof(innerParams), 0, sizeof(innerParams));
860 
861     innerParams.initParamSet = initParamSet;
862     innerParams.outToken = token;
863 
864     int32_t ret = CheckInitParamSetValidityAndGet(keyNode->keyBlobParamSet, &innerParams);
865     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check init params failed")
866 
867     struct HksParamSet *authRuntimeParamSet = NULL;
868     ret = BuildAuthRuntimeParamSet(&innerParams, innerParams.isSecureSign, &authRuntimeParamSet);
869     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "build auth run time params failed")
870 
871     keyNode->authRuntimeParamSet = authRuntimeParamSet;
872     return HKS_SUCCESS;
873 }
874 
GetAuthMode(const struct HksParamSet * paramSet,uint32_t * type)875 static int32_t GetAuthMode(const struct HksParamSet *paramSet, uint32_t *type)
876 {
877     struct HksParam *typeParam = NULL;
878     if (HksGetParam(paramSet, HKS_TAG_USER_AUTH_MODE, &typeParam) == HKS_SUCCESS &&
879         typeParam->uint32Param == HKS_USER_AUTH_MODE_COAUTH) {
880         *type = HKS_USER_AUTH_MODE_COAUTH;
881         return HKS_SUCCESS;
882     }
883 
884     *type = HKS_USER_AUTH_MODE_LOCAL;
885     return HKS_SUCCESS;
886 }
887 
HksCheckAuthType(struct HuksKeyNode * keyNode,const struct HksUserAuthToken * authToken)888 static int32_t HksCheckAuthType(struct HuksKeyNode *keyNode, const struct HksUserAuthToken *authToken)
889 {
890     uint32_t blobAuthMode;
891     int32_t ret = GetAuthMode(keyNode->keyBlobParamSet, &blobAuthMode);
892     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get auth mode failed")
893 
894     enum {
895         // see `enum TokenType` in `drivers/peripheral/user_auth/hdi_service/common/inc/defines.h`
896         TOKEN_TYPE_LOCAL_AUTH = 0,
897         TOKEN_TYPE_LOCAL_RESIGN = 1,
898         TOKEN_TYPE_COAUTH = 2,
899     };
900     switch (authToken->plaintextData.tokenType) {
901         case TOKEN_TYPE_LOCAL_AUTH:
902         case TOKEN_TYPE_LOCAL_RESIGN:
903             break;
904         case TOKEN_TYPE_COAUTH:
905             if (blobAuthMode != HKS_USER_AUTH_MODE_COAUTH) {
906                 HKS_LOG_E("not COAUTH_MODE_AUTH %" LOG_PUBLIC "u", blobAuthMode);
907                 return HKS_ERROR_NOT_SUPPORTED;
908             }
909             break;
910         default:
911             HKS_LOG_E("invalid authMode %" LOG_PUBLIC "u", blobAuthMode);
912             return HKS_ERROR_NOT_SUPPORTED;
913     }
914     return HKS_SUCCESS;
915 }
916 
HksCoreSecureAccessVerifyParams(struct HuksKeyNode * keyNode,const struct HksParamSet * paramSet)917 int32_t HksCoreSecureAccessVerifyParams(struct HuksKeyNode *keyNode, const struct HksParamSet *paramSet)
918 {
919     if (keyNode == NULL || paramSet == NULL) {
920         HKS_LOG_E("the pointer param is invalid");
921         return HKS_ERROR_NULL_POINTER;
922     }
923 
924     struct HksParam *authResult = NULL;
925     bool isNeedSecureAccess = true;
926 
927     int32_t ret = CheckIfNeedVerifyParams(keyNode, &isNeedSecureAccess, &authResult);
928     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "check if need verify params failed!")
929 
930     if (isNeedSecureAccess == false) {
931         return HKS_SUCCESS;
932     }
933 
934     if (authResult->uint32Param == HKS_AUTH_RESULT_FAILED) {
935         HKS_LOG_E("check key auth failed");
936         return HKS_ERROR_KEY_AUTH_FAILED;
937     }
938 
939     struct HksUserAuthToken *authToken = NULL;
940     do {
941         ret = GetAuthToken(paramSet, &authToken);
942         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "get auth token failed! %" LOG_PUBLIC "d", ret)
943 
944         ret = HksVerifyAuthTokenSign(authToken);
945         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "verify the auth token sign failed! %" LOG_PUBLIC "d", ret)
946 
947         ret = HksCheckAuthType(keyNode, authToken);
948         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "HksCheckAuthType failed! %" LOG_PUBLIC "d", ret)
949 
950         ret = HksDecryptAuthToken(authToken);
951         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "decrypt auth token failed! %" LOG_PUBLIC "d", ret)
952 
953         ret = VerifyChallengeOrTimeStamp(keyNode, authToken);
954         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "verify challenge failed! %" LOG_PUBLIC "d", ret)
955 
956         ret = VerifyAuthTokenInfo(keyNode, authToken);
957         HKS_IF_NOT_SUCC_LOGE_BREAK(ret, "verify auth token info failed! %" LOG_PUBLIC "d", ret)
958     } while (0);
959 
960     return AssignVerifyResultAndFree(ret, authResult, keyNode, authToken);
961 }
962 
HksCoreAppendAuthInfoBeforeUpdate(struct HuksKeyNode * keyNode,uint32_t pur,const struct HksParamSet * inParamSet,const struct HksBlob * inData,struct HksBlob * appendedData)963 int32_t HksCoreAppendAuthInfoBeforeUpdate(struct HuksKeyNode *keyNode, uint32_t pur,
964     const struct HksParamSet *inParamSet, const struct HksBlob *inData, struct HksBlob *appendedData)
965 {
966     // current only support append secure sign
967     if (pur != HKS_KEY_PURPOSE_SIGN) {
968         return HKS_SUCCESS;
969     }
970 
971     bool isNeedAppend = false;
972     int32_t authResult = HKS_AUTH_RESULT_NONE;
973     struct HksParam *isAppendedData = NULL;
974     struct HksAppendDataInnerParams innerParams = {
975         .keyNode = keyNode,
976         .inParamSet = inParamSet,
977         .inData = inData
978     };
979 
980     int32_t ret = CheckIfNeedAppendUpdateData(&innerParams, &isNeedAppend, &authResult, appendedData, &isAppendedData);
981     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get if need append update data params failed")
982 
983     if (isNeedAppend == false) {
984         return HKS_SUCCESS;
985     }
986 
987     if (authResult != HKS_AUTH_RESULT_SUCCESS) {
988         HKS_LOG_E("should do user auth success before update");
989         return HKS_ERROR_KEY_AUTH_FAILED;
990     }
991 
992     struct HksSecureSignAuthInfo secureSignInfo;
993     ret = GetSecureSignAuthInfo(keyNode, &secureSignInfo);
994     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get secure sign auth info failed")
995 
996     struct HksBlob outDataBlob = { 0, NULL };
997     ret = DoAppendPrefixAuthInfoToUpdateInData(keyNode, &secureSignInfo, inData, &outDataBlob);
998     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "do append prefix auth info to update in data failed")
999 
1000     isAppendedData->boolParam = true;
1001     *appendedData = outDataBlob;
1002     return HKS_SUCCESS;
1003 }
1004 
HksCoreAppendAuthInfoBeforeFinish(struct HuksKeyNode * keyNode,uint32_t pur,const struct HksParamSet * inParamSet,const struct HksBlob * inData,struct HksBlob * appendedData)1005 int32_t HksCoreAppendAuthInfoBeforeFinish(struct HuksKeyNode *keyNode, uint32_t pur,
1006     const struct HksParamSet *inParamSet, const struct HksBlob *inData, struct HksBlob *appendedData)
1007 {
1008     return HksCoreAppendAuthInfoBeforeUpdate(keyNode, pur, inParamSet, inData, appendedData);
1009 }
1010 
HksCoreAppendAuthInfoAfterFinish(struct HuksKeyNode * keyNode,uint32_t pur,const struct HksParamSet * inParamSet,uint32_t inOutDataOriginSize,struct HksBlob * inOutData)1011 int32_t HksCoreAppendAuthInfoAfterFinish(struct HuksKeyNode *keyNode, uint32_t pur,
1012     const struct HksParamSet *inParamSet, uint32_t inOutDataOriginSize, struct HksBlob *inOutData)
1013 {
1014     if (pur != HKS_KEY_PURPOSE_SIGN) {
1015         return HKS_SUCCESS;
1016     }
1017 
1018     bool isNeedAppend = false;
1019     int32_t authResult = HKS_AUTH_RESULT_NONE;
1020     const struct HksBlob *inDataConst = (const struct HksBlob *)inOutData;
1021     struct HksAppendDataInnerParams innerParams = {
1022         .keyNode = keyNode,
1023         .inParamSet = inParamSet,
1024         .inData = inDataConst
1025     };
1026 
1027     int32_t ret = CheckIfNeedAppendFinishData(&innerParams, &isNeedAppend, &authResult, inOutDataOriginSize);
1028     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get if need append finish data params failed")
1029 
1030     if (isNeedAppend == false) {
1031         return HKS_SUCCESS;
1032     }
1033 
1034     return DoAppendPrefixDataToFinishData(keyNode, &innerParams, inOutData, inOutDataOriginSize);
1035 }
1036 
HksCheckKeybBlobIsSupportUserAuth(const struct HksParamSet * blobParamSet,bool * isSupport)1037 int32_t HksCheckKeybBlobIsSupportUserAuth(const struct HksParamSet *blobParamSet, bool *isSupport)
1038 {
1039     struct HksParam *blobUserAuthType = NULL;
1040     int32_t ret = HksGetParam(blobParamSet, HKS_TAG_USER_AUTH_TYPE, &blobUserAuthType);
1041     if (ret == HKS_ERROR_PARAM_NOT_EXIST) {
1042         *isSupport = false;
1043         return HKS_SUCCESS;
1044     }
1045     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get blob user auth type failed!")
1046     *isSupport = true;
1047     return HKS_SUCCESS;
1048 }
1049 #else
HksCoreSecureAccessInitParams(struct HuksKeyNode * keyNode,const struct HksParamSet * initParamSet,struct HksBlob * token)1050 int32_t HksCoreSecureAccessInitParams(struct HuksKeyNode *keyNode, const struct HksParamSet *initParamSet,
1051     struct HksBlob *token)
1052 {
1053     (void)keyNode;
1054     (void)initParamSet;
1055     (void)token;
1056     return HKS_SUCCESS;
1057 }
1058 
HksCoreSecureAccessVerifyParams(struct HuksKeyNode * keyNode,const struct HksParamSet * inParamSet)1059 int32_t HksCoreSecureAccessVerifyParams(struct HuksKeyNode *keyNode, const struct HksParamSet *inParamSet)
1060 {
1061     (void)keyNode;
1062     (void)inParamSet;
1063     return HKS_SUCCESS;
1064 }
1065 
HksCoreAppendAuthInfoBeforeUpdate(struct HuksKeyNode * keyNode,uint32_t pur,const struct HksParamSet * inParamSet,const struct HksBlob * inData,struct HksBlob * appendedData)1066 int32_t HksCoreAppendAuthInfoBeforeUpdate(struct HuksKeyNode *keyNode, uint32_t pur,
1067     const struct HksParamSet *inParamSet, const struct HksBlob *inData, struct HksBlob *appendedData)
1068 {
1069     (void)keyNode;
1070     (void)pur;
1071     (void)inParamSet;
1072     (void)inData;
1073     (void)appendedData;
1074     return HKS_SUCCESS;
1075 }
1076 
HksCoreAppendAuthInfoBeforeFinish(struct HuksKeyNode * keyNode,uint32_t pur,const struct HksParamSet * inParamSet,const struct HksBlob * inData,struct HksBlob * appendedData)1077 int32_t HksCoreAppendAuthInfoBeforeFinish(struct HuksKeyNode *keyNode, uint32_t pur,
1078     const struct HksParamSet *inParamSet, const struct HksBlob *inData, struct HksBlob *appendedData)
1079 {
1080     (void)keyNode;
1081     (void)pur;
1082     (void)inParamSet;
1083     (void)inData;
1084     (void)appendedData;
1085     return HKS_SUCCESS;
1086 }
1087 
HksCoreAppendAuthInfoAfterFinish(struct HuksKeyNode * keyNode,uint32_t pur,const struct HksParamSet * inParamSet,uint32_t inOutDataBufferSize,struct HksBlob * inOutData)1088 int32_t HksCoreAppendAuthInfoAfterFinish(struct HuksKeyNode *keyNode, uint32_t pur,
1089     const struct HksParamSet *inParamSet, uint32_t inOutDataBufferSize, struct HksBlob *inOutData)
1090 {
1091     (void)keyNode;
1092     (void)pur;
1093     (void)inParamSet;
1094     (void)inOutDataBufferSize;
1095     (void)inOutData;
1096     return HKS_SUCCESS;
1097 }
1098 
HksCheckKeybBlobIsSupportUserAuth(const struct HksParamSet * blobParamSet,bool * isSupport)1099 int32_t HksCheckKeybBlobIsSupportUserAuth(const struct HksParamSet *blobParamSet, bool *isSupport)
1100 {
1101     (void)blobParamSet;
1102     *isSupport = false;
1103     return HKS_SUCCESS;
1104 }
1105 #endif
1106 
1107 #ifndef _STORAGE_LITE_
1108 #ifdef HKS_SUPPORT_ACCESS_TOKEN
HksCheckCompareAccessTokenId(const struct HksParamSet * blobParamSet,const struct HksParamSet * runtimeParamSet)1109 static int32_t HksCheckCompareAccessTokenId(const struct HksParamSet *blobParamSet,
1110     const struct HksParamSet *runtimeParamSet)
1111 {
1112     struct HksParam *blobAccessTokenId = NULL;
1113     int32_t ret = HksGetParam(blobParamSet, HKS_TAG_ACCESS_TOKEN_ID, &blobAccessTokenId);
1114     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_SUCCESS, "no access token id in keyblob")
1115 
1116     struct HksParam *runtimeAccessTokenId = NULL;
1117     ret = HksGetParam(runtimeParamSet, HKS_TAG_ACCESS_TOKEN_ID, &runtimeAccessTokenId);
1118     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get access token id form runtime paramSet failed")
1119 
1120     return (blobAccessTokenId->uint64Param == runtimeAccessTokenId->uint64Param) ? HKS_SUCCESS : HKS_ERROR_BAD_STATE;
1121 }
1122 
1123 #else
HksCheckCompareAccessTokenId(const struct HksParamSet * blobParamSet,const struct HksParamSet * runtimeParamSet)1124 static int32_t HksCheckCompareAccessTokenId(const struct HksParamSet *blobParamSet,
1125     const struct HksParamSet *runtimeParamSet)
1126 {
1127     (void)blobParamSet;
1128     (void)runtimeParamSet;
1129     return HKS_SUCCESS;
1130 }
1131 #endif
1132 
HksCheckCompareUserId(const struct HksParamSet * blobParamSet,const struct HksParamSet * runtimeParamSet)1133 static int32_t HksCheckCompareUserId(const struct HksParamSet *blobParamSet,
1134     const struct HksParamSet *runtimeParamSet)
1135 {
1136     struct HksParam *blobUserId = NULL;
1137     int32_t ret = HksGetParam(blobParamSet, HKS_TAG_USER_ID, &blobUserId);
1138     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_SUCCESS, "no user id in keyblob")
1139 
1140     struct HksParam *runtimeUserId = NULL;
1141     ret = HksGetParam(runtimeParamSet, HKS_TAG_USER_ID, &runtimeUserId);
1142     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get user id from runtime paramSet failed")
1143 
1144     return (blobUserId->uint32Param == runtimeUserId->uint32Param) ? HKS_SUCCESS : HKS_ERROR_BAD_STATE;
1145 }
1146 
HksCheckCompareProcessName(const struct HksParamSet * blobParamSet,const struct HksParamSet * runtimeParamSet)1147 static int32_t HksCheckCompareProcessName(const struct HksParamSet *blobParamSet,
1148     const struct HksParamSet *runtimeParamSet)
1149 {
1150     struct HksParam *blobProcessName = NULL;
1151     int32_t ret = HksGetParam(blobParamSet, HKS_TAG_PROCESS_NAME, &blobProcessName);
1152     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "no process name in keyblob")
1153 
1154     struct HksParam *runtimeProcessName = NULL;
1155     ret = HksGetParam(runtimeParamSet, HKS_TAG_PROCESS_NAME, &runtimeProcessName);
1156     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_BAD_STATE, "get process name form runtime paramSet failed")
1157 
1158     if (blobProcessName->blob.size == runtimeProcessName->blob.size &&
1159         HksMemCmp(blobProcessName->blob.data, runtimeProcessName->blob.data,
1160             blobProcessName->blob.size) == HKS_SUCCESS) {
1161         return HKS_SUCCESS;
1162     }
1163     return HKS_ERROR_BAD_STATE;
1164 }
1165 #endif /** _STORAGE_LITE_ */
1166 
CheckIfNeedIsDevicePasswordSet(const struct HksParamSet * paramSet)1167 int32_t CheckIfNeedIsDevicePasswordSet(const struct HksParamSet *paramSet) // callback
1168 {
1169 #ifdef HKS_ENABLE_IS_PASSWORD_SET
1170     struct HksParam *isSetPassword = NULL;
1171     if (HksGetParam(paramSet, HKS_TAG_IS_DEVICE_PASSWORD_SET, &isSetPassword) != HKS_SUCCESS ||
1172         !isSetPassword->boolParam) {
1173         return HKS_SUCCESS;
1174     }
1175     struct HksParam *userId = NULL;
1176     int32_t ret = HksGetParam(paramSet, HKS_TAG_SPECIFIC_USER_ID, &userId);
1177     if (ret != HKS_SUCCESS) {
1178         if (ret != HKS_ERROR_PARAM_NOT_EXIST || HksGetParam(paramSet, HKS_TAG_USER_ID, &userId) != HKS_SUCCESS) {
1179             HKS_LOG_E("get user id from paramset failed!");
1180             return HKS_ERROR_INVALID_ARGUMENT;
1181         }
1182     }
1183     uint32_t numOfAuthInfo = 0;
1184     ret = HksUserIdmGetAuthInfoNum(userId->int32Param, HKS_USER_AUTH_TYPE_PIN, &numOfAuthInfo); // callback
1185     if (ret == HKS_ERROR_CREDENTIAL_NOT_EXIST || numOfAuthInfo == 0) {
1186         HKS_LOG_E("have not enrolled the pin.");
1187         return HKS_ERROR_DEVICE_PASSWORD_UNSET;
1188     }
1189 #else
1190     (void)paramSet;
1191 #endif
1192     return HKS_SUCCESS;
1193 }
1194 
HksProcessIdentityVerify(const struct HksParamSet * blobParamSet,const struct HksParamSet * runtimeParamSet)1195 int32_t HksProcessIdentityVerify(const struct HksParamSet *blobParamSet, const struct HksParamSet *runtimeParamSet)
1196 {
1197     int32_t ret = HKS_SUCCESS;
1198 
1199 #ifndef _STORAGE_LITE_
1200     ret = HksCheckCompareAccessTokenId(blobParamSet, runtimeParamSet);
1201     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "access token compare failed")
1202 
1203     ret = HksCheckCompareUserId(blobParamSet, runtimeParamSet);
1204     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "user id compare failed")
1205 
1206     ret = HksCheckCompareProcessName(blobParamSet, runtimeParamSet);
1207     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "process name compare failed")
1208 
1209     ret = CheckIfNeedIsDevicePasswordSet(blobParamSet);
1210     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "need password but not set yet!")
1211 #else
1212     (void)blobParamSet;
1213     (void)runtimeParamSet;
1214 #endif
1215 
1216     return ret;
1217 }
1218