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