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(¶mSet);
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(¶mSet);
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(¶mSet);
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