• 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 (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