ppc: Add macros to register hypervisor mode SPRs
[qemu/ar7.git] / crypto / block.c
blob524ed91db82a38340bb54d89107345c05e4acda0
1 /*
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 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 "crypto/blockpriv.h"
23 #include "crypto/block-qcow.h"
24 #include "crypto/block-luks.h"
26 static const QCryptoBlockDriver *qcrypto_block_drivers[] = {
27 [Q_CRYPTO_BLOCK_FORMAT_QCOW] = &qcrypto_block_driver_qcow,
28 [Q_CRYPTO_BLOCK_FORMAT_LUKS] = &qcrypto_block_driver_luks,
32 bool qcrypto_block_has_format(QCryptoBlockFormat format,
33 const uint8_t *buf,
34 size_t len)
36 const QCryptoBlockDriver *driver;
38 if (format >= G_N_ELEMENTS(qcrypto_block_drivers) ||
39 !qcrypto_block_drivers[format]) {
40 return false;
43 driver = qcrypto_block_drivers[format];
45 return driver->has_format(buf, len);
49 QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options,
50 QCryptoBlockReadFunc readfunc,
51 void *opaque,
52 unsigned int flags,
53 Error **errp)
55 QCryptoBlock *block = g_new0(QCryptoBlock, 1);
57 block->format = options->format;
59 if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) ||
60 !qcrypto_block_drivers[options->format]) {
61 error_setg(errp, "Unsupported block driver %d", options->format);
62 g_free(block);
63 return NULL;
66 block->driver = qcrypto_block_drivers[options->format];
68 if (block->driver->open(block, options,
69 readfunc, opaque, flags, errp) < 0) {
70 g_free(block);
71 return NULL;
74 return block;
78 QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options,
79 QCryptoBlockInitFunc initfunc,
80 QCryptoBlockWriteFunc writefunc,
81 void *opaque,
82 Error **errp)
84 QCryptoBlock *block = g_new0(QCryptoBlock, 1);
86 block->format = options->format;
88 if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) ||
89 !qcrypto_block_drivers[options->format]) {
90 error_setg(errp, "Unsupported block driver %d", options->format);
91 g_free(block);
92 return NULL;
95 block->driver = qcrypto_block_drivers[options->format];
97 if (block->driver->create(block, options, initfunc,
98 writefunc, opaque, errp) < 0) {
99 g_free(block);
100 return NULL;
103 return block;
107 int qcrypto_block_decrypt(QCryptoBlock *block,
108 uint64_t startsector,
109 uint8_t *buf,
110 size_t len,
111 Error **errp)
113 return block->driver->decrypt(block, startsector, buf, len, errp);
117 int qcrypto_block_encrypt(QCryptoBlock *block,
118 uint64_t startsector,
119 uint8_t *buf,
120 size_t len,
121 Error **errp)
123 return block->driver->encrypt(block, startsector, buf, len, errp);
127 QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block)
129 return block->cipher;
133 QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block)
135 return block->ivgen;
139 QCryptoHashAlgorithm qcrypto_block_get_kdf_hash(QCryptoBlock *block)
141 return block->kdfhash;
145 uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block)
147 return block->payload_offset;
151 void qcrypto_block_free(QCryptoBlock *block)
153 if (!block) {
154 return;
157 block->driver->cleanup(block);
159 qcrypto_cipher_free(block->cipher);
160 qcrypto_ivgen_free(block->ivgen);
161 g_free(block);
165 int qcrypto_block_decrypt_helper(QCryptoCipher *cipher,
166 size_t niv,
167 QCryptoIVGen *ivgen,
168 int sectorsize,
169 uint64_t startsector,
170 uint8_t *buf,
171 size_t len,
172 Error **errp)
174 uint8_t *iv;
175 int ret = -1;
177 iv = niv ? g_new0(uint8_t, niv) : NULL;
179 while (len > 0) {
180 size_t nbytes;
181 if (niv) {
182 if (qcrypto_ivgen_calculate(ivgen,
183 startsector,
184 iv, niv,
185 errp) < 0) {
186 goto cleanup;
189 if (qcrypto_cipher_setiv(cipher,
190 iv, niv,
191 errp) < 0) {
192 goto cleanup;
196 nbytes = len > sectorsize ? sectorsize : len;
197 if (qcrypto_cipher_decrypt(cipher, buf, buf,
198 nbytes, errp) < 0) {
199 goto cleanup;
202 startsector++;
203 buf += nbytes;
204 len -= nbytes;
207 ret = 0;
208 cleanup:
209 g_free(iv);
210 return ret;
214 int qcrypto_block_encrypt_helper(QCryptoCipher *cipher,
215 size_t niv,
216 QCryptoIVGen *ivgen,
217 int sectorsize,
218 uint64_t startsector,
219 uint8_t *buf,
220 size_t len,
221 Error **errp)
223 uint8_t *iv;
224 int ret = -1;
226 iv = niv ? g_new0(uint8_t, niv) : NULL;
228 while (len > 0) {
229 size_t nbytes;
230 if (niv) {
231 if (qcrypto_ivgen_calculate(ivgen,
232 startsector,
233 iv, niv,
234 errp) < 0) {
235 goto cleanup;
238 if (qcrypto_cipher_setiv(cipher,
239 iv, niv,
240 errp) < 0) {
241 goto cleanup;
245 nbytes = len > sectorsize ? sectorsize : len;
246 if (qcrypto_cipher_encrypt(cipher, buf, buf,
247 nbytes, errp) < 0) {
248 goto cleanup;
251 startsector++;
252 buf += nbytes;
253 len -= nbytes;
256 ret = 0;
257 cleanup:
258 g_free(iv);
259 return ret;