• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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