1b810c926SJohn Wedig #pragma once
2b810c926SJohn Wedig 
3b810c926SJohn Wedig #include <libcryptsetup.h>
4b810c926SJohn Wedig 
52b5454d3SJohn Edward Broadbent #include <phosphor-logging/lg2.hpp>
6b810c926SJohn Wedig #include <stdplus/handle/managed.hpp>
72b5454d3SJohn Edward Broadbent #include <xyz/openbmc_project/Common/error.hpp>
82b5454d3SJohn Edward Broadbent 
92b5454d3SJohn Edward Broadbent #include <string>
10b2c86be3SJohn Edward Broadbent #include <string_view>
11b810c926SJohn Wedig 
12b810c926SJohn Wedig namespace estoraged
13b810c926SJohn Wedig {
14b810c926SJohn Wedig 
152b5454d3SJohn Edward Broadbent using sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound;
162b5454d3SJohn Edward Broadbent 
17b810c926SJohn Wedig /** @class CryptsetupInterface
18b810c926SJohn Wedig  *  @brief Interface to the cryptsetup functions used to manage a LUKS device.
19b810c926SJohn Wedig  *  @details This class is used to mock out the cryptsetup functions.
20b810c926SJohn Wedig  */
21b810c926SJohn Wedig class CryptsetupInterface
22b810c926SJohn Wedig {
23b810c926SJohn Wedig   public:
24b810c926SJohn Wedig     virtual ~CryptsetupInterface() = default;
2582897c35SEd Tanous     CryptsetupInterface() = default;
2682897c35SEd Tanous     CryptsetupInterface(const CryptsetupInterface&) = delete;
2782897c35SEd Tanous     CryptsetupInterface& operator=(const CryptsetupInterface&) = delete;
28b810c926SJohn Wedig 
2982897c35SEd Tanous     CryptsetupInterface(CryptsetupInterface&&) = delete;
3082897c35SEd Tanous     CryptsetupInterface& operator=(CryptsetupInterface&&) = delete;
318d5a3a07SJohn Wedig 
32b810c926SJohn Wedig     /** @brief Wrapper around crypt_format.
33b810c926SJohn Wedig      *  @details Used for mocking purposes.
34b810c926SJohn Wedig      *
35b810c926SJohn Wedig      *  @param[in] cd - crypt device handle.
36b810c926SJohn Wedig      *  @param[in] type - type of device (optional params struct must be of
37b810c926SJohn Wedig      *    this type).
38b810c926SJohn Wedig      *  @param[in] cipher - (e.g. "aes").
39b810c926SJohn Wedig      *  @params[in cipher_mode - including IV specification (e.g. "xts-plain").
40b810c926SJohn Wedig      *  @params[in] uuid - requested UUID or NULL if it should be generated.
41b810c926SJohn Wedig      *  @params[in] volume_key - pre-generated volume key or NULL if it should
42b810c926SJohn Wedig      *    be generated (only for LUKS).
43b810c926SJohn Wedig      *  @params[in] volume_key_size - size of volume key in bytes.
44b810c926SJohn Wedig      *  @params[in] params - crypt type specific parameters.
45b810c926SJohn Wedig      *
46b810c926SJohn Wedig      *  @returns 0 on success or negative errno value otherwise.
47b810c926SJohn Wedig      */
48b810c926SJohn Wedig     virtual int cryptFormat(struct crypt_device* cd, const char* type,
49b810c926SJohn Wedig                             const char* cipher, const char* cipherMode,
50b810c926SJohn Wedig                             const char* uuid, const char* volumeKey,
51b810c926SJohn Wedig                             size_t volumeKeySize, void* params) = 0;
52b810c926SJohn Wedig 
538d5a3a07SJohn Wedig     /** @brief Wrapper around crypt_keyslot_change_by_passphrase.
548d5a3a07SJohn Wedig      *  @details Used for mocking purposes.
558d5a3a07SJohn Wedig      *
568d5a3a07SJohn Wedig      *  @param[in] cd - crypt device handle.
578d5a3a07SJohn Wedig      *  @param[in] keyslotOld - old keyslot or CRYPT_ANY_SLOT.
588d5a3a07SJohn Wedig      *  @param[in] keyslotNew - new keyslot or CRYPT_ANY_SLOT.
598d5a3a07SJohn Wedig      *  @param[in] passphrase - passphrase for new keyslot.
608d5a3a07SJohn Wedig      *  @param[in] passphraseSize - size of passphrase.
618d5a3a07SJohn Wedig      *  @param[in] newPassphrase - new passphrase for the specified keyslot
628d5a3a07SJohn Wedig      *  @param[in] newPassphraseSize - size of newPassphrase (in bytes).
638d5a3a07SJohn Wedig      *
648d5a3a07SJohn Wedig      *  @returns allocated key slot number or negative errno otherwise.
658d5a3a07SJohn Wedig      */
668d5a3a07SJohn Wedig     virtual int cryptKeyslotChangeByPassphrase(struct crypt_device* cd,
678d5a3a07SJohn Wedig                                                int keyslotOld, int keyslotNew,
688d5a3a07SJohn Wedig                                                const char* passphrase,
698d5a3a07SJohn Wedig                                                size_t passphraseSize,
708d5a3a07SJohn Wedig                                                const char* newPassphrase,
718d5a3a07SJohn Wedig                                                size_t newPassphraseSize) = 0;
728d5a3a07SJohn Wedig 
73b810c926SJohn Wedig     /** @brief Wrapper around crypt_keyslot_add_by_volume_key.
74b810c926SJohn Wedig      *  @details Used for mocking purposes.
75b810c926SJohn Wedig      *
76b810c926SJohn Wedig      *  @param[in] cd - crypt device handle.
77b810c926SJohn Wedig      *  @param[in] keyslot - requested keyslot or CRYPT_ANY_SLOT.
78b810c926SJohn Wedig      *  @param[in] volume_key - provided volume key or NULL if used after
79b810c926SJohn Wedig      *    crypt_format.
80b810c926SJohn Wedig      *  @param[in] volume_key_size - size of volume_key.
81b810c926SJohn Wedig      *  @param[in] passphrase - passphrase for new keyslot.
82b810c926SJohn Wedig      *  @param[in] passphrase_size - size of passphrase.
83b810c926SJohn Wedig      *
84b810c926SJohn Wedig      *  @returns allocated key slot number or negative errno otherwise.
85b810c926SJohn Wedig      */
86b810c926SJohn Wedig     virtual int cryptKeyslotAddByVolumeKey(struct crypt_device* cd, int keyslot,
87b810c926SJohn Wedig                                            const char* volumeKey,
88b810c926SJohn Wedig                                            size_t volumeKeySize,
89b810c926SJohn Wedig                                            const char* passphrase,
90b810c926SJohn Wedig                                            size_t passphraseSize) = 0;
91b810c926SJohn Wedig 
92b810c926SJohn Wedig     /** @brief Wrapper around crypt_load.
93b810c926SJohn Wedig      *  @details Used for mocking purposes.
94b810c926SJohn Wedig      *
95b810c926SJohn Wedig      *  @param[in] cd - crypt device handle.
96b810c926SJohn Wedig      *  @param[in] requested_type - crypt-type or NULL for all known.
97b810c926SJohn Wedig      *  @param[in] params - crypt type specific parameters (see crypt-type).
98b810c926SJohn Wedig      *
99b810c926SJohn Wedig      *  @returns 0 on success or negative errno value otherwise.
100b810c926SJohn Wedig      */
101b810c926SJohn Wedig     virtual int cryptLoad(struct crypt_device* cd, const char* requestedType,
102b810c926SJohn Wedig                           void* params) = 0;
103b810c926SJohn Wedig 
104b810c926SJohn Wedig     /** @brief Wrapper around crypt_activate_by_passphrase.
105b810c926SJohn Wedig      *  @details Used for mocking purposes.
106b810c926SJohn Wedig      *
107b810c926SJohn Wedig      *  @param[in] cd - crypt device handle.
108b810c926SJohn Wedig      *  @param[in] name - name of device to create, if NULL only check
109b810c926SJohn Wedig      *    passphrase.
110b810c926SJohn Wedig      *  @param[in] keyslot - requested keyslot to check or CRYPT_ANY_SLOT.
111b810c926SJohn Wedig      *  @param[in] passphrase - passphrase used to unlock volume key.
112b810c926SJohn Wedig      *  @param[in] passphrase_size - size of passphrase.
113b810c926SJohn Wedig      *  @param[in] flags - activation flags.
114b810c926SJohn Wedig      *
115b810c926SJohn Wedig      *  @returns unlocked key slot number or negative errno otherwise.
116b810c926SJohn Wedig      */
117b810c926SJohn Wedig     virtual int cryptActivateByPassphrase(struct crypt_device* cd,
118b810c926SJohn Wedig                                           const char* name, int keyslot,
119b810c926SJohn Wedig                                           const char* passphrase,
120b810c926SJohn Wedig                                           size_t passphraseSize,
121b810c926SJohn Wedig                                           uint32_t flags) = 0;
122b810c926SJohn Wedig 
123b810c926SJohn Wedig     /** @brief Wrapper around crypt_deactivate.
124b810c926SJohn Wedig      *  @details Used for mocking purposes.
125b810c926SJohn Wedig      *
126b810c926SJohn Wedig      *  @param[in] cd - crypt device handle, can be NULL.
127b810c926SJohn Wedig      *  @param[in] name - name of device to deactivate.
128b810c926SJohn Wedig      *
129b810c926SJohn Wedig      *  @returns 0 on success or negative errno value otherwise.
130b810c926SJohn Wedig      */
131b810c926SJohn Wedig     virtual int cryptDeactivate(struct crypt_device* cd, const char* name) = 0;
13259dffa63SJohn Edward Broadbent 
13359dffa63SJohn Edward Broadbent     /** @brief Wrapper around crypt_keyslot_destory.
13459dffa63SJohn Edward Broadbent      *  @details Used for mocking purposes.
13559dffa63SJohn Edward Broadbent      *
13659dffa63SJohn Edward Broadbent      *  @param[in] cd - crypt device handle, can not be NULL.
13759dffa63SJohn Edward Broadbent      *  @param[in] keyslot requested key slot to destroy
13859dffa63SJohn Edward Broadbent      *
13959dffa63SJohn Edward Broadbent      *  @returns 0 on success or negative errno value otherwise.
14059dffa63SJohn Edward Broadbent      */
14182897c35SEd Tanous     virtual int cryptKeyslotDestroy(struct crypt_device* cd, int keyslot) = 0;
14259dffa63SJohn Edward Broadbent 
143*2443a021SJohn Wedig     /** @brief Wrapper around crypt_keyslot_max
14459dffa63SJohn Edward Broadbent      *  @details Used for mocking purposes.
14559dffa63SJohn Edward Broadbent      *
14659dffa63SJohn Edward Broadbent      * @param type crypt device type
14759dffa63SJohn Edward Broadbent      *
14859dffa63SJohn Edward Broadbent      * @return slot count or negative errno otherwise if device
14959dffa63SJohn Edward Broadbent      * does not support keyslots.
15059dffa63SJohn Edward Broadbent      */
15159dffa63SJohn Edward Broadbent     virtual int cryptKeySlotMax(const char* type) = 0;
15259dffa63SJohn Edward Broadbent 
153*2443a021SJohn Wedig     /** @brief Wrapper around crypt_keyslot_status
15459dffa63SJohn Edward Broadbent      *  @details Used for mocking purposes.
15559dffa63SJohn Edward Broadbent      *  Get information about particular key slot.
15659dffa63SJohn Edward Broadbent      *
15759dffa63SJohn Edward Broadbent      * @param cd crypt device handle
15859dffa63SJohn Edward Broadbent      * @param keyslot requested keyslot to check or CRYPT_ANY_SLOT
15959dffa63SJohn Edward Broadbent      *
16059dffa63SJohn Edward Broadbent      * @return value defined by crypt_keyslot_info
16159dffa63SJohn Edward Broadbent      */
16259dffa63SJohn Edward Broadbent     virtual crypt_keyslot_info cryptKeySlotStatus(struct crypt_device* cd,
16359dffa63SJohn Edward Broadbent                                                   int keyslot) = 0;
164*2443a021SJohn Wedig 
165*2443a021SJohn Wedig     /** @brief Wrapper around crypt_get_dir.
166*2443a021SJohn Wedig      *  @details Used for mocking purposes.
167*2443a021SJohn Wedig      *
168*2443a021SJohn Wedig      *  @returns the directory where mapped crypt devices are created.
169*2443a021SJohn Wedig      */
170*2443a021SJohn Wedig     virtual std::string cryptGetDir() = 0;
171b810c926SJohn Wedig };
172b810c926SJohn Wedig 
173b810c926SJohn Wedig /** @class Cryptsetup
174b810c926SJohn Wedig  *  @brief Implements CryptsetupInterface.
175b810c926SJohn Wedig  */
176b810c926SJohn Wedig class Cryptsetup : public CryptsetupInterface
177b810c926SJohn Wedig {
178b810c926SJohn Wedig   public:
17982897c35SEd Tanous     ~Cryptsetup() override = default;
180b810c926SJohn Wedig 
18182897c35SEd Tanous     Cryptsetup() = default;
18282897c35SEd Tanous     Cryptsetup(const Cryptsetup&) = delete;
18382897c35SEd Tanous     Cryptsetup& operator=(const Cryptsetup&) = delete;
18482897c35SEd Tanous 
18582897c35SEd Tanous     Cryptsetup(Cryptsetup&&) = delete;
18682897c35SEd Tanous     Cryptsetup& operator=(Cryptsetup&&) = delete;
cryptFormat(struct crypt_device * cd,const char * type,const char * cipher,const char * cipherMode,const char * uuid,const char * volumeKey,size_t volumeKeySize,void * params)187b810c926SJohn Wedig     int cryptFormat(struct crypt_device* cd, const char* type,
188b810c926SJohn Wedig                     const char* cipher, const char* cipherMode,
189b810c926SJohn Wedig                     const char* uuid, const char* volumeKey,
190b810c926SJohn Wedig                     size_t volumeKeySize, void* params) override
191b810c926SJohn Wedig     {
192b810c926SJohn Wedig         return crypt_format(cd, type, cipher, cipherMode, uuid, volumeKey,
193b810c926SJohn Wedig                             volumeKeySize, params);
194b810c926SJohn Wedig     }
195b810c926SJohn Wedig 
cryptKeyslotChangeByPassphrase(struct crypt_device * cd,int keyslotOld,int keyslotNew,const char * passphrase,size_t passphraseSize,const char * newPassphrase,size_t newPassphraseSize)1968d5a3a07SJohn Wedig     int cryptKeyslotChangeByPassphrase(struct crypt_device* cd, int keyslotOld,
1978d5a3a07SJohn Wedig                                        int keyslotNew, const char* passphrase,
1988d5a3a07SJohn Wedig                                        size_t passphraseSize,
1998d5a3a07SJohn Wedig                                        const char* newPassphrase,
2008d5a3a07SJohn Wedig                                        size_t newPassphraseSize) override
2018d5a3a07SJohn Wedig     {
2028d5a3a07SJohn Wedig         return crypt_keyslot_change_by_passphrase(
2038d5a3a07SJohn Wedig             cd, keyslotOld, keyslotNew, passphrase, passphraseSize,
2048d5a3a07SJohn Wedig             newPassphrase, newPassphraseSize);
2058d5a3a07SJohn Wedig     }
2068d5a3a07SJohn Wedig 
cryptKeyslotAddByVolumeKey(struct crypt_device * cd,int keyslot,const char * volumeKey,size_t volumeKeySize,const char * passphrase,size_t passphraseSize)207b810c926SJohn Wedig     int cryptKeyslotAddByVolumeKey(struct crypt_device* cd, int keyslot,
208b810c926SJohn Wedig                                    const char* volumeKey, size_t volumeKeySize,
209b810c926SJohn Wedig                                    const char* passphrase,
210b810c926SJohn Wedig                                    size_t passphraseSize) override
211b810c926SJohn Wedig     {
212b810c926SJohn Wedig         return crypt_keyslot_add_by_volume_key(
213b810c926SJohn Wedig             cd, keyslot, volumeKey, volumeKeySize, passphrase, passphraseSize);
214b810c926SJohn Wedig     }
215b810c926SJohn Wedig 
cryptLoad(struct crypt_device * cd,const char * requestedType,void * params)216b810c926SJohn Wedig     int cryptLoad(struct crypt_device* cd, const char* requestedType,
217b810c926SJohn Wedig                   void* params) override
218b810c926SJohn Wedig     {
219b810c926SJohn Wedig         return crypt_load(cd, requestedType, params);
220b810c926SJohn Wedig     }
221b810c926SJohn Wedig 
cryptActivateByPassphrase(struct crypt_device * cd,const char * name,int keyslot,const char * passphrase,size_t passphraseSize,uint32_t flags)222b810c926SJohn Wedig     int cryptActivateByPassphrase(struct crypt_device* cd, const char* name,
223b810c926SJohn Wedig                                   int keyslot, const char* passphrase,
224b810c926SJohn Wedig                                   size_t passphraseSize,
225b810c926SJohn Wedig                                   uint32_t flags) override
226b810c926SJohn Wedig     {
227b810c926SJohn Wedig         return crypt_activate_by_passphrase(cd, name, keyslot, passphrase,
228b810c926SJohn Wedig                                             passphraseSize, flags);
229b810c926SJohn Wedig     }
230b810c926SJohn Wedig 
cryptDeactivate(struct crypt_device * cd,const char * name)231b810c926SJohn Wedig     int cryptDeactivate(struct crypt_device* cd, const char* name) override
232b810c926SJohn Wedig     {
233b810c926SJohn Wedig         return crypt_deactivate(cd, name);
234b810c926SJohn Wedig     }
23559dffa63SJohn Edward Broadbent 
cryptKeyslotDestroy(struct crypt_device * cd,const int keyslot)23659dffa63SJohn Edward Broadbent     int cryptKeyslotDestroy(struct crypt_device* cd, const int keyslot) override
23759dffa63SJohn Edward Broadbent     {
23859dffa63SJohn Edward Broadbent         return crypt_keyslot_destroy(cd, keyslot);
23959dffa63SJohn Edward Broadbent     }
24059dffa63SJohn Edward Broadbent 
cryptKeySlotMax(const char * type)24159dffa63SJohn Edward Broadbent     int cryptKeySlotMax(const char* type) override
24259dffa63SJohn Edward Broadbent     {
24359dffa63SJohn Edward Broadbent         return crypt_keyslot_max(type);
24459dffa63SJohn Edward Broadbent     }
24559dffa63SJohn Edward Broadbent 
cryptKeySlotStatus(struct crypt_device * cd,int keyslot)24659dffa63SJohn Edward Broadbent     crypt_keyslot_info cryptKeySlotStatus(struct crypt_device* cd,
24759dffa63SJohn Edward Broadbent                                           int keyslot) override
24859dffa63SJohn Edward Broadbent     {
24959dffa63SJohn Edward Broadbent         return crypt_keyslot_status(cd, keyslot);
25059dffa63SJohn Edward Broadbent     }
251*2443a021SJohn Wedig 
cryptGetDir()252*2443a021SJohn Wedig     std::string cryptGetDir() override
253*2443a021SJohn Wedig     {
254*2443a021SJohn Wedig         return {crypt_get_dir()};
255*2443a021SJohn Wedig     }
256b810c926SJohn Wedig };
257b810c926SJohn Wedig 
258b810c926SJohn Wedig /** @class CryptHandle
259b810c926SJohn Wedig  *  @brief This manages a crypt_device struct and automatically frees it when
260b810c926SJohn Wedig  *  this handle exits the current scope.
261b810c926SJohn Wedig  */
262b810c926SJohn Wedig class CryptHandle
263b810c926SJohn Wedig {
264b810c926SJohn Wedig   public:
265b810c926SJohn Wedig     /** @brief Constructor for CryptHandle
266b810c926SJohn Wedig      *
267b810c926SJohn Wedig      *  @param[in] device - path to device file
268b810c926SJohn Wedig      */
CryptHandle(const std::string_view & device)269b2c86be3SJohn Edward Broadbent     explicit CryptHandle(const std::string_view& device) : handle(init(device))
270b810c926SJohn Wedig     {}
271b810c926SJohn Wedig 
2726218dc5dSJohn Wedig     /** @brief Get a pointer to the crypt_device struct. */
get()2736218dc5dSJohn Wedig     struct crypt_device* get()
2746218dc5dSJohn Wedig     {
2752b5454d3SJohn Edward Broadbent         if (*handle == nullptr)
2762b5454d3SJohn Edward Broadbent         {
2772b5454d3SJohn Edward Broadbent             lg2::error("Failed to get crypt device handle",
2782b5454d3SJohn Edward Broadbent                        "REDFISH_MESSAGE_ID",
2792b5454d3SJohn Edward Broadbent                        std::string("OpenBMC.0.1.HandleGetFail"));
2802b5454d3SJohn Edward Broadbent             throw ResourceNotFound();
2812b5454d3SJohn Edward Broadbent         }
2822b5454d3SJohn Edward Broadbent 
2836218dc5dSJohn Wedig         return *handle;
2846218dc5dSJohn Wedig     }
2856218dc5dSJohn Wedig 
2866218dc5dSJohn Wedig   private:
287b810c926SJohn Wedig     /** @brief Allocate and initialize the crypt_device struct
288b810c926SJohn Wedig      *
289b810c926SJohn Wedig      *  @param[in] device - path to device file
290b810c926SJohn Wedig      */
init(const std::string_view & device)291b2c86be3SJohn Edward Broadbent     struct crypt_device* init(const std::string_view& device)
292b810c926SJohn Wedig     {
29382897c35SEd Tanous         struct crypt_device* cryptDev = nullptr;
294b2c86be3SJohn Edward Broadbent         int retval = crypt_init(&cryptDev, device.data());
295b810c926SJohn Wedig         if (retval < 0)
296b810c926SJohn Wedig         {
29728cc834cSJohn Edward Broadbent             lg2::error("Failed to crypt_init", "REDFISH_MESSAGE_ID",
29828cc834cSJohn Edward Broadbent                        std::string("OpenBMC.0.1.InitFail"));
29928cc834cSJohn Edward Broadbent             throw ResourceNotFound();
300b810c926SJohn Wedig         }
301b810c926SJohn Wedig 
3026218dc5dSJohn Wedig         return cryptDev;
303b810c926SJohn Wedig     }
304b810c926SJohn Wedig 
305b810c926SJohn Wedig     /** @brief Free the crypt_device struct
306b810c926SJohn Wedig      *
307b810c926SJohn Wedig      *  @param[in] cd - pointer to crypt_device*, to be freed
308b810c926SJohn Wedig      */
cryptFree(struct crypt_device * && cd)309b810c926SJohn Wedig     static void cryptFree(struct crypt_device*&& cd)
310b810c926SJohn Wedig     {
311b810c926SJohn Wedig         crypt_free(cd);
312b810c926SJohn Wedig     }
313b810c926SJohn Wedig 
314b810c926SJohn Wedig     /** @brief Managed handle to crypt_device struct */
315b810c926SJohn Wedig     stdplus::Managed<struct crypt_device*>::Handle<cryptFree> handle;
316b810c926SJohn Wedig };
317b810c926SJohn Wedig 
318b810c926SJohn Wedig } // namespace estoraged
319