Merge remote-tracking branch 'remotes/bsdimp/tags/pull-bsd-user-20210511' into staging
[qemu/ar7.git] / crypto / cipher-builtin.c.inc
blob7597cf4a10fd208664c7082240bba49f4fc38a0d
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.1 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  */
21 #include "crypto/aes.h"
22 #include "crypto/desrfb.h"
23 #include "crypto/xts.h"
25 typedef struct QCryptoCipherBuiltinAESContext QCryptoCipherBuiltinAESContext;
26 struct QCryptoCipherBuiltinAESContext {
27     AES_KEY enc;
28     AES_KEY dec;
31 typedef struct QCryptoCipherBuiltinAES QCryptoCipherBuiltinAES;
32 struct QCryptoCipherBuiltinAES {
33     QCryptoCipher base;
34     QCryptoCipherBuiltinAESContext key;
35     QCryptoCipherBuiltinAESContext key_tweak;
36     uint8_t iv[AES_BLOCK_SIZE];
40 static inline bool qcrypto_length_check(size_t len, size_t blocksize,
41                                         Error **errp)
43     if (unlikely(len & (blocksize - 1))) {
44         error_setg(errp, "Length %zu must be a multiple of block size %zu",
45                    len, blocksize);
46         return false;
47     }
48     return true;
51 static void qcrypto_cipher_ctx_free(QCryptoCipher *cipher)
53     g_free(cipher);
56 static int qcrypto_cipher_no_setiv(QCryptoCipher *cipher,
57                                    const uint8_t *iv, size_t niv,
58                                    Error **errp)
60     error_setg(errp, "Setting IV is not supported");
61     return -1;
64 static void do_aes_encrypt_ecb(const void *vctx,
65                                size_t len,
66                                uint8_t *out,
67                                const uint8_t *in)
69     const QCryptoCipherBuiltinAESContext *ctx = vctx;
71     /* We have already verified that len % AES_BLOCK_SIZE == 0. */
72     while (len) {
73         AES_encrypt(in, out, &ctx->enc);
74         in += AES_BLOCK_SIZE;
75         out += AES_BLOCK_SIZE;
76         len -= AES_BLOCK_SIZE;
77     }
80 static void do_aes_decrypt_ecb(const void *vctx,
81                                size_t len,
82                                uint8_t *out,
83                                const uint8_t *in)
85     const QCryptoCipherBuiltinAESContext *ctx = vctx;
87     /* We have already verified that len % AES_BLOCK_SIZE == 0. */
88     while (len) {
89         AES_decrypt(in, out, &ctx->dec);
90         in += AES_BLOCK_SIZE;
91         out += AES_BLOCK_SIZE;
92         len -= AES_BLOCK_SIZE;
93     }
96 static void do_aes_encrypt_cbc(const AES_KEY *key,
97                                size_t len,
98                                uint8_t *out,
99                                const uint8_t *in,
100                                uint8_t *ivec)
102     uint8_t tmp[AES_BLOCK_SIZE];
103     size_t n;
105     /* We have already verified that len % AES_BLOCK_SIZE == 0. */
106     while (len) {
107         for (n = 0; n < AES_BLOCK_SIZE; ++n) {
108             tmp[n] = in[n] ^ ivec[n];
109         }
110         AES_encrypt(tmp, out, key);
111         memcpy(ivec, out, AES_BLOCK_SIZE);
112         len -= AES_BLOCK_SIZE;
113         in += AES_BLOCK_SIZE;
114         out += AES_BLOCK_SIZE;
115     }
118 static void do_aes_decrypt_cbc(const AES_KEY *key,
119                                size_t len,
120                                uint8_t *out,
121                                const uint8_t *in,
122                                uint8_t *ivec)
124     uint8_t tmp[AES_BLOCK_SIZE];
125     size_t n;
127     /* We have already verified that len % AES_BLOCK_SIZE == 0. */
128     while (len) {
129         memcpy(tmp, in, AES_BLOCK_SIZE);
130         AES_decrypt(in, out, key);
131         for (n = 0; n < AES_BLOCK_SIZE; ++n) {
132             out[n] ^= ivec[n];
133         }
134         memcpy(ivec, tmp, AES_BLOCK_SIZE);
135         len -= AES_BLOCK_SIZE;
136         in += AES_BLOCK_SIZE;
137         out += AES_BLOCK_SIZE;
138     }
141 static int qcrypto_cipher_aes_encrypt_ecb(QCryptoCipher *cipher,
142                                           const void *in, void *out,
143                                           size_t len, Error **errp)
145     QCryptoCipherBuiltinAES *ctx
146         = container_of(cipher, QCryptoCipherBuiltinAES, base);
148     if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
149         return -1;
150     }
151     do_aes_encrypt_ecb(&ctx->key, len, out, in);
152     return 0;
155 static int qcrypto_cipher_aes_decrypt_ecb(QCryptoCipher *cipher,
156                                           const void *in, void *out,
157                                           size_t len, Error **errp)
159     QCryptoCipherBuiltinAES *ctx
160         = container_of(cipher, QCryptoCipherBuiltinAES, base);
162     if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
163         return -1;
164     }
165     do_aes_decrypt_ecb(&ctx->key, len, out, in);
166     return 0;
169 static int qcrypto_cipher_aes_encrypt_cbc(QCryptoCipher *cipher,
170                                           const void *in, void *out,
171                                           size_t len, Error **errp)
173     QCryptoCipherBuiltinAES *ctx
174         = container_of(cipher, QCryptoCipherBuiltinAES, base);
176     if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
177         return -1;
178     }
179     do_aes_encrypt_cbc(&ctx->key.enc, len, out, in, ctx->iv);
180     return 0;
183 static int qcrypto_cipher_aes_decrypt_cbc(QCryptoCipher *cipher,
184                                           const void *in, void *out,
185                                           size_t len, Error **errp)
187     QCryptoCipherBuiltinAES *ctx
188         = container_of(cipher, QCryptoCipherBuiltinAES, base);
190     if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
191         return -1;
192     }
193     do_aes_decrypt_cbc(&ctx->key.dec, len, out, in, ctx->iv);
194     return 0;
197 static int qcrypto_cipher_aes_encrypt_xts(QCryptoCipher *cipher,
198                                           const void *in, void *out,
199                                           size_t len, Error **errp)
201     QCryptoCipherBuiltinAES *ctx
202         = container_of(cipher, QCryptoCipherBuiltinAES, base);
204     if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
205         return -1;
206     }
207     xts_encrypt(&ctx->key, &ctx->key_tweak,
208                 do_aes_encrypt_ecb, do_aes_decrypt_ecb,
209                 ctx->iv, len, out, in);
210     return 0;
213 static int qcrypto_cipher_aes_decrypt_xts(QCryptoCipher *cipher,
214                                           const void *in, void *out,
215                                           size_t len, Error **errp)
217     QCryptoCipherBuiltinAES *ctx
218         = container_of(cipher, QCryptoCipherBuiltinAES, base);
220     if (!qcrypto_length_check(len, AES_BLOCK_SIZE, errp)) {
221         return -1;
222     }
223     xts_decrypt(&ctx->key, &ctx->key_tweak,
224                 do_aes_encrypt_ecb, do_aes_decrypt_ecb,
225                 ctx->iv, len, out, in);
226     return 0;
230 static int qcrypto_cipher_aes_setiv(QCryptoCipher *cipher, const uint8_t *iv,
231                              size_t niv, Error **errp)
233     QCryptoCipherBuiltinAES *ctx
234         = container_of(cipher, QCryptoCipherBuiltinAES, base);
236     if (niv != AES_BLOCK_SIZE) {
237         error_setg(errp, "IV must be %d bytes not %zu",
238                    AES_BLOCK_SIZE, niv);
239         return -1;
240     }
242     memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
243     return 0;
246 static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_ecb = {
247     .cipher_encrypt = qcrypto_cipher_aes_encrypt_ecb,
248     .cipher_decrypt = qcrypto_cipher_aes_decrypt_ecb,
249     .cipher_setiv = qcrypto_cipher_no_setiv,
250     .cipher_free = qcrypto_cipher_ctx_free,
253 static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_cbc = {
254     .cipher_encrypt = qcrypto_cipher_aes_encrypt_cbc,
255     .cipher_decrypt = qcrypto_cipher_aes_decrypt_cbc,
256     .cipher_setiv = qcrypto_cipher_aes_setiv,
257     .cipher_free = qcrypto_cipher_ctx_free,
260 static const struct QCryptoCipherDriver qcrypto_cipher_aes_driver_xts = {
261     .cipher_encrypt = qcrypto_cipher_aes_encrypt_xts,
262     .cipher_decrypt = qcrypto_cipher_aes_decrypt_xts,
263     .cipher_setiv = qcrypto_cipher_aes_setiv,
264     .cipher_free = qcrypto_cipher_ctx_free,
268 typedef struct QCryptoCipherBuiltinDESRFB QCryptoCipherBuiltinDESRFB;
269 struct QCryptoCipherBuiltinDESRFB {
270     QCryptoCipher base;
272     /* C.f. alg_key_len[QCRYPTO_CIPHER_ALG_DES_RFB] */
273     uint8_t key[8];
276 static int qcrypto_cipher_encrypt_des_rfb(QCryptoCipher *cipher,
277                                           const void *in, void *out,
278                                           size_t len, Error **errp)
280     QCryptoCipherBuiltinDESRFB *ctx
281         = container_of(cipher, QCryptoCipherBuiltinDESRFB, base);
282     size_t i;
284     if (!qcrypto_length_check(len, 8, errp)) {
285         return -1;
286     }
288     deskey(ctx->key, EN0);
290     for (i = 0; i < len; i += 8) {
291         des((void *)in + i, out + i);
292     }
294     return 0;
297 static int qcrypto_cipher_decrypt_des_rfb(QCryptoCipher *cipher,
298                                           const void *in, void *out,
299                                           size_t len, Error **errp)
301     QCryptoCipherBuiltinDESRFB *ctx
302         = container_of(cipher, QCryptoCipherBuiltinDESRFB, base);
303     size_t i;
305     if (!qcrypto_length_check(len, 8, errp)) {
306         return -1;
307     }
309     deskey(ctx->key, DE1);
311     for (i = 0; i < len; i += 8) {
312         des((void *)in + i, out + i);
313     }
315     return 0;
318 static const struct QCryptoCipherDriver qcrypto_cipher_des_rfb_driver = {
319     .cipher_encrypt = qcrypto_cipher_encrypt_des_rfb,
320     .cipher_decrypt = qcrypto_cipher_decrypt_des_rfb,
321     .cipher_setiv = qcrypto_cipher_no_setiv,
322     .cipher_free = qcrypto_cipher_ctx_free,
325 bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
326                              QCryptoCipherMode mode)
328     switch (alg) {
329     case QCRYPTO_CIPHER_ALG_DES_RFB:
330         return mode == QCRYPTO_CIPHER_MODE_ECB;
331     case QCRYPTO_CIPHER_ALG_AES_128:
332     case QCRYPTO_CIPHER_ALG_AES_192:
333     case QCRYPTO_CIPHER_ALG_AES_256:
334         switch (mode) {
335         case QCRYPTO_CIPHER_MODE_ECB:
336         case QCRYPTO_CIPHER_MODE_CBC:
337         case QCRYPTO_CIPHER_MODE_XTS:
338             return true;
339         default:
340             return false;
341         }
342         break;
343     default:
344         return false;
345     }
348 static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
349                                              QCryptoCipherMode mode,
350                                              const uint8_t *key,
351                                              size_t nkey,
352                                              Error **errp)
354     if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
355         return NULL;
356     }
358     switch (alg) {
359     case QCRYPTO_CIPHER_ALG_DES_RFB:
360         if (mode == QCRYPTO_CIPHER_MODE_ECB) {
361             QCryptoCipherBuiltinDESRFB *ctx;
363             ctx = g_new0(QCryptoCipherBuiltinDESRFB, 1);
364             ctx->base.driver = &qcrypto_cipher_des_rfb_driver;
365             memcpy(ctx->key, key, sizeof(ctx->key));
367             return &ctx->base;
368         }
369         goto bad_mode;
371     case QCRYPTO_CIPHER_ALG_AES_128:
372     case QCRYPTO_CIPHER_ALG_AES_192:
373     case QCRYPTO_CIPHER_ALG_AES_256:
374         {
375             QCryptoCipherBuiltinAES *ctx;
376             const QCryptoCipherDriver *drv;
378             switch (mode) {
379             case QCRYPTO_CIPHER_MODE_ECB:
380                 drv = &qcrypto_cipher_aes_driver_ecb;
381                 break;
382             case QCRYPTO_CIPHER_MODE_CBC:
383                 drv = &qcrypto_cipher_aes_driver_cbc;
384                 break;
385             case QCRYPTO_CIPHER_MODE_XTS:
386                 drv = &qcrypto_cipher_aes_driver_xts;
387                 break;
388             default:
389                 goto bad_mode;
390             }
392             ctx = g_new0(QCryptoCipherBuiltinAES, 1);
393             ctx->base.driver = drv;
395             if (mode == QCRYPTO_CIPHER_MODE_XTS) {
396                 nkey /= 2;
397                 if (AES_set_encrypt_key(key + nkey, nkey * 8,
398                                         &ctx->key_tweak.enc)) {
399                     error_setg(errp, "Failed to set encryption key");
400                     goto error;
401                 }
402                 if (AES_set_decrypt_key(key + nkey, nkey * 8,
403                                         &ctx->key_tweak.dec)) {
404                     error_setg(errp, "Failed to set decryption key");
405                     goto error;
406                 }
407             }
408             if (AES_set_encrypt_key(key, nkey * 8, &ctx->key.enc)) {
409                 error_setg(errp, "Failed to set encryption key");
410                 goto error;
411             }
412             if (AES_set_decrypt_key(key, nkey * 8, &ctx->key.dec)) {
413                 error_setg(errp, "Failed to set decryption key");
414                 goto error;
415             }
417             return &ctx->base;
419         error:
420             g_free(ctx);
421             return NULL;
422         }
424     default:
425         error_setg(errp,
426                    "Unsupported cipher algorithm %s",
427                    QCryptoCipherAlgorithm_str(alg));
428         return NULL;
429     }
431  bad_mode:
432     error_setg(errp, "Unsupported cipher mode %s",
433                QCryptoCipherMode_str(mode));
434     return NULL;