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 "cipher.h"
17 #include "aes_openssl.h"
18 #include "des_openssl.h"
19 #include "config.h"
20 #include "securec.h"
21 #include "result.h"
22 #include "string.h"
23 #include "log.h"
24 #include "memory.h"
25 #include "cipher_rsa_openssl.h"
26 #include "cipher_sm2_openssl.h"
27 #include "sm4_openssl.h"
28 #include "utils.h"
29
30 typedef HcfResult (*HcfCipherGeneratorSpiCreateFunc)(CipherAttr *, HcfCipherGeneratorSpi **);
31
32 typedef struct {
33 HcfCipher super;
34 HcfCipherGeneratorSpi *spiObj;
35 char algoName[HCF_MAX_ALGO_NAME_LEN];
36 } CipherGenImpl;
37
38 typedef struct {
39 HcfCipherGeneratorSpiCreateFunc createFunc;
40 } HcfCipherGenFuncSet;
41
42 typedef struct {
43 HcfAlgValue algo;
44 HcfCipherGenFuncSet funcSet;
45 } HcfCipherGenAbility;
46
47 static const HcfCipherGenAbility CIPHER_ABILITY_SET[] = {
48 { HCF_ALG_RSA, { HcfCipherRsaCipherSpiCreate } },
49 { HCF_ALG_SM2, { HcfCipherSm2CipherSpiCreate } },
50 { HCF_ALG_AES, { HcfCipherAesGeneratorSpiCreate } },
51 { HCF_ALG_3DES, { HcfCipherDesGeneratorSpiCreate } },
52 { HCF_ALG_DES, { HcfCipherDesGeneratorSpiCreate } },
53 { HCF_ALG_SM4, { HcfCipherSm4GeneratorSpiCreate } }
54 };
55
SetKeyType(HcfAlgParaValue value,void * cipher)56 static void SetKeyType(HcfAlgParaValue value, void *cipher)
57 {
58 CipherAttr *cipherAttr = (CipherAttr *)cipher;
59
60 cipherAttr->keySize = 0;
61
62 switch (value) {
63 case HCF_ALG_AES_DEFAULT:
64 cipherAttr->algo = HCF_ALG_AES;
65 break;
66 case HCF_ALG_SM4_DEFAULT:
67 cipherAttr->algo = HCF_ALG_SM4;
68 break;
69 case HCF_ALG_DES_DEFAULT:
70 cipherAttr->algo = HCF_ALG_DES;
71 break;
72 case HCF_ALG_3DES_DEFAULT:
73 cipherAttr->algo = HCF_ALG_3DES;
74 break;
75 case HCF_ALG_RSA_DEFAULT:
76 cipherAttr->algo = HCF_ALG_RSA;
77 break;
78 case HCF_ALG_SM2_DEFAULT:
79 cipherAttr->algo = HCF_ALG_SM2;
80 break;
81 default:
82 LOGE("Invalid algo %{public}u.", value);
83 break;
84 }
85 }
86
SetKeyLength(HcfAlgParaValue value,void * cipher)87 static void SetKeyLength(HcfAlgParaValue value, void *cipher)
88 {
89 CipherAttr *cipherAttr = (CipherAttr *)cipher;
90
91 cipherAttr->keySize = value;
92
93 switch (value) {
94 case HCF_ALG_AES_128:
95 case HCF_ALG_AES_192:
96 case HCF_ALG_AES_256:
97 cipherAttr->algo = HCF_ALG_AES;
98 break;
99 case HCF_ALG_SM4_128:
100 cipherAttr->algo = HCF_ALG_SM4;
101 break;
102 case HCF_ALG_3DES_192:
103 cipherAttr->algo = HCF_ALG_3DES;
104 break;
105 case HCF_ALG_DES_64:
106 cipherAttr->algo = HCF_ALG_DES;
107 break;
108 case HCF_OPENSSL_RSA_512:
109 case HCF_OPENSSL_RSA_768:
110 case HCF_OPENSSL_RSA_1024:
111 case HCF_OPENSSL_RSA_2048:
112 case HCF_OPENSSL_RSA_3072:
113 case HCF_OPENSSL_RSA_4096:
114 case HCF_OPENSSL_RSA_8192:
115 cipherAttr->algo = HCF_ALG_RSA;
116 break;
117 case HCF_ALG_SM2_256:
118 cipherAttr->algo = HCF_ALG_SM2;
119 break;
120 default:
121 LOGE("Invalid algo %{public}u.", value);
122 break;
123 }
124 }
125
SetMode(HcfAlgParaValue value,void * cipher)126 static void SetMode(HcfAlgParaValue value, void *cipher)
127 {
128 CipherAttr *cipherAttr = (CipherAttr *)cipher;
129 cipherAttr->mode = value ;
130 }
131
SetPadding(HcfAlgParaValue value,void * cipher)132 static void SetPadding(HcfAlgParaValue value, void *cipher)
133 {
134 CipherAttr *cipherAttr = (CipherAttr *)cipher;
135 cipherAttr->paddingMode = value;
136 }
137
SetDigest(HcfAlgParaValue value,CipherAttr * cipher)138 static void SetDigest(HcfAlgParaValue value, CipherAttr *cipher)
139 {
140 cipher->md = value;
141 }
142
SetMgf1Digest(HcfAlgParaValue value,CipherAttr * cipher)143 static void SetMgf1Digest(HcfAlgParaValue value, CipherAttr *cipher)
144 {
145 cipher->mgf1md = value;
146 }
147
OnSetParameter(const HcfParaConfig * config,void * cipher)148 static HcfResult OnSetParameter(const HcfParaConfig *config, void *cipher)
149 {
150 if ((config == NULL) || (cipher == NULL)) {
151 LOGE("Invalid cipher params");
152 return HCF_INVALID_PARAMS;
153 }
154 HcfResult ret = HCF_SUCCESS;
155 LOGD("Set Parameter:%s", config->tag);
156 switch (config->paraType) {
157 case HCF_ALG_TYPE:
158 SetKeyType(config->paraValue, cipher);
159 break;
160 case HCF_ALG_KEY_TYPE:
161 SetKeyLength(config->paraValue, cipher);
162 break;
163 case HCF_ALG_MODE:
164 SetMode(config->paraValue, cipher);
165 break;
166 case HCF_ALG_PADDING_TYPE:
167 SetPadding(config->paraValue, cipher);
168 break;
169 case HCF_ALG_DIGEST:
170 SetDigest(config->paraValue, cipher);
171 break;
172 case HCF_ALG_MGF1_DIGEST:
173 SetMgf1Digest(config->paraValue, cipher);
174 break;
175 case HCF_ALG_TEXT_FORMAT:
176 if (config->paraValue == HCF_ALG_TEXT_FORMAT_C1C2C3) {
177 LOGE("Not Support C1C2C3 Format");
178 ret = HCF_INVALID_PARAMS;
179 }
180 break;
181 default:
182 ret = HCF_INVALID_PARAMS;
183 break;
184 }
185 return ret;
186 }
187
GetCipherGeneratorClass(void)188 static const char *GetCipherGeneratorClass(void)
189 {
190 return "HcfCipherGenerator";
191 }
192
GetAlgorithm(HcfCipher * self)193 static const char *GetAlgorithm(HcfCipher *self)
194 {
195 if (self == NULL) {
196 LOGE("The input self ptr is NULL!");
197 return NULL;
198 }
199 if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
200 LOGE("Class is not match.");
201 return NULL;
202 }
203 return ((CipherGenImpl *)self)->algoName;
204 }
205
CipherDestroy(HcfObjectBase * self)206 static void CipherDestroy(HcfObjectBase *self)
207 {
208 if (self == NULL) {
209 return;
210 }
211 if (!HcfIsClassMatch(self, GetCipherGeneratorClass())) {
212 LOGE("Class not match.");
213 return;
214 }
215 CipherGenImpl *impl = (CipherGenImpl *)self;
216 HcfObjDestroy(impl->spiObj);
217 impl->spiObj = NULL;
218 HcfFree(impl);
219 }
220
SetCipherSpecUint8Array(HcfCipher * self,CipherSpecItem item,HcfBlob pSource)221 static HcfResult SetCipherSpecUint8Array(HcfCipher *self, CipherSpecItem item, HcfBlob pSource)
222 {
223 // only implemented for OAEP_MGF1_PSRC_UINT8ARR
224 // if pSource == NULL or len == 0, it means cleaning the pSource
225 if (self == NULL) {
226 LOGE("Invalid input parameter.");
227 return HCF_INVALID_PARAMS;
228 }
229 if (item != OAEP_MGF1_PSRC_UINT8ARR) {
230 LOGE("Spec item not support.");
231 return HCF_INVALID_PARAMS;
232 }
233 if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
234 LOGE("Class not match.");
235 return HCF_INVALID_PARAMS;
236 }
237 CipherGenImpl *impl = (CipherGenImpl *)self;
238 return impl->spiObj->setCipherSpecUint8Array(impl->spiObj, item, pSource);
239 }
240
CheckCipherSpecString(CipherSpecItem item)241 static bool CheckCipherSpecString(CipherSpecItem item)
242 {
243 return ((item == OAEP_MD_NAME_STR) || (item == OAEP_MGF_NAME_STR) ||
244 (item == OAEP_MGF1_MD_STR) || (item == SM2_MD_NAME_STR));
245 }
246
GetCipherSpecString(HcfCipher * self,CipherSpecItem item,char ** returnString)247 static HcfResult GetCipherSpecString(HcfCipher *self, CipherSpecItem item, char **returnString)
248 {
249 if (self == NULL || returnString == NULL) {
250 LOGE("Invalid input parameter.");
251 return HCF_INVALID_PARAMS;
252 }
253 if (!CheckCipherSpecString(item)) {
254 LOGE("Spec item not support.");
255 return HCF_INVALID_PARAMS;
256 }
257 if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
258 LOGE("Class not match.");
259 return HCF_INVALID_PARAMS;
260 }
261 CipherGenImpl *impl = (CipherGenImpl *)self;
262 return impl->spiObj->getCipherSpecString(impl->spiObj, item, returnString);
263 }
264
GetCipherSpecUint8Array(HcfCipher * self,CipherSpecItem item,HcfBlob * returnUint8Array)265 static HcfResult GetCipherSpecUint8Array(HcfCipher *self, CipherSpecItem item, HcfBlob *returnUint8Array)
266 {
267 if (self == NULL || returnUint8Array == NULL) {
268 LOGE("Invalid input parameter.");
269 return HCF_INVALID_PARAMS;
270 }
271 if (item != OAEP_MGF1_PSRC_UINT8ARR) {
272 LOGE("Spec item not support.");
273 return HCF_INVALID_PARAMS;
274 }
275 if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
276 LOGE("Class not match.");
277 return HCF_INVALID_PARAMS;
278 }
279 CipherGenImpl *impl = (CipherGenImpl *)self;
280 return impl->spiObj->getCipherSpecUint8Array(impl->spiObj, item, returnUint8Array);
281 }
282
CipherInit(HcfCipher * self,enum HcfCryptoMode opMode,HcfKey * key,HcfParamsSpec * params)283 static HcfResult CipherInit(HcfCipher *self, enum HcfCryptoMode opMode,
284 HcfKey *key, HcfParamsSpec *params)
285 {
286 if (self == NULL || key == NULL) { /* params maybe is NULL */
287 LOGE("Invalid input parameter.");
288 return HCF_INVALID_PARAMS;
289 }
290 if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
291 LOGE("Class is not match.");
292 return HCF_INVALID_PARAMS;
293 }
294 CipherGenImpl *impl = (CipherGenImpl *)self;
295 return impl->spiObj->init(impl->spiObj, opMode, key, params);
296 }
297
CipherUpdate(HcfCipher * self,HcfBlob * input,HcfBlob * output)298 static HcfResult CipherUpdate(HcfCipher *self, HcfBlob *input, HcfBlob *output)
299 {
300 if ((self == NULL) || (input == NULL) || (output == NULL)) {
301 LOGE("Invalid input parameter.");
302 return HCF_INVALID_PARAMS;
303 }
304 if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
305 LOGE("Class is not match.");
306 return HCF_INVALID_PARAMS;
307 }
308 CipherGenImpl *impl = (CipherGenImpl *)self;
309 return impl->spiObj->update(impl->spiObj, input, output);
310 }
311
CipherFinal(HcfCipher * self,HcfBlob * input,HcfBlob * output)312 static HcfResult CipherFinal(HcfCipher *self, HcfBlob *input, HcfBlob *output)
313 {
314 if ((self == NULL) || (output == NULL)) {
315 LOGE("Invalid input parameter!");
316 return HCF_INVALID_PARAMS;
317 }
318 if (!HcfIsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
319 LOGE("Class is not match.");
320 return HCF_INVALID_PARAMS;
321 }
322 CipherGenImpl *impl = (CipherGenImpl *)self;
323 return impl->spiObj->doFinal(impl->spiObj, input, output);
324 }
325
InitCipher(HcfCipherGeneratorSpi * spiObj,CipherGenImpl * cipher)326 static void InitCipher(HcfCipherGeneratorSpi *spiObj, CipherGenImpl *cipher)
327 {
328 cipher->super.init = CipherInit;
329 cipher->super.update = CipherUpdate;
330 cipher->super.doFinal = CipherFinal;
331 cipher->super.getAlgorithm = GetAlgorithm;
332 cipher->super.base.destroy = CipherDestroy;
333 cipher->super.base.getClass = GetCipherGeneratorClass;
334 cipher->super.getCipherSpecString = GetCipherSpecString;
335 cipher->super.getCipherSpecUint8Array = GetCipherSpecUint8Array;
336 cipher->super.setCipherSpecUint8Array = SetCipherSpecUint8Array;
337 }
338
FindAbility(CipherAttr * attr)339 static const HcfCipherGenFuncSet *FindAbility(CipherAttr *attr)
340 {
341 if (attr == NULL) {
342 return NULL;
343 }
344 for (uint32_t i = 0; i < sizeof(CIPHER_ABILITY_SET) / sizeof(HcfCipherGenAbility); i++) {
345 if (CIPHER_ABILITY_SET[i].algo == attr->algo) {
346 return &(CIPHER_ABILITY_SET[i].funcSet);
347 }
348 }
349 LOGE("Algo not support! [Algo]: %{public}d", attr->algo);
350 return NULL;
351 }
352
HcfCipherCreate(const char * transformation,HcfCipher ** returnObj)353 HcfResult HcfCipherCreate(const char *transformation, HcfCipher **returnObj)
354 {
355 CipherAttr attr = {0};
356 if (!HcfIsStrValid(transformation, HCF_MAX_ALGO_NAME_LEN) || (returnObj == NULL)) {
357 LOGE("Invalid input params while creating cipher!");
358 return HCF_INVALID_PARAMS;
359 }
360 if (ParseAndSetParameter(transformation, (void *)&attr, OnSetParameter) != HCF_SUCCESS) {
361 LOGE("ParseAndSetParameter failed!");
362 return HCF_NOT_SUPPORT;
363 }
364
365 const HcfCipherGenFuncSet *funcSet = FindAbility(&attr);
366 if (funcSet == NULL) {
367 LOGE("FindAbility failed!");
368 return HCF_NOT_SUPPORT;
369 }
370 CipherGenImpl *returnGenerator = (CipherGenImpl *)HcfMalloc(sizeof(CipherGenImpl), 0);
371 if (returnGenerator == NULL) {
372 LOGE("failed to allocate returnGenerator memory!");
373 return HCF_ERR_MALLOC;
374 }
375 if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, transformation) != EOK) {
376 LOGE("Failed to copy algoName!");
377 HcfFree(returnGenerator);
378 returnGenerator = NULL;
379 return HCF_INVALID_PARAMS;
380 }
381 HcfCipherGeneratorSpi *spiObj = NULL;
382 HcfResult res = funcSet->createFunc(&attr, &spiObj);
383 if (res != HCF_SUCCESS) {
384 LOGE("Failed to create spi object!");
385 HcfFree(returnGenerator);
386 returnGenerator = NULL;
387 return res;
388 }
389 returnGenerator->spiObj = spiObj;
390 InitCipher(spiObj, returnGenerator);
391
392 *returnObj = (HcfCipher *)returnGenerator;
393 return res;
394 }
395