• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 "apn_encryption_util.h"
16 
17 #include <iterator>
18 #include <securec.h>
19 #include <sstream>
20 
21 #include "data_storage_log_wrapper.h"
22 #include "data_storage_errors.h"
23 
24 namespace OHOS {
25 namespace Telephony {
26 
27 constexpr uint32_t IV_SIZE = 16;
28 const struct HksParam g_genEncDecParams[] = {
29     {
30         .tag = HKS_TAG_ALGORITHM,
31         .uint32Param = HKS_ALG_AES
32     }, {
33         .tag = HKS_TAG_PURPOSE,
34         .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT
35     }, {
36         .tag = HKS_TAG_KEY_SIZE,
37         .uint32Param = HKS_AES_KEY_SIZE_256
38     }, {
39         .tag = HKS_TAG_PADDING,
40         .uint32Param = HKS_PADDING_PKCS7
41     }, {
42         .tag = HKS_TAG_BLOCK_MODE,
43         .uint32Param = HKS_MODE_CBC
44     }, {
45         .tag = HKS_TAG_AUTH_STORAGE_LEVEL,
46         .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE
47     }
48 };
49 
InitParamSet(struct HksParamSet ** paramSet,const struct HksParam * params,uint32_t paramCount)50 int InitParamSet(struct HksParamSet **paramSet, const struct HksParam *params, uint32_t paramCount)
51 {
52     int ret = HksInitParamSet(paramSet);
53     if (ret != HKS_SUCCESS) {
54         DATA_STORAGE_LOGE("HksInitParamSet failed, error code: %{public}d", ret);
55         return ret;
56     }
57     ret = HksAddParams(*paramSet, params, paramCount);
58     if (ret != HKS_SUCCESS) {
59         DATA_STORAGE_LOGE("HksAddParams failed, error code: %{public}d", ret);
60         return ret;
61     }
62     return HksBuildParamSet(paramSet);
63 }
64 
AesCbcPkcs7EncryptInner(struct HksBlob * keyAlias,struct HksBlob * inData,struct HksBlob * outData)65 int AesCbcPkcs7EncryptInner(struct HksBlob *keyAlias, struct HksBlob *inData, struct HksBlob *outData)
66 {
67     uint8_t iv[IV_SIZE] = { 0 };
68     struct HksBlob ivBlob = { IV_SIZE, iv };
69     int ret = HksGenerateRandom(nullptr, &ivBlob);
70     if (ret != HKS_SUCCESS) {
71         DATA_STORAGE_LOGE("HksGenerateRandom failed, error code: %{public}d", ret);
72         return ret;
73     }
74     struct HksParam encryptParams[] = {
75         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
76         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT },
77         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
78         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_PKCS7 },
79         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_CBC },
80         { .tag = HKS_TAG_IV, .blob = { .size = IV_SIZE, .data = iv }},
81         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE }};
82     struct HksParamSet *encryptParamSet = nullptr;
83     ret = InitParamSet(&encryptParamSet, encryptParams, sizeof(encryptParams) / sizeof(HksParam));
84     if (ret != HKS_SUCCESS) {
85         DATA_STORAGE_LOGE("init encrypt param set failed, error code: %{public}d", ret);
86         HksFreeParamSet(&encryptParamSet);
87         return ret;
88     }
89     uint8_t handleE[sizeof(uint64_t)] = {0};
90     struct HksBlob handleEncrypt = {sizeof(uint64_t), handleE};
91     ret = HksInit(keyAlias, encryptParamSet, &handleEncrypt, nullptr);
92     if (ret != HKS_SUCCESS) {
93         DATA_STORAGE_LOGE("hks init encrypt invoke failed, error code: %{public}d", ret);
94         HksFreeParamSet(&encryptParamSet);
95         return ret;
96     }
97     ret = HksFinish(&handleEncrypt, encryptParamSet, inData, outData);
98     HksFreeParamSet(&encryptParamSet);
99     if (ret != HKS_SUCCESS) {
100         DATA_STORAGE_LOGE("hks finish encrypt invoke failed, error code: %{public}d", ret);
101         return ret;
102     }
103     if (outData->size + IV_SIZE > AES_COMMON_SIZE) {
104         DATA_STORAGE_LOGE("length error!");
105         return -1;
106     }
107     if (memcpy_s(outData->data + outData->size, IV_SIZE, iv, IV_SIZE) != EOK) {
108         DATA_STORAGE_LOGE("copy iv failed!");
109         return -1;
110     }
111     outData->size += IV_SIZE;
112     return ret;
113 }
114 
AesCbcPkcs7Encrypt(const std::string & alias,struct HksBlob * inData,struct HksBlob * outData)115 int AesCbcPkcs7Encrypt(const std::string &alias, struct HksBlob *inData, struct HksBlob *outData)
116 {
117     if (inData == nullptr || outData == nullptr || outData->data == nullptr || outData->size < IV_SIZE) {
118         DATA_STORAGE_LOGE("encrypt input error");
119         return -1;
120     }
121     struct HksParamSet *genParamSet = nullptr;
122     int ret = InitParamSet(&genParamSet, g_genEncDecParams, sizeof(g_genEncDecParams) / sizeof(HksParam));
123     if (ret != HKS_SUCCESS) {
124         HksFreeParamSet(&genParamSet);
125         return ret;
126     }
127     struct HksBlob keyAlias = { alias.length(), (uint8_t *)alias.c_str() };
128     ret = HksKeyExist(&keyAlias, genParamSet);
129     if (ret != HKS_SUCCESS) {
130         ret = HksGenerateKey(&keyAlias, genParamSet, nullptr);
131         if (ret != HKS_SUCCESS) {
132             DATA_STORAGE_LOGE("generate key failed, error code: %{public}d", ret);
133             HksFreeParamSet(&genParamSet);
134             return ret;
135         }
136     }
137     HksFreeParamSet(&genParamSet);
138     return AesCbcPkcs7EncryptInner(&keyAlias, inData, outData);
139 }
140 
AesCbcPkcs7Decrypt(const std::string & alias,struct HksBlob * inData,struct HksBlob * outData)141 int AesCbcPkcs7Decrypt(const std::string &alias, struct HksBlob *inData, struct HksBlob *outData)
142 {
143     if (inData == nullptr || outData == nullptr || inData->data == nullptr || inData->size < IV_SIZE) {
144         DATA_STORAGE_LOGE("decrypt input error");
145         return -1;
146     }
147     struct HksBlob keyAlias = { alias.length(), (uint8_t *)alias.c_str() };
148     struct HksParamSet *genParamSet = nullptr;
149     struct HksParamSet *decryptParamSet = nullptr;
150     int32_t ret = InitParamSet(&genParamSet, g_genEncDecParams, sizeof(g_genEncDecParams) / sizeof(HksParam));
151     if (ret != HKS_SUCCESS) {
152         HksFreeParamSet(&genParamSet);
153         DATA_STORAGE_LOGE("init gen param set failed, error code: %{public}d", ret);
154         return ret;
155     }
156     ret = HksKeyExist(&keyAlias, genParamSet);
157     HksFreeParamSet(&genParamSet);
158     if (ret != HKS_SUCCESS) {
159         DATA_STORAGE_LOGE("hks key is not exist, error code: %{public}d", ret);
160         return ret;
161     }
162     struct HksParam decryptParams[] = {
163         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
164         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
165         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
166         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_PKCS7 },
167         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_CBC },
168         { .tag = HKS_TAG_IV, .blob = { .size = IV_SIZE, .data = inData->data + inData->size - IV_SIZE }},
169         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE }};
170     ret = InitParamSet(&decryptParamSet, decryptParams, sizeof(decryptParams) / sizeof(HksParam));
171     if (ret != HKS_SUCCESS) {
172         DATA_STORAGE_LOGE("init decrypt param set failed, error code: %{public}d", ret);
173         HksFreeParamSet(&decryptParamSet);
174         return ret;
175     }
176     uint8_t handleD[sizeof(uint64_t)] = {0};
177     struct HksBlob handleDecrypt = {sizeof(uint64_t), handleD};
178     ret = HksInit(&keyAlias, decryptParamSet, &handleDecrypt, nullptr);
179     if (ret != HKS_SUCCESS) {
180         HksFreeParamSet(&decryptParamSet);
181         DATA_STORAGE_LOGE("hks init decrypt invoke failed, error code: %{public}d", ret);
182         return ret;
183     }
184     struct HksBlob temp = { .size = inData->size - IV_SIZE, .data = inData->data };
185     ret = HksFinish(&handleDecrypt, decryptParamSet, &temp, outData);
186     HksFreeParamSet(&decryptParamSet);
187     if (ret != HKS_SUCCESS) {
188         DATA_STORAGE_LOGE("hks finish decrypt invoke failed, error code: %{public}d", ret);
189     }
190     return ret;
191 }
192 
EncryptData(std::string encryptData)193 std::vector<uint8_t> EncryptData(std::string encryptData)
194 {
195     std::vector<uint8_t> result;
196     result.clear();
197     if (encryptData.empty()) {
198         DATA_STORAGE_LOGI("encryptData is empty");
199         return result;
200     }
201     struct HksBlob inDataBlob = { encryptData.length(), (uint8_t *)encryptData.c_str() };
202     uint8_t outData[AES_COMMON_SIZE] = {0};
203     struct HksBlob outDataBlob = {AES_COMMON_SIZE, outData};
204     int32_t ret = AesCbcPkcs7Encrypt(APN_PWD_KEY_ALIAS.c_str(), &inDataBlob, &outDataBlob);
205     if (ret != 0) {
206         DATA_STORAGE_LOGE("EncryptDataerror ret=%{public}d", ret);
207         return result;
208     }
209     for (size_t i = 0; i < outDataBlob.size; i++) {
210         result.emplace_back(outDataBlob.data[i]);
211     }
212     return result;
213 }
214 
DecryptData(std::string decryptData)215 std::string DecryptData(std::string decryptData)
216 {
217     DATA_STORAGE_LOGI("DecryptData enter");
218     if (decryptData.empty()) {
219         DATA_STORAGE_LOGI("decryptData is empty");
220         return "";
221     }
222     struct HksBlob inDataBlob = { decryptData.length(), (uint8_t *)decryptData.c_str() };
223     uint8_t outData[AES_COMMON_SIZE] = {0};
224     struct HksBlob outDataBlob = {AES_COMMON_SIZE, outData};
225     int32_t ret = AesCbcPkcs7Decrypt(APN_PWD_KEY_ALIAS.c_str(), &inDataBlob, &outDataBlob);
226     if (ret != 0) {
227         DATA_STORAGE_LOGE("DecryptData error ret=%{public}d", ret);
228         return "";
229     }
230     std::string result(reinterpret_cast<const char*>(outDataBlob.data), outDataBlob.size);
231     return result;
232 }
233 
DecryptUintVecData(std::vector<uint8_t> decryptVecData)234 std::string DecryptUintVecData(std::vector<uint8_t> decryptVecData)
235 {
236     DATA_STORAGE_LOGI("DecryptUintVecData enter");
237     if (decryptVecData.size() == 0) {
238         DATA_STORAGE_LOGI("DecryptUintVecData is empty");
239         return "";
240     }
241     struct HksBlob inDataBlob = { decryptVecData.size(), &decryptVecData[0] };
242     uint8_t outData[AES_COMMON_SIZE] = {0};
243     struct HksBlob outDataBlob = {AES_COMMON_SIZE, outData};
244     int32_t ret = AesCbcPkcs7Decrypt(APN_PWD_KEY_ALIAS.c_str(), &inDataBlob, &outDataBlob);
245     if (ret != 0) {
246         DATA_STORAGE_LOGE("DecryptUintVecData error ret=%{public}d", ret);
247         return "";
248     }
249     std::string result(reinterpret_cast<const char*>(outDataBlob.data), outDataBlob.size);
250     return result;
251 }
252 
253 }  // namespace Telephony
254 }  // namespace OHOS