1 #pragma once 2 3 #include <libcryptsetup.h> 4 5 #include <stdplus/handle/managed.hpp> 6 7 namespace estoraged 8 { 9 10 /** @class CryptsetupInterface 11 * @brief Interface to the cryptsetup functions used to manage a LUKS device. 12 * @details This class is used to mock out the cryptsetup functions. 13 */ 14 class CryptsetupInterface 15 { 16 public: 17 virtual ~CryptsetupInterface() = default; 18 CryptsetupInterface() = default; 19 CryptsetupInterface(const CryptsetupInterface&) = delete; 20 CryptsetupInterface& operator=(const CryptsetupInterface&) = delete; 21 22 CryptsetupInterface(CryptsetupInterface&&) = delete; 23 CryptsetupInterface& operator=(CryptsetupInterface&&) = delete; 24 /** @brief Wrapper around crypt_format. 25 * @details Used for mocking purposes. 26 * 27 * @param[in] cd - crypt device handle. 28 * @param[in] type - type of device (optional params struct must be of 29 * this type). 30 * @param[in] cipher - (e.g. "aes"). 31 * @params[in cipher_mode - including IV specification (e.g. "xts-plain"). 32 * @params[in] uuid - requested UUID or NULL if it should be generated. 33 * @params[in] volume_key - pre-generated volume key or NULL if it should 34 * be generated (only for LUKS). 35 * @params[in] volume_key_size - size of volume key in bytes. 36 * @params[in] params - crypt type specific parameters. 37 * 38 * @returns 0 on success or negative errno value otherwise. 39 */ 40 virtual int cryptFormat(struct crypt_device* cd, const char* type, 41 const char* cipher, const char* cipherMode, 42 const char* uuid, const char* volumeKey, 43 size_t volumeKeySize, void* params) = 0; 44 45 /** @brief Wrapper around crypt_keyslot_add_by_volume_key. 46 * @details Used for mocking purposes. 47 * 48 * @param[in] cd - crypt device handle. 49 * @param[in] keyslot - requested keyslot or CRYPT_ANY_SLOT. 50 * @param[in] volume_key - provided volume key or NULL if used after 51 * crypt_format. 52 * @param[in] volume_key_size - size of volume_key. 53 * @param[in] passphrase - passphrase for new keyslot. 54 * @param[in] passphrase_size - size of passphrase. 55 * 56 * @returns allocated key slot number or negative errno otherwise. 57 */ 58 virtual int cryptKeyslotAddByVolumeKey(struct crypt_device* cd, int keyslot, 59 const char* volumeKey, 60 size_t volumeKeySize, 61 const char* passphrase, 62 size_t passphraseSize) = 0; 63 64 /** @brief Wrapper around crypt_load. 65 * @details Used for mocking purposes. 66 * 67 * @param[in] cd - crypt device handle. 68 * @param[in] requested_type - crypt-type or NULL for all known. 69 * @param[in] params - crypt type specific parameters (see crypt-type). 70 * 71 * @returns 0 on success or negative errno value otherwise. 72 */ 73 virtual int cryptLoad(struct crypt_device* cd, const char* requestedType, 74 void* params) = 0; 75 76 /** @brief Wrapper around crypt_activate_by_passphrase. 77 * @details Used for mocking purposes. 78 * 79 * @param[in] cd - crypt device handle. 80 * @param[in] name - name of device to create, if NULL only check 81 * passphrase. 82 * @param[in] keyslot - requested keyslot to check or CRYPT_ANY_SLOT. 83 * @param[in] passphrase - passphrase used to unlock volume key. 84 * @param[in] passphrase_size - size of passphrase. 85 * @param[in] flags - activation flags. 86 * 87 * @returns unlocked key slot number or negative errno otherwise. 88 */ 89 virtual int cryptActivateByPassphrase(struct crypt_device* cd, 90 const char* name, int keyslot, 91 const char* passphrase, 92 size_t passphraseSize, 93 uint32_t flags) = 0; 94 95 /** @brief Wrapper around crypt_deactivate. 96 * @details Used for mocking purposes. 97 * 98 * @param[in] cd - crypt device handle, can be NULL. 99 * @param[in] name - name of device to deactivate. 100 * 101 * @returns 0 on success or negative errno value otherwise. 102 */ 103 virtual int cryptDeactivate(struct crypt_device* cd, const char* name) = 0; 104 105 /** @brief Wrapper around crypt_keyslot_destory. 106 * @details Used for mocking purposes. 107 * 108 * @param[in] cd - crypt device handle, can not be NULL. 109 * @param[in] keyslot requested key slot to destroy 110 * 111 * @returns 0 on success or negative errno value otherwise. 112 */ 113 virtual int cryptKeyslotDestroy(struct crypt_device* cd, int keyslot) = 0; 114 115 /** @breif Wapper around crypt_keyslot_max 116 * @details Used for mocking purposes. 117 * 118 * @param type crypt device type 119 * 120 * @return slot count or negative errno otherwise if device 121 * does not support keyslots. 122 */ 123 virtual int cryptKeySlotMax(const char* type) = 0; 124 125 /** @breif Wapper around crypt_keyslot_status 126 * @details Used for mocking purposes. 127 * Get information about particular key slot. 128 * 129 * @param cd crypt device handle 130 * @param keyslot requested keyslot to check or CRYPT_ANY_SLOT 131 * 132 * @return value defined by crypt_keyslot_info 133 * 134 */ 135 virtual crypt_keyslot_info cryptKeySlotStatus(struct crypt_device* cd, 136 int keyslot) = 0; 137 }; 138 139 /** @class Cryptsetup 140 * @brief Implements CryptsetupInterface. 141 */ 142 class Cryptsetup : public CryptsetupInterface 143 { 144 public: 145 ~Cryptsetup() override = default; 146 147 Cryptsetup() = default; 148 Cryptsetup(const Cryptsetup&) = delete; 149 Cryptsetup& operator=(const Cryptsetup&) = delete; 150 151 Cryptsetup(Cryptsetup&&) = delete; 152 Cryptsetup& operator=(Cryptsetup&&) = delete; 153 int cryptFormat(struct crypt_device* cd, const char* type, 154 const char* cipher, const char* cipherMode, 155 const char* uuid, const char* volumeKey, 156 size_t volumeKeySize, void* params) override 157 { 158 return crypt_format(cd, type, cipher, cipherMode, uuid, volumeKey, 159 volumeKeySize, params); 160 } 161 162 int cryptKeyslotAddByVolumeKey(struct crypt_device* cd, int keyslot, 163 const char* volumeKey, size_t volumeKeySize, 164 const char* passphrase, 165 size_t passphraseSize) override 166 { 167 return crypt_keyslot_add_by_volume_key( 168 cd, keyslot, volumeKey, volumeKeySize, passphrase, passphraseSize); 169 } 170 171 int cryptLoad(struct crypt_device* cd, const char* requestedType, 172 void* params) override 173 { 174 return crypt_load(cd, requestedType, params); 175 } 176 177 int cryptActivateByPassphrase(struct crypt_device* cd, const char* name, 178 int keyslot, const char* passphrase, 179 size_t passphraseSize, 180 uint32_t flags) override 181 { 182 return crypt_activate_by_passphrase(cd, name, keyslot, passphrase, 183 passphraseSize, flags); 184 } 185 186 int cryptDeactivate(struct crypt_device* cd, const char* name) override 187 { 188 return crypt_deactivate(cd, name); 189 } 190 191 int cryptKeyslotDestroy(struct crypt_device* cd, const int keyslot) override 192 { 193 return crypt_keyslot_destroy(cd, keyslot); 194 } 195 196 int cryptKeySlotMax(const char* type) override 197 { 198 return crypt_keyslot_max(type); 199 } 200 201 crypt_keyslot_info cryptKeySlotStatus(struct crypt_device* cd, 202 int keyslot) override 203 { 204 return crypt_keyslot_status(cd, keyslot); 205 } 206 }; 207 208 /** @class CryptHandle 209 * @brief This manages a crypt_device struct and automatically frees it when 210 * this handle exits the current scope. 211 */ 212 class CryptHandle 213 { 214 public: 215 /** @brief Constructor for CryptHandle 216 * 217 * @param[in] device - path to device file 218 */ 219 explicit CryptHandle(const char* device) : handle(init(device)) 220 {} 221 222 /** @brief Get a pointer to the crypt_device struct. */ 223 struct crypt_device* get() 224 { 225 return *handle; 226 } 227 228 private: 229 /** @brief Allocate and initialize the crypt_device struct 230 * 231 * @param[in] device - path to device file 232 */ 233 struct crypt_device* init(const char* device) 234 { 235 struct crypt_device* cryptDev = nullptr; 236 int retval = crypt_init(&cryptDev, device); 237 if (retval < 0) 238 { 239 return nullptr; 240 } 241 242 return cryptDev; 243 } 244 245 /** @brief Free the crypt_device struct 246 * 247 * @param[in] cd - pointer to crypt_device*, to be freed 248 */ 249 static void cryptFree(struct crypt_device*&& cd) 250 { 251 crypt_free(cd); 252 } 253 254 /** @brief Managed handle to crypt_device struct */ 255 stdplus::Managed<struct crypt_device*>::Handle<cryptFree> handle; 256 }; 257 258 } // namespace estoraged 259