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