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