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(¶mSet);
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(¶mSet);
74 return ret;
75 }
76
77 ret = HksBuildParamSet(¶mSet);
78 if (ret != HKS_SUCCESS) {
79 CM_LOG_E("build paramSet failed");
80 HksFreeParamSet(¶mSet);
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 ¶mSet);
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(¶mSet);
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), ¶mSet);
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(¶mSet);
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), ¶mSet);
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(¶mSet);
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), ¶mSet);
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(¶mSet);
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), ¶mSet);
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(¶mSet);
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(¶mSet);
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(¶mSet);
454 return ret;
455 }
456
457 ret = HksBuildParamSet(¶mSet);
458 if (ret != HKS_SUCCESS) {
459 CM_LOG_E("build params failed, ret = %d", ret);
460 HksFreeParamSet(¶mSet);
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, ¶mSet);
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(¶mSet);
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), ¶mSet);
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(¶mSet);
591 return ret;
592 }
593
594