1 /*
2 * Copyright (C) 2024 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 "../include/wifi_openssl_utils.h"
17 #include <openssl/evp.h>
18 #include <openssl/rand.h>
19 #include "common.h"
20 #include "log.h"
21
22 #undef LOG_TAG
23 #define LOG_TAG "WifiOpensslUtils"
24
25 namespace OHOS {
26 namespace Wifi {
27
28 #define AES_GCM_128 2
29 #define AES_GCM_256 3
30 #define AES_GCM_TAG_LEN 4
31
GetInstance()32 WifiOpensslUtils &WifiOpensslUtils::GetInstance()
33 {
34 static WifiOpensslUtils gWifiOpensslUtils;
35 return gWifiOpensslUtils;
36 }
37
WifiOpensslUtils()38 WifiOpensslUtils::WifiOpensslUtils()
39 {
40 LOGI("%{public}s create success", __func__);
41 }
42
~WifiOpensslUtils()43 WifiOpensslUtils::~WifiOpensslUtils()
44 {
45 LOGI("%{public}s destory success", __func__);
46 }
47
GetAesCipher(int aesType)48 EVP_CIPHER *GetAesCipher(int aesType)
49 {
50 EVP_CIPHER *cipher = nullptr;
51 LOGD("%{public}s aesType %{public}d !", __func__, aesType);
52 switch (aesType) {
53 case AES_GCM_128 :
54 cipher = const_cast<EVP_CIPHER *>(EVP_aes_128_gcm());
55 break;
56 case AES_GCM_256 :
57 cipher = const_cast<EVP_CIPHER *>(EVP_aes_256_gcm());
58 break;
59 default:
60 cipher = const_cast<EVP_CIPHER *>(EVP_aes_128_gcm());
61 }
62 return cipher;
63 }
64
OpensslAesEncrypt(const uint8_t * plainText,int plainTextLen,struct AesCipherInfo * info,uint8_t * cipherText,int * cipherTextLen)65 int WifiOpensslUtils::OpensslAesEncrypt(const uint8_t *plainText, int plainTextLen,
66 struct AesCipherInfo *info, uint8_t *cipherText, int *cipherTextLen)
67 {
68 LOGI("enter %{public}s", __func__);
69 int res = -1;
70 if (plainText == nullptr || plainTextLen == 0 || info == nullptr ||
71 cipherText == nullptr || cipherTextLen == nullptr) {
72 LOGE("%{public}s param is illegal", __func__);
73 return res;
74 }
75
76 EVP_CIPHER_CTX *ctx = nullptr;
77 int len = 0;
78 const EVP_CIPHER *cipher = GetAesCipher(info->aesType);
79
80 if ((ctx = EVP_CIPHER_CTX_new()) == nullptr) {
81 goto err;
82 }
83
84 if (EVP_EncryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr) != 1) {
85 goto err;
86 }
87
88 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, AES_IV_LEN, nullptr) != 1) {
89 goto err;
90 }
91
92 if (EVP_EncryptInit_ex(ctx, nullptr, nullptr, info->key, info->iv) != 1) {
93 goto err;
94 }
95
96 if (EVP_EncryptUpdate(ctx, cipherText, &len, plainText, plainTextLen) != 1) {
97 goto err;
98 }
99 *cipherTextLen = len;
100
101 if (EVP_EncryptFinal_ex(ctx, cipherText + len, &len) != 1) {
102 goto err;
103 }
104 *cipherTextLen += len;
105
106 uint8_t tag[AES_GCM_TAG_LEN];
107 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, AES_GCM_TAG_LEN, static_cast<void *>(tag)) != 1) {
108 goto err;
109 }
110
111 if (memcpy_s(cipherText + *cipherTextLen, AES_GCM_TAG_LEN, tag, AES_GCM_TAG_LEN) != 0) {
112 LOGE("%{public}s: Aes Encrypt memcpy_s failed !", __func__);
113 goto err;
114 }
115 *cipherTextLen += AES_GCM_TAG_LEN;
116 res = 0;
117 err:
118 if (ctx != nullptr) {
119 LOGE("%{public}s: Aes Encrypt encrypt res %{public}d !", __func__, res);
120 EVP_CIPHER_CTX_free(ctx);
121 }
122 return res;
123 }
124
OpensslAesDecrypt(const uint8_t * cipherText,int cipherTextLen,struct AesCipherInfo * info,uint8_t * plainText,int * plainTextLen)125 int WifiOpensslUtils::OpensslAesDecrypt(const uint8_t *cipherText, int cipherTextLen,
126 struct AesCipherInfo *info, uint8_t *plainText, int *plainTextLen)
127 {
128 LOGI("enter %{public}s", __func__);
129 int res = -1;
130 if (cipherText == nullptr || cipherTextLen == 0 || info == nullptr ||
131 cipherTextLen <= AES_GCM_TAG_LEN) {
132 LOGE("%{public}s param is illegal", __func__);
133 return res;
134 }
135
136 EVP_CIPHER_CTX *ctx = nullptr;
137 int len = 0;
138 const EVP_CIPHER *cipher = GetAesCipher(info->aesType);
139
140 if ((ctx = EVP_CIPHER_CTX_new()) == nullptr) {
141 LOGI("%{public}s: Aes decrypt new ctx fail!", __func__);
142 goto err;
143 }
144
145 if (EVP_DecryptInit_ex(ctx, cipher, nullptr, nullptr, nullptr) != 1) {
146 LOGI("%{public}s: Aes decrypt init fail!", __func__);
147 goto err;
148 }
149
150 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, AES_IV_LEN, nullptr) != 1) {
151 LOGI("%{public}s: Aes decrypt set iv len fail!", __func__);
152 goto err;
153 }
154
155 if (EVP_DecryptInit_ex(ctx, nullptr, nullptr, info->key, info->iv) != 1) {
156 LOGI("%{public}s: Aes decrypt set key & iv fail!", __func__);
157 goto err;
158 }
159
160 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, AES_GCM_TAG_LEN,
161 static_cast<void *>(const_cast<uint8_t *>(cipherText + (cipherTextLen - AES_GCM_TAG_LEN)))) != 1) {
162 LOGI("%{public}s: Aes decrypt tag fail!", __func__);
163 goto err;
164 }
165
166 if (EVP_DecryptUpdate(ctx, plainText, &len, cipherText, cipherTextLen - AES_GCM_TAG_LEN) != 1) {
167 LOGI("%{public}s: Aes decrypt start decrypt fail!", __func__);
168 goto err;
169 }
170 *plainTextLen = len;
171
172 if (EVP_DecryptFinal_ex(ctx, plainText + len, &len) != 1) {
173 LOGI("%{public}s: Aes decrypt final fail!", __func__);
174 goto err;
175 }
176 *plainTextLen += len;
177
178 res = 0;
179 err:
180 if (ctx != nullptr) {
181 EVP_CIPHER_CTX_free(ctx);
182 }
183 return res;
184 }
185
186 }
187 }
188