1 /*
2 * Copyright (c) 2021-2022 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 #include "hks_auth.h"
17
18 #include <stddef.h>
19
20 #include "hks_base_check.h"
21 #include "hks_log.h"
22 #include "hks_param.h"
23 #include "hks_template.h"
24 #include "hks_secure_access.h"
25
26 struct HksAuthPolicy {
27 uint32_t authId;
28 uint32_t policyCnt;
29 uint32_t *policyTag;
30 };
31
32 #ifndef _CUT_AUTHENTICATE_
33 static uint32_t g_symCipherPolicyTag[] = { HKS_TAG_ALGORITHM, HKS_TAG_BLOCK_MODE, HKS_TAG_PADDING, HKS_TAG_PURPOSE };
34 static uint32_t g_asymCipherPolicyTag[] = { HKS_TAG_ALGORITHM, HKS_TAG_DIGEST, HKS_TAG_PADDING, HKS_TAG_PURPOSE };
35 static uint32_t g_signVerifyRsaPolicyTag[] = { HKS_TAG_ALGORITHM, HKS_TAG_DIGEST, HKS_TAG_PADDING, HKS_TAG_PURPOSE };
36 static uint32_t g_signVerifyEccPolicyTag[] = { HKS_TAG_ALGORITHM, HKS_TAG_DIGEST, HKS_TAG_PURPOSE };
37 static uint32_t g_signVerifyEd25519PolicyTag[] = { HKS_TAG_PURPOSE };
38 static uint32_t g_macPolicyTag[] = { HKS_TAG_DIGEST, HKS_TAG_PURPOSE };
39 static uint32_t g_macSm3PolicyTag[] = { HKS_TAG_ALGORITHM, HKS_TAG_DIGEST, HKS_TAG_PURPOSE };
40 static uint32_t g_derivePolicyTag[] = { HKS_TAG_DIGEST, HKS_TAG_PURPOSE };
41 static uint32_t g_agreePolicyTag[] = { HKS_TAG_PURPOSE };
42
43 struct HksAuthPolicy g_authPolicyList[] = {
44 { HKS_AUTH_ID_SYM_CIPHER, HKS_ARRAY_SIZE(g_symCipherPolicyTag), g_symCipherPolicyTag },
45 { HKS_AUTH_ID_ASYM_CIPHER, HKS_ARRAY_SIZE(g_asymCipherPolicyTag), g_asymCipherPolicyTag },
46 { HKS_AUTH_ID_SIGN_VERIFY_RSA, HKS_ARRAY_SIZE(g_signVerifyRsaPolicyTag), g_signVerifyRsaPolicyTag },
47 { HKS_AUTH_ID_SIGN_VERIFY_ECC, HKS_ARRAY_SIZE(g_signVerifyEccPolicyTag), g_signVerifyEccPolicyTag },
48 { HKS_AUTH_ID_SIGN_VERIFY_ED25519, HKS_ARRAY_SIZE(g_signVerifyEd25519PolicyTag), g_signVerifyEd25519PolicyTag },
49 { HKS_AUTH_ID_MAC_HMAC, HKS_ARRAY_SIZE(g_macPolicyTag), g_macPolicyTag },
50 { HKS_AUTH_ID_MAC_SM3, HKS_ARRAY_SIZE(g_macSm3PolicyTag), g_macSm3PolicyTag },
51 { HKS_AUTH_ID_DERIVE, HKS_ARRAY_SIZE(g_derivePolicyTag), g_derivePolicyTag },
52 { HKS_AUTH_ID_AGREE, HKS_ARRAY_SIZE(g_agreePolicyTag), g_agreePolicyTag }
53 };
54
CheckPurpose(const struct HksParam * authParam,const struct HksParam * requestParam)55 static int32_t CheckPurpose(const struct HksParam *authParam, const struct HksParam *requestParam)
56 {
57 if (requestParam->uint32Param == 0) {
58 return HKS_ERROR_INVALID_ARGUMENT;
59 }
60 if ((requestParam->uint32Param & authParam->uint32Param) != requestParam->uint32Param) {
61 return HKS_ERROR_INVALID_ARGUMENT;
62 }
63 return HKS_SUCCESS;
64 }
65
OptionalParamCheck(uint32_t authTag,uint32_t alg,uint32_t purpose,const struct HksParamSet * paramSet,const struct ParamsValues * paramValues)66 static int32_t OptionalParamCheck(uint32_t authTag, uint32_t alg, uint32_t purpose, const struct HksParamSet *paramSet,
67 const struct ParamsValues* paramValues)
68 {
69 HKS_LOG_I("tag is 0x%" LOG_PUBLIC "x", authTag);
70 struct HksParam *param = NULL;
71 bool isAbsent = false;
72 int32_t ret = HksGetParam(paramSet, authTag, ¶m);
73 if (ret == HKS_ERROR_INVALID_ARGUMENT) {
74 HKS_LOG_E("get auth param 0x%" LOG_PUBLIC "x failed!", authTag);
75 return ret;
76 }
77 if (ret == HKS_ERROR_PARAM_NOT_EXIST) {
78 HKS_LOG_D("when generates key, the tag is absent. tag is 0x%" LOG_PUBLIC "x", authTag);
79 isAbsent = true;
80 }
81
82 ret = HksCheckOptionalParam(authTag, alg, purpose, isAbsent, param);
83 if (ret != HKS_SUCCESS) {
84 HKS_LOG_E("check optional param fail");
85 return ret;
86 }
87 if (((purpose & HKS_KEY_PURPOSE_DERIVE) != 0) || ((purpose & HKS_KEY_PURPOSE_MAC) != 0)) {
88 HKS_LOG_E("derive or mac no need to check");
89 return HKS_SUCCESS;
90 }
91 // Parameter check is more strict than above
92 return HksCheckGenKeyMutableParams(alg, paramValues);
93 }
94
GetAlgAndPurposeParam(const struct HksParamSet * keyBlobParamSet,const struct HksParamSet * paramSet,struct HksParam ** algParam,struct HksParam ** purposeParam,struct ParamsValues * paramValues)95 static int32_t GetAlgAndPurposeParam(const struct HksParamSet *keyBlobParamSet, const struct HksParamSet *paramSet,
96 struct HksParam **algParam, struct HksParam **purposeParam, struct ParamsValues* paramValues)
97 {
98 int32_t ret = HksGetParam(keyBlobParamSet, HKS_TAG_ALGORITHM, algParam);
99 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL,
100 "get param 0x%" LOG_PUBLIC "x failed!", HKS_TAG_ALGORITHM);
101 ret = HksGetParam(keyBlobParamSet, HKS_TAG_PURPOSE, purposeParam);
102 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_PURPOSE_FAIL,
103 "get param 0x%" LOG_PUBLIC "x failed!", HKS_TAG_PURPOSE);
104 return GetInputParams(paramSet, paramValues);
105 }
106
AuthPolicy(const struct HksAuthPolicy * policy,const struct HksParamSet * keyBlobParamSet,const struct HksParamSet * paramSet)107 static int32_t AuthPolicy(const struct HksAuthPolicy *policy, const struct HksParamSet *keyBlobParamSet,
108 const struct HksParamSet *paramSet)
109 {
110 uint32_t authTag;
111 struct HksParam *authParam = NULL;
112 struct HksParam *requestParam = NULL;
113 struct HksParam *algParam = NULL;
114 struct HksParam *purposeParam = NULL;
115 struct ParamsValues paramValues = { { false, 0, false }, { true, 0, false }, { true, 0, false },
116 { true, 0, false }, { true, 0, false } };
117 int32_t ret = GetAlgAndPurposeParam(keyBlobParamSet, paramSet, &algParam, &purposeParam, ¶mValues);
118 if (ret != HKS_SUCCESS) {
119 HKS_LOG_E("GetAlgAndPurposeParam failed");
120 return ret;
121 }
122 for (uint32_t i = 0; i < policy->policyCnt; i++) {
123 authTag = policy->policyTag[i];
124 ret = HksGetParam(keyBlobParamSet, authTag, &authParam);
125 if (ret == HKS_ERROR_INVALID_ARGUMENT) {
126 HKS_LOG_E("get auth param 0x%" LOG_PUBLIC "x failed!", authTag);
127 return ret;
128 }
129 if (ret == HKS_ERROR_PARAM_NOT_EXIST) {
130 ret = OptionalParamCheck(authTag, algParam->uint32Param, purposeParam->uint32Param, paramSet, ¶mValues);
131 if (ret != HKS_SUCCESS) {
132 return ret;
133 }
134 continue;
135 }
136 ret = HksGetParam(paramSet, authTag, &requestParam);
137 if (ret != HKS_SUCCESS) {
138 HKS_LOG_E("get request param 0x%" LOG_PUBLIC "x failed!", authTag);
139 return ret;
140 }
141 if (authTag != HKS_TAG_PURPOSE) {
142 ret = HksCheckParamMatch((const struct HksParam *)authParam, (const struct HksParam *)requestParam);
143 } else {
144 ret = CheckPurpose((const struct HksParam *)authParam, (const struct HksParam *)requestParam);
145 }
146 if (ret != HKS_SUCCESS) {
147 HKS_LOG_E("unmatch policy 0x%" LOG_PUBLIC "x , 0x%" LOG_PUBLIC "x != 0x%" LOG_PUBLIC "x!", authTag,
148 requestParam->uint32Param, authParam->uint32Param);
149 return ret;
150 }
151 }
152 return HKS_SUCCESS;
153 }
154
HksAuth(uint32_t authId,const struct HksKeyNode * keyNode,const struct HksParamSet * paramSet)155 int32_t HksAuth(uint32_t authId, const struct HksKeyNode *keyNode, const struct HksParamSet *paramSet)
156 {
157 bool isSupportUserAuth = false;
158 int32_t ret = HksCheckKeybBlobIsSupportUserAuth(keyNode->paramSet, &isSupportUserAuth);
159 if (ret != HKS_SUCCESS) {
160 HKS_LOG_E("HksCheckKeybBlobIsSupportUserAuth failed");
161 return ret;
162 }
163
164 if (isSupportUserAuth) {
165 HKS_LOG_E("key should do user auth, but one stage api do not support user auth operation");
166 return HKS_ERROR_NOT_SUPPORTED;
167 }
168
169 for (uint32_t i = 0; i < HKS_ARRAY_SIZE(g_authPolicyList); i++) {
170 if (authId == g_authPolicyList[i].authId) {
171 return AuthPolicy(&g_authPolicyList[i], keyNode->paramSet, paramSet);
172 }
173 }
174 return HKS_ERROR_BAD_STATE;
175 }
176
HksThreeStageAuth(uint32_t authId,const struct HuksKeyNode * keyNode)177 int32_t HksThreeStageAuth(uint32_t authId, const struct HuksKeyNode *keyNode)
178 {
179 for (uint32_t i = 0; i < HKS_ARRAY_SIZE(g_authPolicyList); i++) {
180 if (authId == g_authPolicyList[i].authId) {
181 return AuthPolicy(&g_authPolicyList[i], keyNode->keyBlobParamSet, keyNode->runtimeParamSet);
182 }
183 }
184 return HKS_ERROR_BAD_STATE;
185 }
186 #endif /* _CUT_AUTHENTICATE_ */
187