xref: /openbmc/qemu/include/crypto/block.h (revision 2ba60ec1)
1 /*
2  * QEMU Crypto block device encryption
3  *
4  * Copyright (c) 2015-2016 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #ifndef QCRYPTO_BLOCK_H
22 #define QCRYPTO_BLOCK_H
23 
24 #include "crypto/cipher.h"
25 #include "crypto/ivgen.h"
26 
27 typedef struct QCryptoBlock QCryptoBlock;
28 
29 /* See also QCryptoBlockFormat, QCryptoBlockCreateOptions
30  * and QCryptoBlockOpenOptions in qapi/crypto.json */
31 
32 typedef ssize_t (*QCryptoBlockReadFunc)(QCryptoBlock *block,
33                                         size_t offset,
34                                         uint8_t *buf,
35                                         size_t buflen,
36                                         void *opaque,
37                                         Error **errp);
38 
39 typedef ssize_t (*QCryptoBlockInitFunc)(QCryptoBlock *block,
40                                         size_t headerlen,
41                                         void *opaque,
42                                         Error **errp);
43 
44 typedef ssize_t (*QCryptoBlockWriteFunc)(QCryptoBlock *block,
45                                          size_t offset,
46                                          const uint8_t *buf,
47                                          size_t buflen,
48                                          void *opaque,
49                                          Error **errp);
50 
51 /**
52  * qcrypto_block_has_format:
53  * @format: the encryption format
54  * @buf: the data from head of the volume
55  * @len: the length of @buf in bytes
56  *
57  * Given @len bytes of data from the head of a storage volume
58  * in @buf, probe to determine if the volume has the encryption
59  * format specified in @format.
60  *
61  * Returns: true if the data in @buf matches @format
62  */
63 bool qcrypto_block_has_format(QCryptoBlockFormat format,
64                               const uint8_t *buf,
65                               size_t buflen);
66 
67 typedef enum {
68     QCRYPTO_BLOCK_OPEN_NO_IO = (1 << 0),
69 } QCryptoBlockOpenFlags;
70 
71 /**
72  * qcrypto_block_open:
73  * @options: the encryption options
74  * @optprefix: name prefix for options
75  * @readfunc: callback for reading data from the volume
76  * @opaque: data to pass to @readfunc
77  * @flags: bitmask of QCryptoBlockOpenFlags values
78  * @errp: pointer to a NULL-initialized error object
79  *
80  * Create a new block encryption object for an existing
81  * storage volume encrypted with format identified by
82  * the parameters in @options.
83  *
84  * This will use @readfunc to initialize the encryption
85  * context based on the volume header(s), extracting the
86  * master key(s) as required.
87  *
88  * If @flags contains QCRYPTO_BLOCK_OPEN_NO_IO then
89  * the open process will be optimized to skip any parts
90  * that are only required to perform I/O. In particular
91  * this would usually avoid the need to decrypt any
92  * master keys. The only thing that can be done with
93  * the resulting QCryptoBlock object would be to query
94  * metadata such as the payload offset. There will be
95  * no cipher or ivgen objects available.
96  *
97  * If any part of initializing the encryption context
98  * fails an error will be returned. This could be due
99  * to the volume being in the wrong format, a cipher
100  * or IV generator algorithm that is not supported,
101  * or incorrect passphrases.
102  *
103  * Returns: a block encryption format, or NULL on error
104  */
105 QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
106                                  const char *optprefix,
107                                  QCryptoBlockReadFunc readfunc,
108                                  void *opaque,
109                                  unsigned int flags,
110                                  Error **errp);
111 
112 /**
113  * qcrypto_block_create:
114  * @options: the encryption options
115  * @optprefix: name prefix for options
116  * @initfunc: callback for initializing volume header
117  * @writefunc: callback for writing data to the volume header
118  * @opaque: data to pass to @initfunc and @writefunc
119  * @errp: pointer to a NULL-initialized error object
120  *
121  * Create a new block encryption object for initializing
122  * a storage volume to be encrypted with format identified
123  * by the parameters in @options.
124  *
125  * This method will allocate space for a new volume header
126  * using @initfunc and then write header data using @writefunc,
127  * generating new master keys, etc as required. Any existing
128  * data present on the volume will be irrevocably destroyed.
129  *
130  * If any part of initializing the encryption context
131  * fails an error will be returned. This could be due
132  * to the volume being in the wrong format, a cipher
133  * or IV generator algorithm that is not supported,
134  * or incorrect passphrases.
135  *
136  * Returns: a block encryption format, or NULL on error
137  */
138 QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
139                                    const char *optprefix,
140                                    QCryptoBlockInitFunc initfunc,
141                                    QCryptoBlockWriteFunc writefunc,
142                                    void *opaque,
143                                    Error **errp);
144 
145 
146 /**
147  * qcrypto_block_get_info:
148  * @block: the block encryption object
149  * @errp: pointer to a NULL-initialized error object
150  *
151  * Get information about the configuration options for the
152  * block encryption object. This includes details such as
153  * the cipher algorithms, modes, and initialization vector
154  * generators.
155  *
156  * Returns: a block encryption info object, or NULL on error
157  */
158 QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block,
159                                          Error **errp);
160 
161 /**
162  * @qcrypto_block_decrypt:
163  * @block: the block encryption object
164  * @offset: the position at which @iov was read
165  * @buf: the buffer to decrypt
166  * @len: the length of @buf in bytes
167  * @errp: pointer to a NULL-initialized error object
168  *
169  * Decrypt @len bytes of cipher text in @buf, writing
170  * plain text back into @buf. @len and @offset must be
171  * a multiple of the encryption format sector size.
172  *
173  * Returns 0 on success, -1 on failure
174  */
175 int qcrypto_block_decrypt(QCryptoBlock *block,
176                           uint64_t offset,
177                           uint8_t *buf,
178                           size_t len,
179                           Error **errp);
180 
181 /**
182  * @qcrypto_block_encrypt:
183  * @block: the block encryption object
184  * @offset: the position at which @iov will be written
185  * @buf: the buffer to decrypt
186  * @len: the length of @buf in bytes
187  * @errp: pointer to a NULL-initialized error object
188  *
189  * Encrypt @len bytes of plain text in @buf, writing
190  * cipher text back into @buf. @len and @offset must be
191  * a multiple of the encryption format sector size.
192  *
193  * Returns 0 on success, -1 on failure
194  */
195 int qcrypto_block_encrypt(QCryptoBlock *block,
196                           uint64_t offset,
197                           uint8_t *buf,
198                           size_t len,
199                           Error **errp);
200 
201 /**
202  * qcrypto_block_get_cipher:
203  * @block: the block encryption object
204  *
205  * Get the cipher to use for payload encryption
206  *
207  * Returns: the cipher object
208  */
209 QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block);
210 
211 /**
212  * qcrypto_block_get_ivgen:
213  * @block: the block encryption object
214  *
215  * Get the initialization vector generator to use for
216  * payload encryption
217  *
218  * Returns: the IV generator object
219  */
220 QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block);
221 
222 
223 /**
224  * qcrypto_block_get_kdf_hash:
225  * @block: the block encryption object
226  *
227  * Get the hash algorithm used with the key derivation
228  * function
229  *
230  * Returns: the hash algorithm
231  */
232 QCryptoHashAlgorithm qcrypto_block_get_kdf_hash(QCryptoBlock *block);
233 
234 /**
235  * qcrypto_block_get_payload_offset:
236  * @block: the block encryption object
237  *
238  * Get the offset to the payload indicated by the
239  * encryption header, in bytes.
240  *
241  * Returns: the payload offset in bytes
242  */
243 uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block);
244 
245 /**
246  * qcrypto_block_get_sector_size:
247  * @block: the block encryption object
248  *
249  * Get the size of sectors used for payload encryption. A new
250  * IV is used at the start of each sector. The encryption
251  * sector size is not required to match the sector size of the
252  * underlying storage. For example LUKS will always use a 512
253  * byte sector size, even if the volume is on a disk with 4k
254  * sectors.
255  *
256  * Returns: the sector in bytes
257  */
258 uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block);
259 
260 /**
261  * qcrypto_block_free:
262  * @block: the block encryption object
263  *
264  * Release all resources associated with the encryption
265  * object
266  */
267 void qcrypto_block_free(QCryptoBlock *block);
268 
269 #endif /* QCRYPTO_BLOCK_H */
270