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 9b7cbb874SThomas 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 212a6a4076SMarkus Armbruster #ifndef QCRYPTO_BLOCK_H 222a6a4076SMarkus Armbruster #define QCRYPTO_BLOCK_H 237d969014SDaniel P. Berrange 247d969014SDaniel P. Berrange #include "crypto/cipher.h" 257d969014SDaniel P. Berrange #include "crypto/ivgen.h" 267d969014SDaniel P. Berrange 277d969014SDaniel P. Berrange typedef struct QCryptoBlock QCryptoBlock; 287d969014SDaniel P. Berrange 297d969014SDaniel P. Berrange /* See also QCryptoBlockFormat, QCryptoBlockCreateOptions 307d969014SDaniel P. Berrange * and QCryptoBlockOpenOptions in qapi/crypto.json */ 317d969014SDaniel P. Berrange 32757dda54SAlberto Faria typedef int (*QCryptoBlockReadFunc)(QCryptoBlock *block, 337d969014SDaniel P. Berrange size_t offset, 347d969014SDaniel P. Berrange uint8_t *buf, 357d969014SDaniel P. Berrange size_t buflen, 36e4a3507eSDaniel P. Berrange void *opaque, 3737509233SFam Zheng Error **errp); 387d969014SDaniel P. Berrange 39757dda54SAlberto Faria typedef int (*QCryptoBlockInitFunc)(QCryptoBlock *block, 407d969014SDaniel P. Berrange size_t headerlen, 41e4a3507eSDaniel P. Berrange void *opaque, 4237509233SFam Zheng Error **errp); 437d969014SDaniel P. Berrange 44757dda54SAlberto Faria typedef int (*QCryptoBlockWriteFunc)(QCryptoBlock *block, 457d969014SDaniel P. Berrange size_t offset, 467d969014SDaniel P. Berrange const uint8_t *buf, 477d969014SDaniel P. Berrange size_t buflen, 48e4a3507eSDaniel P. Berrange void *opaque, 4937509233SFam Zheng Error **errp); 507d969014SDaniel P. Berrange 517d969014SDaniel P. Berrange /** 527d969014SDaniel P. Berrange * qcrypto_block_has_format: 537d969014SDaniel P. Berrange * @format: the encryption format 547d969014SDaniel P. Berrange * @buf: the data from head of the volume 557d969014SDaniel P. Berrange * @len: the length of @buf in bytes 567d969014SDaniel P. Berrange * 577d969014SDaniel P. Berrange * Given @len bytes of data from the head of a storage volume 587d969014SDaniel P. Berrange * in @buf, probe to determine if the volume has the encryption 597d969014SDaniel P. Berrange * format specified in @format. 607d969014SDaniel P. Berrange * 617d969014SDaniel P. Berrange * Returns: true if the data in @buf matches @format 627d969014SDaniel P. Berrange */ 637d969014SDaniel P. Berrange bool qcrypto_block_has_format(QCryptoBlockFormat format, 647d969014SDaniel P. Berrange const uint8_t *buf, 657d969014SDaniel P. Berrange size_t buflen); 667d969014SDaniel P. Berrange 677d969014SDaniel P. Berrange typedef enum { 687d969014SDaniel P. Berrange QCRYPTO_BLOCK_OPEN_NO_IO = (1 << 0), 699ad5c4e7SHyman Huang QCRYPTO_BLOCK_OPEN_DETACHED = (1 << 1), 707d969014SDaniel P. Berrange } QCryptoBlockOpenFlags; 717d969014SDaniel P. Berrange 727d969014SDaniel P. Berrange /** 737d969014SDaniel P. Berrange * qcrypto_block_open: 747d969014SDaniel P. Berrange * @options: the encryption options 751cd9a787SDaniel P. Berrange * @optprefix: name prefix for options 767d969014SDaniel P. Berrange * @readfunc: callback for reading data from the volume 777d969014SDaniel P. Berrange * @opaque: data to pass to @readfunc 787d969014SDaniel P. Berrange * @flags: bitmask of QCryptoBlockOpenFlags values 797d969014SDaniel P. Berrange * @errp: pointer to a NULL-initialized error object 807d969014SDaniel P. Berrange * 817d969014SDaniel P. Berrange * Create a new block encryption object for an existing 827d969014SDaniel P. Berrange * storage volume encrypted with format identified by 837d969014SDaniel P. Berrange * the parameters in @options. 847d969014SDaniel P. Berrange * 857d969014SDaniel P. Berrange * This will use @readfunc to initialize the encryption 867d969014SDaniel P. Berrange * context based on the volume header(s), extracting the 877d969014SDaniel P. Berrange * master key(s) as required. 887d969014SDaniel P. Berrange * 897d969014SDaniel P. Berrange * If @flags contains QCRYPTO_BLOCK_OPEN_NO_IO then 907d969014SDaniel P. Berrange * the open process will be optimized to skip any parts 917d969014SDaniel P. Berrange * that are only required to perform I/O. In particular 927d969014SDaniel P. Berrange * this would usually avoid the need to decrypt any 937d969014SDaniel P. Berrange * master keys. The only thing that can be done with 947d969014SDaniel P. Berrange * the resulting QCryptoBlock object would be to query 957d969014SDaniel P. Berrange * metadata such as the payload offset. There will be 967d969014SDaniel P. Berrange * no cipher or ivgen objects available. 977d969014SDaniel P. Berrange * 989ad5c4e7SHyman Huang * If @flags contains QCRYPTO_BLOCK_OPEN_DETACHED then 999ad5c4e7SHyman Huang * the open process will be optimized to skip the LUKS 1009ad5c4e7SHyman Huang * payload overlap check. 1019ad5c4e7SHyman Huang * 1027d969014SDaniel P. Berrange * If any part of initializing the encryption context 1037d969014SDaniel P. Berrange * fails an error will be returned. This could be due 1047d969014SDaniel P. Berrange * to the volume being in the wrong format, a cipher 1057d969014SDaniel P. Berrange * or IV generator algorithm that is not supported, 1067d969014SDaniel P. Berrange * or incorrect passphrases. 1077d969014SDaniel P. Berrange * 1087d969014SDaniel P. Berrange * Returns: a block encryption format, or NULL on error 1097d969014SDaniel P. Berrange */ 1107d969014SDaniel P. Berrange QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, 1111cd9a787SDaniel P. Berrange const char *optprefix, 1127d969014SDaniel P. Berrange QCryptoBlockReadFunc readfunc, 1137d969014SDaniel P. Berrange void *opaque, 1147d969014SDaniel P. Berrange unsigned int flags, 1157d969014SDaniel P. Berrange Error **errp); 1167d969014SDaniel P. Berrange 117d74523a3SHyman Huang typedef enum { 118d74523a3SHyman Huang QCRYPTO_BLOCK_CREATE_DETACHED = (1 << 0), 119d74523a3SHyman Huang } QCryptoBlockCreateFlags; 120d74523a3SHyman Huang 1217d969014SDaniel P. Berrange /** 1227d969014SDaniel P. Berrange * qcrypto_block_create: 1231cd9a787SDaniel P. Berrange * @options: the encryption options 1241cd9a787SDaniel P. Berrange * @optprefix: name prefix for options 1257d969014SDaniel P. Berrange * @initfunc: callback for initializing volume header 1267d969014SDaniel P. Berrange * @writefunc: callback for writing data to the volume header 1277d969014SDaniel P. Berrange * @opaque: data to pass to @initfunc and @writefunc 128d74523a3SHyman Huang * @flags: bitmask of QCryptoBlockCreateFlags values 1297d969014SDaniel P. Berrange * @errp: pointer to a NULL-initialized error object 1307d969014SDaniel P. Berrange * 1317d969014SDaniel P. Berrange * Create a new block encryption object for initializing 1327d969014SDaniel P. Berrange * a storage volume to be encrypted with format identified 1337d969014SDaniel P. Berrange * by the parameters in @options. 1347d969014SDaniel P. Berrange * 1357d969014SDaniel P. Berrange * This method will allocate space for a new volume header 1367d969014SDaniel P. Berrange * using @initfunc and then write header data using @writefunc, 1377d969014SDaniel P. Berrange * generating new master keys, etc as required. Any existing 1387d969014SDaniel P. Berrange * data present on the volume will be irrevocably destroyed. 1397d969014SDaniel P. Berrange * 140d74523a3SHyman Huang * If @flags contains QCRYPTO_BLOCK_CREATE_DETACHED then 141d74523a3SHyman Huang * the open process will set the payload_offset_sector to 0 142d74523a3SHyman Huang * to specify the starting point for the read/write of a 143d74523a3SHyman Huang * detached LUKS header image. 144d74523a3SHyman Huang * 1457d969014SDaniel P. Berrange * If any part of initializing the encryption context 1467d969014SDaniel P. Berrange * fails an error will be returned. This could be due 1477d969014SDaniel P. Berrange * to the volume being in the wrong format, a cipher 1487d969014SDaniel P. Berrange * or IV generator algorithm that is not supported, 1497d969014SDaniel P. Berrange * or incorrect passphrases. 1507d969014SDaniel P. Berrange * 1517d969014SDaniel P. Berrange * Returns: a block encryption format, or NULL on error 1527d969014SDaniel P. Berrange */ 1537d969014SDaniel P. Berrange QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, 1541cd9a787SDaniel P. Berrange const char *optprefix, 1557d969014SDaniel P. Berrange QCryptoBlockInitFunc initfunc, 1567d969014SDaniel P. Berrange QCryptoBlockWriteFunc writefunc, 1577d969014SDaniel P. Berrange void *opaque, 158d74523a3SHyman Huang unsigned int flags, 1597d969014SDaniel P. Berrange Error **errp); 1607d969014SDaniel P. Berrange 16143cbd06dSMaxim Levitsky /** 16243cbd06dSMaxim Levitsky * qcrypto_block_amend_options: 16343cbd06dSMaxim Levitsky * @block: the block encryption object 16443cbd06dSMaxim Levitsky * 16543cbd06dSMaxim Levitsky * @readfunc: callback for reading data from the volume header 16643cbd06dSMaxim Levitsky * @writefunc: callback for writing data to the volume header 16743cbd06dSMaxim Levitsky * @opaque: data to pass to @readfunc and @writefunc 16843cbd06dSMaxim Levitsky * @options: the new/amended encryption options 16943cbd06dSMaxim Levitsky * @force: hint for the driver to allow unsafe operation 17043cbd06dSMaxim Levitsky * @errp: error pointer 17143cbd06dSMaxim Levitsky * 17243cbd06dSMaxim Levitsky * Changes the crypto options of the encryption format 17343cbd06dSMaxim Levitsky * 17443cbd06dSMaxim Levitsky */ 17543cbd06dSMaxim Levitsky int qcrypto_block_amend_options(QCryptoBlock *block, 17643cbd06dSMaxim Levitsky QCryptoBlockReadFunc readfunc, 17743cbd06dSMaxim Levitsky QCryptoBlockWriteFunc writefunc, 17843cbd06dSMaxim Levitsky void *opaque, 17943cbd06dSMaxim Levitsky QCryptoBlockAmendOptions *options, 18043cbd06dSMaxim Levitsky bool force, 18143cbd06dSMaxim Levitsky Error **errp); 18243cbd06dSMaxim Levitsky 18340c85028SDaniel P. Berrange 18440c85028SDaniel P. Berrange /** 1856d49d3a8SStefan Hajnoczi * qcrypto_block_calculate_payload_offset: 1866d49d3a8SStefan Hajnoczi * @create_opts: the encryption options 1876d49d3a8SStefan Hajnoczi * @optprefix: name prefix for options 1886d49d3a8SStefan Hajnoczi * @len: output for number of header bytes before payload 1896d49d3a8SStefan Hajnoczi * @errp: pointer to a NULL-initialized error object 1906d49d3a8SStefan Hajnoczi * 1916d49d3a8SStefan Hajnoczi * Calculate the number of header bytes before the payload in an encrypted 1926d49d3a8SStefan Hajnoczi * storage volume. The header is an area before the payload that is reserved 1936d49d3a8SStefan Hajnoczi * for encryption metadata. 1946d49d3a8SStefan Hajnoczi * 1956d49d3a8SStefan Hajnoczi * Returns: true on success, false on error 1966d49d3a8SStefan Hajnoczi */ 1976d49d3a8SStefan Hajnoczi bool 1986d49d3a8SStefan Hajnoczi qcrypto_block_calculate_payload_offset(QCryptoBlockCreateOptions *create_opts, 1996d49d3a8SStefan Hajnoczi const char *optprefix, 2006d49d3a8SStefan Hajnoczi size_t *len, 2016d49d3a8SStefan Hajnoczi Error **errp); 2026d49d3a8SStefan Hajnoczi 2036d49d3a8SStefan Hajnoczi 2046d49d3a8SStefan Hajnoczi /** 20540c85028SDaniel P. Berrange * qcrypto_block_get_info: 20640c85028SDaniel P. Berrange * @block: the block encryption object 20740c85028SDaniel P. Berrange * @errp: pointer to a NULL-initialized error object 20840c85028SDaniel P. Berrange * 20940c85028SDaniel P. Berrange * Get information about the configuration options for the 21040c85028SDaniel P. Berrange * block encryption object. This includes details such as 21140c85028SDaniel P. Berrange * the cipher algorithms, modes, and initialization vector 21240c85028SDaniel P. Berrange * generators. 21340c85028SDaniel P. Berrange * 21440c85028SDaniel P. Berrange * Returns: a block encryption info object, or NULL on error 21540c85028SDaniel P. Berrange */ 21640c85028SDaniel P. Berrange QCryptoBlockInfo *qcrypto_block_get_info(QCryptoBlock *block, 21740c85028SDaniel P. Berrange Error **errp); 21840c85028SDaniel P. Berrange 2197d969014SDaniel P. Berrange /** 2207d969014SDaniel P. Berrange * @qcrypto_block_decrypt: 2217d969014SDaniel P. Berrange * @block: the block encryption object 2224609742aSDaniel P. Berrange * @offset: the position at which @iov was read 2237d969014SDaniel P. Berrange * @buf: the buffer to decrypt 2247d969014SDaniel P. Berrange * @len: the length of @buf in bytes 2257d969014SDaniel P. Berrange * @errp: pointer to a NULL-initialized error object 2267d969014SDaniel P. Berrange * 2277d969014SDaniel P. Berrange * Decrypt @len bytes of cipher text in @buf, writing 2284609742aSDaniel P. Berrange * plain text back into @buf. @len and @offset must be 2294609742aSDaniel P. Berrange * a multiple of the encryption format sector size. 2307d969014SDaniel P. Berrange * 2317d969014SDaniel P. Berrange * Returns 0 on success, -1 on failure 2327d969014SDaniel P. Berrange */ 2337d969014SDaniel P. Berrange int qcrypto_block_decrypt(QCryptoBlock *block, 2344609742aSDaniel P. Berrange uint64_t offset, 2357d969014SDaniel P. Berrange uint8_t *buf, 2367d969014SDaniel P. Berrange size_t len, 2377d969014SDaniel P. Berrange Error **errp); 2387d969014SDaniel P. Berrange 2397d969014SDaniel P. Berrange /** 2407d969014SDaniel P. Berrange * @qcrypto_block_encrypt: 2417d969014SDaniel P. Berrange * @block: the block encryption object 2424609742aSDaniel P. Berrange * @offset: the position at which @iov will be written 2437d969014SDaniel P. Berrange * @buf: the buffer to decrypt 2447d969014SDaniel P. Berrange * @len: the length of @buf in bytes 2457d969014SDaniel P. Berrange * @errp: pointer to a NULL-initialized error object 2467d969014SDaniel P. Berrange * 2477d969014SDaniel P. Berrange * Encrypt @len bytes of plain text in @buf, writing 2484609742aSDaniel P. Berrange * cipher text back into @buf. @len and @offset must be 2494609742aSDaniel P. Berrange * a multiple of the encryption format sector size. 2507d969014SDaniel P. Berrange * 2517d969014SDaniel P. Berrange * Returns 0 on success, -1 on failure 2527d969014SDaniel P. Berrange */ 2537d969014SDaniel P. Berrange int qcrypto_block_encrypt(QCryptoBlock *block, 2544609742aSDaniel P. Berrange uint64_t offset, 2557d969014SDaniel P. Berrange uint8_t *buf, 2567d969014SDaniel P. Berrange size_t len, 2577d969014SDaniel P. Berrange Error **errp); 2587d969014SDaniel P. Berrange 2597d969014SDaniel P. Berrange /** 2607d969014SDaniel P. Berrange * qcrypto_block_get_cipher: 2617d969014SDaniel P. Berrange * @block: the block encryption object 2627d969014SDaniel P. Berrange * 2637d969014SDaniel P. Berrange * Get the cipher to use for payload encryption 2647d969014SDaniel P. Berrange * 2657d969014SDaniel P. Berrange * Returns: the cipher object 2667d969014SDaniel P. Berrange */ 2677d969014SDaniel P. Berrange QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block); 2687d969014SDaniel P. Berrange 2697d969014SDaniel P. Berrange /** 2707d969014SDaniel P. Berrange * qcrypto_block_get_ivgen: 2717d969014SDaniel P. Berrange * @block: the block encryption object 2727d969014SDaniel P. Berrange * 2737d969014SDaniel P. Berrange * Get the initialization vector generator to use for 2747d969014SDaniel P. Berrange * payload encryption 2757d969014SDaniel P. Berrange * 2767d969014SDaniel P. Berrange * Returns: the IV generator object 2777d969014SDaniel P. Berrange */ 2787d969014SDaniel P. Berrange QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block); 2797d969014SDaniel P. Berrange 2807d969014SDaniel P. Berrange 2817d969014SDaniel P. Berrange /** 2827d969014SDaniel P. Berrange * qcrypto_block_get_kdf_hash: 2837d969014SDaniel P. Berrange * @block: the block encryption object 2847d969014SDaniel P. Berrange * 2857d969014SDaniel P. Berrange * Get the hash algorithm used with the key derivation 2867d969014SDaniel P. Berrange * function 2877d969014SDaniel P. Berrange * 2887d969014SDaniel P. Berrange * Returns: the hash algorithm 2897d969014SDaniel P. Berrange */ 290*ef834aa2SMarkus Armbruster QCryptoHashAlgo qcrypto_block_get_kdf_hash(QCryptoBlock *block); 2917d969014SDaniel P. Berrange 2927d969014SDaniel P. Berrange /** 2937d969014SDaniel P. Berrange * qcrypto_block_get_payload_offset: 2947d969014SDaniel P. Berrange * @block: the block encryption object 2957d969014SDaniel P. Berrange * 2967d969014SDaniel P. Berrange * Get the offset to the payload indicated by the 2977d969014SDaniel P. Berrange * encryption header, in bytes. 2987d969014SDaniel P. Berrange * 2997d969014SDaniel P. Berrange * Returns: the payload offset in bytes 3007d969014SDaniel P. Berrange */ 3017d969014SDaniel P. Berrange uint64_t qcrypto_block_get_payload_offset(QCryptoBlock *block); 3027d969014SDaniel P. Berrange 3037d969014SDaniel P. Berrange /** 304850f49deSDaniel P. Berrange * qcrypto_block_get_sector_size: 305850f49deSDaniel P. Berrange * @block: the block encryption object 306850f49deSDaniel P. Berrange * 307850f49deSDaniel P. Berrange * Get the size of sectors used for payload encryption. A new 308850f49deSDaniel P. Berrange * IV is used at the start of each sector. The encryption 309850f49deSDaniel P. Berrange * sector size is not required to match the sector size of the 310850f49deSDaniel P. Berrange * underlying storage. For example LUKS will always use a 512 311850f49deSDaniel P. Berrange * byte sector size, even if the volume is on a disk with 4k 312850f49deSDaniel P. Berrange * sectors. 313850f49deSDaniel P. Berrange * 314850f49deSDaniel P. Berrange * Returns: the sector in bytes 315850f49deSDaniel P. Berrange */ 316850f49deSDaniel P. Berrange uint64_t qcrypto_block_get_sector_size(QCryptoBlock *block); 317850f49deSDaniel P. Berrange 318850f49deSDaniel P. Berrange /** 3197d969014SDaniel P. Berrange * qcrypto_block_free: 3207d969014SDaniel P. Berrange * @block: the block encryption object 3217d969014SDaniel P. Berrange * 3227d969014SDaniel P. Berrange * Release all resources associated with the encryption 3237d969014SDaniel P. Berrange * object 3247d969014SDaniel P. Berrange */ 3257d969014SDaniel P. Berrange void qcrypto_block_free(QCryptoBlock *block); 3267d969014SDaniel P. Berrange 327133cf1e5SDaniel P. Berrangé G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoBlock, qcrypto_block_free) 328133cf1e5SDaniel P. Berrangé 3292a6a4076SMarkus Armbruster #endif /* QCRYPTO_BLOCK_H */ 330