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 <stdint.h>
18 #include <string.h>
19
20 #include "aes.h"
21 #include "base64.h"
22 #include "cipher.h"
23 #include "cipher_log.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 == 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 == 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
InitAesCryptDataText(const char * action,const char * key,const char * text,CryptData * data)185 static int32_t InitAesCryptDataText(const char *action, const char *key, const char *text, CryptData *data)
186 {
187 if (!strcmp(action, "encrypt")) {
188 data->action = MBEDTLS_AES_ENCRYPT;
189 if (strlen(text) % AES_BLOCK_SIZE) {
190 data->textLen = (strlen(text) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE + AES_BLOCK_SIZE;
191 } else {
192 data->textLen = strlen(text);
193 }
194 if ((data->textLen + 1) <= 0) {
195 return ERROR_CODE_GENERAL;
196 }
197 data->text = malloc(data->textLen + 1);
198 if (data->text == NULL) {
199 return ERROR_CODE_GENERAL;
200 }
201 (void)memset_s(data->text, data->textLen + 1, 0, data->textLen + 1);
202 if (memcpy_s(data->text, data->textLen + 1, text, strlen(text)) != EOK) {
203 free(data->text);
204 data->text = NULL;
205 return ERROR_CODE_GENERAL;
206 }
207 data->textLen = PaddingPkcs5(data->text, strlen(text));
208 } else if (!strcmp(action, "decrypt")) {
209 data->action = MBEDTLS_AES_DECRYPT;
210 size_t textLen = (size_t)data->textLen;
211 data->text = MallocDecodeData(text, &textLen);
212 data->textLen = (uint32_t)textLen;
213 if (data->text == NULL) {
214 return ERROR_CODE_GENERAL;
215 }
216 data->textLen -= data->textLen % AES_BLOCK_SIZE;
217 } else {
218 return ERROR_CODE_GENERAL;
219 }
220 return ERROR_SUCCESS;
221 }
222
InitAesData(const char * action,const char * key,const char * text,CryptData * data)223 static int32_t InitAesData(const char *action, const char *key, const char *text, CryptData *data)
224 {
225 if (action == NULL || text == 0 || data == NULL || key == NULL) {
226 return ERROR_CODE_GENERAL;
227 }
228 int32_t ret = InitAesCryptDataText(action, key, text, data);
229 if (ret != ERROR_SUCCESS) {
230 return ERROR_CODE_GENERAL;
231 }
232 size_t keyLen = (size_t)data->keyLen;
233 data->key = MallocDecodeData(key, &keyLen);
234 data->keyLen = (uint32_t)keyLen;
235 if (data->key == NULL) {
236 goto ERROR;
237 }
238 if (data->keyLen != KEY_LEN) {
239 CIPHER_LOG_E("key length:%d error, need be %d Bytes.",
240 data->keyLen, KEY_LEN);
241 (void)memset_s(data->key, data->keyLen, 0, data->keyLen);
242 free(data->key);
243 data->key = NULL;
244 goto ERROR;
245 }
246 return ERROR_SUCCESS;
247
248 ERROR:
249 free(data->text);
250 data->text = NULL;
251 return ERROR_CODE_GENERAL;
252 }
253
DeinitAesCryptData(AesCryptContext * aesCryptCxt)254 void DeinitAesCryptData(AesCryptContext *aesCryptCxt)
255 {
256 if (aesCryptCxt == NULL) {
257 return;
258 }
259
260 if (aesCryptCxt->iv.ivBuf != NULL) {
261 free(aesCryptCxt->iv.ivBuf);
262 aesCryptCxt->iv.ivBuf = NULL;
263 }
264
265 if (aesCryptCxt->data.key != NULL) {
266 (void)memset_s(aesCryptCxt->data.key, aesCryptCxt->data.keyLen, 0, aesCryptCxt->data.keyLen);
267 free(aesCryptCxt->data.key);
268 aesCryptCxt->data.key = NULL;
269 }
270
271 if (aesCryptCxt->data.text != NULL) {
272 free(aesCryptCxt->data.text);
273 aesCryptCxt->data.text = NULL;
274 }
275 }
276
DoAesCbcEncrypt(mbedtls_aes_context * aesCtx,AesCryptContext * ctx)277 static int32_t DoAesCbcEncrypt(mbedtls_aes_context *aesCtx, AesCryptContext *ctx)
278 {
279 int32_t ret;
280 if (ctx->data.action == MBEDTLS_AES_ENCRYPT) {
281 ret = mbedtls_aes_setkey_enc(aesCtx, (const unsigned char *)ctx->data.key, AES_BYTE_SIZE);
282 } else {
283 ret = mbedtls_aes_setkey_dec(aesCtx, (const unsigned char *)ctx->data.key, AES_BYTE_SIZE);
284 }
285 if (ret != 0) {
286 CIPHER_LOG_E("aes setkey error.");
287 return ERROR_CODE_GENERAL;
288 }
289
290 ret = mbedtls_aes_crypt_cbc(aesCtx, ctx->data.action, ctx->data.textLen,
291 (unsigned char *)ctx->iv.ivBuf, (const unsigned char *)ctx->data.text, (unsigned char *)ctx->data.text);
292 if (ret != 0) {
293 CIPHER_LOG_E("aes crypt cbc error, ret:%d.", ret);
294 return ERROR_CODE_GENERAL;
295 }
296
297 if (ctx->data.action == MBEDTLS_AES_ENCRYPT) {
298 size_t textLen = ctx->data.textLen;
299 char *out = MallocEncodeData((const unsigned char *)ctx->data.text, &textLen);
300 ctx->data.textLen = (uint32_t)textLen;
301 free(ctx->data.text);
302 ctx->data.text = out;
303 if (out == NULL) {
304 return ERROR_CODE_GENERAL;
305 }
306 } else {
307 ctx->data.textLen = UnpaddingPkcs5(ctx->data.text, ctx->data.textLen);
308 if (ctx->data.textLen < 0) {
309 return ERROR_CODE_GENERAL;
310 }
311 }
312
313 return ERROR_SUCCESS;
314 }
315
InitAesCryptData(const char * action,const char * text,const char * key,const AesIvMode * iv,AesCryptContext * aesCryptCxt)316 int32_t InitAesCryptData(const char *action, const char *text, const char *key, const AesIvMode *iv,
317 AesCryptContext *aesCryptCxt)
318 {
319 if (action == NULL || text == NULL || key == NULL || iv == NULL || aesCryptCxt == NULL) {
320 return ERROR_CODE_GENERAL;
321 }
322
323 int32_t ret = InitAesData(action, key, text, &(aesCryptCxt->data));
324 if (ret != 0) {
325 CIPHER_LOG_E("fill aes crypt data failed.");
326 DeinitAesCryptData(aesCryptCxt);
327 return ERROR_CODE_GENERAL;
328 }
329
330 ret = InitAesCryptContext(key, iv, aesCryptCxt);
331 if (ret != 0) {
332 CIPHER_LOG_E("fill aes crypt context failed.");
333 return ERROR_CODE_GENERAL;
334 }
335 return ERROR_SUCCESS;
336 }
337
AesCrypt(AesCryptContext * aesCryptCxt)338 int32_t AesCrypt(AesCryptContext* aesCryptCxt)
339 {
340 if (aesCryptCxt == NULL) {
341 return ERROR_CODE_GENERAL;
342 }
343
344 if (aesCryptCxt->mode == CIPHER_AES_CBC) {
345 mbedtls_aes_context aes;
346 mbedtls_aes_init(&aes);
347 int32_t ret = DoAesCbcEncrypt(&aes, aesCryptCxt);
348 if (ret != ERROR_SUCCESS) {
349 CIPHER_LOG_E("Aes cbc encrypt failed.");
350 mbedtls_aes_free(&aes);
351 return ERROR_CODE_GENERAL;
352 }
353 mbedtls_aes_free(&aes);
354 return ERROR_SUCCESS;
355 } else {
356 CIPHER_LOG_E("crypt mode not support.");
357 return ERROR_CODE_GENERAL;
358 }
359 }
360