xref: /openbmc/estoraged/include/cryptsetupInterface.hpp (revision e6ffe7040eb28d8ea2a242177d2780516b6f5cf0)
1 #pragma once
2 
3 #include <libcryptsetup.h>
4 
5 #include <stdplus/handle/managed.hpp>
6 
7 namespace 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  */
14 class 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  */
104 class 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  */
152 class CryptHandle
153 {
154   public:
155     /** @brief Constructor for CryptHandle
156      *
157      *  @param[out] cd - pointer to crypt_device*, to be allocated
158      *  @param[in] device - path to device file
159      */
160     CryptHandle(struct crypt_device** cd, const char* device) :
161         handle(init(cd, device))
162     {}
163 
164     /** @brief Allocate and initialize the crypt_device struct
165      *
166      *  @param[out] cd - pointer to crypt_device*, to be allocated
167      *  @param[in] device - path to device file
168      */
169     struct crypt_device* init(struct crypt_device** cd, const char* device)
170     {
171         int retval = crypt_init(cd, device);
172         if (retval < 0)
173         {
174             return nullptr;
175         }
176 
177         return *cd;
178     }
179 
180     /** @brief Free the crypt_device struct
181      *
182      *  @param[in] cd - pointer to crypt_device*, to be freed
183      */
184     static void cryptFree(struct crypt_device*&& cd)
185     {
186         crypt_free(cd);
187     }
188 
189     /** @brief Managed handle to crypt_device struct */
190     stdplus::Managed<struct crypt_device*>::Handle<cryptFree> handle;
191 };
192 
193 } // namespace estoraged
194