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 
HksCheckBlobAndParamSet2(const struct HksBlob * data,const struct HksParamSet * paramSet1,const struct HksParamSet * paramSet2)102 int32_t HksCheckBlobAndParamSet2(const struct HksBlob *data, const struct HksParamSet *paramSet1,
103     const struct HksParamSet *paramSet2)
104 {
105     int32_t ret = CheckBlob(data);
106     HKS_IF_NOT_SUCC_RETURN(ret, ret)
107 
108     ret = HksCheckParamSetValidity(paramSet1);
109     HKS_IF_NOT_SUCC_RETURN(ret, ret)
110 
111     ret = HksCheckParamSetValidity(paramSet2);
112     HKS_IF_NOT_SUCC_RETURN(ret, ret)
113 
114     return HKS_SUCCESS;
115 }
116 
HksCheckBlob2AndParamSet2(const struct HksBlob * data1,const struct HksBlob * data2,const struct HksParamSet * paramSet1,const struct HksParamSet * paramSet2)117 int32_t HksCheckBlob2AndParamSet2(const struct HksBlob *data1, const struct HksBlob *data2,
118     const struct HksParamSet *paramSet1, const struct HksParamSet *paramSet2)
119 {
120     int32_t ret = CheckBlob(data1);
121     HKS_IF_NOT_SUCC_RETURN(ret, ret)
122 
123     ret = CheckBlob(data2);
124     HKS_IF_NOT_SUCC_RETURN(ret, ret)
125 
126     ret = HksCheckParamSetValidity(paramSet1);
127     HKS_IF_NOT_SUCC_RETURN(ret, ret)
128 
129     ret = HksCheckParamSetValidity(paramSet2);
130     HKS_IF_NOT_SUCC_RETURN(ret, ret)
131     return HKS_SUCCESS;
132 }
133 
HksGetDigestLen(uint32_t digest,uint32_t * digestLen)134 int32_t HksGetDigestLen(uint32_t digest, uint32_t *digestLen)
135 {
136     switch (digest) {
137         case HKS_DIGEST_MD5:
138             *digestLen = HKS_DIGEST_MD5_LEN;
139             break;
140         case HKS_DIGEST_SHA1:
141             *digestLen = HKS_DIGEST_SHA1_LEN;
142             break;
143         case HKS_DIGEST_SHA224:
144             *digestLen = HKS_DIGEST_SHA224_LEN;
145             break;
146         case HKS_DIGEST_SHA256:
147             *digestLen = HKS_DIGEST_SHA256_LEN;
148             break;
149         case HKS_DIGEST_SHA384:
150             *digestLen = HKS_DIGEST_SHA384_LEN;
151             break;
152         case HKS_DIGEST_SHA512:
153             *digestLen = HKS_DIGEST_SHA512_LEN;
154             break;
155         case HKS_DIGEST_SM3:
156             *digestLen = HKS_DIGEST_SM3_LEN;
157             break;
158         default:
159             return HKS_ERROR_INVALID_DIGEST;
160     }
161     return HKS_SUCCESS;
162 }
163 
HksCheckAesAeMode(const struct HksParamSet * paramSet,bool * isAes,bool * isAeMode)164 int32_t HksCheckAesAeMode(const struct HksParamSet *paramSet, bool *isAes, bool *isAeMode)
165 {
166     struct HksParam *algParam = NULL;
167     int32_t ret = HksGetParam(paramSet, HKS_TAG_ALGORITHM, &algParam);
168     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_ALG_FAIL, "append cipher get alg param failed!")
169     *isAes = (algParam->uint32Param == HKS_ALG_AES);
170     if (!(*isAes)) {
171         return HKS_SUCCESS;
172     }
173 
174     struct HksParam *modeParam = NULL;
175     ret = HksGetParam(paramSet, HKS_TAG_BLOCK_MODE, &modeParam);
176     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, HKS_ERROR_CHECK_GET_MODE_FAIL, "append cipher get mode param failed!")
177 
178     *isAeMode = (modeParam->uint32Param == HKS_MODE_CCM) || (modeParam->uint32Param == HKS_MODE_GCM);
179     return HKS_SUCCESS;
180 }
181 
HksCheckWrappedDataFormatValidity(const struct HksBlob * wrappedData,uint32_t validTotalBlobs,const uint32_t * validBlobLengths)182 int32_t HksCheckWrappedDataFormatValidity(const struct HksBlob *wrappedData, uint32_t validTotalBlobs,
183     const uint32_t *validBlobLengths)
184 {
185     if ((CheckBlob(wrappedData) != HKS_SUCCESS) || (wrappedData->size > HKS_WRAPPED_FORMAT_MAX_SIZE) ||
186         (validTotalBlobs == 0)) {
187         HKS_LOG_E("wrapped data format:invalid argument!");
188         return HKS_ERROR_INVALID_ARGUMENT;
189     }
190     const uint8_t *data = wrappedData->data;
191     uint32_t dataSize = wrappedData->size;
192 
193     uint32_t offset = 0;
194     uint32_t partDataLength = 0;
195     uint32_t blobIndex = 0;
196 
197     for (blobIndex = 0; blobIndex < validTotalBlobs && offset < dataSize; blobIndex++) {
198         if (((dataSize - offset) < sizeof(uint32_t))) {
199             HKS_LOG_E("the residual data length is to small.");
200             return HKS_ERROR_INVALID_WRAPPED_FORMAT;
201         }
202         partDataLength = 0;
203         (void)memcpy_s((uint8_t *)&partDataLength, sizeof(uint32_t), data + offset, sizeof(uint32_t));
204         offset += sizeof(uint32_t);
205 
206         if ((partDataLength == 0) || (partDataLength > dataSize - offset)) {
207             HKS_LOG_E(" the blob part:%" LOG_PUBLIC "u length is out of range!", blobIndex);
208             return HKS_ERROR_INVALID_WRAPPED_FORMAT;
209         }
210         offset += partDataLength;
211 
212         if ((validBlobLengths != NULL) && (*(validBlobLengths + blobIndex) != partDataLength)) {
213             HKS_LOG_E("the blob part:%" LOG_PUBLIC "u length is invalid, should be %" LOG_PUBLIC "u!",
214                 blobIndex, *(validBlobLengths + blobIndex));
215             return HKS_ERROR_INVALID_WRAPPED_FORMAT;
216         }
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, &paramInParamsetOne);
284     if (ret != HKS_SUCCESS) {
285         isExistInParamsetOne = false;
286     }
287     bool isExistInParamsetTwo = true;
288     struct HksParam *paramInParamsetTwo = NULL;
289     ret = HksGetParam(runtimeParamSet, tag, &paramInParamsetTwo);
290     if (ret != HKS_SUCCESS) {
291         isExistInParamsetTwo = false;
292     }
293     if (isExistInParamsetOne && (!isExistInParamsetTwo)) {
294         HKS_LOG_E("please set param in paramsetTwo");
295         return HKS_ERROR_BAD_STATE;
296     }
297     if (isExistInParamsetOne && isExistInParamsetTwo &&
298         (paramInParamsetOne->uint32Param != paramInParamsetTwo->uint32Param)) {
299         HKS_LOG_E("values does not match");
300         return HKS_ERROR_BAD_STATE;
301     }
302     return HKS_SUCCESS;
303 }
304 
SetRsaPssSaltLenType(const struct HksParamSet * paramSet,struct HksUsageSpec * usageSpec)305 void SetRsaPssSaltLenType(const struct HksParamSet *paramSet, struct HksUsageSpec *usageSpec)
306 {
307     struct HksParam *saltLenTypeParam = NULL;
308     int32_t ret = HksGetParam(paramSet, HKS_TAG_RSA_PSS_SALT_LEN_TYPE, &saltLenTypeParam);
309     if (ret == HKS_SUCCESS) {
310         usageSpec->pssSaltLenType = saltLenTypeParam->uint32Param;
311     } else {
312         usageSpec->pssSaltLenType = HKS_RSA_PSS_SALTLEN_MAX;
313     }
314 }