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