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