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