1 /*
2 * Copyright (C) 2022-2023 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 "asy_key_generator.h"
17
18 #include <securec.h>
19
20 #include "asy_key_generator_spi.h"
21 #include "config.h"
22 #include "ecc_asy_key_generator_openssl.h"
23 #include "params_parser.h"
24 #include "rsa_asy_key_generator_openssl.h"
25 #include "log.h"
26 #include "memory.h"
27 #include "utils.h"
28
29 typedef HcfResult (*HcfAsyKeyGeneratorSpiCreateFunc)(HcfAsyKeyGenParams *, HcfAsyKeyGeneratorSpi **);
30
31 typedef struct {
32 HcfAsyKeyGenerator base;
33
34 HcfAsyKeyGeneratorSpi *spiObj;
35
36 char algoName[HCF_MAX_ALGO_NAME_LEN];
37 } HcfAsyKeyGeneratorImpl;
38
39 typedef struct {
40 HCF_ALG_VALUE algo;
41
42 HcfAsyKeyGeneratorSpiCreateFunc createSpifunc;
43 } HcfAsyKeyGenAbility;
44
45 static const HcfAsyKeyGenAbility ASY_KEY_GEN_ABILITY_SET[] = {
46 { HCF_ALG_RSA, HcfAsyKeyGeneratorSpiRsaCreate },
47 { HCF_ALG_ECC, HcfAsyKeyGeneratorSpiEccCreate }
48 };
49
FindAbility(HcfAsyKeyGenParams * params)50 static HcfAsyKeyGeneratorSpiCreateFunc FindAbility(HcfAsyKeyGenParams *params)
51 {
52 for (uint32_t i = 0; i < sizeof(ASY_KEY_GEN_ABILITY_SET) / sizeof(ASY_KEY_GEN_ABILITY_SET[0]); i++) {
53 if (ASY_KEY_GEN_ABILITY_SET[i].algo == params->algo) {
54 return ASY_KEY_GEN_ABILITY_SET[i].createSpifunc;
55 }
56 }
57 LOGE("Algo not support! [Algo]: %d", params->algo);
58 return NULL;
59 }
60
SetPrimes(HCF_ALG_PARA_VALUE value,HcfAsyKeyGenParams * params)61 static void SetPrimes(HCF_ALG_PARA_VALUE value, HcfAsyKeyGenParams *params)
62 {
63 if (params == NULL) {
64 LOGE("params is null.");
65 return;
66 }
67 switch (value) {
68 case HCF_OPENSSL_PRIMES_2:
69 params->primes = (int32_t)HCF_RSA_PRIMES_SIZE_2;
70 break;
71 case HCF_OPENSSL_PRIMES_3:
72 params->primes = (int32_t)HCF_RSA_PRIMES_SIZE_3;
73 break;
74 case HCF_OPENSSL_PRIMES_4:
75 params->primes = (int32_t)HCF_RSA_PRIMES_SIZE_4;
76 break;
77 case HCF_OPENSSL_PRIMES_5:
78 params->primes = (int32_t)HCF_RSA_PRIMES_SIZE_5;
79 break;
80 default:
81 params->primes = (int32_t)HCF_RSA_PRIMES_SIZE_2; // default primes is 2
82 LOGD("user default primes 2");
83 break;
84 }
85 LOGD("Set primes:%d\n", params->primes);
86 }
87
SetKeyType(HCF_ALG_PARA_VALUE value,HcfAsyKeyGenParams * params)88 static void SetKeyType(HCF_ALG_PARA_VALUE value, HcfAsyKeyGenParams *params)
89 {
90 switch (value) {
91 case HCF_ALG_ECC_224:
92 case HCF_ALG_ECC_256:
93 case HCF_ALG_ECC_384:
94 case HCF_ALG_ECC_521:
95 params->bits = value;
96 params->algo = HCF_ALG_ECC;
97 break;
98 case HCF_OPENSSL_RSA_512:
99 params->bits = (int32_t)HCF_RSA_KEY_SIZE_512;
100 params->algo = HCF_ALG_RSA;
101 break;
102 case HCF_OPENSSL_RSA_768:
103 params->bits = (int32_t)HCF_RSA_KEY_SIZE_768;
104 params->algo = HCF_ALG_RSA;
105 break;
106 case HCF_OPENSSL_RSA_1024:
107 params->bits = (int32_t)HCF_RSA_KEY_SIZE_1024;
108 params->algo = HCF_ALG_RSA;
109 break;
110 case HCF_OPENSSL_RSA_2048:
111 params->bits = (int32_t)HCF_RSA_KEY_SIZE_2048;
112 params->algo = HCF_ALG_RSA;
113 break;
114 case HCF_OPENSSL_RSA_3072:
115 params->bits = (int32_t)HCF_RSA_KEY_SIZE_3072;
116 params->algo = HCF_ALG_RSA;
117 break;
118 case HCF_OPENSSL_RSA_4096:
119 params->bits = (int32_t)HCF_RSA_KEY_SIZE_4096;
120 params->algo = HCF_ALG_RSA;
121 break;
122 case HCF_OPENSSL_RSA_8192:
123 params->bits = (int32_t)HCF_RSA_KEY_SIZE_8192;
124 params->algo = HCF_ALG_RSA;
125 break;
126 default:
127 LOGE("there is not matched algorithm.");
128 break;
129 }
130 }
131
ParseAsyKeyGenParams(const HcfParaConfig * config,void * params)132 static HcfResult ParseAsyKeyGenParams(const HcfParaConfig* config, void *params)
133 {
134 if (config == NULL || params == NULL) {
135 return HCF_INVALID_PARAMS;
136 }
137 HcfResult ret = HCF_SUCCESS;
138 HcfAsyKeyGenParams *paramsObj = (HcfAsyKeyGenParams *)params;
139 LOGI("Set Parameter: %s", config->tag);
140 switch (config->paraType) {
141 case HCF_ALG_KEY_TYPE:
142 SetKeyType(config->paraValue, paramsObj);
143 break;
144 case HCF_ALG_PRIMES:
145 SetPrimes(config->paraValue, paramsObj);
146 break;
147 default:
148 ret = HCF_INVALID_PARAMS;
149 break;
150 }
151 return ret;
152 }
153
154 // export interfaces
GetAsyKeyGeneratorClass(void)155 static const char *GetAsyKeyGeneratorClass(void)
156 {
157 return "HcfAsyKeyGenerator";
158 }
159
GetAlgoName(HcfAsyKeyGenerator * self)160 static const char *GetAlgoName(HcfAsyKeyGenerator *self)
161 {
162 if (self == NULL) {
163 LOGE("The input self ptr is NULL!");
164 return NULL;
165 }
166 if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) {
167 return NULL;
168 }
169 return ((HcfAsyKeyGeneratorImpl *)self)->algoName;
170 }
171
ConvertKey(HcfAsyKeyGenerator * self,HcfParamsSpec * params,HcfBlob * pubKeyBlob,HcfBlob * priKeyBlob,HcfKeyPair ** returnKeyPair)172 static HcfResult ConvertKey(HcfAsyKeyGenerator *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob,
173 HcfBlob *priKeyBlob, HcfKeyPair **returnKeyPair)
174 {
175 if (self == NULL) {
176 LOGE("Invalid input parameter.");
177 return HCF_INVALID_PARAMS;
178 }
179 if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) {
180 return HCF_INVALID_PARAMS;
181 }
182 return ((HcfAsyKeyGeneratorImpl *)self)->spiObj->engineConvertKey(
183 ((HcfAsyKeyGeneratorImpl *)self)->spiObj, params, pubKeyBlob, priKeyBlob, returnKeyPair);
184 }
185
GenerateKeyPair(HcfAsyKeyGenerator * self,HcfParamsSpec * params,HcfKeyPair ** returnKeyPair)186 static HcfResult GenerateKeyPair(HcfAsyKeyGenerator *self, HcfParamsSpec *params,
187 HcfKeyPair **returnKeyPair)
188 {
189 if (self == NULL) {
190 LOGE("Invalid input parameter.");
191 return HCF_INVALID_PARAMS;
192 }
193 if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) {
194 return HCF_INVALID_PARAMS;
195 }
196 return ((HcfAsyKeyGeneratorImpl *)self)->spiObj->engineGenerateKeyPair(
197 ((HcfAsyKeyGeneratorImpl *)self)->spiObj, returnKeyPair);
198 }
199
DestroyAsyKeyGenerator(HcfObjectBase * self)200 static void DestroyAsyKeyGenerator(HcfObjectBase *self)
201 {
202 if (self == NULL) {
203 return;
204 }
205 if (!IsClassMatch((HcfObjectBase *)self, GetAsyKeyGeneratorClass())) {
206 return;
207 }
208 HcfAsyKeyGeneratorImpl *impl = (HcfAsyKeyGeneratorImpl *)self;
209 HcfObjDestroy(impl->spiObj);
210 impl->spiObj = NULL;
211 HcfFree(impl);
212 }
213
HcfAsyKeyGeneratorCreate(const char * algoName,HcfAsyKeyGenerator ** returnObj)214 HcfResult HcfAsyKeyGeneratorCreate(const char *algoName, HcfAsyKeyGenerator **returnObj)
215 {
216 if ((!IsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) {
217 return HCF_INVALID_PARAMS;
218 }
219
220 HcfAsyKeyGenParams params = { 0 };
221 if (ParseAndSetParameter(algoName, ¶ms, ParseAsyKeyGenParams) != HCF_SUCCESS) {
222 LOGE("Failed to parser parmas!");
223 return HCF_INVALID_PARAMS;
224 }
225
226 HcfAsyKeyGeneratorSpiCreateFunc createSpifunc = FindAbility(¶ms);
227 if (createSpifunc == NULL) {
228 return HCF_NOT_SUPPORT;
229 }
230
231 HcfAsyKeyGeneratorImpl *returnGenerator = (HcfAsyKeyGeneratorImpl *)HcfMalloc(sizeof(HcfAsyKeyGeneratorImpl), 0);
232 if (returnGenerator == NULL) {
233 LOGE("Failed to allocate returnGenerator memory!");
234 return HCF_ERR_MALLOC;
235 }
236 if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) {
237 LOGE("Failed to copy algoName!");
238 HcfFree(returnGenerator);
239 return HCF_ERR_COPY;
240 }
241 HcfAsyKeyGeneratorSpi *spiObj = NULL;
242 int32_t res = HCF_SUCCESS;
243 res = createSpifunc(¶ms, &spiObj);
244 if (res != HCF_SUCCESS) {
245 LOGE("Failed to create spi object!");
246 HcfFree(returnGenerator);
247 return res;
248 }
249 returnGenerator->base.base.destroy = DestroyAsyKeyGenerator;
250 returnGenerator->base.base.getClass = GetAsyKeyGeneratorClass;
251 returnGenerator->base.convertKey = ConvertKey;
252 returnGenerator->base.generateKeyPair = GenerateKeyPair;
253 returnGenerator->base.getAlgoName = GetAlgoName;
254 returnGenerator->spiObj = spiObj;
255 *returnObj = (HcfAsyKeyGenerator *)returnGenerator;
256 return HCF_SUCCESS;
257 }
258