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