cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

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
     98typedef 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 */
    136QCryptoIVGen *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 */
    156int 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 */
    170QCryptoIVGenAlgorithm 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 */
    182QCryptoCipherAlgorithm 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 */
    194QCryptoHashAlgorithm 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 */
    204void qcrypto_ivgen_free(QCryptoIVGen *ivgen);
    205
    206G_DEFINE_AUTOPTR_CLEANUP_FUNC(QCryptoIVGen, qcrypto_ivgen_free)
    207
    208#endif /* QCRYPTO_IVGEN_H */