blob: 25c69d052eb1e1b135c8dc606a4e9ae49f609965 [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;
99};
100
101/** @class Cryptsetup
102 * @brief Implements CryptsetupInterface.
103 */
104class Cryptsetup : public CryptsetupInterface
105{
106 public:
107 ~Cryptsetup() = default;
108
109 int cryptFormat(struct crypt_device* cd, const char* type,
110 const char* cipher, const char* cipherMode,
111 const char* uuid, const char* volumeKey,
112 size_t volumeKeySize, void* params) override
113 {
114 return crypt_format(cd, type, cipher, cipherMode, uuid, volumeKey,
115 volumeKeySize, params);
116 }
117
118 int cryptKeyslotAddByVolumeKey(struct crypt_device* cd, int keyslot,
119 const char* volumeKey, size_t volumeKeySize,
120 const char* passphrase,
121 size_t passphraseSize) override
122 {
123 return crypt_keyslot_add_by_volume_key(
124 cd, keyslot, volumeKey, volumeKeySize, passphrase, passphraseSize);
125 }
126
127 int cryptLoad(struct crypt_device* cd, const char* requestedType,
128 void* params) override
129 {
130 return crypt_load(cd, requestedType, params);
131 }
132
133 int cryptActivateByPassphrase(struct crypt_device* cd, const char* name,
134 int keyslot, const char* passphrase,
135 size_t passphraseSize,
136 uint32_t flags) override
137 {
138 return crypt_activate_by_passphrase(cd, name, keyslot, passphrase,
139 passphraseSize, flags);
140 }
141
142 int cryptDeactivate(struct crypt_device* cd, const char* name) override
143 {
144 return crypt_deactivate(cd, name);
145 }
146};
147
148/** @class CryptHandle
149 * @brief This manages a crypt_device struct and automatically frees it when
150 * this handle exits the current scope.
151 */
152class CryptHandle
153{
154 public:
155 /** @brief Constructor for CryptHandle
156 *
John Wedigb810c922021-11-17 16:38:03 -0800157 * @param[in] device - path to device file
158 */
John Wedig6218dc52021-12-03 09:36:35 -0800159 explicit CryptHandle(const char* device) : handle(init(device))
John Wedigb810c922021-11-17 16:38:03 -0800160 {}
161
John Wedig6218dc52021-12-03 09:36:35 -0800162 /** @brief Get a pointer to the crypt_device struct. */
163 struct crypt_device* get()
164 {
165 return *handle;
166 }
167
168 private:
John Wedigb810c922021-11-17 16:38:03 -0800169 /** @brief Allocate and initialize the crypt_device struct
170 *
John Wedigb810c922021-11-17 16:38:03 -0800171 * @param[in] device - path to device file
172 */
John Wedig6218dc52021-12-03 09:36:35 -0800173 struct crypt_device* init(const char* device)
John Wedigb810c922021-11-17 16:38:03 -0800174 {
John Wedig6218dc52021-12-03 09:36:35 -0800175 struct crypt_device* cryptDev;
176 int retval = crypt_init(&cryptDev, device);
John Wedigb810c922021-11-17 16:38:03 -0800177 if (retval < 0)
178 {
179 return nullptr;
180 }
181
John Wedig6218dc52021-12-03 09:36:35 -0800182 return cryptDev;
John Wedigb810c922021-11-17 16:38:03 -0800183 }
184
185 /** @brief Free the crypt_device struct
186 *
187 * @param[in] cd - pointer to crypt_device*, to be freed
188 */
189 static void cryptFree(struct crypt_device*&& cd)
190 {
191 crypt_free(cd);
192 }
193
194 /** @brief Managed handle to crypt_device struct */
195 stdplus::Managed<struct crypt_device*>::Handle<cryptFree> handle;
196};
197
198} // namespace estoraged