2 * QEMU Crypto block device encryption
4 * Copyright (c) 2015-2016 Red Hat, Inc.
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.1 of the License, or (at your option) any later version.
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.
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/>.
21 #include "qemu/osdep.h"
22 #include "qapi/error.h"
23 #include "blockpriv.h"
24 #include "block-qcow.h"
25 #include "block-luks.h"
27 static const QCryptoBlockDriver
*qcrypto_block_drivers
[] = {
28 [Q_CRYPTO_BLOCK_FORMAT_QCOW
] = &qcrypto_block_driver_qcow
,
29 [Q_CRYPTO_BLOCK_FORMAT_LUKS
] = &qcrypto_block_driver_luks
,
33 bool qcrypto_block_has_format(QCryptoBlockFormat format
,
37 const QCryptoBlockDriver
*driver
;
39 if (format
>= G_N_ELEMENTS(qcrypto_block_drivers
) ||
40 !qcrypto_block_drivers
[format
]) {
44 driver
= qcrypto_block_drivers
[format
];
46 return driver
->has_format(buf
, len
);
50 QCryptoBlock
*qcrypto_block_open(QCryptoBlockOpenOptions
*options
,
51 const char *optprefix
,
52 QCryptoBlockReadFunc readfunc
,
58 QCryptoBlock
*block
= g_new0(QCryptoBlock
, 1);
60 block
->format
= options
->format
;
62 if (options
->format
>= G_N_ELEMENTS(qcrypto_block_drivers
) ||
63 !qcrypto_block_drivers
[options
->format
]) {
64 error_setg(errp
, "Unsupported block driver %s",
65 QCryptoBlockFormat_str(options
->format
));
70 block
->driver
= qcrypto_block_drivers
[options
->format
];
72 if (block
->driver
->open(block
, options
, optprefix
,
73 readfunc
, opaque
, flags
, n_threads
, errp
) < 0)
79 qemu_mutex_init(&block
->mutex
);
85 QCryptoBlock
*qcrypto_block_create(QCryptoBlockCreateOptions
*options
,
86 const char *optprefix
,
87 QCryptoBlockInitFunc initfunc
,
88 QCryptoBlockWriteFunc writefunc
,
92 QCryptoBlock
*block
= g_new0(QCryptoBlock
, 1);
94 block
->format
= options
->format
;
96 if (options
->format
>= G_N_ELEMENTS(qcrypto_block_drivers
) ||
97 !qcrypto_block_drivers
[options
->format
]) {
98 error_setg(errp
, "Unsupported block driver %s",
99 QCryptoBlockFormat_str(options
->format
));
104 block
->driver
= qcrypto_block_drivers
[options
->format
];
106 if (block
->driver
->create(block
, options
, optprefix
, initfunc
,
107 writefunc
, opaque
, errp
) < 0) {
112 qemu_mutex_init(&block
->mutex
);
118 QCryptoBlockInfo
*qcrypto_block_get_info(QCryptoBlock
*block
,
121 QCryptoBlockInfo
*info
= g_new0(QCryptoBlockInfo
, 1);
123 info
->format
= block
->format
;
125 if (block
->driver
->get_info
&&
126 block
->driver
->get_info(block
, info
, errp
) < 0) {
135 int qcrypto_block_decrypt(QCryptoBlock
*block
,
141 return block
->driver
->decrypt(block
, offset
, buf
, len
, errp
);
145 int qcrypto_block_encrypt(QCryptoBlock
*block
,
151 return block
->driver
->encrypt(block
, offset
, buf
, len
, errp
);
155 QCryptoCipher
*qcrypto_block_get_cipher(QCryptoBlock
*block
)
157 /* Ciphers should be accessed through pop/push method to be thread-safe.
158 * Better, they should not be accessed externally at all (note, that
159 * pop/push are static functions)
160 * This function is used only in test with one thread (it's safe to skip
161 * pop/push interface), so it's enough to assert it here:
163 assert(block
->n_ciphers
<= 1);
164 return block
->ciphers
? block
->ciphers
[0] : NULL
;
168 static QCryptoCipher
*qcrypto_block_pop_cipher(QCryptoBlock
*block
)
170 QCryptoCipher
*cipher
;
172 qemu_mutex_lock(&block
->mutex
);
174 assert(block
->n_free_ciphers
> 0);
175 block
->n_free_ciphers
--;
176 cipher
= block
->ciphers
[block
->n_free_ciphers
];
178 qemu_mutex_unlock(&block
->mutex
);
184 static void qcrypto_block_push_cipher(QCryptoBlock
*block
,
185 QCryptoCipher
*cipher
)
187 qemu_mutex_lock(&block
->mutex
);
189 assert(block
->n_free_ciphers
< block
->n_ciphers
);
190 block
->ciphers
[block
->n_free_ciphers
] = cipher
;
191 block
->n_free_ciphers
++;
193 qemu_mutex_unlock(&block
->mutex
);
197 int qcrypto_block_init_cipher(QCryptoBlock
*block
,
198 QCryptoCipherAlgorithm alg
,
199 QCryptoCipherMode mode
,
200 const uint8_t *key
, size_t nkey
,
201 size_t n_threads
, Error
**errp
)
205 assert(!block
->ciphers
&& !block
->n_ciphers
&& !block
->n_free_ciphers
);
207 block
->ciphers
= g_new0(QCryptoCipher
*, n_threads
);
209 for (i
= 0; i
< n_threads
; i
++) {
210 block
->ciphers
[i
] = qcrypto_cipher_new(alg
, mode
, key
, nkey
, errp
);
211 if (!block
->ciphers
[i
]) {
212 qcrypto_block_free_cipher(block
);
216 block
->n_free_ciphers
++;
223 void qcrypto_block_free_cipher(QCryptoBlock
*block
)
227 if (!block
->ciphers
) {
231 assert(block
->n_ciphers
== block
->n_free_ciphers
);
233 for (i
= 0; i
< block
->n_ciphers
; i
++) {
234 qcrypto_cipher_free(block
->ciphers
[i
]);
237 g_free(block
->ciphers
);
238 block
->ciphers
= NULL
;
239 block
->n_ciphers
= block
->n_free_ciphers
= 0;
242 QCryptoIVGen
*qcrypto_block_get_ivgen(QCryptoBlock
*block
)
244 /* ivgen should be accessed under mutex. However, this function is used only
245 * in test with one thread, so it's enough to assert it here:
247 assert(block
->n_ciphers
<= 1);
252 QCryptoHashAlgorithm
qcrypto_block_get_kdf_hash(QCryptoBlock
*block
)
254 return block
->kdfhash
;
258 uint64_t qcrypto_block_get_payload_offset(QCryptoBlock
*block
)
260 return block
->payload_offset
;
264 uint64_t qcrypto_block_get_sector_size(QCryptoBlock
*block
)
266 return block
->sector_size
;
270 void qcrypto_block_free(QCryptoBlock
*block
)
276 block
->driver
->cleanup(block
);
278 qcrypto_block_free_cipher(block
);
279 qcrypto_ivgen_free(block
->ivgen
);
280 qemu_mutex_destroy(&block
->mutex
);
285 typedef int (*QCryptoCipherEncDecFunc
)(QCryptoCipher
*cipher
,
291 static int do_qcrypto_block_cipher_encdec(QCryptoCipher
*cipher
,
294 QemuMutex
*ivgen_mutex
,
299 QCryptoCipherEncDecFunc func
,
302 g_autofree
uint8_t *iv
= niv
? g_new0(uint8_t, niv
) : NULL
;
304 uint64_t startsector
= offset
/ sectorsize
;
306 assert(QEMU_IS_ALIGNED(offset
, sectorsize
));
307 assert(QEMU_IS_ALIGNED(len
, sectorsize
));
313 qemu_mutex_lock(ivgen_mutex
);
315 ret
= qcrypto_ivgen_calculate(ivgen
, startsector
, iv
, niv
, errp
);
317 qemu_mutex_unlock(ivgen_mutex
);
324 if (qcrypto_cipher_setiv(cipher
,
331 nbytes
= len
> sectorsize
? sectorsize
: len
;
332 if (func(cipher
, buf
, buf
, nbytes
, errp
) < 0) {
345 int qcrypto_block_cipher_decrypt_helper(QCryptoCipher
*cipher
,
354 return do_qcrypto_block_cipher_encdec(cipher
, niv
, ivgen
, NULL
, sectorsize
,
356 qcrypto_cipher_decrypt
, errp
);
360 int qcrypto_block_cipher_encrypt_helper(QCryptoCipher
*cipher
,
369 return do_qcrypto_block_cipher_encdec(cipher
, niv
, ivgen
, NULL
, sectorsize
,
371 qcrypto_cipher_encrypt
, errp
);
374 int qcrypto_block_decrypt_helper(QCryptoBlock
*block
,
382 QCryptoCipher
*cipher
= qcrypto_block_pop_cipher(block
);
384 ret
= do_qcrypto_block_cipher_encdec(cipher
, block
->niv
, block
->ivgen
,
385 &block
->mutex
, sectorsize
, offset
, buf
,
386 len
, qcrypto_cipher_decrypt
, errp
);
388 qcrypto_block_push_cipher(block
, cipher
);
393 int qcrypto_block_encrypt_helper(QCryptoBlock
*block
,
401 QCryptoCipher
*cipher
= qcrypto_block_pop_cipher(block
);
403 ret
= do_qcrypto_block_cipher_encdec(cipher
, block
->niv
, block
->ivgen
,
404 &block
->mutex
, sectorsize
, offset
, buf
,
405 len
, qcrypto_cipher_encrypt
, errp
);
407 qcrypto_block_push_cipher(block
, cipher
);