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