1 /*
2 * Copyright (c) 2021 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 "softbus_adapter_crypto.h"
17
18 #include <securec.h>
19
20 #include "comm_log.h"
21 #include "mbedtls/base64.h"
22 #include "mbedtls/cipher.h"
23 #include "mbedtls/ctr_drbg.h"
24 #include "mbedtls/entropy.h"
25 #include "mbedtls/gcm.h"
26 #include "mbedtls/md.h"
27 #include "mbedtls/platform.h"
28 #include "softbus_adapter_file.h"
29 #include "softbus_errcode.h"
30
31 #ifndef MBEDTLS_CTR_DRBG_C
32 #define MBEDTLS_CTR_DRBG_C
33 #endif
34
35 #ifndef MBEDTLS_MD_C
36 #define MBEDTLS_MD_C
37 #endif
38
39 #ifndef MBEDTLS_SHA256_C
40 #define MBEDTLS_SHA256_C
41 #endif
42
43 #ifndef MBEDTLS_ENTROPY_C
44 #define MBEDTLS_ENTROPY_C
45 #endif
46
47 #ifndef MBEDTLS_CIPHER_MODE_CTR
48 #define MBEDTLS_CIPHER_MODE_CTR
49 #endif
50
51 #ifndef MBEDTLS_AES_C
52 #define MBEDTLS_AES_C
53 #endif
54
55 #ifndef MBEDTLS_CIPHER_C
56 #define MBEDTLS_CIPHER_C
57 #endif
58
59 #define EVP_AES_128_KEYLEN 16
60 #define EVP_AES_256_KEYLEN 32
61 #define BYTES_BIT_NUM 8
62
63 static SoftBusMutex g_randomLock;
64
GetCtrAlgorithmByKeyLen(uint32_t keyLen)65 static mbedtls_cipher_type_t GetCtrAlgorithmByKeyLen(uint32_t keyLen)
66 {
67 switch (keyLen) {
68 case EVP_AES_128_KEYLEN:
69 return MBEDTLS_CIPHER_ARIA_128_CTR;
70 case EVP_AES_256_KEYLEN:
71 return MBEDTLS_CIPHER_ARIA_256_CTR;
72 default:
73 return MBEDTLS_CIPHER_NONE;
74 }
75 return MBEDTLS_CIPHER_NONE;
76 }
77
MbedAesGcmEncrypt(const AesGcmCipherKey * cipherKey,const unsigned char * plainText,uint32_t plainTextSize,unsigned char * cipherText,uint32_t cipherTextLen)78 static int32_t MbedAesGcmEncrypt(const AesGcmCipherKey *cipherKey, const unsigned char *plainText,
79 uint32_t plainTextSize, unsigned char *cipherText, uint32_t cipherTextLen)
80 {
81 if ((cipherKey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL ||
82 (cipherTextLen < plainTextSize + OVERHEAD_LEN)) {
83 COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para");
84 return SOFTBUS_INVALID_PARAM;
85 }
86
87 int32_t ret;
88 unsigned char tagBuf[TAG_LEN] = { 0 };
89 mbedtls_gcm_context aesContext;
90 mbedtls_gcm_init(&aesContext);
91
92 ret = mbedtls_gcm_setkey(&aesContext, MBEDTLS_CIPHER_ID_AES, cipherKey->key, cipherKey->keyLen * KEY_BITS_UNIT);
93 if (ret != 0) {
94 mbedtls_gcm_free(&aesContext);
95 return SOFTBUS_ENCRYPT_ERR;
96 }
97
98 ret = mbedtls_gcm_crypt_and_tag(&aesContext, MBEDTLS_GCM_ENCRYPT, plainTextSize, cipherKey->iv, GCM_IV_LEN, NULL, 0,
99 plainText, cipherText + GCM_IV_LEN, TAG_LEN, tagBuf);
100 if (ret != 0) {
101 mbedtls_gcm_free(&aesContext);
102 return SOFTBUS_ENCRYPT_ERR;
103 }
104
105 if (memcpy_s(cipherText, cipherTextLen, cipherKey->iv, GCM_IV_LEN) != EOK) {
106 mbedtls_gcm_free(&aesContext);
107 return SOFTBUS_ENCRYPT_ERR;
108 }
109
110 if (memcpy_s(cipherText + GCM_IV_LEN + plainTextSize, cipherTextLen - GCM_IV_LEN - plainTextSize, tagBuf,
111 TAG_LEN) != 0) {
112 mbedtls_gcm_free(&aesContext);
113 return SOFTBUS_ENCRYPT_ERR;
114 }
115
116 mbedtls_gcm_free(&aesContext);
117 return (plainTextSize + OVERHEAD_LEN);
118 }
119
MbedAesGcmDecrypt(const AesGcmCipherKey * cipherKey,const unsigned char * cipherText,uint32_t cipherTextSize,unsigned char * plain,uint32_t plainLen)120 static int32_t MbedAesGcmDecrypt(const AesGcmCipherKey *cipherKey, const unsigned char *cipherText,
121 uint32_t cipherTextSize, unsigned char *plain, uint32_t plainLen)
122 {
123 if ((cipherKey == NULL) || (cipherText == NULL) || (cipherTextSize <= OVERHEAD_LEN) || plain == NULL ||
124 (plainLen < cipherTextSize - OVERHEAD_LEN)) {
125 COMM_LOGE(COMM_ADAPTER, "Decrypt invalid para");
126 return SOFTBUS_INVALID_PARAM;
127 }
128
129 mbedtls_gcm_context aesContext;
130 mbedtls_gcm_init(&aesContext);
131 int32_t ret =
132 mbedtls_gcm_setkey(&aesContext, MBEDTLS_CIPHER_ID_AES, cipherKey->key, cipherKey->keyLen * KEY_BITS_UNIT);
133 if (ret != 0) {
134 COMM_LOGE(COMM_ADAPTER, "Decrypt mbedtls_gcm_setkey fail.");
135 mbedtls_gcm_free(&aesContext);
136 return SOFTBUS_DECRYPT_ERR;
137 }
138
139 int32_t actualPlainLen = (int32_t)(cipherTextSize - OVERHEAD_LEN);
140 ret = mbedtls_gcm_auth_decrypt(&aesContext, cipherTextSize - OVERHEAD_LEN, cipherKey->iv, GCM_IV_LEN, NULL, 0,
141 cipherText + actualPlainLen + GCM_IV_LEN, TAG_LEN, cipherText + GCM_IV_LEN, plain);
142 if (ret != 0) {
143 COMM_LOGE(COMM_ADAPTER, "[TRANS] Decrypt mbedtls_gcm_auth_decrypt fail. ret=%{public}d", ret);
144 mbedtls_gcm_free(&aesContext);
145 return SOFTBUS_DECRYPT_ERR;
146 }
147
148 mbedtls_gcm_free(&aesContext);
149 return actualPlainLen;
150 }
151
HandleError(mbedtls_cipher_context_t * ctx,const char * buf)152 static int32_t HandleError(mbedtls_cipher_context_t *ctx, const char *buf)
153 {
154 if (buf != NULL) {
155 COMM_LOGE(COMM_ADAPTER, "buf=%{public}s", buf);
156 }
157 if (ctx != NULL) {
158 mbedtls_cipher_free(ctx);
159 }
160 return SOFTBUS_DECRYPT_ERR;
161 }
162
SoftBusBase64Encode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)163 int32_t SoftBusBase64Encode(unsigned char *dst, size_t dlen,
164 size_t *olen, const unsigned char *src, size_t slen)
165 {
166 if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
167 COMM_LOGE(COMM_ADAPTER, "base64 encode invalid para");
168 return SOFTBUS_INVALID_PARAM;
169 }
170 return mbedtls_base64_encode(dst, dlen, olen, src, slen);
171 }
172
SoftBusBase64Decode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)173 int32_t SoftBusBase64Decode(unsigned char *dst, size_t dlen,
174 size_t *olen, const unsigned char *src, size_t slen)
175 {
176 if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
177 COMM_LOGE(COMM_ADAPTER, "base64 decode invalid para");
178 return SOFTBUS_INVALID_PARAM;
179 }
180 return mbedtls_base64_decode(dst, dlen, olen, src, slen);
181 }
182
SoftBusGenerateStrHash(const unsigned char * str,uint32_t len,unsigned char * hash)183 int32_t SoftBusGenerateStrHash(const unsigned char *str, uint32_t len, unsigned char *hash)
184 {
185 if (str == NULL || hash == NULL || len == 0) {
186 return SOFTBUS_INVALID_PARAM;
187 }
188
189 mbedtls_md_context_t ctx;
190 const mbedtls_md_info_t *info = NULL;
191 mbedtls_md_init(&ctx);
192
193 info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
194 if (info == NULL) {
195 mbedtls_md_free(&ctx);
196 return SOFTBUS_ENCRYPT_ERR;
197 }
198 if (mbedtls_md_setup(&ctx, info, 0) != 0) {
199 mbedtls_md_free(&ctx);
200 return SOFTBUS_ENCRYPT_ERR;
201 }
202 if (mbedtls_md_starts(&ctx) != 0) {
203 mbedtls_md_free(&ctx);
204 return SOFTBUS_ENCRYPT_ERR;
205 }
206 if (mbedtls_md_update(&ctx, str, len) != 0) {
207 mbedtls_md_free(&ctx);
208 return SOFTBUS_ENCRYPT_ERR;
209 }
210 if (mbedtls_md_finish(&ctx, hash) != 0) {
211 mbedtls_md_free(&ctx);
212 return SOFTBUS_ENCRYPT_ERR;
213 }
214
215 mbedtls_md_free(&ctx);
216 return SOFTBUS_OK;
217 }
218
SoftBusGenerateRandomArray(unsigned char * randStr,uint32_t len)219 int32_t SoftBusGenerateRandomArray(unsigned char *randStr, uint32_t len)
220 {
221 if (randStr == NULL || len == 0) {
222 return SOFTBUS_INVALID_PARAM;
223 }
224
225 static mbedtls_entropy_context entropy;
226 static mbedtls_ctr_drbg_context ctrDrbg;
227 static bool initFlag = false;
228 int32_t ret;
229
230 if (!initFlag) {
231 if (SoftBusMutexInit(&g_randomLock, NULL) != SOFTBUS_OK) {
232 COMM_LOGE(COMM_ADAPTER, "SoftBusGenerateRandomArray init lock fail");
233 return SOFTBUS_LOCK_ERR;
234 }
235 mbedtls_ctr_drbg_init(&ctrDrbg);
236 mbedtls_entropy_init(&entropy);
237 ret = mbedtls_ctr_drbg_seed(&ctrDrbg, mbedtls_entropy_func, &entropy, NULL, 0);
238 if (ret != 0) {
239 SoftBusMutexUnlock(&g_randomLock);
240 COMM_LOGE(COMM_ADAPTER, "gen random seed error, ret=%{public}d", ret);
241 return SOFTBUS_ERR;
242 }
243 initFlag = true;
244 }
245
246 if (SoftBusMutexLock(&g_randomLock) != SOFTBUS_OK) {
247 COMM_LOGE(COMM_ADAPTER, "SoftBusGenerateRandomArray lock fail");
248 return SOFTBUS_LOCK_ERR;
249 }
250
251 ret = mbedtls_ctr_drbg_random(&ctrDrbg, randStr, len);
252 SoftBusMutexUnlock(&g_randomLock);
253 if (ret != 0) {
254 COMM_LOGE(COMM_ADAPTER, "gen random error, ret=%{public}d", ret);
255 return SOFTBUS_ERR;
256 }
257 return SOFTBUS_OK;
258 }
259
SoftBusGenerateSessionKey(char * key,uint32_t len)260 int32_t SoftBusGenerateSessionKey(char *key, uint32_t len)
261 {
262 if (SoftBusGenerateRandomArray((unsigned char *)key, len) != SOFTBUS_OK) {
263 COMM_LOGE(COMM_ADAPTER, "generate sessionKey error.");
264 return SOFTBUS_ENCRYPT_ERR;
265 }
266 return SOFTBUS_OK;
267 }
268
SoftBusEncryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)269 int32_t SoftBusEncryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
270 unsigned char *encryptData, uint32_t *encryptLen)
271 {
272 if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
273 return SOFTBUS_INVALID_PARAM;
274 }
275
276 if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
277 COMM_LOGE(COMM_ADAPTER, "generate random iv error.");
278 return SOFTBUS_ENCRYPT_ERR;
279 }
280 uint32_t outLen = inLen + OVERHEAD_LEN;
281 int32_t result = MbedAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
282 if (result <= 0) {
283 return SOFTBUS_ENCRYPT_ERR;
284 }
285 *encryptLen = result;
286 return SOFTBUS_OK;
287 }
288
SoftBusEncryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen,int32_t seqNum)289 int32_t SoftBusEncryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
290 unsigned char *encryptData, uint32_t *encryptLen, int32_t seqNum)
291 {
292 if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
293 return SOFTBUS_INVALID_PARAM;
294 }
295 if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
296 COMM_LOGE(COMM_ADAPTER, "generate random iv error.");
297 return SOFTBUS_ENCRYPT_ERR;
298 }
299 if (memcpy_s(cipherKey->iv, sizeof(int32_t), &seqNum, sizeof(int32_t)) != EOK) {
300 return SOFTBUS_ENCRYPT_ERR;
301 }
302 uint32_t outLen = inLen + OVERHEAD_LEN;
303 int32_t result = MbedAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
304 if (result <= 0) {
305 return SOFTBUS_ENCRYPT_ERR;
306 }
307 *encryptLen = result;
308 return SOFTBUS_OK;
309 }
310
SoftBusDecryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)311 int32_t SoftBusDecryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
312 unsigned char *decryptData, uint32_t *decryptLen)
313 {
314 if (cipherKey == NULL || input == NULL || inLen < GCM_IV_LEN || decryptData == NULL || decryptLen == NULL) {
315 return SOFTBUS_INVALID_PARAM;
316 }
317
318 if (memcpy_s(cipherKey->iv, sizeof(cipherKey->iv), input, GCM_IV_LEN) != EOK) {
319 COMM_LOGE(COMM_ADAPTER, "copy iv failed.");
320 return SOFTBUS_ENCRYPT_ERR;
321 }
322 uint32_t outLen = inLen - OVERHEAD_LEN;
323 int32_t result = MbedAesGcmDecrypt(cipherKey, input, inLen, decryptData, outLen);
324 if (result <= 0) {
325 return SOFTBUS_ENCRYPT_ERR;
326 }
327 *decryptLen = (uint32_t)result;
328 return SOFTBUS_OK;
329 }
330
SoftBusDecryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen,int32_t seqNum)331 int32_t SoftBusDecryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
332 unsigned char *decryptData, uint32_t *decryptLen, int32_t seqNum)
333 {
334 (void)seqNum;
335 return SoftBusDecryptData(cipherKey, input, inLen, decryptData, decryptLen);
336 }
337
SoftBusCryptoRand(void)338 uint32_t SoftBusCryptoRand(void)
339 {
340 int32_t fd = SoftBusOpenFile("/dev/urandom", SOFTBUS_O_RDONLY);
341 if (fd < 0) {
342 COMM_LOGE(COMM_ADAPTER, "CryptoRand open file fail");
343 return 0;
344 }
345 uint32_t value = 0;
346 int32_t len = SoftBusReadFile(fd, &value, sizeof(uint32_t));
347 if (len < 0) {
348 COMM_LOGE(COMM_ADAPTER, "CryptoRand read file fail");
349 SoftBusCloseFile(fd);
350 return 0;
351 }
352 SoftBusCloseFile(fd);
353 return value;
354 }
355
SoftBusEncryptDataByCtr(AesCtrCipherKey * key,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)356 int32_t SoftBusEncryptDataByCtr(AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen,
357 unsigned char *encryptData, uint32_t *encryptLen)
358 {
359 if (key == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
360 COMM_LOGE(COMM_ADAPTER, "softbus encrypt data by ctr invalid para");
361 return SOFTBUS_INVALID_PARAM;
362 }
363 mbedtls_cipher_type_t type = GetCtrAlgorithmByKeyLen(key->keyLen);
364 if (type == MBEDTLS_CIPHER_NONE) {
365 return HandleError(NULL, "get cipher failed");
366 }
367 size_t len = 0;
368 *encryptLen = 0;
369 mbedtls_cipher_context_t ctx;
370 const mbedtls_cipher_info_t *info = NULL;
371 mbedtls_cipher_init(&ctx);
372 if (!(info = mbedtls_cipher_info_from_type(type))) {
373 return HandleError(&ctx, "mbedtls_cipher_info_from_type ctr failed");
374 }
375 if (mbedtls_cipher_setup(&ctx, info) != 0) {
376 return HandleError(&ctx, "mbedtls_cipher_setup ctr failed");
377 }
378 if (mbedtls_cipher_setkey(&ctx, key->key, key->keyLen * BYTES_BIT_NUM, MBEDTLS_ENCRYPT) != 0) {
379 return HandleError(&ctx, "mbedtls_cipher_setkey ctr failed");
380 }
381 if (mbedtls_cipher_set_iv(&ctx, key->iv, BLE_BROADCAST_IV_LEN) != 0) {
382 return HandleError(&ctx, "mbedtls_cipher_set_iv ctr failed");
383 }
384 if (mbedtls_cipher_update(&ctx, input, inLen, encryptData, &len) != 0) {
385 return HandleError(&ctx, "mbedtls_cipher_update ctr failed");
386 }
387 *encryptLen += len;
388 if (mbedtls_cipher_finish(&ctx, encryptData, &len) != 0) {
389 return HandleError(&ctx, "mbedtls_cipher_finish ctr failed");
390 }
391 *encryptLen += len;
392 mbedtls_cipher_free(&ctx);
393 return SOFTBUS_OK;
394 }
395
SoftBusDecryptDataByCtr(AesCtrCipherKey * key,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)396 int32_t SoftBusDecryptDataByCtr(AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen,
397 unsigned char *decryptData, uint32_t *decryptLen)
398 {
399 return SoftBusEncryptDataByCtr(key, input, inLen, decryptData, decryptLen);
400 }
401