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