1 /*
2  * Copyright (c) 2022 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 #define LOG_TAG "SECURITYMANAGER"
16 #include "security_manager.h"
17 
18 #include <chrono>
19 #include <limits>
20 #include <random>
21 #include <unistd.h>
22 
23 #include "file_ex.h"
24 #include "hks_api.h"
25 #include "hks_param.h"
26 #include "log_print.h"
27 #include "securec.h"
28 #include "store_types.h"
29 #include "store_util.h"
30 #include "task_executor.h"
31 namespace OHOS::DistributedKv {
SecurityManager()32 SecurityManager::SecurityManager()
33 {
34     vecRootKeyAlias_ = std::vector<uint8_t>(ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS));
35     vecNonce_ = std::vector<uint8_t>(HKS_BLOB_TYPE_NONCE, HKS_BLOB_TYPE_NONCE + strlen(HKS_BLOB_TYPE_NONCE));
36     vecAad_ = std::vector<uint8_t>(HKS_BLOB_TYPE_AAD, HKS_BLOB_TYPE_AAD + strlen(HKS_BLOB_TYPE_AAD));
37 }
38 
~SecurityManager()39 SecurityManager::~SecurityManager()
40 {}
41 
GetInstance()42 SecurityManager &SecurityManager::GetInstance()
43 {
44     static SecurityManager instance;
45     return instance;
46 }
47 
Retry()48 bool SecurityManager::Retry()
49 {
50     auto status = CheckRootKey();
51     if (status == HKS_SUCCESS) {
52         hasRootKey_ = true;
53         ZLOGE("root key already exist.");
54         return true;
55     }
56 
57     if (status == HKS_ERROR_NOT_EXIST && GenerateRootKey() == HKS_SUCCESS) {
58         hasRootKey_ = true;
59         ZLOGE("GenerateRootKey success.");
60         return true;
61     }
62 
63     constexpr int32_t interval = 100;
64     TaskExecutor::GetInstance().Schedule(std::chrono::milliseconds(interval), [this] {
65         Retry();
66     });
67     return false;
68 }
69 
GetDBPassword(const std::string & name,const std::string & path,bool needCreate)70 SecurityManager::DBPassword SecurityManager::GetDBPassword(const std::string &name,
71     const std::string &path, bool needCreate)
72 {
73     DBPassword dbPassword;
74     auto secKey = LoadKeyFromFile(name, path, dbPassword.isKeyOutdated);
75     std::vector<uint8_t> key{};
76 
77     if (secKey.empty() && needCreate) {
78         key = Random(KEY_SIZE);
79         if (!SaveKeyToFile(name, path, key)) {
80             secKey.assign(secKey.size(), 0);
81             key.assign(key.size(), 0);
82             return dbPassword;
83         }
84     }
85 
86     if ((!secKey.empty() && Decrypt(secKey, key)) || !key.empty()) {
87         dbPassword.SetValue(key.data(), key.size());
88     }
89 
90     secKey.assign(secKey.size(), 0);
91     key.assign(key.size(), 0);
92     return dbPassword;
93 }
94 
SaveDBPassword(const std::string & name,const std::string & path,const DistributedDB::CipherPassword & key)95 bool SecurityManager::SaveDBPassword(const std::string &name, const std::string &path,
96     const DistributedDB::CipherPassword &key)
97 {
98     std::vector<uint8_t> pwd(key.GetData(), key.GetData() + key.GetSize());
99     auto result = SaveKeyToFile(name, path, pwd);
100     pwd.assign(pwd.size(), 0);
101     return result;
102 }
103 
DelDBPassword(const std::string & name,const std::string & path)104 void SecurityManager::DelDBPassword(const std::string &name, const std::string &path)
105 {
106     auto keyPath = path + "/key/" + name + ".key";
107     StoreUtil::Remove(keyPath);
108 }
109 
Random(int32_t len)110 std::vector<uint8_t> SecurityManager::Random(int32_t len)
111 {
112     std::random_device randomDevice;
113     std::uniform_int_distribution<int> distribution(0, std::numeric_limits<uint8_t>::max());
114     std::vector<uint8_t> key(len);
115     for (int32_t i = 0; i < len; i++) {
116         key[i] = static_cast<uint8_t>(distribution(randomDevice));
117     }
118     return key;
119 }
120 
LoadKeyFromFile(const std::string & name,const std::string & path,bool & isOutdated)121 std::vector<uint8_t> SecurityManager::LoadKeyFromFile(const std::string &name, const std::string &path,
122     bool &isOutdated)
123 {
124     auto keyPath = path + "/key/" + name + ".key";
125     if (!FileExists(keyPath)) {
126         return {};
127     }
128     StoreUtil::RemoveRWXForOthers(path + "/key");
129 
130     std::vector<char> content;
131     auto loaded = LoadBufferFromFile(keyPath, content);
132     if (!loaded) {
133         return {};
134     }
135 
136     if (content.size() < (sizeof(time_t) / sizeof(uint8_t)) + KEY_SIZE + 1) {
137         return {};
138     }
139 
140     size_t offset = 0;
141     if (content[offset] != char((sizeof(time_t) / sizeof(uint8_t)) + KEY_SIZE)) {
142         return {};
143     }
144 
145     offset++;
146     std::vector<uint8_t> date;
147     date.assign(content.begin() + offset, content.begin() + (sizeof(time_t) / sizeof(uint8_t)) + offset);
148     isOutdated = IsKeyOutdated(date);
149     offset += (sizeof(time_t) / sizeof(uint8_t));
150     std::vector<uint8_t> key{ content.begin() + offset, content.end() };
151     content.assign(content.size(), 0);
152     return key;
153 }
154 
SaveKeyToFile(const std::string & name,const std::string & path,std::vector<uint8_t> & key)155 bool SecurityManager::SaveKeyToFile(const std::string &name, const std::string &path, std::vector<uint8_t> &key)
156 {
157     if (!hasRootKey_ && !Retry()) {
158         ZLOGE("failed! no root key and generation failed");
159         return false;
160     }
161     auto secretKey = Encrypt(key);
162     auto keyPath = path + "/key";
163     StoreUtil::InitPath(keyPath);
164     std::vector<char> content;
165     auto time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::system_clock::now());
166     std::vector<uint8_t> date(reinterpret_cast<uint8_t *>(&time), reinterpret_cast<uint8_t *>(&time) + sizeof(time));
167     content.push_back(char((sizeof(time_t) / sizeof(uint8_t)) + KEY_SIZE));
168     content.insert(content.end(), date.begin(), date.end());
169     content.insert(content.end(), secretKey.begin(), secretKey.end());
170     auto keyFullPath = keyPath + "/" + name + ".key";
171     auto ret = SaveBufferToFile(keyFullPath, content);
172     if (access(keyFullPath.c_str(), F_OK) == 0) {
173         StoreUtil::RemoveRWXForOthers(keyFullPath);
174     }
175     content.assign(content.size(), 0);
176     if (!ret) {
177         ZLOGE("client SaveSecretKey failed!");
178         return false;
179     }
180     return ret;
181 }
182 
Encrypt(const std::vector<uint8_t> & key)183 std::vector<uint8_t> SecurityManager::Encrypt(const std::vector<uint8_t> &key)
184 {
185     struct HksBlob blobAad = { uint32_t(vecAad_.size()), vecAad_.data() };
186     struct HksBlob blobNonce = { uint32_t(vecNonce_.size()), vecNonce_.data() };
187     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
188     struct HksBlob plainKey = { uint32_t(key.size()), const_cast<uint8_t *>(key.data()) };
189     struct HksParamSet *params = nullptr;
190     int32_t ret = HksInitParamSet(&params);
191     if (ret != HKS_SUCCESS) {
192         ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
193         return {};
194     }
195     struct HksParam hksParam[] = {
196         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
197         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT },
198         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
199         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
200         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
201         { .tag = HKS_TAG_NONCE, .blob = blobNonce },
202         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad },
203         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
204     };
205     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
206     if (ret != HKS_SUCCESS) {
207         ZLOGE("HksAddParams failed, status: %{public}d", ret);
208         HksFreeParamSet(&params);
209         return {};
210     }
211 
212     ret = HksBuildParamSet(&params);
213     if (ret != HKS_SUCCESS) {
214         ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
215         HksFreeParamSet(&params);
216         return {};
217     }
218 
219     uint8_t cipherBuf[256] = { 0 };
220     struct HksBlob cipherText = { sizeof(cipherBuf), cipherBuf };
221     ret = HksEncrypt(&rootKeyName, params, &plainKey, &cipherText);
222     (void)HksFreeParamSet(&params);
223     if (ret != HKS_SUCCESS) {
224         ZLOGE("HksEncrypt failed, status: %{public}d", ret);
225         return {};
226     }
227     std::vector<uint8_t> encryptedKey(cipherText.data, cipherText.data + cipherText.size);
228     (void)memset_s(cipherBuf, sizeof(cipherBuf), 0, sizeof(cipherBuf));
229     return encryptedKey;
230 }
231 
Decrypt(std::vector<uint8_t> & source,std::vector<uint8_t> & key)232 bool SecurityManager::Decrypt(std::vector<uint8_t> &source, std::vector<uint8_t> &key)
233 {
234     struct HksBlob blobAad = { uint32_t(vecAad_.size()), &(vecAad_[0]) };
235     struct HksBlob blobNonce = { uint32_t(vecNonce_.size()), &(vecNonce_[0]) };
236     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) };
237     struct HksBlob encryptedKeyBlob = { uint32_t(source.size()), source.data() };
238 
239     struct HksParamSet *params = nullptr;
240     int32_t ret = HksInitParamSet(&params);
241     if (ret != HKS_SUCCESS) {
242         ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
243         return false;
244     }
245     struct HksParam hksParam[] = {
246         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
247         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
248         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
249         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
250         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
251         { .tag = HKS_TAG_NONCE, .blob = blobNonce },
252         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad },
253         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
254     };
255     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
256     if (ret != HKS_SUCCESS) {
257         ZLOGE("HksAddParams failed, status: %{public}d", ret);
258         HksFreeParamSet(&params);
259         return false;
260     }
261 
262     ret = HksBuildParamSet(&params);
263     if (ret != HKS_SUCCESS) {
264         ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
265         HksFreeParamSet(&params);
266         return false;
267     }
268 
269     uint8_t plainBuf[256] = { 0 };
270     struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf };
271     ret = HksDecrypt(&rootKeyName, params, &encryptedKeyBlob, &plainKeyBlob);
272     (void)HksFreeParamSet(&params);
273     if (ret != HKS_SUCCESS) {
274         ZLOGE("HksDecrypt, status: %{public}d", ret);
275         return false;
276     }
277 
278     key.assign(plainKeyBlob.data, plainKeyBlob.data + plainKeyBlob.size);
279     (void)memset_s(plainBuf, sizeof(plainBuf), 0, sizeof(plainBuf));
280     return true;
281 }
282 
GenerateRootKey()283 int32_t SecurityManager::GenerateRootKey()
284 {
285     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
286     struct HksParamSet *params = nullptr;
287     int32_t ret = HksInitParamSet(&params);
288     if (ret != HKS_SUCCESS) {
289         ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
290         return ret;
291     }
292 
293     struct HksParam hksParam[] = {
294         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
295         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
296         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
297         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
298         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
299         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
300         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
301     };
302 
303     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
304     if (ret != HKS_SUCCESS) {
305         ZLOGE("HksAddParams failed, status: %{public}d", ret);
306         HksFreeParamSet(&params);
307         return ret;
308     }
309 
310     ret = HksBuildParamSet(&params);
311     if (ret != HKS_SUCCESS) {
312         ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
313         HksFreeParamSet(&params);
314         return ret;
315     }
316 
317     ret = HksGenerateKey(&rootKeyName, params, nullptr);
318     HksFreeParamSet(&params);
319     ZLOGI("HksGenerateKey status: %{public}d", ret);
320     return ret;
321 }
322 
CheckRootKey()323 int32_t SecurityManager::CheckRootKey()
324 {
325     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
326     struct HksParamSet *params = nullptr;
327     int32_t ret = HksInitParamSet(&params);
328     if (ret != HKS_SUCCESS) {
329         ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
330         return ret;
331     }
332 
333     struct HksParam hksParam[] = {
334         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
335         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
336         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
337         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
338         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
339         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
340         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
341     };
342 
343     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
344     if (ret != HKS_SUCCESS) {
345         ZLOGE("HksAddParams failed, status: %{public}d", ret);
346         HksFreeParamSet(&params);
347         return ret;
348     }
349 
350     ret = HksBuildParamSet(&params);
351     if (ret != HKS_SUCCESS) {
352         ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
353         HksFreeParamSet(&params);
354         return ret;
355     }
356 
357     ret = HksKeyExist(&rootKeyName, params);
358     HksFreeParamSet(&params);
359     ZLOGI("HksKeyExist status: %{public}d", ret);
360     return ret;
361 }
362 
IsKeyOutdated(const std::vector<uint8_t> & date)363 bool SecurityManager::IsKeyOutdated(const std::vector<uint8_t> &date)
364 {
365     time_t time = *reinterpret_cast<time_t *>(const_cast<uint8_t *>(&date[0]));
366     auto createTime = std::chrono::system_clock::from_time_t(time);
367     return ((createTime + std::chrono::hours(HOURS_PER_YEAR)) < std::chrono::system_clock::now());
368 }
369 
370 } // namespace OHOS::DistributedKv
371