• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_param.h"
17 
18 #include <stddef.h>
19 
20 #include "hks_log.h"
21 #include "hks_mem.h"
22 #include "hks_template.h"
23 #include "hks_type_inner.h"
24 
25 #include "securec.h"
26 
27 static uint32_t g_validTags[] = {
28     HKS_TAG_ALGORITHM,
29     HKS_TAG_PURPOSE,
30     HKS_TAG_KEY_SIZE,
31     HKS_TAG_DIGEST,
32     HKS_TAG_PADDING,
33     HKS_TAG_BLOCK_MODE,
34     HKS_TAG_KEY_TYPE,
35     HKS_TAG_ASSOCIATED_DATA,
36     HKS_TAG_NONCE,
37     HKS_TAG_IV,
38 
39     HKS_TAG_SALT,
40     HKS_TAG_PWD,
41     HKS_TAG_INFO,
42     HKS_TAG_ITERATION,
43 
44     HKS_TAG_KEY_GENERATE_TYPE,
45     HKS_TAG_DERIVE_MAIN_KEY,
46     HKS_TAG_DERIVE_FACTOR,
47     HKS_TAG_DERIVE_ALG,
48     HKS_TAG_AGREE_ALG,
49     HKS_TAG_AGREE_PUBLIC_KEY_IS_KEY_ALIAS,
50     HKS_TAG_AGREE_PRIVATE_KEY_ALIAS,
51     HKS_TAG_AGREE_PUBLIC_KEY,
52     HKS_TAG_KEY_ALIAS,
53     HKS_TAG_DERIVE_KEY_SIZE,
54     HKS_TAG_IMPORT_KEY_TYPE,
55     HKS_TAG_UNWRAP_ALGORITHM_SUITE,
56     HKS_TAG_DERIVE_AGREE_KEY_STORAGE_FLAG,
57     HKS_TAG_RSA_PSS_SALT_LEN_TYPE,
58     HKS_TAG_MGF_DIGEST,
59 
60     HKS_TAG_ACTIVE_DATETIME,
61     HKS_TAG_ORIGINATION_EXPIRE_DATETIME,
62     HKS_TAG_USAGE_EXPIRE_DATETIME,
63     HKS_TAG_CREATION_DATETIME,
64 
65     HKS_TAG_ALL_USERS,
66     HKS_TAG_USER_ID,
67     HKS_TAG_FRONT_USER_ID,
68     HKS_TAG_NO_AUTH_REQUIRED,
69     HKS_TAG_USER_AUTH_TYPE,
70     HKS_TAG_AUTH_TIMEOUT,
71     HKS_TAG_AUTH_TOKEN,
72     HKS_TAG_AUTH_STORAGE_LEVEL,
73     HKS_TAG_SPECIFIC_USER_ID,
74 
75     HKS_TAG_OS_VERSION,
76     HKS_TAG_OS_PATCHLEVEL,
77 
78     HKS_TAG_ATTESTATION_CHALLENGE,
79     HKS_TAG_ATTESTATION_APPLICATION_ID,
80     HKS_TAG_ATTESTATION_ID_BRAND,
81     HKS_TAG_ATTESTATION_ID_DEVICE,
82     HKS_TAG_ATTESTATION_ID_PRODUCT,
83     HKS_TAG_ATTESTATION_ID_SERIAL,
84     HKS_TAG_ATTESTATION_ID_IMEI,
85     HKS_TAG_ATTESTATION_ID_MEID,
86     HKS_TAG_ATTESTATION_ID_MANUFACTURER,
87     HKS_TAG_ATTESTATION_ID_MODEL,
88     HKS_TAG_ATTESTATION_ID_ALIAS,
89     HKS_TAG_ATTESTATION_ID_SOCID,
90     HKS_TAG_ATTESTATION_ID_UDID,
91     HKS_TAG_ATTESTATION_ID_SEC_LEVEL_INFO,
92     HKS_TAG_ATTESTATION_ID_VERSION_INFO,
93     HKS_TAG_ATTESTATION_BASE64,
94     HKS_TAG_ATTESTATION_MODE,
95 
96     HKS_TAG_IS_KEY_ALIAS,
97     HKS_TAG_KEY_STORAGE_FLAG,
98     HKS_TAG_IS_ALLOWED_WRAP,
99     HKS_TAG_KEY_WRAP_TYPE,
100     HKS_TAG_KEY_AUTH_ID,
101     HKS_TAG_KEY_ROLE,
102     HKS_TAG_KEY_FLAG,
103     HKS_TAG_KEY_DOMAIN,
104 
105     HKS_TAG_KEY_AUTH_ACCESS_TYPE,
106     HKS_TAG_KEY_SECURE_SIGN_TYPE,
107     HKS_TAG_CHALLENGE_TYPE,
108     HKS_TAG_CHALLENGE_POS,
109     HKS_TAG_KEY_AUTH_PURPOSE,
110     HKS_TAG_BATCH_PURPOSE,
111     HKS_TAG_IS_BATCH_OPERATION,
112     HKS_TAG_BATCH_OPERATION_TIMEOUT,
113 
114     HKS_TAG_KEY_INIT_CHALLENGE,
115     HKS_TAG_IS_USER_AUTH_ACCESS,
116     HKS_TAG_USER_AUTH_CHALLENGE,
117     HKS_TAG_USER_AUTH_ENROLL_ID_INFO,
118     HKS_TAG_USER_AUTH_SECURE_UID,
119     HKS_TAG_KEY_AUTH_RESULT,
120     HKS_TAG_IF_NEED_APPEND_AUTH_INFO,
121     HKS_TAG_VERIFIED_AUTH_TOKEN,
122     HKS_TAG_IS_APPEND_UPDATE_DATA,
123 
124     HKS_TAG_PROCESS_NAME,
125     HKS_TAG_PACKAGE_NAME,
126     HKS_TAG_PAYLOAD_LEN,
127     HKS_TAG_AE_TAG,
128     HKS_TAG_CRYPTO_CTX,
129     HKS_TAG_KEY,
130     HKS_TAG_KEY_VERSION,
131     HKS_TAG_IS_KEY_HANDLE,
132     HKS_TAG_SYMMETRIC_KEY_DATA,
133     HKS_TAG_ASYMMETRIC_PUBLIC_KEY_DATA,
134     HKS_TAG_ASYMMETRIC_PRIVATE_KEY_DATA,
135     HKS_TAG_KEY_ACCESS_TIME,
136 
137     HKS_TAG_ACCESS_TOKEN_ID,
138     HKS_TAG_BUNDLE_NAME,
139     HKS_TAG_IS_DEVICE_PASSWORD_SET,
140 };
141 
GetTagType(enum HksTag tag)142 HKS_API_EXPORT enum HksTagType GetTagType(enum HksTag tag)
143 {
144     return (enum HksTagType)((uint32_t)tag & (uint32_t)HKS_TAG_TYPE_MASK);
145 }
146 
IsValidTag(uint32_t tag)147 static bool IsValidTag(uint32_t tag)
148 {
149     uint32_t tagSize = HKS_ARRAY_SIZE(g_validTags);
150     for (uint32_t i = 0; i < tagSize; ++i) {
151         if (tag == g_validTags[i]) {
152             return true;
153         }
154     }
155     return false;
156 }
157 
HksCheckParamSetTag(const struct HksParamSet * paramSet)158 HKS_API_EXPORT int32_t HksCheckParamSetTag(const struct HksParamSet *paramSet)
159 {
160     HKS_IF_NULL_RETURN(paramSet, HKS_ERROR_NULL_POINTER)
161 
162     for (uint32_t i = 0; i < paramSet->paramsCnt; ++i) {
163         uint32_t curTag = paramSet->params[i].tag;
164         if (!IsValidTag(curTag)) {
165             HKS_LOG_E("paramSet contains invalid tag! 0x%" LOG_PUBLIC "x", curTag);
166             return HKS_ERROR_INVALID_ARGUMENT;
167         }
168 
169         for (uint32_t j = i + 1; j < paramSet->paramsCnt; ++j) {
170             if (curTag == paramSet->params[j].tag) {
171                 HKS_LOG_E("paramSet contains multi-tags! 0x%" LOG_PUBLIC "x", curTag);
172                 return HKS_ERROR_INVALID_ARGUMENT;
173             }
174         }
175     }
176 
177     return HKS_SUCCESS;
178 }
179 
CheckBeforeAddParams(const struct HksParamSet * paramSet,const struct HksParam * params,uint32_t paramCnt)180 static int32_t CheckBeforeAddParams(const struct HksParamSet *paramSet, const struct HksParam *params,
181     uint32_t paramCnt)
182 {
183     if ((params == NULL) || (paramSet == NULL) || (paramSet->paramSetSize > HKS_PARAM_SET_MAX_SIZE) ||
184         (paramCnt > HKS_DEFAULT_PARAM_CNT) || (paramSet->paramsCnt > (HKS_DEFAULT_PARAM_CNT - paramCnt))) {
185         HKS_LOG_E("invalid params or paramset!");
186         return HKS_ERROR_INVALID_ARGUMENT;
187     }
188 
189     for (uint32_t i = 0; i < paramCnt; i++) {
190         if ((GetTagType((enum HksTag)(params[i].tag)) == HKS_TAG_TYPE_BYTES) &&
191             (params[i].blob.data == NULL)) {
192             HKS_LOG_E("invalid blob param!");
193             return HKS_ERROR_INVALID_ARGUMENT;
194         }
195     }
196     return HKS_SUCCESS;
197 }
198 
BuildParamSet(struct HksParamSet ** paramSet)199 static int32_t BuildParamSet(struct HksParamSet **paramSet)
200 {
201     struct HksParamSet *freshParamSet = *paramSet;
202     uint32_t size = freshParamSet->paramSetSize;
203     uint32_t offset = sizeof(struct HksParamSet) + sizeof(struct HksParam) * freshParamSet->paramsCnt;
204 
205     if (size > HKS_DEFAULT_PARAM_SET_SIZE) {
206         freshParamSet = (struct HksParamSet *)HksMalloc(size);
207         HKS_IF_NULL_LOGE_RETURN(freshParamSet, HKS_ERROR_MALLOC_FAIL, "malloc params failed!")
208 
209         if (memcpy_s(freshParamSet, size, *paramSet, offset) != EOK) {
210             HKS_FREE(freshParamSet);
211             HKS_LOG_E("copy params failed!");
212             return HKS_ERROR_INSUFFICIENT_MEMORY;
213         }
214         HKS_FREE(*paramSet);
215         *paramSet = freshParamSet;
216     }
217 
218     return HksFreshParamSet(freshParamSet, true);
219 }
220 
HksCheckParamSet(const struct HksParamSet * paramSet,uint32_t size)221 HKS_API_EXPORT int32_t HksCheckParamSet(const struct HksParamSet *paramSet, uint32_t size)
222 {
223     HKS_IF_NULL_RETURN(paramSet, HKS_ERROR_NULL_POINTER)
224 
225     if ((size < sizeof(struct HksParamSet)) || (size > HKS_PARAM_SET_MAX_SIZE) ||
226         (paramSet->paramSetSize != size) ||
227         (paramSet->paramsCnt > ((size - sizeof(struct HksParamSet)) / sizeof(struct HksParam)))) {
228         HKS_LOG_E("invalid param set!");
229         return HKS_ERROR_INVALID_ARGUMENT;
230     }
231     return HKS_SUCCESS;
232 }
233 
HksInitParamSet(struct HksParamSet ** paramSet)234 HKS_API_EXPORT int32_t HksInitParamSet(struct HksParamSet **paramSet)
235 {
236     HKS_IF_NULL_LOGE_RETURN(paramSet, HKS_ERROR_NULL_POINTER, "invalid init params!")
237 
238     *paramSet = (struct HksParamSet *)HksMalloc(HKS_DEFAULT_PARAM_SET_SIZE);
239     HKS_IF_NULL_LOGE_RETURN(*paramSet, HKS_ERROR_MALLOC_FAIL, "malloc init param set failed!")
240 
241     (*paramSet)->paramsCnt = 0;
242     (*paramSet)->paramSetSize = sizeof(struct HksParamSet);
243     return HKS_SUCCESS;
244 }
245 
HksAddParams(struct HksParamSet * paramSet,const struct HksParam * params,uint32_t paramCnt)246 HKS_API_EXPORT int32_t HksAddParams(struct HksParamSet *paramSet,
247     const struct HksParam *params, uint32_t paramCnt)
248 {
249     int32_t ret = CheckBeforeAddParams(paramSet, params, paramCnt);
250     HKS_IF_NOT_SUCC_RETURN(ret, ret)
251 
252     for (uint32_t i = 0; i < paramCnt; i++) {
253         paramSet->paramSetSize += sizeof(struct HksParam);
254         if (GetTagType((enum HksTag)(params[i].tag)) == HKS_TAG_TYPE_BYTES) {
255             if (IsAdditionOverflow(paramSet->paramSetSize, params[i].blob.size)) {
256                 HKS_LOG_E("params size overflow!");
257                 paramSet->paramSetSize -= sizeof(struct HksParam);
258                 return HKS_ERROR_INVALID_ARGUMENT;
259             }
260             paramSet->paramSetSize += params[i].blob.size;
261         }
262         (void)memcpy_s(&paramSet->params[paramSet->paramsCnt++], sizeof(struct HksParam), &params[i],
263             sizeof(struct HksParam));
264     }
265     return HKS_SUCCESS;
266 }
267 
HksBuildParamSet(struct HksParamSet ** paramSet)268 HKS_API_EXPORT int32_t HksBuildParamSet(struct HksParamSet **paramSet)
269 {
270     if ((paramSet == NULL) || (*paramSet == NULL)) {
271         return HKS_ERROR_NULL_POINTER;
272     }
273 
274     int ret = HksCheckParamSet(*paramSet, (*paramSet)->paramSetSize);
275     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "invalid build params!")
276 
277     return BuildParamSet(paramSet);
278 }
279 
HksFreeParamSet(struct HksParamSet ** paramSet)280 HKS_API_EXPORT void HksFreeParamSet(struct HksParamSet **paramSet)
281 {
282     if (paramSet == NULL) {
283         HKS_LOG_E("invalid free paramset!");
284         return;
285     }
286     HKS_FREE(*paramSet);
287 }
288 
FreshParamSet(struct HksParamSet * paramSet,bool isCopy)289 static int32_t FreshParamSet(struct HksParamSet *paramSet, bool isCopy)
290 {
291     uint32_t size = paramSet->paramSetSize;
292     uint32_t offset = sizeof(struct HksParamSet) + sizeof(struct HksParam) * paramSet->paramsCnt;
293 
294     for (uint32_t i = 0; i < paramSet->paramsCnt; i++) {
295         if (offset > size) {
296             HKS_LOG_E("invalid param set offset!");
297             return HKS_ERROR_INVALID_ARGUMENT;
298         }
299         if (GetTagType((enum HksTag)(paramSet->params[i].tag)) == HKS_TAG_TYPE_BYTES) {
300             if (IsAdditionOverflow(offset, paramSet->params[i].blob.size)) {
301                 HKS_LOG_E("blob size overflow!");
302                 return HKS_ERROR_INVALID_ARGUMENT;
303             }
304             if (isCopy && (memcpy_s((uint8_t *)paramSet + offset, size - offset,
305                 paramSet->params[i].blob.data, paramSet->params[i].blob.size) != EOK)) {
306                 HKS_LOG_E("copy param blob failed!");
307                 return HKS_ERROR_INSUFFICIENT_MEMORY;
308             }
309             paramSet->params[i].blob.data = (uint8_t *)paramSet + offset;
310             offset += paramSet->params[i].blob.size;
311         }
312     }
313 
314     if (paramSet->paramSetSize != offset) {
315         HKS_LOG_E("invalid param set size!");
316         return HKS_ERROR_INVALID_ARGUMENT;
317     }
318     return HKS_SUCCESS;
319 }
320 
321 
HksFreshParamSet(struct HksParamSet * paramSet,bool isCopy)322 HKS_API_EXPORT int32_t HksFreshParamSet(struct HksParamSet *paramSet, bool isCopy)
323 {
324     HKS_IF_NULL_LOGE_RETURN(paramSet, HKS_ERROR_NULL_POINTER, "invalid NULL paramSet")
325 
326     int32_t ret = HksCheckParamSet(paramSet, paramSet->paramSetSize);
327     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "invalid fresh paramSet")
328 
329     return FreshParamSet(paramSet, isCopy);
330 }
331 
HksGetParam(const struct HksParamSet * paramSet,uint32_t tag,struct HksParam ** param)332 HKS_API_EXPORT int32_t HksGetParam(const struct HksParamSet *paramSet, uint32_t tag, struct HksParam **param)
333 {
334     if ((paramSet == NULL) || (param == NULL)) {
335         HKS_LOG_E("invalid params!");
336         return HKS_ERROR_INVALID_ARGUMENT;
337     }
338 
339     HKS_IF_NOT_SUCC_LOGE_RETURN(HksCheckParamSet(paramSet, paramSet->paramSetSize),
340         HKS_ERROR_INVALID_ARGUMENT, "invalid paramSet!")
341 
342     for (uint32_t i = 0; i < paramSet->paramsCnt; i++) {
343         if (tag == paramSet->params[i].tag) {
344             *param = (struct HksParam *)&paramSet->params[i];
345             return HKS_SUCCESS;
346         }
347     }
348 
349     return HKS_ERROR_PARAM_NOT_EXIST;
350 }
351 
HksGetParamSet(const struct HksParamSet * inParamSet,uint32_t inParamSetSize,struct HksParamSet ** outParamSet)352 HKS_API_EXPORT int32_t HksGetParamSet(const struct HksParamSet *inParamSet,
353     uint32_t inParamSetSize, struct HksParamSet **outParamSet)
354 {
355     int32_t ret = HksCheckParamSet(inParamSet, inParamSetSize);
356     HKS_IF_NOT_SUCC_RETURN(ret, ret)
357 
358     HKS_IF_NULL_RETURN(outParamSet, HKS_ERROR_NULL_POINTER)
359 
360     uint32_t size = inParamSet->paramSetSize;
361     struct HksParamSet *buf = (struct HksParamSet *)HksMalloc(size);
362     HKS_IF_NULL_LOGE_RETURN(buf, HKS_ERROR_MALLOC_FAIL, "malloc from param set failed!")
363 
364     (void)memcpy_s(buf, size, inParamSet, size);
365 
366     ret = FreshParamSet(buf, false);
367     if (ret != HKS_SUCCESS) {
368         HKS_FREE(buf);
369         return ret;
370     }
371     *outParamSet = buf;
372     return HKS_SUCCESS;
373 }
374 
HksCheckParamMatch(const struct HksParam * baseParam,const struct HksParam * param)375 HKS_API_EXPORT int32_t HksCheckParamMatch(const struct HksParam *baseParam, const struct HksParam *param)
376 {
377     if (baseParam == NULL || param == NULL) {
378         return HKS_ERROR_NULL_POINTER;
379     }
380 
381     if (baseParam->tag != param->tag) {
382         HKS_LOG_E("unmatch param type!");
383         return HKS_ERROR_INVALID_ARGUMENT;
384     }
385 
386     switch (GetTagType((enum HksTag)(baseParam->tag))) {
387         case HKS_TAG_TYPE_INT:
388             return (baseParam->int32Param == param->int32Param) ? HKS_SUCCESS : HKS_ERROR_INVALID_ARGUMENT;
389         case HKS_TAG_TYPE_UINT:
390             return (baseParam->uint32Param == param->uint32Param) ? HKS_SUCCESS : HKS_ERROR_INVALID_ARGUMENT;
391         case HKS_TAG_TYPE_ULONG:
392             return (baseParam->uint64Param == param->uint64Param) ? HKS_SUCCESS : HKS_ERROR_INVALID_ARGUMENT;
393         case HKS_TAG_TYPE_BOOL:
394             return (baseParam->boolParam == param->boolParam) ? HKS_SUCCESS : HKS_ERROR_INVALID_ARGUMENT;
395         case HKS_TAG_TYPE_BYTES:
396             if (baseParam->blob.size != param->blob.size ||
397                 baseParam->blob.data == NULL ||(param->blob.data == NULL)) {
398                 HKS_LOG_E("unmatch byte type len!");
399                 return HKS_ERROR_INVALID_ARGUMENT;
400             }
401             if (HksMemCmp(baseParam->blob.data, param->blob.data, baseParam->blob.size)) {
402                 HKS_LOG_E("unmatch byte type content!");
403                 return HKS_ERROR_INVALID_ARGUMENT;
404             }
405             return HKS_SUCCESS;
406         default:
407             HKS_LOG_E("invalid tag type:%" LOG_PUBLIC "x", GetTagType((enum HksTag)(baseParam->tag)));
408             return HKS_ERROR_INVALID_ARGUMENT;
409     }
410 }
411 
HksCheckIsTagAlreadyExist(const struct HksParam * params,uint32_t paramsCnt,const struct HksParamSet * targetParamSet)412 HKS_API_EXPORT int32_t HksCheckIsTagAlreadyExist(const struct HksParam *params, uint32_t paramsCnt,
413     const struct HksParamSet *targetParamSet)
414 {
415     if (params == NULL || targetParamSet == NULL) {
416         return HKS_ERROR_NULL_POINTER;
417     }
418 
419     int32_t ret = HksCheckParamSet(targetParamSet, targetParamSet->paramSetSize);
420     HKS_IF_NOT_SUCC_RETURN(ret, ret)
421 
422     for (uint32_t i = 0; i < targetParamSet->paramsCnt; ++i) {
423         for (uint32_t j = 0; j < paramsCnt; ++j) {
424             if (params[j].tag == targetParamSet->params[i].tag) {
425                 return HKS_ERROR_INVALID_ARGUMENT;
426             }
427         }
428     }
429 
430     return HKS_SUCCESS;
431 }
432 
HksDeleteTagsFromParamSet(const uint32_t * tag,uint32_t tagCount,const struct HksParamSet * paramSet,struct HksParamSet ** outParamSet)433 HKS_API_EXPORT int32_t HksDeleteTagsFromParamSet(const uint32_t *tag, uint32_t tagCount,
434     const struct HksParamSet *paramSet, struct HksParamSet **outParamSet)
435 {
436     if (tag == NULL || paramSet == NULL || outParamSet == NULL) {
437         return HKS_ERROR_NULL_POINTER;
438     }
439     int32_t ret = HksFreshParamSet((struct HksParamSet *)paramSet, false);
440     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "fresh paramset failed")
441 
442     struct HksParamSet *newParamSet = NULL;
443     ret = HksInitParamSet(&newParamSet);
444     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init param set failed")
445 
446     for (uint32_t i = 0; i < paramSet->paramsCnt; ++i) {
447         bool isDeleteTag = false;
448         for (uint32_t j = 0; j < tagCount; ++j) {
449             if (paramSet->params[i].tag == tag[j]) {
450                 isDeleteTag = true;
451                 break;
452             }
453         }
454         if (!isDeleteTag) {
455             ret = HksAddParams(newParamSet, &paramSet->params[i], 1);
456             if (ret != HKS_SUCCESS) {
457                 HKS_LOG_E("add in params failed");
458                 HksFreeParamSet(&newParamSet);
459                 return ret;
460             }
461         }
462     }
463 
464     ret = HksBuildParamSet(&newParamSet);
465     if (ret != HKS_SUCCESS) {
466         HKS_LOG_E("build paramset failed");
467         HksFreeParamSet(&newParamSet);
468         return ret;
469     }
470 
471     *outParamSet = newParamSet;
472     return HKS_SUCCESS;
473 }
474