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