• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "vpn_encryption_util.h"
16 
17 #include <iterator>
18 #include <securec.h>
19 #include <sstream>
20 
21 #include "netmgr_ext_log_wrapper.h"
22 #include "net_manager_constants.h"
23 
24 namespace OHOS {
25 namespace NetManagerStandard {
26 struct HksParam g_genParam[] = {
27     { .tag = HKS_TAG_SPECIFIC_USER_ID, .int32Param = 0 },
28     { .tag = HKS_TAG_KEY_STORAGE_FLAG, .uint32Param = HKS_STORAGE_PERSISTENT },
29     { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
30     { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
31     { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
32     { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_NONE },
33     { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
34     { .tag = HKS_TAG_IS_KEY_ALIAS, .boolParam = true },
35     { .tag = HKS_TAG_KEY_GENERATE_TYPE, .uint32Param = HKS_KEY_GENERATE_TYPE_DEFAULT },
36     { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
37     { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_CE },
38     { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = { .size = AAD_SIZE, .data = (uint8_t *)AAD } },
39 };
40 
ConvertArrayChar(uint8_t ch)41 static char ConvertArrayChar(uint8_t ch)
42 {
43     constexpr int maxDecNum = 9;
44     constexpr int numDiffForHexAlphabet = 10;
45     if (ch <= maxDecNum) {
46         return '0' + ch;
47     }
48     if (ch <= 0xf) {
49         return ch + 'a' - numDiffForHexAlphabet;
50     }
51     return '0';
52 }
53 
IsValidHexCharAndConvert(char c)54 static int8_t IsValidHexCharAndConvert(char c)
55 {
56     if (c >= '0' && c <= '9') {
57         return c - '0';
58     }
59     if (c >= 'a' && c <= 'f') {
60         return c - 'a' + ('9' - '0' + 1);
61     }
62     if (c >= 'A' && c <= 'F') {
63         return c - 'A' + ('9' - '0' + 1);
64     }
65     return -1;
66 }
67 
ConvertArrayToHex(const uint8_t plainText[],uint32_t size)68 std::string ConvertArrayToHex(const uint8_t plainText[], uint32_t size)
69 {
70     constexpr int bitWidth = 4;
71     std::stringstream ss;
72     for (uint32_t i = 0; i < size; i++) {
73         ss << ConvertArrayChar(plainText[i] >> bitWidth) << ConvertArrayChar (plainText[i] & 0xf);
74     }
75     return ss.str();
76 }
77 
HexStringToVec(const std::string & str,std::vector<char> & vec)78 int HexStringToVec(const std::string &str, std::vector<char> &vec)
79 {
80     unsigned len = str.length();
81     if ((len & 1) != 0) {
82         return -1;
83     }
84     const int hexShiftNum = 4;
85     const int hexOffsetNum = 2;
86     for (unsigned i = 0; i + 1 < len;) {
87         uint8_t high = static_cast<uint8_t>(IsValidHexCharAndConvert(str[i]));
88         uint8_t low = static_cast<uint8_t>(IsValidHexCharAndConvert(str[i + 1]));
89         if (high < 0 || low < 0) {
90             return -1;
91         }
92         char tmp = ((high << hexShiftNum) | (low & 0x0F));
93         vec.push_back(tmp);
94         i += hexOffsetNum;
95     }
96     return 0;
97 }
98 
HexStringToVec(const std::string & str,uint8_t plainText[],uint32_t plainLength,uint32_t & resultLength)99 int HexStringToVec(const std::string &str, uint8_t plainText[], uint32_t plainLength, uint32_t &resultLength)
100 {
101     std::vector<char> result;
102     result.clear();
103     int ret = HexStringToVec(str, result);
104     if (ret == -1 || result.size() > plainLength) {
105         return -1;
106     }
107     for (std::vector<char>::size_type i = 0; i < result.size(); ++i) {
108         plainText[i] = result[i];
109     }
110     resultLength = result.size();
111     return 0;
112 }
113 
Split(const std::string & str,const std::string & sep)114 std::vector<std::string> Split(const std::string &str, const std::string &sep)
115 {
116     std::string s = str;
117     std::vector<std::string> res;
118     while (!s.empty()) {
119         size_t pos = s.find(sep);
120         if (pos == std::string::npos) {
121             res.emplace_back(s);
122             break;
123         }
124         res.emplace_back(s.substr(0, pos));
125         s = s.substr(pos + sep.size());
126     }
127     return res;
128 }
129 
SetUpHks()130 int32_t SetUpHks()
131 {
132     int32_t ret = HksInitialize();
133     if (ret != HKS_SUCCESS) {
134         NETMGR_EXT_LOG_E("vpn encryption init failed");
135     }
136     return ret;
137 }
138 
GetKeyByAlias(struct HksBlob * keyAlias,const struct HksParamSet * genParamSet)139 int32_t GetKeyByAlias(struct HksBlob *keyAlias, const struct HksParamSet *genParamSet)
140 {
141     if (keyAlias == nullptr || genParamSet == nullptr) {
142         NETMGR_EXT_LOG_E("%{public}s invalid param", __func__);
143         return -1;
144     }
145     int32_t keyExist = HksKeyExist(keyAlias, genParamSet);
146     if (keyExist == HKS_ERROR_NOT_EXIST) {
147         int32_t ret = HksGenerateKey(keyAlias, genParamSet, nullptr);
148         if (ret != HKS_SUCCESS) {
149             NETMGR_EXT_LOG_E("%{public}s generate key failed:%{public}d", __func__, keyExist);
150         }
151         return ret;
152     } else if (keyExist != HKS_SUCCESS) {
153         NETMGR_EXT_LOG_E("%{public}s search key failed:%{public}d", __func__, keyExist);
154         return keyExist;
155     }
156     return keyExist;
157 }
158 
VpnBuildHksParamSet(struct HksParamSet ** paramSet,int32_t userId)159 int32_t VpnBuildHksParamSet(struct HksParamSet **paramSet, int32_t userId)
160 {
161     uint8_t nonce[NONCE_SIZE] = {0};
162     struct HksParam IVParam[] = {
163         { .tag = HKS_TAG_NONCE, .blob = { .size = NONCE_SIZE, .data = nonce } },
164     };
165     g_genParam[0].int32Param = userId;
166     int32_t ret = HksInitParamSet(paramSet);
167     if (ret != HKS_SUCCESS) {
168         NETMGR_EXT_LOG_E("HksInitParamSet failed");
169         return ret;
170     }
171     ret = HksAddParams(*paramSet, g_genParam, sizeof(g_genParam) / sizeof(HksParam));
172     if (ret != HKS_SUCCESS) {
173         NETMGR_EXT_LOG_E("HksAddParams g_genParam failed");
174         HksFreeParamSet(paramSet);
175         return ret;
176     }
177     ret = HksAddParams(*paramSet, IVParam, sizeof(IVParam) / sizeof(HksParam));
178     if (ret != HKS_SUCCESS) {
179         NETMGR_EXT_LOG_E("HksAddParams IVParam failed");
180         HksFreeParamSet(paramSet);
181         return ret;
182     }
183     ret = HksBuildParamSet(paramSet);
184     if (ret != HKS_SUCCESS) {
185         NETMGR_EXT_LOG_E("HksBuildParamSet failed");
186         HksFreeParamSet(paramSet);
187         return ret;
188     }
189     return ret;
190 }
191 
VpnEncryptData(const VpnEncryptionInfo & vpnEncryptionInfo,std::string & data)192 int32_t VpnEncryptData(const VpnEncryptionInfo &vpnEncryptionInfo, std::string &data)
193 {
194     if (!data.empty()) {
195         EncryptedData encryptedData;
196         if (VpnEncryption(vpnEncryptionInfo, data, encryptedData) != HKS_SUCCESS) {
197             NETMGR_EXT_LOG_E("VpnEncryption failed");
198             return NETMANAGER_EXT_ERR_INTERNAL;
199         }
200         data = encryptedData.encryptedData_ + ENCRYT_SPLIT_SEP + encryptedData.iv_;
201     }
202     return NETMANAGER_EXT_SUCCESS;
203 }
204 
VpnDecryptData(const VpnEncryptionInfo & vpnEncryptionInfo,std::string & data)205 int32_t VpnDecryptData(const VpnEncryptionInfo &vpnEncryptionInfo, std::string &data)
206 {
207     if (!data.empty()) {
208         const std::vector<std::string> encryedDataStrs = Split(data, ENCRYT_SPLIT_SEP);
209         if (encryedDataStrs.size() > 1) {
210             EncryptedData *encryptedData = new (std::nothrow) EncryptedData(encryedDataStrs[0], encryedDataStrs[1]);
211             if (encryptedData == nullptr) {
212                 NETMGR_EXT_LOG_E("new EncryptedData failed");
213                 return NETMANAGER_EXT_ERR_INTERNAL;
214             }
215             std::string decryptedData = "";
216             if (VpnDecryption(vpnEncryptionInfo, *encryptedData, decryptedData) != HKS_SUCCESS) {
217                 NETMGR_EXT_LOG_E("VpnDecryption failed");
218                 delete encryptedData;
219                 encryptedData = nullptr;
220                 return NETMANAGER_EXT_ERR_INTERNAL;
221             }
222             data = decryptedData;
223             delete encryptedData;
224             encryptedData = nullptr;
225         }
226     }
227     return NETMANAGER_EXT_SUCCESS;
228 }
229 
VpnEncryption(const VpnEncryptionInfo & vpnEncryptionInfo,const std::string & inputString,EncryptedData & encryptedData)230 int32_t VpnEncryption(const VpnEncryptionInfo &vpnEncryptionInfo, const std::string &inputString,
231     EncryptedData &encryptedData)
232 {
233     if (inputString.length() == 0) {
234         return HKS_SUCCESS;
235     }
236     struct HksBlob authId = vpnEncryptionInfo.keyAlias;
237     struct HksBlob plainText = { inputString.length(), (uint8_t *)&inputString[0] };
238 
239     uint8_t nonce[NONCE_SIZE] = {0};
240     struct HksBlob randomIV = {NONCE_SIZE, nonce};
241     int32_t ret = HksGenerateRandom(NULL, &randomIV);
242     if (ret != HKS_SUCCESS) {
243         NETMGR_EXT_LOG_E("vpn encryption generate IV failed");
244         return ret;
245     }
246 
247     struct HksParamSet *encryParamSet = nullptr;
248     ret = VpnBuildHksParamSet(&encryParamSet, vpnEncryptionInfo.userId);
249     if (ret != HKS_SUCCESS) {
250         NETMGR_EXT_LOG_E("VpnBuildHksParamSet failed");
251         return ret;
252     }
253 
254     ret = GetKeyByAlias(&authId, encryParamSet);
255     if (ret != HKS_SUCCESS) {
256         NETMGR_EXT_LOG_E("vpn encryption failed");
257         HksFreeParamSet(&encryParamSet);
258         return ret;
259     }
260 
261     uint8_t cipherBuf[AES_COMMON_SIZE] = {0};
262     HksBlob cipherData = {
263         .size = AES_COMMON_SIZE,
264         .data = cipherBuf
265     };
266 
267     ret = HksEncrypt(&authId, encryParamSet, &plainText, &cipherData);
268     if (ret != HKS_SUCCESS) {
269         NETMGR_EXT_LOG_E("Hks encryption failed");
270         HksFreeParamSet(&encryParamSet);
271         return ret;
272     }
273 
274     encryptedData.encryptedData_ = ConvertArrayToHex(cipherBuf, cipherData.size);
275     encryptedData.iv_ = ConvertArrayToHex(nonce, NONCE_SIZE);
276     HksFreeParamSet(&encryParamSet);
277     return ret;
278 }
279 
VpnDecryption(const VpnEncryptionInfo & vpnEncryptionInfo,const EncryptedData & encryptedData,std::string & decryptedData)280 int32_t VpnDecryption(const VpnEncryptionInfo &vpnEncryptionInfo, const EncryptedData &encryptedData,
281     std::string &decryptedData)
282 {
283     if (encryptedData.encryptedData_.size() == 0) {
284         return HKS_SUCCESS;
285     }
286     struct HksBlob authId = vpnEncryptionInfo.keyAlias;
287     uint8_t cipherBuf[AES_COMMON_SIZE] = {0};
288     uint32_t length = AES_COMMON_SIZE;
289     int32_t retStrToArrat = HexStringToVec(encryptedData.encryptedData_, cipherBuf, AES_COMMON_SIZE, length);
290     if (retStrToArrat != 0) {
291         return HKS_FAILURE;
292     }
293 
294     uint8_t nonce[NONCE_SIZE] = {0};
295     uint32_t lengthIV = NONCE_SIZE;
296     retStrToArrat = HexStringToVec(encryptedData.iv_, nonce, NONCE_SIZE, lengthIV);
297     if (retStrToArrat != 0) {
298         return HKS_FAILURE;
299     }
300 
301     struct HksBlob cipherData = { length, cipherBuf };
302     struct HksParamSet *decryParamSet = nullptr;
303     int32_t ret = VpnBuildHksParamSet(&decryParamSet, vpnEncryptionInfo.userId);
304     if (ret != HKS_SUCCESS) {
305         NETMGR_EXT_LOG_E("BuildHksParamSet failed");
306         return ret;
307     }
308 
309     ret = HksKeyExist(&authId, decryParamSet);
310     if (ret != HKS_SUCCESS) {
311         NETMGR_EXT_LOG_E("vpn decryption key not exist");
312         HksFreeParamSet(&decryParamSet);
313         return ret;
314     }
315     uint8_t plainBuff[AES_COMMON_SIZE] = {0};
316     HksBlob plainText = {
317         .size = AES_COMMON_SIZE,
318         .data = plainBuff
319     };
320 
321     ret = HksDecrypt(&authId, decryParamSet, &cipherData, &plainText);
322     if (ret != HKS_SUCCESS) {
323         NETMGR_EXT_LOG_E("Hks decryption failed");
324         HksFreeParamSet(&decryParamSet);
325         return ret;
326     }
327 
328     std::string temp(plainText.data, plainText.data + plainText.size);
329     decryptedData = temp;
330     HksFreeParamSet(&decryParamSet);
331     return ret;
332 }
333 
334 }  // namespace NetManagerStandard
335 }  // namespace OHOS