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 #include "hks_type.h" 30 31 namespace OHOS::NativeRdb { 32 struct RdbSecretKeyData { 33 uint8_t distributed = 0; 34 time_t timeValue {}; 35 std::vector<uint8_t> secretKey {}; 36 RdbSecretKeyData() = default; ~RdbSecretKeyDataRdbSecretKeyData37 ~RdbSecretKeyData() 38 { 39 secretKey.assign(secretKey.size(), 0); 40 } 41 }; 42 43 class RdbPassword final { 44 public: 45 RdbPassword(); 46 ~RdbPassword(); 47 48 bool isKeyExpired = false; 49 bool operator==(const RdbPassword &input) const; 50 bool operator!=(const RdbPassword &input) const; 51 52 size_t GetSize() const; 53 const uint8_t *GetData() const; 54 int SetValue(const uint8_t *inputData, size_t inputSize); 55 int Clear(); 56 bool IsValid() const; 57 58 private: 59 static constexpr size_t MAX_PASSWORD_SIZE = 128; 60 uint8_t data_[MAX_PASSWORD_SIZE] = { UCHAR_MAX }; 61 size_t size_ = 0; 62 }; 63 64 class RdbSecurityManager { 65 public: 66 enum KeyFileType : int32_t { 67 PUB_KEY_FILE = 0, 68 PUB_KEY_FILE_NEW_KEY, 69 PUB_KEY_FILE_BUTT 70 }; 71 class KeyFiles { 72 public: 73 KeyFiles(const std::string &dbPath, bool openFile = true); 74 ~KeyFiles(); 75 const std::string &GetKeyFile(KeyFileType type); 76 int32_t InitKeyPath(); 77 int32_t DestroyLock(); 78 int32_t Lock(); 79 int32_t Unlock(); 80 81 private: 82 int32_t lockFd_ = -1; 83 std::string lock_; 84 std::string keys_[PUB_KEY_FILE_BUTT]; 85 }; 86 static RdbSecurityManager &GetInstance(); 87 int32_t Init(const std::string &bundleName); 88 89 RdbPassword GetRdbPassword(const std::string &dbPath, KeyFileType keyFileType); 90 void DelAllKeyFiles(const std::string &dbPath); 91 void DelKeyFile(const std::string &dbPath, KeyFileType keyFileType); 92 void ChangeKeyFile(const std::string &dbPath); 93 int32_t RestoreKeyFile(const std::string &dbPath, const std::vector<uint8_t> &key); 94 bool IsKeyFileExists(const std::string &dbPath, KeyFileType keyFileType); 95 96 private: 97 RdbSecurityManager(); 98 ~RdbSecurityManager(); 99 100 bool HasRootKey(); 101 int GenerateRootKey(const std::vector<uint8_t> &rootKeyAlias); 102 int32_t CheckRootKeyExists(std::vector<uint8_t> &rootKeyAlias); 103 std::vector<uint8_t> EncryptWorkKey(std::vector<uint8_t> &key); 104 bool DecryptWorkKey(std::vector<uint8_t> &source, std::vector<uint8_t> &key); 105 std::vector<uint8_t> GenerateRootKeyAlias(const std::string &bundleName); 106 static bool InitPath(const std::string &fileDir); 107 std::vector<uint8_t> GenerateRandomNum(int32_t len); 108 bool SaveSecretKeyToFile(const std::string &keyFile, const std::vector<uint8_t> &workey = {}); 109 bool SaveSecretKeyToDisk(const std::string &keyPath, RdbSecretKeyData &keyData); 110 RdbPassword LoadSecretKeyFromFile(const std::string &keyFile); 111 bool LoadSecretKeyFromDisk(const std::string &keyPath, RdbSecretKeyData &keyData); 112 bool IsKeyFileEmpty(const std::string &keyFile); 113 static bool IsKeyExpired(const time_t &createTime) ; 114 int32_t HksLoopUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet, 115 const struct HksBlob *inData, struct HksBlob *outData); 116 int32_t HksEncryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, 117 const struct HksBlob *plainText, struct HksBlob *cipherText); 118 int32_t HksDecryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, 119 const struct HksBlob *cipherText, struct HksBlob *plainText); 120 121 static constexpr char const *SUFFIX_KEY_LOCK = ".key_lock"; 122 static constexpr char const *SUFFIX_PUB_KEY = ".pub_key"; 123 static constexpr char const *SUFFIX_PUB_KEY_NEW = ".pub_key.new"; 124 static constexpr const char *RDB_ROOT_KEY_ALIAS_PREFIX = "DistributedDataRdb"; 125 static constexpr const char *RDB_HKS_BLOB_TYPE_NONCE = "Z5s0Bo571Koq"; 126 static constexpr const char *RDB_HKS_BLOB_TYPE_AAD = "RdbClientAAD"; 127 static constexpr uint32_t TIMES = 4; 128 static constexpr uint32_t MAX_UPDATE_SIZE = 64; 129 static constexpr uint32_t MAX_OUTDATA_SIZE = MAX_UPDATE_SIZE * TIMES; 130 static constexpr uint8_t AEAD_LEN = 16; 131 static constexpr int RDB_KEY_SIZE = 32; 132 133 static constexpr int HOURS_PER_YEAR = (24 * 365); 134 static constexpr uint8_t UNDISTRIBUTED = 0; 135 static constexpr uint8_t DISTRIBUTED = 1; 136 137 std::vector<uint8_t> rootKeyAlias_ {}; 138 std::vector<uint8_t> nonce_; 139 std::vector<uint8_t> aad_; 140 std::mutex mutex_; 141 std::atomic<bool> hasRootKey_ = false; 142 }; 143 144 } // namespace OHOS::NativeRdb 145 #endif 146