1 /*
2 * Copyright (c) 2020-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 <stdlib.h>
17 #include "aes.h"
18 #include "base64.h"
19 #include "cipher.h"
20 #include "cipher_log.h"
21 #include "md.h"
22 #include "md_internal.h"
23 #include "pkcs5.h"
24 #include "securec.h"
25
26 #define AES_BYTE_SIZE 256
27
PaddingPkcs5(char * data,size_t inSize)28 static int32_t PaddingPkcs5(char *data, size_t inSize)
29 {
30 if (inSize % AES_BLOCK_SIZE == 0) {
31 return strlen((const char *)(uintptr_t)data);
32 }
33
34 int32_t paddingLen = AES_BLOCK_SIZE - inSize % AES_BLOCK_SIZE;
35 int32_t needLen = paddingLen + inSize;
36 for (int32_t i = 0; i < paddingLen; i++) {
37 data[inSize + i] = paddingLen;
38 }
39
40 return needLen;
41 }
42
UnpaddingPkcs5(char * data,size_t dataLen)43 static int32_t UnpaddingPkcs5(char *data, size_t dataLen)
44 {
45 int32_t padLen = data[dataLen - 1];
46
47 if (padLen <= 0 || padLen >= AES_BLOCK_SIZE) {
48 return ERROR_CODE_GENERAL;
49 }
50
51 for (int32_t i = 0; i < padLen; i++) {
52 if (data[dataLen - 1 - i] != padLen) {
53 return ERROR_CODE_GENERAL;
54 }
55 data[dataLen - 1 - i] = '\0';
56 }
57 return (dataLen - padLen);
58 }
59
MallocDecodeData(const char * text,size_t * olen)60 static char *MallocDecodeData(const char *text, size_t *olen)
61 {
62 size_t decodeLen = 0;
63 int32_t ret = mbedtls_base64_decode(NULL, 0, &decodeLen, (const unsigned char *)(text), strlen(text));
64 if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) {
65 return NULL;
66 }
67
68 if ((decodeLen + 1) <= 0) {
69 return NULL;
70 }
71 char *decData = (char *)malloc(decodeLen + 1);
72 if (decData == NULL) {
73 CIPHER_LOG_E("malloc failed, length:%d.", (int32_t)(decodeLen + 1));
74 return NULL;
75 }
76 (void)memset_s(decData, decodeLen + 1, 0, decodeLen + 1);
77 if (mbedtls_base64_decode((unsigned char *)decData, decodeLen + 1, olen,
78 (const unsigned char *)text, strlen(text)) != 0) {
79 free(decData);
80 CIPHER_LOG_E("decode data failed, text:%s.", text);
81 return NULL;
82 }
83 return decData;
84 }
85
MallocEncodeData(const unsigned char * text,size_t * olen)86 static char *MallocEncodeData(const unsigned char *text, size_t *olen)
87 {
88 size_t dataLen = 0;
89 int32_t ret = mbedtls_base64_encode(NULL, 0, &dataLen, text, *olen);
90 if (ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) {
91 return NULL;
92 }
93
94 if ((dataLen + 1) <= 0) {
95 return NULL;
96 }
97 char *encData = (char *)malloc(dataLen + 1);
98 if (encData == NULL) {
99 CIPHER_LOG_E("malloc data failed, expect len:%zu.", dataLen);
100 return NULL;
101 }
102 (void)memset_s(encData, dataLen + 1, 0, dataLen + 1);
103 if (mbedtls_base64_encode((unsigned char *)(encData), dataLen, olen, text, *olen) != 0) {
104 CIPHER_LOG_E("encode data failed.");
105 free(encData);
106 return NULL;
107 }
108 return encData;
109 }
110
SetIv(const char * ivBuf,int32_t ivBufLen,AesCryptContext * ctx)111 static int32_t SetIv(const char *ivBuf, int32_t ivBufLen, AesCryptContext *ctx)
112 {
113 if ((ivBuf == NULL) || (ctx == NULL)) {
114 return ERROR_CODE_GENERAL;
115 }
116
117 if ((ivBufLen < (ctx->iv.ivOffset + ctx->iv.ivLen)) || (ctx->iv.ivOffset < 0) || (ctx->iv.ivLen <= 0)) {
118 CIPHER_LOG_E("ivLen or ivOffset err.");
119 return ERROR_CODE_GENERAL;
120 }
121 ctx->iv.ivBuf = malloc(ctx->iv.ivLen);
122 if (ctx->iv.ivBuf == NULL) {
123 CIPHER_LOG_E("malloc failed.");
124 return ERROR_CODE_GENERAL;
125 }
126
127 int32_t ret = memcpy_s(ctx->iv.ivBuf, ctx->iv.ivLen, ivBuf + ctx->iv.ivOffset, ctx->iv.ivLen);
128 if (ret) {
129 CIPHER_LOG_E("memcpy failed, ret:%d.", ret);
130 free(ctx->iv.ivBuf);
131 ctx->iv.ivBuf = NULL;
132 return ERROR_CODE_GENERAL;
133 }
134
135 return ERROR_SUCCESS;
136 }
137
InitAesCryptContext(const char * key,const AesIvMode * iv,AesCryptContext * ctx)138 static int32_t InitAesCryptContext(const char *key, const AesIvMode *iv, AesCryptContext *ctx)
139 {
140 int32_t ret;
141
142 if (iv == NULL || ctx == NULL || key == NULL) {
143 return ERROR_CODE_GENERAL;
144 }
145
146 if ((iv->transformation != NULL) && (strcmp(iv->transformation, "AES/CBC/PKCS5Padding"))) {
147 CIPHER_LOG_E("transformation err.");
148 return ERROR_CODE_GENERAL;
149 }
150 ctx->mode = CIPHER_AES_CBC;
151 ctx->iv.ivOffset = iv->ivOffset;
152
153 if ((iv->ivLen < 0) || (iv->ivLen != AES_BLOCK_SIZE)) {
154 CIPHER_LOG_E("ivLen:%d error, need be %d Bytes.",
155 iv->ivLen, AES_BLOCK_SIZE);
156 return ERROR_CODE_GENERAL;
157 }
158 ctx->iv.ivLen = AES_BLOCK_SIZE;
159
160 if (iv->ivBuf != NULL) {
161 size_t ivBufLen = strlen((const char *)(uintptr_t)iv->ivBuf);
162 char* ivBuf = MallocDecodeData(iv->ivBuf, &ivBufLen);
163 if (ivBuf == NULL) {
164 CIPHER_LOG_E("base64 decode failed.");
165 return ERROR_CODE_GENERAL;
166 }
167 ret = SetIv((const char *)ivBuf, strlen((const char *)(uintptr_t)ivBuf), ctx);
168 if (ret == ERROR_CODE_GENERAL) {
169 free(ivBuf);
170 CIPHER_LOG_E("SetIv failed.");
171 return ERROR_CODE_GENERAL;
172 }
173 free(ivBuf);
174 } else {
175 ret = SetIv(ctx->data.key, strlen((const char *)(uintptr_t)ctx->data.key), ctx);
176 if (ret == ERROR_CODE_GENERAL) {
177 CIPHER_LOG_E("SetIv failed.");
178 return ERROR_CODE_GENERAL;
179 }
180 }
181
182 return ERROR_SUCCESS;
183 }
184
InitAesData(const char * action,const char * key,const char * text,CryptData * data)185 static int32_t InitAesData(const char *action, const char *key, const char *text, CryptData *data)
186 {
187 if (action == NULL || text == 0 || data == NULL || key == NULL) {
188 return ERROR_CODE_GENERAL;
189 }
190 if (!strcmp(action, "encrypt")) {
191 data->action = MBEDTLS_AES_ENCRYPT;
192 if (strlen(text) % AES_BLOCK_SIZE) {
193 data->textLen = (strlen(text) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE + AES_BLOCK_SIZE;
194 } else {
195 data->textLen = strlen(text);
196 }
197 if ((data->textLen + 1) <= 0) {
198 return ERROR_CODE_GENERAL;
199 }
200 data->text = malloc(data->textLen + 1);
201 if (data->text == NULL) {
202 return ERROR_CODE_GENERAL;
203 }
204 (void)memset_s(data->text, data->textLen + 1, 0, data->textLen + 1);
205 if (memcpy_s(data->text, data->textLen + 1, text, strlen(text)) != EOK) {
206 goto ERROR;
207 }
208 data->textLen = PaddingPkcs5(data->text, strlen(text));
209 } else if (!strcmp(action, "decrypt")) {
210 data->action = MBEDTLS_AES_DECRYPT;
211 data->text = MallocDecodeData(text, (size_t *)&data->textLen);
212 if (data->text == NULL) {
213 return ERROR_CODE_GENERAL;
214 }
215 data->textLen -= data->textLen % AES_BLOCK_SIZE;
216 } else {
217 return ERROR_CODE_GENERAL;
218 }
219 data->key = MallocDecodeData(key, (size_t *)&data->keyLen);
220 if (data->key == NULL) {
221 goto ERROR;
222 }
223 if (data->keyLen != KEY_LEN) {
224 CIPHER_LOG_E("key length:%d error, need be %d Bytes.",
225 data->keyLen, KEY_LEN);
226 (void)memset_s(data->key, data->keyLen, 0, data->keyLen);
227 free(data->key);
228 data->key = NULL;
229 goto ERROR;
230 }
231 return ERROR_SUCCESS;
232
233 ERROR:
234 free(data->text);
235 data->text = NULL;
236 return ERROR_CODE_GENERAL;
237 }
238
DeinitAesCryptData(AesCryptContext * ctx)239 void DeinitAesCryptData(AesCryptContext *ctx)
240 {
241 if (ctx == NULL) {
242 return;
243 }
244
245 if (ctx->iv.ivBuf != NULL) {
246 free(ctx->iv.ivBuf);
247 ctx->iv.ivBuf = NULL;
248 }
249
250 if (ctx->data.key != NULL) {
251 (void)memset_s(ctx->data.key, ctx->data.keyLen, 0, ctx->data.keyLen);
252 free(ctx->data.key);
253 ctx->data.key = NULL;
254 }
255
256 if (ctx->data.text != NULL) {
257 free(ctx->data.text);
258 ctx->data.text = NULL;
259 }
260 }
261
DoAesCbcEncrypt(mbedtls_aes_context * aesCtx,AesCryptContext * ctx)262 static int32_t DoAesCbcEncrypt(mbedtls_aes_context *aesCtx, AesCryptContext *ctx)
263 {
264 int32_t ret;
265 if (ctx->data.action == MBEDTLS_AES_ENCRYPT) {
266 ret = mbedtls_aes_setkey_enc(aesCtx, (const unsigned char *)ctx->data.key, AES_BYTE_SIZE);
267 } else {
268 ret = mbedtls_aes_setkey_dec(aesCtx, (const unsigned char *)ctx->data.key, AES_BYTE_SIZE);
269 }
270 if (ret != 0) {
271 CIPHER_LOG_E("aes setkey error.");
272 return ERROR_CODE_GENERAL;
273 }
274
275 ret = mbedtls_aes_crypt_cbc(aesCtx, ctx->data.action, ctx->data.textLen,
276 (unsigned char *)ctx->iv.ivBuf, (const unsigned char *)ctx->data.text, (unsigned char *)ctx->data.text);
277 if (ret != 0) {
278 CIPHER_LOG_E("aes crypt cbc error, ret:%d.", ret);
279 return ERROR_CODE_GENERAL;
280 }
281
282 if (ctx->data.action == MBEDTLS_AES_ENCRYPT) {
283 char *out = MallocEncodeData((const unsigned char *)ctx->data.text, (size_t *)&ctx->data.textLen);
284 free(ctx->data.text);
285 ctx->data.text = out;
286 if (out == NULL) {
287 return ERROR_CODE_GENERAL;
288 }
289 } else {
290 ctx->data.textLen = UnpaddingPkcs5(ctx->data.text, ctx->data.textLen);
291 if (ctx->data.textLen < 0) {
292 return ERROR_CODE_GENERAL;
293 }
294 }
295
296 return ERROR_SUCCESS;
297 }
298
InitAesCryptData(const char * action,const char * text,const char * key,const AesIvMode * iv,AesCryptContext * aesCryptCxt)299 int32_t InitAesCryptData(const char *action, const char *text, const char *key, const AesIvMode *iv,
300 AesCryptContext *aesCryptCxt)
301 {
302 if (action == NULL || text == NULL || key == NULL || iv == NULL || aesCryptCxt == NULL) {
303 return ERROR_CODE_GENERAL;
304 }
305
306 int32_t ret = InitAesData(action, key, text, &(aesCryptCxt->data));
307 if (ret != 0) {
308 CIPHER_LOG_E("fill aes crypt data failed.");
309 DeinitAesCryptData(aesCryptCxt);
310 return ERROR_CODE_GENERAL;
311 }
312
313 ret = InitAesCryptContext(key, iv, aesCryptCxt);
314 if (ret != 0) {
315 CIPHER_LOG_E("fill aes crypt context failed.");
316 return ERROR_CODE_GENERAL;
317 }
318 return ERROR_SUCCESS;
319 }
320
AesCrypt(AesCryptContext * aesCryptCxt)321 int32_t AesCrypt(AesCryptContext* aesCryptCxt)
322 {
323 if (aesCryptCxt == NULL) {
324 return ERROR_CODE_GENERAL;
325 }
326
327 if (aesCryptCxt->mode == CIPHER_AES_CBC) {
328 mbedtls_aes_context aes;
329 mbedtls_aes_init(&aes);
330 int32_t ret = DoAesCbcEncrypt(&aes, aesCryptCxt);
331 if (ret != ERROR_SUCCESS) {
332 CIPHER_LOG_E("Aes cbc encrypt failed.");
333 mbedtls_aes_free(&aes);
334 return ERROR_CODE_GENERAL;
335 }
336 mbedtls_aes_free(&aes);
337 return ERROR_SUCCESS;
338 } else {
339 CIPHER_LOG_E("crypt mode not support.");
340 return ERROR_CODE_GENERAL;
341 }
342 }
343