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