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 <chrono> 25 #include <climits> 26 #include <list> 27 #include <map> 28 #include <memory> 29 #include <mutex> 30 #include <random> 31 #include <vector> 32 33 #include "hks_api.h" 34 #include "rdb_errno.h" 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 isKeyExpired = false; 54 bool operator==(const RdbPassword &input) const; 55 bool operator!=(const RdbPassword &input) const; 56 57 size_t GetSize() const; 58 const uint8_t *GetData() const; 59 int SetValue(const uint8_t *inputData, size_t inputSize); 60 int Clear(); 61 bool IsValid() const; 62 63 private: 64 static constexpr size_t MAX_PASSWORD_SIZE = 128; 65 uint8_t data_[MAX_PASSWORD_SIZE] = { UCHAR_MAX }; 66 size_t size_ = 0; 67 }; 68 69 class RdbSecurityManager { 70 public: 71 enum class KeyFileType { 72 PUB_KEY_FILE = 1, 73 PUB_KEY_FILE_NEW_KEY 74 }; 75 76 RdbPassword GetRdbPassword(const std::string &dbPath, RdbSecurityManager::KeyFileType keyFileType); 77 void DelRdbSecretDataFile(const std::string &dbPath); 78 void DelRdbSecretDataFile(const std::string &dbPath, RdbSecurityManager::KeyFileType keyFileType); 79 static RdbSecurityManager &GetInstance(); 80 int32_t Init(const std::string &bundleName); 81 void UpdateKeyFile(const std::string &dbPath); 82 bool IsKeyFileExists(const std::string &dbPath, RdbSecurityManager::KeyFileType keyFileType); 83 84 private: 85 RdbSecurityManager(); 86 ~RdbSecurityManager(); 87 88 int GenerateRootKey(const std::vector<uint8_t> &rootKeyAlias); 89 int32_t CheckRootKeyExists(std::vector<uint8_t> &rootKeyAlias); 90 bool HasRootKey(); 91 std::vector<uint8_t> EncryptWorkKey(const std::vector<uint8_t> &key); 92 bool DecryptWorkKey(std::vector<uint8_t> &source, std::vector<uint8_t> &key); 93 std::vector<uint8_t> GenerateRootKeyAlias(const std::string &bundleName); 94 bool InitPath(const std::string &dbKeyDir); 95 std::pair<std::string, std::string> ConcatenateKeyPath(const std::string &dbPath); 96 std::vector<uint8_t> GenerateRandomNum(int32_t len); 97 bool SaveSecretKeyToFile(const std::string &dbPath, RdbSecurityManager::KeyFileType keyFileType); 98 bool SaveSecretKeyToDisk(const std::string &keyPath, RdbSecretKeyData &keyData); 99 RdbPassword LoadSecretKeyFromFile(const std::string &dbPath, KeyFileType keyFileType); 100 bool LoadSecretKeyFromDisk(const std::string &keyPath, RdbSecretKeyData &keyData); 101 static bool IsKeyExpired(const time_t &createTime) ; 102 std::string GetKeyPath(const std::string &dbPath, KeyFileType keyFileType); 103 int32_t MallocAndCheckBlobData(struct HksBlob *blob, const uint32_t blobSize); 104 int32_t HksLoopUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet, 105 const struct HksBlob *inData, struct HksBlob *outData); 106 int32_t HksEncryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, 107 const struct HksBlob *plainText, struct HksBlob *cipherText); 108 int32_t HksDecryptThreeStage(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, 109 const struct HksBlob *cipherText, struct HksBlob *plainText); 110 111 static constexpr char const *SUFFIX_PUB_KEY = ".pub_key"; 112 static constexpr char const *SUFFIX_PUB_KEY_NEW = ".pub_key.new"; 113 static constexpr const char *RDB_ROOT_KEY_ALIAS_PREFIX = "DistributedDataRdb"; 114 static constexpr const char *RDB_HKS_BLOB_TYPE_NONCE = "Z5s0Bo571Koq"; 115 static constexpr const char *RDB_HKS_BLOB_TYPE_AAD = "RdbClientAAD"; 116 static const uint32_t TIMES = 4; 117 static const uint32_t MAX_UPDATE_SIZE = 64; 118 static const uint32_t MAX_OUTDATA_SIZE = MAX_UPDATE_SIZE * TIMES; 119 static const uint8_t AEAD_LEN = 16; 120 static constexpr int RDB_KEY_SIZE = 32; 121 122 static constexpr int HOURS_PER_YEAR = (24 * 365); 123 static constexpr uint8_t UNDISTRIBUTED = 0; 124 static constexpr uint8_t DISTRIBUTED = 1; 125 126 std::vector<uint8_t> rootKeyAlias_ {}; 127 std::vector<uint8_t> nonce_; 128 std::vector<uint8_t> aad_; 129 std::mutex mutex_; 130 std::atomic<bool> hasRootKey_ = false; 131 }; 132 133 } // namespace OHOS::NativeRdb 134 #endif 135