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 #include "wifi_encryption_util.h"
16 #if defined(FEATURE_ENCRYPTION_SUPPORT) || defined(SUPPORT_LOCAL_RANDOM_MAC)
17 #include <iterator>
18 #include <sstream>
19 #include "wifi_logger.h"
20 #include "wifi_global_func.h"
21 DEFINE_WIFILOG_LABEL("WifiConfigEncryption");
22 namespace OHOS {
23 namespace Wifi {
24 
25 struct HksParam g_genParam[] = {
26     { .tag = HKS_TAG_KEY_STORAGE_FLAG, .uint32Param = HKS_STORAGE_PERSISTENT },
27     { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
28     { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
29     { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
30     { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_NONE },
31     { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
32     { .tag = HKS_TAG_IS_KEY_ALIAS, .boolParam = true },
33     { .tag = HKS_TAG_KEY_GENERATE_TYPE, .uint32Param = HKS_KEY_GENERATE_TYPE_DEFAULT },
34     { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
35     { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
36     { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = { .size = AAD_SIZE, .data = (uint8_t *)AAD } },
37 };
38 
39 struct HksParam g_genAes256Param[] = {
40     { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
41     { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
42     { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_NONE },
43     { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
44     { .tag = HKS_TAG_IS_KEY_ALIAS, .boolParam = true },
45     { .tag = HKS_TAG_KEY_GENERATE_TYPE, .uint32Param = HKS_KEY_GENERATE_TYPE_DEFAULT },
46     { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
47     { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
48 };
49 
50 static struct HksParam g_genHmacParams[] = {
51     { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_HMAC },
52     { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_MAC },
53     { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
54     { .tag = HKS_TAG_DIGEST, .uint32Param = HKS_DIGEST_SHA256 },
55     { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
56 };
57 
SetUpHks()58 int32_t SetUpHks()
59 {
60     int32_t ret = HksInitialize();
61     if (ret != HKS_SUCCESS) {
62         WIFI_LOGE("wifi encryption init failed");
63     }
64     return ret;
65 }
66 
GetKeyByAlias(struct HksBlob * keyAlias,const struct HksParamSet * genParamSet)67 int32_t GetKeyByAlias(struct HksBlob *keyAlias, const struct HksParamSet *genParamSet)
68 {
69     if (keyAlias == nullptr || genParamSet == nullptr) {
70         WIFI_LOGE("%{public}s invalid param", __func__);
71         return -1;
72     }
73     int32_t keyExist = HksKeyExist(keyAlias, genParamSet);
74     if (keyExist == HKS_ERROR_NOT_EXIST) {
75         int32_t ret = HksGenerateKey(keyAlias, genParamSet, nullptr);
76         if (ret != HKS_SUCCESS) {
77             WIFI_LOGE("%{public}s generate key failed:%{public}d", __func__, keyExist);
78             return ret;
79         } else {
80             return ret;
81         }
82     } else if (keyExist != HKS_SUCCESS) {
83         WIFI_LOGE("%{public}s search key failed:%{public}d", __func__, keyExist);
84         return keyExist;
85     }
86     return keyExist;
87 }
88 
WifiEncryption(const WifiEncryptionInfo & wifiEncryptionInfo,const std::string & inputString,EncryptedData & encryptedData)89 int32_t WifiEncryption(const WifiEncryptionInfo &wifiEncryptionInfo, const std::string &inputString,
90     EncryptedData &encryptedData)
91 {
92     if (inputString.length() == 0) {
93         return HKS_SUCCESS;
94     }
95     struct HksBlob authId = wifiEncryptionInfo.keyAlias;
96     struct HksBlob plainText = { inputString.length(), (uint8_t *)&inputString[0] };
97 
98     uint8_t nonce[NONCE_SIZE] = {0};
99     struct HksBlob randomIV = {NONCE_SIZE, nonce};
100     int32_t ret = HksGenerateRandom(NULL, &randomIV);
101     if (ret != HKS_SUCCESS) {
102         WIFI_LOGE("wifi encryption generate IV failed");
103         return ret;
104     }
105     struct HksParam IVParam[] = {
106         { .tag = HKS_TAG_NONCE, .blob = { .size = NONCE_SIZE, .data = nonce } },
107     };
108 
109     struct HksParamSet *encryParamSet = nullptr;
110     HksInitParamSet(&encryParamSet);
111     HksAddParams(encryParamSet, g_genParam, sizeof(g_genParam) / sizeof(HksParam));
112     HksAddParams(encryParamSet, IVParam, sizeof(IVParam) / sizeof(HksParam));
113     HksBuildParamSet(&encryParamSet);
114 
115     ret = GetKeyByAlias(&authId, encryParamSet);
116     if (ret != HKS_SUCCESS) {
117         WIFI_LOGE("wifi encryption failed");
118         return ret;
119     }
120 
121     uint8_t cipherBuf[AES_COMMON_SIZE] = {0};
122     HksBlob cipherData = {
123         .size = AES_COMMON_SIZE,
124         .data = cipherBuf
125     };
126 
127     ret = HksEncrypt(&authId, encryParamSet, &plainText, &cipherData);
128     if (ret != HKS_SUCCESS) {
129         WIFI_LOGE("Hks encryption failed");
130         return ret;
131     }
132 
133     encryptedData.encryptedPassword = ConvertArrayToHex(cipherBuf, cipherData.size);
134     encryptedData.IV = ConvertArrayToHex(nonce, NONCE_SIZE);
135     HksFreeParamSet(&encryParamSet);
136     return ret;
137 }
138 
WifiDecryption(const WifiEncryptionInfo & wifiEncryptionInfo,const EncryptedData & encryptedData,std::string & decryptedData)139 int32_t WifiDecryption(const WifiEncryptionInfo &wifiEncryptionInfo, const EncryptedData &encryptedData,
140     std::string &decryptedData)
141 {
142     if (encryptedData.encryptedPassword.size() == 0) {
143         return HKS_SUCCESS;
144     }
145     struct HksBlob authId = wifiEncryptionInfo.keyAlias;
146     uint8_t cipherBuf[AES_COMMON_SIZE] = {0};
147     uint32_t length = AES_COMMON_SIZE;
148     int32_t retStrToArrat = HexStringToVec(encryptedData.encryptedPassword, cipherBuf, AES_COMMON_SIZE, length);
149     if (retStrToArrat != 0) {
150         return HKS_FAILURE;
151     }
152 
153     uint8_t nonce[NONCE_SIZE] = {0};
154     uint32_t lengthIV = NONCE_SIZE;
155     retStrToArrat = HexStringToVec(encryptedData.IV, nonce, NONCE_SIZE, lengthIV);
156     if (retStrToArrat != 0) {
157         return HKS_FAILURE;
158     }
159     struct HksParam IVParam[] = {
160         { .tag = HKS_TAG_NONCE, .blob = { .size = NONCE_SIZE, .data = nonce } },
161     };
162 
163     struct HksBlob cipherData = { length, cipherBuf };
164     struct HksParamSet *decryParamSet = nullptr;
165 
166     HksInitParamSet(&decryParamSet);
167     HksAddParams(decryParamSet, g_genParam, sizeof(g_genParam) / sizeof(HksParam));
168     HksAddParams(decryParamSet, IVParam, sizeof(IVParam) / sizeof(HksParam));
169     HksBuildParamSet(&decryParamSet);
170 
171     int32_t ret = HksKeyExist(&authId, decryParamSet);
172     if (ret != HKS_SUCCESS) {
173         WIFI_LOGE("wifi decryption key not exist");
174         return ret;
175     }
176     uint8_t plainBuff[AES_COMMON_SIZE] = {0};
177     HksBlob plainText = {
178         .size = AES_COMMON_SIZE,
179         .data = plainBuff
180     };
181 
182     ret = HksDecrypt(&authId, decryParamSet, &cipherData, &plainText);
183     if (ret != HKS_SUCCESS) {
184         WIFI_LOGE("Hks decryption failed");
185         return ret;
186     }
187 
188     std::string temp(plainText.data, plainText.data + plainText.size);
189     decryptedData = temp;
190     HksFreeParamSet(&decryParamSet);
191     return ret;
192 }
193 
HksUpdateAndFinish(const struct HksBlob * handle,const struct HksParamSet * paramSet,const struct HksBlob * inData,struct HksBlob * outData)194 int32_t HksUpdateAndFinish(const struct HksBlob *handle, const struct HksParamSet *paramSet,
195     const struct HksBlob *inData, struct HksBlob *outData)
196 {
197     uint32_t handledInDataSize = 0;
198     uint32_t handledOutDataSize = 0;
199     uint8_t *handledOutData = outData->data;
200     struct HksBlob inDataSeg = *inData;
201     struct HksBlob outDataSeg = { MAX_UPDATE_SIZE, nullptr };
202     WIFI_LOGI("HksUpdateAndFinish inData.size: %{public}d.", static_cast<int>(inData->size));
203     while (handledInDataSize < inData->size) {
204         uint32_t aesDataLen = std::min(MAX_UPDATE_SIZE, (inData->size - handledInDataSize));
205         inDataSeg.size = aesDataLen;
206         outDataSeg.size = MAX_UPDATE_SIZE + AEAD_SIZE;
207         outDataSeg.data = (uint8_t *)malloc(outDataSeg.size);
208         if (outDataSeg.data == nullptr) {
209             WIFI_LOGE("HksUpdateAndFinish malloc failed.");
210             return HKS_FAILURE;
211         }
212         int32_t hksResult = 0;
213         if (handledInDataSize + aesDataLen < inData->size) {
214             hksResult = HksUpdate(handle, paramSet, &inDataSeg, &outDataSeg);
215         } else {
216             hksResult = HksFinish(handle, paramSet, &inDataSeg, &outDataSeg);
217         }
218         if (hksResult != HKS_SUCCESS) {
219             WIFI_LOGE("HksUpdateAndFinish do HksUpdate or HksFinish failed: %{public}d.", hksResult);
220             free(outDataSeg.data);
221             outDataSeg.data = nullptr;
222             return HKS_FAILURE;
223         }
224 
225         if (handledOutDataSize + outDataSeg.size > outData->size) {
226             WIFI_LOGE("HksUpdateAndFinish outData->size is too small.");
227             free(outDataSeg.data);
228             outDataSeg.data = nullptr;
229             return HKS_FAILURE;
230         }
231         if (memcpy_s(handledOutData, outDataSeg.size, outDataSeg.data, outDataSeg.size) != EOK) {
232             WIFI_LOGE("HksUpdateAndFinish memcpy_s failed.");
233             free(outDataSeg.data);
234             outDataSeg.data = nullptr;
235             return HKS_FAILURE;
236         }
237         handledOutData += outDataSeg.size;
238         handledOutDataSize += outDataSeg.size;
239         inDataSeg.data += aesDataLen;
240         handledInDataSize += aesDataLen;
241         free(outDataSeg.data);
242         outDataSeg.data = nullptr;
243     }
244     outData->size = handledOutDataSize;
245     WIFI_LOGI("HksUpdateAndFinish outData.size: %{public}d.", static_cast<int>(outData->size));
246     return HKS_SUCCESS;
247 }
248 
ImportKey(const WifiEncryptionInfo & wifiEncryptionInfo,const std::string & key)249 int32_t ImportKey(const WifiEncryptionInfo &wifiEncryptionInfo, const std::string &key)
250 {
251     WIFI_LOGI("ImportKey enter.");
252     uint8_t aesKey[AES_COMMON_SIZE] = { 0 };
253     uint32_t length = 0;
254     if (HexStringToVec(key, aesKey, AES_COMMON_SIZE, length) != 0) {
255         WIFI_LOGE("ImportKey HexStringToVec failed.");
256         return HKS_FAILURE;
257     }
258 
259     struct HksBlob hksKey = { length, aesKey };
260     struct HksBlob authId = wifiEncryptionInfo.keyAlias;
261     struct HksParam purposeParam[] = {
262         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
263     };
264     struct HksParamSet *encryParamSet = nullptr;
265     HksInitParamSet(&encryParamSet);
266     HksAddParams(encryParamSet, g_genAes256Param, sizeof(g_genAes256Param) / sizeof(HksParam));
267     HksAddParams(encryParamSet, purposeParam, sizeof(purposeParam) / sizeof(HksParam));
268     HksBuildParamSet(&encryParamSet);
269 
270     int32_t keyExist = HksKeyExist(&authId, encryParamSet);
271     if (keyExist == HKS_ERROR_NOT_EXIST) {
272         int32_t ret = HksImportKey(&authId, encryParamSet, &hksKey);
273         if (memset_s(aesKey, sizeof(aesKey), 0, sizeof(aesKey)) != EOK) {
274             WIFI_LOGE("ImportKey memset_s return error!");
275             return HKS_FAILURE;
276         }
277         if (ret != HKS_SUCCESS) {
278             WIFI_LOGE("ImportKey failed: %{public}d.", ret);
279         }
280         return ret;
281     } else if (keyExist == HKS_SUCCESS) {
282         WIFI_LOGI("ImportKey key is exist, donot need import key.");
283         return HKS_SUCCESS;
284     }
285     WIFI_LOGE("ImportKey HksKeyExist check failed: %{public}d.", keyExist);
286     return keyExist;
287 }
288 
DeleteKey(const WifiEncryptionInfo & wifiEncryptionInfo)289 int32_t DeleteKey(const WifiEncryptionInfo &wifiEncryptionInfo)
290 {
291     WIFI_LOGI("DeleteKey enter.");
292     struct HksBlob authId = wifiEncryptionInfo.keyAlias;
293     struct HksParam purposeParam[] = {
294         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
295     };
296     struct HksParamSet *encryParamSet = nullptr;
297     HksInitParamSet(&encryParamSet);
298     HksAddParams(encryParamSet, g_genAes256Param, sizeof(g_genAes256Param) / sizeof(HksParam));
299     HksAddParams(encryParamSet, purposeParam, sizeof(purposeParam) / sizeof(HksParam));
300     HksBuildParamSet(&encryParamSet);
301 
302     int32_t keyExist = HksKeyExist(&authId, encryParamSet);
303     if (keyExist == HKS_SUCCESS) {
304         int32_t ret = HksDeleteKey(&authId, encryParamSet);
305         if (ret != HKS_SUCCESS) {
306             WIFI_LOGE("DeleteKey failed: %{public}d.", ret);
307         }
308         return ret;
309     } else if (keyExist == HKS_ERROR_NOT_EXIST) {
310         WIFI_LOGI("DeleteKey key is not exist, donot need delete key.");
311         return HKS_SUCCESS;
312     }
313     WIFI_LOGE("DeleteKey HksKeyExist check failed: %{public}d.", keyExist);
314     return keyExist;
315 }
316 
EncryptParamSet(struct HksParamSet ** encryParamSet,const WifiEncryptionInfo & wifiEncryptionInfo,const EncryptedData & encryptedData)317 int32_t EncryptParamSet(struct HksParamSet **encryParamSet, const WifiEncryptionInfo &wifiEncryptionInfo,
318     const EncryptedData &encryptedData)
319 {
320     uint8_t nonce[AES_256_NONCE_SIZE] = { 0 };
321     uint32_t nonceLength = 0;
322     if (HexStringToVec(encryptedData.IV, nonce, AES_256_NONCE_SIZE, nonceLength) != 0) {
323         WIFI_LOGE("EncryptParamSet HexStringToVec failed.");
324         return HKS_FAILURE;
325     }
326     struct HksBlob encryptNonce = { nonceLength, nonce };
327     struct HksParam encryptParam[] = {
328         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT },
329         { .tag = HKS_TAG_NONCE, .blob = { .size = encryptNonce.size, .data = encryptNonce.data } },
330     };
331 
332     HksInitParamSet(encryParamSet);
333     HksAddParams(*encryParamSet, g_genAes256Param, sizeof(g_genAes256Param) / sizeof(HksParam));
334     HksAddParams(*encryParamSet, encryptParam, sizeof(encryptParam) / sizeof(HksParam));
335     HksBuildParamSet(encryParamSet);
336 
337     struct HksBlob authId = wifiEncryptionInfo.keyAlias;
338     int32_t ret = HksKeyExist(&authId, *encryParamSet);
339     if (ret != HKS_SUCCESS) {
340         WIFI_LOGE("EncryptParamSet Key is not exist.");
341         return ret;
342     }
343     return HKS_SUCCESS;
344 }
345 
DecryptParamSet(struct HksParamSet ** decryParamSet,const WifiEncryptionInfo & wifiEncryptionInfo,const EncryptedData & encryptedData)346 int32_t DecryptParamSet(struct HksParamSet **decryParamSet, const WifiEncryptionInfo &wifiEncryptionInfo,
347     const EncryptedData &encryptedData)
348 {
349     uint8_t nonce[AES_256_NONCE_SIZE] = { 0 };
350     uint32_t nonceLength = 0;
351     if (HexStringToVec(encryptedData.IV, nonce, AES_256_NONCE_SIZE, nonceLength) != 0) {
352         WIFI_LOGE("DecryptParamSet HexStringToVec failed.");
353         return HKS_FAILURE;
354     }
355     struct HksBlob decryptNonce = { nonceLength, nonce };
356     uint32_t cipherLength = encryptedData.encryptedPassword.length();
357     uint8_t *cipherBuf = reinterpret_cast<uint8_t*>(const_cast<char*>(encryptedData.encryptedPassword.c_str()));
358     if (cipherLength < AEAD_SIZE) {
359         WIFI_LOGE("DecryptParamSet cipherLength is too small.");
360         return HKS_FAILURE;
361     }
362     struct HksBlob decryptAead = { AEAD_SIZE, cipherBuf + cipherLength - AEAD_SIZE };
363     struct HksParam decryptParam[] = {
364         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
365         { .tag = HKS_TAG_NONCE, .blob = { .size = decryptNonce.size, .data = decryptNonce.data } },
366         { .tag = HKS_TAG_AE_TAG, .blob = { .size = decryptAead.size, .data = decryptAead.data } },
367     };
368 
369     HksInitParamSet(decryParamSet);
370     HksAddParams(*decryParamSet, g_genAes256Param, sizeof(g_genAes256Param) / sizeof(HksParam));
371     HksAddParams(*decryParamSet, decryptParam, sizeof(decryptParam) / sizeof(HksParam));
372     HksBuildParamSet(decryParamSet);
373 
374     struct HksBlob authId = wifiEncryptionInfo.keyAlias;
375     int32_t ret = HksKeyExist(&authId, *decryParamSet);
376     if (ret != HKS_SUCCESS) {
377         WIFI_LOGE("DecryptParamSet Key is not exist.");
378         return ret;
379     }
380     return HKS_SUCCESS;
381 }
382 
WifiLoopEncrypt(const WifiEncryptionInfo & wifiEncryptionInfo,const std::string & inputString,EncryptedData & encryptedData)383 int32_t WifiLoopEncrypt(const WifiEncryptionInfo &wifiEncryptionInfo, const std::string &inputString,
384     EncryptedData &encryptedData)
385 {
386     if (inputString.length() == 0) {
387         WIFI_LOGI("WifiLoopEncrypt inputString is nullptr.");
388         return HKS_SUCCESS;
389     }
390 
391     struct HksParamSet *encryParamSet = nullptr;
392     int32_t ret = EncryptParamSet(&encryParamSet, wifiEncryptionInfo, encryptedData);
393     if (ret != HKS_SUCCESS) {
394         WIFI_LOGE("WifiLoopEncrypt EncryptParamSet failed: %{public}d.", ret);
395         return ret;
396     }
397 
398     uint8_t handle[sizeof(uint64_t)] = { 0 };
399     struct HksBlob handleEncrypt = { sizeof(uint64_t), handle };
400     struct HksBlob authId = wifiEncryptionInfo.keyAlias;
401     ret = HksInit(&authId, encryParamSet, &handleEncrypt, nullptr);
402     if (ret != HKS_SUCCESS) {
403         WIFI_LOGE("WifiLoopEncrypt HksInit failed: %{public}d.", ret);
404         return ret;
405     }
406 
407     struct HksBlob inData = { inputString.length(), (uint8_t *)&inputString[0] };
408     uint8_t *cipherBuf = (uint8_t *)malloc(inputString.length() + AEAD_SIZE);
409     if (cipherBuf == nullptr) {
410         WIFI_LOGE("WifiLoopEncrypt malloc failed.");
411         return HKS_FAILURE;
412     }
413     struct HksBlob outData = { inputString.length() + AEAD_SIZE, cipherBuf };
414     ret = HksUpdateAndFinish(&handleEncrypt, encryParamSet, &inData, &outData);
415     if (ret != HKS_SUCCESS) {
416         WIFI_LOGE("WifiLoopEncrypt HksUpdateAndFinish failed: %{public}d.", ret);
417         free(cipherBuf);
418         cipherBuf = nullptr;
419         return ret;
420     }
421 
422     std::string temp(outData.data, outData.data + outData.size);
423     encryptedData.encryptedPassword = temp;
424     HksFreeParamSet(&encryParamSet);
425     free(cipherBuf);
426     cipherBuf = nullptr;
427     return ret;
428 }
429 
WifiLoopDecrypt(const WifiEncryptionInfo & wifiEncryptionInfo,const EncryptedData & encryptedData,std::string & decryptedData)430 int32_t WifiLoopDecrypt(const WifiEncryptionInfo &wifiEncryptionInfo, const EncryptedData &encryptedData,
431     std::string &decryptedData)
432 {
433     if (encryptedData.encryptedPassword.length() == 0) {
434         WIFI_LOGI("WifiLoopDecrypt encryptedData is nullptr.");
435         return HKS_SUCCESS;
436     }
437 
438     struct HksParamSet *decryParamSet = nullptr;
439     int32_t ret = DecryptParamSet(&decryParamSet, wifiEncryptionInfo, encryptedData);
440     if (ret != HKS_SUCCESS) {
441         WIFI_LOGE("WifiLoopDecrypt DecryptParamSet failed: %{public}d.", ret);
442         return ret;
443     }
444 
445     uint8_t handle[sizeof(uint64_t)] = { 0 };
446     struct HksBlob handleDecrypt = { sizeof(uint64_t), handle };
447     struct HksBlob authId = wifiEncryptionInfo.keyAlias;
448     ret = HksInit(&authId, decryParamSet, &handleDecrypt, nullptr);
449     if (ret != HKS_SUCCESS) {
450         WIFI_LOGE("WifiLoopDecrypt HksInit failed: %{public}d.", ret);
451         return ret;
452     }
453 
454     uint32_t cipherLength = encryptedData.encryptedPassword.length();
455     uint8_t *cipherBuf = reinterpret_cast<uint8_t*>(const_cast<char*>(encryptedData.encryptedPassword.c_str()));
456     struct HksBlob inData = { cipherLength - AEAD_SIZE, cipherBuf };
457     uint8_t *plainBuf = (uint8_t *)malloc(cipherLength);
458     if (plainBuf == nullptr) {
459         WIFI_LOGE("WifiLoopDecrypt malloc failed.");
460         return HKS_FAILURE;
461     }
462     struct HksBlob outData = { cipherLength, plainBuf };
463     ret = HksUpdateAndFinish(&handleDecrypt, decryParamSet, &inData, &outData);
464     if (ret != HKS_SUCCESS) {
465         WIFI_LOGE("WifiLoopDecrypt HksUpdateAndFinish failed: %{public}d.", ret);
466         free(plainBuf);
467         plainBuf = nullptr;
468         return ret;
469     }
470     std::string temp(outData.data, outData.data + outData.size);
471     if (memset_s(outData.data, outData.size, 0, outData.size) != EOK) {
472         WIFI_LOGE("WifiLoopDecrypt memset_s return error!");
473         free(plainBuf);
474         plainBuf = nullptr;
475         return HKS_FAILURE;
476     }
477     decryptedData = temp;
478     std::fill(temp.begin(), temp.end(), 0);
479     HksFreeParamSet(&decryParamSet);
480     free(plainBuf);
481     plainBuf = nullptr;
482     return ret;
483 }
484 
InitParamSet(struct HksParamSet ** paramSet,const struct HksParam * params,uint32_t paramCount)485 static int32_t InitParamSet(struct HksParamSet **paramSet, const struct HksParam *params, uint32_t paramCount)
486 {
487     int32_t ret = HksInitParamSet(paramSet);
488     if (ret != HKS_SUCCESS) {
489         WIFI_LOGE("%{public}s HksInitParamSet failed %{public}d", __func__, ret);
490         return ret;
491     }
492     ret = HksAddParams(*paramSet, params, paramCount);
493     if (ret != HKS_SUCCESS) {
494         WIFI_LOGE("%{public}s HksAddParams failed %{public}d", __func__, ret);
495         HksFreeParamSet(paramSet);
496         return ret;
497     }
498     ret = HksBuildParamSet(paramSet);
499     if (ret != HKS_SUCCESS) {
500         WIFI_LOGE("%{public}s HksBuildParamSet failed %{public}d", __func__, ret);
501         HksFreeParamSet(paramSet);
502         return ret;
503     }
504     return ret;
505 }
506 
507 static const uint32_t HMAC_COMMON_SIZE = 1024;
CalculateHksHmac(const struct HksBlob * keyAlias,const struct HksParamSet * hmacParamSet,const struct HksBlob * inData,struct HksBlob * hashText)508 static int32_t CalculateHksHmac(const struct HksBlob *keyAlias, const struct HksParamSet *hmacParamSet,
509     const struct HksBlob *inData, struct HksBlob *hashText)
510 {
511     uint8_t handleE[sizeof(uint64_t)] = {0};
512     struct HksBlob handle = {sizeof(uint64_t), handleE};
513     int32_t ret = HksInit(keyAlias, hmacParamSet, &handle, nullptr);
514     if (ret != HKS_SUCCESS) {
515         WIFI_LOGE("%{public}s HksInit failed %{public}d", __func__, ret);
516         return ret;
517     }
518     ret = HksFinish(&handle, hmacParamSet, inData, hashText);
519     return ret;
520 }
521 
WifiGenerateMacRandomizationSecret(const std::string & keyName,const std::string & data,std::vector<uint8_t> & outPlant)522 int32_t WifiGenerateMacRandomizationSecret(const std::string &keyName,
523     const std::string &data, std::vector<uint8_t> &outPlant)
524 {
525     if (keyName.empty() || data.empty()) {
526         WIFI_LOGE("%{public}s failed keyName or data is empty", __func__);
527         return -1;
528     }
529     struct HksBlob keyAlias = {
530         .size = (uint32_t)keyName.length(),
531         .data = (uint8_t *)(&keyName[0])
532     };
533     struct HksParamSet *hmacParamSet = nullptr;
534     int32_t ret = InitParamSet(&hmacParamSet, g_genHmacParams, sizeof(g_genHmacParams) / sizeof(HksParam));
535     if (ret != HKS_SUCCESS) {
536         WIFI_LOGE("%{public}s InitParamSet:[%{public}s] failed:%{public}d", __func__, keyName.c_str(), ret);
537         return ret;
538     }
539 
540     ret = GetKeyByAlias(&keyAlias, hmacParamSet);
541     if (ret == HKS_ERROR_NOT_EXIST) {
542         WIFI_LOGE("%{public}s GetKeyByAlias:[%{public}s] failed:%{public}d", __func__, keyName.c_str(), ret);
543         return ret;
544     }
545 
546     struct HksBlob inData = {
547         .size = (uint32_t)data.length(),
548         .data = (uint8_t *)&data[0]
549     };
550     uint8_t cipher[HMAC_COMMON_SIZE] = {0};
551     struct HksBlob hashText = {
552         .size = HMAC_COMMON_SIZE,
553         .data = cipher
554     };
555     ret = CalculateHksHmac(&keyAlias, hmacParamSet, &inData, &hashText);
556     if (ret != HKS_SUCCESS) {
557         WIFI_LOGE("%{public}s HksHmacTest failed :%{public}d", __func__, ret);
558         return ret;
559     }
560 
561     outPlant.clear();
562     for (size_t i = 0; i < hashText.size; i++) {
563         outPlant.emplace_back(hashText.data[i]);
564     }
565     HksFreeParamSet(&hmacParamSet);
566     return 0;
567 }
568 
569 }  // namespace Wifi
570 }  // namespace OHOS
571 #endif