• 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 namespace OHOS::NativeRdb {
36 struct RdbSecretKeyData {
37     uint8_t distributed = 0;
38     time_t timeValue {};
39     std::vector<uint8_t> secretKey {};
40     RdbSecretKeyData() = default;
~RdbSecretKeyDataRdbSecretKeyData41     ~RdbSecretKeyData()
42     {
43         secretKey.assign(secretKey.size(), 0);
44     }
45 };
46 
47 class RdbPassword final {
48 public:
49     RdbPassword();
50     ~RdbPassword();
51 
52     bool isKeyExpired = false;
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     bool IsValid() const;
61 
62 private:
63     static constexpr size_t MAX_PASSWORD_SIZE = 128;
64     uint8_t data_[MAX_PASSWORD_SIZE] = { UCHAR_MAX };
65     size_t size_ = 0;
66 };
67 
68 class RdbSecurityManager {
69 public:
70     enum class KeyFileType {
71         PUB_KEY_FILE = 1,
72         PUB_KEY_FILE_NEW_KEY
73     };
74 
75     RdbPassword GetRdbPassword(KeyFileType keyFile);
76     void DelRdbSecretDataFile(const std::string &path);
77     void DelRdbSecretDataFile(RdbSecurityManager::KeyFileType keyFile);
78     static RdbSecurityManager &GetInstance();
79     void Init(const std::string &bundleName, const std::string &path);
80     void UpdateKeyFile();
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();
91     bool InitPath(const std::string &path);
92     void ParsePath(const std::string &path);
93     bool CheckKeyDataFileExists(RdbSecurityManager::KeyFileType keyFile);
94     std::vector<uint8_t> GenerateRandomNum(int32_t len);
95     bool SaveSecretKeyToFile(RdbSecurityManager::KeyFileType keyFile);
96     bool SaveSecretKeyToDisk(const std::string &path, RdbSecretKeyData &keyData);
97     RdbPassword LoadSecretKeyFromFile(KeyFileType keyFile);
98     bool LoadSecretKeyFromDisk(const std::string &keyPath, RdbSecretKeyData &keyData);
99     static bool IsKeyExpired(const time_t &createTime) ;
100     void GetKeyPath(KeyFileType keyType, std::string &keyPath);
101     int32_t MallocAndCheckBlobData(struct HksBlob *blob, const uint32_t blobSize);
102     int32_t HksLoopUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet,
103         const struct HksBlob *inData, struct HksBlob *outData);
104     int32_t HksEncryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
105         const struct HksBlob *plainText, struct HksBlob *cipherText);
106     int32_t HksDecryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet,
107         const struct HksBlob *cipherText, struct HksBlob *plainText);
108 
109     static constexpr char const *SUFFIX_PUB_KEY = ".pub_key";
110     static constexpr char const *SUFFIX_PUB_KEY_NEW = ".pub_key.new";
111     static constexpr const char *RDB_ROOT_KEY_ALIAS_PREFIX = "DistributedDataRdb";
112     static constexpr const char *RDB_HKS_BLOB_TYPE_NONCE = "Z5s0Bo571Koq";
113     static constexpr const char *RDB_HKS_BLOB_TYPE_AAD = "RdbClientAAD";
114     static const uint32_t TIMES = 4;
115     static const uint32_t MAX_UPDATE_SIZE = 64;
116     static const uint32_t MAX_OUTDATA_SIZE = MAX_UPDATE_SIZE * TIMES;
117     static const uint8_t AEAD_LEN = 16;
118     static constexpr int RDB_KEY_SIZE = 32;
119 
120     std::string bundleName_;
121     std::string dbDir_;
122     std::string dbName_;
123     std::string dbKeyDir_;
124     std::string keyPath_;
125     std::string newKeyPath_;
126 
127     static constexpr int HOURS_PER_YEAR = (24 * 365);
128     static constexpr uint8_t UNDISTRIBUTED = 0;
129     static constexpr uint8_t DISTRIBUTED = 1;
130 
131     std::vector<uint8_t> rootKeyAlias_ {};
132     std::vector<uint8_t> nonce_ {};
133     std::vector<uint8_t> aad_ {};
134     std::mutex mutex_;
135 };
136 
TransferTypeToByteArray(const T & t)137 template<typename T> std::vector<uint8_t> TransferTypeToByteArray(const T &t)
138 {
139     return std::vector<uint8_t>(reinterpret_cast<uint8_t *>(const_cast<T *>(&t)),
140         reinterpret_cast<uint8_t *>(const_cast<T *>(&t)) + sizeof(T));
141 }
142 
TransferByteArrayToType(const std::vector<uint8_t> & blob)143 template<typename T> T TransferByteArrayToType(const std::vector<uint8_t> &blob)
144 {
145     if (blob.size() != sizeof(T) || blob.size() == 0) {
146         constexpr int tSize = sizeof(T);
147         uint8_t tContent[tSize] = { 0 };
148         return *reinterpret_cast<T *>(tContent);
149     }
150     return *reinterpret_cast<T *>(const_cast<uint8_t *>(&blob[0]));
151 }
152 } // namespace OHOS::NativeRdb
153 #endif
154