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 
23 #include "comm_log.h"
24 #include "softbus_adapter_file.h"
25 #include "softbus_adapter_mem.h"
26 #include "softbus_errcode.h"
27 
28 static SoftBusMutex g_randomLock;
29 
30 #define OPENSSL_EVP_PADDING_FUNC_OPEN  (1)
31 #define OPENSSL_EVP_PADDING_FUNC_CLOSE (0)
32 
33 #define EVP_AES_128_KEYLEN 16
34 #define EVP_AES_256_KEYLEN 32
35 
GetGcmAlgorithmByKeyLen(uint32_t keyLen)36 static EVP_CIPHER *GetGcmAlgorithmByKeyLen(uint32_t keyLen)
37 {
38     switch (keyLen) {
39         case EVP_AES_128_KEYLEN:
40             return (EVP_CIPHER *)EVP_aes_128_gcm();
41         case EVP_AES_256_KEYLEN:
42             return (EVP_CIPHER *)EVP_aes_256_gcm();
43         default:
44             return NULL;
45     }
46     return NULL;
47 }
48 
GetCtrAlgorithmByKeyLen(uint32_t keyLen)49 static EVP_CIPHER *GetCtrAlgorithmByKeyLen(uint32_t keyLen)
50 {
51     switch (keyLen) {
52         case EVP_AES_128_KEYLEN:
53             return (EVP_CIPHER *)EVP_aes_128_ctr();
54         case EVP_AES_256_KEYLEN:
55             return (EVP_CIPHER *)EVP_aes_256_ctr();
56         default:
57             return NULL;
58     }
59     return NULL;
60 }
61 
OpensslEvpInit(EVP_CIPHER_CTX ** ctx,const AesGcmCipherKey * cipherkey,bool mode)62 static int32_t OpensslEvpInit(EVP_CIPHER_CTX **ctx, const AesGcmCipherKey *cipherkey, bool mode)
63 {
64     EVP_CIPHER *cipher = GetGcmAlgorithmByKeyLen(cipherkey->keyLen);
65     if (cipher == NULL) {
66         COMM_LOGE(COMM_ADAPTER, "get cipher fail.");
67         return SOFTBUS_DECRYPT_ERR;
68     }
69     int32_t ret;
70     *ctx = EVP_CIPHER_CTX_new();
71     if (*ctx == NULL) {
72         return SOFTBUS_DECRYPT_ERR;
73     }
74     EVP_CIPHER_CTX_set_padding(*ctx, OPENSSL_EVP_PADDING_FUNC_OPEN);
75     if (mode == true) {
76         ret = EVP_EncryptInit_ex(*ctx, cipher, NULL, NULL, NULL);
77         if (ret != 1) {
78             COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
79             EVP_CIPHER_CTX_free(*ctx);
80             return SOFTBUS_DECRYPT_ERR;
81         }
82     } else {
83         ret = EVP_DecryptInit_ex(*ctx, cipher, NULL, NULL, NULL);
84         if (ret != 1) {
85             COMM_LOGE(COMM_ADAPTER, "EVP_DecryptInit_ex fail.");
86             EVP_CIPHER_CTX_free(*ctx);
87             return SOFTBUS_DECRYPT_ERR;
88         }
89     }
90     ret = EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_SET_IVLEN, GCM_IV_LEN, NULL);
91     if (ret != 1) {
92         COMM_LOGE(COMM_ADAPTER, "Set iv len fail.");
93         EVP_CIPHER_CTX_free(*ctx);
94         return SOFTBUS_DECRYPT_ERR;
95     }
96     return SOFTBUS_OK;
97 }
98 
PackIvAndTag(EVP_CIPHER_CTX * ctx,const AesGcmCipherKey * cipherkey,uint32_t dataLen,unsigned char * cipherText,uint32_t cipherTextLen)99 static int32_t PackIvAndTag(EVP_CIPHER_CTX *ctx, const AesGcmCipherKey *cipherkey, uint32_t dataLen,
100     unsigned char *cipherText, uint32_t cipherTextLen)
101 {
102     if ((dataLen + OVERHEAD_LEN) > cipherTextLen) {
103         COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
104         return SOFTBUS_ENCRYPT_ERR;
105     }
106     if (memcpy_s(cipherText, cipherTextLen - dataLen, cipherkey->iv, GCM_IV_LEN) != EOK) {
107         COMM_LOGE(COMM_ADAPTER, "EVP memcpy iv fail.");
108         return SOFTBUS_ENCRYPT_ERR;
109     }
110     char tagbuf[TAG_LEN];
111     int ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAG_LEN, (void *)tagbuf);
112     if (ret != 1) {
113         COMM_LOGE(COMM_ADAPTER, "EVP_CIPHER_CTX_ctrl fail.");
114         return SOFTBUS_DECRYPT_ERR;
115     }
116     if (memcpy_s(cipherText + dataLen + GCM_IV_LEN, cipherTextLen - dataLen - GCM_IV_LEN, tagbuf, TAG_LEN) != EOK) {
117         COMM_LOGE(COMM_ADAPTER, "EVP memcpy tag fail.");
118         return SOFTBUS_ENCRYPT_ERR;
119     }
120     return SOFTBUS_OK;
121 }
122 
SslAesGcmEncrypt(const AesGcmCipherKey * cipherkey,const unsigned char * plainText,uint32_t plainTextSize,unsigned char * cipherText,uint32_t cipherTextLen)123 static int32_t SslAesGcmEncrypt(const AesGcmCipherKey *cipherkey, const unsigned char *plainText,
124     uint32_t plainTextSize, unsigned char *cipherText, uint32_t cipherTextLen)
125 {
126     if ((cipherkey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL ||
127         (cipherTextLen < plainTextSize + OVERHEAD_LEN)) {
128         COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
129         return SOFTBUS_INVALID_PARAM;
130     }
131 
132     int32_t outlen = 0;
133     int32_t outbufLen;
134     EVP_CIPHER_CTX *ctx = NULL;
135     int32_t ret = OpensslEvpInit(&ctx, cipherkey, true);
136     if (ret != SOFTBUS_OK) {
137         COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
138         return SOFTBUS_DECRYPT_ERR;
139     }
140     ret = EVP_EncryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
141     if (ret != 1) {
142         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
143         EVP_CIPHER_CTX_free(ctx);
144         return SOFTBUS_DECRYPT_ERR;
145     }
146     ret = EVP_EncryptUpdate(ctx, cipherText + GCM_IV_LEN, (int32_t *)&outbufLen, plainText, plainTextSize);
147     if (ret != 1) {
148         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptUpdate fail.");
149         EVP_CIPHER_CTX_free(ctx);
150         return SOFTBUS_DECRYPT_ERR;
151     }
152     outlen += outbufLen;
153     ret = EVP_EncryptFinal_ex(ctx, cipherText + GCM_IV_LEN + outbufLen, (int32_t *)&outbufLen);
154     if (ret != 1) {
155         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptFinal_ex fail.");
156         EVP_CIPHER_CTX_free(ctx);
157         return SOFTBUS_DECRYPT_ERR;
158     }
159     outlen += outbufLen;
160     ret = PackIvAndTag(ctx, cipherkey, outlen, cipherText, cipherTextLen);
161     if (ret != SOFTBUS_OK) {
162         COMM_LOGE(COMM_ADAPTER, "pack iv and tag fail.");
163         EVP_CIPHER_CTX_free(ctx);
164         return SOFTBUS_DECRYPT_ERR;
165     }
166     EVP_CIPHER_CTX_free(ctx);
167     return (outlen + OVERHEAD_LEN);
168 }
169 
SslAesGcmDecrypt(const AesGcmCipherKey * cipherkey,const unsigned char * cipherText,uint32_t cipherTextSize,unsigned char * plain,uint32_t plainLen)170 static int32_t SslAesGcmDecrypt(const AesGcmCipherKey *cipherkey, const unsigned char *cipherText,
171     uint32_t cipherTextSize, unsigned char *plain, uint32_t plainLen)
172 {
173     if ((cipherkey == NULL) || (cipherText == NULL) || (cipherTextSize <= OVERHEAD_LEN) || plain == NULL ||
174         (plainLen < cipherTextSize - OVERHEAD_LEN)) {
175         COMM_LOGE(COMM_ADAPTER, "Decrypt invalid para.");
176         return SOFTBUS_INVALID_PARAM;
177     }
178 
179     int32_t outLen = 0;
180     EVP_CIPHER_CTX *ctx = NULL;
181     int32_t ret = OpensslEvpInit(&ctx, cipherkey, false);
182     if (ret != SOFTBUS_OK) {
183         COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
184         return SOFTBUS_DECRYPT_ERR;
185     }
186     ret = EVP_DecryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
187     if (ret != 1) {
188         COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
189         goto EXIT;
190     }
191     ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, TAG_LEN, (void *)(cipherText + (cipherTextSize - TAG_LEN)));
192     if (ret != 1) {
193         COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
194         goto EXIT;
195     }
196     ret = EVP_DecryptUpdate(ctx, plain, (int32_t *)&plainLen, cipherText + GCM_IV_LEN, cipherTextSize - OVERHEAD_LEN);
197     if (ret != 1) {
198         COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
199         goto EXIT;
200     }
201     if (plainLen > INT32_MAX) {
202         COMM_LOGE(COMM_ADAPTER, "PlainLen convert overflow.");
203         goto EXIT;
204     }
205     outLen += (int32_t)plainLen;
206     ret = EVP_DecryptFinal_ex(ctx, plain + plainLen, (int32_t *)&plainLen);
207     if (ret != 1) {
208         COMM_LOGE(COMM_ADAPTER, "EVP_DecryptFinal_ex fail.");
209         goto EXIT;
210     }
211     if ((int32_t)plainLen > INT32_MAX - outLen) {
212         COMM_LOGE(COMM_ADAPTER, "outLen convert overflow.");
213         goto EXIT;
214     }
215     outLen += (int32_t)plainLen;
216     EVP_CIPHER_CTX_free(ctx);
217     return outLen;
218 EXIT:
219     EVP_CIPHER_CTX_free(ctx);
220     return SOFTBUS_DECRYPT_ERR;
221 }
222 
HandleError(EVP_CIPHER_CTX * ctx,const char * buf)223 static int32_t HandleError(EVP_CIPHER_CTX *ctx, const char *buf)
224 {
225     if (buf != NULL) {
226         COMM_LOGE(COMM_ADAPTER, "buf=%{public}s", buf);
227     }
228     if (ctx != NULL) {
229         EVP_CIPHER_CTX_free(ctx);
230     }
231     return SOFTBUS_DECRYPT_ERR;
232 }
233 
SoftBusBase64Encode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)234 int32_t SoftBusBase64Encode(unsigned char *dst, size_t dlen, 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     unsigned char *dstTmp = SoftBusCalloc(EVP_ENCODE_LENGTH(slen));
246     if (dstTmp == NULL) {
247         COMM_LOGE(COMM_ADAPTER, "[TRANS] SoftBusCalloc fail.");
248         EVP_ENCODE_CTX_free(ctx);
249         return SOFTBUS_MEM_ERR;
250     }
251     EVP_EncodeInit(ctx);
252     int32_t ret = EVP_EncodeUpdate(ctx, dstTmp, &outlen, src, slen);
253     if (ret != 1) {
254         COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_EncodeUpdate fail.");
255         EVP_ENCODE_CTX_free(ctx);
256         SoftBusFree(dstTmp);
257         return SOFTBUS_DECRYPT_ERR;
258     }
259     *olen += outlen;
260     EVP_EncodeFinal(ctx, dstTmp + outlen, &outlen);
261     *olen += outlen;
262 
263     if (*olen > dlen) {
264         COMM_LOGE(COMM_ADAPTER, "[TRANS] invalid dlen=%{public}zu, olen=%{public}zu.", dlen, *olen);
265         EVP_ENCODE_CTX_free(ctx);
266         SoftBusFree(dstTmp);
267         return SOFTBUS_INVALID_PARAM;
268     }
269 
270     ret = memcpy_s(dst, dlen, dstTmp, *olen);
271     if (ret != EOK) {
272         COMM_LOGE(COMM_ADAPTER, "[TRANS] memcpy_s failed.");
273         EVP_ENCODE_CTX_free(ctx);
274         SoftBusFree(dstTmp);
275         return SOFTBUS_MEM_ERR;
276     }
277     if ((*olen > 0) && (dst[*olen - 1] == '\n')) {
278         (*olen)--;
279         dst[*olen] = 0;
280     }
281 
282     EVP_ENCODE_CTX_free(ctx);
283     SoftBusFree(dstTmp);
284     return SOFTBUS_OK;
285 }
286 
SoftBusBase64Decode(unsigned char * dst,size_t dlen,size_t * olen,const unsigned char * src,size_t slen)287 int32_t SoftBusBase64Decode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen)
288 {
289     if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
290         return SOFTBUS_INVALID_PARAM;
291     }
292     *olen = 0;
293     int32_t outlen;
294     EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
295     if (ctx == NULL) {
296         return SOFTBUS_DECRYPT_ERR;
297     }
298     unsigned char *dstTmp = SoftBusCalloc(EVP_DECODE_LENGTH(slen));
299     if (dstTmp == NULL) {
300         COMM_LOGE(COMM_ADAPTER, "[TRANS] SoftBusCalloc fail.");
301         EVP_ENCODE_CTX_free(ctx);
302         return SOFTBUS_MEM_ERR;
303     }
304     EVP_DecodeInit(ctx);
305     int32_t ret = EVP_DecodeUpdate(ctx, dstTmp, &outlen, src, slen);
306     if (ret == -1) {
307         COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_DecodeUpdate fail.");
308         ret = SOFTBUS_DECRYPT_ERR;
309         goto FINISHED;
310     }
311     *olen += outlen;
312     ret = EVP_DecodeFinal(ctx, dstTmp + outlen, &outlen);
313     if (ret != 1) {
314         COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_DecodeFinal fail.");
315         ret = SOFTBUS_DECRYPT_ERR;
316         goto FINISHED;
317     }
318     *olen += outlen;
319     if (*olen > dlen) {
320         COMM_LOGE(COMM_ADAPTER, "[TRANS] invalid dlen=%{public}zu, olen=%{public}zu.", dlen, *olen);
321         ret = SOFTBUS_INVALID_PARAM;
322         goto FINISHED;
323     }
324 
325     ret = memcpy_s(dst, dlen, dstTmp, *olen);
326     if (ret != EOK) {
327         COMM_LOGE(COMM_ADAPTER, "[TRANS] memcpy_s failed.");
328         ret = SOFTBUS_MEM_ERR;
329         goto FINISHED;
330     }
331     ret = SOFTBUS_OK;
332 FINISHED:
333     EVP_ENCODE_CTX_free(ctx);
334     SoftBusFree(dstTmp);
335     return ret;
336 }
337 
SoftBusGenerateStrHash(const unsigned char * str,uint32_t len,unsigned char * hash)338 int32_t SoftBusGenerateStrHash(const unsigned char *str, uint32_t len, unsigned char *hash)
339 {
340     if (str == NULL || hash == NULL || len == 0) {
341         return SOFTBUS_INVALID_PARAM;
342     }
343     uint32_t olen;
344     int32_t ret = EVP_Digest(str, len, hash, &olen, EVP_sha256(), NULL);
345     if (ret != 1) {
346         COMM_LOGE(COMM_ADAPTER, "[TRANS] Get Openssl Hash fail.");
347         return SOFTBUS_DECRYPT_ERR;
348     }
349     return SOFTBUS_OK;
350 }
351 
SoftBusGenerateRandomArray(unsigned char * randStr,uint32_t len)352 int32_t SoftBusGenerateRandomArray(unsigned char *randStr, uint32_t len)
353 {
354     if (randStr == NULL || len == 0) {
355         return SOFTBUS_INVALID_PARAM;
356     }
357 
358     static bool initFlag = false;
359     int32_t ret;
360 
361     if (SoftBusMutexInit(&g_randomLock, NULL) != SOFTBUS_OK) {
362         COMM_LOGE(COMM_ADAPTER, "init mutex failed.");
363         return SOFTBUS_ERR;
364     }
365 
366     if (SoftBusMutexLock(&g_randomLock) != SOFTBUS_OK) {
367         COMM_LOGE(COMM_ADAPTER, "lock mutex failed");
368         return SOFTBUS_ERR;
369     }
370     if (initFlag == false) {
371         RAND_seed(randStr, (int32_t)len);
372         initFlag = true;
373     }
374 
375     ret = RAND_bytes(randStr, (int32_t)len);
376     SoftBusMutexUnlock(&g_randomLock);
377     if (ret != 1) {
378         COMM_LOGE(COMM_ADAPTER, "gen random error, ret=%{public}d", ret);
379         return SOFTBUS_ERR;
380     }
381     return SOFTBUS_OK;
382 }
383 
SoftBusGenerateSessionKey(char * key,uint32_t len)384 int32_t SoftBusGenerateSessionKey(char *key, uint32_t len)
385 {
386     if (SoftBusGenerateRandomArray((unsigned char *)key, len) != SOFTBUS_OK) {
387         COMM_LOGE(COMM_ADAPTER, "generate sessionKey error.");
388         return SOFTBUS_ENCRYPT_ERR;
389     }
390     return SOFTBUS_OK;
391 }
392 
SoftBusEncryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)393 int32_t SoftBusEncryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
394     unsigned char *encryptData, uint32_t *encryptLen)
395 {
396     if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
397         return SOFTBUS_INVALID_PARAM;
398     }
399 
400     if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
401         COMM_LOGE(COMM_ADAPTER, "generate random iv error.");
402         return SOFTBUS_ENCRYPT_ERR;
403     }
404     uint32_t outLen = inLen + OVERHEAD_LEN;
405     int32_t result = SslAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
406     if (result <= 0) {
407         return SOFTBUS_ENCRYPT_ERR;
408     }
409     *encryptLen = result;
410     return SOFTBUS_OK;
411 }
412 
SoftBusEncryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen,int32_t seqNum)413 int32_t SoftBusEncryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
414     unsigned char *encryptData, uint32_t *encryptLen, int32_t seqNum)
415 {
416     if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
417         return SOFTBUS_INVALID_PARAM;
418     }
419     if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
420         COMM_LOGE(COMM_ADAPTER, "generate random iv error.");
421         return SOFTBUS_ENCRYPT_ERR;
422     }
423     if (memcpy_s(cipherKey->iv, sizeof(int32_t), &seqNum, sizeof(int32_t)) != EOK) {
424         return SOFTBUS_ENCRYPT_ERR;
425     }
426     uint32_t outLen = inLen + OVERHEAD_LEN;
427     int32_t result = SslAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
428     if (result <= 0) {
429         return SOFTBUS_ENCRYPT_ERR;
430     }
431     *encryptLen = result;
432     return SOFTBUS_OK;
433 }
434 
SoftBusDecryptData(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)435 int32_t SoftBusDecryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
436     unsigned char *decryptData, uint32_t *decryptLen)
437 {
438     if (cipherKey == NULL || input == NULL || inLen < GCM_IV_LEN || decryptData == NULL || decryptLen == NULL) {
439         return SOFTBUS_INVALID_PARAM;
440     }
441 
442     if (memcpy_s(cipherKey->iv, sizeof(cipherKey->iv), input, GCM_IV_LEN) != EOK) {
443         COMM_LOGE(COMM_ADAPTER, "copy iv failed.");
444         return SOFTBUS_ENCRYPT_ERR;
445     }
446     uint32_t outLen = inLen - OVERHEAD_LEN;
447     int32_t result = SslAesGcmDecrypt(cipherKey, input, inLen, decryptData, outLen);
448     if (result <= 0) {
449         return SOFTBUS_ENCRYPT_ERR;
450     }
451     *decryptLen = (uint32_t)result;
452     return SOFTBUS_OK;
453 }
454 
SoftBusDecryptDataWithSeq(AesGcmCipherKey * cipherKey,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen,int32_t seqNum)455 int32_t SoftBusDecryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
456     unsigned char *decryptData, uint32_t *decryptLen, int32_t seqNum)
457 {
458     (void)seqNum;
459     return SoftBusDecryptData(cipherKey, input, inLen, decryptData, decryptLen);
460 }
461 
SoftBusCryptoRand(void)462 uint32_t SoftBusCryptoRand(void)
463 {
464     int32_t fd = SoftBusOpenFile("/dev/urandom", SOFTBUS_O_RDONLY);
465     if (fd < 0) {
466         COMM_LOGE(COMM_ADAPTER, "CryptoRand open file fail");
467         return 0;
468     }
469     uint32_t value = 0;
470     int32_t len = SoftBusReadFile(fd, &value, sizeof(uint32_t));
471     if (len < 0) {
472         COMM_LOGE(COMM_ADAPTER, "CryptoRand read file fail");
473         SoftBusCloseFile(fd);
474         return 0;
475     }
476     SoftBusCloseFile(fd);
477     return value;
478 }
479 
SoftBusEncryptDataByCtr(AesCtrCipherKey * key,const unsigned char * input,uint32_t inLen,unsigned char * encryptData,uint32_t * encryptLen)480 int32_t SoftBusEncryptDataByCtr(
481     AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen, unsigned char *encryptData, uint32_t *encryptLen)
482 {
483     if (key == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
484         return SOFTBUS_INVALID_PARAM;
485     }
486     EVP_CIPHER_CTX *ctx = NULL;
487     int32_t len = 0;
488     *encryptLen = 0;
489     EVP_CIPHER *cipher = NULL;
490     if (!(cipher = GetCtrAlgorithmByKeyLen(key->keyLen))) {
491         return HandleError(ctx, "get cipher failed");
492     }
493     if (!(ctx = EVP_CIPHER_CTX_new())) {
494         return HandleError(ctx, "EVP_CIPHER_CTX_new ctr failed");
495     }
496     if (EVP_EncryptInit_ex(ctx, cipher, NULL, key->key, key->iv) != 1) {
497         return HandleError(ctx, "EVP_EncryptInit_ex ctr failed");
498     }
499     if (EVP_EncryptUpdate(ctx, encryptData, &len, input, inLen) != 1) {
500         return HandleError(ctx, "EVP_EncryptUpdate ctr failed");
501     }
502     *encryptLen += len;
503     if (EVP_EncryptFinal_ex(ctx, encryptData + len, &len) != 1) {
504         return HandleError(ctx, "EVP_EncryptFinal_ex ctr failed");
505     }
506     *encryptLen += len;
507     EVP_CIPHER_CTX_free(ctx);
508     return SOFTBUS_OK;
509 }
510 
SoftBusDecryptDataByCtr(AesCtrCipherKey * key,const unsigned char * input,uint32_t inLen,unsigned char * decryptData,uint32_t * decryptLen)511 int32_t SoftBusDecryptDataByCtr(
512     AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen, unsigned char *decryptData, uint32_t *decryptLen)
513 {
514     if (key == NULL || input == NULL || inLen == 0 || decryptData == NULL || decryptLen == NULL) {
515         return SOFTBUS_INVALID_PARAM;
516     }
517     EVP_CIPHER_CTX *ctx = NULL;
518     int32_t len = 0;
519     *decryptLen = 0;
520     EVP_CIPHER *cipher = NULL;
521     if (!(cipher = GetCtrAlgorithmByKeyLen(key->keyLen))) {
522         return HandleError(ctx, "get cipher failed");
523     }
524     if (!(ctx = EVP_CIPHER_CTX_new())) {
525         return HandleError(ctx, "EVP_CIPHER_CTX_new ctr failed");
526     }
527     if (EVP_DecryptInit_ex(ctx, cipher, NULL, key->key, key->iv) != 1) {
528         return HandleError(ctx, "EVP_DecryptInit_ex ctr failed");
529     }
530     if (EVP_DecryptUpdate(ctx, decryptData, &len, input, inLen) != 1) {
531         return HandleError(ctx, "EVP_DecryptUpdate ctr failed");
532     }
533     *decryptLen += len;
534     if (EVP_DecryptFinal_ex(ctx, decryptData + len, &len) != 1) {
535         return HandleError(ctx, "EVP_DecryptFinal_ex ctr failed");
536     }
537     *decryptLen += len;
538     EVP_CIPHER_CTX_free(ctx);
539     return SOFTBUS_OK;
540 }
541