blob: 719e98bdfa08072e9d09ff28275420d89c54d5d6 [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 Wedigb810c922021-11-17 16:38:03 -080010
11namespace estoraged
12{
13
John Edward Broadbent2b5454d2022-04-14 19:28:12 -070014using sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound;
15
John Wedigb810c922021-11-17 16:38:03 -080016/** @class CryptsetupInterface
17 * @brief Interface to the cryptsetup functions used to manage a LUKS device.
18 * @details This class is used to mock out the cryptsetup functions.
19 */
20class CryptsetupInterface
21{
22 public:
23 virtual ~CryptsetupInterface() = default;
Ed Tanous82897c32022-02-21 14:11:59 -080024 CryptsetupInterface() = default;
25 CryptsetupInterface(const CryptsetupInterface&) = delete;
26 CryptsetupInterface& operator=(const CryptsetupInterface&) = delete;
John Wedigb810c922021-11-17 16:38:03 -080027
Ed Tanous82897c32022-02-21 14:11:59 -080028 CryptsetupInterface(CryptsetupInterface&&) = delete;
29 CryptsetupInterface& operator=(CryptsetupInterface&&) = delete;
John Wedigb810c922021-11-17 16:38:03 -080030 /** @brief Wrapper around crypt_format.
31 * @details Used for mocking purposes.
32 *
33 * @param[in] cd - crypt device handle.
34 * @param[in] type - type of device (optional params struct must be of
35 * this type).
36 * @param[in] cipher - (e.g. "aes").
37 * @params[in cipher_mode - including IV specification (e.g. "xts-plain").
38 * @params[in] uuid - requested UUID or NULL if it should be generated.
39 * @params[in] volume_key - pre-generated volume key or NULL if it should
40 * be generated (only for LUKS).
41 * @params[in] volume_key_size - size of volume key in bytes.
42 * @params[in] params - crypt type specific parameters.
43 *
44 * @returns 0 on success or negative errno value otherwise.
45 */
46 virtual int cryptFormat(struct crypt_device* cd, const char* type,
47 const char* cipher, const char* cipherMode,
48 const char* uuid, const char* volumeKey,
49 size_t volumeKeySize, void* params) = 0;
50
51 /** @brief Wrapper around crypt_keyslot_add_by_volume_key.
52 * @details Used for mocking purposes.
53 *
54 * @param[in] cd - crypt device handle.
55 * @param[in] keyslot - requested keyslot or CRYPT_ANY_SLOT.
56 * @param[in] volume_key - provided volume key or NULL if used after
57 * crypt_format.
58 * @param[in] volume_key_size - size of volume_key.
59 * @param[in] passphrase - passphrase for new keyslot.
60 * @param[in] passphrase_size - size of passphrase.
61 *
62 * @returns allocated key slot number or negative errno otherwise.
63 */
64 virtual int cryptKeyslotAddByVolumeKey(struct crypt_device* cd, int keyslot,
65 const char* volumeKey,
66 size_t volumeKeySize,
67 const char* passphrase,
68 size_t passphraseSize) = 0;
69
70 /** @brief Wrapper around crypt_load.
71 * @details Used for mocking purposes.
72 *
73 * @param[in] cd - crypt device handle.
74 * @param[in] requested_type - crypt-type or NULL for all known.
75 * @param[in] params - crypt type specific parameters (see crypt-type).
76 *
77 * @returns 0 on success or negative errno value otherwise.
78 */
79 virtual int cryptLoad(struct crypt_device* cd, const char* requestedType,
80 void* params) = 0;
81
82 /** @brief Wrapper around crypt_activate_by_passphrase.
83 * @details Used for mocking purposes.
84 *
85 * @param[in] cd - crypt device handle.
86 * @param[in] name - name of device to create, if NULL only check
87 * passphrase.
88 * @param[in] keyslot - requested keyslot to check or CRYPT_ANY_SLOT.
89 * @param[in] passphrase - passphrase used to unlock volume key.
90 * @param[in] passphrase_size - size of passphrase.
91 * @param[in] flags - activation flags.
92 *
93 * @returns unlocked key slot number or negative errno otherwise.
94 */
95 virtual int cryptActivateByPassphrase(struct crypt_device* cd,
96 const char* name, int keyslot,
97 const char* passphrase,
98 size_t passphraseSize,
99 uint32_t flags) = 0;
100
101 /** @brief Wrapper around crypt_deactivate.
102 * @details Used for mocking purposes.
103 *
104 * @param[in] cd - crypt device handle, can be NULL.
105 * @param[in] name - name of device to deactivate.
106 *
107 * @returns 0 on success or negative errno value otherwise.
108 */
109 virtual int cryptDeactivate(struct crypt_device* cd, const char* name) = 0;
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800110
111 /** @brief Wrapper around crypt_keyslot_destory.
112 * @details Used for mocking purposes.
113 *
114 * @param[in] cd - crypt device handle, can not be NULL.
115 * @param[in] keyslot requested key slot to destroy
116 *
117 * @returns 0 on success or negative errno value otherwise.
118 */
Ed Tanous82897c32022-02-21 14:11:59 -0800119 virtual int cryptKeyslotDestroy(struct crypt_device* cd, int keyslot) = 0;
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800120
121 /** @breif Wapper around crypt_keyslot_max
122 * @details Used for mocking purposes.
123 *
124 * @param type crypt device type
125 *
126 * @return slot count or negative errno otherwise if device
127 * does not support keyslots.
128 */
129 virtual int cryptKeySlotMax(const char* type) = 0;
130
131 /** @breif Wapper around crypt_keyslot_status
132 * @details Used for mocking purposes.
133 * Get information about particular key slot.
134 *
135 * @param cd crypt device handle
136 * @param keyslot requested keyslot to check or CRYPT_ANY_SLOT
137 *
138 * @return value defined by crypt_keyslot_info
139 *
140 */
141 virtual crypt_keyslot_info cryptKeySlotStatus(struct crypt_device* cd,
142 int keyslot) = 0;
John Wedigb810c922021-11-17 16:38:03 -0800143};
144
145/** @class Cryptsetup
146 * @brief Implements CryptsetupInterface.
147 */
148class Cryptsetup : public CryptsetupInterface
149{
150 public:
Ed Tanous82897c32022-02-21 14:11:59 -0800151 ~Cryptsetup() override = default;
John Wedigb810c922021-11-17 16:38:03 -0800152
Ed Tanous82897c32022-02-21 14:11:59 -0800153 Cryptsetup() = default;
154 Cryptsetup(const Cryptsetup&) = delete;
155 Cryptsetup& operator=(const Cryptsetup&) = delete;
156
157 Cryptsetup(Cryptsetup&&) = delete;
158 Cryptsetup& operator=(Cryptsetup&&) = delete;
John Wedigb810c922021-11-17 16:38:03 -0800159 int cryptFormat(struct crypt_device* cd, const char* type,
160 const char* cipher, const char* cipherMode,
161 const char* uuid, const char* volumeKey,
162 size_t volumeKeySize, void* params) override
163 {
164 return crypt_format(cd, type, cipher, cipherMode, uuid, volumeKey,
165 volumeKeySize, params);
166 }
167
168 int cryptKeyslotAddByVolumeKey(struct crypt_device* cd, int keyslot,
169 const char* volumeKey, size_t volumeKeySize,
170 const char* passphrase,
171 size_t passphraseSize) override
172 {
173 return crypt_keyslot_add_by_volume_key(
174 cd, keyslot, volumeKey, volumeKeySize, passphrase, passphraseSize);
175 }
176
177 int cryptLoad(struct crypt_device* cd, const char* requestedType,
178 void* params) override
179 {
180 return crypt_load(cd, requestedType, params);
181 }
182
183 int cryptActivateByPassphrase(struct crypt_device* cd, const char* name,
184 int keyslot, const char* passphrase,
185 size_t passphraseSize,
186 uint32_t flags) override
187 {
188 return crypt_activate_by_passphrase(cd, name, keyslot, passphrase,
189 passphraseSize, flags);
190 }
191
192 int cryptDeactivate(struct crypt_device* cd, const char* name) override
193 {
194 return crypt_deactivate(cd, name);
195 }
John Edward Broadbent59dffa62022-01-13 17:41:32 -0800196
197 int cryptKeyslotDestroy(struct crypt_device* cd, const int keyslot) override
198 {
199 return crypt_keyslot_destroy(cd, keyslot);
200 }
201
202 int cryptKeySlotMax(const char* type) override
203 {
204 return crypt_keyslot_max(type);
205 }
206
207 crypt_keyslot_info cryptKeySlotStatus(struct crypt_device* cd,
208 int keyslot) override
209 {
210 return crypt_keyslot_status(cd, keyslot);
211 }
John Wedigb810c922021-11-17 16:38:03 -0800212};
213
214/** @class CryptHandle
215 * @brief This manages a crypt_device struct and automatically frees it when
216 * this handle exits the current scope.
217 */
218class CryptHandle
219{
220 public:
221 /** @brief Constructor for CryptHandle
222 *
John Wedigb810c922021-11-17 16:38:03 -0800223 * @param[in] device - path to device file
224 */
John Wedig6218dc52021-12-03 09:36:35 -0800225 explicit CryptHandle(const char* device) : handle(init(device))
John Wedigb810c922021-11-17 16:38:03 -0800226 {}
227
John Wedig6218dc52021-12-03 09:36:35 -0800228 /** @brief Get a pointer to the crypt_device struct. */
229 struct crypt_device* get()
230 {
John Edward Broadbent2b5454d2022-04-14 19:28:12 -0700231 if (*handle == nullptr)
232 {
233 lg2::error("Failed to get crypt device handle",
234 "REDFISH_MESSAGE_ID",
235 std::string("OpenBMC.0.1.HandleGetFail"));
236 throw ResourceNotFound();
237 }
238
John Wedig6218dc52021-12-03 09:36:35 -0800239 return *handle;
240 }
241
242 private:
John Wedigb810c922021-11-17 16:38:03 -0800243 /** @brief Allocate and initialize the crypt_device struct
244 *
John Wedigb810c922021-11-17 16:38:03 -0800245 * @param[in] device - path to device file
246 */
John Wedig6218dc52021-12-03 09:36:35 -0800247 struct crypt_device* init(const char* device)
John Wedigb810c922021-11-17 16:38:03 -0800248 {
Ed Tanous82897c32022-02-21 14:11:59 -0800249 struct crypt_device* cryptDev = nullptr;
John Wedig6218dc52021-12-03 09:36:35 -0800250 int retval = crypt_init(&cryptDev, device);
John Wedigb810c922021-11-17 16:38:03 -0800251 if (retval < 0)
252 {
253 return nullptr;
254 }
255
John Wedig6218dc52021-12-03 09:36:35 -0800256 return cryptDev;
John Wedigb810c922021-11-17 16:38:03 -0800257 }
258
259 /** @brief Free the crypt_device struct
260 *
261 * @param[in] cd - pointer to crypt_device*, to be freed
262 */
263 static void cryptFree(struct crypt_device*&& cd)
264 {
265 crypt_free(cd);
266 }
267
268 /** @brief Managed handle to crypt_device struct */
269 stdplus::Managed<struct crypt_device*>::Handle<cryptFree> handle;
270};
271
272} // namespace estoraged