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 (memcpy_s(outData->data + outData->size, IV_SIZE, iv, IV_SIZE) != EOK) {
104 DATA_STORAGE_LOGE("copy iv failed!");
105 return -1;
106 }
107 outData->size += IV_SIZE;
108 return ret;
109 }
110
AesCbcPkcs7Encrypt(const std::string & alias,struct HksBlob * inData,struct HksBlob * outData)111 int AesCbcPkcs7Encrypt(const std::string &alias, struct HksBlob *inData, struct HksBlob *outData)
112 {
113 if (inData == nullptr || outData == nullptr || outData->data == nullptr || outData->size < IV_SIZE) {
114 DATA_STORAGE_LOGE("encrypt input error");
115 return -1;
116 }
117 struct HksParamSet *genParamSet = nullptr;
118 int ret = InitParamSet(&genParamSet, g_genEncDecParams, sizeof(g_genEncDecParams) / sizeof(HksParam));
119 if (ret != HKS_SUCCESS) {
120 HksFreeParamSet(&genParamSet);
121 return ret;
122 }
123 struct HksBlob keyAlias = { alias.length(), (uint8_t *)alias.c_str() };
124 ret = HksKeyExist(&keyAlias, genParamSet);
125 if (ret != HKS_SUCCESS) {
126 ret = HksGenerateKey(&keyAlias, genParamSet, nullptr);
127 if (ret != HKS_SUCCESS) {
128 DATA_STORAGE_LOGE("generate key failed, error code: %{public}d", ret);
129 HksFreeParamSet(&genParamSet);
130 return ret;
131 }
132 }
133 HksFreeParamSet(&genParamSet);
134 return AesCbcPkcs7EncryptInner(&keyAlias, inData, outData);
135 }
136
AesCbcPkcs7Decrypt(const std::string & alias,struct HksBlob * inData,struct HksBlob * outData)137 int AesCbcPkcs7Decrypt(const std::string &alias, struct HksBlob *inData, struct HksBlob *outData)
138 {
139 if (inData == nullptr || outData == nullptr || inData->data == nullptr || inData->size < IV_SIZE) {
140 DATA_STORAGE_LOGE("decrypt input error");
141 return -1;
142 }
143 struct HksBlob keyAlias = { alias.length(), (uint8_t *)alias.c_str() };
144 struct HksParamSet *genParamSet = nullptr;
145 struct HksParamSet *decryptParamSet = nullptr;
146 int32_t ret = InitParamSet(&genParamSet, g_genEncDecParams, sizeof(g_genEncDecParams) / sizeof(HksParam));
147 if (ret != HKS_SUCCESS) {
148 HksFreeParamSet(&genParamSet);
149 DATA_STORAGE_LOGE("init gen param set failed, error code: %{public}d", ret);
150 return ret;
151 }
152 ret = HksKeyExist(&keyAlias, genParamSet);
153 HksFreeParamSet(&genParamSet);
154 if (ret != HKS_SUCCESS) {
155 DATA_STORAGE_LOGE("hks key is not exist, error code: %{public}d", ret);
156 return ret;
157 }
158 struct HksParam decryptParams[] = {
159 { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
160 { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
161 { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
162 { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_PKCS7 },
163 { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_CBC },
164 { .tag = HKS_TAG_IV, .blob = { .size = IV_SIZE, .data = inData->data + inData->size - IV_SIZE }},
165 { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE }};
166 ret = InitParamSet(&decryptParamSet, decryptParams, sizeof(decryptParams) / sizeof(HksParam));
167 if (ret != HKS_SUCCESS) {
168 DATA_STORAGE_LOGE("init decrypt param set failed, error code: %{public}d", ret);
169 HksFreeParamSet(&decryptParamSet);
170 return ret;
171 }
172 uint8_t handleD[sizeof(uint64_t)] = {0};
173 struct HksBlob handleDecrypt = {sizeof(uint64_t), handleD};
174 ret = HksInit(&keyAlias, decryptParamSet, &handleDecrypt, nullptr);
175 if (ret != HKS_SUCCESS) {
176 HksFreeParamSet(&decryptParamSet);
177 DATA_STORAGE_LOGE("hks init decrypt invoke failed, error code: %{public}d", ret);
178 return ret;
179 }
180 struct HksBlob temp = { .size = inData->size - IV_SIZE, .data = inData->data };
181 ret = HksFinish(&handleDecrypt, decryptParamSet, &temp, outData);
182 HksFreeParamSet(&decryptParamSet);
183 if (ret != HKS_SUCCESS) {
184 DATA_STORAGE_LOGE("hks finish decrypt invoke failed, error code: %{public}d", ret);
185 }
186 return ret;
187 }
188
EncryptData(std::string encryptData)189 std::string EncryptData(std::string encryptData)
190 {
191 if (encryptData.empty()) {
192 DATA_STORAGE_LOGI("encryptData is empty");
193 return "";
194 }
195 struct HksBlob inDataBlob = { encryptData.length(), (uint8_t *)encryptData.c_str() };
196 uint8_t outData[AES_COMMON_SIZE] = {0};
197 struct HksBlob outDataBlob = {AES_COMMON_SIZE, outData};
198 int32_t ret = AesCbcPkcs7Encrypt(APN_PWD_KEY_ALIAS.c_str(), &inDataBlob, &outDataBlob);
199 if (ret != 0) {
200 DATA_STORAGE_LOGE("EncryptDataerror ret=%{public}d", ret);
201 return "";
202 }
203 std::string result(reinterpret_cast<const char*>(outDataBlob.data), outDataBlob.size);
204 return result;
205 }
206
DecryptData(std::string decryptData)207 std::string DecryptData(std::string decryptData)
208 {
209 if (decryptData.empty()) {
210 DATA_STORAGE_LOGI("decryptData is empty");
211 return "";
212 }
213 struct HksBlob inDataBlob = { decryptData.length(), (uint8_t *)decryptData.c_str() };
214 uint8_t outData[AES_COMMON_SIZE] = {0};
215 struct HksBlob outDataBlob = {AES_COMMON_SIZE, outData};
216 int32_t ret = AesCbcPkcs7Decrypt(APN_PWD_KEY_ALIAS.c_str(), &inDataBlob, &outDataBlob);
217 if (ret != 0) {
218 DATA_STORAGE_LOGE("DecryptData error ret=%{public}d", ret);
219 return "";
220 }
221 std::string result(reinterpret_cast<const char*>(outDataBlob.data), outDataBlob.size);
222 return result;
223 }
224 } // namespace Telephony
225 } // namespace OHOS