17d969014SDaniel P. Berrange /* 27d969014SDaniel P. Berrange * QEMU Crypto block device encryption 37d969014SDaniel P. Berrange * 47d969014SDaniel P. Berrange * Copyright (c) 2015-2016 Red Hat, Inc. 57d969014SDaniel P. Berrange * 67d969014SDaniel P. Berrange * This library is free software; you can redistribute it and/or 77d969014SDaniel P. Berrange * modify it under the terms of the GNU Lesser General Public 87d969014SDaniel P. Berrange * License as published by the Free Software Foundation; either 9*b7cbb874SThomas Huth * version 2.1 of the License, or (at your option) any later version. 107d969014SDaniel P. Berrange * 117d969014SDaniel P. Berrange * This library is distributed in the hope that it will be useful, 127d969014SDaniel P. Berrange * but WITHOUT ANY WARRANTY; without even the implied warranty of 137d969014SDaniel P. Berrange * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 147d969014SDaniel P. Berrange * Lesser General Public License for more details. 157d969014SDaniel P. Berrange * 167d969014SDaniel P. Berrange * You should have received a copy of the GNU Lesser General Public 177d969014SDaniel P. Berrange * License along with this library; if not, see <http://www.gnu.org/licenses/>. 187d969014SDaniel P. Berrange * 197d969014SDaniel P. Berrange */ 207d969014SDaniel P. Berrange 217d969014SDaniel P. Berrange #include "qemu/osdep.h" 22da34e65cSMarkus Armbruster #include "qapi/error.h" 23986bc8deSMichael S. Tsirkin #include "blockpriv.h" 24986bc8deSMichael S. Tsirkin #include "block-qcow.h" 25986bc8deSMichael S. Tsirkin #include "block-luks.h" 267d969014SDaniel P. Berrange 277d969014SDaniel P. Berrange static const QCryptoBlockDriver *qcrypto_block_drivers[] = { 287d969014SDaniel P. Berrange [Q_CRYPTO_BLOCK_FORMAT_QCOW] = &qcrypto_block_driver_qcow, 293e308f20SDaniel P. Berrange [Q_CRYPTO_BLOCK_FORMAT_LUKS] = &qcrypto_block_driver_luks, 307d969014SDaniel P. Berrange }; 317d969014SDaniel P. Berrange 327d969014SDaniel P. Berrange 337d969014SDaniel P. Berrange bool qcrypto_block_has_format(QCryptoBlockFormat format, 347d969014SDaniel P. Berrange const uint8_t *buf, 357d969014SDaniel P. Berrange size_t len) 367d969014SDaniel P. Berrange { 377d969014SDaniel P. Berrange const QCryptoBlockDriver *driver; 387d969014SDaniel P. Berrange 397d969014SDaniel P. Berrange if (format >= G_N_ELEMENTS(qcrypto_block_drivers) || 407d969014SDaniel P. Berrange !qcrypto_block_drivers[format]) { 417d969014SDaniel P. Berrange return false; 427d969014SDaniel P. Berrange } 437d969014SDaniel P. Berrange 447d969014SDaniel P. Berrange driver = qcrypto_block_drivers[format]; 457d969014SDaniel P. Berrange 467d969014SDaniel P. Berrange return driver->has_format(buf, len); 477d969014SDaniel P. Berrange } 487d969014SDaniel P. Berrange 497d969014SDaniel P. Berrange 507d969014SDaniel P. Berrange QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, 511cd9a787SDaniel P. Berrange const char *optprefix, 527d969014SDaniel P. Berrange QCryptoBlockReadFunc readfunc, 537d969014SDaniel P. Berrange void *opaque, 547d969014SDaniel P. Berrange unsigned int flags, 55c972fa12SVladimir Sementsov-Ogievskiy size_t n_threads, 567d969014SDaniel P. Berrange Error **errp) 577d969014SDaniel P. Berrange { 587d969014SDaniel P. Berrange QCryptoBlock *block = g_new0(QCryptoBlock, 1); 597d969014SDaniel P. Berrange 607d969014SDaniel P. Berrange block->format = options->format; 617d969014SDaniel P. Berrange 627d969014SDaniel P. Berrange if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) || 637d969014SDaniel P. Berrange !qcrypto_block_drivers[options->format]) { 6490d6f60dSDaniel P. Berrange error_setg(errp, "Unsupported block driver %s", 65977c736fSMarkus Armbruster QCryptoBlockFormat_str(options->format)); 667d969014SDaniel P. Berrange g_free(block); 677d969014SDaniel P. Berrange return NULL; 687d969014SDaniel P. Berrange } 697d969014SDaniel P. Berrange 707d969014SDaniel P. Berrange block->driver = qcrypto_block_drivers[options->format]; 717d969014SDaniel P. Berrange 721cd9a787SDaniel P. Berrange if (block->driver->open(block, options, optprefix, 73c972fa12SVladimir Sementsov-Ogievskiy readfunc, opaque, flags, n_threads, errp) < 0) 74c972fa12SVladimir Sementsov-Ogievskiy { 757d969014SDaniel P. Berrange g_free(block); 767d969014SDaniel P. Berrange return NULL; 777d969014SDaniel P. Berrange } 787d969014SDaniel P. Berrange 79c972fa12SVladimir Sementsov-Ogievskiy qemu_mutex_init(&block->mutex); 80c972fa12SVladimir Sementsov-Ogievskiy 817d969014SDaniel P. Berrange return block; 827d969014SDaniel P. Berrange } 837d969014SDaniel P. Berrange 847d969014SDaniel P. Berrange 857d969014SDaniel P. Berrange QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, 861cd9a787SDaniel P. Berrange const char *optprefix, 877d969014SDaniel P. Berrange QCryptoBlockInitFunc initfunc, 887d969014SDaniel P. Berrange QCryptoBlockWriteFunc writefunc, 897d969014SDaniel P. Berrange void *opaque, 907d969014SDaniel P. Berrange Error **errp) 917d969014SDaniel P. Berrange { 927d969014SDaniel P. Berrange QCryptoBlock *block = g_new0(QCryptoBlock, 1); 937d969014SDaniel P. Berrange 947d969014SDaniel P. Berrange block->format = options->format; 957d969014SDaniel P. Berrange 967d969014SDaniel P. Berrange if (options->format >= G_N_ELEMENTS(qcrypto_block_drivers) || 977d969014SDaniel P. Berrange !qcrypto_block_drivers[options->format]) { 9890d6f60dSDaniel P. Berrange error_setg(errp, "Unsupported block driver %s", 99977c736fSMarkus Armbruster QCryptoBlockFormat_str(options->format)); 1007d969014SDaniel P. Berrange g_free(block); 1017d969014SDaniel P. Berrange return NULL; 1027d969014SDaniel P. Berrange } 1037d969014SDaniel P. Berrange 1047d969014SDaniel P. Berrange block->driver = qcrypto_block_drivers[options->format]; 1057d969014SDaniel P. Berrange 1061cd9a787SDaniel P. Berrange if (block->driver->create(block, options, optprefix, initfunc, 1077d969014SDaniel P. Berrange writefunc, opaque, errp) < 0) { 1087d969014SDaniel P. Berrange g_free(block); 1097d969014SDaniel P. Berrange return NULL; 1107d969014SDaniel P. Berrange } 1117d969014SDaniel P. Berrange 112c972fa12SVladimir Sementsov-Ogievskiy qemu_mutex_init(&block->mutex); 113c972fa12SVladimir Sementsov-Ogievskiy 1147d969014SDaniel P. Berrange return block; 1157d969014SDaniel P. Berrange } 1167d969014SDaniel P. Berrange 1177d969014SDaniel P. Berrange 11840c85028SDaniel P. Berrange QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block, 11940c85028SDaniel P. Berrange Error **errp) 12040c85028SDaniel P. Berrange { 12140c85028SDaniel P. Berrange QCryptoBlockInfo *info = g_new0(QCryptoBlockInfo, 1); 12240c85028SDaniel P. Berrange 12340c85028SDaniel P. Berrange info->format = block->format; 12440c85028SDaniel P. Berrange 12540c85028SDaniel P. Berrange if (block->driver->get_info && 12640c85028SDaniel P. Berrange block->driver->get_info(block, info, errp) < 0) { 12740c85028SDaniel P. Berrange g_free(info); 12840c85028SDaniel P. Berrange return NULL; 12940c85028SDaniel P. Berrange } 13040c85028SDaniel P. Berrange 13140c85028SDaniel P. Berrange return info; 13240c85028SDaniel P. Berrange } 13340c85028SDaniel P. Berrange 13440c85028SDaniel P. Berrange 1357d969014SDaniel P. Berrange int qcrypto_block_decrypt(QCryptoBlock *block, 1364609742aSDaniel P. Berrange uint64_t offset, 1377d969014SDaniel P. Berrange uint8_t *buf, 1387d969014SDaniel P. Berrange size_t len, 1397d969014SDaniel P. Berrange Error **errp) 1407d969014SDaniel P. Berrange { 1414609742aSDaniel P. Berrange return block->driver->decrypt(block, offset, buf, len, errp); 1427d969014SDaniel P. Berrange } 1437d969014SDaniel P. Berrange 1447d969014SDaniel P. Berrange 1457d969014SDaniel P. Berrange int qcrypto_block_encrypt(QCryptoBlock *block, 1464609742aSDaniel P. Berrange uint64_t offset, 1477d969014SDaniel P. Berrange uint8_t *buf, 1487d969014SDaniel P. Berrange size_t len, 1497d969014SDaniel P. Berrange Error **errp) 1507d969014SDaniel P. Berrange { 1514609742aSDaniel P. Berrange return block->driver->encrypt(block, offset, buf, len, errp); 1527d969014SDaniel P. Berrange } 1537d969014SDaniel P. Berrange 1547d969014SDaniel P. Berrange 1557d969014SDaniel P. Berrange QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block) 1567d969014SDaniel P. Berrange { 157c972fa12SVladimir Sementsov-Ogievskiy /* Ciphers should be accessed through pop/push method to be thread-safe. 158c972fa12SVladimir Sementsov-Ogievskiy * Better, they should not be accessed externally at all (note, that 159c972fa12SVladimir Sementsov-Ogievskiy * pop/push are static functions) 160c972fa12SVladimir Sementsov-Ogievskiy * This function is used only in test with one thread (it's safe to skip 161c972fa12SVladimir Sementsov-Ogievskiy * pop/push interface), so it's enough to assert it here: 162c972fa12SVladimir Sementsov-Ogievskiy */ 163c972fa12SVladimir Sementsov-Ogievskiy assert(block->n_ciphers <= 1); 164c972fa12SVladimir Sementsov-Ogievskiy return block->ciphers ? block->ciphers[0] : NULL; 1657d969014SDaniel P. Berrange } 1667d969014SDaniel P. Berrange 1677d969014SDaniel P. Berrange 168c972fa12SVladimir Sementsov-Ogievskiy static QCryptoCipher *qcrypto_block_pop_cipher(QCryptoBlock *block) 169c972fa12SVladimir Sementsov-Ogievskiy { 170c972fa12SVladimir Sementsov-Ogievskiy QCryptoCipher *cipher; 171c972fa12SVladimir Sementsov-Ogievskiy 172c972fa12SVladimir Sementsov-Ogievskiy qemu_mutex_lock(&block->mutex); 173c972fa12SVladimir Sementsov-Ogievskiy 174c972fa12SVladimir Sementsov-Ogievskiy assert(block->n_free_ciphers > 0); 175c972fa12SVladimir Sementsov-Ogievskiy block->n_free_ciphers--; 176c972fa12SVladimir Sementsov-Ogievskiy cipher = block->ciphers[block->n_free_ciphers]; 177c972fa12SVladimir Sementsov-Ogievskiy 178c972fa12SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(&block->mutex); 179c972fa12SVladimir Sementsov-Ogievskiy 180c972fa12SVladimir Sementsov-Ogievskiy return cipher; 181c972fa12SVladimir Sementsov-Ogievskiy } 182c972fa12SVladimir Sementsov-Ogievskiy 183c972fa12SVladimir Sementsov-Ogievskiy 184c972fa12SVladimir Sementsov-Ogievskiy static void qcrypto_block_push_cipher(QCryptoBlock *block, 185c972fa12SVladimir Sementsov-Ogievskiy QCryptoCipher *cipher) 186c972fa12SVladimir Sementsov-Ogievskiy { 187c972fa12SVladimir Sementsov-Ogievskiy qemu_mutex_lock(&block->mutex); 188c972fa12SVladimir Sementsov-Ogievskiy 189c972fa12SVladimir Sementsov-Ogievskiy assert(block->n_free_ciphers < block->n_ciphers); 190c972fa12SVladimir Sementsov-Ogievskiy block->ciphers[block->n_free_ciphers] = cipher; 191c972fa12SVladimir Sementsov-Ogievskiy block->n_free_ciphers++; 192c972fa12SVladimir Sementsov-Ogievskiy 193c972fa12SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(&block->mutex); 194c972fa12SVladimir Sementsov-Ogievskiy } 195c972fa12SVladimir Sementsov-Ogievskiy 196c972fa12SVladimir Sementsov-Ogievskiy 197c972fa12SVladimir Sementsov-Ogievskiy int qcrypto_block_init_cipher(QCryptoBlock *block, 198c972fa12SVladimir Sementsov-Ogievskiy QCryptoCipherAlgorithm alg, 199c972fa12SVladimir Sementsov-Ogievskiy QCryptoCipherMode mode, 200c972fa12SVladimir Sementsov-Ogievskiy const uint8_t *key, size_t nkey, 201c972fa12SVladimir Sementsov-Ogievskiy size_t n_threads, Error **errp) 202c972fa12SVladimir Sementsov-Ogievskiy { 203c972fa12SVladimir Sementsov-Ogievskiy size_t i; 204c972fa12SVladimir Sementsov-Ogievskiy 205c972fa12SVladimir Sementsov-Ogievskiy assert(!block->ciphers && !block->n_ciphers && !block->n_free_ciphers); 206c972fa12SVladimir Sementsov-Ogievskiy 207c972fa12SVladimir Sementsov-Ogievskiy block->ciphers = g_new0(QCryptoCipher *, n_threads); 208c972fa12SVladimir Sementsov-Ogievskiy 209c972fa12SVladimir Sementsov-Ogievskiy for (i = 0; i < n_threads; i++) { 210c972fa12SVladimir Sementsov-Ogievskiy block->ciphers[i] = qcrypto_cipher_new(alg, mode, key, nkey, errp); 211c972fa12SVladimir Sementsov-Ogievskiy if (!block->ciphers[i]) { 212c972fa12SVladimir Sementsov-Ogievskiy qcrypto_block_free_cipher(block); 213c972fa12SVladimir Sementsov-Ogievskiy return -1; 214c972fa12SVladimir Sementsov-Ogievskiy } 215c972fa12SVladimir Sementsov-Ogievskiy block->n_ciphers++; 216c972fa12SVladimir Sementsov-Ogievskiy block->n_free_ciphers++; 217c972fa12SVladimir Sementsov-Ogievskiy } 218c972fa12SVladimir Sementsov-Ogievskiy 219c972fa12SVladimir Sementsov-Ogievskiy return 0; 220c972fa12SVladimir Sementsov-Ogievskiy } 221c972fa12SVladimir Sementsov-Ogievskiy 222c972fa12SVladimir Sementsov-Ogievskiy 223c972fa12SVladimir Sementsov-Ogievskiy void qcrypto_block_free_cipher(QCryptoBlock *block) 224c972fa12SVladimir Sementsov-Ogievskiy { 225c972fa12SVladimir Sementsov-Ogievskiy size_t i; 226c972fa12SVladimir Sementsov-Ogievskiy 227c972fa12SVladimir Sementsov-Ogievskiy if (!block->ciphers) { 228c972fa12SVladimir Sementsov-Ogievskiy return; 229c972fa12SVladimir Sementsov-Ogievskiy } 230c972fa12SVladimir Sementsov-Ogievskiy 231c972fa12SVladimir Sementsov-Ogievskiy assert(block->n_ciphers == block->n_free_ciphers); 232c972fa12SVladimir Sementsov-Ogievskiy 233c972fa12SVladimir Sementsov-Ogievskiy for (i = 0; i < block->n_ciphers; i++) { 234c972fa12SVladimir Sementsov-Ogievskiy qcrypto_cipher_free(block->ciphers[i]); 235c972fa12SVladimir Sementsov-Ogievskiy } 236c972fa12SVladimir Sementsov-Ogievskiy 237c972fa12SVladimir Sementsov-Ogievskiy g_free(block->ciphers); 238c972fa12SVladimir Sementsov-Ogievskiy block->ciphers = NULL; 239c972fa12SVladimir Sementsov-Ogievskiy block->n_ciphers = block->n_free_ciphers = 0; 240c972fa12SVladimir Sementsov-Ogievskiy } 241c972fa12SVladimir Sementsov-Ogievskiy 2427d969014SDaniel P. Berrange QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block) 2437d969014SDaniel P. Berrange { 244c972fa12SVladimir Sementsov-Ogievskiy /* ivgen should be accessed under mutex. However, this function is used only 245c972fa12SVladimir Sementsov-Ogievskiy * in test with one thread, so it's enough to assert it here: 246c972fa12SVladimir Sementsov-Ogievskiy */ 247c972fa12SVladimir Sementsov-Ogievskiy assert(block->n_ciphers <= 1); 2487d969014SDaniel P. Berrange return block->ivgen; 2497d969014SDaniel P. Berrange } 2507d969014SDaniel P. Berrange 2517d969014SDaniel P. Berrange 2527d969014SDaniel P. Berrange QCryptoHashAlgorithm qcrypto_block_get_kdf_hash(QCryptoBlock *block) 2537d969014SDaniel P. Berrange { 2547d969014SDaniel P. Berrange return block->kdfhash; 2557d969014SDaniel P. Berrange } 2567d969014SDaniel P. Berrange 2577d969014SDaniel P. Berrange 2587d969014SDaniel P. Berrange uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block) 2597d969014SDaniel P. Berrange { 2607d969014SDaniel P. Berrange return block->payload_offset; 2617d969014SDaniel P. Berrange } 2627d969014SDaniel P. Berrange 2637d969014SDaniel P. Berrange 264850f49deSDaniel P. Berrange uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block) 265850f49deSDaniel P. Berrange { 266850f49deSDaniel P. Berrange return block->sector_size; 267850f49deSDaniel P. Berrange } 268850f49deSDaniel P. Berrange 269850f49deSDaniel P. Berrange 2707d969014SDaniel P. Berrange void qcrypto_block_free(QCryptoBlock *block) 2717d969014SDaniel P. Berrange { 2727d969014SDaniel P. Berrange if (!block) { 2737d969014SDaniel P. Berrange return; 2747d969014SDaniel P. Berrange } 2757d969014SDaniel P. Berrange 2767d969014SDaniel P. Berrange block->driver->cleanup(block); 2777d969014SDaniel P. Berrange 278c972fa12SVladimir Sementsov-Ogievskiy qcrypto_block_free_cipher(block); 2797d969014SDaniel P. Berrange qcrypto_ivgen_free(block->ivgen); 280c972fa12SVladimir Sementsov-Ogievskiy qemu_mutex_destroy(&block->mutex); 2817d969014SDaniel P. Berrange g_free(block); 2827d969014SDaniel P. Berrange } 2837d969014SDaniel P. Berrange 2847d969014SDaniel P. Berrange 2851dc57b60SVladimir Sementsov-Ogievskiy typedef int (*QCryptoCipherEncDecFunc)(QCryptoCipher *cipher, 2861dc57b60SVladimir Sementsov-Ogievskiy const void *in, 2871dc57b60SVladimir Sementsov-Ogievskiy void *out, 2881dc57b60SVladimir Sementsov-Ogievskiy size_t len, 2891dc57b60SVladimir Sementsov-Ogievskiy Error **errp); 2901dc57b60SVladimir Sementsov-Ogievskiy 2910270417cSVladimir Sementsov-Ogievskiy static int do_qcrypto_block_cipher_encdec(QCryptoCipher *cipher, 2927d969014SDaniel P. Berrange size_t niv, 2937d969014SDaniel P. Berrange QCryptoIVGen *ivgen, 294c972fa12SVladimir Sementsov-Ogievskiy QemuMutex *ivgen_mutex, 2957d969014SDaniel P. Berrange int sectorsize, 2964609742aSDaniel P. Berrange uint64_t offset, 2977d969014SDaniel P. Berrange uint8_t *buf, 2987d969014SDaniel P. Berrange size_t len, 2991dc57b60SVladimir Sementsov-Ogievskiy QCryptoCipherEncDecFunc func, 3007d969014SDaniel P. Berrange Error **errp) 3017d969014SDaniel P. Berrange { 3027d969014SDaniel P. Berrange uint8_t *iv; 3037d969014SDaniel P. Berrange int ret = -1; 3044609742aSDaniel P. Berrange uint64_t startsector = offset / sectorsize; 3054609742aSDaniel P. Berrange 3064609742aSDaniel P. Berrange assert(QEMU_IS_ALIGNED(offset, sectorsize)); 3074609742aSDaniel P. Berrange assert(QEMU_IS_ALIGNED(len, sectorsize)); 3087d969014SDaniel P. Berrange 3097d969014SDaniel P. Berrange iv = niv ? g_new0(uint8_t, niv) : NULL; 3107d969014SDaniel P. Berrange 3117d969014SDaniel P. Berrange while (len > 0) { 3127d969014SDaniel P. Berrange size_t nbytes; 3137d969014SDaniel P. Berrange if (niv) { 314c972fa12SVladimir Sementsov-Ogievskiy if (ivgen_mutex) { 315c972fa12SVladimir Sementsov-Ogievskiy qemu_mutex_lock(ivgen_mutex); 316c972fa12SVladimir Sementsov-Ogievskiy } 317c972fa12SVladimir Sementsov-Ogievskiy ret = qcrypto_ivgen_calculate(ivgen, startsector, iv, niv, errp); 318c972fa12SVladimir Sementsov-Ogievskiy if (ivgen_mutex) { 319c972fa12SVladimir Sementsov-Ogievskiy qemu_mutex_unlock(ivgen_mutex); 320c972fa12SVladimir Sementsov-Ogievskiy } 321c972fa12SVladimir Sementsov-Ogievskiy 322c972fa12SVladimir Sementsov-Ogievskiy if (ret < 0) { 3237d969014SDaniel P. Berrange goto cleanup; 3247d969014SDaniel P. Berrange } 3257d969014SDaniel P. Berrange 3267d969014SDaniel P. Berrange if (qcrypto_cipher_setiv(cipher, 3277d969014SDaniel P. Berrange iv, niv, 3287d969014SDaniel P. Berrange errp) < 0) { 3297d969014SDaniel P. Berrange goto cleanup; 3307d969014SDaniel P. Berrange } 3317d969014SDaniel P. Berrange } 3327d969014SDaniel P. Berrange 3337d969014SDaniel P. Berrange nbytes = len > sectorsize ? sectorsize : len; 3341dc57b60SVladimir Sementsov-Ogievskiy if (func(cipher, buf, buf, nbytes, errp) < 0) { 3357d969014SDaniel P. Berrange goto cleanup; 3367d969014SDaniel P. Berrange } 3377d969014SDaniel P. Berrange 3387d969014SDaniel P. Berrange startsector++; 3397d969014SDaniel P. Berrange buf += nbytes; 3407d969014SDaniel P. Berrange len -= nbytes; 3417d969014SDaniel P. Berrange } 3427d969014SDaniel P. Berrange 3437d969014SDaniel P. Berrange ret = 0; 3447d969014SDaniel P. Berrange cleanup: 3457d969014SDaniel P. Berrange g_free(iv); 3467d969014SDaniel P. Berrange return ret; 3477d969014SDaniel P. Berrange } 3487d969014SDaniel P. Berrange 3497d969014SDaniel P. Berrange 3500270417cSVladimir Sementsov-Ogievskiy int qcrypto_block_cipher_decrypt_helper(QCryptoCipher *cipher, 3511dc57b60SVladimir Sementsov-Ogievskiy size_t niv, 3521dc57b60SVladimir Sementsov-Ogievskiy QCryptoIVGen *ivgen, 3531dc57b60SVladimir Sementsov-Ogievskiy int sectorsize, 3541dc57b60SVladimir Sementsov-Ogievskiy uint64_t offset, 3551dc57b60SVladimir Sementsov-Ogievskiy uint8_t *buf, 3561dc57b60SVladimir Sementsov-Ogievskiy size_t len, 3571dc57b60SVladimir Sementsov-Ogievskiy Error **errp) 3581dc57b60SVladimir Sementsov-Ogievskiy { 359c972fa12SVladimir Sementsov-Ogievskiy return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, NULL, sectorsize, 3600270417cSVladimir Sementsov-Ogievskiy offset, buf, len, 3610270417cSVladimir Sementsov-Ogievskiy qcrypto_cipher_decrypt, errp); 3621dc57b60SVladimir Sementsov-Ogievskiy } 3631dc57b60SVladimir Sementsov-Ogievskiy 3641dc57b60SVladimir Sementsov-Ogievskiy 3650270417cSVladimir Sementsov-Ogievskiy int qcrypto_block_cipher_encrypt_helper(QCryptoCipher *cipher, 3667d969014SDaniel P. Berrange size_t niv, 3677d969014SDaniel P. Berrange QCryptoIVGen *ivgen, 3687d969014SDaniel P. Berrange int sectorsize, 3694609742aSDaniel P. Berrange uint64_t offset, 3707d969014SDaniel P. Berrange uint8_t *buf, 3717d969014SDaniel P. Berrange size_t len, 3727d969014SDaniel P. Berrange Error **errp) 3737d969014SDaniel P. Berrange { 374c972fa12SVladimir Sementsov-Ogievskiy return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, NULL, sectorsize, 3750270417cSVladimir Sementsov-Ogievskiy offset, buf, len, 3760270417cSVladimir Sementsov-Ogievskiy qcrypto_cipher_encrypt, errp); 3777d969014SDaniel P. Berrange } 3780f0d596cSVladimir Sementsov-Ogievskiy 3790f0d596cSVladimir Sementsov-Ogievskiy int qcrypto_block_decrypt_helper(QCryptoBlock *block, 3800f0d596cSVladimir Sementsov-Ogievskiy int sectorsize, 3810f0d596cSVladimir Sementsov-Ogievskiy uint64_t offset, 3820f0d596cSVladimir Sementsov-Ogievskiy uint8_t *buf, 3830f0d596cSVladimir Sementsov-Ogievskiy size_t len, 3840f0d596cSVladimir Sementsov-Ogievskiy Error **errp) 3850f0d596cSVladimir Sementsov-Ogievskiy { 386c972fa12SVladimir Sementsov-Ogievskiy int ret; 387c972fa12SVladimir Sementsov-Ogievskiy QCryptoCipher *cipher = qcrypto_block_pop_cipher(block); 3880f0d596cSVladimir Sementsov-Ogievskiy 389c972fa12SVladimir Sementsov-Ogievskiy ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen, 390c972fa12SVladimir Sementsov-Ogievskiy &block->mutex, sectorsize, offset, buf, 391c972fa12SVladimir Sementsov-Ogievskiy len, qcrypto_cipher_decrypt, errp); 392c972fa12SVladimir Sementsov-Ogievskiy 393c972fa12SVladimir Sementsov-Ogievskiy qcrypto_block_push_cipher(block, cipher); 394c972fa12SVladimir Sementsov-Ogievskiy 395c972fa12SVladimir Sementsov-Ogievskiy return ret; 396c972fa12SVladimir Sementsov-Ogievskiy } 3970f0d596cSVladimir Sementsov-Ogievskiy 3980f0d596cSVladimir Sementsov-Ogievskiy int qcrypto_block_encrypt_helper(QCryptoBlock *block, 3990f0d596cSVladimir Sementsov-Ogievskiy int sectorsize, 4000f0d596cSVladimir Sementsov-Ogievskiy uint64_t offset, 4010f0d596cSVladimir Sementsov-Ogievskiy uint8_t *buf, 4020f0d596cSVladimir Sementsov-Ogievskiy size_t len, 4030f0d596cSVladimir Sementsov-Ogievskiy Error **errp) 4040f0d596cSVladimir Sementsov-Ogievskiy { 405c972fa12SVladimir Sementsov-Ogievskiy int ret; 406c972fa12SVladimir Sementsov-Ogievskiy QCryptoCipher *cipher = qcrypto_block_pop_cipher(block); 407c972fa12SVladimir Sementsov-Ogievskiy 408c972fa12SVladimir Sementsov-Ogievskiy ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen, 409c972fa12SVladimir Sementsov-Ogievskiy &block->mutex, sectorsize, offset, buf, 410c972fa12SVladimir Sementsov-Ogievskiy len, qcrypto_cipher_encrypt, errp); 411c972fa12SVladimir Sementsov-Ogievskiy 412c972fa12SVladimir Sementsov-Ogievskiy qcrypto_block_push_cipher(block, cipher); 413c972fa12SVladimir Sementsov-Ogievskiy 414c972fa12SVladimir Sementsov-Ogievskiy return ret; 4150f0d596cSVladimir Sementsov-Ogievskiy } 416