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