• 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/hmac.h>
22 #include <openssl/kdf.h>
23 #include <openssl/rand.h>
24 
25 #include "comm_log.h"
26 #include "softbus_adapter_file.h"
27 #include "softbus_adapter_mem.h"
28 #include "softbus_error_code.h"
29 
30 static SoftBusMutex g_randomLock;
31 
32 #define OPENSSL_EVP_PADDING_FUNC_OPEN  (1)
33 #define OPENSSL_EVP_PADDING_FUNC_CLOSE (0)
34 
35 #define EVP_AES_128_KEYLEN 16
36 #define EVP_AES_256_KEYLEN 32
37 
GetGcmAlgorithmByKeyLen(uint32_t keyLen)38 static EVP_CIPHER *GetGcmAlgorithmByKeyLen(uint32_t keyLen)
39 {
40     switch (keyLen) {
41         case EVP_AES_128_KEYLEN:
42             return (EVP_CIPHER *)EVP_aes_128_gcm();
43         case EVP_AES_256_KEYLEN:
44             return (EVP_CIPHER *)EVP_aes_256_gcm();
45         default:
46             return NULL;
47     }
48     return NULL;
49 }
50 
GetCtrAlgorithmByKeyLen(uint32_t keyLen)51 static EVP_CIPHER *GetCtrAlgorithmByKeyLen(uint32_t keyLen)
52 {
53     switch (keyLen) {
54         case EVP_AES_128_KEYLEN:
55             return (EVP_CIPHER *)EVP_aes_128_ctr();
56         case EVP_AES_256_KEYLEN:
57             return (EVP_CIPHER *)EVP_aes_256_ctr();
58         default:
59             return NULL;
60     }
61     return NULL;
62 }
63 
OpensslEvpInit(EVP_CIPHER_CTX ** ctx,uint32_t keyLen,bool mode)64 static int32_t OpensslEvpInit(EVP_CIPHER_CTX **ctx, uint32_t keyLen, bool mode)
65 {
66     EVP_CIPHER *cipher = GetGcmAlgorithmByKeyLen(keyLen);
67     if (cipher == NULL) {
68         COMM_LOGE(COMM_ADAPTER, "get cipher fail.");
69         return SOFTBUS_DECRYPT_ERR;
70     }
71     int32_t ret;
72     *ctx = EVP_CIPHER_CTX_new();
73     if (*ctx == NULL) {
74         return SOFTBUS_DECRYPT_ERR;
75     }
76     EVP_CIPHER_CTX_set_padding(*ctx, OPENSSL_EVP_PADDING_FUNC_OPEN);
77     if (mode == true) {
78         ret = EVP_EncryptInit_ex(*ctx, cipher, NULL, NULL, NULL);
79         if (ret != 1) {
80             COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
81             EVP_CIPHER_CTX_free(*ctx);
82             return SOFTBUS_DECRYPT_ERR;
83         }
84     } else {
85         ret = EVP_DecryptInit_ex(*ctx, cipher, NULL, NULL, NULL);
86         if (ret != 1) {
87             COMM_LOGE(COMM_ADAPTER, "EVP_DecryptInit_ex fail.");
88             EVP_CIPHER_CTX_free(*ctx);
89             return SOFTBUS_DECRYPT_ERR;
90         }
91     }
92     ret = EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_SET_IVLEN, GCM_IV_LEN, NULL);
93     if (ret != 1) {
94         COMM_LOGE(COMM_ADAPTER, "Set iv len fail.");
95         EVP_CIPHER_CTX_free(*ctx);
96         return SOFTBUS_DECRYPT_ERR;
97     }
98     return SOFTBUS_OK;
99 }
100 
PackIvAndTag(EVP_CIPHER_CTX * ctx,const AesGcmCipherKey * cipherkey,uint32_t dataLen,unsigned char * cipherText,uint32_t cipherTextLen)101 static int32_t PackIvAndTag(EVP_CIPHER_CTX *ctx, const AesGcmCipherKey *cipherkey, uint32_t dataLen,
102     unsigned char *cipherText, uint32_t cipherTextLen)
103 {
104     if ((dataLen + OVERHEAD_LEN) > cipherTextLen) {
105         COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
106         return SOFTBUS_ENCRYPT_ERR;
107     }
108     if (memcpy_s(cipherText, cipherTextLen - dataLen, cipherkey->iv, GCM_IV_LEN) != EOK) {
109         COMM_LOGE(COMM_ADAPTER, "EVP memcpy iv fail.");
110         return SOFTBUS_ENCRYPT_ERR;
111     }
112     char tagbuf[TAG_LEN];
113     int ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAG_LEN, (void *)tagbuf);
114     if (ret != 1) {
115         COMM_LOGE(COMM_ADAPTER, "EVP_CIPHER_CTX_ctrl fail.");
116         return SOFTBUS_DECRYPT_ERR;
117     }
118     if (memcpy_s(cipherText + dataLen + GCM_IV_LEN, cipherTextLen - dataLen - GCM_IV_LEN, tagbuf, TAG_LEN) != EOK) {
119         COMM_LOGE(COMM_ADAPTER, "EVP memcpy tag fail.");
120         return SOFTBUS_ENCRYPT_ERR;
121     }
122     return SOFTBUS_OK;
123 }
124 
SslAesGcmEncrypt(const AesGcmCipherKey * cipherkey,const unsigned char * plainText,uint32_t plainTextSize,unsigned char * cipherText,uint32_t cipherTextLen)125 static int32_t SslAesGcmEncrypt(const AesGcmCipherKey *cipherkey, const unsigned char *plainText,
126     uint32_t plainTextSize, unsigned char *cipherText, uint32_t cipherTextLen)
127 {
128     if ((cipherkey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL ||
129         (cipherTextLen < plainTextSize + OVERHEAD_LEN)) {
130         COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
131         return SOFTBUS_INVALID_PARAM;
132     }
133 
134     int32_t outlen = 0;
135     int32_t outbufLen;
136     EVP_CIPHER_CTX *ctx = NULL;
137     int32_t ret = OpensslEvpInit(&ctx, cipherkey->keyLen, true);
138     if (ret != SOFTBUS_OK) {
139         COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
140         return SOFTBUS_DECRYPT_ERR;
141     }
142     ret = EVP_EncryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
143     if (ret != 1) {
144         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
145         EVP_CIPHER_CTX_free(ctx);
146         return SOFTBUS_DECRYPT_ERR;
147     }
148     ret = EVP_EncryptUpdate(ctx, cipherText + GCM_IV_LEN, (int32_t *)&outbufLen, plainText, plainTextSize);
149     if (ret != 1) {
150         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptUpdate fail.");
151         EVP_CIPHER_CTX_free(ctx);
152         return SOFTBUS_DECRYPT_ERR;
153     }
154     outlen += outbufLen;
155     ret = EVP_EncryptFinal_ex(ctx, cipherText + GCM_IV_LEN + outbufLen, (int32_t *)&outbufLen);
156     if (ret != 1) {
157         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptFinal_ex fail.");
158         EVP_CIPHER_CTX_free(ctx);
159         return SOFTBUS_DECRYPT_ERR;
160     }
161     outlen += outbufLen;
162     ret = PackIvAndTag(ctx, cipherkey, outlen, cipherText, cipherTextLen);
163     if (ret != SOFTBUS_OK) {
164         COMM_LOGE(COMM_ADAPTER, "pack iv and tag fail.");
165         EVP_CIPHER_CTX_free(ctx);
166         return SOFTBUS_DECRYPT_ERR;
167     }
168     EVP_CIPHER_CTX_free(ctx);
169     return (outlen + OVERHEAD_LEN);
170 }
171 
SslAesGcmDecrypt(const AesGcmCipherKey * cipherkey,const unsigned char * cipherText,uint32_t cipherTextSize,unsigned char * plain,uint32_t plainLen)172 static int32_t SslAesGcmDecrypt(const AesGcmCipherKey *cipherkey, const unsigned char *cipherText,
173     uint32_t cipherTextSize, unsigned char *plain, uint32_t plainLen)
174 {
175     if ((cipherkey == NULL) || (cipherText == NULL) || (cipherTextSize <= OVERHEAD_LEN) || plain == NULL ||
176         (plainLen < cipherTextSize - OVERHEAD_LEN)) {
177         COMM_LOGE(COMM_ADAPTER, "Decrypt invalid para.");
178         return SOFTBUS_INVALID_PARAM;
179     }
180 
181     int32_t outLen = 0;
182     EVP_CIPHER_CTX *ctx = NULL;
183     int32_t ret = OpensslEvpInit(&ctx, cipherkey->keyLen, false);
184     if (ret != SOFTBUS_OK) {
185         COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
186         return SOFTBUS_DECRYPT_ERR;
187     }
188     ret = EVP_DecryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
189     if (ret != 1) {
190         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
191         goto EXIT;
192     }
193     ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, TAG_LEN, (void *)(cipherText + (cipherTextSize - TAG_LEN)));
194     if (ret != 1) {
195         COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
196         goto EXIT;
197     }
198     ret = EVP_DecryptUpdate(ctx, plain, (int32_t *)&plainLen, cipherText + GCM_IV_LEN, cipherTextSize - OVERHEAD_LEN);
199     if (ret != 1) {
200         COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
201         goto EXIT;
202     }
203     if (plainLen > INT32_MAX) {
204         COMM_LOGE(COMM_ADAPTER, "PlainLen convert overflow.");
205         goto EXIT;
206     }
207     outLen += (int32_t)plainLen;
208     ret = EVP_DecryptFinal_ex(ctx, plain + plainLen, (int32_t *)&plainLen);
209     if (ret != 1) {
210         COMM_LOGE(COMM_ADAPTER, "EVP_DecryptFinal_ex fail.");
211         goto EXIT;
212     }
213     if ((int32_t)plainLen > INT32_MAX - outLen) {
214         COMM_LOGE(COMM_ADAPTER, "outLen convert overflow.");
215         goto EXIT;
216     }
217     outLen += (int32_t)plainLen;
218     EVP_CIPHER_CTX_free(ctx);
219     return outLen;
220 EXIT:
221     EVP_CIPHER_CTX_free(ctx);
222     return SOFTBUS_DECRYPT_ERR;
223 }
224 
HandleError(EVP_CIPHER_CTX * ctx,const char * buf)225 static int32_t HandleError(EVP_CIPHER_CTX *ctx, const char *buf)
226 {
227     if (buf != NULL) {
228         COMM_LOGE(COMM_ADAPTER, "buf=%{public}s", buf);
229     }
230     if (ctx != NULL) {
231         EVP_CIPHER_CTX_free(ctx);
232     }
233     return SOFTBUS_DECRYPT_ERR;
234 }
235 
SoftBusBase64Encode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)236 int32_t SoftBusBase64Encode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen)
237 {
238     if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
239         return SOFTBUS_INVALID_PARAM;
240     }
241     *olen = 0;
242     int32_t outlen;
243     EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
244     if (ctx == NULL) {
245         return SOFTBUS_DECRYPT_ERR;
246     }
247     unsigned char *dstTmp = SoftBusCalloc(EVP_ENCODE_LENGTH(slen));
248     if (dstTmp == NULL) {
249         COMM_LOGE(COMM_ADAPTER, "[TRANS] SoftBusCalloc fail.");
250         EVP_ENCODE_CTX_free(ctx);
251         return SOFTBUS_MEM_ERR;
252     }
253     EVP_EncodeInit(ctx);
254     int32_t ret = EVP_EncodeUpdate(ctx, dstTmp, &outlen, src, slen);
255     if (ret != 1) {
256         COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_EncodeUpdate fail.");
257         EVP_ENCODE_CTX_free(ctx);
258         SoftBusFree(dstTmp);
259         return SOFTBUS_DECRYPT_ERR;
260     }
261     *olen += outlen;
262     EVP_EncodeFinal(ctx, dstTmp + outlen, &outlen);
263     *olen += outlen;
264 
265     if (*olen > dlen) {
266         COMM_LOGE(COMM_ADAPTER, "[TRANS] invalid dlen=%{public}zu, olen=%{public}zu.", dlen, *olen);
267         EVP_ENCODE_CTX_free(ctx);
268         SoftBusFree(dstTmp);
269         return SOFTBUS_INVALID_PARAM;
270     }
271 
272     ret = memcpy_s(dst, dlen, dstTmp, *olen);
273     if (ret != EOK) {
274         COMM_LOGE(COMM_ADAPTER, "[TRANS] memcpy_s failed.");
275         EVP_ENCODE_CTX_free(ctx);
276         SoftBusFree(dstTmp);
277         return SOFTBUS_MEM_ERR;
278     }
279     if ((*olen > 0) && (dst[*olen - 1] == '\n')) {
280         (*olen)--;
281         dst[*olen] = 0;
282     }
283 
284     EVP_ENCODE_CTX_free(ctx);
285     SoftBusFree(dstTmp);
286     return SOFTBUS_OK;
287 }
288 
SoftBusBase64Decode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)289 int32_t SoftBusBase64Decode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen)
290 {
291     if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
292         return SOFTBUS_INVALID_PARAM;
293     }
294     *olen = 0;
295     int32_t outlen;
296     EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
297     if (ctx == NULL) {
298         return SOFTBUS_DECRYPT_ERR;
299     }
300     unsigned char *dstTmp = SoftBusCalloc(EVP_DECODE_LENGTH(slen));
301     if (dstTmp == NULL) {
302         COMM_LOGE(COMM_ADAPTER, "[TRANS] SoftBusCalloc fail.");
303         EVP_ENCODE_CTX_free(ctx);
304         return SOFTBUS_MEM_ERR;
305     }
306     EVP_DecodeInit(ctx);
307     int32_t ret = EVP_DecodeUpdate(ctx, dstTmp, &outlen, src, slen);
308     if (ret == -1) {
309         COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_DecodeUpdate fail.");
310         ret = SOFTBUS_DECRYPT_ERR;
311         goto FINISHED;
312     }
313     *olen += outlen;
314     ret = EVP_DecodeFinal(ctx, dstTmp + outlen, &outlen);
315     if (ret != 1) {
316         COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_DecodeFinal fail.");
317         ret = SOFTBUS_DECRYPT_ERR;
318         goto FINISHED;
319     }
320     *olen += outlen;
321     if (*olen > dlen) {
322         COMM_LOGE(COMM_ADAPTER, "[TRANS] invalid dlen=%{public}zu, olen=%{public}zu.", dlen, *olen);
323         ret = SOFTBUS_INVALID_PARAM;
324         goto FINISHED;
325     }
326 
327     ret = memcpy_s(dst, dlen, dstTmp, *olen);
328     if (ret != EOK) {
329         COMM_LOGE(COMM_ADAPTER, "[TRANS] memcpy_s failed.");
330         ret = SOFTBUS_MEM_ERR;
331         goto FINISHED;
332     }
333     ret = SOFTBUS_OK;
334 FINISHED:
335     EVP_ENCODE_CTX_free(ctx);
336     SoftBusFree(dstTmp);
337     return ret;
338 }
339 
SoftBusGenerateStrHash(const unsigned char * str,uint32_t len,unsigned char * hash)340 int32_t SoftBusGenerateStrHash(const unsigned char *str, uint32_t len, unsigned char *hash)
341 {
342     if (str == NULL || hash == NULL || len == 0) {
343         return SOFTBUS_INVALID_PARAM;
344     }
345     uint32_t olen;
346     int32_t ret = EVP_Digest(str, len, hash, &olen, EVP_sha256(), NULL);
347     if (ret != 1) {
348         COMM_LOGE(COMM_ADAPTER, "[TRANS] Get Openssl Hash fail.");
349         return SOFTBUS_DECRYPT_ERR;
350     }
351     return SOFTBUS_OK;
352 }
353 
SoftBusGenerateRandomArray(unsigned char * randStr,uint32_t len)354 int32_t SoftBusGenerateRandomArray(unsigned char *randStr, uint32_t len)
355 {
356     if (randStr == NULL || len == 0) {
357         return SOFTBUS_INVALID_PARAM;
358     }
359 
360     static bool initFlag = false;
361     int32_t ret;
362 
363     if (SoftBusMutexInit(&g_randomLock, NULL) != SOFTBUS_OK) {
364         COMM_LOGE(COMM_ADAPTER, "init mutex failed.");
365         return SOFTBUS_ERR;
366     }
367 
368     if (SoftBusMutexLock(&g_randomLock) != SOFTBUS_OK) {
369         COMM_LOGE(COMM_ADAPTER, "lock mutex failed");
370         return SOFTBUS_ERR;
371     }
372     if (initFlag == false) {
373         RAND_seed(randStr, (int32_t)len);
374         initFlag = true;
375     }
376 
377     ret = RAND_bytes(randStr, (int32_t)len);
378     SoftBusMutexUnlock(&g_randomLock);
379     if (ret != 1) {
380         COMM_LOGE(COMM_ADAPTER, "gen random error, ret=%{public}d", ret);
381         return SOFTBUS_ERR;
382     }
383     return SOFTBUS_OK;
384 }
385 
SoftBusGenerateSessionKey(char * key,uint32_t len)386 int32_t SoftBusGenerateSessionKey(char *key, uint32_t len)
387 {
388     if (SoftBusGenerateRandomArray((unsigned char *)key, len) != SOFTBUS_OK) {
389         COMM_LOGE(COMM_ADAPTER, "generate sessionKey error.");
390         return SOFTBUS_ENCRYPT_ERR;
391     }
392     return SOFTBUS_OK;
393 }
394 
SoftBusEncryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)395 int32_t SoftBusEncryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
396     unsigned char *encryptData, uint32_t *encryptLen)
397 {
398     if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
399         return SOFTBUS_INVALID_PARAM;
400     }
401 
402     if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
403         COMM_LOGE(COMM_ADAPTER, "generate random iv error.");
404         return SOFTBUS_ENCRYPT_ERR;
405     }
406     uint32_t outLen = inLen + OVERHEAD_LEN;
407     int32_t result = SslAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
408     if (result <= 0) {
409         return SOFTBUS_ENCRYPT_ERR;
410     }
411     *encryptLen = result;
412     return SOFTBUS_OK;
413 }
414 
SoftBusEncryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen,int32_t seqNum)415 int32_t SoftBusEncryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
416     unsigned char *encryptData, uint32_t *encryptLen, int32_t seqNum)
417 {
418     if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
419         return SOFTBUS_INVALID_PARAM;
420     }
421     if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
422         COMM_LOGE(COMM_ADAPTER, "generate random iv error.");
423         return SOFTBUS_ENCRYPT_ERR;
424     }
425     if (memcpy_s(cipherKey->iv, sizeof(int32_t), &seqNum, sizeof(int32_t)) != EOK) {
426         return SOFTBUS_ENCRYPT_ERR;
427     }
428     uint32_t outLen = inLen + OVERHEAD_LEN;
429     int32_t result = SslAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
430     if (result <= 0) {
431         return SOFTBUS_ENCRYPT_ERR;
432     }
433     *encryptLen = result;
434     return SOFTBUS_OK;
435 }
436 
SoftBusDecryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)437 int32_t SoftBusDecryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
438     unsigned char *decryptData, uint32_t *decryptLen)
439 {
440     if (cipherKey == NULL || input == NULL || inLen < GCM_IV_LEN || decryptData == NULL || decryptLen == NULL) {
441         return SOFTBUS_INVALID_PARAM;
442     }
443 
444     if (memcpy_s(cipherKey->iv, sizeof(cipherKey->iv), input, GCM_IV_LEN) != EOK) {
445         COMM_LOGE(COMM_ADAPTER, "copy iv failed.");
446         return SOFTBUS_MEM_ERR;
447     }
448     uint32_t outLen = inLen - OVERHEAD_LEN;
449     int32_t result = SslAesGcmDecrypt(cipherKey, input, inLen, decryptData, outLen);
450     if (result <= 0) {
451         return SOFTBUS_DECRYPT_ERR;
452     }
453     *decryptLen = (uint32_t)result;
454     return SOFTBUS_OK;
455 }
456 
SoftBusDecryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen,int32_t seqNum)457 int32_t SoftBusDecryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
458     unsigned char *decryptData, uint32_t *decryptLen, int32_t seqNum)
459 {
460     (void)seqNum;
461     return SoftBusDecryptData(cipherKey, input, inLen, decryptData, decryptLen);
462 }
463 
SoftBusCryptoRand(void)464 uint32_t SoftBusCryptoRand(void)
465 {
466     int32_t fd = SoftBusOpenFile("/dev/urandom", SOFTBUS_O_RDONLY);
467     if (fd < 0) {
468         COMM_LOGE(COMM_ADAPTER, "CryptoRand open file fail");
469         return 0;
470     }
471     uint32_t value = 0;
472     int32_t len = SoftBusReadFile(fd, &value, sizeof(uint32_t));
473     if (len < 0) {
474         COMM_LOGE(COMM_ADAPTER, "CryptoRand read file fail");
475         SoftBusCloseFile(fd);
476         return 0;
477     }
478     SoftBusCloseFile(fd);
479     return value;
480 }
481 
SoftBusEncryptDataByCtr(AesCtrCipherKey * key,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)482 int32_t SoftBusEncryptDataByCtr(
483     AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen, unsigned char *encryptData, uint32_t *encryptLen)
484 {
485     if (key == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
486         return SOFTBUS_INVALID_PARAM;
487     }
488     EVP_CIPHER_CTX *ctx = NULL;
489     int32_t len = 0;
490     *encryptLen = 0;
491     EVP_CIPHER *cipher = NULL;
492     if (!(cipher = GetCtrAlgorithmByKeyLen(key->keyLen))) {
493         return HandleError(ctx, "get cipher failed");
494     }
495     if (!(ctx = EVP_CIPHER_CTX_new())) {
496         return HandleError(ctx, "EVP_CIPHER_CTX_new ctr failed");
497     }
498     if (EVP_EncryptInit_ex(ctx, cipher, NULL, key->key, key->iv) != 1) {
499         return HandleError(ctx, "EVP_EncryptInit_ex ctr failed");
500     }
501     if (EVP_EncryptUpdate(ctx, encryptData, &len, input, inLen) != 1) {
502         return HandleError(ctx, "EVP_EncryptUpdate ctr failed");
503     }
504     *encryptLen += len;
505     if (EVP_EncryptFinal_ex(ctx, encryptData + len, &len) != 1) {
506         return HandleError(ctx, "EVP_EncryptFinal_ex ctr failed");
507     }
508     *encryptLen += len;
509     EVP_CIPHER_CTX_free(ctx);
510     return SOFTBUS_OK;
511 }
512 
SoftBusDecryptDataByCtr(AesCtrCipherKey * key,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)513 int32_t SoftBusDecryptDataByCtr(
514     AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen, unsigned char *decryptData, uint32_t *decryptLen)
515 {
516     if (key == NULL || input == NULL || inLen == 0 || decryptData == NULL || decryptLen == NULL) {
517         return SOFTBUS_INVALID_PARAM;
518     }
519     EVP_CIPHER_CTX *ctx = NULL;
520     int32_t len = 0;
521     *decryptLen = 0;
522     EVP_CIPHER *cipher = NULL;
523     if (!(cipher = GetCtrAlgorithmByKeyLen(key->keyLen))) {
524         return HandleError(ctx, "get cipher failed");
525     }
526     if (!(ctx = EVP_CIPHER_CTX_new())) {
527         return HandleError(ctx, "EVP_CIPHER_CTX_new ctr failed");
528     }
529     if (EVP_DecryptInit_ex(ctx, cipher, NULL, key->key, key->iv) != 1) {
530         return HandleError(ctx, "EVP_DecryptInit_ex ctr failed");
531     }
532     if (EVP_DecryptUpdate(ctx, decryptData, &len, input, inLen) != 1) {
533         return HandleError(ctx, "EVP_DecryptUpdate ctr failed");
534     }
535     *decryptLen += len;
536     if (EVP_DecryptFinal_ex(ctx, decryptData + len, &len) != 1) {
537         return HandleError(ctx, "EVP_DecryptFinal_ex ctr failed");
538     }
539     *decryptLen += len;
540     EVP_CIPHER_CTX_free(ctx);
541     return SOFTBUS_OK;
542 }
543 
PackTag(EVP_CIPHER_CTX * ctx,uint32_t dataLen,unsigned char * cipherText,uint32_t cipherTextLen)544 static int32_t PackTag(EVP_CIPHER_CTX *ctx, uint32_t dataLen, unsigned char *cipherText, uint32_t cipherTextLen)
545 {
546     if ((dataLen + SHORT_TAG_LEN) > cipherTextLen) {
547         COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
548         return SOFTBUS_ENCRYPT_ERR;
549     }
550 
551     char tagbuf[SHORT_TAG_LEN];
552     int ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, SHORT_TAG_LEN, (void *)tagbuf);
553     if (ret != 1) {
554         COMM_LOGE(COMM_ADAPTER, "EVP_CIPHER_CTX_ctrl fail.");
555         return SOFTBUS_ENCRYPT_ERR;
556     }
557     if (memcpy_s(cipherText + dataLen, cipherTextLen - dataLen, tagbuf, SHORT_TAG_LEN) != EOK) {
558         COMM_LOGE(COMM_ADAPTER, "EVP memcpy tag fail.");
559         return SOFTBUS_ENCRYPT_ERR;
560     }
561     return SOFTBUS_OK;
562 }
563 
SslAesGcm128Encrypt(const AesGcm128CipherKey * cipherkey,const unsigned char * plainText,uint32_t plainTextSize,unsigned char * cipherText,uint32_t cipherTextLen)564 static int32_t SslAesGcm128Encrypt(const AesGcm128CipherKey *cipherkey, const unsigned char *plainText,
565     uint32_t plainTextSize, unsigned char *cipherText, uint32_t cipherTextLen)
566 {
567     if ((cipherkey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL ||
568         (cipherTextLen < plainTextSize + SHORT_TAG_LEN)) {
569         COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
570         return SOFTBUS_INVALID_PARAM;
571     }
572 
573     int32_t outlen = 0;
574     int32_t outbufLen;
575     EVP_CIPHER_CTX *ctx = NULL;
576     int32_t ret = OpensslEvpInit(&ctx, cipherkey->keyLen, true);
577     if (ret != SOFTBUS_OK) {
578         COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
579         return SOFTBUS_ENCRYPT_ERR;
580     }
581     ret = EVP_EncryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
582     if (ret != 1) {
583         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
584         EVP_CIPHER_CTX_free(ctx);
585         return SOFTBUS_ENCRYPT_ERR;
586     }
587     ret = EVP_EncryptUpdate(ctx, cipherText, (int32_t *)&outbufLen, plainText, plainTextSize);
588     if (ret != 1) {
589         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptUpdate fail.");
590         EVP_CIPHER_CTX_free(ctx);
591         return SOFTBUS_ENCRYPT_ERR;
592     }
593     outlen += outbufLen;
594     ret = EVP_EncryptFinal_ex(ctx, cipherText + outbufLen, (int32_t *)&outbufLen);
595     if (ret != 1) {
596         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptFinal_ex fail.");
597         EVP_CIPHER_CTX_free(ctx);
598         return SOFTBUS_ENCRYPT_ERR;
599     }
600     outlen += outbufLen;
601     ret = PackTag(ctx, outlen, cipherText, cipherTextLen);
602     if (ret != SOFTBUS_OK) {
603         COMM_LOGE(COMM_ADAPTER, "pack iv and tag fail.");
604         EVP_CIPHER_CTX_free(ctx);
605         return SOFTBUS_ENCRYPT_ERR;
606     }
607     EVP_CIPHER_CTX_free(ctx);
608     return (outlen + SHORT_TAG_LEN);
609 }
610 
SoftBusEncryptDataByGcm128(AesGcm128CipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)611 int32_t SoftBusEncryptDataByGcm128(AesGcm128CipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
612     unsigned char *encryptData, uint32_t *encryptLen)
613 {
614     if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
615         COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
616         return SOFTBUS_INVALID_PARAM;
617     }
618     uint32_t outLen = inLen + SHORT_TAG_LEN;
619     int32_t result = SslAesGcm128Encrypt(cipherKey, input, inLen, encryptData, outLen);
620     if (result <= 0) {
621         COMM_LOGE(COMM_ADAPTER, "SslAesGcmEncrypt error.");
622         return SOFTBUS_ENCRYPT_ERR;
623     }
624     *encryptLen = result;
625     return SOFTBUS_OK;
626 }
627 
SslAesGcm128Decryp(const AesGcm128CipherKey * cipherkey,const unsigned char * cipherText,uint32_t cipherTextSize,unsigned char * plain,uint32_t plainLen)628 static int32_t SslAesGcm128Decryp(const AesGcm128CipherKey *cipherkey, const unsigned char *cipherText,
629     uint32_t cipherTextSize, unsigned char *plain, uint32_t plainLen)
630 {
631     if ((cipherkey == NULL) || (cipherText == NULL) || (cipherTextSize <= SHORT_TAG_LEN) || plain == NULL ||
632         (plainLen < cipherTextSize - SHORT_TAG_LEN)) {
633         COMM_LOGE(COMM_ADAPTER, "Decrypt invalid para.");
634         return SOFTBUS_INVALID_PARAM;
635     }
636 
637     int32_t outLen = 0;
638     EVP_CIPHER_CTX *ctx = NULL;
639     int32_t ret = OpensslEvpInit(&ctx, cipherkey->keyLen, false);
640     if (ret != SOFTBUS_OK) {
641         COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
642         return SOFTBUS_DECRYPT_ERR;
643     }
644     ret = EVP_DecryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
645     if (ret != 1) {
646         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
647         goto EXIT;
648     }
649     ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, SHORT_TAG_LEN,
650         (void *)(cipherText + (cipherTextSize - SHORT_TAG_LEN)));
651     if (ret != 1) {
652         COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
653         goto EXIT;
654     }
655     ret = EVP_DecryptUpdate(ctx, plain, (int32_t *)&plainLen, cipherText, cipherTextSize - SHORT_TAG_LEN);
656     if (ret != 1) {
657         COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
658         goto EXIT;
659     }
660     if (plainLen > INT32_MAX) {
661         COMM_LOGE(COMM_ADAPTER, "PlainLen convert overflow.");
662         goto EXIT;
663     }
664     outLen += (int32_t)plainLen;
665     ret = EVP_DecryptFinal_ex(ctx, plain + plainLen, (int32_t *)&plainLen);
666     if (ret != 1) {
667         COMM_LOGE(COMM_ADAPTER, "EVP_DecryptFinal_ex fail.");
668         goto EXIT;
669     }
670     if ((int32_t)plainLen > INT32_MAX - outLen) {
671         COMM_LOGE(COMM_ADAPTER, "outLen convert overflow.");
672         goto EXIT;
673     }
674     outLen += (int32_t)plainLen;
675     EVP_CIPHER_CTX_free(ctx);
676     return outLen;
677 EXIT:
678     EVP_CIPHER_CTX_free(ctx);
679     return SOFTBUS_DECRYPT_ERR;
680 }
681 
SoftBusDecryptDataByGcm128(AesGcm128CipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)682 int32_t SoftBusDecryptDataByGcm128(AesGcm128CipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
683     unsigned char *decryptData, uint32_t *decryptLen)
684 {
685     if (cipherKey == NULL || input == NULL || inLen < SHORT_TAG_LEN || decryptData == NULL || decryptLen == NULL) {
686         return SOFTBUS_INVALID_PARAM;
687     }
688 
689     uint32_t outLen = inLen - SHORT_TAG_LEN;
690     int32_t result = SslAesGcm128Decryp(cipherKey, input, inLen, decryptData, outLen);
691     if (result <= 0) {
692         return SOFTBUS_DECRYPT_ERR;
693     }
694     *decryptLen = (uint32_t)result;
695     return SOFTBUS_OK;
696 }
697 
SoftBusCalcHKDF(const uint8_t * inData,uint32_t inLen,uint8_t * outData,uint32_t outLen)698 int32_t SoftBusCalcHKDF(const uint8_t *inData, uint32_t inLen, uint8_t *outData, uint32_t outLen)
699 {
700     if (outLen > HKDF_BYTES_LEN || inData == NULL || outData == NULL) {
701         COMM_LOGE(COMM_ADAPTER, "calc HKDF invalid para.");
702         return SOFTBUS_INVALID_PARAM;
703     }
704     EVP_PKEY_CTX *pctx;
705     const EVP_MD *md = EVP_sha256();
706     if (md == NULL) {
707         COMM_LOGE(COMM_ADAPTER, "get EVP_sha256 fail.");
708         return SOFTBUS_CALC_HKDF_FAIL;
709     }
710     unsigned char tmp[HKDF_BYTES_LEN] = { 0 };
711     size_t tmpLen = sizeof(tmp);
712     pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL);
713     if (pctx == NULL) {
714         COMM_LOGE(COMM_ADAPTER, "EVP_PKEY_CTX_new_id fail.");
715         return SOFTBUS_CALC_HKDF_FAIL;
716     }
717     int32_t ret = EVP_PKEY_derive_init(pctx);
718     if (ret <= 0) {
719         COMM_LOGE(COMM_ADAPTER, "EVP_PKEY_derive_init fail.");
720         return SOFTBUS_CALC_HKDF_FAIL;
721     }
722     ret = EVP_PKEY_CTX_set_hkdf_md(pctx, md);
723     if (ret <= 0) {
724         COMM_LOGE(COMM_ADAPTER, "EVP_PKEY_CTX_set_hkdf_md fail.");
725         return SOFTBUS_CALC_HKDF_FAIL;
726     }
727     ret = EVP_PKEY_CTX_set1_hkdf_key(pctx, inData, inLen);
728     if (ret <= 0) {
729         COMM_LOGE(COMM_ADAPTER, "EVP_PKEY_CTX_set1_hkdf_key fail.");
730         EVP_PKEY_CTX_free(pctx);
731         return SOFTBUS_CALC_HKDF_FAIL;
732     }
733     ret = EVP_PKEY_derive(pctx, tmp, &tmpLen);
734     if (ret <= 0) {
735         COMM_LOGE(COMM_ADAPTER, "EVP_PKEY_derive fail.");
736         EVP_PKEY_CTX_free(pctx);
737         return SOFTBUS_CALC_HKDF_FAIL;
738     }
739     if (memcpy_s(outData, outLen, tmp, outLen) != EOK) {
740         COMM_LOGE(COMM_ADAPTER, "memcpy_s fail.");
741         EVP_PKEY_CTX_free(pctx);
742         return SOFTBUS_CALC_HKDF_FAIL;
743     }
744     EVP_PKEY_CTX_free(pctx);
745     return SOFTBUS_OK;
746 }
747 
748