• 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 
16 #ifndef NATIVE_RDB_RDB_SECURITY_MANAGER_H
17 #define NATIVE_RDB_RDB_SECURITY_MANAGER_H
18 
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 
23 #include <atomic>
24 #include <climits>
25 #include <mutex>
26 #include <random>
27 #include <vector>
28 
29 namespace OHOS::NativeRdb {
30 struct RdbSecretKeyData {
31     static constexpr uint32_t CURRENT_VERSION = 1;
32     uint8_t distributed = CURRENT_VERSION;
33     time_t timeValue{};
34     std::vector<uint8_t> secretKey{};
35     RdbSecretKeyData() = default;
~RdbSecretKeyDataRdbSecretKeyData36     ~RdbSecretKeyData()
37     {
38         distributed = 0;
39         timeValue = time_t();
40         secretKey.assign(secretKey.size(), 0);
41     }
42 };
43 
44 struct RdbSecretContent {
45     static constexpr uint32_t MAGIC_NUMBER_V2 = 0x6B6B6B6B;
46     static constexpr uint32_t NONCE_VALUE_SIZE = 12;
47     uint32_t magicNum = MAGIC_NUMBER_V2;
48     std::vector<uint8_t> nonce_{};
49     std::vector<uint8_t> encrypt_{};
50     RdbSecretContent() = default;
~RdbSecretContentRdbSecretContent51     ~RdbSecretContent()
52     {
53         nonce_.assign(nonce_.size(), 0);
54         encrypt_.assign(encrypt_.size(), 0);
55     }
56 };
57 
58 class RdbPassword final {
59 public:
60     RdbPassword();
61     ~RdbPassword();
62 
63     bool isKeyExpired = false;
64     bool operator==(const RdbPassword &input) const;
65     bool operator!=(const RdbPassword &input) const;
66 
67     size_t GetSize() const;
68     const uint8_t *GetData() const;
69     int SetValue(const uint8_t *inputData, size_t inputSize);
70     int Clear();
71     bool IsValid() const;
72 
73 private:
74     static constexpr size_t MAX_PASSWORD_SIZE = 128;
75     uint8_t data_[MAX_PASSWORD_SIZE] = { UCHAR_MAX };
76     size_t size_ = 0;
77 };
78 
79 class RdbSecurityManager {
80 public:
81     enum HksErrCode {
82         HKS_SUCCESS = 0,
83         HKS_FAILURE = -1,
84         HKS_ERROR_NOT_EXIST = -13,
85     };
86 
87     enum KeyFileType : int32_t {
88         PUB_KEY_FILE = 0,
89         PUB_KEY_FILE_NEW_KEY,
90         PUB_KEY_FILE_BUTT
91     };
92     class KeyFiles {
93     public:
94         KeyFiles(const std::string &dbPath, bool openFile = true);
95         ~KeyFiles();
96         const std::string &GetKeyFile(KeyFileType type);
97         int32_t InitKeyPath();
98         int32_t DestroyLock();
99         int32_t Lock(bool isBlock = true);
100         int32_t Unlock();
101 
102     private:
103         int32_t lockFd_ = -1;
104         std::string lock_;
105         std::string keys_[PUB_KEY_FILE_BUTT];
106     };
107     static RdbSecurityManager &GetInstance();
108     int32_t Init(const std::string &bundleName);
109 
110     RdbPassword GetRdbPassword(const std::string &dbPath, KeyFileType keyFileType);
111     void DelAllKeyFiles(const std::string &dbPath);
112     void DelKeyFile(const std::string &dbPath, KeyFileType keyFileType);
113     void ChangeKeyFile(const std::string &dbPath);
114     int32_t RestoreKeyFile(const std::string &dbPath, const std::vector<uint8_t> &key);
115     bool IsKeyFileExists(const std::string &dbPath, KeyFileType keyFileType);
116 
117 private:
118     RdbSecurityManager();
119     ~RdbSecurityManager();
120 
121     bool HasRootKey();
122     void* GetHandle();
123     int32_t GenerateRootKey(const std::vector<uint8_t> &rootKeyAlias);
124     int32_t CheckRootKeyExists(std::vector<uint8_t> &rootKeyAlias);
125     std::pair<bool, RdbSecretContent> EncryptWorkKey(const std::vector<uint8_t> &key);
126     std::vector<uint8_t> DecryptWorkKey(const std::vector<uint8_t> &key, const std::vector<uint8_t> &nonce);
127     void ReportCryptFault(int32_t code, const std::string &message);
128     std::vector<uint8_t> GenerateRootKeyAlias(const std::string &bundleName);
129     static bool InitPath(const std::string &fileDir);
130     std::vector<uint8_t> GenerateRandomNum(int32_t len);
131     bool SaveSecretKeyToFile(const std::string &keyFile, const std::vector<uint8_t> &workey = {});
132     bool SaveSecretKeyToDisk(const std::string &keyPath, const RdbSecretContent &secretContent);
133     RdbPassword LoadSecretKeyFromFile(const std::string &keyFile);
134     bool LoadSecretKeyFromDisk(const std::string &keyPath, RdbSecretKeyData &keyData);
135     bool LoadSecretKeyFromDiskV1(const std::string &keyPath, RdbSecretKeyData &keyData);
136     std::pair<bool, RdbSecretContent> UnpackV1(const std::vector<char> &content);
137     std::pair<bool, RdbSecretContent> UnpackV2(const std::vector<char> &content);
138     std::pair<bool, RdbSecretKeyData> DecryptV1(const RdbSecretContent &content);
139     std::pair<bool, RdbSecretKeyData> DecryptV2(const RdbSecretContent &content);
140     bool IsKeyFileEmpty(const std::string &keyFile);
141     static bool IsKeyExpired(const time_t &createTime);
142     std::vector<uint8_t> GetRootKeyAlias();
143     std::string GetBundleNameByAlias();
144     std::string GetBundleNameByAlias(const std::vector<uint8_t> &rootKeyAlias);
145     void SetRootKeyAlias(std::vector<uint8_t> rootKeyAlias);
146     std::string ReplaceSuffix(const std::string& str);
147 
148     static constexpr char const *SUFFIX_KEY_LOCK = ".key_lock";
149     static constexpr char const *SUFFIX_PUB_KEY = ".pub_key_v1";
150     static constexpr char const *SUFFIX_PUB_KEY_NEW = ".pub_key.new";
151     static constexpr const char *SUFFIX_PUB_KEY_OLD = ".pub_key";
152     static constexpr const char *SUFFIX_PUB_TMP_NEW_KEY = ".pub_key_v1.new";
153     static constexpr const char *RDB_ROOT_KEY_ALIAS_PREFIX = "DistributedDataRdb";
154     static constexpr const char *RDB_HKS_BLOB_TYPE_NONCE = "Z5s0Bo571Koq";
155     static constexpr uint32_t TIMES = 4;
156     static constexpr uint32_t MAX_UPDATE_SIZE = 64;
157     static constexpr uint32_t MAX_OUTDATA_SIZE = MAX_UPDATE_SIZE * TIMES;
158     static constexpr uint8_t AEAD_LEN = 16;
159     static constexpr int RDB_KEY_SIZE = 32;
160 
161     static constexpr int HOURS_PER_YEAR = (24 * 365);
162     static constexpr uint8_t UNDISTRIBUTED = 0;
163     static constexpr uint8_t DISTRIBUTED = 1;
164 
165     std::mutex rootKeyMutex_;
166     std::vector<uint8_t> rootKeyAlias_{};
167     std::mutex mutex_;
168     std::atomic<bool> hasRootKey_ = false;
169     void *handle_;
170     std::mutex handleMutex_;
171 };
172 
173 } // namespace OHOS::NativeRdb
174 #endif
175