xref: /openbmc/qemu/include/crypto/cipher.h (revision dd2bf9eb)
1 /*
2  * QEMU Crypto cipher algorithms
3  *
4  * Copyright (c) 2015 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_CIPHER_H__
22 #define QCRYPTO_CIPHER_H__
23 
24 #include "qemu-common.h"
25 #include "qapi/error.h"
26 
27 typedef struct QCryptoCipher QCryptoCipher;
28 
29 typedef enum {
30     QCRYPTO_CIPHER_ALG_AES_128,
31     QCRYPTO_CIPHER_ALG_AES_192,
32     QCRYPTO_CIPHER_ALG_AES_256,
33     QCRYPTO_CIPHER_ALG_DES_RFB, /* A stupid variant on DES for VNC */
34 
35     QCRYPTO_CIPHER_ALG_LAST
36 } QCryptoCipherAlgorithm;
37 
38 typedef enum {
39     QCRYPTO_CIPHER_MODE_ECB,
40     QCRYPTO_CIPHER_MODE_CBC,
41 
42     QCRYPTO_CIPHER_MODE_LAST
43 } QCryptoCipherMode;
44 
45 /**
46  * QCryptoCipher:
47  *
48  * The QCryptoCipher object provides a way to perform encryption
49  * and decryption of data, with a standard API, regardless of the
50  * algorithm used. It further isolates the calling code from the
51  * details of the specific underlying implementation, whether
52  * built-in, libgcrypt or nettle.
53  *
54  * Each QCryptoCipher object is capable of performing both
55  * encryption and decryption, and can operate in a number
56  * or modes including ECB, CBC.
57  *
58  * <example>
59  *   <title>Encrypting data with AES-128 in CBC mode</title>
60  *   <programlisting>
61  * QCryptoCipher *cipher;
62  * uint8_t key = ....;
63  * size_t keylen = 16;
64  * uint8_t iv = ....;
65  *
66  * if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALG_AES_128)) {
67  *    error_report(errp, "Feature <blah> requires AES cipher support");
68  *    return -1;
69  * }
70  *
71  * cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128,
72  *                             QCRYPTO_CIPHER_MODE_CBC,
73  *                             key, keylen,
74  *                             errp);
75  * if (!cipher) {
76  *    return -1;
77  * }
78  *
79  * if (qcrypto_cipher_set_iv(cipher, iv, keylen, errp) < 0) {
80  *    return -1;
81  * }
82  *
83  * if (qcrypto_cipher_encrypt(cipher, rawdata, encdata, datalen, errp) < 0) {
84  *    return -1;
85  * }
86  *
87  * qcrypto_cipher_free(cipher);
88  *   </programlisting>
89  * </example>
90  *
91  */
92 
93 struct QCryptoCipher {
94     QCryptoCipherAlgorithm alg;
95     QCryptoCipherMode mode;
96     void *opaque;
97 };
98 
99 /**
100  * qcrypto_cipher_supports:
101  * @alg: the cipher algorithm
102  *
103  * Determine if @alg cipher algorithm is supported by the
104  * current configured build
105  *
106  * Returns: true if the algorithm is supported, false otherwise
107  */
108 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg);
109 
110 /**
111  * qcrypto_cipher_get_block_len:
112  * @alg: the cipher algorithm
113  *
114  * Get the required data block size in bytes. When
115  * encrypting data, it must be a multiple of the
116  * block size.
117  *
118  * Returns: the block size in bytes
119  */
120 size_t qcrypto_cipher_get_block_len(QCryptoCipherAlgorithm alg);
121 
122 
123 /**
124  * qcrypto_cipher_get_key_len:
125  * @alg: the cipher algorithm
126  *
127  * Get the required key size in bytes.
128  *
129  * Returns: the key size in bytes
130  */
131 size_t qcrypto_cipher_get_key_len(QCryptoCipherAlgorithm alg);
132 
133 
134 /**
135  * qcrypto_cipher_get_iv_len:
136  * @alg: the cipher algorithm
137  * @mode: the cipher mode
138  *
139  * Get the required initialization vector size
140  * in bytes, if one is required.
141  *
142  * Returns: the IV size in bytes, or 0 if no IV is permitted
143  */
144 size_t qcrypto_cipher_get_iv_len(QCryptoCipherAlgorithm alg,
145                                  QCryptoCipherMode mode);
146 
147 
148 /**
149  * qcrypto_cipher_new:
150  * @alg: the cipher algorithm
151  * @mode: the cipher usage mode
152  * @key: the private key bytes
153  * @nkey: the length of @key
154  * @errp: pointer to an uninitialized error object
155  *
156  * Creates a new cipher object for encrypting/decrypting
157  * data with the algorithm @alg in the usage mode @mode.
158  *
159  * The @key parameter provides the bytes representing
160  * the encryption/decryption key to use. The @nkey parameter
161  * specifies the length of @key in bytes. Each algorithm has
162  * one or more valid key lengths, and it is an error to provide
163  * a key of the incorrect length.
164  *
165  * The returned cipher object must be released with
166  * qcrypto_cipher_free() when no longer required
167  *
168  * Returns: a new cipher object, or NULL on error
169  */
170 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
171                                   QCryptoCipherMode mode,
172                                   const uint8_t *key, size_t nkey,
173                                   Error **errp);
174 
175 /**
176  * qcrypto_cipher_free:
177  * @cipher: the cipher object
178  *
179  * Release the memory associated with @cipher that
180  * was previously allocated by qcrypto_cipher_new()
181  */
182 void qcrypto_cipher_free(QCryptoCipher *cipher);
183 
184 /**
185  * qcrypto_cipher_encrypt:
186  * @cipher: the cipher object
187  * @in: buffer holding the plain text input data
188  * @out: buffer to fill with the cipher text output data
189  * @len: the length of @in and @out buffers
190  * @errp: pointer to an uninitialized error object
191  *
192  * Encrypts the plain text stored in @in, filling
193  * @out with the resulting ciphered text. Both the
194  * @in and @out buffers must have the same size,
195  * given by @len.
196  *
197  * Returns: 0 on success, or -1 on error
198  */
199 int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
200                            const void *in,
201                            void *out,
202                            size_t len,
203                            Error **errp);
204 
205 
206 /**
207  * qcrypto_cipher_decrypt:
208  * @cipher: the cipher object
209  * @in: buffer holding the cipher text input data
210  * @out: buffer to fill with the plain text output data
211  * @len: the length of @in and @out buffers
212  * @errp: pointer to an uninitialized error object
213  *
214  * Decrypts the cipher text stored in @in, filling
215  * @out with the resulting plain text. Both the
216  * @in and @out buffers must have the same size,
217  * given by @len.
218  *
219  * Returns: 0 on success, or -1 on error
220  */
221 int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
222                            const void *in,
223                            void *out,
224                            size_t len,
225                            Error **errp);
226 
227 /**
228  * qcrypto_cipher_setiv:
229  * @cipher: the cipher object
230  * @iv: the initialization vector bytes
231  * @niv: the length of @iv
232  * @errpr: pointer to an uninitialized error object
233  *
234  * If the @cipher object is setup to use a mode that requires
235  * initialization vectors, this sets the initialization vector
236  * bytes. The @iv data should have the same length as the
237  * cipher key used when originally constructing the cipher
238  * object. It is an error to set an initialization vector
239  * if the cipher mode does not require one.
240  *
241  * Returns: 0 on success, -1 on error
242  */
243 int qcrypto_cipher_setiv(QCryptoCipher *cipher,
244                          const uint8_t *iv, size_t niv,
245                          Error **errp);
246 
247 #endif /* QCRYPTO_CIPHER_H__ */
248