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