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