1 /* 2 * Copyright (c) 2021-2024 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 #ifndef STORAGE_DAEMON_CRYPTO_KEY_UTILS_H 16 #define STORAGE_DAEMON_CRYPTO_KEY_UTILS_H 17 18 #include <memory> 19 #include <string> 20 #include <vector> 21 #include <linux/keyctl.h> 22 #include <linux/version.h> 23 24 #include "hks_type.h" 25 #include "securec.h" 26 27 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0) 28 #include <linux/fscrypt.h> 29 #define SUPPORT_FSCRYPT_V2 30 #else 31 #include "libfscrypt/fscrypt_uapi.h" 32 #endif 33 34 namespace OHOS { 35 namespace StorageDaemon { 36 constexpr uint32_t CRYPTO_KEY_SECDISC_SIZE = 16384; 37 constexpr uint32_t CRYPTO_KEY_ALIAS_SIZE = 16; 38 constexpr uint32_t CRYPTO_AES_AAD_LEN = 16; 39 constexpr uint32_t CRYPTO_AES_NONCE_LEN = 64; 40 constexpr uint32_t CRYPTO_HKS_NONCE_LEN = 12; 41 constexpr uint32_t CRYPTO_AES_256_XTS_KEY_SIZE = 64; 42 constexpr uint32_t CRYPTO_KEY_SHIELD_MAX_SIZE = 2048; 43 constexpr uint32_t CRYPTO_AES_256_KEY_ENCRYPTED_SIZE = 80; 44 constexpr uint32_t CRYPTO_TOKEN_SIZE = TOKEN_CHALLENGE_LEN; // 32 45 46 using key_serial_t = int; 47 constexpr uint32_t CRYPTO_KEY_DESC_SIZE = FSCRYPT_KEY_DESCRIPTOR_SIZE; 48 static const std::string MNT_DATA = "/data"; 49 static const std::string PATH_LATEST = "/latest"; 50 static const std::string PATH_SHIELD = "/shield"; 51 static const std::string PATH_SECDISC = "/sec_discard"; 52 static const std::string PATH_ENCRYPTED = "/encrypted"; 53 static const std::string PATH_KEYID = "/key_id"; 54 static const std::string PATH_KEYDESC = "/key_desc"; 55 56 const std::string DATA_EL0_DIR = std::string() + "/data/service/el0"; 57 const std::string STORAGE_DAEMON_DIR = DATA_EL0_DIR + "/storage_daemon"; 58 const std::string DEVICE_EL1_DIR = STORAGE_DAEMON_DIR + "/sd"; 59 60 class KeyBlob { 61 public: 62 KeyBlob() = default; KeyBlob(KeyBlob const & blob)63 KeyBlob(KeyBlob const &blob) 64 { 65 Alloc(blob.size); 66 auto ret = memcpy_s(data.get(), size, blob.data.get(), blob.size); 67 if (ret != EOK) { 68 Clear(); 69 } 70 } ~KeyBlob()71 ~KeyBlob() 72 { 73 Clear(); 74 } KeyBlob(uint32_t len)75 KeyBlob(uint32_t len) 76 { 77 Alloc(len); 78 // may fail, need check IsEmpty() if needed 79 } KeyBlob(KeyBlob && right)80 KeyBlob(KeyBlob &&right) 81 { 82 data = std::move(right.data); 83 size = right.size; 84 } KeyBlob(const std::vector<uint8_t> & vec)85 KeyBlob(const std::vector<uint8_t> &vec) 86 { 87 if (Alloc(vec.size())) { 88 auto ret = memcpy_s(data.get(), size, vec.data(), vec.size()); 89 if (ret != EOK) { 90 Clear(); 91 } 92 } 93 } 94 KeyBlob& operator=(KeyBlob &&right) 95 { 96 data = std::move(right.data); 97 size = right.size; 98 return *this; 99 } Alloc(uint32_t len)100 bool Alloc(uint32_t len) 101 { 102 if (len > CRYPTO_KEY_SECDISC_SIZE) { 103 return false; 104 } 105 if (!IsEmpty()) { 106 Clear(); 107 } 108 109 data = std::make_unique<uint8_t[]>(len); 110 size = len; 111 (void)memset_s(data.get(), size, 0, size); 112 return true; 113 } Clear()114 void Clear() 115 { 116 if (data != nullptr && size != 0) { 117 (void)memset_s(data.get(), size, 0, size); 118 } 119 size = 0; 120 data.reset(nullptr); 121 } IsEmpty()122 bool IsEmpty() const 123 { 124 return size == 0 || data.get() == nullptr; 125 } ToString()126 std::string ToString() const 127 { 128 std::string hex; 129 const char *hexMap = "0123456789abcdef"; 130 static_assert(sizeof(data[0]) == sizeof(char)); 131 for (size_t i = 0; i < size; i++) { 132 hex = hex + hexMap[(data[i] & 0xF0) >> 4] + hexMap[data[i] & 0x0F]; // higher 4 bits 133 } 134 return hex; 135 } ToHksBlob()136 HksBlob ToHksBlob() const 137 { 138 return {size, data.get()}; 139 } 140 uint32_t size { 0 }; 141 std::unique_ptr<uint8_t[]> data { nullptr }; 142 }; 143 144 struct KeyInfo { 145 uint8_t version { 0 }; 146 KeyBlob key; 147 // the legacy interface use key_spec.u.descriptor 148 KeyBlob keyDesc; 149 // the v2 interface use the key_spec.u.identifier 150 KeyBlob keyId; 151 }; 152 153 struct KeyContext { 154 // secure discardable keyblob 155 KeyBlob secDiscard; 156 // encrypted huks key for encrypt/decrypt 157 KeyBlob shield; 158 // encrypted blob of rawkey 159 KeyBlob rndEnc; 160 // aes_gcm tags 161 KeyBlob nonce; 162 KeyBlob aad; 163 }; 164 165 struct UserAuth { 166 // when secure access enabled, token is needed to authenticate the user 167 KeyBlob token; 168 KeyBlob secret; 169 uint64_t secureUid { 0 }; 170 }; 171 } // namespace StorageDaemon 172 } // namespace OHOS 173 174 #endif // STORAGE_DAEMON_CRYPTO_KEY_UTILS_H 175