blob: 49076dd19f7debcfd93d48c75ed7a6662e5a017c [file] [log] [blame]
John Wedigb810c922021-11-17 16:38:03 -08001#pragma once
2
3#include <libcryptsetup.h>
4
5#include <stdplus/handle/managed.hpp>
6
7namespace 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 */
14class CryptsetupInterface
15{
16 public:
17 virtual ~CryptsetupInterface() = default;
Ed Tanous82897c32022-02-21 14:11:59 -080018 CryptsetupInterface() = default;
19 CryptsetupInterface(const CryptsetupInterface&) = delete;
20 CryptsetupInterface& operator=(const CryptsetupInterface&) = delete;
John Wedigb810c922021-11-17 16:38:03 -080021
Ed Tanous82897c32022-02-21 14:11:59 -080022 CryptsetupInterface(CryptsetupInterface&&) = delete;
23 CryptsetupInterface& operator=(CryptsetupInterface&&) = delete;
John Wedigb810c922021-11-17 16:38:03 -080024 /** @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;
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800104
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 */
Ed Tanous82897c32022-02-21 14:11:59 -0800113 virtual int cryptKeyslotDestroy(struct crypt_device* cd, int keyslot) = 0;
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800114
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;
John Wedigb810c922021-11-17 16:38:03 -0800137};
138
139/** @class Cryptsetup
140 * @brief Implements CryptsetupInterface.
141 */
142class Cryptsetup : public CryptsetupInterface
143{
144 public:
Ed Tanous82897c32022-02-21 14:11:59 -0800145 ~Cryptsetup() override = default;
John Wedigb810c922021-11-17 16:38:03 -0800146
Ed Tanous82897c32022-02-21 14:11:59 -0800147 Cryptsetup() = default;
148 Cryptsetup(const Cryptsetup&) = delete;
149 Cryptsetup& operator=(const Cryptsetup&) = delete;
150
151 Cryptsetup(Cryptsetup&&) = delete;
152 Cryptsetup& operator=(Cryptsetup&&) = delete;
John Wedigb810c922021-11-17 16:38:03 -0800153 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 }
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800190
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 }
John Wedigb810c922021-11-17 16:38:03 -0800206};
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 */
212class CryptHandle
213{
214 public:
215 /** @brief Constructor for CryptHandle
216 *
John Wedigb810c922021-11-17 16:38:03 -0800217 * @param[in] device - path to device file
218 */
John Wedig6218dc52021-12-03 09:36:35 -0800219 explicit CryptHandle(const char* device) : handle(init(device))
John Wedigb810c922021-11-17 16:38:03 -0800220 {}
221
John Wedig6218dc52021-12-03 09:36:35 -0800222 /** @brief Get a pointer to the crypt_device struct. */
223 struct crypt_device* get()
224 {
225 return *handle;
226 }
227
228 private:
John Wedigb810c922021-11-17 16:38:03 -0800229 /** @brief Allocate and initialize the crypt_device struct
230 *
John Wedigb810c922021-11-17 16:38:03 -0800231 * @param[in] device - path to device file
232 */
John Wedig6218dc52021-12-03 09:36:35 -0800233 struct crypt_device* init(const char* device)
John Wedigb810c922021-11-17 16:38:03 -0800234 {
Ed Tanous82897c32022-02-21 14:11:59 -0800235 struct crypt_device* cryptDev = nullptr;
John Wedig6218dc52021-12-03 09:36:35 -0800236 int retval = crypt_init(&cryptDev, device);
John Wedigb810c922021-11-17 16:38:03 -0800237 if (retval < 0)
238 {
239 return nullptr;
240 }
241
John Wedig6218dc52021-12-03 09:36:35 -0800242 return cryptDev;
John Wedigb810c922021-11-17 16:38:03 -0800243 }
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