Add qemu 2.4.0
[kvmfornfv.git] / qemu / crypto / cipher-builtin.c
1 /*
2  * QEMU Crypto cipher built-in 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 #include "crypto/aes.h"
22 #include "crypto/desrfb.h"
23
24 typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES;
25 struct QCryptoCipherBuiltinAES {
26     AES_KEY encrypt_key;
27     AES_KEY decrypt_key;
28     uint8_t *iv;
29     size_t niv;
30 };
31 typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
32 struct QCryptoCipherBuiltinDESRFB {
33     uint8_t *key;
34     size_t nkey;
35 };
36
37 typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin;
38 struct QCryptoCipherBuiltin {
39     union {
40         QCryptoCipherBuiltinAES aes;
41         QCryptoCipherBuiltinDESRFB desrfb;
42     } state;
43     void (*free)(QCryptoCipher *cipher);
44     int (*setiv)(QCryptoCipher *cipher,
45                  const uint8_t *iv, size_t niv,
46                  Error **errp);
47     int (*encrypt)(QCryptoCipher *cipher,
48                    const void *in,
49                    void *out,
50                    size_t len,
51                    Error **errp);
52     int (*decrypt)(QCryptoCipher *cipher,
53                    const void *in,
54                    void *out,
55                    size_t len,
56                    Error **errp);
57 };
58
59
60 static void qcrypto_cipher_free_aes(QCryptoCipher *cipher)
61 {
62     QCryptoCipherBuiltin *ctxt = cipher->opaque;
63
64     g_free(ctxt->state.aes.iv);
65     g_free(ctxt);
66     cipher->opaque = NULL;
67 }
68
69
70 static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
71                                       const void *in,
72                                       void *out,
73                                       size_t len,
74                                       Error **errp)
75 {
76     QCryptoCipherBuiltin *ctxt = cipher->opaque;
77
78     if (cipher->mode == QCRYPTO_CIPHER_MODE_ECB) {
79         const uint8_t *inptr = in;
80         uint8_t *outptr = out;
81         while (len) {
82             if (len > AES_BLOCK_SIZE) {
83                 AES_encrypt(inptr, outptr, &ctxt->state.aes.encrypt_key);
84                 inptr += AES_BLOCK_SIZE;
85                 outptr += AES_BLOCK_SIZE;
86                 len -= AES_BLOCK_SIZE;
87             } else {
88                 uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
89                 memcpy(tmp1, inptr, len);
90                 /* Fill with 0 to avoid valgrind uninitialized reads */
91                 memset(tmp1 + len, 0, sizeof(tmp1) - len);
92                 AES_encrypt(tmp1, tmp2, &ctxt->state.aes.encrypt_key);
93                 memcpy(outptr, tmp2, len);
94                 len = 0;
95             }
96         }
97     } else {
98         AES_cbc_encrypt(in, out, len,
99                         &ctxt->state.aes.encrypt_key,
100                         ctxt->state.aes.iv, 1);
101     }
102
103     return 0;
104 }
105
106
107 static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
108                                       const void *in,
109                                       void *out,
110                                       size_t len,
111                                       Error **errp)
112 {
113     QCryptoCipherBuiltin *ctxt = cipher->opaque;
114
115     if (cipher->mode == QCRYPTO_CIPHER_MODE_ECB) {
116         const uint8_t *inptr = in;
117         uint8_t *outptr = out;
118         while (len) {
119             if (len > AES_BLOCK_SIZE) {
120                 AES_decrypt(inptr, outptr, &ctxt->state.aes.decrypt_key);
121                 inptr += AES_BLOCK_SIZE;
122                 outptr += AES_BLOCK_SIZE;
123                 len -= AES_BLOCK_SIZE;
124             } else {
125                 uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
126                 memcpy(tmp1, inptr, len);
127                 /* Fill with 0 to avoid valgrind uninitialized reads */
128                 memset(tmp1 + len, 0, sizeof(tmp1) - len);
129                 AES_decrypt(tmp1, tmp2, &ctxt->state.aes.decrypt_key);
130                 memcpy(outptr, tmp2, len);
131                 len = 0;
132             }
133         }
134     } else {
135         AES_cbc_encrypt(in, out, len,
136                         &ctxt->state.aes.decrypt_key,
137                         ctxt->state.aes.iv, 0);
138     }
139
140     return 0;
141 }
142
143 static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
144                                      const uint8_t *iv, size_t niv,
145                                      Error **errp)
146 {
147     QCryptoCipherBuiltin *ctxt = cipher->opaque;
148     if (niv != 16) {
149         error_setg(errp, "IV must be 16 bytes not %zu", niv);
150         return -1;
151     }
152
153     g_free(ctxt->state.aes.iv);
154     ctxt->state.aes.iv = g_new0(uint8_t, niv);
155     memcpy(ctxt->state.aes.iv, iv, niv);
156     ctxt->state.aes.niv = niv;
157
158     return 0;
159 }
160
161
162
163
164 static int qcrypto_cipher_init_aes(QCryptoCipher *cipher,
165                                    const uint8_t *key, size_t nkey,
166                                    Error **errp)
167 {
168     QCryptoCipherBuiltin *ctxt;
169
170     if (cipher->mode != QCRYPTO_CIPHER_MODE_CBC &&
171         cipher->mode != QCRYPTO_CIPHER_MODE_ECB) {
172         error_setg(errp, "Unsupported cipher mode %d", cipher->mode);
173         return -1;
174     }
175
176     ctxt = g_new0(QCryptoCipherBuiltin, 1);
177
178     if (AES_set_encrypt_key(key, nkey * 8, &ctxt->state.aes.encrypt_key) != 0) {
179         error_setg(errp, "Failed to set encryption key");
180         goto error;
181     }
182
183     if (AES_set_decrypt_key(key, nkey * 8, &ctxt->state.aes.decrypt_key) != 0) {
184         error_setg(errp, "Failed to set decryption key");
185         goto error;
186     }
187
188     ctxt->free = qcrypto_cipher_free_aes;
189     ctxt->setiv = qcrypto_cipher_setiv_aes;
190     ctxt->encrypt = qcrypto_cipher_encrypt_aes;
191     ctxt->decrypt = qcrypto_cipher_decrypt_aes;
192
193     cipher->opaque = ctxt;
194
195     return 0;
196
197  error:
198     g_free(ctxt);
199     return -1;
200 }
201
202
203 static void qcrypto_cipher_free_des_rfb(QCryptoCipher *cipher)
204 {
205     QCryptoCipherBuiltin *ctxt = cipher->opaque;
206
207     g_free(ctxt->state.desrfb.key);
208     g_free(ctxt);
209     cipher->opaque = NULL;
210 }
211
212
213 static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher,
214                                           const void *in,
215                                           void *out,
216                                           size_t len,
217                                           Error **errp)
218 {
219     QCryptoCipherBuiltin *ctxt = cipher->opaque;
220     size_t i;
221
222     if (len % 8) {
223         error_setg(errp, "Buffer size must be multiple of 8 not %zu",
224                    len);
225         return -1;
226     }
227
228     deskey(ctxt->state.desrfb.key, EN0);
229
230     for (i = 0; i < len; i += 8) {
231         des((void *)in + i, out + i);
232     }
233
234     return 0;
235 }
236
237
238 static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher,
239                                           const void *in,
240                                           void *out,
241                                           size_t len,
242                                           Error **errp)
243 {
244     QCryptoCipherBuiltin *ctxt = cipher->opaque;
245     size_t i;
246
247     if (len % 8) {
248         error_setg(errp, "Buffer size must be multiple of 8 not %zu",
249                    len);
250         return -1;
251     }
252
253     deskey(ctxt->state.desrfb.key, DE1);
254
255     for (i = 0; i < len; i += 8) {
256         des((void *)in + i, out + i);
257     }
258
259     return 0;
260 }
261
262
263 static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher *cipher,
264                                         const uint8_t *iv, size_t niv,
265                                         Error **errp)
266 {
267     error_setg(errp, "Setting IV is not supported");
268     return -1;
269 }
270
271
272 static int qcrypto_cipher_init_des_rfb(QCryptoCipher *cipher,
273                                        const uint8_t *key, size_t nkey,
274                                        Error **errp)
275 {
276     QCryptoCipherBuiltin *ctxt;
277
278     if (cipher->mode != QCRYPTO_CIPHER_MODE_ECB) {
279         error_setg(errp, "Unsupported cipher mode %d", cipher->mode);
280         return -1;
281     }
282
283     ctxt = g_new0(QCryptoCipherBuiltin, 1);
284
285     ctxt->state.desrfb.key = g_new0(uint8_t, nkey);
286     memcpy(ctxt->state.desrfb.key, key, nkey);
287     ctxt->state.desrfb.nkey = nkey;
288
289     ctxt->free = qcrypto_cipher_free_des_rfb;
290     ctxt->setiv = qcrypto_cipher_setiv_des_rfb;
291     ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
292     ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb;
293
294     cipher->opaque = ctxt;
295
296     return 0;
297 }
298
299
300 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg)
301 {
302     switch (alg) {
303     case QCRYPTO_CIPHER_ALG_DES_RFB:
304     case QCRYPTO_CIPHER_ALG_AES_128:
305     case QCRYPTO_CIPHER_ALG_AES_192:
306     case QCRYPTO_CIPHER_ALG_AES_256:
307         return true;
308     default:
309         return false;
310     }
311 }
312
313
314 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
315                                   QCryptoCipherMode mode,
316                                   const uint8_t *key, size_t nkey,
317                                   Error **errp)
318 {
319     QCryptoCipher *cipher;
320
321     cipher = g_new0(QCryptoCipher, 1);
322     cipher->alg = alg;
323     cipher->mode = mode;
324
325     if (!qcrypto_cipher_validate_key_length(alg, nkey, errp)) {
326         goto error;
327     }
328
329     switch (cipher->alg) {
330     case QCRYPTO_CIPHER_ALG_DES_RFB:
331         if (qcrypto_cipher_init_des_rfb(cipher, key, nkey, errp) < 0) {
332             goto error;
333         }
334         break;
335     case QCRYPTO_CIPHER_ALG_AES_128:
336     case QCRYPTO_CIPHER_ALG_AES_192:
337     case QCRYPTO_CIPHER_ALG_AES_256:
338         if (qcrypto_cipher_init_aes(cipher, key, nkey, errp) < 0) {
339             goto error;
340         }
341         break;
342     default:
343         error_setg(errp,
344                    "Unsupported cipher algorithm %d", cipher->alg);
345         goto error;
346     }
347
348     return cipher;
349
350  error:
351     g_free(cipher);
352     return NULL;
353 }
354
355 void qcrypto_cipher_free(QCryptoCipher *cipher)
356 {
357     QCryptoCipherBuiltin *ctxt;
358
359     if (!cipher) {
360         return;
361     }
362
363     ctxt = cipher->opaque;
364     ctxt->free(cipher);
365     g_free(cipher);
366 }
367
368
369 int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
370                            const void *in,
371                            void *out,
372                            size_t len,
373                            Error **errp)
374 {
375     QCryptoCipherBuiltin *ctxt = cipher->opaque;
376
377     return ctxt->encrypt(cipher, in, out, len, errp);
378 }
379
380
381 int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
382                            const void *in,
383                            void *out,
384                            size_t len,
385                            Error **errp)
386 {
387     QCryptoCipherBuiltin *ctxt = cipher->opaque;
388
389     return ctxt->decrypt(cipher, in, out, len, errp);
390 }
391
392
393 int qcrypto_cipher_setiv(QCryptoCipher *cipher,
394                          const uint8_t *iv, size_t niv,
395                          Error **errp)
396 {
397     QCryptoCipherBuiltin *ctxt = cipher->opaque;
398
399     return ctxt->setiv(cipher, iv, niv, errp);
400 }