]> git.proxmox.com Git - mirror_qemu.git/blob - include/crypto/ivgen.h
09cdb6fcd9e1a66ca0c73f666b12071f4b3d9745
[mirror_qemu.git] / include / crypto / ivgen.h
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 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 #endif /* QCRYPTO_IVGEN_H__ */