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