xref: /openbmc/qemu/include/crypto/cipher.h (revision b45c03f5)
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 /**
112  * qcrypto_cipher_new:
113  * @alg: the cipher algorithm
114  * @mode: the cipher usage mode
115  * @key: the private key bytes
116  * @nkey: the length of @key
117  * @errp: pointer to an uninitialized error object
118  *
119  * Creates a new cipher object for encrypting/decrypting
120  * data with the algorithm @alg in the usage mode @mode.
121  *
122  * The @key parameter provides the bytes representing
123  * the encryption/decryption key to use. The @nkey parameter
124  * specifies the length of @key in bytes. Each algorithm has
125  * one or more valid key lengths, and it is an error to provide
126  * a key of the incorrect length.
127  *
128  * The returned cipher object must be released with
129  * qcrypto_cipher_free() when no longer required
130  *
131  * Returns: a new cipher object, or NULL on error
132  */
133 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
134                                   QCryptoCipherMode mode,
135                                   const uint8_t *key, size_t nkey,
136                                   Error **errp);
137 
138 /**
139  * qcrypto_cipher_free:
140  * @cipher: the cipher object
141  *
142  * Release the memory associated with @cipher that
143  * was previously allocated by qcrypto_cipher_new()
144  */
145 void qcrypto_cipher_free(QCryptoCipher *cipher);
146 
147 /**
148  * qcrypto_cipher_encrypt:
149  * @cipher: the cipher object
150  * @in: buffer holding the plain text input data
151  * @out: buffer to fill with the cipher text output data
152  * @len: the length of @in and @out buffers
153  * @errp: pointer to an uninitialized error object
154  *
155  * Encrypts the plain text stored in @in, filling
156  * @out with the resulting ciphered text. Both the
157  * @in and @out buffers must have the same size,
158  * given by @len.
159  *
160  * Returns: 0 on success, or -1 on error
161  */
162 int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
163                            const void *in,
164                            void *out,
165                            size_t len,
166                            Error **errp);
167 
168 
169 /**
170  * qcrypto_cipher_decrypt:
171  * @cipher: the cipher object
172  * @in: buffer holding the cipher text input data
173  * @out: buffer to fill with the plain text output data
174  * @len: the length of @in and @out buffers
175  * @errp: pointer to an uninitialized error object
176  *
177  * Decrypts the cipher text stored in @in, filling
178  * @out with the resulting plain text. Both the
179  * @in and @out buffers must have the same size,
180  * given by @len.
181  *
182  * Returns: 0 on success, or -1 on error
183  */
184 int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
185                            const void *in,
186                            void *out,
187                            size_t len,
188                            Error **errp);
189 
190 /**
191  * qcrypto_cipher_setiv:
192  * @cipher: the cipher object
193  * @iv: the initialization vector bytes
194  * @niv: the length of @iv
195  * @errpr: pointer to an uninitialized error object
196  *
197  * If the @cipher object is setup to use a mode that requires
198  * initialization vectors, this sets the initialization vector
199  * bytes. The @iv data should have the same length as the
200  * cipher key used when originally constructing the cipher
201  * object. It is an error to set an initialization vector
202  * if the cipher mode does not require one.
203  *
204  * Returns: 0 on success, -1 on error
205  */
206 int qcrypto_cipher_setiv(QCryptoCipher *cipher,
207                          const uint8_t *iv, size_t niv,
208                          Error **errp);
209 
210 #endif /* QCRYPTO_CIPHER_H__ */
211