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