blob: e13320c5677c986f1474aeaa6764af973aaecd0e [file] [log] [blame]
John Wedigb810c922021-11-17 16:38:03 -08001#pragma once
2
3#include <libcryptsetup.h>
4
John Edward Broadbent2b5454d2022-04-14 19:28:12 -07005#include <phosphor-logging/lg2.hpp>
John Wedigb810c922021-11-17 16:38:03 -08006#include <stdplus/handle/managed.hpp>
John Edward Broadbent2b5454d2022-04-14 19:28:12 -07007#include <xyz/openbmc_project/Common/error.hpp>
8
9#include <string>
John Edward Broadbentb2c86be2022-04-15 11:45:53 -070010#include <string_view>
John Wedigb810c922021-11-17 16:38:03 -080011
12namespace estoraged
13{
14
John Edward Broadbent2b5454d2022-04-14 19:28:12 -070015using sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound;
16
John Wedigb810c922021-11-17 16:38:03 -080017/** @class CryptsetupInterface
18 * @brief Interface to the cryptsetup functions used to manage a LUKS device.
19 * @details This class is used to mock out the cryptsetup functions.
20 */
21class CryptsetupInterface
22{
23 public:
24 virtual ~CryptsetupInterface() = default;
Ed Tanous82897c32022-02-21 14:11:59 -080025 CryptsetupInterface() = default;
26 CryptsetupInterface(const CryptsetupInterface&) = delete;
27 CryptsetupInterface& operator=(const CryptsetupInterface&) = delete;
John Wedigb810c922021-11-17 16:38:03 -080028
Ed Tanous82897c32022-02-21 14:11:59 -080029 CryptsetupInterface(CryptsetupInterface&&) = delete;
30 CryptsetupInterface& operator=(CryptsetupInterface&&) = delete;
John Wedig8d5a3a02022-09-29 15:25:58 -070031
John Wedigb810c922021-11-17 16:38:03 -080032 /** @brief Wrapper around crypt_format.
33 * @details Used for mocking purposes.
34 *
35 * @param[in] cd - crypt device handle.
36 * @param[in] type - type of device (optional params struct must be of
37 * this type).
38 * @param[in] cipher - (e.g. "aes").
39 * @params[in cipher_mode - including IV specification (e.g. "xts-plain").
40 * @params[in] uuid - requested UUID or NULL if it should be generated.
41 * @params[in] volume_key - pre-generated volume key or NULL if it should
42 * be generated (only for LUKS).
43 * @params[in] volume_key_size - size of volume key in bytes.
44 * @params[in] params - crypt type specific parameters.
45 *
46 * @returns 0 on success or negative errno value otherwise.
47 */
48 virtual int cryptFormat(struct crypt_device* cd, const char* type,
49 const char* cipher, const char* cipherMode,
50 const char* uuid, const char* volumeKey,
51 size_t volumeKeySize, void* params) = 0;
52
John Wedig8d5a3a02022-09-29 15:25:58 -070053 /** @brief Wrapper around crypt_keyslot_change_by_passphrase.
54 * @details Used for mocking purposes.
55 *
56 * @param[in] cd - crypt device handle.
57 * @param[in] keyslotOld - old keyslot or CRYPT_ANY_SLOT.
58 * @param[in] keyslotNew - new keyslot or CRYPT_ANY_SLOT.
59 * @param[in] passphrase - passphrase for new keyslot.
60 * @param[in] passphraseSize - size of passphrase.
61 * @param[in] newPassphrase - new passphrase for the specified keyslot
62 * @param[in] newPassphraseSize - size of newPassphrase (in bytes).
63 *
64 * @returns allocated key slot number or negative errno otherwise.
65 */
66 virtual int cryptKeyslotChangeByPassphrase(struct crypt_device* cd,
67 int keyslotOld, int keyslotNew,
68 const char* passphrase,
69 size_t passphraseSize,
70 const char* newPassphrase,
71 size_t newPassphraseSize) = 0;
72
John Wedigb810c922021-11-17 16:38:03 -080073 /** @brief Wrapper around crypt_keyslot_add_by_volume_key.
74 * @details Used for mocking purposes.
75 *
76 * @param[in] cd - crypt device handle.
77 * @param[in] keyslot - requested keyslot or CRYPT_ANY_SLOT.
78 * @param[in] volume_key - provided volume key or NULL if used after
79 * crypt_format.
80 * @param[in] volume_key_size - size of volume_key.
81 * @param[in] passphrase - passphrase for new keyslot.
82 * @param[in] passphrase_size - size of passphrase.
83 *
84 * @returns allocated key slot number or negative errno otherwise.
85 */
86 virtual int cryptKeyslotAddByVolumeKey(struct crypt_device* cd, int keyslot,
87 const char* volumeKey,
88 size_t volumeKeySize,
89 const char* passphrase,
90 size_t passphraseSize) = 0;
91
92 /** @brief Wrapper around crypt_load.
93 * @details Used for mocking purposes.
94 *
95 * @param[in] cd - crypt device handle.
96 * @param[in] requested_type - crypt-type or NULL for all known.
97 * @param[in] params - crypt type specific parameters (see crypt-type).
98 *
99 * @returns 0 on success or negative errno value otherwise.
100 */
101 virtual int cryptLoad(struct crypt_device* cd, const char* requestedType,
102 void* params) = 0;
103
104 /** @brief Wrapper around crypt_activate_by_passphrase.
105 * @details Used for mocking purposes.
106 *
107 * @param[in] cd - crypt device handle.
108 * @param[in] name - name of device to create, if NULL only check
109 * passphrase.
110 * @param[in] keyslot - requested keyslot to check or CRYPT_ANY_SLOT.
111 * @param[in] passphrase - passphrase used to unlock volume key.
112 * @param[in] passphrase_size - size of passphrase.
113 * @param[in] flags - activation flags.
114 *
115 * @returns unlocked key slot number or negative errno otherwise.
116 */
117 virtual int cryptActivateByPassphrase(struct crypt_device* cd,
118 const char* name, int keyslot,
119 const char* passphrase,
120 size_t passphraseSize,
121 uint32_t flags) = 0;
122
123 /** @brief Wrapper around crypt_deactivate.
124 * @details Used for mocking purposes.
125 *
126 * @param[in] cd - crypt device handle, can be NULL.
127 * @param[in] name - name of device to deactivate.
128 *
129 * @returns 0 on success or negative errno value otherwise.
130 */
131 virtual int cryptDeactivate(struct crypt_device* cd, const char* name) = 0;
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800132
133 /** @brief Wrapper around crypt_keyslot_destory.
134 * @details Used for mocking purposes.
135 *
136 * @param[in] cd - crypt device handle, can not be NULL.
137 * @param[in] keyslot requested key slot to destroy
138 *
139 * @returns 0 on success or negative errno value otherwise.
140 */
Ed Tanous82897c32022-02-21 14:11:59 -0800141 virtual int cryptKeyslotDestroy(struct crypt_device* cd, int keyslot) = 0;
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800142
143 /** @breif Wapper around crypt_keyslot_max
144 * @details Used for mocking purposes.
145 *
146 * @param type crypt device type
147 *
148 * @return slot count or negative errno otherwise if device
149 * does not support keyslots.
150 */
151 virtual int cryptKeySlotMax(const char* type) = 0;
152
153 /** @breif Wapper around crypt_keyslot_status
154 * @details Used for mocking purposes.
155 * Get information about particular key slot.
156 *
157 * @param cd crypt device handle
158 * @param keyslot requested keyslot to check or CRYPT_ANY_SLOT
159 *
160 * @return value defined by crypt_keyslot_info
161 *
162 */
163 virtual crypt_keyslot_info cryptKeySlotStatus(struct crypt_device* cd,
164 int keyslot) = 0;
John Wedigb810c922021-11-17 16:38:03 -0800165};
166
167/** @class Cryptsetup
168 * @brief Implements CryptsetupInterface.
169 */
170class Cryptsetup : public CryptsetupInterface
171{
172 public:
Ed Tanous82897c32022-02-21 14:11:59 -0800173 ~Cryptsetup() override = default;
John Wedigb810c922021-11-17 16:38:03 -0800174
Ed Tanous82897c32022-02-21 14:11:59 -0800175 Cryptsetup() = default;
176 Cryptsetup(const Cryptsetup&) = delete;
177 Cryptsetup& operator=(const Cryptsetup&) = delete;
178
179 Cryptsetup(Cryptsetup&&) = delete;
180 Cryptsetup& operator=(Cryptsetup&&) = delete;
John Wedigb810c922021-11-17 16:38:03 -0800181 int cryptFormat(struct crypt_device* cd, const char* type,
182 const char* cipher, const char* cipherMode,
183 const char* uuid, const char* volumeKey,
184 size_t volumeKeySize, void* params) override
185 {
186 return crypt_format(cd, type, cipher, cipherMode, uuid, volumeKey,
187 volumeKeySize, params);
188 }
189
John Wedig8d5a3a02022-09-29 15:25:58 -0700190 int cryptKeyslotChangeByPassphrase(struct crypt_device* cd, int keyslotOld,
191 int keyslotNew, const char* passphrase,
192 size_t passphraseSize,
193 const char* newPassphrase,
194 size_t newPassphraseSize) override
195 {
196 return crypt_keyslot_change_by_passphrase(
197 cd, keyslotOld, keyslotNew, passphrase, passphraseSize,
198 newPassphrase, newPassphraseSize);
199 }
200
John Wedigb810c922021-11-17 16:38:03 -0800201 int cryptKeyslotAddByVolumeKey(struct crypt_device* cd, int keyslot,
202 const char* volumeKey, size_t volumeKeySize,
203 const char* passphrase,
204 size_t passphraseSize) override
205 {
206 return crypt_keyslot_add_by_volume_key(
207 cd, keyslot, volumeKey, volumeKeySize, passphrase, passphraseSize);
208 }
209
210 int cryptLoad(struct crypt_device* cd, const char* requestedType,
211 void* params) override
212 {
213 return crypt_load(cd, requestedType, params);
214 }
215
216 int cryptActivateByPassphrase(struct crypt_device* cd, const char* name,
217 int keyslot, const char* passphrase,
218 size_t passphraseSize,
219 uint32_t flags) override
220 {
221 return crypt_activate_by_passphrase(cd, name, keyslot, passphrase,
222 passphraseSize, flags);
223 }
224
225 int cryptDeactivate(struct crypt_device* cd, const char* name) override
226 {
227 return crypt_deactivate(cd, name);
228 }
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800229
230 int cryptKeyslotDestroy(struct crypt_device* cd, const int keyslot) override
231 {
232 return crypt_keyslot_destroy(cd, keyslot);
233 }
234
235 int cryptKeySlotMax(const char* type) override
236 {
237 return crypt_keyslot_max(type);
238 }
239
240 crypt_keyslot_info cryptKeySlotStatus(struct crypt_device* cd,
241 int keyslot) override
242 {
243 return crypt_keyslot_status(cd, keyslot);
244 }
John Wedigb810c922021-11-17 16:38:03 -0800245};
246
247/** @class CryptHandle
248 * @brief This manages a crypt_device struct and automatically frees it when
249 * this handle exits the current scope.
250 */
251class CryptHandle
252{
253 public:
254 /** @brief Constructor for CryptHandle
255 *
John Wedigb810c922021-11-17 16:38:03 -0800256 * @param[in] device - path to device file
257 */
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700258 explicit CryptHandle(const std::string_view& device) : handle(init(device))
John Wedigb810c922021-11-17 16:38:03 -0800259 {}
260
John Wedig6218dc52021-12-03 09:36:35 -0800261 /** @brief Get a pointer to the crypt_device struct. */
262 struct crypt_device* get()
263 {
John Edward Broadbent2b5454d2022-04-14 19:28:12 -0700264 if (*handle == nullptr)
265 {
266 lg2::error("Failed to get crypt device handle",
267 "REDFISH_MESSAGE_ID",
268 std::string("OpenBMC.0.1.HandleGetFail"));
269 throw ResourceNotFound();
270 }
271
John Wedig6218dc52021-12-03 09:36:35 -0800272 return *handle;
273 }
274
275 private:
John Wedigb810c922021-11-17 16:38:03 -0800276 /** @brief Allocate and initialize the crypt_device struct
277 *
John Wedigb810c922021-11-17 16:38:03 -0800278 * @param[in] device - path to device file
279 */
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700280 struct crypt_device* init(const std::string_view& device)
John Wedigb810c922021-11-17 16:38:03 -0800281 {
Ed Tanous82897c32022-02-21 14:11:59 -0800282 struct crypt_device* cryptDev = nullptr;
John Edward Broadbentb2c86be2022-04-15 11:45:53 -0700283 int retval = crypt_init(&cryptDev, device.data());
John Wedigb810c922021-11-17 16:38:03 -0800284 if (retval < 0)
285 {
John Edward Broadbent28cc8342022-04-14 19:28:12 -0700286 lg2::error("Failed to crypt_init", "REDFISH_MESSAGE_ID",
287 std::string("OpenBMC.0.1.InitFail"));
288 throw ResourceNotFound();
John Wedigb810c922021-11-17 16:38:03 -0800289 }
290
John Wedig6218dc52021-12-03 09:36:35 -0800291 return cryptDev;
John Wedigb810c922021-11-17 16:38:03 -0800292 }
293
294 /** @brief Free the crypt_device struct
295 *
296 * @param[in] cd - pointer to crypt_device*, to be freed
297 */
298 static void cryptFree(struct crypt_device*&& cd)
299 {
300 crypt_free(cd);
301 }
302
303 /** @brief Managed handle to crypt_device struct */
304 stdplus::Managed<struct crypt_device*>::Handle<cryptFree> handle;
305};
306
307} // namespace estoraged