• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #include "cipher.h"
17 #include "aes_openssl.h"
18 #include "config.h"
19 #include "aes_openssl_common.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 "utils.h"
27 
28 typedef HcfResult (*HcfCipherGeneratorSpiCreateFunc)(CipherAttr *, HcfCipherGeneratorSpi **);
29 
30 typedef struct {
31     HcfCipher super;
32     HcfCipherGeneratorSpi *spiObj;
33     char algoName[HCF_MAX_ALGO_NAME_LEN];
34 } CipherGenImpl;
35 
36 typedef struct {
37     HcfCipherGeneratorSpiCreateFunc createFunc;
38 } HcfCipherGenFuncSet;
39 
40 typedef struct {
41     HCF_ALG_VALUE algo;
42     HcfCipherGenFuncSet funcSet;
43 } HcfCipherGenAbility;
44 
45 static const HcfCipherGenAbility CIPHER_ABILITY_SET[] = {
46     { HCF_ALG_RSA, { HcfCipherRsaCipherSpiCreate } },
47     { HCF_ALG_AES, { HcfCipherAesGeneratorSpiCreate } },
48     { HCF_ALG_DES, { HcfCipherDesGeneratorSpiCreate } }
49 };
50 
SetKeyLength(HCF_ALG_PARA_VALUE value,void * cipher)51 static void SetKeyLength(HCF_ALG_PARA_VALUE value, void *cipher)
52 {
53     CipherAttr *cipherAttr = (CipherAttr *)cipher;
54 
55     cipherAttr->keySize = value;
56 
57     switch (value) {
58         case HCF_ALG_AES_128:
59         case HCF_ALG_AES_192:
60         case HCF_ALG_AES_256:
61             cipherAttr->algo = HCF_ALG_AES;
62             break;
63         case HCF_ALG_3DES_192:
64             cipherAttr->algo = HCF_ALG_DES;
65             break;
66         case HCF_OPENSSL_RSA_512:
67         case HCF_OPENSSL_RSA_768:
68         case HCF_OPENSSL_RSA_1024:
69         case HCF_OPENSSL_RSA_2048:
70         case HCF_OPENSSL_RSA_3072:
71         case HCF_OPENSSL_RSA_4096:
72         case HCF_OPENSSL_RSA_8192:
73             cipherAttr->algo = HCF_ALG_RSA;
74             break;
75         default:
76             LOGE("Invalid algo %u.", value);
77             break;
78     }
79 }
80 
SetMode(HCF_ALG_PARA_VALUE value,void * cipher)81 static void SetMode(HCF_ALG_PARA_VALUE value, void *cipher)
82 {
83     CipherAttr *cipherAttr = (CipherAttr *)cipher;
84     cipherAttr->mode = value ;
85 }
86 
SetPadding(HCF_ALG_PARA_VALUE value,void * cipher)87 static void SetPadding(HCF_ALG_PARA_VALUE value, void *cipher)
88 {
89     CipherAttr *cipherAttr = (CipherAttr *)cipher;
90     cipherAttr->paddingMode = value;
91 }
92 
SetDigest(HCF_ALG_PARA_VALUE value,CipherAttr * cipher)93 static void SetDigest(HCF_ALG_PARA_VALUE value, CipherAttr *cipher)
94 {
95     cipher->md = value;
96 }
97 
SetMgf1Digest(HCF_ALG_PARA_VALUE value,CipherAttr * cipher)98 static void SetMgf1Digest(HCF_ALG_PARA_VALUE value, CipherAttr *cipher)
99 {
100     cipher->mgf1md = value;
101 }
102 
OnSetParameter(const HcfParaConfig * config,void * cipher)103 static HcfResult OnSetParameter(const HcfParaConfig *config, void *cipher)
104 {
105     if ((config == NULL) || (cipher == NULL)) {
106         return HCF_INVALID_PARAMS;
107     }
108     HcfResult ret = HCF_SUCCESS;
109     LOGD("Set Parameter:%s", config->tag);
110     switch (config->paraType) {
111         case HCF_ALG_TYPE:
112         case HCF_ALG_KEY_TYPE:
113             SetKeyLength(config->paraValue, cipher);
114             break;
115         case HCF_ALG_MODE:
116             SetMode(config->paraValue, cipher);
117             break;
118         case HCF_ALG_PADDING_TYPE:
119             SetPadding(config->paraValue, cipher);
120             break;
121         case HCF_ALG_DIGEST:
122             SetDigest(config->paraValue, cipher);
123             break;
124         case HCF_ALG_MGF1_DIGEST:
125             SetMgf1Digest(config->paraValue, cipher);
126             break;
127         default:
128             ret = HCF_INVALID_PARAMS;
129             break;
130     }
131     return ret;
132 }
133 
GetCipherGeneratorClass(void)134 static const char *GetCipherGeneratorClass(void)
135 {
136     return "HcfCipherGenerator";
137 }
138 
GetAlogrithm(HcfCipher * self)139 const char *GetAlogrithm(HcfCipher *self)
140 {
141     if (self == NULL) {
142         LOGE("The input self ptr is NULL!");
143         return NULL;
144     }
145     if (!IsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
146         LOGE("Class is not match.");
147         return NULL;
148     }
149     return ((CipherGenImpl *)self)->algoName;
150 }
151 
CipherDestroy(HcfObjectBase * self)152 static void CipherDestroy(HcfObjectBase *self)
153 {
154     if (self == NULL) {
155         return;
156     }
157     if (!IsClassMatch(self, GetCipherGeneratorClass())) {
158         LOGE("Class not match.");
159         return;
160     }
161     CipherGenImpl *impl = (CipherGenImpl *)self;
162     HcfObjDestroy(impl->spiObj);
163     HcfFree(impl);
164 }
165 
CipherInit(HcfCipher * self,enum HcfCryptoMode opMode,HcfKey * key,HcfParamsSpec * params)166 static HcfResult CipherInit(HcfCipher *self, enum HcfCryptoMode opMode,
167     HcfKey *key, HcfParamsSpec *params)
168 {
169     if (self == NULL || key == NULL) { /* params maybe is NULL */
170         LOGE("Invalid input parameter.");
171         return HCF_INVALID_PARAMS;
172     }
173     if (!IsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
174         LOGE("Class is not match.");
175         return HCF_INVALID_PARAMS;
176     }
177     CipherGenImpl *impl = (CipherGenImpl *)self;
178     return impl->spiObj->init(impl->spiObj, opMode, key, params);
179 }
180 
CipherUpdate(HcfCipher * self,HcfBlob * input,HcfBlob * output)181 static HcfResult CipherUpdate(HcfCipher *self, HcfBlob *input, HcfBlob *output)
182 {
183     if ((self == NULL) || (input == NULL) || (output == NULL)) {
184         LOGE("Invalid input parameter.");
185         return HCF_INVALID_PARAMS;
186     }
187     if (!IsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
188         LOGE("Class is not match.");
189         return HCF_INVALID_PARAMS;
190     }
191     CipherGenImpl *impl = (CipherGenImpl *)self;
192     return impl->spiObj->update(impl->spiObj, input, output);
193 }
194 
CipherFinal(HcfCipher * self,HcfBlob * input,HcfBlob * output)195 static HcfResult CipherFinal(HcfCipher *self, HcfBlob *input, HcfBlob *output)
196 {
197     if ((self == NULL) || (output == NULL)) {
198         LOGE("Invalid input parameter!");
199         return HCF_INVALID_PARAMS;
200     }
201     if (!IsClassMatch((HcfObjectBase *)self, GetCipherGeneratorClass())) {
202         LOGE("Class is not match.");
203         return HCF_INVALID_PARAMS;
204     }
205     CipherGenImpl *impl = (CipherGenImpl *)self;
206     return impl->spiObj->doFinal(impl->spiObj, input, output);
207 }
208 
InitCipher(HcfCipherGeneratorSpi * spiObj,CipherGenImpl * cipher)209 static void InitCipher(HcfCipherGeneratorSpi *spiObj, CipherGenImpl *cipher)
210 {
211     cipher->super.init = CipherInit;
212     cipher->super.update = CipherUpdate;
213     cipher->super.doFinal = CipherFinal;
214     cipher->super.getAlgorithm = GetAlogrithm;
215     cipher->super.base.destroy = CipherDestroy;
216     cipher->super.base.getClass = GetCipherGeneratorClass;
217 }
218 
FindAbility(CipherAttr * attr)219 static const HcfCipherGenFuncSet *FindAbility(CipherAttr *attr)
220 {
221     if (attr == NULL) {
222         return NULL;
223     }
224     for (uint32_t i = 0; i < sizeof(CIPHER_ABILITY_SET) / sizeof(HcfCipherGenAbility); i++) {
225         if (CIPHER_ABILITY_SET[i].algo == attr->algo) {
226             return &(CIPHER_ABILITY_SET[i].funcSet);
227         }
228     }
229     LOGE("Algo not support! [Algo]: %d", attr->algo);
230     return NULL;
231 }
232 
HcfCipherCreate(const char * transformation,HcfCipher ** returnObj)233 HcfResult HcfCipherCreate(const char *transformation, HcfCipher **returnObj)
234 {
235     CipherAttr attr = {0};
236     if (!IsStrValid(transformation, HCF_MAX_ALGO_NAME_LEN) || (returnObj == NULL)) {
237         LOGE("Invalid input params while creating cipher!");
238         return HCF_INVALID_PARAMS;
239     }
240     if (ParseAndSetParameter(transformation, (void *)&attr, OnSetParameter) != HCF_SUCCESS) {
241         LOGE("ParseAndSetParameter failed!");
242         return HCF_NOT_SUPPORT;
243     }
244 
245     const HcfCipherGenFuncSet *funcSet = FindAbility(&attr);
246     if (funcSet == NULL) {
247         LOGE("FindAbility failed!");
248         return HCF_NOT_SUPPORT;
249     }
250     CipherGenImpl *returnGenerator = (CipherGenImpl *)HcfMalloc(sizeof(CipherGenImpl), 0);
251     if (returnGenerator == NULL) {
252         LOGE("failed to allocate returnGenerator memory!");
253         return HCF_ERR_MALLOC;
254     }
255     if (strcpy_s(returnGenerator->algoName, HCF_MAX_ALGO_NAME_LEN, transformation) != EOK) {
256         LOGE("Failed to copy algoName!");
257         HcfFree(returnGenerator);
258         return HCF_ERR_COPY;
259     }
260     HcfCipherGeneratorSpi *spiObj = NULL;
261     HcfResult res = funcSet->createFunc(&attr, &spiObj);
262     if (res != HCF_SUCCESS) {
263         LOGE("Failed to create spi object!");
264         HcfFree(returnGenerator);
265         return res;
266     }
267     returnGenerator->spiObj = spiObj;
268     InitCipher(spiObj, returnGenerator);
269 
270     *returnObj = (HcfCipher *)returnGenerator;
271     return res;
272 }
273