1 /*
2 * Copyright (c) 2023 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
16 #include "keystore_adapter_impl.h"
17
18 #include <algorithm>
19 #include <climits>
20 #include <fcntl.h>
21 #include <string>
22 #include <sys/ioctl.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26
27 #include "asset_api.h"
28 #include "nweb_log.h"
29
30 namespace {
31 const uint32_t AES_COMMON_SIZE = 1024;
32 static const uint32_t IV_SIZE = 16;
33 static const uint8_t IV[IV_SIZE] = { 0 };
34 }
35
36 namespace OHOS::NWeb {
37 // static
GetInstance()38 KeystoreAdapterImpl& KeystoreAdapterImpl::GetInstance()
39 {
40 static KeystoreAdapterImpl instance;
41 return instance;
42 }
43
InitParamSet(struct HksParamSet ** paramSet,const struct HksParam * params,uint32_t paramCount)44 int32_t KeystoreAdapterImpl::InitParamSet(
45 struct HksParamSet **paramSet,
46 const struct HksParam *params,
47 uint32_t paramCount)
48 {
49 int32_t ret = HksInitParamSet(paramSet);
50 if (ret != HKS_SUCCESS) {
51 return ret;
52 }
53
54 ret = HksAddParams(*paramSet, params, paramCount);
55 if (ret != HKS_SUCCESS) {
56 HksFreeParamSet(paramSet);
57 return ret;
58 }
59
60 ret = HksBuildParamSet(paramSet);
61 if (ret != HKS_SUCCESS) {
62 HksFreeParamSet(paramSet);
63 return ret;
64 }
65
66 return ret;
67 }
68
69 struct HksParam g_genEncDecParams[] = {
70 {
71 .tag = HKS_TAG_ALGORITHM,
72 .uint32Param = HKS_ALG_AES
73 }, {
74 .tag = HKS_TAG_PURPOSE,
75 .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT
76 }, {
77 .tag = HKS_TAG_KEY_SIZE,
78 .uint32Param = HKS_AES_KEY_SIZE_256
79 }, {
80 .tag = HKS_TAG_PADDING,
81 .uint32Param = HKS_PADDING_NONE
82 }, {
83 .tag = HKS_TAG_BLOCK_MODE,
84 .uint32Param = HKS_MODE_CBC
85 }
86 };
87
88 struct HksParam g_encryptParams[] = {
89 {
90 .tag = HKS_TAG_ALGORITHM,
91 .uint32Param = HKS_ALG_AES
92 }, {
93 .tag = HKS_TAG_PURPOSE,
94 .uint32Param = HKS_KEY_PURPOSE_ENCRYPT
95 }, {
96 .tag = HKS_TAG_KEY_SIZE,
97 .uint32Param = HKS_AES_KEY_SIZE_256
98 }, {
99 .tag = HKS_TAG_PADDING,
100 .uint32Param = HKS_PADDING_NONE
101 }, {
102 .tag = HKS_TAG_BLOCK_MODE,
103 .uint32Param = HKS_MODE_CBC
104 }, {
105 .tag = HKS_TAG_IV,
106 .blob = {
107 .size = IV_SIZE,
108 .data = (uint8_t *)IV
109 }
110 }
111 };
112
113 struct HksParam g_decryptParams[] = {
114 {
115 .tag = HKS_TAG_ALGORITHM,
116 .uint32Param = HKS_ALG_AES
117 }, {
118 .tag = HKS_TAG_PURPOSE,
119 .uint32Param = HKS_KEY_PURPOSE_DECRYPT
120 }, {
121 .tag = HKS_TAG_KEY_SIZE,
122 .uint32Param = HKS_AES_KEY_SIZE_256
123 }, {
124 .tag = HKS_TAG_PADDING,
125 .uint32Param = HKS_PADDING_NONE
126 }, {
127 .tag = HKS_TAG_BLOCK_MODE,
128 .uint32Param = HKS_MODE_CBC
129 }, {
130 .tag = HKS_TAG_IV,
131 .blob = {
132 .size = IV_SIZE,
133 .data = (uint8_t *)IV
134 }
135 }
136 };
137
EncryptKey(const std::string alias,const std::string plainData)138 std::string KeystoreAdapterImpl::EncryptKey(const std::string alias, const std::string plainData)
139 {
140 struct HksBlob keyAlias = { alias.length(), (uint8_t *)alias.c_str() };
141 struct HksBlob inData = { plainData.length(), (uint8_t *)plainData.c_str() };
142 struct HksParamSet *genParamSet = nullptr;
143 struct HksParamSet *encryptParamSet = nullptr;
144 uint8_t cipher[AES_COMMON_SIZE] = {0};
145 struct HksBlob cipherText = {AES_COMMON_SIZE, cipher};
146 int32_t ohResult = InitParamSet(&genParamSet, g_genEncDecParams, sizeof(g_genEncDecParams) / sizeof(HksParam));
147 if (ohResult != HKS_SUCCESS) {
148 WVLOG_E("init gen param set failed, error code: %d", ohResult);
149 HksFreeParamSet(&genParamSet);
150 return std::string();
151 }
152 ohResult = HksKeyExist(&keyAlias, genParamSet);
153 if (ohResult != HKS_SUCCESS) {
154 ohResult = HksGenerateKey(&keyAlias, genParamSet, nullptr);
155 if (ohResult != HKS_SUCCESS) {
156 WVLOG_E("generate key failed, error code: %d", ohResult);
157 HksFreeParamSet(&genParamSet);
158 return std::string();
159 }
160 }
161 ohResult = InitParamSet(&encryptParamSet, g_encryptParams, sizeof(g_encryptParams) / sizeof(HksParam));
162 if (ohResult != HKS_SUCCESS) {
163 WVLOG_E("init encrypt param set failed, error code: %d", ohResult);
164 HksFreeParamSet(&genParamSet);
165 HksFreeParamSet(&encryptParamSet);
166 return std::string();
167 }
168 uint8_t handleE[sizeof(uint64_t)] = {0};
169 struct HksBlob handleEncrypt = {sizeof(uint64_t), handleE};
170 ohResult = HksInit(&keyAlias, encryptParamSet, &handleEncrypt, nullptr);
171 if (ohResult != HKS_SUCCESS) {
172 WVLOG_E("hks init invoke failed, error code: %d", ohResult);
173 HksFreeParamSet(&genParamSet);
174 HksFreeParamSet(&encryptParamSet);
175 return std::string();
176 }
177 ohResult = HksFinish(&handleEncrypt, encryptParamSet, &inData, &cipherText);
178 if (ohResult != HKS_SUCCESS) {
179 WVLOG_E("hks finish invoke failed, error code: %d", ohResult);
180 HksFreeParamSet(&genParamSet);
181 HksFreeParamSet(&encryptParamSet);
182 return std::string();
183 }
184
185 HksFreeParamSet(&genParamSet);
186 HksFreeParamSet(&encryptParamSet);
187 return std::string(reinterpret_cast<char*>(cipherText.data), cipherText.size);
188 }
189
DecryptKey(const std::string alias,const std::string encryptedData)190 std::string KeystoreAdapterImpl::DecryptKey(const std::string alias, const std::string encryptedData)
191 {
192 struct HksBlob keyAlias = { alias.length(), (uint8_t *)alias.c_str() };
193 struct HksBlob cipherText = { encryptedData.length(), (uint8_t *)encryptedData.c_str() };
194 struct HksParamSet *genParamSet = nullptr;
195 struct HksParamSet *decryptParamSet = nullptr;
196 uint8_t plain[AES_COMMON_SIZE] = {0};
197 struct HksBlob plainText = {AES_COMMON_SIZE, plain};
198 int32_t ohResult = InitParamSet(&genParamSet, g_genEncDecParams, sizeof(g_genEncDecParams) / sizeof(HksParam));
199 if (ohResult != HKS_SUCCESS) {
200 HksFreeParamSet(&genParamSet);
201 WVLOG_E("init gen param set failed, error code: %d", ohResult);
202 return std::string();
203 }
204 ohResult = InitParamSet(&decryptParamSet, g_decryptParams, sizeof(g_decryptParams) / sizeof(HksParam));
205 if (ohResult != HKS_SUCCESS) {
206 WVLOG_E("init decrypt param set failed, error code: %d", ohResult);
207 HksFreeParamSet(&genParamSet);
208 HksFreeParamSet(&decryptParamSet);
209 return std::string();
210 }
211 ohResult = HksKeyExist(&keyAlias, genParamSet);
212 if (ohResult != HKS_SUCCESS) {
213 HksFreeParamSet(&genParamSet);
214 HksFreeParamSet(&decryptParamSet);
215 WVLOG_E("hks key is not exist, error code: %d", ohResult);
216 return std::string();
217 }
218 uint8_t handleD[sizeof(uint64_t)] = {0};
219 struct HksBlob handleDecrypt = {sizeof(uint64_t), handleD};
220 ohResult = HksInit(&keyAlias, decryptParamSet, &handleDecrypt, nullptr);
221 if (ohResult != HKS_SUCCESS) {
222 HksFreeParamSet(&genParamSet);
223 HksFreeParamSet(&decryptParamSet);
224 WVLOG_E("hks init invoke failed, error code: %d", ohResult);
225 return std::string();
226 }
227 ohResult = HksFinish(&handleDecrypt, decryptParamSet, &cipherText, &plainText);
228 if (ohResult != HKS_SUCCESS) {
229 HksFreeParamSet(&genParamSet);
230 HksFreeParamSet(&decryptParamSet);
231 WVLOG_E("hks finish invoke failed, error code: %d", ohResult);
232 return std::string();
233 }
234 HksFreeParamSet(&genParamSet);
235 HksFreeParamSet(&decryptParamSet);
236 return std::string(reinterpret_cast<char*>(plainText.data), plainText.size);
237 }
238
AssetQuery(const std::string assetHandle)239 std::string KeystoreAdapterImpl::AssetQuery(const std::string assetHandle)
240 {
241 Asset_Blob alias = { (uint32_t)(assetHandle.length()), (uint8_t*)assetHandle.c_str() };
242 Asset_Attr attr[] = {
243 { .tag = ASSET_TAG_ALIAS, .value.blob = alias },
244 { .tag = ASSET_TAG_RETURN_TYPE, .value.u32 = ASSET_RETURN_ALL },
245 };
246
247 Asset_ResultSet resultSet = { 0 };
248 int32_t ret = OH_Asset_Query(attr, sizeof(attr) / sizeof(attr[0]), &resultSet);
249 if (ret == ASSET_SUCCESS) {
250 Asset_Attr* secret = OH_Asset_ParseAttr(resultSet.results, ASSET_TAG_SECRET);
251 if (secret) {
252 Asset_Blob valueBlob = secret->value.blob;
253 std::string localKey(reinterpret_cast<char*>(valueBlob.data), valueBlob.size);
254 OH_Asset_FreeResultSet(&resultSet);
255 WVLOG_I("get key from asset success.");
256 return localKey;
257 }
258 }
259 OH_Asset_FreeResultSet(&resultSet);
260 WVLOG_E("hks finish invoke, query ret: %d", ret);
261 return std::string();
262 }
263
264 } // namespace OHOS::NWeb
265