• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #include "security_manager.h"
18 
19 #include <chrono>
20 #include <fcntl.h>
21 #include <limits>
22 #include <sys/file.h>
23 #include <unistd.h>
24 
25 #include "file_ex.h"
26 #include "hks_api.h"
27 #include "hks_param.h"
28 #include "log_print.h"
29 #include "securec.h"
30 #include "store_types.h"
31 #include "store_util.h"
32 #include "task_executor.h"
33 
34 namespace OHOS::DistributedKv {
35 static constexpr int HOURS_PER_YEAR = (24 * 365);
36 static constexpr const char *ROOT_KEY_ALIAS = "distributeddb_client_root_key";
37 static constexpr const char *HKS_BLOB_TYPE_NONCE = "Z5s0Bo571KoqwIi6";
38 static constexpr const char *HKS_BLOB_TYPE_AAD = "distributeddata_client";
39 static constexpr const char *SUFFIX_KEY = ".key";
40 static constexpr const char *SUFFIX_KEY_V1 = ".key_v1";
41 static constexpr const char *SUFFIX_KEY_LOCK = ".key_lock";
42 static constexpr const char *KEY_DIR = "/key";
43 static constexpr const char *SLASH = "/";
44 
SecurityManager()45 SecurityManager::SecurityManager()
46 {
47     vecRootKeyAlias_ = std::vector<uint8_t>(ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS));
48     vecNonce_ = std::vector<uint8_t>(HKS_BLOB_TYPE_NONCE, HKS_BLOB_TYPE_NONCE + strlen(HKS_BLOB_TYPE_NONCE));
49     vecAad_ = std::vector<uint8_t>(HKS_BLOB_TYPE_AAD, HKS_BLOB_TYPE_AAD + strlen(HKS_BLOB_TYPE_AAD));
50 }
51 
~SecurityManager()52 SecurityManager::~SecurityManager()
53 {}
54 
GetInstance()55 SecurityManager &SecurityManager::GetInstance()
56 {
57     static SecurityManager instance;
58     return instance;
59 }
60 
Retry()61 bool SecurityManager::Retry()
62 {
63     auto status = CheckRootKey();
64     if (status == HKS_SUCCESS) {
65         hasRootKey_ = true;
66         ZLOGE("Root key already exist.");
67         return true;
68     }
69 
70     if (status == HKS_ERROR_NOT_EXIST && GenerateRootKey() == HKS_SUCCESS) {
71         hasRootKey_ = true;
72         ZLOGE("GenerateRootKey success.");
73         return true;
74     }
75 
76     constexpr int32_t interval = 100;
77     TaskExecutor::GetInstance().Schedule(std::chrono::milliseconds(interval), [this] {
78         Retry();
79     });
80     return false;
81 }
82 
Random(int32_t length)83 std::vector<uint8_t> SecurityManager::Random(int32_t length)
84 {
85     std::vector<uint8_t> value(length, 0);
86     struct HksBlob blobValue = { .size = length, .data = &(value[0]) };
87     auto ret = HksGenerateRandom(nullptr, &blobValue);
88     if (ret != HKS_SUCCESS) {
89         ZLOGE("HksGenerateRandom failed, status: %{public}d", ret);
90         return {};
91     }
92     return value;
93 }
94 
LoadContent(SecurityManager::SecurityContent & content,const std::string & path)95 bool SecurityManager::LoadContent(SecurityManager::SecurityContent &content, const std::string &path)
96 {
97     if (!FileExists(path)) {
98         return false;
99     }
100     LoadKeyFromFile(path, content);
101     if (content.encryptValue.empty() || !Decrypt(content)) {
102         return false;
103     }
104     return true;
105 }
106 
GetDBPassword(const std::string & name,const std::string & path,bool needCreate)107 SecurityManager::DBPassword SecurityManager::GetDBPassword(const std::string &name, const std::string &path,
108     bool needCreate)
109 {
110     KeyFiles keyFiles(name, path);
111     KeyFilesAutoLock fileLock(keyFiles);
112     DBPassword dbPassword;
113     auto oldKeyPath = path + KEY_DIR + SLASH + name + SUFFIX_KEY;
114     auto newKeyPath = path + KEY_DIR + SLASH + name + SUFFIX_KEY_V1;
115     SecurityContent content;
116     auto result = LoadContent(content, newKeyPath);
117     if (!result) {
118         content.isNewStyle = false;
119         result = LoadContent(content, oldKeyPath);
120     }
121     content.encryptValue.assign(content.encryptValue.size(), 0);
122     std::vector<uint8_t> key;
123     if (result) {
124         size_t offset = 0;
125         if (content.isNewStyle && content.fullKeyValue.size() > (sizeof(time_t) / sizeof(uint8_t)) + 1) {
126             content.version = content.fullKeyValue[offset++];
127             content.time.assign(content.fullKeyValue.begin() + offset,
128                 content.fullKeyValue.begin() + offset + (sizeof(time_t) / sizeof(uint8_t)));
129         }
130         offset = content.isNewStyle ? (sizeof(time_t) / sizeof(uint8_t)) + 1 : 0;
131         if (content.fullKeyValue.size() > offset) {
132             key.assign(content.fullKeyValue.begin() + offset, content.fullKeyValue.end());
133         }
134         // old security key file and update key file
135         if (!content.isNewStyle && !key.empty() && SaveKeyToFile(name, path, key)) {
136             StoreUtil::Remove(oldKeyPath);
137         }
138         content.fullKeyValue.assign(content.fullKeyValue.size(), 0);
139     }
140     if (!result && needCreate) {
141         key = Random(SecurityContent::KEY_SIZE);
142         if (key.empty() || !SaveKeyToFile(name, path, key)) {
143             key.assign(key.size(), 0);
144             return dbPassword;
145         }
146         StoreUtil::Remove(oldKeyPath);
147     }
148     if (!content.time.empty()) {
149         dbPassword.isKeyOutdated = IsKeyOutdated(content.time);
150     }
151     dbPassword.SetValue(key.data(), key.size());
152     key.assign(key.size(), 0);
153     return dbPassword;
154 }
155 
SaveDBPassword(const std::string & name,const std::string & path,const DistributedDB::CipherPassword & key)156 bool SecurityManager::SaveDBPassword(const std::string &name, const std::string &path,
157     const DistributedDB::CipherPassword &key)
158 {
159     KeyFiles keyFiles(name, path);
160     KeyFilesAutoLock fileLock(keyFiles);
161     std::vector<uint8_t> pwd(key.GetData(), key.GetData() + key.GetSize());
162     auto result = SaveKeyToFile(name, path, pwd);
163     pwd.assign(pwd.size(), 0);
164     return result;
165 }
166 
DelDBPassword(const std::string & name,const std::string & path)167 void SecurityManager::DelDBPassword(const std::string &name, const std::string &path)
168 {
169     KeyFiles keyFiles(name, path);
170     KeyFilesAutoLock fileLock(keyFiles);
171     auto oldKeyPath = path + KEY_DIR + SLASH + name + SUFFIX_KEY;
172     auto newKeyPath = path + KEY_DIR + SLASH + name + SUFFIX_KEY_V1;
173     StoreUtil::Remove(oldKeyPath);
174     StoreUtil::Remove(newKeyPath);
175     fileLock.UnLockAndDestroy();
176 }
177 
LoadKeyFromFile(const std::string & path,SecurityManager::SecurityContent & securityContent)178 void SecurityManager::LoadKeyFromFile(const std::string &path, SecurityManager::SecurityContent &securityContent)
179 {
180     std::vector<char> content;
181     auto loaded = LoadBufferFromFile(path, content);
182     if (!loaded) {
183         return;
184     }
185     if (securityContent.isNewStyle) {
186         LoadNewKey(content, securityContent);
187     } else {
188         LoadOldKey(content, securityContent);
189     }
190     content.assign(content.size(), 0);
191 }
192 
LoadNewKey(const std::vector<char> & content,SecurityManager::SecurityContent & securityContent)193 void SecurityManager::LoadNewKey(const std::vector<char> &content, SecurityManager::SecurityContent &securityContent)
194 {
195     if (content.size() < SecurityContent::MAGIC_NUM + SecurityContent::NONCE_SIZE + 1) {
196         return;
197     }
198     for (size_t index = 0; index < SecurityContent::MAGIC_NUM; ++index) {
199         if (content[index] != char(SecurityContent::MAGIC_CHAR)) {
200             return;
201         }
202     }
203     size_t offset = SecurityContent::MAGIC_NUM;
204     securityContent.nonceValue.assign(content.begin() + offset, content.begin() + offset + SecurityContent::NONCE_SIZE);
205     offset += SecurityContent::NONCE_SIZE;
206     securityContent.encryptValue.assign(content.begin() + offset, content.end());
207 }
208 
LoadOldKey(const std::vector<char> & content,SecurityManager::SecurityContent & securityContent)209 void SecurityManager::LoadOldKey(const std::vector<char> &content, SecurityManager::SecurityContent &securityContent)
210 {
211     size_t offset = 0;
212     if (content.size() < (sizeof(time_t) / sizeof(uint8_t)) + SecurityContent::KEY_SIZE + 1) {
213         return;
214     }
215     if (content[offset] != char((sizeof(time_t) / sizeof(uint8_t)) + SecurityContent::KEY_SIZE)) {
216         return;
217     }
218     ++offset;
219     securityContent.time.assign(content.begin() + offset, content.begin() +
220         (sizeof(time_t) / sizeof(uint8_t)) + offset);
221     offset += (sizeof(time_t) / sizeof(uint8_t));
222     securityContent.encryptValue.assign(content.begin() + offset, content.end());
223 }
224 
SaveKeyToFile(const std::string & name,const std::string & path,std::vector<uint8_t> & key)225 bool SecurityManager::SaveKeyToFile(const std::string &name, const std::string &path,
226     std::vector<uint8_t> &key)
227 {
228     if (!hasRootKey_ && !Retry()) {
229         ZLOGE("Failed! no root key and generation failed");
230         return false;
231     }
232     SecurityContent securityContent;
233     securityContent.version = SecurityContent::CURRENT_VERSION;
234     auto time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
235     securityContent.time = { reinterpret_cast<uint8_t *>(&time), reinterpret_cast<uint8_t *>(&time) + sizeof(time) };
236     std::vector<uint8_t> keyContent;
237     keyContent.push_back(securityContent.version);
238     keyContent.insert(keyContent.end(), securityContent.time.begin(), securityContent.time.end());
239     keyContent.insert(keyContent.end(), key.begin(), key.end());
240     if (!Encrypt(keyContent, securityContent)) {
241         keyContent.assign(keyContent.size(), 0);
242         return false;
243     }
244     keyContent.assign(keyContent.size(), 0);
245     auto keyPath = path + KEY_DIR;
246     StoreUtil::InitPath(keyPath);
247     auto keyFullPath = keyPath + SLASH + name + SUFFIX_KEY_V1;
248     auto fd = open(keyFullPath.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
249     if (fd < 0) {
250         ZLOGE("Create file failed, ret:%{public}d", errno);
251         return false;
252     }
253     std::string content(SecurityContent::MAGIC_NUM, static_cast<char>(SecurityContent::MAGIC_CHAR));
254     content.append(reinterpret_cast<const char *>(securityContent.nonceValue.data()),
255         securityContent.nonceValue.size());
256     content.append(reinterpret_cast<const char *>(securityContent.encryptValue.data()),
257         securityContent.encryptValue.size());
258     auto ret = SaveStringToFd(fd, content);
259     std::fill(content.begin(), content.end(), '\0');
260     close(fd);
261     if (!ret) {
262         ZLOGE("Save key to file fail, ret:%{public}d", ret);
263         return false;
264     }
265     StoreUtil::RemoveRWXForOthers(keyFullPath);
266     return ret;
267 }
268 
Encrypt(const std::vector<uint8_t> & key,SecurityManager::SecurityContent & content)269 bool SecurityManager::Encrypt(const std::vector<uint8_t> &key, SecurityManager::SecurityContent &content)
270 {
271     struct HksParamSet *params = nullptr;
272     int32_t ret = HksInitParamSet(&params);
273     if (ret != HKS_SUCCESS) {
274         ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
275         return false;
276     }
277     content.nonceValue = Random(SecurityContent::NONCE_SIZE);
278     if (content.nonceValue.empty()) {
279         HksFreeParamSet(&params);
280         return false;
281     }
282     struct HksParam hksParam[] = {
283         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
284         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT },
285         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
286         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
287         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
288         { .tag = HKS_TAG_NONCE, .blob = { SecurityContent::NONCE_SIZE, &(content.nonceValue[0]) } },
289         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = { uint32_t(vecAad_.size()), &(vecAad_[0]) } },
290         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
291     };
292     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
293     if (ret != HKS_SUCCESS) {
294         ZLOGE("HksAddParams failed, status: %{public}d", ret);
295         HksFreeParamSet(&params);
296         return false;
297     }
298     ret = HksBuildParamSet(&params);
299     if (ret != HKS_SUCCESS) {
300         ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
301         HksFreeParamSet(&params);
302         return false;
303     }
304     uint8_t cipherBuf[256] = { 0 };
305     struct HksBlob cipherText = { sizeof(cipherBuf), cipherBuf };
306     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
307     struct HksBlob plainKey = { uint32_t(key.size()), const_cast<uint8_t *>(key.data()) };
308     ret = HksEncrypt(&rootKeyName, params, &plainKey, &cipherText);
309     (void)HksFreeParamSet(&params);
310     if (ret != HKS_SUCCESS) {
311         ZLOGE("HksEncrypt failed, status: %{public}d", ret);
312         return false;
313     }
314     content.encryptValue = std::vector<uint8_t>(cipherText.data, cipherText.data + cipherText.size);
315     std::fill(cipherBuf, cipherBuf + sizeof(cipherBuf), 0);
316     return true;
317 }
318 
Decrypt(SecurityManager::SecurityContent & content)319 bool SecurityManager::Decrypt(SecurityManager::SecurityContent &content)
320 {
321     struct HksParamSet *params = nullptr;
322     int32_t ret = HksInitParamSet(&params);
323     if (ret != HKS_SUCCESS) {
324         ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
325         return false;
326     }
327     struct HksBlob blobNonce = { .size = uint32_t(vecNonce_.size()), .data = &(vecNonce_[0]) };
328     if (!(content.nonceValue.empty())) {
329         blobNonce.size = uint32_t(content.nonceValue.size());
330         blobNonce.data = const_cast<uint8_t*>(&(content.nonceValue[0]));
331     }
332     struct HksParam hksParam[] = {
333         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
334         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT },
335         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
336         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
337         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
338         { .tag = HKS_TAG_NONCE, .blob = blobNonce },
339         { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = { uint32_t(vecAad_.size()), &(vecAad_[0]) } },
340         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
341     };
342     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
343     if (ret != HKS_SUCCESS) {
344         ZLOGE("HksAddParams failed, status: %{public}d", ret);
345         HksFreeParamSet(&params);
346         return false;
347     }
348     ret = HksBuildParamSet(&params);
349     if (ret != HKS_SUCCESS) {
350         ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
351         HksFreeParamSet(&params);
352         return false;
353     }
354     uint8_t plainBuf[256] = { 0 };
355     struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf };
356     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) };
357     struct HksBlob encryptedKeyBlob = { uint32_t(content.encryptValue.size()),
358         const_cast<uint8_t *>(content.encryptValue.data()) };
359     ret = HksDecrypt(&rootKeyName, params, &encryptedKeyBlob, &plainKeyBlob);
360     (void)HksFreeParamSet(&params);
361     if (ret != HKS_SUCCESS) {
362         ZLOGE("HksDecrypt, status: %{public}d", ret);
363         return false;
364     }
365     content.fullKeyValue.assign(plainKeyBlob.data, plainKeyBlob.data + plainKeyBlob.size);
366     std::fill(plainBuf, plainBuf + sizeof(plainBuf), 0);
367     return true;
368 }
369 
GenerateRootKey()370 int32_t SecurityManager::GenerateRootKey()
371 {
372     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
373     struct HksParamSet *params = nullptr;
374     int32_t ret = HksInitParamSet(&params);
375     if (ret != HKS_SUCCESS) {
376         ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
377         return ret;
378     }
379 
380     struct HksParam hksParam[] = {
381         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
382         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
383         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
384         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
385         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
386         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
387         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
388     };
389 
390     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
391     if (ret != HKS_SUCCESS) {
392         ZLOGE("HksAddParams failed, status: %{public}d", ret);
393         HksFreeParamSet(&params);
394         return ret;
395     }
396 
397     ret = HksBuildParamSet(&params);
398     if (ret != HKS_SUCCESS) {
399         ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
400         HksFreeParamSet(&params);
401         return ret;
402     }
403 
404     ret = HksGenerateKey(&rootKeyName, params, nullptr);
405     HksFreeParamSet(&params);
406     ZLOGI("HksGenerateKey status: %{public}d", ret);
407     return ret;
408 }
409 
CheckRootKey()410 int32_t SecurityManager::CheckRootKey()
411 {
412     struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), vecRootKeyAlias_.data() };
413     struct HksParamSet *params = nullptr;
414     int32_t ret = HksInitParamSet(&params);
415     if (ret != HKS_SUCCESS) {
416         ZLOGE("HksInitParamSet failed, status: %{public}d", ret);
417         return ret;
418     }
419 
420     struct HksParam hksParam[] = {
421         { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES },
422         { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 },
423         { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT },
424         { .tag = HKS_TAG_DIGEST, .uint32Param = 0 },
425         { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE },
426         { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM },
427         { .tag = HKS_TAG_AUTH_STORAGE_LEVEL, .uint32Param = HKS_AUTH_STORAGE_LEVEL_DE },
428     };
429 
430     ret = HksAddParams(params, hksParam, sizeof(hksParam) / sizeof(hksParam[0]));
431     if (ret != HKS_SUCCESS) {
432         ZLOGE("HksAddParams failed, status: %{public}d", ret);
433         HksFreeParamSet(&params);
434         return ret;
435     }
436 
437     ret = HksBuildParamSet(&params);
438     if (ret != HKS_SUCCESS) {
439         ZLOGE("HksBuildParamSet failed, status: %{public}d", ret);
440         HksFreeParamSet(&params);
441         return ret;
442     }
443 
444     ret = HksKeyExist(&rootKeyName, params);
445     HksFreeParamSet(&params);
446     ZLOGI("HksKeyExist status: %{public}d", ret);
447     return ret;
448 }
449 
IsKeyOutdated(const std::vector<uint8_t> & date)450 bool SecurityManager::IsKeyOutdated(const std::vector<uint8_t> &date)
451 {
452     time_t time = *reinterpret_cast<time_t *>(const_cast<uint8_t *>(&date[0]));
453     auto createTime = std::chrono::system_clock::from_time_t(time);
454     return ((createTime + std::chrono::hours(HOURS_PER_YEAR)) < std::chrono::system_clock::now());
455 }
456 
KeyFiles(const std::string & name,const std::string & path,bool openFile)457 SecurityManager::KeyFiles::KeyFiles(const std::string &name, const std::string &path, bool openFile)
458 {
459     lockFile_ = path + KEY_DIR + SLASH + name + SUFFIX_KEY_LOCK;
460     StoreUtil::InitPath(path + KEY_DIR);
461     if (!openFile) {
462         return;
463     }
464     lockFd_ = open(lockFile_.c_str(), O_RDONLY | O_CREAT, S_IRUSR | S_IWUSR);
465     if (lockFd_ < 0) {
466         ZLOGE("Open failed, errno:%{public}d, path:%{public}s", errno, StoreUtil::Anonymous(lockFile_).c_str());
467     }
468 }
469 
~KeyFiles()470 SecurityManager::KeyFiles::~KeyFiles()
471 {
472     if (lockFd_ < 0) {
473         return;
474     }
475     close(lockFd_);
476     lockFd_ = -1;
477 }
478 
Lock()479 int32_t SecurityManager::KeyFiles::Lock()
480 {
481     return FileLock(LOCK_EX);
482 }
483 
UnLock()484 int32_t SecurityManager::KeyFiles::UnLock()
485 {
486     return FileLock(LOCK_UN);
487 }
488 
DestroyLock()489 int32_t SecurityManager::KeyFiles::DestroyLock()
490 {
491     if (lockFd_ > 0) {
492         close(lockFd_);
493         lockFd_ = -1;
494     }
495     StoreUtil::Remove(lockFile_);
496     return Status::SUCCESS;
497 }
498 
FileLock(int32_t lockType)499 int32_t SecurityManager::KeyFiles::FileLock(int32_t lockType)
500 {
501     if (lockFd_ < 0) {
502         return Status::INVALID_ARGUMENT;
503     }
504     int32_t errCode = 0;
505     do {
506         errCode = flock(lockFd_, lockType);
507     } while (errCode < 0 && errno == EINTR);
508     if (errCode < 0) {
509         ZLOGE("This flock is failed, type:%{public}d, errno:%{public}d, path:%{public}s", lockType, errno,
510             StoreUtil::Anonymous(lockFile_).c_str());
511         return Status::ERROR;
512     }
513     return Status::SUCCESS;
514 }
515 
KeyFilesAutoLock(KeyFiles & keyFiles)516 SecurityManager::KeyFilesAutoLock::KeyFilesAutoLock(KeyFiles& keyFiles) : keyFiles_(keyFiles)
517 {
518     keyFiles_.Lock();
519 }
520 
~KeyFilesAutoLock()521 SecurityManager::KeyFilesAutoLock::~KeyFilesAutoLock()
522 {
523     keyFiles_.UnLock();
524 }
525 
UnLockAndDestroy()526 int32_t SecurityManager::KeyFilesAutoLock::UnLockAndDestroy()
527 {
528     keyFiles_.UnLock();
529     return keyFiles_.DestroyLock();
530 }
531 } // namespace OHOS::DistributedKv
532