1 /*
2 * Copyright (c) 2021-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 #define HUKS_DISABLE_LOG_AT_FILE_TO_REDUCE_ROM_SIZE
16
17 #include "hks_common_check.h"
18
19 #include <stddef.h>
20
21 #include "hks_log.h"
22 #include "hks_param.h"
23 #include "hks_template.h"
24 #include "securec.h"
25
HksCheckBlob4(const struct HksBlob * data1,const struct HksBlob * data2,const struct HksBlob * data3,const struct HksBlob * data4)26 int32_t HksCheckBlob4(const struct HksBlob *data1, const struct HksBlob *data2,
27 const struct HksBlob *data3, const struct HksBlob *data4)
28 {
29 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(data1), HKS_ERROR_INVALID_ARGUMENT, "invalid data1.")
30
31 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(data2), HKS_ERROR_INVALID_ARGUMENT, "invalid data2.")
32
33 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(data3), HKS_ERROR_INVALID_ARGUMENT, "invalid data3.")
34
35 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(data4), HKS_ERROR_INVALID_ARGUMENT, "invalid data4.")
36
37 return HKS_SUCCESS;
38 }
39
HksCheckBlob3(const struct HksBlob * data1,const struct HksBlob * data2,const struct HksBlob * data3)40 int32_t HksCheckBlob3(const struct HksBlob *data1, const struct HksBlob *data2, const struct HksBlob *data3)
41 {
42 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(data1), HKS_ERROR_INVALID_ARGUMENT, "invalid data1.")
43
44 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(data2), HKS_ERROR_INVALID_ARGUMENT, "invalid data2.")
45
46 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(data3), HKS_ERROR_INVALID_ARGUMENT, "invalid data3.")
47
48 return HKS_SUCCESS;
49 }
50
HksCheckBlob2(const struct HksBlob * data1,const struct HksBlob * data2)51 int32_t HksCheckBlob2(const struct HksBlob *data1, const struct HksBlob *data2)
52 {
53 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(data1), HKS_ERROR_INVALID_ARGUMENT, "invalid data1.")
54
55 HKS_IF_NOT_SUCC_LOGE_RETURN(CheckBlob(data2), HKS_ERROR_INVALID_ARGUMENT, "invalid data2.")
56
57 return HKS_SUCCESS;
58 }
59
HksCheckParamSetValidity(const struct HksParamSet * paramSet)60 int32_t HksCheckParamSetValidity(const struct HksParamSet *paramSet)
61 {
62 HKS_IF_NULL_LOGE_RETURN(paramSet, HKS_ERROR_NULL_POINTER, "paramSet NULL!")
63 HKS_IF_NOT_SUCC_LOGE_RETURN(HksCheckParamSet(paramSet, paramSet->paramSetSize),
64 HKS_ERROR_INVALID_ARGUMENT, "paramSet invalid!")
65
66 return HksCheckParamSetTag(paramSet);
67 }
68
HksCheckBlob4AndParamSet(const struct HksBlob * data1,const struct HksBlob * data2,const struct HksBlob * data3,const struct HksBlob * data4,const struct HksParamSet * paramSet)69 int32_t HksCheckBlob4AndParamSet(const struct HksBlob *data1, const struct HksBlob *data2,
70 const struct HksBlob *data3, const struct HksBlob *data4, const struct HksParamSet *paramSet)
71 {
72 int32_t ret = HksCheckBlob4(data1, data2, data3, data4);
73 HKS_IF_NOT_SUCC_RETURN(ret, ret)
74
75 return HksCheckParamSetValidity(paramSet);
76 }
77
HksCheckBlob3AndParamSet(const struct HksBlob * data1,const struct HksBlob * data2,const struct HksBlob * data3,const struct HksParamSet * paramSet)78 int32_t HksCheckBlob3AndParamSet(const struct HksBlob *data1, const struct HksBlob *data2,
79 const struct HksBlob *data3, const struct HksParamSet *paramSet)
80 {
81 int32_t ret = HksCheckBlob3(data1, data2, data3);
82 HKS_IF_NOT_SUCC_RETURN(ret, ret)
83
84 return HksCheckParamSetValidity(paramSet);
85 }
86
HksCheckBlob2AndParamSet(const struct HksBlob * data1,const struct HksBlob * data2,const struct HksParamSet * paramSet)87 int32_t HksCheckBlob2AndParamSet(const struct HksBlob *data1, const struct HksBlob *data2,
88 const struct HksParamSet *paramSet)
89 {
90 int32_t ret = HksCheckBlob2(data1, data2);
91 HKS_IF_NOT_SUCC_RETURN(ret, ret)
92
93 return HksCheckParamSetValidity(paramSet);
94 }
95
HksCheckBlobAndParamSet(const struct HksBlob * data,const struct HksParamSet * paramSet)96 int32_t HksCheckBlobAndParamSet(const struct HksBlob *data, const struct HksParamSet *paramSet)
97 {
98 HKS_IF_NOT_SUCC_RETURN(CheckBlob(data), HKS_ERROR_INVALID_ARGUMENT)
99
100 return HksCheckParamSetValidity(paramSet);
101 }
102
HksCheckBlobAndParamSet2(const struct HksBlob * data,const struct HksParamSet * paramSet1,const struct HksParamSet * paramSet2)103 int32_t HksCheckBlobAndParamSet2(const struct HksBlob *data, const struct HksParamSet *paramSet1,
104 const struct HksParamSet *paramSet2)
105 {
106 int32_t ret = CheckBlob(data);
107 HKS_IF_NOT_SUCC_RETURN(ret, ret)
108
109 ret = HksCheckParamSetValidity(paramSet1);
110 HKS_IF_NOT_SUCC_RETURN(ret, ret)
111
112 ret = HksCheckParamSetValidity(paramSet2);
113 HKS_IF_NOT_SUCC_RETURN(ret, ret)
114
115 return HKS_SUCCESS;
116 }
117
HksCheckBlob2AndParamSet2(const struct HksBlob * data1,const struct HksBlob * data2,const struct HksParamSet * paramSet1,const struct HksParamSet * paramSet2)118 int32_t HksCheckBlob2AndParamSet2(const struct HksBlob *data1, const struct HksBlob *data2,
119 const struct HksParamSet *paramSet1, const struct HksParamSet *paramSet2)
120 {
121 int32_t ret = CheckBlob(data1);
122 HKS_IF_NOT_SUCC_RETURN(ret, ret)
123
124 ret = CheckBlob(data2);
125 HKS_IF_NOT_SUCC_RETURN(ret, ret)
126
127 ret = HksCheckParamSetValidity(paramSet1);
128 HKS_IF_NOT_SUCC_RETURN(ret, ret)
129
130 ret = HksCheckParamSetValidity(paramSet2);
131 HKS_IF_NOT_SUCC_RETURN(ret, ret)
132 return HKS_SUCCESS;
133 }
134
HksGetDigestLen(uint32_t digest,uint32_t * digestLen)135 int32_t HksGetDigestLen(uint32_t digest, uint32_t *digestLen)
136 {
137 switch (digest) {
138 case HKS_DIGEST_MD5:
139 *digestLen = HKS_DIGEST_MD5_LEN;
140 break;
141 case HKS_DIGEST_SHA1:
142 *digestLen = HKS_DIGEST_SHA1_LEN;
143 break;
144 case HKS_DIGEST_SHA224:
145 *digestLen = HKS_DIGEST_SHA224_LEN;
146 break;
147 case HKS_DIGEST_SHA256:
148 *digestLen = HKS_DIGEST_SHA256_LEN;
149 break;
150 case HKS_DIGEST_SHA384:
151 *digestLen = HKS_DIGEST_SHA384_LEN;
152 break;
153 case HKS_DIGEST_SHA512:
154 *digestLen = HKS_DIGEST_SHA512_LEN;
155 break;
156 case HKS_DIGEST_SM3:
157 *digestLen = HKS_DIGEST_SM3_LEN;
158 break;
159 default:
160 return HKS_ERROR_INVALID_DIGEST;
161 }
162 return HKS_SUCCESS;
163 }
164
HksCheckAesAeMode(const struct HksParamSet * paramSet,bool * isAes,bool * isAeMode)165 int32_t HksCheckAesAeMode(const struct HksParamSet *paramSet, bool *isAes, bool *isAeMode)
166 {
167 struct HksParam *algParam = NULL;
168 int32_t ret = HksGetParam(paramSet, HKS_TAG_ALGORITHM, &algParam);
169 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL, "append cipher get alg param failed!")
170 *isAes = (algParam->uint32Param == HKS_ALG_AES);
171 if (!(*isAes)) {
172 return HKS_SUCCESS;
173 }
174
175 struct HksParam *modeParam = NULL;
176 ret = HksGetParam(paramSet, HKS_TAG_BLOCK_MODE, &modeParam);
177 HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_MODE_FAIL, "append cipher get mode param failed!")
178
179 *isAeMode = (modeParam->uint32Param == HKS_MODE_CCM) || (modeParam->uint32Param == HKS_MODE_GCM);
180 return HKS_SUCCESS;
181 }
182
HksCheckWrappedDataFormatValidity(const struct HksBlob * wrappedData,uint32_t validTotalBlobs,const uint32_t * validBlobLengths)183 int32_t HksCheckWrappedDataFormatValidity(const struct HksBlob *wrappedData, uint32_t validTotalBlobs,
184 const uint32_t *validBlobLengths)
185 {
186 if ((CheckBlob(wrappedData) != HKS_SUCCESS) || (wrappedData->size > HKS_WRAPPED_FORMAT_MAX_SIZE) ||
187 (validTotalBlobs == 0)) {
188 HKS_LOG_E("wrapped data format:invalid argument!");
189 return HKS_ERROR_INVALID_ARGUMENT;
190 }
191 const uint8_t *data = wrappedData->data;
192 uint32_t dataSize = wrappedData->size;
193
194 uint32_t offset = 0;
195 uint32_t partDataLength = 0;
196 uint32_t blobIndex = 0;
197
198 for (blobIndex = 0; blobIndex < validTotalBlobs && offset < dataSize; blobIndex++) {
199 if (((dataSize - offset) < sizeof(uint32_t))) {
200 HKS_LOG_E("the residual data length is to small.");
201 return HKS_ERROR_INVALID_WRAPPED_FORMAT;
202 }
203 partDataLength = 0;
204 (void)memcpy_s((uint8_t *)&partDataLength, sizeof(uint32_t), data + offset, sizeof(uint32_t));
205 offset += sizeof(uint32_t);
206
207 if ((partDataLength == 0) || (partDataLength > dataSize - offset)) {
208 HKS_LOG_E(" the blob part:%" LOG_PUBLIC "u length is out of range!", blobIndex);
209 return HKS_ERROR_INVALID_WRAPPED_FORMAT;
210 }
211 offset += partDataLength;
212
213 HKS_IF_TRUE_LOGE_RETURN((validBlobLengths != NULL) && (*(validBlobLengths + blobIndex) != partDataLength),
214 HKS_ERROR_INVALID_WRAPPED_FORMAT,
215 "the blob part:%" LOG_PUBLIC "u length is invalid, should be %" LOG_PUBLIC "u!",
216 blobIndex, *(validBlobLengths + blobIndex));
217 }
218
219 if (offset != dataSize) {
220 HKS_LOG_E("data is redundant!");
221 return HKS_ERROR_INVALID_WRAPPED_FORMAT;
222 }
223 return HKS_SUCCESS;
224 }
225
HksGetBlobFromWrappedData(const struct HksBlob * wrappedData,uint32_t blobIndex,uint32_t totalBlobs,struct HksBlob * blob)226 int32_t HksGetBlobFromWrappedData(const struct HksBlob *wrappedData, uint32_t blobIndex, uint32_t totalBlobs,
227 struct HksBlob *blob)
228 {
229 if ((CheckBlob(wrappedData) != HKS_SUCCESS) || (blobIndex >= totalBlobs) || (blob == NULL)) {
230 HKS_LOG_E("invalid argument!");
231 return HKS_ERROR_INVALID_ARGUMENT;
232 }
233
234 const uint8_t *data = wrappedData->data;
235 uint32_t dataSize = wrappedData->size;
236 uint32_t partDataLength = 0;
237
238 for (uint32_t index = 0, offset = 0; index < totalBlobs && offset < dataSize; index++) {
239 partDataLength = 0;
240 (void)memcpy_s((uint8_t *)&partDataLength, sizeof(uint32_t), data + offset, sizeof(uint32_t));
241 offset += sizeof(uint32_t);
242
243 if ((partDataLength == 0) || (partDataLength > HKS_WRAPPED_FORMAT_MAX_SIZE) ||
244 (partDataLength > dataSize - offset)) {
245 return HKS_ERROR_INVALID_WRAPPED_FORMAT;
246 }
247
248 if (blobIndex == index) {
249 blob->size = partDataLength;
250 blob->data = (uint8_t *)(data + offset);
251 return HKS_SUCCESS;
252 }
253 offset += partDataLength;
254 }
255 return HKS_ERROR_INVALID_WRAPPED_FORMAT;
256 }
257
HksCheckKeyNeedStored(const struct HksParamSet * paramSet,bool * isNeedStorage)258 int32_t HksCheckKeyNeedStored(const struct HksParamSet *paramSet, bool *isNeedStorage)
259 {
260 struct HksParam *storageFlag = NULL;
261 int32_t ret = HksGetParam(paramSet, HKS_TAG_KEY_STORAGE_FLAG, &storageFlag);
262 if ((ret == HKS_SUCCESS) && (storageFlag->uint32Param == HKS_STORAGE_PERSISTENT)) {
263 *isNeedStorage = true;
264 return ret;
265 }
266 ret = HksGetParam(paramSet, HKS_TAG_DERIVE_AGREE_KEY_STORAGE_FLAG, &storageFlag);
267 if ((ret == HKS_SUCCESS) && (storageFlag->uint32Param == HKS_STORAGE_ONLY_USED_IN_HUKS)) {
268 *isNeedStorage = true;
269 return ret;
270 }
271 return ret;
272 }
273
HksCheckKeyBlobParamSetEqualRuntimeParamSet(const struct HksParamSet * keyBlobParamSet,const struct HksParamSet * runtimeParamSet,uint32_t tag)274 int32_t HksCheckKeyBlobParamSetEqualRuntimeParamSet(const struct HksParamSet *keyBlobParamSet,
275 const struct HksParamSet *runtimeParamSet, uint32_t tag)
276 {
277 if (keyBlobParamSet == NULL || runtimeParamSet == NULL) {
278 HKS_LOG_E("invalid params!");
279 return HKS_ERROR_INVALID_ARGUMENT;
280 }
281 bool isExistInParamsetOne = true;
282 struct HksParam *paramInParamsetOne = NULL;
283 int32_t ret = HksGetParam(keyBlobParamSet, tag, ¶mInParamsetOne);
284 if (ret != HKS_SUCCESS) {
285 isExistInParamsetOne = false;
286 }
287 bool isExistInParamsetTwo = true;
288 struct HksParam *paramInParamsetTwo = NULL;
289 ret = HksGetParam(runtimeParamSet, tag, ¶mInParamsetTwo);
290 if (ret != HKS_SUCCESS) {
291 isExistInParamsetTwo = false;
292 }
293
294 HKS_IF_TRUE_LOGE_RETURN(isExistInParamsetOne && (!isExistInParamsetTwo),
295 HKS_ERROR_BAD_STATE, "please set param in paramsetTwo");
296 HKS_IF_TRUE_LOGE_RETURN(isExistInParamsetOne && isExistInParamsetTwo &&
297 (paramInParamsetOne->uint32Param != paramInParamsetTwo->uint32Param),
298 HKS_ERROR_BAD_STATE, "values does not match");
299
300 return HKS_SUCCESS;
301 }
302
SetRsaPssSaltLenType(const struct HksParamSet * paramSet,struct HksUsageSpec * usageSpec)303 void SetRsaPssSaltLenType(const struct HksParamSet *paramSet, struct HksUsageSpec *usageSpec)
304 {
305 struct HksParam *saltLenTypeParam = NULL;
306 int32_t ret = HksGetParam(paramSet, HKS_TAG_RSA_PSS_SALT_LEN_TYPE, &saltLenTypeParam);
307 if (ret == HKS_SUCCESS) {
308 usageSpec->pssSaltLenType = saltLenTypeParam->uint32Param;
309 } else {
310 usageSpec->pssSaltLenType = HKS_RSA_PSS_SALTLEN_MAX;
311 }
312 }