• 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/ctr_drbg.h"
22 #include "mbedtls/entropy.h"
23 #include "mbedtls/gcm.h"
24 #include "mbedtls/md.h"
25 #include "mbedtls/platform.h"
26 #include "softbus_adapter_file.h"
27 #include "softbus_adapter_log.h"
28 #include "softbus_errcode.h"
29 
30 #ifndef MBEDTLS_CTR_DRBG_C
31 #define MBEDTLS_CTR_DRBG_C
32 #endif
33 
34 #ifndef MBEDTLS_MD_C
35 #define MBEDTLS_MD_C
36 #endif
37 
38 #ifndef MBEDTLS_SHA256_C
39 #define MBEDTLS_SHA256_C
40 #endif
41 
42 #ifndef MBEDTLS_ENTROPY_C
43 #define MBEDTLS_ENTROPY_C
44 #endif
45 
46 static pthread_mutex_t g_randomLock = PTHREAD_MUTEX_INITIALIZER;
47 
MbedAesGcmEncrypt(const AesGcmCipherKey * cipherkey,const unsigned char * plainText,uint32_t plainTextSize,unsigned char * cipherText,uint32_t cipherTextLen)48 static int32_t MbedAesGcmEncrypt(const AesGcmCipherKey *cipherkey, const unsigned char *plainText,
49     uint32_t plainTextSize, unsigned char *cipherText, uint32_t cipherTextLen)
50 {
51     if ((cipherkey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL ||
52         (cipherTextLen < plainTextSize + OVERHEAD_LEN)) {
53         HILOG_ERROR(SOFTBUS_HILOG_ID, "Encrypt invalid para\n");
54         return SOFTBUS_INVALID_PARAM;
55     }
56 
57     int32_t ret;
58     unsigned char tagBuf[TAG_LEN] = {0};
59     mbedtls_gcm_context aesContext;
60     mbedtls_gcm_init(&aesContext);
61 
62     ret = mbedtls_gcm_setkey(&aesContext, MBEDTLS_CIPHER_ID_AES, cipherkey->key, cipherkey->keyLen * KEY_BITS_UNIT);
63     if (ret != 0) {
64         mbedtls_gcm_free(&aesContext);
65         return SOFTBUS_ENCRYPT_ERR;
66     }
67 
68     ret = mbedtls_gcm_crypt_and_tag(&aesContext, MBEDTLS_GCM_ENCRYPT, plainTextSize, cipherkey->iv,
69         GCM_IV_LEN, NULL, 0, plainText, cipherText + GCM_IV_LEN, TAG_LEN, tagBuf);
70     if (ret != 0) {
71         mbedtls_gcm_free(&aesContext);
72         return SOFTBUS_ENCRYPT_ERR;
73     }
74 
75     if (memcpy_s(cipherText, cipherTextLen, cipherkey->iv, GCM_IV_LEN) != EOK) {
76         mbedtls_gcm_free(&aesContext);
77         return SOFTBUS_ENCRYPT_ERR;
78     }
79 
80     if (memcpy_s(cipherText + GCM_IV_LEN + plainTextSize, cipherTextLen - GCM_IV_LEN - plainTextSize,
81         tagBuf, TAG_LEN) != 0) {
82         mbedtls_gcm_free(&aesContext);
83         return SOFTBUS_ENCRYPT_ERR;
84     }
85 
86     mbedtls_gcm_free(&aesContext);
87     return (plainTextSize + OVERHEAD_LEN);
88 }
89 
MbedAesGcmDecrypt(const AesGcmCipherKey * cipherkey,const unsigned char * cipherText,uint32_t cipherTextSize,unsigned char * plain,uint32_t plainLen)90 static int32_t MbedAesGcmDecrypt(const AesGcmCipherKey *cipherkey, const unsigned char *cipherText,
91     uint32_t cipherTextSize, unsigned char *plain, uint32_t plainLen)
92 {
93     if ((cipherkey == NULL) || (cipherText == NULL) || (cipherTextSize <= OVERHEAD_LEN) || plain == NULL ||
94         (plainLen < cipherTextSize - OVERHEAD_LEN)) {
95         HILOG_ERROR(SOFTBUS_HILOG_ID, "Decrypt invalid para\n");
96         return SOFTBUS_INVALID_PARAM;
97     }
98 
99     mbedtls_gcm_context aesContext;
100     mbedtls_gcm_init(&aesContext);
101     int32_t ret = mbedtls_gcm_setkey(&aesContext, MBEDTLS_CIPHER_ID_AES, cipherkey->key,
102         cipherkey->keyLen * KEY_BITS_UNIT);
103     if (ret != 0) {
104         HILOG_ERROR(SOFTBUS_HILOG_ID, "Decrypt mbedtls_gcm_setkey fail\n");
105         mbedtls_gcm_free(&aesContext);
106         return SOFTBUS_DECRYPT_ERR;
107     }
108 
109     int32_t actualPlainLen = (int32_t)(cipherTextSize - OVERHEAD_LEN);
110     ret = mbedtls_gcm_auth_decrypt(&aesContext, cipherTextSize - OVERHEAD_LEN, cipherkey->iv,
111         GCM_IV_LEN, NULL, 0, cipherText + actualPlainLen + GCM_IV_LEN, TAG_LEN, cipherText + GCM_IV_LEN, plain);
112     if (ret != 0) {
113         HILOG_ERROR(SOFTBUS_HILOG_ID, "[TRANS] Decrypt mbedtls_gcm_auth_decrypt fail.[%d]\n", ret);
114         mbedtls_gcm_free(&aesContext);
115         return SOFTBUS_DECRYPT_ERR;
116     }
117 
118     mbedtls_gcm_free(&aesContext);
119     return actualPlainLen;
120 }
121 
SoftBusBase64Encode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)122 int32_t SoftBusBase64Encode(unsigned char *dst, size_t dlen,
123     size_t *olen, const unsigned char *src, size_t slen)
124 {
125     if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
126         return SOFTBUS_INVALID_PARAM;
127     }
128     return mbedtls_base64_encode(dst, dlen, olen, src, slen);
129 }
130 
SoftBusBase64Decode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)131 int32_t SoftBusBase64Decode(unsigned char *dst, size_t dlen,
132     size_t *olen, const unsigned char *src, size_t slen)
133 {
134     if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
135         return SOFTBUS_INVALID_PARAM;
136     }
137     return mbedtls_base64_decode(dst, dlen, olen, src, slen);
138 }
139 
SoftBusGenerateStrHash(const unsigned char * str,uint32_t len,unsigned char * hash)140 int32_t SoftBusGenerateStrHash(const unsigned char *str, uint32_t len, unsigned char *hash)
141 {
142     if (str == NULL || hash == NULL || len == 0) {
143         return SOFTBUS_INVALID_PARAM;
144     }
145 
146     mbedtls_md_context_t ctx;
147     const mbedtls_md_info_t *info = NULL;
148     mbedtls_md_init(&ctx);
149 
150     info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
151     if (mbedtls_md_setup(&ctx, info, 0) != 0) {
152         mbedtls_md_free(&ctx);
153         return SOFTBUS_ENCRYPT_ERR;
154     }
155     if (mbedtls_md_starts(&ctx) != 0) {
156         mbedtls_md_free(&ctx);
157         return SOFTBUS_ENCRYPT_ERR;
158     }
159     if (mbedtls_md_update(&ctx, str, len) != 0) {
160         mbedtls_md_free(&ctx);
161         return SOFTBUS_ENCRYPT_ERR;
162     }
163     if (mbedtls_md_finish(&ctx, hash) != 0) {
164         mbedtls_md_free(&ctx);
165         return SOFTBUS_ENCRYPT_ERR;
166     }
167 
168     mbedtls_md_free(&ctx);
169     return SOFTBUS_OK;
170 }
171 
SoftBusGenerateRandomArray(unsigned char * randStr,uint32_t len)172 int32_t SoftBusGenerateRandomArray(unsigned char *randStr, uint32_t len)
173 {
174     if (randStr == NULL || len == 0) {
175         return SOFTBUS_INVALID_PARAM;
176     }
177 
178     static mbedtls_entropy_context entropy;
179     static mbedtls_ctr_drbg_context ctrDrbg;
180     static bool initFlag = false;
181     int32_t ret;
182 
183     if (pthread_mutex_lock(&g_randomLock) != 0) {
184         HILOG_ERROR(SOFTBUS_HILOG_ID, "lock mutex failed");
185         return SOFTBUS_ERR;
186     }
187 
188     if (initFlag == false) {
189         mbedtls_ctr_drbg_init(&ctrDrbg);
190         mbedtls_entropy_init(&entropy);
191         ret = mbedtls_ctr_drbg_seed(&ctrDrbg, mbedtls_entropy_func, &entropy, NULL, 0);
192         if (ret != 0) {
193             pthread_mutex_unlock(&g_randomLock);
194             HILOG_ERROR(SOFTBUS_HILOG_ID, "gen random seed error, ret[%d]", ret);
195             return SOFTBUS_ERR;
196         }
197         initFlag = true;
198     }
199 
200     ret = mbedtls_ctr_drbg_random(&ctrDrbg, randStr, len);
201     pthread_mutex_unlock(&g_randomLock);
202     if (ret != 0) {
203         HILOG_ERROR(SOFTBUS_HILOG_ID, "gen random error, ret[%d]", ret);
204         return SOFTBUS_ERR;
205     }
206     return SOFTBUS_OK;
207 }
208 
SoftBusGenerateSessionKey(char * key,uint32_t len)209 int32_t SoftBusGenerateSessionKey(char *key, uint32_t len)
210 {
211     if (SoftBusGenerateRandomArray((unsigned char*)key, len) != SOFTBUS_OK) {
212         HILOG_ERROR(SOFTBUS_HILOG_ID, "generate sessionKey error.");
213         return SOFTBUS_ENCRYPT_ERR;
214     }
215     return SOFTBUS_OK;
216 }
217 
SoftBusEncryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)218 int32_t SoftBusEncryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
219     unsigned char *encryptData, uint32_t *encryptLen)
220 {
221     if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
222         return SOFTBUS_INVALID_PARAM;
223     }
224 
225     if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
226         HILOG_ERROR(SOFTBUS_HILOG_ID, "generate random iv error.");
227         return SOFTBUS_ENCRYPT_ERR;
228     }
229     uint32_t outLen = inLen + OVERHEAD_LEN;
230     int32_t result = MbedAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
231     if (result <= 0) {
232         return SOFTBUS_ENCRYPT_ERR;
233     }
234     *encryptLen = result;
235     return SOFTBUS_OK;
236 }
237 
SoftBusEncryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen,int32_t seqNum)238 int32_t SoftBusEncryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
239     unsigned char *encryptData, uint32_t *encryptLen, int32_t seqNum)
240 {
241     if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
242         return SOFTBUS_INVALID_PARAM;
243     }
244     if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
245         HILOG_ERROR(SOFTBUS_HILOG_ID, "generate random iv error.");
246         return SOFTBUS_ENCRYPT_ERR;
247     }
248     if (memcpy_s(cipherKey->iv, sizeof(int32_t), &seqNum, sizeof(int32_t)) != EOK) {
249         return SOFTBUS_ENCRYPT_ERR;
250     }
251     uint32_t outLen = inLen + OVERHEAD_LEN;
252     int32_t result = MbedAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
253     if (result <= 0) {
254         return SOFTBUS_ENCRYPT_ERR;
255     }
256     *encryptLen = result;
257     return SOFTBUS_OK;
258 }
259 
SoftBusDecryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)260 int32_t SoftBusDecryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
261     unsigned char *decryptData, uint32_t *decryptLen)
262 {
263     if (cipherKey == NULL || input == NULL || inLen < GCM_IV_LEN || decryptData == NULL || decryptLen == NULL) {
264         return SOFTBUS_INVALID_PARAM;
265     }
266 
267     if (memcpy_s(cipherKey->iv, sizeof(cipherKey->iv), input, GCM_IV_LEN) != EOK) {
268         HILOG_ERROR(SOFTBUS_HILOG_ID, "copy iv failed.");
269         return SOFTBUS_ENCRYPT_ERR;
270     }
271     uint32_t outLen = inLen - OVERHEAD_LEN;
272     int32_t result = MbedAesGcmDecrypt(cipherKey, input, inLen, decryptData, outLen);
273     if (result <= 0) {
274         return SOFTBUS_ENCRYPT_ERR;
275     }
276     *decryptLen = (uint32_t)result;
277     return SOFTBUS_OK;
278 }
279 
SoftBusDecryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen,int32_t seqNum)280 int32_t SoftBusDecryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
281     unsigned char *decryptData, uint32_t *decryptLen, int32_t seqNum)
282 {
283     (void)seqNum;
284     return SoftBusDecryptData(cipherKey, input, inLen, decryptData, decryptLen);
285 }
286 
SoftBusCryptoRand(void)287 uint32_t SoftBusCryptoRand(void)
288 {
289     int32_t fd = SoftBusOpenFile("/dev/urandom", SOFTBUS_O_RDONLY);
290     if (fd < 0) {
291         HILOG_ERROR(SOFTBUS_HILOG_ID, "CryptoRand open file fail");
292         return 0;
293     }
294     uint32_t value = 0;
295     int32_t len = SoftBusReadFile(fd, &value, sizeof(uint32_t));
296     if (len < 0) {
297         HILOG_ERROR(SOFTBUS_HILOG_ID, "CryptoRand read file fail");
298         return 0;
299     }
300     SoftBusCloseFile(fd);
301     return value;
302 }
303