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