• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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