• 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 <chrono>
24 #include <climits>
25 #include <list>
26 #include <map>
27 #include <memory>
28 #include <mutex>
29 #include <random>
30 #include <vector>
31 
32 #include "hks_api.h"
33 #include "rdb_errno.h"
34 
35 
36 namespace OHOS::NativeRdb {
37 struct RdbSecretKeyData {
38     uint8_t distributed = 0;
39     time_t timeValue {};
40     std::vector<uint8_t> secretKey {};
41     RdbSecretKeyData() = default;
~RdbSecretKeyDataRdbSecretKeyData42     ~RdbSecretKeyData()
43     {
44         secretKey.assign(secretKey.size(), 0);
45     }
46 };
47 
48 class RdbPassword final {
49 public:
50     RdbPassword();
51     ~RdbPassword();
52 
53     bool operator==(const RdbPassword &input) const;
54     bool operator!=(const RdbPassword &input) const;
55 
56     size_t GetSize() const;
57     const uint8_t *GetData() const;
58     int SetValue(const uint8_t *inputData, size_t inputSize);
59     int Clear();
60 
61 private:
62     static constexpr size_t MAX_PASSWORD_SIZE = 128;
63     uint8_t data_[MAX_PASSWORD_SIZE] = { UCHAR_MAX };
64     size_t size_ = 0;
65 };
66 
67 class RdbSecurityManager {
68 public:
69     enum class KeyFileType { PUB_KEY_FILE = 1, PUB_KEY_BAK_FILE };
70 
71     RdbPassword GetRdbPassword(KeyFileType keyFile);
72     void DelRdbSecretDataFile(const std::string &path);
73     bool CheckKeyDataFileExists(RdbSecurityManager::KeyFileType keyFile);
74     bool SaveSecretKeyToFile(RdbSecurityManager::KeyFileType keyFile, const std::vector<uint8_t> &key);
75     static RdbSecurityManager &GetInstance();
76     int GetKeyDistributedStatus(KeyFileType keyFile, bool &status);
77     int SetKeyDistributedStatus(KeyFileType keyFile, bool status);
78     void Init(const std::string &bundleName, const std::string &path);
79     std::vector<uint8_t> GenerateRandomNum(int32_t len);
80     static constexpr int RDB_KEY_SIZE = 32;
81 
82 private:
83     RdbSecurityManager();
84     ~RdbSecurityManager();
85 
86     int GenerateRootKey();
87     bool CheckRootKeyExists();
88     std::vector<uint8_t> EncryptWorkKey(const std::vector<uint8_t> &key);
89     bool DecryptWorkKey(std::vector<uint8_t> &source, std::vector<uint8_t> &key);
90     std::vector<uint8_t> GenerateRootKeyAlias(const std::string &bundleName);
91     bool InitPath(const std::string &path);
92     void ParsePath(const std::string &path);
93     bool SaveSecretKeyToDisk(const std::string &path, RdbSecretKeyData &keyData);
94     bool LoadSecretKeyFromDisk(const std::string &keyPath, RdbSecretKeyData &keyData);
95     bool IsKeyOutOfdate(const time_t &createTime) const;
96     int32_t MallocAndCheckBlobData(struct HksBlob *blob, const uint32_t blobSize);
97     int32_t HksLoopUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet,
98         const struct HksBlob *inData, struct HksBlob *outData);
99     int32_t HksEncryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
100         const struct HksBlob *plainText, struct HksBlob *cipherText);
101     int32_t HksDecryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
102         const struct HksBlob *cipherText, struct HksBlob *plainText);
103 
104     static constexpr char const *SUFFIX_PUB_KEY = ".pub_key";
105     static constexpr char const *SUFFIX_PUB_KEY_BAK = ".pub_key_bak";
106     static constexpr const char *RDB_ROOT_KEY_ALIAS_PREFIX = "DistributedDataRdb";
107     static constexpr const char *RDB_HKS_BLOB_TYPE_NONCE = "Z5s0Bo571Koq";
108     static constexpr const char *RDB_HKS_BLOB_TYPE_AAD = "RdbClientAAD";
109     static const uint32_t TIMES = 4;
110     static const uint32_t MAX_UPDATE_SIZE = 64;
111     static const uint32_t MAX_OUTDATA_SIZE = MAX_UPDATE_SIZE * TIMES;
112     static const uint8_t AEAD_LEN = 16;
113 
114     std::string bundleName_;
115     std::string dbDir_;
116     std::string dbName_;
117     std::string dbKeyDir_;
118     std::string keyPath_;
119     std::string keyBakPath_;
120 
121     static constexpr int HOURS_PER_YEAR = (24 * 365);
122     static constexpr uint8_t UNDISTRIBUTED = 0;
123     static constexpr uint8_t DISTRIBUTED = 1;
124 
125     std::vector<uint8_t> rootKeyAlias_ {};
126     std::vector<uint8_t> nonce_ {};
127     std::vector<uint8_t> aad_ {};
128     std::mutex mutex_;
129 };
130 
TransferTypeToByteArray(const T & t)131 template<typename T> std::vector<uint8_t> TransferTypeToByteArray(const T &t)
132 {
133     return std::vector<uint8_t>(reinterpret_cast<uint8_t *>(const_cast<T *>(&t)),
134         reinterpret_cast<uint8_t *>(const_cast<T *>(&t)) + sizeof(T));
135 }
136 
TransferByteArrayToType(const std::vector<uint8_t> & blob)137 template<typename T> T TransferByteArrayToType(const std::vector<uint8_t> &blob)
138 {
139     if (blob.size() != sizeof(T) || blob.size() == 0) {
140         constexpr int tSize = sizeof(T);
141         uint8_t tContent[tSize] = { 0 };
142         return *reinterpret_cast<T *>(tContent);
143     }
144     return *reinterpret_cast<T *>(const_cast<uint8_t *>(&blob[0]));
145 }
146 } // namespace OHOS::NativeRdb
147 #endif
148