• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 "softbus_adapter_crypto.h"
17 
18 #include <securec.h>
19 
20 #include <openssl/evp.h>
21 #include <openssl/rand.h>
22 #include "softbus_adapter_file.h"
23 #include "softbus_adapter_log.h"
24 #include "softbus_errcode.h"
25 
26 static pthread_mutex_t g_randomLock = PTHREAD_MUTEX_INITIALIZER;
27 
28 #define OPENSSL_EVP_PADDING_FUNC_OPEN (1)
29 #define OPENSSL_EVP_PADDING_FUNC_CLOSE (0)
30 
31 #define EVP_AES_128_GCM_KEYLEN 16
32 #define EVP_AES_256_GCM_KEYLEN 32
33 
GetSslAlgorithmByKeyLen(uint32_t keyLen)34 static EVP_CIPHER *GetSslAlgorithmByKeyLen(uint32_t keyLen)
35 {
36     switch (keyLen) {
37         case EVP_AES_128_GCM_KEYLEN:
38             return (EVP_CIPHER *)EVP_aes_128_gcm();
39         case EVP_AES_256_GCM_KEYLEN:
40             return (EVP_CIPHER *)EVP_aes_256_gcm();
41     }
42     return NULL;
43 }
44 
OpensslEvpInit(EVP_CIPHER_CTX ** ctx,const AesGcmCipherKey * cipherkey,bool mode)45 static int32_t OpensslEvpInit(EVP_CIPHER_CTX **ctx, const AesGcmCipherKey *cipherkey, bool mode)
46 {
47     EVP_CIPHER *cipher = GetSslAlgorithmByKeyLen(cipherkey->keyLen);
48     if (cipher == NULL) {
49         HILOG_ERROR(SOFTBUS_HILOG_ID, "get cipher fail.");
50         return SOFTBUS_DECRYPT_ERR;
51     }
52     int32_t ret;
53     *ctx = EVP_CIPHER_CTX_new();
54     if (*ctx == NULL) {
55         return SOFTBUS_DECRYPT_ERR;
56     }
57     EVP_CIPHER_CTX_set_padding(*ctx, OPENSSL_EVP_PADDING_FUNC_OPEN);
58     if (mode == true) {
59         ret = EVP_EncryptInit_ex(*ctx, cipher, NULL, NULL, NULL);
60         if (ret != 1) {
61             HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP_EncryptInit_ex fail.");
62             EVP_CIPHER_CTX_free(*ctx);
63             return SOFTBUS_DECRYPT_ERR;
64         }
65     } else {
66         ret = EVP_DecryptInit_ex(*ctx, cipher, NULL, NULL, NULL);
67         if (ret != 1) {
68             HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP_DecryptInit_ex fail.");
69             EVP_CIPHER_CTX_free(*ctx);
70             return SOFTBUS_DECRYPT_ERR;
71         }
72     }
73     ret = EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_SET_IVLEN, GCM_IV_LEN, NULL);
74     if (ret != 1) {
75         HILOG_ERROR(SOFTBUS_HILOG_ID, "Set iv len fail.");
76         EVP_CIPHER_CTX_free(*ctx);
77         return SOFTBUS_DECRYPT_ERR;
78     }
79     return SOFTBUS_OK;
80 }
81 
PackIvAndTag(EVP_CIPHER_CTX * ctx,const AesGcmCipherKey * cipherkey,uint32_t dataLen,unsigned char * cipherText,uint32_t cipherTextLen)82 static int32_t PackIvAndTag(EVP_CIPHER_CTX *ctx, const AesGcmCipherKey *cipherkey,
83     uint32_t dataLen, unsigned char *cipherText, uint32_t cipherTextLen)
84 {
85     if ((dataLen + OVERHEAD_LEN) > cipherTextLen) {
86         HILOG_ERROR(SOFTBUS_HILOG_ID, "Encrypt invalid para.");
87         return SOFTBUS_ENCRYPT_ERR;
88     }
89     if (memcpy_s(cipherText, cipherTextLen - dataLen, cipherkey->iv, GCM_IV_LEN) != EOK) {
90         HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP memcpy iv fail.");
91         return SOFTBUS_ENCRYPT_ERR;
92     }
93     char tagbuf[TAG_LEN];
94     int ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAG_LEN, (void *)tagbuf);
95     if (ret != 1) {
96         HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP_CIPHER_CTX_ctrl fail.");
97         return SOFTBUS_DECRYPT_ERR;
98     }
99     if (memcpy_s(cipherText + dataLen + GCM_IV_LEN,
100         cipherTextLen - dataLen - GCM_IV_LEN, tagbuf, TAG_LEN) != EOK) {
101         HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP memcpy tag fail.");
102         return SOFTBUS_ENCRYPT_ERR;
103     }
104     return SOFTBUS_OK;
105 }
106 
SslAesGcmEncrypt(const AesGcmCipherKey * cipherkey,const unsigned char * plainText,uint32_t plainTextSize,unsigned char * cipherText,uint32_t cipherTextLen)107 static int32_t SslAesGcmEncrypt(const AesGcmCipherKey *cipherkey, const unsigned char *plainText,
108     uint32_t plainTextSize, unsigned char *cipherText, uint32_t cipherTextLen)
109 {
110     if ((cipherkey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL ||
111         (cipherTextLen < plainTextSize + OVERHEAD_LEN)) {
112         HILOG_ERROR(SOFTBUS_HILOG_ID, "Encrypt invalid para.");
113         return SOFTBUS_INVALID_PARAM;
114     }
115 
116     int32_t outlen = 0;
117     int32_t outbufLen;
118     EVP_CIPHER_CTX *ctx = NULL;
119     int32_t ret = OpensslEvpInit(&ctx, cipherkey, true);
120     if (ret != SOFTBUS_OK) {
121         HILOG_ERROR(SOFTBUS_HILOG_ID, "OpensslEvpInit fail.");
122         return SOFTBUS_DECRYPT_ERR;
123     }
124     ret = EVP_EncryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
125     if (ret != 1) {
126         HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP_EncryptInit_ex fail.");
127         EVP_CIPHER_CTX_free(ctx);
128         return SOFTBUS_DECRYPT_ERR;
129     }
130     ret = EVP_EncryptUpdate(ctx, cipherText + GCM_IV_LEN,
131         (int32_t *)&outbufLen, plainText, plainTextSize);
132     if (ret != 1) {
133         HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP_EncryptUpdate fail.");
134         EVP_CIPHER_CTX_free(ctx);
135         return SOFTBUS_DECRYPT_ERR;
136     }
137     outlen += outbufLen;
138     ret = EVP_EncryptFinal_ex(ctx, cipherText + GCM_IV_LEN + outbufLen, (int32_t *)&outbufLen);
139     if (ret != 1) {
140         HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP_EncryptFinal_ex fail.");
141         EVP_CIPHER_CTX_free(ctx);
142         return SOFTBUS_DECRYPT_ERR;
143     }
144     outlen += outbufLen;
145     ret = PackIvAndTag(ctx, cipherkey, outlen, cipherText, cipherTextLen);
146     if (ret != SOFTBUS_OK) {
147         HILOG_ERROR(SOFTBUS_HILOG_ID, "pack iv and tag fail.");
148         EVP_CIPHER_CTX_free(ctx);
149         return SOFTBUS_DECRYPT_ERR;
150     }
151     EVP_CIPHER_CTX_free(ctx);
152     return (outlen + OVERHEAD_LEN);
153 }
154 
SslAesGcmDecrypt(const AesGcmCipherKey * cipherkey,const unsigned char * cipherText,uint32_t cipherTextSize,unsigned char * plain,uint32_t plainLen)155 static int32_t SslAesGcmDecrypt(const AesGcmCipherKey *cipherkey, const unsigned char *cipherText,
156     uint32_t cipherTextSize, unsigned char *plain, uint32_t plainLen)
157 {
158     if ((cipherkey == NULL) || (cipherText == NULL) || (cipherTextSize <= OVERHEAD_LEN) || plain == NULL ||
159         (plainLen < cipherTextSize - OVERHEAD_LEN)) {
160         HILOG_ERROR(SOFTBUS_HILOG_ID, "Decrypt invalid para.");
161         return SOFTBUS_INVALID_PARAM;
162     }
163 
164     int32_t outlen = 0;
165     EVP_CIPHER_CTX *ctx = NULL;
166     int32_t ret = OpensslEvpInit(&ctx, cipherkey, false);
167     if (ret != SOFTBUS_OK) {
168         HILOG_ERROR(SOFTBUS_HILOG_ID, "OpensslEvpInit fail.");
169         return SOFTBUS_DECRYPT_ERR;
170     }
171     ret = EVP_DecryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
172     if (ret != 1) {
173         HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP_EncryptInit_ex fail.");
174         EVP_CIPHER_CTX_free(ctx);
175         return SOFTBUS_DECRYPT_ERR;
176     }
177     ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, TAG_LEN,
178         (void *)(cipherText + (cipherTextSize - TAG_LEN)));
179     if (ret != 1) {
180         HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP_DecryptUpdate fail.");
181         EVP_CIPHER_CTX_free(ctx);
182         return SOFTBUS_DECRYPT_ERR;
183     }
184     ret = EVP_DecryptUpdate(ctx, plain, (int32_t *)&plainLen,
185         cipherText + GCM_IV_LEN, cipherTextSize - OVERHEAD_LEN);
186     if (ret != 1) {
187         HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP_DecryptUpdate fail.");
188         EVP_CIPHER_CTX_free(ctx);
189         return SOFTBUS_DECRYPT_ERR;
190     }
191     outlen += plainLen;
192     ret = EVP_DecryptFinal_ex(ctx, plain + plainLen, (int32_t *)&plainLen);
193     if (ret != 1) {
194         HILOG_ERROR(SOFTBUS_HILOG_ID, "EVP_DecryptFinal_ex fail.");
195         EVP_CIPHER_CTX_free(ctx);
196         return SOFTBUS_DECRYPT_ERR;
197     }
198     outlen += plainLen;
199     EVP_CIPHER_CTX_free(ctx);
200     return outlen;
201 }
202 
SoftBusBase64Encode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)203 int32_t SoftBusBase64Encode(unsigned char *dst, size_t dlen,
204     size_t *olen, const unsigned char *src, size_t slen)
205 {
206     if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
207         return SOFTBUS_INVALID_PARAM;
208     }
209     *olen = 0;
210     int32_t outlen;
211     EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
212     if (ctx == NULL) {
213         return SOFTBUS_DECRYPT_ERR;
214     }
215     EVP_EncodeInit(ctx);
216     int32_t ret = EVP_EncodeUpdate(ctx, dst, &outlen, src, slen);
217     if (ret != 1) {
218         HILOG_ERROR(SOFTBUS_HILOG_ID, "[TRANS] EVP_EncodeUpdate fail.");
219         EVP_ENCODE_CTX_free(ctx);
220         return SOFTBUS_DECRYPT_ERR;
221     }
222     *olen += outlen;
223     EVP_EncodeFinal(ctx, dst + outlen, &outlen);
224     *olen += outlen;
225     if ((*olen > 0) && (dst[*olen - 1] == '\n')) {
226         (*olen)--;
227         dst[*olen] = 0;
228     }
229     EVP_ENCODE_CTX_free(ctx);
230     return SOFTBUS_OK;
231 }
232 
SoftBusBase64Decode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)233 int32_t SoftBusBase64Decode(unsigned char *dst, size_t dlen,
234     size_t *olen, const unsigned char *src, size_t slen)
235 {
236     if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
237         return SOFTBUS_INVALID_PARAM;
238     }
239     *olen = 0;
240     int32_t outlen;
241     EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
242     if (ctx == NULL) {
243         return SOFTBUS_DECRYPT_ERR;
244     }
245     EVP_DecodeInit(ctx);
246     int32_t ret = EVP_DecodeUpdate(ctx, dst, &outlen, src, slen);
247     if (ret == -1) {
248         HILOG_ERROR(SOFTBUS_HILOG_ID, "[TRANS] EVP_DecodeUpdate fail.");
249         EVP_ENCODE_CTX_free(ctx);
250         return SOFTBUS_DECRYPT_ERR;
251     }
252     *olen += outlen;
253     ret = EVP_DecodeFinal(ctx, dst + outlen, &outlen);
254     if (ret != 1) {
255         HILOG_ERROR(SOFTBUS_HILOG_ID, "[TRANS] EVP_DecodeFinal fail.");
256         EVP_ENCODE_CTX_free(ctx);
257         return SOFTBUS_DECRYPT_ERR;
258     }
259     *olen += outlen;
260     EVP_ENCODE_CTX_free(ctx);
261     return SOFTBUS_OK;
262 }
263 
SoftBusGenerateStrHash(const unsigned char * str,uint32_t len,unsigned char * hash)264 int32_t SoftBusGenerateStrHash(const unsigned char *str, uint32_t len, unsigned char *hash)
265 {
266     if (str == NULL || hash == NULL || len == 0) {
267         return SOFTBUS_INVALID_PARAM;
268     }
269     uint32_t olen;
270     int32_t ret = EVP_Digest(str, len, hash, &olen, EVP_sha256(), NULL);
271     if (ret != 1) {
272         HILOG_ERROR(SOFTBUS_HILOG_ID, "[TRANS] Get Openssl Hash fail.");
273         return SOFTBUS_DECRYPT_ERR;
274     }
275     return SOFTBUS_OK;
276 }
277 
SoftBusGenerateRandomArray(unsigned char * randStr,uint32_t len)278 int32_t SoftBusGenerateRandomArray(unsigned char *randStr, uint32_t len)
279 {
280     if (randStr == NULL || len == 0) {
281         return SOFTBUS_INVALID_PARAM;
282     }
283 
284     static bool initFlag = false;
285     int32_t ret;
286 
287     if (pthread_mutex_lock(&g_randomLock) != 0) {
288         HILOG_ERROR(SOFTBUS_HILOG_ID, "lock mutex failed.");
289         return SOFTBUS_ERR;
290     }
291 
292     if (initFlag == false) {
293         RAND_seed(randStr, (int32_t)len);
294         initFlag = true;
295     }
296 
297     ret = RAND_bytes(randStr, (int32_t)len);
298     pthread_mutex_unlock(&g_randomLock);
299     if (ret != 1) {
300         HILOG_ERROR(SOFTBUS_HILOG_ID, "gen random error, ret[%d]", ret);
301         return SOFTBUS_ERR;
302     }
303     return SOFTBUS_OK;
304 }
305 
SoftBusGenerateSessionKey(char * key,uint32_t len)306 int32_t SoftBusGenerateSessionKey(char *key, uint32_t len)
307 {
308     if (SoftBusGenerateRandomArray((unsigned char*)key, len) != SOFTBUS_OK) {
309         HILOG_ERROR(SOFTBUS_HILOG_ID, "generate sessionKey error.");
310         return SOFTBUS_ENCRYPT_ERR;
311     }
312     return SOFTBUS_OK;
313 }
314 
SoftBusEncryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)315 int32_t SoftBusEncryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
316     unsigned char *encryptData, uint32_t *encryptLen)
317 {
318     if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
319         return SOFTBUS_INVALID_PARAM;
320     }
321 
322     if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
323         HILOG_ERROR(SOFTBUS_HILOG_ID, "generate random iv error.");
324         return SOFTBUS_ENCRYPT_ERR;
325     }
326     uint32_t outLen = inLen + OVERHEAD_LEN;
327     int32_t result = SslAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
328     if (result <= 0) {
329         return SOFTBUS_ENCRYPT_ERR;
330     }
331     *encryptLen = result;
332     return SOFTBUS_OK;
333 }
334 
SoftBusEncryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen,int32_t seqNum)335 int32_t SoftBusEncryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
336     unsigned char *encryptData, uint32_t *encryptLen, int32_t seqNum)
337 {
338     if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
339         return SOFTBUS_INVALID_PARAM;
340     }
341     if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
342         HILOG_ERROR(SOFTBUS_HILOG_ID, "generate random iv error.");
343         return SOFTBUS_ENCRYPT_ERR;
344     }
345     if (memcpy_s(cipherKey->iv, sizeof(int32_t), &seqNum, sizeof(int32_t)) != EOK) {
346         return SOFTBUS_ENCRYPT_ERR;
347     }
348     uint32_t outLen = inLen + OVERHEAD_LEN;
349     int32_t result = SslAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
350     if (result <= 0) {
351         return SOFTBUS_ENCRYPT_ERR;
352     }
353     *encryptLen = result;
354     return SOFTBUS_OK;
355 }
356 
SoftBusDecryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)357 int32_t SoftBusDecryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
358     unsigned char *decryptData, uint32_t *decryptLen)
359 {
360     if (cipherKey == NULL || input == NULL || inLen < GCM_IV_LEN || decryptData == NULL || decryptLen == NULL) {
361         return SOFTBUS_INVALID_PARAM;
362     }
363 
364     if (memcpy_s(cipherKey->iv, sizeof(cipherKey->iv), input, GCM_IV_LEN) != EOK) {
365         HILOG_ERROR(SOFTBUS_HILOG_ID, "copy iv failed.");
366         return SOFTBUS_ENCRYPT_ERR;
367     }
368     uint32_t outLen = inLen - OVERHEAD_LEN;
369     int32_t result = SslAesGcmDecrypt(cipherKey, input, inLen, decryptData, outLen);
370     if (result <= 0) {
371         return SOFTBUS_ENCRYPT_ERR;
372     }
373     *decryptLen = (uint32_t)result;
374     return SOFTBUS_OK;
375 }
376 
SoftBusDecryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen,int32_t seqNum)377 int32_t SoftBusDecryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
378     unsigned char *decryptData, uint32_t *decryptLen, int32_t seqNum)
379 {
380     (void)seqNum;
381     return SoftBusDecryptData(cipherKey, input, inLen, decryptData, decryptLen);
382 }
383 
SoftBusCryptoRand(void)384 uint32_t SoftBusCryptoRand(void)
385 {
386     int32_t fd = SoftBusOpenFile("/dev/urandom", SOFTBUS_O_RDONLY);
387     if (fd < 0) {
388         HILOG_ERROR(SOFTBUS_HILOG_ID, "CryptoRand open file fail");
389         return 0;
390     }
391     uint32_t value = 0;
392     int32_t len = SoftBusReadFile(fd, &value, sizeof(uint32_t));
393     if (len < 0) {
394         HILOG_ERROR(SOFTBUS_HILOG_ID, "CryptoRand read file fail");
395         return 0;
396     }
397     SoftBusCloseFile(fd);
398     return value;
399 }
400