1060ff233Sopenharmony_ci/*
2060ff233Sopenharmony_ci * Copyright (c) 2023-2024 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_aes_encrypt.h"
17060ff233Sopenharmony_ci
18060ff233Sopenharmony_ci#include <openssl/evp.h>
19060ff233Sopenharmony_ci#include <openssl/hmac.h>
20060ff233Sopenharmony_ci#include <openssl/rand.h>
21060ff233Sopenharmony_ci#include <securec.h>
22060ff233Sopenharmony_ci
23060ff233Sopenharmony_ci#include "openssl/aes.h"
24060ff233Sopenharmony_ci
25060ff233Sopenharmony_ci#include "comm_log.h"
26060ff233Sopenharmony_ci#include "softbus_adapter_crypto.h"
27060ff233Sopenharmony_ci#include "softbus_adapter_mem.h"
28060ff233Sopenharmony_ci#include "softbus_errcode.h"
29060ff233Sopenharmony_ci
30060ff233Sopenharmony_ci#define AES_128_CFB_KEYLEN             16
31060ff233Sopenharmony_ci#define AES_256_CFB_KEYLEN             32
32060ff233Sopenharmony_ci#define AES_128_GCM_KEYLEN             16
33060ff233Sopenharmony_ci#define AES_256_GCM_KEYLEN             32
34060ff233Sopenharmony_ci#define AES_128_CFB_BITS_LEN           128
35060ff233Sopenharmony_ci#define AES_256_CFB_BITS_LEN           256
36060ff233Sopenharmony_ci#define OPENSSL_EVP_PADDING_FUNC_OPEN  (1)
37060ff233Sopenharmony_ci#define OPENSSL_EVP_PADDING_FUNC_CLOSE (0)
38060ff233Sopenharmony_ci
39060ff233Sopenharmony_ciint32_t SoftBusGenerateHmacHash(
40060ff233Sopenharmony_ci    const EncryptKey *randomKey, const uint8_t *rootKey, uint32_t rootKeyLen, uint8_t *hash, uint32_t hashLen)
41060ff233Sopenharmony_ci{
42060ff233Sopenharmony_ci    uint32_t outBufLen;
43060ff233Sopenharmony_ci    uint8_t tempOutputData[EVP_MAX_MD_SIZE];
44060ff233Sopenharmony_ci
45060ff233Sopenharmony_ci    if (randomKey == NULL || rootKey == NULL || rootKeyLen == 0 || hash == NULL || hashLen < SHA256_MAC_LEN) {
46060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "invalid param.");
47060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
48060ff233Sopenharmony_ci    }
49060ff233Sopenharmony_ci    HMAC_CTX *ctx = HMAC_CTX_new();
50060ff233Sopenharmony_ci    if (ctx == NULL) {
51060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "HMAC_CTX_new failed.");
52060ff233Sopenharmony_ci        return SOFTBUS_HMAC_ERR;
53060ff233Sopenharmony_ci    }
54060ff233Sopenharmony_ci    if (HMAC_CTX_reset(ctx) != 1) {
55060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "HMAC_CTX_reset failed.");
56060ff233Sopenharmony_ci        HMAC_CTX_free(ctx);
57060ff233Sopenharmony_ci        return SOFTBUS_HMAC_ERR;
58060ff233Sopenharmony_ci    }
59060ff233Sopenharmony_ci    if (HMAC_Init_ex(ctx, rootKey, rootKeyLen, EVP_sha256(), NULL) != 1) {
60060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "HMAC_Init_ex failed.");
61060ff233Sopenharmony_ci        HMAC_CTX_free(ctx);
62060ff233Sopenharmony_ci        return SOFTBUS_HMAC_ERR;
63060ff233Sopenharmony_ci    }
64060ff233Sopenharmony_ci    if (HMAC_Update(ctx, randomKey->key, (size_t)randomKey->len) != 1) {
65060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "HMAC_Update failed.");
66060ff233Sopenharmony_ci        HMAC_CTX_free(ctx);
67060ff233Sopenharmony_ci        return SOFTBUS_HMAC_ERR;
68060ff233Sopenharmony_ci    }
69060ff233Sopenharmony_ci    if (HMAC_Final(ctx, tempOutputData, &outBufLen) != 1) {
70060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "HMAC_Final failed.");
71060ff233Sopenharmony_ci        HMAC_CTX_free(ctx);
72060ff233Sopenharmony_ci        return SOFTBUS_HMAC_ERR;
73060ff233Sopenharmony_ci    }
74060ff233Sopenharmony_ci    HMAC_CTX_free(ctx);
75060ff233Sopenharmony_ci    if (outBufLen != SHA256_MAC_LEN) {
76060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "outBufLen is invalid length for hash.");
77060ff233Sopenharmony_ci        (void)memset_s(tempOutputData, sizeof(tempOutputData), 0, sizeof(tempOutputData));
78060ff233Sopenharmony_ci        return SOFTBUS_HMAC_ERR;
79060ff233Sopenharmony_ci    }
80060ff233Sopenharmony_ci    if (memcpy_s(hash, hashLen, tempOutputData, outBufLen) != EOK) {
81060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "hash result memcpy_s failed.");
82060ff233Sopenharmony_ci        (void)memset_s(tempOutputData, sizeof(tempOutputData), 0, sizeof(tempOutputData));
83060ff233Sopenharmony_ci        return SOFTBUS_MEM_ERR;
84060ff233Sopenharmony_ci    }
85060ff233Sopenharmony_ci    (void)memset_s(tempOutputData, sizeof(tempOutputData), 0, sizeof(tempOutputData));
86060ff233Sopenharmony_ci    return SOFTBUS_OK;
87060ff233Sopenharmony_ci}
88060ff233Sopenharmony_ci
89060ff233Sopenharmony_cistatic int32_t OpensslAesCfbEncrypt(
90060ff233Sopenharmony_ci    AesCipherKey *cipherKey, const AesInputData *inData, int32_t encMode, AesOutputData *outData)
91060ff233Sopenharmony_ci{
92060ff233Sopenharmony_ci    int32_t num = 0;
93060ff233Sopenharmony_ci    AES_KEY aes;
94060ff233Sopenharmony_ci
95060ff233Sopenharmony_ci    if (cipherKey == NULL || cipherKey->ivLen != AES_IV_LENGTH || inData == NULL || inData->data == NULL ||
96060ff233Sopenharmony_ci        outData == NULL || (encMode != ENCRYPT_MODE && encMode != DECRYPT_MODE)) {
97060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "invalid param.");
98060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
99060ff233Sopenharmony_ci    }
100060ff233Sopenharmony_ci    int32_t bits = 0;
101060ff233Sopenharmony_ci    switch (cipherKey->keyLen) {
102060ff233Sopenharmony_ci        case AES_128_CFB_KEYLEN:
103060ff233Sopenharmony_ci            bits = AES_128_CFB_BITS_LEN;
104060ff233Sopenharmony_ci            break;
105060ff233Sopenharmony_ci        case AES_256_CFB_KEYLEN:
106060ff233Sopenharmony_ci            bits = AES_256_CFB_BITS_LEN;
107060ff233Sopenharmony_ci            break;
108060ff233Sopenharmony_ci        default:
109060ff233Sopenharmony_ci            COMM_LOGE(COMM_ADAPTER, "cipherKey->keyLen unable to get encryption bits.");
110060ff233Sopenharmony_ci            return SOFTBUS_INVALID_PARAM;
111060ff233Sopenharmony_ci    }
112060ff233Sopenharmony_ci    if (AES_set_encrypt_key(cipherKey->key, bits, &aes) < 0) {
113060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "SoftbusAesCfbEncrypt unable to set encryption key in AES.");
114060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
115060ff233Sopenharmony_ci    }
116060ff233Sopenharmony_ci    if (encMode == ENCRYPT_MODE) {
117060ff233Sopenharmony_ci        AES_cfb128_encrypt(inData->data, outData->data, inData->len, &aes, cipherKey->iv, &num, ENCRYPT_MODE);
118060ff233Sopenharmony_ci    } else {
119060ff233Sopenharmony_ci        AES_cfb128_encrypt(inData->data, outData->data, inData->len, &aes, cipherKey->iv, &num, DECRYPT_MODE);
120060ff233Sopenharmony_ci    }
121060ff233Sopenharmony_ci    outData->len = inData->len;
122060ff233Sopenharmony_ci    OPENSSL_cleanse(&aes, sizeof(aes));
123060ff233Sopenharmony_ci    return SOFTBUS_OK;
124060ff233Sopenharmony_ci}
125060ff233Sopenharmony_ci
126060ff233Sopenharmony_cistatic int32_t RootKeyGenerateIvAndSessionKey(const EncryptKey *randomKey, EncryptKey *rootKey, AesCipherKey *cipherKey)
127060ff233Sopenharmony_ci{
128060ff233Sopenharmony_ci    uint8_t result[SHA256_MAC_LEN] = { 0 };
129060ff233Sopenharmony_ci    if (SoftBusGenerateHmacHash(randomKey, rootKey->key, rootKey->len, result, sizeof(result)) != SOFTBUS_OK) {
130060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "SslHmacSha256 failed.");
131060ff233Sopenharmony_ci        return SOFTBUS_HMAC_ERR;
132060ff233Sopenharmony_ci    }
133060ff233Sopenharmony_ci    if (memcpy_s(cipherKey->key, cipherKey->keyLen, result, AES_SESSION_KEY_LENGTH) != EOK) {
134060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "RootKeyGenerateIvAndSessionKey fill sessionKey failed!");
135060ff233Sopenharmony_ci        (void)memset_s(result, sizeof(result), 0, sizeof(result));
136060ff233Sopenharmony_ci        return SOFTBUS_MEM_ERR;
137060ff233Sopenharmony_ci    }
138060ff233Sopenharmony_ci    if (memcpy_s(cipherKey->iv, cipherKey->ivLen, result + AES_SESSION_KEY_LENGTH,
139060ff233Sopenharmony_ci            SHA256_MAC_LEN - AES_SESSION_KEY_LENGTH) != EOK) {
140060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "RootKeyGenerateIvAndSessionKey fill iv failed!");
141060ff233Sopenharmony_ci        (void)memset_s(result, sizeof(result), 0, sizeof(result));
142060ff233Sopenharmony_ci        return SOFTBUS_MEM_ERR;
143060ff233Sopenharmony_ci    }
144060ff233Sopenharmony_ci    (void)memset_s(result, sizeof(result), 0, sizeof(result));
145060ff233Sopenharmony_ci    return SOFTBUS_OK;
146060ff233Sopenharmony_ci}
147060ff233Sopenharmony_ci
148060ff233Sopenharmony_cistatic int32_t GenerateIvAndSessionKey(const EncryptKey *randomKey, EncryptKey *rootKey, AesCipherKey *cipherKey)
149060ff233Sopenharmony_ci{
150060ff233Sopenharmony_ci    if (cipherKey == NULL) {
151060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "invalid param.");
152060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
153060ff233Sopenharmony_ci    }
154060ff233Sopenharmony_ci    cipherKey->keyLen = AES_SESSION_KEY_LENGTH;
155060ff233Sopenharmony_ci    cipherKey->ivLen = AES_IV_LENGTH;
156060ff233Sopenharmony_ci    cipherKey->key = (uint8_t *)SoftBusCalloc(cipherKey->keyLen);
157060ff233Sopenharmony_ci    if (cipherKey->key == NULL) {
158060ff233Sopenharmony_ci        return SOFTBUS_MALLOC_ERR;
159060ff233Sopenharmony_ci    }
160060ff233Sopenharmony_ci    cipherKey->iv = (uint8_t *)SoftBusCalloc(cipherKey->ivLen);
161060ff233Sopenharmony_ci    if (cipherKey->iv == NULL) {
162060ff233Sopenharmony_ci        SoftBusFree(cipherKey->key);
163060ff233Sopenharmony_ci        return SOFTBUS_MALLOC_ERR;
164060ff233Sopenharmony_ci    }
165060ff233Sopenharmony_ci    if (RootKeyGenerateIvAndSessionKey(randomKey, rootKey, cipherKey) != SOFTBUS_OK) {
166060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "RootKeyGenerateIvAndSessionKey failed!");
167060ff233Sopenharmony_ci        (void)memset_s(cipherKey->key, cipherKey->keyLen, 0, cipherKey->keyLen);
168060ff233Sopenharmony_ci        (void)memset_s(cipherKey->iv, cipherKey->ivLen, 0, cipherKey->ivLen);
169060ff233Sopenharmony_ci        SoftBusFree(cipherKey->key);
170060ff233Sopenharmony_ci        SoftBusFree(cipherKey->iv);
171060ff233Sopenharmony_ci        return SOFTBUS_GENERATE_KEY_FAIL;
172060ff233Sopenharmony_ci    }
173060ff233Sopenharmony_ci    return SOFTBUS_OK;
174060ff233Sopenharmony_ci}
175060ff233Sopenharmony_ci
176060ff233Sopenharmony_ciint32_t SoftBusAesCfbRootEncrypt(const AesInputData *inData, const EncryptKey *randomKey, EncryptKey *rootKey,
177060ff233Sopenharmony_ci    int32_t encMode, AesOutputData *outData)
178060ff233Sopenharmony_ci{
179060ff233Sopenharmony_ci    if (inData == NULL || inData->data == NULL || randomKey == NULL || randomKey->key == NULL || rootKey == NULL ||
180060ff233Sopenharmony_ci        rootKey->key == NULL || outData == NULL || (encMode != ENCRYPT_MODE && encMode != DECRYPT_MODE)) {
181060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "invalid param.");
182060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
183060ff233Sopenharmony_ci    }
184060ff233Sopenharmony_ci    AesCipherKey cipherKey = { 0 };
185060ff233Sopenharmony_ci    AesOutputData encryptData = { .data = (uint8_t *)SoftBusCalloc(inData->len), .len = inData->len };
186060ff233Sopenharmony_ci    if (encryptData.data == NULL) {
187060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "encryptData calloc failed.");
188060ff233Sopenharmony_ci        return SOFTBUS_MEM_ERR;
189060ff233Sopenharmony_ci    }
190060ff233Sopenharmony_ci    if (GenerateIvAndSessionKey(randomKey, rootKey, &cipherKey) != SOFTBUS_OK) {
191060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "GenerateIvAndSessionKey failed!");
192060ff233Sopenharmony_ci        SoftBusFree(encryptData.data);
193060ff233Sopenharmony_ci        return SOFTBUS_GENERATE_KEY_FAIL;
194060ff233Sopenharmony_ci    }
195060ff233Sopenharmony_ci    if (OpensslAesCfbEncrypt(&cipherKey, inData, encMode, &encryptData) != SOFTBUS_OK) {
196060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "OpensslAesCfb encrypt or decrypt by root key failed.");
197060ff233Sopenharmony_ci        (void)memset_s(cipherKey.key, cipherKey.keyLen, 0, cipherKey.keyLen);
198060ff233Sopenharmony_ci        (void)memset_s(cipherKey.iv, cipherKey.ivLen, 0, cipherKey.ivLen);
199060ff233Sopenharmony_ci        SoftBusFree(cipherKey.key);
200060ff233Sopenharmony_ci        SoftBusFree(cipherKey.iv);
201060ff233Sopenharmony_ci        SoftBusFree(encryptData.data);
202060ff233Sopenharmony_ci        encryptData.data = NULL;
203060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
204060ff233Sopenharmony_ci    }
205060ff233Sopenharmony_ci    (void)memset_s(cipherKey.key, cipherKey.keyLen, 0, cipherKey.keyLen);
206060ff233Sopenharmony_ci    (void)memset_s(cipherKey.iv, cipherKey.ivLen, 0, cipherKey.ivLen);
207060ff233Sopenharmony_ci    SoftBusFree(cipherKey.key);
208060ff233Sopenharmony_ci    SoftBusFree(cipherKey.iv);
209060ff233Sopenharmony_ci    outData->len = encryptData.len;
210060ff233Sopenharmony_ci    outData->data = encryptData.data;
211060ff233Sopenharmony_ci    return SOFTBUS_OK;
212060ff233Sopenharmony_ci}
213060ff233Sopenharmony_ci
214060ff233Sopenharmony_ciint32_t SoftBusAesCfbEncrypt(
215060ff233Sopenharmony_ci    const AesInputData *inData, AesCipherKey *cipherKey, int32_t encMode, AesOutputData *outData)
216060ff233Sopenharmony_ci{
217060ff233Sopenharmony_ci    uint8_t random[RANDOM_LENGTH] = { 0 };
218060ff233Sopenharmony_ci    uint8_t result[SHA256_MAC_LEN] = { 0 };
219060ff233Sopenharmony_ci
220060ff233Sopenharmony_ci    if (inData == NULL || inData->data == NULL || cipherKey == NULL || cipherKey->ivLen < RANDOM_LENGTH ||
221060ff233Sopenharmony_ci        outData == NULL || (encMode != ENCRYPT_MODE && encMode != DECRYPT_MODE)) {
222060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "invalid param.");
223060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
224060ff233Sopenharmony_ci    }
225060ff233Sopenharmony_ci    if (memcpy_s(random, sizeof(random), cipherKey->iv, sizeof(random)) != EOK) {
226060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "random memcpy_s failed!");
227060ff233Sopenharmony_ci        return SOFTBUS_MEM_ERR;
228060ff233Sopenharmony_ci    }
229060ff233Sopenharmony_ci    EncryptKey key = { cipherKey->key, cipherKey->keyLen };
230060ff233Sopenharmony_ci    if (SoftBusGenerateHmacHash(&key, random, sizeof(random), result, SHA256_MAC_LEN) != SOFTBUS_OK) {
231060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "SslHmacSha256 failed.");
232060ff233Sopenharmony_ci        (void)memset_s(random, sizeof(random), 0, sizeof(random));
233060ff233Sopenharmony_ci        return SOFTBUS_HMAC_ERR;
234060ff233Sopenharmony_ci    }
235060ff233Sopenharmony_ci    (void)memset_s(cipherKey->key, cipherKey->keyLen, 0, cipherKey->keyLen);
236060ff233Sopenharmony_ci    if (memcpy_s(cipherKey->key, cipherKey->keyLen, result, SHA256_MAC_LEN) != EOK) {
237060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "fill cipherKey->key failed!");
238060ff233Sopenharmony_ci        (void)memset_s(random, sizeof(random), 0, sizeof(random));
239060ff233Sopenharmony_ci        (void)memset_s(result, sizeof(result), 0, sizeof(result));
240060ff233Sopenharmony_ci        return SOFTBUS_MEM_ERR;
241060ff233Sopenharmony_ci    }
242060ff233Sopenharmony_ci    AesOutputData encryptData = { .data = (uint8_t *)SoftBusCalloc(inData->len), .len = inData->len };
243060ff233Sopenharmony_ci    if (encryptData.data == NULL) {
244060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "encryptData calloc failed.");
245060ff233Sopenharmony_ci        (void)memset_s(random, sizeof(random), 0, sizeof(random));
246060ff233Sopenharmony_ci        (void)memset_s(result, sizeof(result), 0, sizeof(result));
247060ff233Sopenharmony_ci        return SOFTBUS_MALLOC_ERR;
248060ff233Sopenharmony_ci    }
249060ff233Sopenharmony_ci    if (OpensslAesCfbEncrypt(cipherKey, inData, encMode, &encryptData) != SOFTBUS_OK) {
250060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "OpensslAesCfbEncrypt failed.");
251060ff233Sopenharmony_ci        (void)memset_s(random, sizeof(random), 0, sizeof(random));
252060ff233Sopenharmony_ci        (void)memset_s(result, sizeof(result), 0, sizeof(result));
253060ff233Sopenharmony_ci        SoftBusFree(encryptData.data);
254060ff233Sopenharmony_ci        encryptData.data = NULL;
255060ff233Sopenharmony_ci        return SOFTBUS_ENCRYPT_ERR;
256060ff233Sopenharmony_ci    }
257060ff233Sopenharmony_ci
258060ff233Sopenharmony_ci    outData->data = encryptData.data;
259060ff233Sopenharmony_ci    outData->len = encryptData.len;
260060ff233Sopenharmony_ci    return SOFTBUS_OK;
261060ff233Sopenharmony_ci}
262060ff233Sopenharmony_ci
263060ff233Sopenharmony_cistatic EVP_CIPHER *GetSslGcmAlgorithmByKeyLen(uint32_t keyLen)
264060ff233Sopenharmony_ci{
265060ff233Sopenharmony_ci    switch (keyLen) {
266060ff233Sopenharmony_ci        case AES_128_GCM_KEYLEN:
267060ff233Sopenharmony_ci            return (EVP_CIPHER *)EVP_aes_128_gcm();
268060ff233Sopenharmony_ci        case AES_256_GCM_KEYLEN:
269060ff233Sopenharmony_ci            return (EVP_CIPHER *)EVP_aes_256_gcm();
270060ff233Sopenharmony_ci        default:
271060ff233Sopenharmony_ci            COMM_LOGE(COMM_ADAPTER, "Get SslGcmAlgorithm ByKeyLen failed.");
272060ff233Sopenharmony_ci            return NULL;
273060ff233Sopenharmony_ci    }
274060ff233Sopenharmony_ci    return NULL;
275060ff233Sopenharmony_ci}
276060ff233Sopenharmony_ci
277060ff233Sopenharmony_cistatic int32_t GcmOpensslEvpInit(EVP_CIPHER_CTX **ctx, uint32_t keyLen, int32_t encMode)
278060ff233Sopenharmony_ci{
279060ff233Sopenharmony_ci    if (ctx == NULL || keyLen == 0 || (encMode != ENCRYPT_MODE && encMode != DECRYPT_MODE)) {
280060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "invalid param.");
281060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
282060ff233Sopenharmony_ci    }
283060ff233Sopenharmony_ci    EVP_CIPHER *cipher = GetSslGcmAlgorithmByKeyLen(keyLen);
284060ff233Sopenharmony_ci    if (cipher == NULL) {
285060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "GetSslGcmAlgorithmByKeyLen failed.");
286060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
287060ff233Sopenharmony_ci    }
288060ff233Sopenharmony_ci    *ctx = EVP_CIPHER_CTX_new();
289060ff233Sopenharmony_ci    if (*ctx == NULL) {
290060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_CIPHER_CTX_new failed.");
291060ff233Sopenharmony_ci        return SOFTBUS_MALLOC_ERR;
292060ff233Sopenharmony_ci    }
293060ff233Sopenharmony_ci    EVP_CIPHER_CTX_set_padding(*ctx, OPENSSL_EVP_PADDING_FUNC_CLOSE);
294060ff233Sopenharmony_ci    if (encMode == ENCRYPT_MODE) {
295060ff233Sopenharmony_ci        if (EVP_EncryptInit_ex(*ctx, cipher, NULL, NULL, NULL) != 1) {
296060ff233Sopenharmony_ci            COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex failed.");
297060ff233Sopenharmony_ci            EVP_CIPHER_CTX_free(*ctx);
298060ff233Sopenharmony_ci            *ctx = NULL;
299060ff233Sopenharmony_ci            return SOFTBUS_ENCRYPT_ERR;
300060ff233Sopenharmony_ci        }
301060ff233Sopenharmony_ci    } else {
302060ff233Sopenharmony_ci        if (EVP_DecryptInit_ex(*ctx, cipher, NULL, NULL, NULL) != 1) {
303060ff233Sopenharmony_ci            COMM_LOGE(COMM_ADAPTER, "EVP_DecryptInit_ex failed.");
304060ff233Sopenharmony_ci            EVP_CIPHER_CTX_free(*ctx);
305060ff233Sopenharmony_ci            *ctx = NULL;
306060ff233Sopenharmony_ci            return SOFTBUS_DECRYPT_ERR;
307060ff233Sopenharmony_ci        }
308060ff233Sopenharmony_ci    }
309060ff233Sopenharmony_ci    if (EVP_CIPHER_CTX_ctrl(*ctx, EVP_CTRL_GCM_SET_IVLEN, AES_IV_LENGTH, NULL) != 1) {
310060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_CIPHER_CTX_ctrl failed.");
311060ff233Sopenharmony_ci        EVP_CIPHER_CTX_free(*ctx);
312060ff233Sopenharmony_ci        *ctx = NULL;
313060ff233Sopenharmony_ci        return SOFTBUS_GCM_SET_IV_FAIL;
314060ff233Sopenharmony_ci    }
315060ff233Sopenharmony_ci    return SOFTBUS_OK;
316060ff233Sopenharmony_ci}
317060ff233Sopenharmony_ci
318060ff233Sopenharmony_cistatic int32_t OpensslAesGcmEncrypt(
319060ff233Sopenharmony_ci    const uint8_t *srcData, uint32_t srcDataLen, AesCipherKey *cipherKey, uint8_t *outData, uint32_t *outDataLen)
320060ff233Sopenharmony_ci{
321060ff233Sopenharmony_ci    if (srcData == NULL || srcDataLen == 0 || cipherKey == NULL || outData == NULL || outDataLen == NULL ||
322060ff233Sopenharmony_ci        *outDataLen < (srcDataLen + AES_GCM_TAG_LEN)) {
323060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "invalid param.");
324060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
325060ff233Sopenharmony_ci    }
326060ff233Sopenharmony_ci    EVP_CIPHER_CTX *ctx = NULL;
327060ff233Sopenharmony_ci    int32_t ret = GcmOpensslEvpInit(&ctx, cipherKey->keyLen, ENCRYPT_MODE);
328060ff233Sopenharmony_ci    COMM_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, SOFTBUS_ENCRYPT_ERR, COMM_ADAPTER, "GcmOpensslEvpInit failed.");
329060ff233Sopenharmony_ci    if (EVP_EncryptInit_ex(ctx, NULL, NULL, cipherKey->key, cipherKey->iv) != 1) {
330060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_EncryptInit_ex failed.");
331060ff233Sopenharmony_ci        goto EXIT;
332060ff233Sopenharmony_ci    }
333060ff233Sopenharmony_ci    int32_t outLen = 0;
334060ff233Sopenharmony_ci    int32_t outBufLen = 0;
335060ff233Sopenharmony_ci    if (EVP_EncryptUpdate(ctx, outData, &outBufLen, srcData, srcDataLen) != 1) {
336060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_EncryptUpdate failed.");
337060ff233Sopenharmony_ci        goto EXIT;
338060ff233Sopenharmony_ci    }
339060ff233Sopenharmony_ci    outLen += outBufLen;
340060ff233Sopenharmony_ci    if (EVP_EncryptFinal_ex(ctx, outData + outBufLen, &outBufLen) != 1) {
341060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_EncryptFinal_ex failed.");
342060ff233Sopenharmony_ci        goto EXIT;
343060ff233Sopenharmony_ci    }
344060ff233Sopenharmony_ci    if (outBufLen > INT32_MAX - outLen) {
345060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "outLen convert overflow.");
346060ff233Sopenharmony_ci        goto EXIT;
347060ff233Sopenharmony_ci    }
348060ff233Sopenharmony_ci    outLen += outBufLen;
349060ff233Sopenharmony_ci    if (*outDataLen < ((uint32_t)outLen + AES_GCM_TAG_LEN)) {
350060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "invalid param. *outDataLen=%{public}u, outLen=%{public}u", *outDataLen,
351060ff233Sopenharmony_ci            (uint32_t)outLen);
352060ff233Sopenharmony_ci        goto EXIT;
353060ff233Sopenharmony_ci    }
354060ff233Sopenharmony_ci    uint8_t tagbuf[AES_GCM_TAG_LEN]; // outData has two part: EncryptedData & AES-GCM-TAG
355060ff233Sopenharmony_ci    if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, AES_GCM_TAG_LEN, (void *)tagbuf) != 1) {
356060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_CTRL_GCM_GET_TAG failed.");
357060ff233Sopenharmony_ci        goto EXIT;
358060ff233Sopenharmony_ci    }
359060ff233Sopenharmony_ci    if (memcpy_s(outData + outLen, *outDataLen - outLen, tagbuf, AES_GCM_TAG_LEN) != EOK) {
360060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "tag memcpy_s failed.");
361060ff233Sopenharmony_ci        goto EXIT;
362060ff233Sopenharmony_ci    }
363060ff233Sopenharmony_ci    *outDataLen = outLen + AES_GCM_TAG_LEN;
364060ff233Sopenharmony_ci    EVP_CIPHER_CTX_free(ctx);
365060ff233Sopenharmony_ci    return SOFTBUS_OK;
366060ff233Sopenharmony_ciEXIT:
367060ff233Sopenharmony_ci    EVP_CIPHER_CTX_free(ctx);
368060ff233Sopenharmony_ci    return SOFTBUS_ENCRYPT_ERR;
369060ff233Sopenharmony_ci}
370060ff233Sopenharmony_ci
371060ff233Sopenharmony_cistatic int32_t OpensslAesGcmDecrypt(
372060ff233Sopenharmony_ci    const uint8_t *srcData, uint32_t srcDataLen, AesCipherKey *cipherKey, uint8_t *outData, uint32_t *outDataLen)
373060ff233Sopenharmony_ci{
374060ff233Sopenharmony_ci    if (srcData == NULL || srcDataLen <= AES_GCM_TAG_LEN || cipherKey == NULL || outData == NULL ||
375060ff233Sopenharmony_ci        outDataLen == NULL || *outDataLen < (srcDataLen - AES_GCM_TAG_LEN)) {
376060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "invalid param.");
377060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
378060ff233Sopenharmony_ci    }
379060ff233Sopenharmony_ci    EVP_CIPHER_CTX *ctx = NULL;
380060ff233Sopenharmony_ci    if (GcmOpensslEvpInit(&ctx, cipherKey->keyLen, DECRYPT_MODE) != SOFTBUS_OK) {
381060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "GcmOpensslEvpInit failed.");
382060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
383060ff233Sopenharmony_ci    }
384060ff233Sopenharmony_ci    if (EVP_DecryptInit_ex(ctx, NULL, NULL, cipherKey->key, cipherKey->iv) != 1) {
385060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_DecryptInit_ex failed.");
386060ff233Sopenharmony_ci        EVP_CIPHER_CTX_free(ctx);
387060ff233Sopenharmony_ci        return SOFTBUS_DECRYPT_ERR;
388060ff233Sopenharmony_ci    }
389060ff233Sopenharmony_ci    int32_t outLen = 0;
390060ff233Sopenharmony_ci    int32_t outBufLen = 0;
391060ff233Sopenharmony_ci    uint8_t trueEncryptedData[srcDataLen - AES_GCM_TAG_LEN];
392060ff233Sopenharmony_ci    if (memcpy_s(trueEncryptedData, srcDataLen - AES_GCM_TAG_LEN, srcData, srcDataLen - AES_GCM_TAG_LEN) != EOK) {
393060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "trueEncryptedData memcpy_s failed.");
394060ff233Sopenharmony_ci        goto EXIT;
395060ff233Sopenharmony_ci    }
396060ff233Sopenharmony_ci    if (EVP_CIPHER_CTX_ctrl(
397060ff233Sopenharmony_ci        ctx, EVP_CTRL_GCM_SET_TAG, AES_GCM_TAG_LEN, (void *)(srcData + (srcDataLen - AES_GCM_TAG_LEN))) != 1) {
398060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_CTRL_GCM_SET_TAG failed.");
399060ff233Sopenharmony_ci        goto EXIT;
400060ff233Sopenharmony_ci    }
401060ff233Sopenharmony_ci    if (EVP_DecryptUpdate(ctx, outData, &outBufLen, trueEncryptedData, srcDataLen - AES_GCM_TAG_LEN) != 1) {
402060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_DecryptUpdate failed.");
403060ff233Sopenharmony_ci        goto EXIT;
404060ff233Sopenharmony_ci    }
405060ff233Sopenharmony_ci    outLen += outBufLen;
406060ff233Sopenharmony_ci    if (EVP_DecryptFinal_ex(ctx, outData + outBufLen, &outBufLen) != 1) {
407060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "EVP_DecryptFinal_ex failed.");
408060ff233Sopenharmony_ci        goto EXIT;
409060ff233Sopenharmony_ci    }
410060ff233Sopenharmony_ci    if (outBufLen > INT32_MAX - outLen) {
411060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "outLen convert overflow.");
412060ff233Sopenharmony_ci        goto EXIT;
413060ff233Sopenharmony_ci    }
414060ff233Sopenharmony_ci    outLen += outBufLen;
415060ff233Sopenharmony_ci    *outDataLen = outLen;
416060ff233Sopenharmony_ci    EVP_CIPHER_CTX_free(ctx);
417060ff233Sopenharmony_ci    return SOFTBUS_OK;
418060ff233Sopenharmony_ciEXIT:
419060ff233Sopenharmony_ci    EVP_CIPHER_CTX_free(ctx);
420060ff233Sopenharmony_ci    return SOFTBUS_DECRYPT_ERR;
421060ff233Sopenharmony_ci}
422060ff233Sopenharmony_ci
423060ff233Sopenharmony_ciint32_t SoftBusAesGcmEncrypt(
424060ff233Sopenharmony_ci    const AesInputData *inData, AesCipherKey *cipherKey, int32_t encMode, AesOutputData *outData)
425060ff233Sopenharmony_ci{
426060ff233Sopenharmony_ci    if (inData == NULL || inData->data == NULL || cipherKey == NULL || cipherKey->key == NULL ||
427060ff233Sopenharmony_ci        cipherKey->iv == NULL || outData == NULL || (encMode != ENCRYPT_MODE && encMode != DECRYPT_MODE)) {
428060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "invalid param.");
429060ff233Sopenharmony_ci        return SOFTBUS_INVALID_PARAM;
430060ff233Sopenharmony_ci    }
431060ff233Sopenharmony_ci    uint32_t encryptDataLen = inData->len + AES_GCM_TAG_LEN;
432060ff233Sopenharmony_ci    uint8_t *encryptData = (uint8_t *)SoftBusCalloc(encryptDataLen);
433060ff233Sopenharmony_ci    if (encryptData == NULL) {
434060ff233Sopenharmony_ci        COMM_LOGE(COMM_ADAPTER, "encrypt data calloc fail.");
435060ff233Sopenharmony_ci        return SOFTBUS_MALLOC_ERR;
436060ff233Sopenharmony_ci    }
437060ff233Sopenharmony_ci    if (encMode == ENCRYPT_MODE) {
438060ff233Sopenharmony_ci        if (OpensslAesGcmEncrypt(inData->data, inData->len, cipherKey, encryptData, &encryptDataLen) != SOFTBUS_OK) {
439060ff233Sopenharmony_ci            COMM_LOGE(COMM_ADAPTER, "OpensslAesGcmEncrypt failed.");
440060ff233Sopenharmony_ci            SoftBusFree(encryptData);
441060ff233Sopenharmony_ci            encryptData = NULL;
442060ff233Sopenharmony_ci            return SOFTBUS_ENCRYPT_ERR;
443060ff233Sopenharmony_ci        }
444060ff233Sopenharmony_ci    } else {
445060ff233Sopenharmony_ci        if (OpensslAesGcmDecrypt(inData->data, inData->len, cipherKey, encryptData, &encryptDataLen) != SOFTBUS_OK) {
446060ff233Sopenharmony_ci            COMM_LOGE(COMM_ADAPTER, "OpensslAesGcmDecrypt failed.");
447060ff233Sopenharmony_ci            SoftBusFree(encryptData);
448060ff233Sopenharmony_ci            encryptData = NULL;
449060ff233Sopenharmony_ci            return SOFTBUS_DECRYPT_ERR;
450060ff233Sopenharmony_ci        }
451060ff233Sopenharmony_ci    }
452060ff233Sopenharmony_ci    outData->data = encryptData;
453060ff233Sopenharmony_ci    outData->len = encryptDataLen;
454060ff233Sopenharmony_ci    return SOFTBUS_OK;
455060ff233Sopenharmony_ci}