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