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