]> Git Repo - qemu.git/blob - crypto/cipher-builtin.c
ACPI: Add vmgenid blob storage to the build tables
[qemu.git] / 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 "qemu/osdep.h"
22 #include "crypto/aes.h"
23 #include "crypto/desrfb.h"
24 #include "crypto/xts.h"
25
26 typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext;
27 struct QCryptoCipherBuiltinAESContext {
28     AES_KEY enc;
29     AES_KEY dec;
30 };
31 typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES;
32 struct QCryptoCipherBuiltinAES {
33     QCryptoCipherBuiltinAESContext key;
34     QCryptoCipherBuiltinAESContext key_tweak;
35     uint8_t iv[AES_BLOCK_SIZE];
36 };
37 typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
38 struct QCryptoCipherBuiltinDESRFB {
39     uint8_t *key;
40     size_t nkey;
41 };
42
43 typedef struct QCryptoCipherBuiltin QCryptoCipherBuiltin;
44 struct QCryptoCipherBuiltin {
45     union {
46         QCryptoCipherBuiltinAES aes;
47         QCryptoCipherBuiltinDESRFB desrfb;
48     } state;
49     size_t blocksize;
50     void (*free)(QCryptoCipher *cipher);
51     int (*setiv)(QCryptoCipher *cipher,
52                  const uint8_t *iv, size_t niv,
53                  Error **errp);
54     int (*encrypt)(QCryptoCipher *cipher,
55                    const void *in,
56                    void *out,
57                    size_t len,
58                    Error **errp);
59     int (*decrypt)(QCryptoCipher *cipher,
60                    const void *in,
61                    void *out,
62                    size_t len,
63                    Error **errp);
64 };
65
66
67 static void qcrypto_cipher_free_aes(QCryptoCipher *cipher)
68 {
69     QCryptoCipherBuiltin *ctxt = cipher->opaque;
70
71     g_free(ctxt);
72     cipher->opaque = NULL;
73 }
74
75
76 static void qcrypto_cipher_aes_ecb_encrypt(AES_KEY *key,
77                                            const void *in,
78                                            void *out,
79                                            size_t len)
80 {
81     const uint8_t *inptr = in;
82     uint8_t *outptr = out;
83     while (len) {
84         if (len > AES_BLOCK_SIZE) {
85             AES_encrypt(inptr, outptr, key);
86             inptr += AES_BLOCK_SIZE;
87             outptr += AES_BLOCK_SIZE;
88             len -= AES_BLOCK_SIZE;
89         } else {
90             uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
91             memcpy(tmp1, inptr, len);
92             /* Fill with 0 to avoid valgrind uninitialized reads */
93             memset(tmp1 + len, 0, sizeof(tmp1) - len);
94             AES_encrypt(tmp1, tmp2, key);
95             memcpy(outptr, tmp2, len);
96             len = 0;
97         }
98     }
99 }
100
101
102 static void qcrypto_cipher_aes_ecb_decrypt(AES_KEY *key,
103                                            const void *in,
104                                            void *out,
105                                            size_t len)
106 {
107     const uint8_t *inptr = in;
108     uint8_t *outptr = out;
109     while (len) {
110         if (len > AES_BLOCK_SIZE) {
111             AES_decrypt(inptr, outptr, key);
112             inptr += AES_BLOCK_SIZE;
113             outptr += AES_BLOCK_SIZE;
114             len -= AES_BLOCK_SIZE;
115         } else {
116             uint8_t tmp1[AES_BLOCK_SIZE], tmp2[AES_BLOCK_SIZE];
117             memcpy(tmp1, inptr, len);
118             /* Fill with 0 to avoid valgrind uninitialized reads */
119             memset(tmp1 + len, 0, sizeof(tmp1) - len);
120             AES_decrypt(tmp1, tmp2, key);
121             memcpy(outptr, tmp2, len);
122             len = 0;
123         }
124     }
125 }
126
127
128 static void qcrypto_cipher_aes_xts_encrypt(const void *ctx,
129                                            size_t length,
130                                            uint8_t *dst,
131                                            const uint8_t *src)
132 {
133     const QCryptoCipherBuiltinAESContext *aesctx = ctx;
134
135     qcrypto_cipher_aes_ecb_encrypt((AES_KEY *)&aesctx->enc,
136                                    src, dst, length);
137 }
138
139
140 static void qcrypto_cipher_aes_xts_decrypt(const void *ctx,
141                                            size_t length,
142                                            uint8_t *dst,
143                                            const uint8_t *src)
144 {
145     const QCryptoCipherBuiltinAESContext *aesctx = ctx;
146
147     qcrypto_cipher_aes_ecb_decrypt((AES_KEY *)&aesctx->dec,
148                                    src, dst, length);
149 }
150
151
152 static int qcrypto_cipher_encrypt_aes(QCryptoCipher *cipher,
153                                       const void *in,
154                                       void *out,
155                                       size_t len,
156                                       Error **errp)
157 {
158     QCryptoCipherBuiltin *ctxt = cipher->opaque;
159
160     switch (cipher->mode) {
161     case QCRYPTO_CIPHER_MODE_ECB:
162         qcrypto_cipher_aes_ecb_encrypt(&ctxt->state.aes.key.enc,
163                                        in, out, len);
164         break;
165     case QCRYPTO_CIPHER_MODE_CBC:
166         AES_cbc_encrypt(in, out, len,
167                         &ctxt->state.aes.key.enc,
168                         ctxt->state.aes.iv, 1);
169         break;
170     case QCRYPTO_CIPHER_MODE_XTS:
171         xts_encrypt(&ctxt->state.aes.key,
172                     &ctxt->state.aes.key_tweak,
173                     qcrypto_cipher_aes_xts_encrypt,
174                     qcrypto_cipher_aes_xts_decrypt,
175                     ctxt->state.aes.iv,
176                     len, out, in);
177         break;
178     default:
179         g_assert_not_reached();
180     }
181
182     return 0;
183 }
184
185
186 static int qcrypto_cipher_decrypt_aes(QCryptoCipher *cipher,
187                                       const void *in,
188                                       void *out,
189                                       size_t len,
190                                       Error **errp)
191 {
192     QCryptoCipherBuiltin *ctxt = cipher->opaque;
193
194     switch (cipher->mode) {
195     case QCRYPTO_CIPHER_MODE_ECB:
196         qcrypto_cipher_aes_ecb_decrypt(&ctxt->state.aes.key.dec,
197                                        in, out, len);
198         break;
199     case QCRYPTO_CIPHER_MODE_CBC:
200         AES_cbc_encrypt(in, out, len,
201                         &ctxt->state.aes.key.dec,
202                         ctxt->state.aes.iv, 0);
203         break;
204     case QCRYPTO_CIPHER_MODE_XTS:
205         xts_decrypt(&ctxt->state.aes.key,
206                     &ctxt->state.aes.key_tweak,
207                     qcrypto_cipher_aes_xts_encrypt,
208                     qcrypto_cipher_aes_xts_decrypt,
209                     ctxt->state.aes.iv,
210                     len, out, in);
211         break;
212     default:
213         g_assert_not_reached();
214     }
215
216     return 0;
217 }
218
219 static int qcrypto_cipher_setiv_aes(QCryptoCipher *cipher,
220                                      const uint8_t *iv, size_t niv,
221                                      Error **errp)
222 {
223     QCryptoCipherBuiltin *ctxt = cipher->opaque;
224     if (niv != AES_BLOCK_SIZE) {
225         error_setg(errp, "IV must be %d bytes not %zu",
226                    AES_BLOCK_SIZE, niv);
227         return -1;
228     }
229
230     memcpy(ctxt->state.aes.iv, iv, AES_BLOCK_SIZE);
231
232     return 0;
233 }
234
235
236
237
238 static int qcrypto_cipher_init_aes(QCryptoCipher *cipher,
239                                    const uint8_t *key, size_t nkey,
240                                    Error **errp)
241 {
242     QCryptoCipherBuiltin *ctxt;
243
244     if (cipher->mode != QCRYPTO_CIPHER_MODE_CBC &&
245         cipher->mode != QCRYPTO_CIPHER_MODE_ECB &&
246         cipher->mode != QCRYPTO_CIPHER_MODE_XTS) {
247         error_setg(errp, "Unsupported cipher mode %s",
248                    QCryptoCipherMode_lookup[cipher->mode]);
249         return -1;
250     }
251
252     ctxt = g_new0(QCryptoCipherBuiltin, 1);
253
254     if (cipher->mode == QCRYPTO_CIPHER_MODE_XTS) {
255         if (AES_set_encrypt_key(key, nkey * 4, &ctxt->state.aes.key.enc) != 0) {
256             error_setg(errp, "Failed to set encryption key");
257             goto error;
258         }
259
260         if (AES_set_decrypt_key(key, nkey * 4, &ctxt->state.aes.key.dec) != 0) {
261             error_setg(errp, "Failed to set decryption key");
262             goto error;
263         }
264
265         if (AES_set_encrypt_key(key + (nkey / 2), nkey * 4,
266                                 &ctxt->state.aes.key_tweak.enc) != 0) {
267             error_setg(errp, "Failed to set encryption key");
268             goto error;
269         }
270
271         if (AES_set_decrypt_key(key + (nkey / 2), nkey * 4,
272                                 &ctxt->state.aes.key_tweak.dec) != 0) {
273             error_setg(errp, "Failed to set decryption key");
274             goto error;
275         }
276     } else {
277         if (AES_set_encrypt_key(key, nkey * 8, &ctxt->state.aes.key.enc) != 0) {
278             error_setg(errp, "Failed to set encryption key");
279             goto error;
280         }
281
282         if (AES_set_decrypt_key(key, nkey * 8, &ctxt->state.aes.key.dec) != 0) {
283             error_setg(errp, "Failed to set decryption key");
284             goto error;
285         }
286     }
287
288     ctxt->blocksize = AES_BLOCK_SIZE;
289     ctxt->free = qcrypto_cipher_free_aes;
290     ctxt->setiv = qcrypto_cipher_setiv_aes;
291     ctxt->encrypt = qcrypto_cipher_encrypt_aes;
292     ctxt->decrypt = qcrypto_cipher_decrypt_aes;
293
294     cipher->opaque = ctxt;
295
296     return 0;
297
298  error:
299     g_free(ctxt);
300     return -1;
301 }
302
303
304 static void qcrypto_cipher_free_des_rfb(QCryptoCipher *cipher)
305 {
306     QCryptoCipherBuiltin *ctxt = cipher->opaque;
307
308     g_free(ctxt->state.desrfb.key);
309     g_free(ctxt);
310     cipher->opaque = NULL;
311 }
312
313
314 static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher,
315                                           const void *in,
316                                           void *out,
317                                           size_t len,
318                                           Error **errp)
319 {
320     QCryptoCipherBuiltin *ctxt = cipher->opaque;
321     size_t i;
322
323     if (len % 8) {
324         error_setg(errp, "Buffer size must be multiple of 8 not %zu",
325                    len);
326         return -1;
327     }
328
329     deskey(ctxt->state.desrfb.key, EN0);
330
331     for (i = 0; i < len; i += 8) {
332         des((void *)in + i, out + i);
333     }
334
335     return 0;
336 }
337
338
339 static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher,
340                                           const void *in,
341                                           void *out,
342                                           size_t len,
343                                           Error **errp)
344 {
345     QCryptoCipherBuiltin *ctxt = cipher->opaque;
346     size_t i;
347
348     if (len % 8) {
349         error_setg(errp, "Buffer size must be multiple of 8 not %zu",
350                    len);
351         return -1;
352     }
353
354     deskey(ctxt->state.desrfb.key, DE1);
355
356     for (i = 0; i < len; i += 8) {
357         des((void *)in + i, out + i);
358     }
359
360     return 0;
361 }
362
363
364 static int qcrypto_cipher_setiv_des_rfb(QCryptoCipher *cipher,
365                                         const uint8_t *iv, size_t niv,
366                                         Error **errp)
367 {
368     error_setg(errp, "Setting IV is not supported");
369     return -1;
370 }
371
372
373 static int qcrypto_cipher_init_des_rfb(QCryptoCipher *cipher,
374                                        const uint8_t *key, size_t nkey,
375                                        Error **errp)
376 {
377     QCryptoCipherBuiltin *ctxt;
378
379     if (cipher->mode != QCRYPTO_CIPHER_MODE_ECB) {
380         error_setg(errp, "Unsupported cipher mode %s",
381                    QCryptoCipherMode_lookup[cipher->mode]);
382         return -1;
383     }
384
385     ctxt = g_new0(QCryptoCipherBuiltin, 1);
386
387     ctxt->state.desrfb.key = g_new0(uint8_t, nkey);
388     memcpy(ctxt->state.desrfb.key, key, nkey);
389     ctxt->state.desrfb.nkey = nkey;
390
391     ctxt->blocksize = 8;
392     ctxt->free = qcrypto_cipher_free_des_rfb;
393     ctxt->setiv = qcrypto_cipher_setiv_des_rfb;
394     ctxt->encrypt = qcrypto_cipher_encrypt_des_rfb;
395     ctxt->decrypt = qcrypto_cipher_decrypt_des_rfb;
396
397     cipher->opaque = ctxt;
398
399     return 0;
400 }
401
402
403 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
404                              QCryptoCipherMode mode)
405 {
406     switch (alg) {
407     case QCRYPTO_CIPHER_ALG_DES_RFB:
408     case QCRYPTO_CIPHER_ALG_AES_128:
409     case QCRYPTO_CIPHER_ALG_AES_192:
410     case QCRYPTO_CIPHER_ALG_AES_256:
411         break;
412     default:
413         return false;
414     }
415
416     switch (mode) {
417     case QCRYPTO_CIPHER_MODE_ECB:
418     case QCRYPTO_CIPHER_MODE_CBC:
419     case QCRYPTO_CIPHER_MODE_XTS:
420         return true;
421     case QCRYPTO_CIPHER_MODE_CTR:
422         return false;
423     default:
424         return false;
425     }
426 }
427
428
429 QCryptoCipher *qcrypto_cipher_new(QCryptoCipherAlgorithm alg,
430                                   QCryptoCipherMode mode,
431                                   const uint8_t *key, size_t nkey,
432                                   Error **errp)
433 {
434     QCryptoCipher *cipher;
435
436     switch (mode) {
437     case QCRYPTO_CIPHER_MODE_ECB:
438     case QCRYPTO_CIPHER_MODE_CBC:
439     case QCRYPTO_CIPHER_MODE_XTS:
440         break;
441     default:
442         error_setg(errp, "Unsupported cipher mode %s",
443                    QCryptoCipherMode_lookup[mode]);
444         return NULL;
445     }
446
447     cipher = g_new0(QCryptoCipher, 1);
448     cipher->alg = alg;
449     cipher->mode = mode;
450
451     if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
452         goto error;
453     }
454
455     switch (cipher->alg) {
456     case QCRYPTO_CIPHER_ALG_DES_RFB:
457         if (qcrypto_cipher_init_des_rfb(cipher, key, nkey, errp) < 0) {
458             goto error;
459         }
460         break;
461     case QCRYPTO_CIPHER_ALG_AES_128:
462     case QCRYPTO_CIPHER_ALG_AES_192:
463     case QCRYPTO_CIPHER_ALG_AES_256:
464         if (qcrypto_cipher_init_aes(cipher, key, nkey, errp) < 0) {
465             goto error;
466         }
467         break;
468     default:
469         error_setg(errp,
470                    "Unsupported cipher algorithm %s",
471                    QCryptoCipherAlgorithm_lookup[cipher->alg]);
472         goto error;
473     }
474
475     return cipher;
476
477  error:
478     g_free(cipher);
479     return NULL;
480 }
481
482 void qcrypto_cipher_free(QCryptoCipher *cipher)
483 {
484     QCryptoCipherBuiltin *ctxt;
485
486     if (!cipher) {
487         return;
488     }
489
490     ctxt = cipher->opaque;
491     ctxt->free(cipher);
492     g_free(cipher);
493 }
494
495
496 int qcrypto_cipher_encrypt(QCryptoCipher *cipher,
497                            const void *in,
498                            void *out,
499                            size_t len,
500                            Error **errp)
501 {
502     QCryptoCipherBuiltin *ctxt = cipher->opaque;
503
504     if (len % ctxt->blocksize) {
505         error_setg(errp, "Length %zu must be a multiple of block size %zu",
506                    len, ctxt->blocksize);
507         return -1;
508     }
509
510     return ctxt->encrypt(cipher, in, out, len, errp);
511 }
512
513
514 int qcrypto_cipher_decrypt(QCryptoCipher *cipher,
515                            const void *in,
516                            void *out,
517                            size_t len,
518                            Error **errp)
519 {
520     QCryptoCipherBuiltin *ctxt = cipher->opaque;
521
522     if (len % ctxt->blocksize) {
523         error_setg(errp, "Length %zu must be a multiple of block size %zu",
524                    len, ctxt->blocksize);
525         return -1;
526     }
527
528     return ctxt->decrypt(cipher, in, out, len, errp);
529 }
530
531
532 int qcrypto_cipher_setiv(QCryptoCipher *cipher,
533                          const uint8_t *iv, size_t niv,
534                          Error **errp)
535 {
536     QCryptoCipherBuiltin *ctxt = cipher->opaque;
537
538     return ctxt->setiv(cipher, iv, niv, errp);
539 }
This page took 0.055663 seconds and 4 git commands to generate.