1060ff233Sopenharmony_ci/*
2060ff233Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3060ff233Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4060ff233Sopenharmony_ci * you may not use this file except in compliance with the License.
5060ff233Sopenharmony_ci * You may obtain a copy of the License at
6060ff233Sopenharmony_ci *
7060ff233Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8060ff233Sopenharmony_ci *
9060ff233Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10060ff233Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11060ff233Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12060ff233Sopenharmony_ci * See the License for the specific language governing permissions and
13060ff233Sopenharmony_ci * limitations under the License.
14060ff233Sopenharmony_ci */
15060ff233Sopenharmony_ci
16060ff233Sopenharmony_ci#include "softbus_adapter_crypto.h"
17060ff233Sopenharmony_ci
18060ff233Sopenharmony_ci#include <securec.h>
19060ff233Sopenharmony_ci
20060ff233Sopenharmony_ci#include <openssl/evp.h>
21060ff233Sopenharmony_ci#include <openssl/rand.h>
22060ff233Sopenharmony_ci
23060ff233Sopenharmony_ci#include "comm_log.h"
24060ff233Sopenharmony_ci#include "softbus_adapter_file.h"
25060ff233Sopenharmony_ci#include "softbus_adapter_mem.h"
26060ff233Sopenharmony_ci#include "softbus_errcode.h"
27060ff233Sopenharmony_ci
28060ff233Sopenharmony_cistatic SoftBusMutex g_randomLock;
29060ff233Sopenharmony_ci
30060ff233Sopenharmony_ci#define OPENSSL_EVP_PADDING_FUNC_OPEN  (1)
31060ff233Sopenharmony_ci#define OPENSSL_EVP_PADDING_FUNC_CLOSE (0)
32060ff233Sopenharmony_ci
33060ff233Sopenharmony_ci#define EVP_AES_128_KEYLEN 16
34060ff233Sopenharmony_ci#define EVP_AES_256_KEYLEN 32
35060ff233Sopenharmony_ci
36060ff233Sopenharmony_cistatic EVP_CIPHER *GetGcmAlgorithmByKeyLen(uint32_t keyLen)
37060ff233Sopenharmony_ci{
38060ff233Sopenharmony_ci    switch (keyLen) {
39060ff233Sopenharmony_ci        case EVP_AES_128_KEYLEN:
40060ff233Sopenharmony_ci            return (EVP_CIPHER *)EVP_aes_128_gcm();
41060ff233Sopenharmony_ci        case EVP_AES_256_KEYLEN:
42060ff233Sopenharmony_ci            return (EVP_CIPHER *)EVP_aes_256_gcm();
43060ff233Sopenharmony_ci        default:
44060ff233Sopenharmony_ci            return NULL;
45060ff233Sopenharmony_ci    }
46060ff233Sopenharmony_ci    return NULL;
47060ff233Sopenharmony_ci}
48060ff233Sopenharmony_ci
49060ff233Sopenharmony_cistatic EVP_CIPHER *GetCtrAlgorithmByKeyLen(uint32_t keyLen)
50060ff233Sopenharmony_ci{
51060ff233Sopenharmony_ci    switch (keyLen) {
52060ff233Sopenharmony_ci        case EVP_AES_128_KEYLEN:
53060ff233Sopenharmony_ci            return (EVP_CIPHER *)EVP_aes_128_ctr();
54060ff233Sopenharmony_ci        case EVP_AES_256_KEYLEN:
55060ff233Sopenharmony_ci            return (EVP_CIPHER *)EVP_aes_256_ctr();
56060ff233Sopenharmony_ci        default:
57060ff233Sopenharmony_ci            return NULL;
58060ff233Sopenharmony_ci    }
59060ff233Sopenharmony_ci    return NULL;
60060ff233Sopenharmony_ci}
61060ff233Sopenharmony_ci
62060ff233Sopenharmony_cistatic int32_t OpensslEvpInit(EVP_CIPHER_CTX **ctx, const AesGcmCipherKey *cipherkey, bool mode)
63060ff233Sopenharmony_ci{
64060ff233Sopenharmony_ci    if (cipherkey == NULL) {
65060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
66060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
67060ff233Sopenharmony_ci    }
68060ff233Sopenharmony_ci    EVP_CIPHER *cipher = GetGcmAlgorithmByKeyLen(cipherkey->keyLen);
69060ff233Sopenharmony_ci    if (cipher == NULL) {
70060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "get cipher fail.");
71060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
72060ff233Sopenharmony_ci    }
73060ff233Sopenharmony_ci    int32_t ret;
74060ff233Sopenharmony_ci    *ctx = EVP_CIPHER_CTX_new();
75060ff233Sopenharmony_ci    if (*ctx == NULL) {
76060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
77060ff233Sopenharmony_ci    }
78060ff233Sopenharmony_ci    EVP_CIPHER_CTX_set_padding(*ctx, OPENSSL_EVP_PADDING_FUNC_OPEN);
79060ff233Sopenharmony_ci    if (mode == true) {
80060ff233Sopenharmony_ci        ret = EVP_EncryptInit_ex(*ctx, cipher, NULL, NULL, NULL);
81060ff233Sopenharmony_ci        if (ret != 1) {
82060ff233Sopenharmony_ci            COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
83060ff233Sopenharmony_ci            EVP_CIPHER_CTX_free(*ctx);
84060ff233Sopenharmony_ci            return SOFTBUS_DECRYPT_ERR;
85060ff233Sopenharmony_ci        }
86060ff233Sopenharmony_ci    } else {
87060ff233Sopenharmony_ci        ret = EVP_DecryptInit_ex(*ctx, cipher, NULL, NULL, NULL);
88060ff233Sopenharmony_ci        if (ret != 1) {
89060ff233Sopenharmony_ci            COMM_LOGE(COMM_ADAPTER, "EVP_DecryptInit_ex fail.");
90060ff233Sopenharmony_ci            EVP_CIPHER_CTX_free(*ctx);
91060ff233Sopenharmony_ci            return SOFTBUS_DECRYPT_ERR;
92060ff233Sopenharmony_ci        }
93060ff233Sopenharmony_ci    }
94060ff233Sopenharmony_ci    ret = EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_SET_IVLEN, GCM_IV_LEN, NULL);
95060ff233Sopenharmony_ci    if (ret != 1) {
96060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "Set iv len fail.");
97060ff233Sopenharmony_ci        EVP_CIPHER_CTX_free(*ctx);
98060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
99060ff233Sopenharmony_ci    }
100060ff233Sopenharmony_ci    return SOFTBUS_OK;
101060ff233Sopenharmony_ci}
102060ff233Sopenharmony_ci
103060ff233Sopenharmony_cistatic int32_t PackIvAndTag(EVP_CIPHER_CTX *ctx, const AesGcmCipherKey *cipherkey, uint32_t dataLen,
104060ff233Sopenharmony_ci    unsigned char *cipherText, uint32_t cipherTextLen)
105060ff233Sopenharmony_ci{
106060ff233Sopenharmony_ci    if ((dataLen + OVERHEAD_LEN) > cipherTextLen) {
107060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
108060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
109060ff233Sopenharmony_ci    }
110060ff233Sopenharmony_ci    if (memcpy_s(cipherText, cipherTextLen - dataLen, cipherkey->iv, GCM_IV_LEN) != EOK) {
111060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP memcpy iv fail.");
112060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
113060ff233Sopenharmony_ci    }
114060ff233Sopenharmony_ci    char tagbuf[TAG_LEN];
115060ff233Sopenharmony_ci    int ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, TAG_LEN, (void *)tagbuf);
116060ff233Sopenharmony_ci    if (ret != 1) {
117060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_CIPHER_CTX_ctrl fail.");
118060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
119060ff233Sopenharmony_ci    }
120060ff233Sopenharmony_ci    if (memcpy_s(cipherText + dataLen + GCM_IV_LEN, cipherTextLen - dataLen - GCM_IV_LEN, tagbuf, TAG_LEN) != EOK) {
121060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP memcpy tag fail.");
122060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
123060ff233Sopenharmony_ci    }
124060ff233Sopenharmony_ci    return SOFTBUS_OK;
125060ff233Sopenharmony_ci}
126060ff233Sopenharmony_ci
127060ff233Sopenharmony_cistatic int32_t SslAesGcmEncrypt(const AesGcmCipherKey *cipherkey, const unsigned char *plainText,
128060ff233Sopenharmony_ci    uint32_t plainTextSize, unsigned char *cipherText, uint32_t cipherTextLen)
129060ff233Sopenharmony_ci{
130060ff233Sopenharmony_ci    if ((cipherkey == NULL) || (plainText == NULL) || (plainTextSize == 0) || cipherText == NULL ||
131060ff233Sopenharmony_ci        (cipherTextLen < plainTextSize + OVERHEAD_LEN)) {
132060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "Encrypt invalid para.");
133060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
134060ff233Sopenharmony_ci    }
135060ff233Sopenharmony_ci
136060ff233Sopenharmony_ci    int32_t outlen = 0;
137060ff233Sopenharmony_ci    int32_t outbufLen;
138060ff233Sopenharmony_ci    EVP_CIPHER_CTX *ctx = NULL;
139060ff233Sopenharmony_ci    int32_t ret = OpensslEvpInit(&ctx, cipherkey, true);
140060ff233Sopenharmony_ci    if (ret != SOFTBUS_OK) {
141060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
142060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
143060ff233Sopenharmony_ci    }
144060ff233Sopenharmony_ci    ret = EVP_EncryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
145060ff233Sopenharmony_ci    if (ret != 1) {
146060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
147060ff233Sopenharmony_ci        EVP_CIPHER_CTX_free(ctx);
148060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
149060ff233Sopenharmony_ci    }
150060ff233Sopenharmony_ci    ret = EVP_EncryptUpdate(ctx, cipherText + GCM_IV_LEN, (int32_t *)&outbufLen, plainText, plainTextSize);
151060ff233Sopenharmony_ci    if (ret != 1) {
152060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_EncryptUpdate fail.");
153060ff233Sopenharmony_ci        EVP_CIPHER_CTX_free(ctx);
154060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
155060ff233Sopenharmony_ci    }
156060ff233Sopenharmony_ci    outlen += outbufLen;
157060ff233Sopenharmony_ci    ret = EVP_EncryptFinal_ex(ctx, cipherText + GCM_IV_LEN + outbufLen, (int32_t *)&outbufLen);
158060ff233Sopenharmony_ci    if (ret != 1) {
159060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_EncryptFinal_ex fail.");
160060ff233Sopenharmony_ci        EVP_CIPHER_CTX_free(ctx);
161060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
162060ff233Sopenharmony_ci    }
163060ff233Sopenharmony_ci    outlen += outbufLen;
164060ff233Sopenharmony_ci    ret = PackIvAndTag(ctx, cipherkey, outlen, cipherText, cipherTextLen);
165060ff233Sopenharmony_ci    if (ret != SOFTBUS_OK) {
166060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "pack iv and tag fail.");
167060ff233Sopenharmony_ci        EVP_CIPHER_CTX_free(ctx);
168060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
169060ff233Sopenharmony_ci    }
170060ff233Sopenharmony_ci    EVP_CIPHER_CTX_free(ctx);
171060ff233Sopenharmony_ci    return (outlen + OVERHEAD_LEN);
172060ff233Sopenharmony_ci}
173060ff233Sopenharmony_ci
174060ff233Sopenharmony_cistatic int32_t SslAesGcmDecrypt(const AesGcmCipherKey *cipherkey, const unsigned char *cipherText,
175060ff233Sopenharmony_ci    uint32_t cipherTextSize, unsigned char *plain, uint32_t plainLen)
176060ff233Sopenharmony_ci{
177060ff233Sopenharmony_ci    if ((cipherkey == NULL) || (cipherText == NULL) || (cipherTextSize <= OVERHEAD_LEN) || plain == NULL ||
178060ff233Sopenharmony_ci        (plainLen < cipherTextSize - OVERHEAD_LEN)) {
179060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "Decrypt invalid para.");
180060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
181060ff233Sopenharmony_ci    }
182060ff233Sopenharmony_ci
183060ff233Sopenharmony_ci    int32_t outLen = 0;
184060ff233Sopenharmony_ci    EVP_CIPHER_CTX *ctx = NULL;
185060ff233Sopenharmony_ci    int32_t ret = OpensslEvpInit(&ctx, cipherkey, false);
186060ff233Sopenharmony_ci    if (ret != SOFTBUS_OK) {
187060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "OpensslEvpInit fail.");
188060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
189060ff233Sopenharmony_ci    }
190060ff233Sopenharmony_ci    ret = EVP_DecryptInit_ex(ctx, NULL, NULL, cipherkey->key, cipherkey->iv);
191060ff233Sopenharmony_ci    if (ret != 1) {
192060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex fail.");
193060ff233Sopenharmony_ci        goto EXIT;
194060ff233Sopenharmony_ci    }
195060ff233Sopenharmony_ci    ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, TAG_LEN, (void *)(cipherText + (cipherTextSize - TAG_LEN)));
196060ff233Sopenharmony_ci    if (ret != 1) {
197060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
198060ff233Sopenharmony_ci        goto EXIT;
199060ff233Sopenharmony_ci    }
200060ff233Sopenharmony_ci    ret = EVP_DecryptUpdate(ctx, plain, (int32_t *)&plainLen, cipherText + GCM_IV_LEN, cipherTextSize - OVERHEAD_LEN);
201060ff233Sopenharmony_ci    if (ret != 1) {
202060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate fail.");
203060ff233Sopenharmony_ci        goto EXIT;
204060ff233Sopenharmony_ci    }
205060ff233Sopenharmony_ci    if (plainLen > INT32_MAX) {
206060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "PlainLen convert overflow.");
207060ff233Sopenharmony_ci        goto EXIT;
208060ff233Sopenharmony_ci    }
209060ff233Sopenharmony_ci    outLen += (int32_t)plainLen;
210060ff233Sopenharmony_ci    ret = EVP_DecryptFinal_ex(ctx, plain + plainLen, (int32_t *)&plainLen);
211060ff233Sopenharmony_ci    if (ret != 1) {
212060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_DecryptFinal_ex fail.");
213060ff233Sopenharmony_ci        goto EXIT;
214060ff233Sopenharmony_ci    }
215060ff233Sopenharmony_ci    if ((int32_t)plainLen > INT32_MAX - outLen) {
216060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "outLen convert overflow.");
217060ff233Sopenharmony_ci        goto EXIT;
218060ff233Sopenharmony_ci    }
219060ff233Sopenharmony_ci    outLen += (int32_t)plainLen;
220060ff233Sopenharmony_ci    EVP_CIPHER_CTX_free(ctx);
221060ff233Sopenharmony_ci    return outLen;
222060ff233Sopenharmony_ciEXIT:
223060ff233Sopenharmony_ci    EVP_CIPHER_CTX_free(ctx);
224060ff233Sopenharmony_ci    return SOFTBUS_DECRYPT_ERR;
225060ff233Sopenharmony_ci}
226060ff233Sopenharmony_ci
227060ff233Sopenharmony_cistatic int32_t HandleError(EVP_CIPHER_CTX *ctx, const char *buf)
228060ff233Sopenharmony_ci{
229060ff233Sopenharmony_ci    if (buf != NULL) {
230060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "buf=%{public}s", buf);
231060ff233Sopenharmony_ci    }
232060ff233Sopenharmony_ci    if (ctx != NULL) {
233060ff233Sopenharmony_ci        EVP_CIPHER_CTX_free(ctx);
234060ff233Sopenharmony_ci    }
235060ff233Sopenharmony_ci    return SOFTBUS_DECRYPT_ERR;
236060ff233Sopenharmony_ci}
237060ff233Sopenharmony_ci
238060ff233Sopenharmony_ciint32_t SoftBusBase64Encode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen)
239060ff233Sopenharmony_ci{
240060ff233Sopenharmony_ci    if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
241060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
242060ff233Sopenharmony_ci    }
243060ff233Sopenharmony_ci    *olen = 0;
244060ff233Sopenharmony_ci    int32_t outlen;
245060ff233Sopenharmony_ci    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
246060ff233Sopenharmony_ci    if (ctx == NULL) {
247060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
248060ff233Sopenharmony_ci    }
249060ff233Sopenharmony_ci    unsigned char *dstTmp = SoftBusCalloc(EVP_ENCODE_LENGTH(slen));
250060ff233Sopenharmony_ci    if (dstTmp == NULL) {
251060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "[TRANS] SoftBusCalloc fail.");
252060ff233Sopenharmony_ci        EVP_ENCODE_CTX_free(ctx);
253060ff233Sopenharmony_ci        return SOFTBUS_MEM_ERR;
254060ff233Sopenharmony_ci    }
255060ff233Sopenharmony_ci    EVP_EncodeInit(ctx);
256060ff233Sopenharmony_ci    int32_t ret = EVP_EncodeUpdate(ctx, dstTmp, &outlen, src, slen);
257060ff233Sopenharmony_ci    if (ret != 1) {
258060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_EncodeUpdate fail.");
259060ff233Sopenharmony_ci        EVP_ENCODE_CTX_free(ctx);
260060ff233Sopenharmony_ci        SoftBusFree(dstTmp);
261060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
262060ff233Sopenharmony_ci    }
263060ff233Sopenharmony_ci    *olen += outlen;
264060ff233Sopenharmony_ci    EVP_EncodeFinal(ctx, dstTmp + outlen, &outlen);
265060ff233Sopenharmony_ci    *olen += outlen;
266060ff233Sopenharmony_ci
267060ff233Sopenharmony_ci    if (*olen > dlen) {
268060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "[TRANS] invalid dlen=%{public}zu, olen=%{public}zu.", dlen, *olen);
269060ff233Sopenharmony_ci        EVP_ENCODE_CTX_free(ctx);
270060ff233Sopenharmony_ci        SoftBusFree(dstTmp);
271060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
272060ff233Sopenharmony_ci    }
273060ff233Sopenharmony_ci
274060ff233Sopenharmony_ci    ret = memcpy_s(dst, dlen, dstTmp, *olen);
275060ff233Sopenharmony_ci    if (ret != EOK) {
276060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "[TRANS] memcpy_s failed.");
277060ff233Sopenharmony_ci        EVP_ENCODE_CTX_free(ctx);
278060ff233Sopenharmony_ci        SoftBusFree(dstTmp);
279060ff233Sopenharmony_ci        return SOFTBUS_MEM_ERR;
280060ff233Sopenharmony_ci    }
281060ff233Sopenharmony_ci    if ((*olen > 0) && (dst[*olen - 1] == '\n')) {
282060ff233Sopenharmony_ci        (*olen)--;
283060ff233Sopenharmony_ci        dst[*olen] = 0;
284060ff233Sopenharmony_ci    }
285060ff233Sopenharmony_ci
286060ff233Sopenharmony_ci    EVP_ENCODE_CTX_free(ctx);
287060ff233Sopenharmony_ci    SoftBusFree(dstTmp);
288060ff233Sopenharmony_ci    return SOFTBUS_OK;
289060ff233Sopenharmony_ci}
290060ff233Sopenharmony_ci
291060ff233Sopenharmony_ciint32_t SoftBusBase64Decode(unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen)
292060ff233Sopenharmony_ci{
293060ff233Sopenharmony_ci    if (dst == NULL || dlen == 0 || olen == NULL || src == NULL || slen == 0) {
294060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
295060ff233Sopenharmony_ci    }
296060ff233Sopenharmony_ci    *olen = 0;
297060ff233Sopenharmony_ci    int32_t outlen;
298060ff233Sopenharmony_ci    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
299060ff233Sopenharmony_ci    if (ctx == NULL) {
300060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
301060ff233Sopenharmony_ci    }
302060ff233Sopenharmony_ci    unsigned char *dstTmp = SoftBusCalloc(EVP_DECODE_LENGTH(slen));
303060ff233Sopenharmony_ci    if (dstTmp == NULL) {
304060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "[TRANS] SoftBusCalloc fail.");
305060ff233Sopenharmony_ci        EVP_ENCODE_CTX_free(ctx);
306060ff233Sopenharmony_ci        return SOFTBUS_MEM_ERR;
307060ff233Sopenharmony_ci    }
308060ff233Sopenharmony_ci    EVP_DecodeInit(ctx);
309060ff233Sopenharmony_ci    int32_t ret = EVP_DecodeUpdate(ctx, dstTmp, &outlen, src, slen);
310060ff233Sopenharmony_ci    if (ret == -1) {
311060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_DecodeUpdate fail.");
312060ff233Sopenharmony_ci        ret = SOFTBUS_DECRYPT_ERR;
313060ff233Sopenharmony_ci        goto FINISHED;
314060ff233Sopenharmony_ci    }
315060ff233Sopenharmony_ci    *olen += outlen;
316060ff233Sopenharmony_ci    ret = EVP_DecodeFinal(ctx, dstTmp + outlen, &outlen);
317060ff233Sopenharmony_ci    if (ret != 1) {
318060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "[TRANS] EVP_DecodeFinal fail.");
319060ff233Sopenharmony_ci        ret = SOFTBUS_DECRYPT_ERR;
320060ff233Sopenharmony_ci        goto FINISHED;
321060ff233Sopenharmony_ci    }
322060ff233Sopenharmony_ci    *olen += outlen;
323060ff233Sopenharmony_ci    if (*olen > dlen) {
324060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "[TRANS] invalid dlen=%{public}zu, olen=%{public}zu.", dlen, *olen);
325060ff233Sopenharmony_ci        ret = SOFTBUS_INVALID_PARAM;
326060ff233Sopenharmony_ci        goto FINISHED;
327060ff233Sopenharmony_ci    }
328060ff233Sopenharmony_ci
329060ff233Sopenharmony_ci    ret = memcpy_s(dst, dlen, dstTmp, *olen);
330060ff233Sopenharmony_ci    if (ret != EOK) {
331060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "[TRANS] memcpy_s failed.");
332060ff233Sopenharmony_ci        ret = SOFTBUS_MEM_ERR;
333060ff233Sopenharmony_ci        goto FINISHED;
334060ff233Sopenharmony_ci    }
335060ff233Sopenharmony_ci    ret = SOFTBUS_OK;
336060ff233Sopenharmony_ciFINISHED:
337060ff233Sopenharmony_ci    EVP_ENCODE_CTX_free(ctx);
338060ff233Sopenharmony_ci    SoftBusFree(dstTmp);
339060ff233Sopenharmony_ci    return ret;
340060ff233Sopenharmony_ci}
341060ff233Sopenharmony_ci
342060ff233Sopenharmony_ciint32_t SoftBusGenerateStrHash(const unsigned char *str, uint32_t len, unsigned char *hash)
343060ff233Sopenharmony_ci{
344060ff233Sopenharmony_ci    if (str == NULL || hash == NULL || len == 0) {
345060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
346060ff233Sopenharmony_ci    }
347060ff233Sopenharmony_ci    uint32_t olen;
348060ff233Sopenharmony_ci    int32_t ret = EVP_Digest(str, len, hash, &olen, EVP_sha256(), NULL);
349060ff233Sopenharmony_ci    if (ret != 1) {
350060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "[TRANS] Get Openssl Hash fail.");
351060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
352060ff233Sopenharmony_ci    }
353060ff233Sopenharmony_ci    return SOFTBUS_OK;
354060ff233Sopenharmony_ci}
355060ff233Sopenharmony_ci
356060ff233Sopenharmony_ciint32_t SoftBusGenerateRandomArray(unsigned char *randStr, uint32_t len)
357060ff233Sopenharmony_ci{
358060ff233Sopenharmony_ci    if (randStr == NULL || len == 0) {
359060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
360060ff233Sopenharmony_ci    }
361060ff233Sopenharmony_ci
362060ff233Sopenharmony_ci    static bool initFlag = false;
363060ff233Sopenharmony_ci    int32_t ret;
364060ff233Sopenharmony_ci
365060ff233Sopenharmony_ci    if (SoftBusMutexInit(&g_randomLock, NULL) != SOFTBUS_OK) {
366060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "init mutex failed.");
367060ff233Sopenharmony_ci        return SOFTBUS_ERR;
368060ff233Sopenharmony_ci    }
369060ff233Sopenharmony_ci
370060ff233Sopenharmony_ci    if (SoftBusMutexLock(&g_randomLock) != SOFTBUS_OK) {
371060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "lock mutex failed");
372060ff233Sopenharmony_ci        return SOFTBUS_ERR;
373060ff233Sopenharmony_ci    }
374060ff233Sopenharmony_ci    if (initFlag == false) {
375060ff233Sopenharmony_ci        RAND_seed(randStr, (int32_t)len);
376060ff233Sopenharmony_ci        initFlag = true;
377060ff233Sopenharmony_ci    }
378060ff233Sopenharmony_ci
379060ff233Sopenharmony_ci    ret = RAND_bytes(randStr, (int32_t)len);
380060ff233Sopenharmony_ci    SoftBusMutexUnlock(&g_randomLock);
381060ff233Sopenharmony_ci    if (ret != 1) {
382060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "gen random error, ret=%{public}d", ret);
383060ff233Sopenharmony_ci        return SOFTBUS_ERR;
384060ff233Sopenharmony_ci    }
385060ff233Sopenharmony_ci    return SOFTBUS_OK;
386060ff233Sopenharmony_ci}
387060ff233Sopenharmony_ci
388060ff233Sopenharmony_ciint32_t SoftBusGenerateSessionKey(char *key, uint32_t len)
389060ff233Sopenharmony_ci{
390060ff233Sopenharmony_ci    if (SoftBusGenerateRandomArray((unsigned char *)key, len) != SOFTBUS_OK) {
391060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "generate sessionKey error.");
392060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
393060ff233Sopenharmony_ci    }
394060ff233Sopenharmony_ci    return SOFTBUS_OK;
395060ff233Sopenharmony_ci}
396060ff233Sopenharmony_ci
397060ff233Sopenharmony_ciint32_t SoftBusEncryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
398060ff233Sopenharmony_ci    unsigned char *encryptData, uint32_t *encryptLen)
399060ff233Sopenharmony_ci{
400060ff233Sopenharmony_ci    if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
401060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
402060ff233Sopenharmony_ci    }
403060ff233Sopenharmony_ci
404060ff233Sopenharmony_ci    if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
405060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "generate random iv error.");
406060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
407060ff233Sopenharmony_ci    }
408060ff233Sopenharmony_ci    uint32_t outLen = inLen + OVERHEAD_LEN;
409060ff233Sopenharmony_ci    int32_t result = SslAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
410060ff233Sopenharmony_ci    if (result <= 0) {
411060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
412060ff233Sopenharmony_ci    }
413060ff233Sopenharmony_ci    *encryptLen = result;
414060ff233Sopenharmony_ci    return SOFTBUS_OK;
415060ff233Sopenharmony_ci}
416060ff233Sopenharmony_ci
417060ff233Sopenharmony_ciint32_t SoftBusEncryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
418060ff233Sopenharmony_ci    unsigned char *encryptData, uint32_t *encryptLen, int32_t seqNum)
419060ff233Sopenharmony_ci{
420060ff233Sopenharmony_ci    if (cipherKey == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
421060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
422060ff233Sopenharmony_ci    }
423060ff233Sopenharmony_ci    if (SoftBusGenerateRandomArray(cipherKey->iv, sizeof(cipherKey->iv)) != SOFTBUS_OK) {
424060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "generate random iv error.");
425060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
426060ff233Sopenharmony_ci    }
427060ff233Sopenharmony_ci    if (memcpy_s(cipherKey->iv, sizeof(int32_t), &seqNum, sizeof(int32_t)) != EOK) {
428060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
429060ff233Sopenharmony_ci    }
430060ff233Sopenharmony_ci    uint32_t outLen = inLen + OVERHEAD_LEN;
431060ff233Sopenharmony_ci    int32_t result = SslAesGcmEncrypt(cipherKey, input, inLen, encryptData, outLen);
432060ff233Sopenharmony_ci    if (result <= 0) {
433060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
434060ff233Sopenharmony_ci    }
435060ff233Sopenharmony_ci    *encryptLen = result;
436060ff233Sopenharmony_ci    return SOFTBUS_OK;
437060ff233Sopenharmony_ci}
438060ff233Sopenharmony_ci
439060ff233Sopenharmony_ciint32_t SoftBusDecryptData(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
440060ff233Sopenharmony_ci    unsigned char *decryptData, uint32_t *decryptLen)
441060ff233Sopenharmony_ci{
442060ff233Sopenharmony_ci    if (cipherKey == NULL || input == NULL || inLen < GCM_IV_LEN || decryptData == NULL || decryptLen == NULL) {
443060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
444060ff233Sopenharmony_ci    }
445060ff233Sopenharmony_ci
446060ff233Sopenharmony_ci    if (memcpy_s(cipherKey->iv, sizeof(cipherKey->iv), input, GCM_IV_LEN) != EOK) {
447060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "copy iv failed.");
448060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
449060ff233Sopenharmony_ci    }
450060ff233Sopenharmony_ci    uint32_t outLen = inLen - OVERHEAD_LEN;
451060ff233Sopenharmony_ci    int32_t result = SslAesGcmDecrypt(cipherKey, input, inLen, decryptData, outLen);
452060ff233Sopenharmony_ci    if (result <= 0) {
453060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
454060ff233Sopenharmony_ci    }
455060ff233Sopenharmony_ci    *decryptLen = (uint32_t)result;
456060ff233Sopenharmony_ci    return SOFTBUS_OK;
457060ff233Sopenharmony_ci}
458060ff233Sopenharmony_ci
459060ff233Sopenharmony_ciint32_t SoftBusDecryptDataWithSeq(AesGcmCipherKey *cipherKey, const unsigned char *input, uint32_t inLen,
460060ff233Sopenharmony_ci    unsigned char *decryptData, uint32_t *decryptLen, int32_t seqNum)
461060ff233Sopenharmony_ci{
462060ff233Sopenharmony_ci    (void)seqNum;
463060ff233Sopenharmony_ci    return SoftBusDecryptData(cipherKey, input, inLen, decryptData, decryptLen);
464060ff233Sopenharmony_ci}
465060ff233Sopenharmony_ci
466060ff233Sopenharmony_ciuint32_t SoftBusCryptoRand(void)
467060ff233Sopenharmony_ci{
468060ff233Sopenharmony_ci    int32_t fd = SoftBusOpenFile("/dev/urandom", SOFTBUS_O_RDONLY);
469060ff233Sopenharmony_ci    if (fd < 0) {
470060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "CryptoRand open file fail");
471060ff233Sopenharmony_ci        return 0;
472060ff233Sopenharmony_ci    }
473060ff233Sopenharmony_ci    uint32_t value = 0;
474060ff233Sopenharmony_ci    int32_t len = SoftBusReadFile(fd, &value, sizeof(uint32_t));
475060ff233Sopenharmony_ci    if (len < 0) {
476060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "CryptoRand read file fail");
477060ff233Sopenharmony_ci        SoftBusCloseFile(fd);
478060ff233Sopenharmony_ci        return 0;
479060ff233Sopenharmony_ci    }
480060ff233Sopenharmony_ci    SoftBusCloseFile(fd);
481060ff233Sopenharmony_ci    return value;
482060ff233Sopenharmony_ci}
483060ff233Sopenharmony_ci
484060ff233Sopenharmony_ciint32_t SoftBusEncryptDataByCtr(
485060ff233Sopenharmony_ci    AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen, unsigned char *encryptData, uint32_t *encryptLen)
486060ff233Sopenharmony_ci{
487060ff233Sopenharmony_ci    if (key == NULL || input == NULL || inLen == 0 || encryptData == NULL || encryptLen == NULL) {
488060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
489060ff233Sopenharmony_ci    }
490060ff233Sopenharmony_ci    EVP_CIPHER_CTX *ctx = NULL;
491060ff233Sopenharmony_ci    int32_t len = 0;
492060ff233Sopenharmony_ci    *encryptLen = 0;
493060ff233Sopenharmony_ci    EVP_CIPHER *cipher = NULL;
494060ff233Sopenharmony_ci    if (!(cipher = GetCtrAlgorithmByKeyLen(key->keyLen))) {
495060ff233Sopenharmony_ci        return HandleError(ctx, "get cipher failed");
496060ff233Sopenharmony_ci    }
497060ff233Sopenharmony_ci    if (!(ctx = EVP_CIPHER_CTX_new())) {
498060ff233Sopenharmony_ci        return HandleError(ctx, "EVP_CIPHER_CTX_new ctr failed");
499060ff233Sopenharmony_ci    }
500060ff233Sopenharmony_ci    if (EVP_EncryptInit_ex(ctx, cipher, NULL, key->key, key->iv) != 1) {
501060ff233Sopenharmony_ci        return HandleError(ctx, "EVP_EncryptInit_ex ctr failed");
502060ff233Sopenharmony_ci    }
503060ff233Sopenharmony_ci    if (EVP_EncryptUpdate(ctx, encryptData, &len, input, inLen) != 1) {
504060ff233Sopenharmony_ci        return HandleError(ctx, "EVP_EncryptUpdate ctr failed");
505060ff233Sopenharmony_ci    }
506060ff233Sopenharmony_ci    *encryptLen += len;
507060ff233Sopenharmony_ci    if (EVP_EncryptFinal_ex(ctx, encryptData + len, &len) != 1) {
508060ff233Sopenharmony_ci        return HandleError(ctx, "EVP_EncryptFinal_ex ctr failed");
509060ff233Sopenharmony_ci    }
510060ff233Sopenharmony_ci    *encryptLen += len;
511060ff233Sopenharmony_ci    EVP_CIPHER_CTX_free(ctx);
512060ff233Sopenharmony_ci    return SOFTBUS_OK;
513060ff233Sopenharmony_ci}
514060ff233Sopenharmony_ci
515060ff233Sopenharmony_ciint32_t SoftBusDecryptDataByCtr(
516060ff233Sopenharmony_ci    AesCtrCipherKey *key, const unsigned char *input, uint32_t inLen, unsigned char *decryptData, uint32_t *decryptLen)
517060ff233Sopenharmony_ci{
518060ff233Sopenharmony_ci    if (key == NULL || input == NULL || inLen == 0 || decryptData == NULL || decryptLen == NULL) {
519060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
520060ff233Sopenharmony_ci    }
521060ff233Sopenharmony_ci    EVP_CIPHER_CTX *ctx = NULL;
522060ff233Sopenharmony_ci    int32_t len = 0;
523060ff233Sopenharmony_ci    *decryptLen = 0;
524060ff233Sopenharmony_ci    EVP_CIPHER *cipher = NULL;
525060ff233Sopenharmony_ci    if (!(cipher = GetCtrAlgorithmByKeyLen(key->keyLen))) {
526060ff233Sopenharmony_ci        return HandleError(ctx, "get cipher failed");
527060ff233Sopenharmony_ci    }
528060ff233Sopenharmony_ci    if (!(ctx = EVP_CIPHER_CTX_new())) {
529060ff233Sopenharmony_ci        return HandleError(ctx, "EVP_CIPHER_CTX_new ctr failed");
530060ff233Sopenharmony_ci    }
531060ff233Sopenharmony_ci    if (EVP_DecryptInit_ex(ctx, cipher, NULL, key->key, key->iv) != 1) {
532060ff233Sopenharmony_ci        return HandleError(ctx, "EVP_DecryptInit_ex ctr failed");
533060ff233Sopenharmony_ci    }
534060ff233Sopenharmony_ci    if (EVP_DecryptUpdate(ctx, decryptData, &len, input, inLen) != 1) {
535060ff233Sopenharmony_ci        return HandleError(ctx, "EVP_DecryptUpdate ctr failed");
536060ff233Sopenharmony_ci    }
537060ff233Sopenharmony_ci    *decryptLen += len;
538060ff233Sopenharmony_ci    if (EVP_DecryptFinal_ex(ctx, decryptData + len, &len) != 1) {
539060ff233Sopenharmony_ci        return HandleError(ctx, "EVP_DecryptFinal_ex ctr failed");
540060ff233Sopenharmony_ci    }
541060ff233Sopenharmony_ci    *decryptLen += len;
542060ff233Sopenharmony_ci    EVP_CIPHER_CTX_free(ctx);
543060ff233Sopenharmony_ci    return SOFTBUS_OK;
544060ff233Sopenharmony_ci}
545