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