qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

ivgen.h (6051B)


      1 /*
      2  * QEMU Crypto block IV generator
      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.1 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_IVGEN_H
     22 #define QCRYPTO_IVGEN_H
     23 
     24 #include "crypto/cipher.h"
     25 #include "crypto/hash.h"
     26 
     27 /**
     28  * This module provides a framework for generating initialization
     29  * vectors for block encryption schemes using chained cipher modes
     30  * CBC. The principle is that each disk sector is assigned a unique
     31  * initialization vector for use for encryption of data in that
     32  * sector.
     33  *
     34  * <example>
     35  *   <title>Encrypting block data with initialiation vectors</title>
     36  *   <programlisting>
     37  * uint8_t *data = ....data to encrypt...
     38  * size_t ndata = XXX;
     39  * uint8_t *key = ....some encryption key...
     40  * size_t nkey = XXX;
     41  * uint8_t *iv;
     42  * size_t niv;
     43  * size_t sector = 0;
     44  *
     45  * g_assert((ndata % 512) == 0);
     46  *
     47  * QCryptoIVGen *ivgen = qcrypto_ivgen_new(QCRYPTO_IVGEN_ALG_ESSIV,
     48  *                                         QCRYPTO_CIPHER_ALG_AES_128,
     49  *                                         QCRYPTO_HASH_ALG_SHA256,
     50  *                                         key, nkey, errp);
     51  * if (!ivgen) {
     52  *    return -1;
     53  * }
     54  *
     55  * QCryptoCipher *cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
     56  *                                            QCRYPTO_CIPHER_MODE_CBC,
     57  *                                            key, nkey, errp);
     58  * if (!cipher) {
     59  *     goto error;
     60  * }
     61  *
     62  * niv =  qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALG_AES_128,
     63  *                                  QCRYPTO_CIPHER_MODE_CBC);
     64  * iv = g_new0(uint8_t, niv);
     65  *
     66  *
     67  * while (ndata) {
     68  *     if (qcrypto_ivgen_calculate(ivgen, sector, iv, niv, errp) < 0) {
     69  *         goto error;
     70  *     }
     71  *     if (qcrypto_cipher_setiv(cipher, iv, niv, errp) < 0) {
     72  *         goto error;
     73  *     }
     74  *     if (qcrypto_cipher_encrypt(cipher,
     75  *                                data + (sector * 512),
     76  *                                data + (sector * 512),
     77  *                                512, errp) < 0) {
     78  *         goto error;
     79  *     }
     80  *     sector++;
     81  *     ndata -= 512;
     82  * }
     83  *
     84  * g_free(iv);
     85  * qcrypto_ivgen_free(ivgen);
     86  * qcrypto_cipher_free(cipher);
     87  * return 0;
     88  *
     89  *error:
     90  * g_free(iv);
     91  * qcrypto_ivgen_free(ivgen);
     92  * qcrypto_cipher_free(cipher);
     93  * return -1;
     94  *   </programlisting>
     95  * </example>
     96  */
     97 
     98 typedef struct QCryptoIVGen QCryptoIVGen;
     99 
    100 /* See also QCryptoIVGenAlgorithm enum in qapi/crypto.json */
    101 
    102 
    103 /**
    104  * qcrypto_ivgen_new:
    105  * @alg: the initialization vector generation algorithm
    106  * @cipheralg: the cipher algorithm or 0
    107  * @hash: the hash algorithm or 0
    108  * @key: the encryption key or NULL
    109  * @nkey: the size of @key in bytes
    110  *
    111  * Create a new initialization vector generator that uses
    112  * the algorithm @alg. Whether the remaining parameters
    113  * are required or not depends on the choice of @alg
    114  * requested.
    115  *
    116  * - QCRYPTO_IVGEN_ALG_PLAIN
    117  *
    118  * The IVs are generated by the 32-bit truncated sector
    119  * number. This should never be used for block devices
    120  * that are larger than 2^32 sectors in size.
    121  * All the other parameters are unused.
    122  *
    123  * - QCRYPTO_IVGEN_ALG_PLAIN64
    124  *
    125  * The IVs are generated by the 64-bit sector number.
    126  * All the other parameters are unused.
    127  *
    128  * - QCRYPTO_IVGEN_ALG_ESSIV:
    129  *
    130  * The IVs are generated by encrypting the 64-bit sector
    131  * number with a hash of an encryption key. The @cipheralg,
    132  * @hash, @key and @nkey parameters are all required.
    133  *
    134  * Returns: a new IV generator, or NULL on error
    135  */
    136 QCryptoIVGen *qcrypto_ivgen_new(QCryptoIVGenAlgorithm alg,
    137                                 QCryptoCipherAlgorithm cipheralg,
    138                                 QCryptoHashAlgorithm hash,
    139                                 const uint8_t *key, size_t nkey,
    140                                 Error **errp);
    141 
    142 /**
    143  * qcrypto_ivgen_calculate:
    144  * @ivgen: the IV generator object
    145  * @sector: the 64-bit sector number
    146  * @iv: a pre-allocated buffer to hold the generated IV
    147  * @niv: the number of bytes in @iv
    148  * @errp: pointer to a NULL-initialized error object
    149  *
    150  * Calculate a new initialiation vector for the data
    151  * to be stored in sector @sector. The IV will be
    152  * written into the buffer @iv of size @niv.
    153  *
    154  * Returns: 0 on success, -1 on error
    155  */
    156 int qcrypto_ivgen_calculate(QCryptoIVGen *ivgen,
    157                             uint64_t sector,
    158                             uint8_t *iv, size_t niv,
    159                             Error **errp);
    160 
    161 
    162 /**
    163  * qcrypto_ivgen_get_algorithm:
    164  * @ivgen: the IV generator object
    165  *
    166  * Get the algorithm used by this IV generator
    167  *
    168  * Returns: the IV generator algorithm
    169  */
    170 QCryptoIVGenAlgorithm qcrypto_ivgen_get_algorithm(QCryptoIVGen *ivgen);
    171 
    172 
    173 /**
    174  * qcrypto_ivgen_get_cipher:
    175  * @ivgen: the IV generator object
    176  *
    177  * Get the cipher algorithm used by this IV generator (if
    178  * applicable)
    179  *
    180  * Returns: the cipher algorithm
    181  */
    182 QCryptoCipherAlgorithm qcrypto_ivgen_get_cipher(QCryptoIVGen *ivgen);
    183 
    184 
    185 /**
    186  * qcrypto_ivgen_get_hash:
    187  * @ivgen: the IV generator object
    188  *
    189  * Get the hash algorithm used by this IV generator (if
    190  * applicable)
    191  *
    192  * Returns: the hash algorithm
    193  */
    194 QCryptoHashAlgorithm qcrypto_ivgen_get_hash(QCryptoIVGen *ivgen);
    195 
    196 
    197 /**
    198  * qcrypto_ivgen_free:
    199  * @ivgen: the IV generator object
    200  *
    201  * Release all resources associated with @ivgen, or a no-op
    202  * if @ivgen is NULL
    203  */
    204 void qcrypto_ivgen_free(QCryptoIVGen *ivgen);
    205 
    206 G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoIVGen, qcrypto_ivgen_free)
    207 
    208 #endif /* QCRYPTO_IVGEN_H */