• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #ifdef HKS_CONFIG_FILE
17 #include HKS_CONFIG_FILE
18 #else
19 #include "hks_config.h"
20 #endif
21 
22 #include "hks_crypto_adapter.h"
23 
24 #include <stddef.h>
25 
26 #include "hks_common_check.h"
27 #include "hks_log.h"
28 #include "hks_mem.h"
29 #include "hks_param.h"
30 #include "hks_template.h"
31 #include "securec.h"
32 
HksFillKeySpec(const struct HksParamSet * paramSet,struct HksKeySpec * spec)33 void HksFillKeySpec(const struct HksParamSet *paramSet, struct HksKeySpec *spec)
34 {
35     for (uint32_t i = 0; i < paramSet->paramsCnt; i++) {
36         switch (paramSet->params[i].tag) {
37             case HKS_TAG_ALGORITHM:
38                 spec->algType = paramSet->params[i].uint32Param;
39                 break;
40             case HKS_TAG_KEY_SIZE:
41                 spec->keyLen = paramSet->params[i].uint32Param;
42                 break;
43             default:
44                 break;
45         }
46     }
47 }
48 
HksFillUsageSpec(const struct HksParamSet * paramSet,struct HksUsageSpec * usageSpec)49 void HksFillUsageSpec(const struct HksParamSet *paramSet, struct HksUsageSpec *usageSpec)
50 {
51     for (uint32_t i = 0; i < paramSet->paramsCnt; i++) {
52         switch (paramSet->params[i].tag) {
53             case HKS_TAG_ALGORITHM:
54                 usageSpec->algType = paramSet->params[i].uint32Param;
55                 break;
56             case HKS_TAG_PADDING:
57                 usageSpec->padding = paramSet->params[i].uint32Param;
58                 break;
59             case HKS_TAG_DIGEST:
60                 usageSpec->digest = paramSet->params[i].uint32Param;
61                 break;
62             case HKS_TAG_BLOCK_MODE:
63                 usageSpec->mode = paramSet->params[i].uint32Param;
64                 break;
65             case HKS_TAG_PURPOSE:
66                 usageSpec->purpose = paramSet->params[i].uint32Param;
67                 break;
68             default:
69                 break;
70         }
71     }
72     usageSpec->algParam = NULL;
73 }
74 
HksFreeUsageSpec(struct HksUsageSpec ** usageSpec)75 void HksFreeUsageSpec(struct HksUsageSpec **usageSpec)
76 {
77     if ((usageSpec == NULL) || (*usageSpec == NULL)) {
78         return;
79     }
80 
81     if ((*usageSpec)->algParam != NULL) {
82         HKS_FREE_PTR((*usageSpec)->algParam);
83     }
84     HKS_FREE_PTR(*usageSpec);
85 }
86 
HksFillKeyDerivationParam(const struct HksParamSet * paramSet,struct HksKeyDerivationParam * param)87 void HksFillKeyDerivationParam(const struct HksParamSet *paramSet, struct HksKeyDerivationParam *param)
88 {
89     for (uint32_t i = 0; i < paramSet->paramsCnt; i++) {
90         switch (paramSet->params[i].tag) {
91             case HKS_TAG_DIGEST:
92                 param->digestAlg = paramSet->params[i].uint32Param;
93                 break;
94             case HKS_TAG_SALT:
95                 param->salt = paramSet->params[i].blob;
96                 break;
97             case HKS_TAG_INFO:
98                 param->info = paramSet->params[i].blob;
99                 break;
100             case HKS_TAG_ITERATION:
101                 param->iterations = paramSet->params[i].uint32Param;
102                 break;
103             default:
104                 break;
105         }
106     }
107 }
108 
HksFillAeadParam(const struct HksParamSet * paramSet,struct HksBlob * inputText,struct HksUsageSpec * usageSpec,bool isEncrypt)109 int32_t HksFillAeadParam(
110     const struct HksParamSet *paramSet, struct HksBlob *inputText, struct HksUsageSpec *usageSpec, bool isEncrypt)
111 {
112     struct HksParam *nonceParam = NULL;
113     int32_t ret = HksGetParam(paramSet, HKS_TAG_NONCE, &nonceParam);
114     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksFillAeadParam get nonce param failed!")
115 
116     struct HksParam *aadParam = NULL;
117     ret = HksGetParam(paramSet, HKS_TAG_ASSOCIATED_DATA, &aadParam);
118     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "HksFillAeadParam get aad param failed!")
119 
120     struct HksParam tagParam;
121     if (!isEncrypt) {
122         if (inputText->size <= HKS_AE_TAG_LEN) {
123             HKS_LOG_E("too small inputText size");
124             return HKS_ERROR_INVALID_ARGUMENT;
125         }
126         inputText->size -= HKS_AE_TAG_LEN;
127 
128         tagParam.blob.size = HKS_AE_TAG_LEN;
129         tagParam.blob.data = inputText->data + inputText->size;
130     }
131 
132     struct HksAeadParam *aeadParam = (struct HksAeadParam *)HksMalloc(sizeof(struct HksAeadParam));
133     HKS_IF_NULL_LOGE_RETURN(aeadParam, HKS_ERROR_MALLOC_FAIL, "aeadParam malloc failed!")
134 
135     if (!isEncrypt) {
136         aeadParam->tagDec = tagParam.blob;
137     } else {
138         aeadParam->tagLenEnc = HKS_AE_TAG_LEN;
139     }
140 
141     aeadParam->nonce = nonceParam->blob;
142     aeadParam->aad = aadParam->blob;
143     aeadParam->payloadLen = 0;
144     usageSpec->algParam = aeadParam;
145     return HKS_SUCCESS;
146 }
147 
HksFillIvParam(const struct HksParamSet * paramSet,struct HksUsageSpec * usageSpec)148 int32_t HksFillIvParam(const struct HksParamSet *paramSet, struct HksUsageSpec *usageSpec)
149 {
150     struct HksParam *ivParam = NULL;
151     int32_t ret = HksGetParam(paramSet, HKS_TAG_IV, &ivParam);
152     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "cipher get iv param failed!")
153 
154     struct HksCipherParam *param = (struct HksCipherParam *)HksMalloc(sizeof(struct HksCipherParam));
155     HKS_IF_NULL_LOGE_RETURN(param, HKS_ERROR_MALLOC_FAIL, "param malloc failed!")
156 
157     param->iv = ivParam->blob;
158     usageSpec->algParam = param;
159     return HKS_SUCCESS;
160 }
161 
HksIsAlgorithmSm4(const struct HksParamSet * paramSet)162 static bool HksIsAlgorithmSm4(const struct HksParamSet *paramSet)
163 {
164     struct HksParam *algParam = NULL;
165     int32_t ret = HksGetParam(paramSet, HKS_TAG_ALGORITHM, &algParam);
166     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, false, "check sm4 get alg param failed!")
167     return (algParam->uint32Param == HKS_ALG_SM4);
168 }
169 
HksBuildCipherUsageSpec(const struct HksParamSet * paramSet,bool isEncrypt,struct HksBlob * inputText,struct HksUsageSpec ** outUsageSpec)170 int32_t HksBuildCipherUsageSpec(
171     const struct HksParamSet *paramSet, bool isEncrypt, struct HksBlob *inputText, struct HksUsageSpec **outUsageSpec)
172 {
173     bool isAes = false;
174     bool isAeMode = false;
175     int32_t ret = HksCheckAesAeMode(paramSet, &isAes, &isAeMode);
176     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get aeMode failed!")
177 
178     struct HksUsageSpec *usageSpec = (struct HksUsageSpec *)HksMalloc(sizeof(struct HksUsageSpec));
179     HKS_IF_NULL_LOGE_RETURN(usageSpec, HKS_ERROR_MALLOC_FAIL, "cipher usageSpec malloc failed!")
180 
181     HksFillUsageSpec(paramSet, usageSpec);
182 
183     if (usageSpec->algType == HKS_ALG_RSA && usageSpec->digest == HKS_DIGEST_NONE) {
184         usageSpec->digest = HKS_DIGEST_SHA1;
185     }
186 
187     if (HksIsAlgorithmSm4(paramSet)) { // is sm4
188         ret = HksFillIvParam(paramSet, usageSpec);
189     } else if (!isAes) { // not sm4, not aes
190         *outUsageSpec = usageSpec;
191         return HKS_SUCCESS;
192     } else if (isAeMode) { // is aes, is ae mode
193         ret = HksFillAeadParam(paramSet, inputText, usageSpec, isEncrypt);
194     } else { // is aes, not ae mode
195         ret = HksFillIvParam(paramSet, usageSpec);
196     }
197 
198     if (ret != HKS_SUCCESS) {
199         HksFreeUsageSpec(&usageSpec);
200         HKS_LOG_E("fill[%" LOG_PUBLIC "x] param failed!", isAeMode);
201         return ret;
202     }
203 
204     *outUsageSpec = usageSpec;
205     return HKS_SUCCESS;
206 }
207 
HksGetEncryptAeTag(const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData,struct HksBlob * tagAead)208 int32_t HksGetEncryptAeTag(
209     const struct HksParamSet *paramSet, const struct HksBlob *inData, struct HksBlob *outData, struct HksBlob *tagAead)
210 {
211     bool isAes = false;
212     bool isAeMode = false;
213     int32_t ret = HksCheckAesAeMode(paramSet, &isAes, &isAeMode);
214     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get aeMode failed!")
215 
216     if ((!isAes) || (!isAeMode)) {
217         tagAead->data = NULL;
218         tagAead->size = 0;
219         return HKS_SUCCESS;
220     }
221 
222     if (outData->size < (inData->size + HKS_AE_TAG_LEN)) {
223         HKS_LOG_E("too small out buf!");
224         return HKS_ERROR_INVALID_ARGUMENT;
225     }
226 
227     tagAead->data = outData->data + inData->size;
228     tagAead->size = HKS_AE_TAG_LEN;
229     return HKS_SUCCESS;
230 }
231 
232 #ifndef _CUT_AUTHENTICATE_
SetCurve25519KeyMaterial(bool isPubKey,const struct HksBlob * keyIn,struct HksBlob * keyOut)233 static int32_t SetCurve25519KeyMaterial(bool isPubKey, const struct HksBlob *keyIn, struct HksBlob *keyOut)
234 {
235     struct KeyMaterial25519 curve25519Km = {HKS_ALG_ED25519, 0, 0, 0, 0};
236     curve25519Km.keySize = HKS_CURVE25519_KEY_SIZE_256;
237     curve25519Km.reserved = 0;
238 
239     uint32_t offset = sizeof(struct KeyMaterial25519);
240     if (isPubKey) {
241         curve25519Km.pubKeySize = keyIn->size;
242         curve25519Km.priKeySize = 0;
243     } else {
244         curve25519Km.pubKeySize = 0;
245         curve25519Km.priKeySize = keyIn->size;
246     }
247 
248     keyOut->size = sizeof(struct KeyMaterial25519) + curve25519Km.pubKeySize + curve25519Km.priKeySize;
249     keyOut->data = (uint8_t *)HksMalloc(keyOut->size);
250     HKS_IF_NULL_RETURN(keyOut->data, HKS_ERROR_MALLOC_FAIL)
251 
252     (void)memcpy_s(keyOut->data, keyOut->size, &curve25519Km, sizeof(struct KeyMaterial25519));
253 
254     (void)memcpy_s(keyOut->data + offset, keyOut->size - offset, keyIn->data, keyIn->size);
255 
256     return HKS_SUCCESS;
257 }
258 
CheckCurve25519KeySize(const struct HksBlob * keyIn)259 static int32_t CheckCurve25519KeySize(const struct HksBlob *keyIn)
260 {
261     if (keyIn->size < sizeof(struct KeyMaterial25519)) {
262         HKS_LOG_E("keyIn buffer too small");
263         return HKS_ERROR_INVALID_ARGUMENT;
264     }
265 
266     struct KeyMaterial25519 *keyMaterial = (struct KeyMaterial25519 *)keyIn->data;
267 
268     /* input pubKeySize and priKeySize of keyMaterial have been guaranteed that the addition will not overflow */
269     if (keyIn->size < (sizeof(struct KeyMaterial25519) + keyMaterial->pubKeySize + keyMaterial->priKeySize)) {
270         HKS_LOG_E("keyIn is not a valid key material");
271         return HKS_ERROR_INVALID_ARGUMENT;
272     }
273 
274     return HKS_SUCCESS;
275 }
276 
CheckFormatCurve25519Key(const struct HksBlob * keyIn,struct HksParamSet * paramSetOut)277 static int32_t CheckFormatCurve25519Key(const struct HksBlob *keyIn, struct HksParamSet *paramSetOut)
278 {
279     int32_t ret = CheckCurve25519KeySize(keyIn);
280     HKS_IF_NOT_SUCC_RETURN(ret, ret)
281 
282     struct KeyMaterial25519 *keyMaterial = (struct KeyMaterial25519 *)keyIn->data;
283     uint32_t offset = sizeof(struct HksParamSet) + (sizeof(struct HksParam) << 1);
284     if (keyMaterial->pubKeySize > MAX_KEY_SIZE || keyMaterial->priKeySize > MAX_KEY_SIZE) {
285         HKS_LOG_E("pubKey or priKey buffer too big");
286         return HKS_ERROR_INVALID_ARGUMENT;
287     }
288     if (paramSetOut->paramSetSize < (offset + keyMaterial->pubKeySize + keyMaterial->priKeySize)) {
289         HKS_LOG_E("pubKey or priKey buffer too small");
290         return HKS_ERROR_BUFFER_TOO_SMALL;
291     }
292 
293     return HKS_SUCCESS;
294 }
295 
BuildParamSetOut(const struct HksParam * params,uint32_t paramCnt,struct HksParamSet * paramSetOut)296 static int32_t BuildParamSetOut(const struct HksParam *params, uint32_t paramCnt, struct HksParamSet *paramSetOut)
297 {
298     int32_t ret;
299     struct HksParamSet *tmpParamSetOut = NULL;
300 
301     ret = HksInitParamSet(&tmpParamSetOut);
302     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "init paramSet failed!")
303 
304     ret = HksAddParams(tmpParamSetOut, params, paramCnt);
305     if (ret != HKS_SUCCESS) {
306         HKS_LOG_E("add params failed");
307         HksFreeParamSet(&tmpParamSetOut);
308         return ret;
309     }
310 
311     ret = HksBuildParamSet(&tmpParamSetOut);
312     if (ret != HKS_SUCCESS) {
313         HKS_LOG_E("build paramSet failed");
314         HksFreeParamSet(&tmpParamSetOut);
315         return ret;
316     }
317 
318     if (memcpy_s(paramSetOut, paramSetOut->paramSetSize, tmpParamSetOut, tmpParamSetOut->paramSetSize) != EOK) {
319         HksFreeParamSet(&tmpParamSetOut);
320         HKS_LOG_E("memcpy paramSet out failed, paramSetOut size = %" LOG_PUBLIC "u", paramSetOut->paramSetSize);
321         return HKS_ERROR_INSUFFICIENT_MEMORY;
322     }
323 
324     paramSetOut->paramSetSize = tmpParamSetOut->paramSetSize;
325     HksFreeParamSet(&tmpParamSetOut);
326     return HksFreshParamSet(paramSetOut, false);
327 }
328 
FormatCurve25519Key(const struct HksBlob * keyIn,struct HksParamSet * paramSetOut)329 static int32_t FormatCurve25519Key(const struct HksBlob *keyIn, struct HksParamSet *paramSetOut)
330 {
331     int32_t ret = CheckFormatCurve25519Key(keyIn, paramSetOut);
332     HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "check curve 25519 key failed")
333 
334     struct KeyMaterial25519 *keyMaterial = (struct KeyMaterial25519 *)keyIn->data;
335     struct HksParam params[] = {
336         {
337             .tag = HKS_TAG_ASYMMETRIC_PUBLIC_KEY_DATA,
338             .blob = { keyMaterial->pubKeySize, keyIn->data + sizeof(struct KeyMaterial25519) },
339         },
340         {
341             .tag = HKS_TAG_ASYMMETRIC_PRIVATE_KEY_DATA,
342             .blob = { keyMaterial->priKeySize,
343                 keyIn->data + sizeof(struct KeyMaterial25519) + keyMaterial->pubKeySize },
344         },
345     };
346 
347     return BuildParamSetOut(params, HKS_ARRAY_SIZE(params), paramSetOut);
348 }
349 
GetCurve25519FromKeyMaterial(const bool isPubKey,const struct HksBlob * keyMaterial,struct HksBlob * keyOut)350 int32_t GetCurve25519FromKeyMaterial(const bool isPubKey, const struct HksBlob *keyMaterial,
351     struct HksBlob *keyOut)
352 {
353     int32_t ret = CheckCurve25519KeySize(keyMaterial);
354     HKS_IF_NOT_SUCC_RETURN(ret, ret)
355 
356     const struct KeyMaterial25519 *km = (struct KeyMaterial25519 *)(keyMaterial->data);
357 
358     uint32_t size = (isPubKey ? km->pubKeySize : km->priKeySize);
359     if (size == 0) {
360         HKS_LOG_E("get key material size invalid, pubSize = %" LOG_PUBLIC "u, priSize = %" LOG_PUBLIC "u",
361             km->pubKeySize, km->priKeySize);
362         return HKS_ERROR_INVALID_KEY_INFO;
363     }
364     uint8_t *buffer = (uint8_t *)HksMalloc(size);
365     HKS_IF_NULL_RETURN(buffer, HKS_ERROR_MALLOC_FAIL)
366 
367     uint32_t offset = sizeof(struct KeyMaterial25519);
368     uint8_t *tmp = (isPubKey ? (keyMaterial->data + offset) : (keyMaterial->data + offset + km->pubKeySize));
369     (void)memcpy_s(buffer, size, tmp, size);
370 
371     keyOut->data = buffer;
372     keyOut->size = size;
373     return HKS_SUCCESS;
374 }
375 
376 #ifdef HKS_SUPPORT_AES_C
FormatAesKey(const struct HksBlob * keyIn,struct HksParamSet * paramSetOut)377 static int32_t FormatAesKey(const struct HksBlob *keyIn, struct HksParamSet *paramSetOut)
378 {
379     struct HksParam params[] = {
380         {
381             .tag = HKS_TAG_SYMMETRIC_KEY_DATA,
382             .blob = { keyIn->size, keyIn->data },
383         },
384     };
385     return BuildParamSetOut(params, HKS_ARRAY_SIZE(params), paramSetOut);
386 }
387 #endif
388 
389 #if defined(HKS_SUPPORT_RSA_C) && defined(HKS_SUPPORT_RSA_GENERATE_KEY)
FormatRsaKey(const struct HksBlob * keyIn,struct HksParamSet * paramSetOut)390 static int32_t FormatRsaKey(const struct HksBlob *keyIn, struct HksParamSet *paramSetOut)
391 {
392     if (keyIn->size < sizeof(struct KeyMaterialRsa)) {
393         return HKS_ERROR_INVALID_ARGUMENT;
394     }
395 
396     struct KeyMaterialRsa *keyMaterial = (struct KeyMaterialRsa *)keyIn->data;
397     uint32_t publicKeySize = sizeof(struct KeyMaterialRsa) + keyMaterial->nSize + keyMaterial->eSize;
398     if (keyIn->size < publicKeySize) {
399         HKS_LOG_E("invalid key info.");
400         return HKS_ERROR_INVALID_KEY_INFO;
401     }
402 
403     uint8_t *publicKey = (uint8_t *)HksMalloc(publicKeySize);
404     HKS_IF_NULL_LOGE_RETURN(publicKey, HKS_ERROR_MALLOC_FAIL, "malloc public key failed.")
405 
406     (void)memcpy_s(publicKey, publicKeySize, keyIn->data, publicKeySize);
407     ((struct KeyMaterialRsa *)publicKey)->dSize = 0;
408 
409     struct HksParam params[] = {
410         {
411             .tag = HKS_TAG_ASYMMETRIC_PUBLIC_KEY_DATA,
412             .blob = { publicKeySize, publicKey },
413         },
414         {
415             .tag = HKS_TAG_ASYMMETRIC_PRIVATE_KEY_DATA,
416             .blob = { keyIn->size, keyIn->data },
417         },
418     };
419     int32_t ret = BuildParamSetOut(params, HKS_ARRAY_SIZE(params), paramSetOut);
420     (void)memset_s(publicKey, publicKeySize, 0, publicKeySize);
421     HksFree(publicKey);
422     return ret;
423 }
424 #endif
425 
426 #if defined(HKS_SUPPORT_HMAC_C) && defined(HKS_SUPPORT_HMAC_GENERATE_KEY)
FormatHmacKey(const struct HksBlob * keyIn,struct HksParamSet * paramSetOut)427 static int32_t FormatHmacKey(const struct HksBlob *keyIn, struct HksParamSet *paramSetOut)
428 {
429     struct HksParam params[] = {
430         {
431             .tag = HKS_TAG_SYMMETRIC_KEY_DATA,
432             .blob = { keyIn->size, keyIn->data },
433         },
434     };
435     return BuildParamSetOut(params, HKS_ARRAY_SIZE(params), paramSetOut);
436 }
437 #endif
438 
439 #if defined(HKS_SUPPORT_DSA_C) && defined(HKS_SUPPORT_DSA_GENERATE_KEY)
FormatDsaKey(const struct HksBlob * keyIn,struct HksParamSet * paramSetOut)440 static int32_t FormatDsaKey(const struct HksBlob *keyIn, struct HksParamSet *paramSetOut)
441 {
442     if (keyIn->size < sizeof(struct KeyMaterialDsa)) {
443         return HKS_ERROR_INVALID_ARGUMENT;
444     }
445 
446     struct KeyMaterialDsa *keyMaterial = (struct KeyMaterialDsa *)keyIn->data;
447     uint32_t publicKeySize = sizeof(struct KeyMaterialDsa) + keyMaterial->ySize + keyMaterial->pSize +
448                              keyMaterial->qSize + keyMaterial->gSize;
449     if (keyIn->size < publicKeySize) {
450         HKS_LOG_E("invalid key info.");
451         return HKS_ERROR_INVALID_KEY_INFO;
452     }
453 
454     uint8_t *publicKey = (uint8_t *)HksMalloc(publicKeySize);
455     HKS_IF_NULL_LOGE_RETURN(publicKey, HKS_ERROR_MALLOC_FAIL, "malloc key failed.")
456 
457     (void)memcpy_s(publicKey, publicKeySize, keyIn->data, sizeof(struct KeyMaterialDsa));
458     uint32_t inOffset = sizeof(struct KeyMaterialDsa);
459     uint32_t outOffset = sizeof(struct KeyMaterialDsa) + keyMaterial->xSize;
460     (void)memcpy_s(publicKey + inOffset, publicKeySize - inOffset, keyIn->data + outOffset, publicKeySize - inOffset);
461     ((struct KeyMaterialDsa *)publicKey)->xSize = 0;
462 
463     struct HksParam params[] = {
464         {
465             .tag = HKS_TAG_ASYMMETRIC_PUBLIC_KEY_DATA,
466             .blob = { publicKeySize, publicKey },
467         },
468         {
469             .tag = HKS_TAG_ASYMMETRIC_PRIVATE_KEY_DATA,
470             .blob = { keyIn->size, keyIn->data },
471         },
472     };
473 
474     int32_t ret = BuildParamSetOut(params, HKS_ARRAY_SIZE(params), paramSetOut);
475     (void)memset_s(publicKey, publicKeySize, 0, publicKeySize);
476     HksFree(publicKey);
477     return ret;
478 }
479 #endif
480 
481 #if defined(HKS_SUPPORT_ECC_C) && defined(HKS_SUPPORT_ECC_GENERATE_KEY)
FormatEccKey(const struct HksBlob * keyIn,struct HksParamSet * paramSetOut)482 static int32_t FormatEccKey(const struct HksBlob *keyIn, struct HksParamSet *paramSetOut)
483 {
484     if (keyIn->size < sizeof(struct KeyMaterialEcc)) {
485         return HKS_ERROR_INVALID_ARGUMENT;
486     }
487 
488     struct KeyMaterialEcc *keyMaterial = (struct KeyMaterialEcc *)keyIn->data;
489     uint32_t publicKeySize = sizeof(struct KeyMaterialEcc) + keyMaterial->xSize + keyMaterial->ySize;
490     if (keyIn->size < publicKeySize) {
491         HKS_LOG_E("invalid key info.");
492         return HKS_ERROR_INVALID_KEY_INFO;
493     }
494 
495     uint8_t *publicKey = (uint8_t *)HksMalloc(publicKeySize);
496     HKS_IF_NULL_LOGE_RETURN(publicKey, HKS_ERROR_MALLOC_FAIL, "malloc public key failed.")
497 
498     (void)memcpy_s(publicKey, publicKeySize, keyIn->data, publicKeySize);
499     ((struct KeyMaterialEcc *)publicKey)->zSize = 0;
500 
501     struct HksParam params[] = {
502         {
503             .tag = HKS_TAG_ASYMMETRIC_PUBLIC_KEY_DATA,
504             .blob = { publicKeySize, publicKey },
505         },
506         {
507             .tag = HKS_TAG_ASYMMETRIC_PRIVATE_KEY_DATA,
508             .blob = { keyIn->size, keyIn->data },
509         },
510     };
511     int32_t ret = BuildParamSetOut(params, HKS_ARRAY_SIZE(params), paramSetOut);
512     (void)memset_s(publicKey, publicKeySize, 0, publicKeySize);
513     HksFree(publicKey);
514     return ret;
515 }
516 #endif
517 
518 #if defined(HKS_SUPPORT_DH_C) && defined(HKS_SUPPORT_DH_GENERATE_KEY)
FormatDhKey(const struct HksBlob * keyIn,struct HksParamSet * paramSetOut)519 static int32_t FormatDhKey(const struct HksBlob *keyIn, struct HksParamSet *paramSetOut)
520 {
521     if (keyIn->size < sizeof(struct KeyMaterialDh)) {
522         return HKS_ERROR_INVALID_ARGUMENT;
523     }
524 
525     struct KeyMaterialDh *keyMaterial = (struct KeyMaterialDh *)keyIn->data;
526     uint32_t publicKeySize = sizeof(struct KeyMaterialDh) + keyMaterial->pubKeySize;
527     if (keyIn->size < publicKeySize) {
528         HKS_LOG_E("invalid key info.");
529         return HKS_ERROR_INVALID_KEY_INFO;
530     }
531 
532     uint8_t *publicKey = (uint8_t *)HksMalloc(publicKeySize);
533     HKS_IF_NULL_LOGE_RETURN(publicKey, HKS_ERROR_MALLOC_FAIL, "malloc public key failed.")
534 
535     (void)memcpy_s(publicKey, publicKeySize, keyIn->data, publicKeySize);
536     ((struct KeyMaterialDh *)publicKey)->priKeySize = 0;
537 
538     struct HksParam params[] = {
539         {
540             .tag = HKS_TAG_ASYMMETRIC_PUBLIC_KEY_DATA,
541             .blob = { publicKeySize, publicKey },
542         },
543         {
544             .tag = HKS_TAG_ASYMMETRIC_PRIVATE_KEY_DATA,
545             .blob = { keyIn->size, keyIn->data },
546         },
547     };
548     int32_t ret = BuildParamSetOut(params, HKS_ARRAY_SIZE(params), paramSetOut);
549     (void)memset_s(publicKey, publicKeySize, 0, publicKeySize);
550     HksFree(publicKey);
551     return ret;
552 }
553 #endif
554 
HksSetKeyToMaterial(uint32_t alg,bool isPubKey,const struct HksBlob * key,struct HksBlob * keyMaterial)555 int32_t HksSetKeyToMaterial(uint32_t alg, bool isPubKey, const struct HksBlob *key, struct HksBlob *keyMaterial)
556 {
557     switch (alg) {
558         case HKS_ALG_X25519:
559         case HKS_ALG_ED25519:
560             return SetCurve25519KeyMaterial(isPubKey, key, keyMaterial);
561         case HKS_ALG_RSA:
562         case HKS_ALG_DSA:
563         case HKS_ALG_ECC:
564         case HKS_ALG_ECDH:
565         case HKS_ALG_DH:
566             keyMaterial->size = key->size;
567             keyMaterial->data = (uint8_t *)HksMalloc(keyMaterial->size);
568             if (keyMaterial->data != NULL) {
569                 (void)memcpy_s(keyMaterial->data, keyMaterial->size, key->data, key->size);
570                 return HKS_SUCCESS;
571             } else {
572                 return HKS_ERROR_MALLOC_FAIL;
573             }
574             break;
575         default:
576             HKS_LOG_E("alg not support");
577             return HKS_ERROR_INVALID_ALGORITHM;
578     }
579 }
580 
HksGetKeyFromMaterial(uint32_t alg,bool isPubKey,const struct HksBlob * keyMaterial,struct HksBlob * key)581 int32_t HksGetKeyFromMaterial(uint32_t alg, bool isPubKey, const struct HksBlob *keyMaterial, struct HksBlob *key)
582 {
583     switch (alg) {
584         case HKS_ALG_X25519:
585         case HKS_ALG_ED25519:
586             return GetCurve25519FromKeyMaterial(isPubKey, keyMaterial, key);
587         default:
588             HKS_LOG_E("alg not support");
589             return HKS_ERROR_INVALID_ALGORITHM;
590     }
591 }
592 
HksFormatKeyFromMaterial(uint32_t alg,const struct HksBlob * keyMaterial,struct HksParamSet * paramSetOut)593 int32_t HksFormatKeyFromMaterial(uint32_t alg, const struct HksBlob *keyMaterial,
594     struct HksParamSet *paramSetOut)
595 {
596     switch (alg) {
597         case HKS_ALG_X25519:
598         case HKS_ALG_ED25519:
599             return FormatCurve25519Key(keyMaterial, paramSetOut);
600 #if defined(HKS_SUPPORT_AES_C) && defined(HKS_SUPPORT_AES_GENERATE_KEY)
601         case HKS_ALG_AES:
602             return FormatAesKey(keyMaterial, paramSetOut);
603 #endif
604 #if defined(HKS_SUPPORT_RSA_C) && defined(HKS_SUPPORT_RSA_GENERATE_KEY)
605         case HKS_ALG_RSA:
606             return FormatRsaKey(keyMaterial, paramSetOut);
607 #endif
608 #if defined(HKS_SUPPORT_HMAC_C) && defined(HKS_SUPPORT_HMAC_GENERATE_KEY)
609         case HKS_ALG_HMAC:
610             return FormatHmacKey(keyMaterial, paramSetOut);
611 #endif
612 #if defined(HKS_SUPPORT_DSA_C) && defined(HKS_SUPPORT_DSA_GENERATE_KEY)
613         case HKS_ALG_DSA:
614             return FormatDsaKey(keyMaterial, paramSetOut);
615 #endif
616 #if defined(HKS_SUPPORT_ECC_C) && defined(HKS_SUPPORT_ECC_GENERATE_KEY)
617         case HKS_ALG_ECC:
618         case HKS_ALG_ECDH:
619             return FormatEccKey(keyMaterial, paramSetOut);
620 #endif
621 #if defined(HKS_SUPPORT_DH_C) && defined(HKS_SUPPORT_DH_GENERATE_KEY)
622         case HKS_ALG_DH:
623             return FormatDhKey(keyMaterial, paramSetOut);
624 #endif
625         default:
626             HKS_LOG_E("alg not support");
627             return HKS_ERROR_INVALID_ALGORITHM;
628     }
629 }
630 #endif
631