• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 "cert_manager_key_operation.h"
17 
18 #include "securec.h"
19 
20 #include "cert_manager_mem.h"
21 #include "cert_manager_session_mgr.h"
22 #include "cert_manager_crypto_operation.h"
23 #include "cert_manager_uri.h"
24 #include "cm_cert_property_rdb.h"
25 #include "cm_log.h"
26 #include "cm_type.h"
27 #include "cm_util.h"
28 
29 #include "hks_api.h"
30 #include "hks_param.h"
31 #include "hks_type.h"
32 
33 #define HAP_USER_ID 100
34 struct PropertyToHuks {
35     uint32_t cmProperty;
36     uint32_t huksProperty;
37 };
38 
39 static struct PropertyToHuks g_cmPurposeProperty[] = {
40     { CM_KEY_PURPOSE_SIGN, HKS_KEY_PURPOSE_SIGN },
41     { CM_KEY_PURPOSE_VERIFY, HKS_KEY_PURPOSE_VERIFY },
42 };
43 
44 static struct PropertyToHuks g_cmPaddingProperty[] = {
45     { CM_PADDING_NONE, HKS_PADDING_NONE },
46     { CM_PADDING_OAEP, HKS_PADDING_OAEP },
47     { CM_PADDING_PSS, HKS_PADDING_PSS },
48     { CM_PADDING_PKCS1_V1_5, HKS_PADDING_PKCS1_V1_5 },
49     { CM_PADDING_PKCS5, HKS_PADDING_PKCS5 },
50     { CM_PADDING_PKCS7, HKS_PADDING_PKCS7 },
51 };
52 
53 static struct PropertyToHuks g_cmDigestProperty[] = {
54     { CM_DIGEST_NONE, HKS_DIGEST_NONE },
55     { CM_DIGEST_MD5, HKS_DIGEST_MD5 },
56     { CM_DIGEST_SHA1, HKS_DIGEST_SHA1 },
57     { CM_DIGEST_SHA224, HKS_DIGEST_SHA224 },
58     { CM_DIGEST_SHA256, HKS_DIGEST_SHA256 },
59     { CM_DIGEST_SHA384, HKS_DIGEST_SHA384 },
60     { CM_DIGEST_SHA512, HKS_DIGEST_SHA512 },
61     { CM_DIGEST_SM3, HKS_DIGEST_SM3 },
62 };
63 
64 static struct PropertyToHuks g_cmLevelProperty[] = {
65     { CM_AUTH_STORAGE_LEVEL_EL1, HKS_AUTH_STORAGE_LEVEL_DE },
66     { CM_AUTH_STORAGE_LEVEL_EL2, HKS_AUTH_STORAGE_LEVEL_CE },
67     { CM_AUTH_STORAGE_LEVEL_EL4, HKS_AUTH_STORAGE_LEVEL_ECE },
68 };
69 
70 #define INVALID_PROPERTY_VALUE 0xFFFF
71 #define DEFAULT_LEN_USED_FOR_MALLOC 1024
72 
73 // LCOV_EXCL_START
AddUserIdParam(struct HksParamSet * paramSet,enum CmAuthStorageLevel level,const struct CmBlob * uri)74 static int32_t AddUserIdParam(struct HksParamSet *paramSet, enum CmAuthStorageLevel level, const struct CmBlob *uri)
75 {
76     if (level == CM_AUTH_STORAGE_LEVEL_EL1) {
77         CM_LOG_D("level is el1");
78         return CM_SUCCESS;
79     }
80     struct CMUri uriObj;
81     (void)memset_s(&uriObj, sizeof(uriObj), 0, sizeof(uriObj));
82 
83     int32_t ret = CertManagerUriDecode(&uriObj, (char *)uri->data); //uri->data已被校验有\0结尾
84     if (ret != CM_SUCCESS) {
85         CM_LOG_E("Failed to decode uri, ret = %d", ret);
86         return ret;
87     }
88     do {
89         if (uriObj.user == NULL) {
90             CM_LOG_E("uri format is invalid");
91             ret = CMR_ERROR_INVALID_ARGUMENT_URI;
92             break;
93         }
94 
95         uint32_t userId = 0;
96         if (CmIsNumeric(uriObj.user, strlen(uriObj.user) + 1, &userId) != CM_SUCCESS) {
97             CM_LOG_E("parse string to uint32 failed.");
98             ret = CMR_ERROR_INVALID_ARGUMENT_URI;
99             break;
100         }
101         /* If the caller is SA and the level is not EL1,
102             the initial value of userid needs to be set and passed to HUKS.  */
103         if (userId == 0) {
104             userId = HAP_USER_ID;
105         }
106         struct HksParam userIdParam = {
107             .tag = HKS_TAG_SPECIFIC_USER_ID,
108             .uint32Param = userId,
109         };
110         ret = HksAddParams(paramSet, &userIdParam, 1);
111         if (ret != HKS_SUCCESS) {
112             CM_LOG_E("add userIdParam tag failed");
113             break;
114         }
115     } while (0);
116     (void)CertManagerFreeUri(&uriObj);
117     return ret;
118 }
119 
ConstructParamSet(const struct HksParam * params,uint32_t paramCount,struct HksParamSet ** outParamSet,enum CmAuthStorageLevel level,const struct CmBlob * uri)120 static int32_t ConstructParamSet(const struct HksParam *params, uint32_t paramCount, struct HksParamSet **outParamSet,
121     enum CmAuthStorageLevel level, const struct CmBlob *uri)
122 {
123     struct HksParamSet *paramSet = NULL;
124     int32_t ret = HksInitParamSet(&paramSet);
125     if (ret != HKS_SUCCESS) {
126         CM_LOG_E("init huks paramset failed, ret = %d", ret);
127         return ret;
128     }
129 
130     ret = AddUserIdParam(paramSet, level, uri);
131     if (ret != HKS_SUCCESS) {
132         CM_LOG_E("add userid param failed, ret = %d", ret);
133         HksFreeParamSet(&paramSet);
134         return ret;
135     }
136 
137     ret = HksAddParams(paramSet, params, paramCount);
138     if (ret != HKS_SUCCESS) {
139         CM_LOG_E("add huks params failed, ret = %d", ret);
140         HksFreeParamSet(&paramSet);
141         return ret;
142     }
143 
144     ret = HksBuildParamSet(&paramSet);
145     if (ret != HKS_SUCCESS) {
146         CM_LOG_E("build huks paramSet failed, ret = %d", ret);
147         HksFreeParamSet(&paramSet);
148         return ret;
149     }
150 
151     *outParamSet = paramSet;
152     return CM_SUCCESS;
153 }
154 
GetKeyAlias(struct HksBlob * keyAlias,struct CmBlob * encodeTarget)155 static int32_t GetKeyAlias(struct HksBlob *keyAlias, struct CmBlob *encodeTarget)
156 {
157     int32_t ret = CM_SUCCESS;
158     if (keyAlias->size > MAX_LEN_MAC_KEY) {
159         ret = GetNameEncode((struct CmBlob *)keyAlias, encodeTarget);
160         if (ret != CM_SUCCESS) {
161             CM_LOG_E("base64urlsha256 failed");
162             return ret;
163         }
164         keyAlias->data = encodeTarget->data;
165         keyAlias->size = encodeTarget->size;
166     }
167     return ret;
168 }
169 
TranslateToHuksLevel(enum CmAuthStorageLevel level)170 static uint32_t TranslateToHuksLevel(enum CmAuthStorageLevel level)
171 {
172     uint32_t res = HKS_AUTH_STORAGE_LEVEL_DE;
173     for (uint32_t i = 0; i < CM_ARRAY_SIZE(g_cmLevelProperty); ++i) {
174         if (level == g_cmLevelProperty[i].cmProperty) {
175             res = (uint32_t)g_cmLevelProperty[i].huksProperty;
176         }
177     }
178     return res;
179 }
180 
CmKeyOpGenMacKey(const struct CmBlob * alias,enum CmAuthStorageLevel level)181 int32_t CmKeyOpGenMacKey(const struct CmBlob *alias, enum CmAuthStorageLevel level)
182 {
183     uint32_t huksAuthStorageLevel = TranslateToHuksLevel(level);
184     struct HksParam genMacKeyParams[] = {
185         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_HMAC },
186         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
187         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_MAC },
188         { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256 },
189         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = huksAuthStorageLevel },
190     };
191 
192     struct HksParamSet *paramSet = NULL;
193     int32_t ret = ConstructParamSet(genMacKeyParams, sizeof(genMacKeyParams) / sizeof(struct HksParam),
194         &paramSet, level, alias);
195     if (ret != CM_SUCCESS) {
196         CM_LOG_E("construct gen mac key paramSet failed");
197         return CMR_ERROR_KEY_GENERATE_PARAM_FAILED;
198     }
199 
200     struct HksBlob keyAlias = { alias->size, alias->data };
201 
202     uint8_t encodeBuf[MAX_LEN_BASE64URL_SHA256] = { 0 };
203     struct CmBlob encodeTarget = { sizeof(encodeBuf), encodeBuf };
204     ret = GetKeyAlias(&keyAlias, &encodeTarget);
205     if (ret != CM_SUCCESS) {
206         HksFreeParamSet(&paramSet);
207         CM_LOG_E("get keyalias failed");
208         return ret;
209     }
210 
211     ret = HksGenerateKey(&keyAlias, paramSet, NULL);
212     HksFreeParamSet(&paramSet);
213     if (ret != HKS_SUCCESS) {
214         CM_LOG_E("hks generate key failed, ret = %d", ret);
215         return CMR_ERROR_KEY_GENERATE_FAILED;
216     }
217     return CM_SUCCESS;
218 }
219 
CmKeyOpGenMacKeyIfNotExist(const struct CmBlob * alias)220 int32_t CmKeyOpGenMacKeyIfNotExist(const struct CmBlob *alias)
221 {
222     struct HksParam keyExistParams[] = {
223         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
224     };
225     struct HksParamSet *paramSet = NULL;
226     int32_t ret = ConstructParamSet(keyExistParams, sizeof(keyExistParams) / sizeof(struct HksParam), &paramSet,
227         CM_AUTH_STORAGE_LEVEL_EL1, alias);
228     if (ret != CM_SUCCESS) {
229         CM_LOG_E("Failed to construct key exist paramSet");
230         return CMR_ERROR_KEY_CHECK_EXIST_PARAM_FAILED;
231     }
232 
233     struct HksBlob keyAlias = { alias->size, alias->data };
234 
235     uint8_t encodeBuf[MAX_LEN_BASE64URL_SHA256] = { 0 };
236     struct CmBlob encodeTarget = { sizeof(encodeBuf), encodeBuf };
237     ret = GetKeyAlias(&keyAlias, &encodeTarget);
238     if (ret != CM_SUCCESS) {
239         HksFreeParamSet(&paramSet);
240         CM_LOG_E("get keyalias failed");
241         return ret;
242     }
243 
244     ret = HksKeyExist(&keyAlias, paramSet);
245     HksFreeParamSet(&paramSet);
246     if (ret == HKS_SUCCESS) {
247         return ret;
248     }
249     if (ret != HKS_ERROR_NOT_EXIST) {
250         CM_LOG_E("find mac key failed, ret = %d", ret);
251         return CMR_ERROR_KEY_CHECK_EXIST_FAILED;
252     }
253 
254     return CmKeyOpGenMacKey(alias, CM_AUTH_STORAGE_LEVEL_EL1);
255 }
256 
CmKeyOpDeleteKey(const struct CmBlob * alias,enum CmAuthStorageLevel level)257 int32_t CmKeyOpDeleteKey(const struct CmBlob *alias, enum CmAuthStorageLevel level)
258 {
259     uint32_t huksAuthStorageLevel = TranslateToHuksLevel(level);
260     struct HksParam deleteKeyParams[] = {
261         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = huksAuthStorageLevel },
262     };
263     struct HksParamSet *paramSet = NULL;
264     int32_t ret = ConstructParamSet(deleteKeyParams, sizeof(deleteKeyParams) / sizeof(struct HksParam), &paramSet,
265         level, alias);
266     if (ret != CM_SUCCESS) {
267         CM_LOG_E("Failed to construct delete key paramSet");
268         return CMR_ERROR_KEY_OPERATION_FAILED;
269     }
270 
271     struct HksBlob keyAlias = { alias->size, alias->data };
272 
273     uint8_t encodeBuf[MAX_LEN_BASE64URL_SHA256] = { 0 };
274     struct CmBlob encodeTarget = { sizeof(encodeBuf), encodeBuf };
275     ret = GetKeyAlias(&keyAlias, &encodeTarget);
276     if (ret != CM_SUCCESS) {
277         HksFreeParamSet(&paramSet);
278         CM_LOG_E("get keyalias failed");
279         return ret;
280     }
281 
282     ret = HksDeleteKey(&keyAlias, paramSet);
283     HksFreeParamSet(&paramSet);
284     if ((ret != HKS_SUCCESS) && (ret != HKS_ERROR_NOT_EXIST)) {
285         CM_LOG_E("hks delete key failed, ret = %d", ret);
286         return CMR_ERROR_KEY_OPERATION_FAILED;
287     }
288 
289     return CM_SUCCESS;
290 }
291 
CmKeyOpCalcMac(const struct CmBlob * alias,const struct CmBlob * srcData,struct CmBlob * mac,enum CmAuthStorageLevel level)292 int32_t CmKeyOpCalcMac(const struct CmBlob *alias, const struct CmBlob *srcData,
293     struct CmBlob *mac, enum CmAuthStorageLevel level)
294 {
295     uint32_t huksAuthStorageLevel = TranslateToHuksLevel(level);
296     struct HksParam macParams[] = {
297         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_HMAC },
298         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
299         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_MAC },
300         { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256 },
301         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = huksAuthStorageLevel },
302     };
303 
304     struct HksParamSet *paramSet = NULL;
305     int32_t ret = ConstructParamSet(macParams, sizeof(macParams) / sizeof(struct HksParam), &paramSet,
306         level, alias);
307     if (ret != CM_SUCCESS) {
308         CM_LOG_E("construct mac init paramSet failed");
309         return CMR_ERROR_KEY_MAC_PARAM_FAILED;
310     }
311 
312     do {
313         uint64_t handleValue = 0;
314         struct HksBlob handle = { sizeof(handleValue), (uint8_t *)&handleValue };
315         struct HksBlob keyAlias = { alias->size, alias->data };
316 
317         uint8_t encodeBuf[MAX_LEN_BASE64URL_SHA256] = { 0 };
318         struct CmBlob encodeTarget = { sizeof(encodeBuf), encodeBuf };
319         ret = GetKeyAlias(&keyAlias, &encodeTarget);
320         if (ret != CM_SUCCESS) {
321             CM_LOG_E("get keyalias failed");
322             break;
323         }
324 
325         ret = HksInit(&keyAlias, paramSet, &handle, NULL);
326         if (ret != HKS_SUCCESS) {
327             CM_LOG_E("mac calc init failed, ret = %d", ret);
328             ret = CMR_ERROR_KEY_MAC_INIT_FAILED;
329             break;
330         }
331 
332         struct HksBlob inData = { srcData->size, srcData->data };
333         struct HksBlob outMac = { mac->size, mac->data };
334         ret = HksFinish(&handle, paramSet, &inData, &outMac);
335         if (ret != HKS_SUCCESS) {
336             CM_LOG_E("mac calc finish failed, ret = %d", ret);
337             ret = CMR_ERROR_KEY_MAC_FINISH_FAILED;
338             break;
339         }
340         mac->size = outMac.size;
341     } while (0);
342 
343     HksFreeParamSet(&paramSet);
344     return ret;
345 }
346 
CmKeyOpImportKey(const struct CmBlob * alias,const struct CmKeyProperties * properties,const struct CmBlob * keyPair)347 int32_t CmKeyOpImportKey(const struct CmBlob *alias, const struct CmKeyProperties *properties,
348     const struct CmBlob *keyPair)
349 {
350     uint32_t huksAuthStorageLevel = TranslateToHuksLevel(properties->level);
351     struct HksParam importKeyParams[] = {
352         { .tag = HKS_TAG_IMPORT_KEY_TYPE, .uint32Param = HKS_KEY_TYPE_KEY_PAIR },
353         { .tag = HKS_TAG_ALGORITHM, .uint32Param = properties->algType },
354         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = properties->keySize },
355         { .tag = HKS_TAG_PURPOSE, .uint32Param = properties->purpose },
356         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = huksAuthStorageLevel },
357     };
358 
359     struct HksParamSet *paramSet = NULL;
360     int32_t ret = ConstructParamSet(importKeyParams, sizeof(importKeyParams) / sizeof(struct HksParam), &paramSet,
361         properties->level, alias);
362     if (ret != CM_SUCCESS) {
363         CM_LOG_E("construct import key paramSet failed");
364         return CMR_ERROR_KEY_IMPORT_PARAM_FAILED;
365     }
366 
367     struct HksBlob keyAlias = { alias->size, alias->data };
368     struct HksBlob key = { keyPair->size, keyPair->data };
369 
370     uint8_t encodeBuf[MAX_LEN_BASE64URL_SHA256] = { 0 };
371     struct CmBlob encodeTarget = { sizeof(encodeBuf), encodeBuf };
372     ret = GetKeyAlias(&keyAlias, &encodeTarget);
373     if (ret != CM_SUCCESS) {
374         HksFreeParamSet(&paramSet);
375         CM_LOG_E("get keyalias failed");
376         return ret;
377     }
378 
379     ret = HksImportKey(&keyAlias, paramSet, &key);
380     HksFreeParamSet(&paramSet);
381     if (ret != HKS_SUCCESS) {
382         CM_LOG_E("hks import key failed, ret = %d", ret);
383         return CMR_ERROR_KEY_IMPORT_FAILED;
384     }
385     return CM_SUCCESS;
386 }
387 
FillKeySpec(const struct HksParamSet * paramSet,struct CmKeyProperties * spec)388 static void FillKeySpec(const struct HksParamSet *paramSet, struct CmKeyProperties *spec)
389 {
390     for (uint32_t i = 0; i < paramSet->paramsCnt; ++i) {
391         switch (paramSet->params[i].tag) {
392             case HKS_TAG_ALGORITHM:
393                 spec->algType = paramSet->params[i].uint32Param;
394                 break;
395             case HKS_TAG_KEY_SIZE:
396                 spec->keySize = paramSet->params[i].uint32Param;
397                 break;
398             default:
399                 break;
400         }
401     }
402 }
403 
TranslateToHuksProperties(const struct CmSignatureSpec * spec,struct CmKeyProperties * keyProperties)404 static void TranslateToHuksProperties(const struct CmSignatureSpec *spec, struct CmKeyProperties *keyProperties)
405 {
406     keyProperties->purpose = INVALID_PROPERTY_VALUE;
407     keyProperties->padding = INVALID_PROPERTY_VALUE;
408     keyProperties->digest = INVALID_PROPERTY_VALUE;
409     keyProperties->level = INVALID_PROPERTY_VALUE;
410 
411     for (uint32_t i = 0; i < CM_ARRAY_SIZE(g_cmPurposeProperty); ++i) {
412         if (spec->purpose == g_cmPurposeProperty[i].cmProperty) {
413             keyProperties->purpose = g_cmPurposeProperty[i].huksProperty;
414             break;
415         }
416     }
417 
418     for (uint32_t i = 0; i < CM_ARRAY_SIZE(g_cmPaddingProperty); ++i) {
419         if (spec->padding == g_cmPaddingProperty[i].cmProperty) {
420             keyProperties->padding = g_cmPaddingProperty[i].huksProperty;
421             break;
422         }
423     }
424 
425     for (uint32_t i = 0; i < CM_ARRAY_SIZE(g_cmDigestProperty); ++i) {
426         if (spec->digest == g_cmDigestProperty[i].cmProperty) {
427             keyProperties->digest = g_cmDigestProperty[i].huksProperty;
428             break;
429         }
430     }
431 
432     CM_LOG_D("purpose[%u], digest[%u], padding[%u]", spec->purpose, spec->digest, spec->padding);
433 }
434 
GetKeyProperties(const struct CmBlob * commonUri,struct CmKeyProperties * keySpec,enum CmAuthStorageLevel level)435 static int32_t GetKeyProperties(const struct CmBlob *commonUri, struct CmKeyProperties *keySpec,
436     enum CmAuthStorageLevel level)
437 {
438     struct HksParamSet *outParamSet = (struct HksParamSet*)CMMalloc(DEFAULT_LEN_USED_FOR_MALLOC);
439     if (outParamSet == NULL) {
440         CM_LOG_E("malloc failed");
441         return CMR_ERROR_MALLOC_FAIL;
442     }
443     outParamSet->paramSetSize = DEFAULT_LEN_USED_FOR_MALLOC;
444 
445     uint32_t huksAuthStorageLevel = TranslateToHuksLevel(level);
446     struct HksParam getKeyParams[] = {
447         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = huksAuthStorageLevel },
448     };
449     struct HksParamSet *inParamSet = NULL;
450     int32_t ret = ConstructParamSet(getKeyParams, sizeof(getKeyParams) / sizeof(struct HksParam), &inParamSet,
451         level, commonUri);
452     if (ret != CM_SUCCESS) {
453         CM_LOG_E("Failed to construct get key inParamSet");
454         CM_FREE_PTR(outParamSet);
455         return CMR_ERROR_KEY_OPERATION_FAILED;
456     }
457 
458     struct HksBlob keyAlias = { commonUri->size, commonUri->data };
459     uint8_t encodeBuf[MAX_LEN_BASE64URL_SHA256] = { 0 };
460     struct CmBlob encodeTarget = { sizeof(encodeBuf), encodeBuf };
461     ret = GetKeyAlias(&keyAlias, &encodeTarget);
462     if (ret != CM_SUCCESS) {
463         CM_FREE_PTR(outParamSet);
464         HksFreeParamSet(&inParamSet);
465         CM_LOG_E("get keyalias failed");
466         return ret;
467     }
468 
469     ret = HksGetKeyParamSet(&keyAlias, inParamSet, outParamSet);
470 
471     HksFreeParamSet(&inParamSet);
472     if (ret != HKS_SUCCESS) {
473         CM_LOG_E("get paramSet from huks failed, ret = %d", ret);
474         CM_FREE_PTR(outParamSet);
475         return ret;
476     }
477 
478     FillKeySpec(outParamSet, keySpec);
479     CM_FREE_PTR(outParamSet);
480     return ret;
481 }
482 
AddParamsToParamSet(const struct CmBlob * commonUri,const struct CmSignatureSpec * spec,struct HksParamSet * paramSet,enum CmAuthStorageLevel level)483 static int32_t AddParamsToParamSet(const struct CmBlob *commonUri, const struct CmSignatureSpec *spec,
484     struct HksParamSet *paramSet, enum CmAuthStorageLevel level)
485 {
486     struct CmKeyProperties inputKeyProp = {0};
487     TranslateToHuksProperties(spec, &inputKeyProp);
488 
489     int32_t ret;
490     do {
491         struct CmKeyProperties keySpec = {0};
492         ret = GetKeyProperties(commonUri, &keySpec, level);
493         if (ret != HKS_SUCCESS) {
494             CM_LOG_E("Failed to get key properties, ret = %d", ret);
495             break;
496         }
497 
498         uint32_t huksAuthStorageLevel = TranslateToHuksLevel(level);
499         struct HksParam params[] = {
500             { .tag = HKS_TAG_ALGORITHM, .uint32Param = keySpec.algType },
501             { .tag = HKS_TAG_KEY_SIZE, .uint32Param = keySpec.keySize },
502             { .tag = HKS_TAG_PURPOSE, .uint32Param = inputKeyProp.purpose },
503             { .tag = HKS_TAG_DIGEST, .uint32Param = inputKeyProp.digest },
504             { .tag = HKS_TAG_PADDING, .uint32Param = inputKeyProp.padding },
505             { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = huksAuthStorageLevel },
506         };
507 
508         ret = AddUserIdParam(paramSet, level, commonUri);
509         if (ret != HKS_SUCCESS) {
510             CM_LOG_E("add userid param failed");
511             break;
512         }
513 
514         ret = HksAddParams(paramSet, params, sizeof(params) / sizeof(struct HksParam));
515         if (ret != HKS_SUCCESS) {
516             CM_LOG_E("add params failed");
517             break;
518         }
519 
520         /* In the case of RSA PSS-Padding, set the salt length to the digest length */
521         if ((keySpec.algType == HKS_ALG_RSA) && (inputKeyProp.padding == HKS_PADDING_PSS)) {
522             struct HksParam saltLenParam = {
523                 .tag = HKS_TAG_RSA_PSS_SALT_LEN_TYPE,
524                 .uint32Param = HKS_RSA_PSS_SALTLEN_DIGEST
525             };
526             ret = HksAddParams(paramSet, &saltLenParam, 1);
527             if (ret != HKS_SUCCESS) {
528                 CM_LOG_E("add saltLen tag failed");
529                 break;
530             }
531         }
532     } while (0);
533 
534     return (ret == HKS_SUCCESS) ? CM_SUCCESS : CMR_ERROR_KEY_OPERATION_FAILED;
535 }
536 
ConstructInitParamSet(const struct CmBlob * commonUri,const struct CmSignatureSpec * spec,struct HksParamSet ** outParamSet,enum CmAuthStorageLevel level)537 static int32_t ConstructInitParamSet(const struct CmBlob *commonUri, const struct CmSignatureSpec *spec,
538     struct HksParamSet **outParamSet, enum CmAuthStorageLevel level)
539 {
540     struct HksParamSet *paramSet = NULL;
541     int32_t ret = HksInitParamSet(&paramSet);
542     if (ret != HKS_SUCCESS) {
543         CM_LOG_E("init paramSet failed, ret = %d", ret);
544         return CMR_ERROR_KEY_OPERATION_FAILED;
545     }
546 
547     ret = AddParamsToParamSet(commonUri, spec, paramSet, level);
548     if (ret != CM_SUCCESS) {
549         CM_LOG_E("add params failed");
550         HksFreeParamSet(&paramSet);
551         return ret;
552     }
553 
554     ret = HksBuildParamSet(&paramSet);
555     if (ret != HKS_SUCCESS) {
556         CM_LOG_E("build params failed, ret = %d", ret);
557         HksFreeParamSet(&paramSet);
558         return CMR_ERROR_KEY_OPERATION_FAILED;
559     }
560 
561     *outParamSet = paramSet;
562     return CM_SUCCESS;
563 }
564 
ServiceSignVerifyUpdate(const struct CmBlob * handle,const struct HksParamSet * paramSet,const struct CmBlob * inData)565 static int32_t ServiceSignVerifyUpdate(const struct CmBlob *handle, const struct HksParamSet *paramSet,
566     const struct CmBlob *inData)
567 {
568     uint32_t temp = 0;
569     struct HksBlob tempOut = { sizeof(uint32_t), (uint8_t *)&temp };
570 
571     struct HksBlob handleHks = { handle->size, handle->data };
572     struct HksBlob inDataHks = { inData->size, inData->data };
573 
574     int32_t ret = HksUpdate(&handleHks, paramSet, &inDataHks, &tempOut);
575     if (ret != HKS_SUCCESS) {
576         CM_LOG_E("huks update fail, ret = %d", ret);
577         CmDeleteSession(handle);
578         return CMR_ERROR_KEY_UPDATE_FAILED;
579     }
580     return CM_SUCCESS;
581 }
582 
ServiceSignVerifyFinish(const struct CmBlob * handle,const struct HksParamSet * paramSet,const struct CmBlob * inData,struct CmBlob * outData)583 static int32_t ServiceSignVerifyFinish(const struct CmBlob *handle, const struct HksParamSet *paramSet,
584     const struct CmBlob *inData, struct CmBlob *outData)
585 {
586     struct HksBlob handleHks = { handle->size, handle->data };
587     struct HksBlob inDataHks = { inData->size, inData->data };
588     struct HksBlob outDataHks = { outData->size, outData->data };
589 
590     int32_t ret = HksFinish(&handleHks, paramSet, &inDataHks, &outDataHks);
591     CmDeleteSession(handle);
592     if (ret != HKS_SUCCESS) {
593         CM_LOG_E("huks finish fail, ret = %d", ret);
594         return CMR_ERROR_KEY_FINISH_FAILED;
595     }
596     outData->size = outDataHks.size;
597     return CM_SUCCESS;
598 }
599 
ServiceSignVerifyAbort(const struct CmBlob * handle,const struct HksParamSet * paramSet)600 static int32_t ServiceSignVerifyAbort(const struct CmBlob *handle, const struct HksParamSet *paramSet)
601 {
602     struct HksBlob handleHks = { handle->size, handle->data };
603 
604     int32_t ret = HksAbort(&handleHks, paramSet);
605     CmDeleteSession(handle);
606     if (ret != HKS_SUCCESS) {
607         CM_LOG_E("huks abort fail, ret = %d", ret);
608         return CMR_ERROR_KEY_ABORT_FAILED;
609     }
610     return CM_SUCCESS;
611 }
612 
CmKeyOpInit(const struct CmContext * context,const struct CmBlob * alias,const struct CmSignatureSpec * spec,enum CmAuthStorageLevel level,struct CmBlob * handle)613 int32_t CmKeyOpInit(const struct CmContext *context, const struct CmBlob *alias, const struct CmSignatureSpec *spec,
614     enum CmAuthStorageLevel level, struct CmBlob *handle)
615 {
616     struct HksParamSet *paramSet = NULL;
617     int32_t ret = ConstructInitParamSet(alias, spec, &paramSet, level);
618     if (ret != CM_SUCCESS) {
619         CM_LOG_E("construct init paramSet failed, ret = %d", ret);
620         return CMR_ERROR_KEY_INIT_PARAM_FAILED;
621     }
622 
623     do {
624         struct HksBlob keyAlias = { alias->size, alias->data };
625         uint8_t encodeBuf[MAX_LEN_BASE64URL_SHA256] = { 0 };
626         struct CmBlob encodeTarget = { sizeof(encodeBuf), encodeBuf };
627         ret = GetKeyAlias(&keyAlias, &encodeTarget);
628         if (ret != CM_SUCCESS) {
629             CM_LOG_E("get keyalias failed");
630             break;
631         }
632 
633         struct HksBlob handleOut = { handle->size, handle->data };
634         ret = HksInit(&keyAlias, paramSet, &handleOut, NULL);
635         if (ret != HKS_SUCCESS) {
636             CM_LOG_E("Huks init failed, ret = %d", ret);
637             ret = CMR_ERROR_KEY_INIT_FAILED;
638             break;
639         }
640         handle->size = handleOut.size;
641 
642         struct CmSessionNodeInfo info = { context->userId, context->uid, *alias };
643         ret = CmCreateSession(&info, handle, true);
644         if (ret != CM_SUCCESS) {
645             CM_LOG_E("create session failed, ret = %d", ret);
646             break;
647         }
648     } while (0);
649 
650     HksFreeParamSet(&paramSet);
651     return ret;
652 }
653 
CmKeyOpProcess(enum CmSignVerifyCmd cmdId,const struct CmContext * context,const struct CmBlob * handle,const struct CmBlob * inData,struct CmBlob * outData)654 int32_t CmKeyOpProcess(enum CmSignVerifyCmd cmdId, const struct CmContext *context, const struct CmBlob *handle,
655     const struct CmBlob *inData, struct CmBlob *outData)
656 {
657     struct CmSessionNodeInfo info = { context->userId, context->uid, { 0, NULL } };
658     if (CmQuerySession(&info, handle) == NULL) {
659         CM_LOG_E("session handle not exist");
660         return (cmdId == SIGN_VERIFY_CMD_ABORT) ? CM_SUCCESS : CMR_ERROR_NOT_EXIST;
661     }
662 
663     struct HksParam params[] = {
664         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
665     };
666     struct HksParamSet *paramSet = NULL;
667     /* There is no need to specify level and userid. Pass the default values instead. */
668     int32_t ret = ConstructParamSet(params, sizeof(params) / sizeof(struct HksParam), &paramSet,
669         CM_AUTH_STORAGE_LEVEL_EL1, NULL);
670     if (ret != CM_SUCCESS) {
671         CM_LOG_E("Failed to construct paramSet");
672         CmDeleteSession(handle);
673         return CMR_ERROR_KEY_PROCESS_PARAM_FAILED;
674     }
675 
676     switch (cmdId) {
677         case SIGN_VERIFY_CMD_UPDATE:
678             ret = ServiceSignVerifyUpdate(handle, paramSet, inData);
679             break;
680         case SIGN_VERIFY_CMD_FINISH:
681             ret = ServiceSignVerifyFinish(handle, paramSet, inData, outData);
682             break;
683         case SIGN_VERIFY_CMD_ABORT:
684             ret = ServiceSignVerifyAbort(handle, paramSet);
685             break;
686         default:
687             ret = CMR_ERROR_INVALID_ARGUMENT;
688             break;
689     }
690 
691     HksFreeParamSet(&paramSet);
692     return ret;
693 }
694 // LCOV_EXCL_STOP
695