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