blob: 24cc61f87bfc4ae7ab8ff523a4105a67bace67a1 [file] [log] [blame]
Daniel P. Berrangeed754742015-07-01 18:10:34 +01001/*
2 * QEMU Crypto cipher nettle 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
Thomas Huthb7cbb872019-02-13 16:54:59 +01009 * version 2.1 of the License, or (at your option) any later version.
Daniel P. Berrangeed754742015-07-01 18:10:34 +010010 *
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
Daniel P. Berrangédc2207a2019-10-14 17:28:27 +010021#ifdef CONFIG_QEMU_PRIVATE_XTS
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +000022#include "crypto/xts.h"
Daniel P. Berrangédc2207a2019-10-14 17:28:27 +010023#endif
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +000024
Daniel P. Berrangeed754742015-07-01 18:10:34 +010025#include <nettle/nettle-types.h>
26#include <nettle/aes.h>
27#include <nettle/des.h>
28#include <nettle/cbc.h>
Daniel P. Berrange084a85e2016-02-10 17:07:42 +000029#include <nettle/cast128.h>
Daniel P. Berrange94318522016-02-10 17:07:42 +000030#include <nettle/serpent.h>
Daniel P. Berrange50f67532016-02-10 17:07:42 +000031#include <nettle/twofish.h>
Gonglei3c282922016-09-26 17:23:22 +080032#include <nettle/ctr.h>
Daniel P. Berrangédc2207a2019-10-14 17:28:27 +010033#ifndef CONFIG_QEMU_PRIVATE_XTS
34#include <nettle/xts.h>
35#endif
Daniel P. Berrangeed754742015-07-01 18:10:34 +010036
Richard Henderson53ddad92020-08-28 10:05:22 -070037static inline bool qcrypto_length_check(size_t len, size_t blocksize,
38 Error **errp)
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +000039{
Richard Henderson53ddad92020-08-28 10:05:22 -070040 if (unlikely(len & (blocksize - 1))) {
41 error_setg(errp, "Length %zu must be a multiple of block size %zu",
42 len, blocksize);
43 return false;
44 }
45 return true;
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +000046}
47
Richard Henderson53ddad92020-08-28 10:05:22 -070048
49static void qcrypto_cipher_ctx_free(QCryptoCipher *ctx)
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +010050{
Richard Henderson53ddad92020-08-28 10:05:22 -070051 g_free(ctx);
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +010052}
53
Richard Henderson53ddad92020-08-28 10:05:22 -070054static int qcrypto_cipher_no_setiv(QCryptoCipher *cipher,
55 const uint8_t *iv, size_t niv,
56 Error **errp)
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +000057{
Richard Henderson53ddad92020-08-28 10:05:22 -070058 error_setg(errp, "Setting IV is not supported");
59 return -1;
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +010060}
61
Richard Henderson53ddad92020-08-28 10:05:22 -070062
63#define DEFINE_SETIV(NAME, TYPE, BLEN) \
64static int NAME##_setiv(QCryptoCipher *cipher, const uint8_t *iv, \
65 size_t niv, Error **errp) \
66{ \
67 TYPE *ctx = container_of(cipher, TYPE, base); \
68 if (niv != BLEN) { \
69 error_setg(errp, "Expected IV size %d not %zu", BLEN, niv); \
70 return -1; \
71 } \
72 memcpy(ctx->iv, iv, niv); \
73 return 0; \
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +010074}
75
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +010076
Richard Henderson53ddad92020-08-28 10:05:22 -070077#define DEFINE_ECB(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
78static int NAME##_encrypt_ecb(QCryptoCipher *cipher, const void *in, \
79 void *out, size_t len, Error **errp) \
80{ \
81 TYPE *ctx = container_of(cipher, TYPE, base); \
82 if (!qcrypto_length_check(len, BLEN, errp)) { \
83 return -1; \
84 } \
85 ENCRYPT(&ctx->key, len, out, in); \
86 return 0; \
87} \
88static int NAME##_decrypt_ecb(QCryptoCipher *cipher, const void *in, \
89 void *out, size_t len, Error **errp) \
90{ \
91 TYPE *ctx = container_of(cipher, TYPE, base); \
92 if (!qcrypto_length_check(len, BLEN, errp)) { \
93 return -1; \
94 } \
95 DECRYPT(&ctx->key, len, out, in); \
96 return 0; \
97} \
98static const struct QCryptoCipherDriver NAME##_driver_ecb = { \
99 .cipher_encrypt = NAME##_encrypt_ecb, \
100 .cipher_decrypt = NAME##_decrypt_ecb, \
101 .cipher_setiv = qcrypto_cipher_no_setiv, \
102 .cipher_free = qcrypto_cipher_ctx_free, \
103};
104
105
106#define DEFINE_CBC(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
107static int NAME##_encrypt_cbc(QCryptoCipher *cipher, const void *in, \
108 void *out, size_t len, Error **errp) \
109{ \
110 TYPE *ctx = container_of(cipher, TYPE, base); \
111 if (!qcrypto_length_check(len, BLEN, errp)) { \
112 return -1; \
113 } \
114 cbc_encrypt(&ctx->key, ENCRYPT, BLEN, ctx->iv, len, out, in); \
115 return 0; \
116} \
117static int NAME##_decrypt_cbc(QCryptoCipher *cipher, const void *in, \
118 void *out, size_t len, Error **errp) \
119{ \
120 TYPE *ctx = container_of(cipher, TYPE, base); \
121 if (!qcrypto_length_check(len, BLEN, errp)) { \
122 return -1; \
123 } \
124 cbc_decrypt(&ctx->key, DECRYPT, BLEN, ctx->iv, len, out, in); \
125 return 0; \
126} \
127static const struct QCryptoCipherDriver NAME##_driver_cbc = { \
128 .cipher_encrypt = NAME##_encrypt_cbc, \
129 .cipher_decrypt = NAME##_decrypt_cbc, \
130 .cipher_setiv = NAME##_setiv, \
131 .cipher_free = qcrypto_cipher_ctx_free, \
132};
133
134
135#define DEFINE_CTR(NAME, TYPE, BLEN, ENCRYPT) \
136static int NAME##_encrypt_ctr(QCryptoCipher *cipher, const void *in, \
137 void *out, size_t len, Error **errp) \
138{ \
139 TYPE *ctx = container_of(cipher, TYPE, base); \
140 if (!qcrypto_length_check(len, BLEN, errp)) { \
141 return -1; \
142 } \
143 ctr_crypt(&ctx->key, ENCRYPT, BLEN, ctx->iv, len, out, in); \
144 return 0; \
145} \
146static const struct QCryptoCipherDriver NAME##_driver_ctr = { \
147 .cipher_encrypt = NAME##_encrypt_ctr, \
148 .cipher_decrypt = NAME##_encrypt_ctr, \
149 .cipher_setiv = NAME##_setiv, \
150 .cipher_free = qcrypto_cipher_ctx_free, \
151};
152
153
154#ifdef CONFIG_QEMU_PRIVATE_XTS
155#define DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
156static void NAME##_xts_wrape(const void *ctx, size_t length, \
157 uint8_t *dst, const uint8_t *src) \
158{ \
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100159 ENCRYPT((const void *)ctx, length, dst, src); \
Richard Henderson53ddad92020-08-28 10:05:22 -0700160} \
161static void NAME##_xts_wrapd(const void *ctx, size_t length, \
162 uint8_t *dst, const uint8_t *src) \
163{ \
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100164 DECRYPT((const void *)ctx, length, dst, src); \
Richard Henderson53ddad92020-08-28 10:05:22 -0700165} \
166static int NAME##_encrypt_xts(QCryptoCipher *cipher, const void *in, \
167 void *out, size_t len, Error **errp) \
168{ \
169 TYPE *ctx = container_of(cipher, TYPE, base); \
170 if (!qcrypto_length_check(len, BLEN, errp)) { \
171 return -1; \
172 } \
173 xts_encrypt(&ctx->key, &ctx->key_xts, \
174 NAME##_xts_wrape, NAME##_xts_wrapd, \
175 ctx->iv, len, out, in); \
176 return 0; \
177} \
178static int NAME##_decrypt_xts(QCryptoCipher *cipher, const void *in, \
179 void *out, size_t len, Error **errp) \
180{ \
181 TYPE *ctx = container_of(cipher, TYPE, base); \
182 if (!qcrypto_length_check(len, BLEN, errp)) { \
183 return -1; \
184 } \
185 xts_decrypt(&ctx->key, &ctx->key_xts, \
186 NAME##_xts_wrape, NAME##_xts_wrapd, \
187 ctx->iv, len, out, in); \
188 return 0; \
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +0000189}
Richard Henderson53ddad92020-08-28 10:05:22 -0700190#else
191#define DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
192static int NAME##_encrypt_xts(QCryptoCipher *cipher, const void *in, \
193 void *out, size_t len, Error **errp) \
194{ \
195 TYPE *ctx = container_of(cipher, TYPE, base); \
196 if (!qcrypto_length_check(len, BLEN, errp)) { \
197 return -1; \
198 } \
199 xts_encrypt_message(&ctx->key, &ctx->key_xts, ENCRYPT, \
200 ctx->iv, len, out, in); \
201 return 0; \
202} \
203static int NAME##_decrypt_xts(QCryptoCipher *cipher, const void *in, \
204 void *out, size_t len, Error **errp) \
205{ \
206 TYPE *ctx = container_of(cipher, TYPE, base); \
207 if (!qcrypto_length_check(len, BLEN, errp)) { \
208 return -1; \
209 } \
210 xts_decrypt_message(&ctx->key, &ctx->key_xts, DECRYPT, ENCRYPT, \
211 ctx->iv, len, out, in); \
212 return 0; \
213}
214#endif
215
216#define DEFINE_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
217 QEMU_BUILD_BUG_ON(BLEN != XTS_BLOCK_SIZE); \
218 DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
219static const struct QCryptoCipherDriver NAME##_driver_xts = { \
220 .cipher_encrypt = NAME##_encrypt_xts, \
221 .cipher_decrypt = NAME##_decrypt_xts, \
222 .cipher_setiv = NAME##_setiv, \
223 .cipher_free = qcrypto_cipher_ctx_free, \
224};
225
226
227#define DEFINE_ECB_CBC_CTR(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
228 DEFINE_SETIV(NAME, TYPE, BLEN) \
229 DEFINE_ECB(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
230 DEFINE_CBC(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
231 DEFINE_CTR(NAME, TYPE, BLEN, ENCRYPT)
232
233#define DEFINE_ECB_CBC_CTR_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
234 DEFINE_ECB_CBC_CTR(NAME, TYPE, BLEN, ENCRYPT, DECRYPT) \
235 DEFINE_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)
236
237
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100238typedef struct QCryptoNettleDES {
Richard Henderson53ddad92020-08-28 10:05:22 -0700239 QCryptoCipher base;
240 struct des_ctx key;
241 uint8_t iv[DES_BLOCK_SIZE];
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100242} QCryptoNettleDES;
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +0000243
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100244static void des_encrypt_native(const void *ctx, size_t length,
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +0000245 uint8_t *dst, const uint8_t *src)
246{
247 des_encrypt(ctx, length, dst, src);
248}
249
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100250static void des_decrypt_native(const void *ctx, size_t length,
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +0000251 uint8_t *dst, const uint8_t *src)
252{
253 des_decrypt(ctx, length, dst, src);
254}
255
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100256DEFINE_ECB_CBC_CTR(qcrypto_nettle_des, QCryptoNettleDES,
Richard Henderson53ddad92020-08-28 10:05:22 -0700257 DES_BLOCK_SIZE, des_encrypt_native, des_decrypt_native)
258
259
260typedef struct QCryptoNettleDES3 {
261 QCryptoCipher base;
262 struct des3_ctx key;
263 uint8_t iv[DES3_BLOCK_SIZE];
264} QCryptoNettleDES3;
265
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100266static void des3_encrypt_native(const void *ctx, size_t length,
Longpeng(Mike)ffb7bf42016-12-08 10:33:28 +0800267 uint8_t *dst, const uint8_t *src)
268{
269 des3_encrypt(ctx, length, dst, src);
270}
271
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100272static void des3_decrypt_native(const void *ctx, size_t length,
Longpeng(Mike)ffb7bf42016-12-08 10:33:28 +0800273 uint8_t *dst, const uint8_t *src)
274{
275 des3_decrypt(ctx, length, dst, src);
276}
277
Richard Henderson53ddad92020-08-28 10:05:22 -0700278DEFINE_ECB_CBC_CTR(qcrypto_nettle_des3, QCryptoNettleDES3, DES3_BLOCK_SIZE,
279 des3_encrypt_native, des3_decrypt_native)
280
281
282typedef struct QCryptoNettleAES128 {
283 QCryptoCipher base;
284 uint8_t iv[AES_BLOCK_SIZE];
285 /* First key from pair is encode, second key is decode. */
286 struct aes128_ctx key[2], key_xts[2];
287} QCryptoNettleAES128;
288
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100289static void aes128_encrypt_native(const void *ctx, size_t length,
Richard Henderson53ddad92020-08-28 10:05:22 -0700290 uint8_t *dst, const uint8_t *src)
291{
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100292 const struct aes128_ctx *keys = ctx;
Richard Henderson53ddad92020-08-28 10:05:22 -0700293 aes128_encrypt(&keys[0], length, dst, src);
294}
295
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100296static void aes128_decrypt_native(const void *ctx, size_t length,
Richard Henderson53ddad92020-08-28 10:05:22 -0700297 uint8_t *dst, const uint8_t *src)
298{
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100299 const struct aes128_ctx *keys = ctx;
Richard Henderson53ddad92020-08-28 10:05:22 -0700300 aes128_decrypt(&keys[1], length, dst, src);
301}
302
303DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes128,
304 QCryptoNettleAES128, AES_BLOCK_SIZE,
305 aes128_encrypt_native, aes128_decrypt_native)
306
307
308typedef struct QCryptoNettleAES192 {
309 QCryptoCipher base;
310 uint8_t iv[AES_BLOCK_SIZE];
311 /* First key from pair is encode, second key is decode. */
312 struct aes192_ctx key[2], key_xts[2];
313} QCryptoNettleAES192;
314
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100315static void aes192_encrypt_native(const void *ctx, size_t length,
Richard Henderson53ddad92020-08-28 10:05:22 -0700316 uint8_t *dst, const uint8_t *src)
317{
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100318 const struct aes192_ctx *keys = ctx;
Richard Henderson53ddad92020-08-28 10:05:22 -0700319 aes192_encrypt(&keys[0], length, dst, src);
320}
321
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100322static void aes192_decrypt_native(const void *ctx, size_t length,
Richard Henderson53ddad92020-08-28 10:05:22 -0700323 uint8_t *dst, const uint8_t *src)
324{
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100325 const struct aes192_ctx *keys = ctx;
Richard Henderson53ddad92020-08-28 10:05:22 -0700326 aes192_decrypt(&keys[1], length, dst, src);
327}
328
329DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes192,
330 QCryptoNettleAES192, AES_BLOCK_SIZE,
331 aes192_encrypt_native, aes192_decrypt_native)
332
333
334typedef struct QCryptoNettleAES256 {
335 QCryptoCipher base;
336 uint8_t iv[AES_BLOCK_SIZE];
337 /* First key from pair is encode, second key is decode. */
338 struct aes256_ctx key[2], key_xts[2];
339} QCryptoNettleAES256;
340
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100341static void aes256_encrypt_native(const void *ctx, size_t length,
Richard Henderson53ddad92020-08-28 10:05:22 -0700342 uint8_t *dst, const uint8_t *src)
343{
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100344 const struct aes256_ctx *keys = ctx;
Richard Henderson53ddad92020-08-28 10:05:22 -0700345 aes256_encrypt(&keys[0], length, dst, src);
346}
347
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100348static void aes256_decrypt_native(const void *ctx, size_t length,
349 uint8_t *dst, const uint8_t *src)
Richard Henderson53ddad92020-08-28 10:05:22 -0700350{
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100351 const struct aes256_ctx *keys = ctx;
Richard Henderson53ddad92020-08-28 10:05:22 -0700352 aes256_decrypt(&keys[1], length, dst, src);
353}
354
355DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes256,
356 QCryptoNettleAES256, AES_BLOCK_SIZE,
357 aes256_encrypt_native, aes256_decrypt_native)
358
359
360typedef struct QCryptoNettleCAST128 {
361 QCryptoCipher base;
362 uint8_t iv[CAST128_BLOCK_SIZE];
363 struct cast128_ctx key, key_xts;
364} QCryptoNettleCAST128;
365
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100366static void cast128_encrypt_native(const void *ctx, size_t length,
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +0000367 uint8_t *dst, const uint8_t *src)
368{
369 cast128_encrypt(ctx, length, dst, src);
370}
371
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100372static void cast128_decrypt_native(const void *ctx, size_t length,
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +0000373 uint8_t *dst, const uint8_t *src)
374{
375 cast128_decrypt(ctx, length, dst, src);
376}
377
Richard Henderson53ddad92020-08-28 10:05:22 -0700378DEFINE_ECB_CBC_CTR(qcrypto_nettle_cast128,
379 QCryptoNettleCAST128, CAST128_BLOCK_SIZE,
380 cast128_encrypt_native, cast128_decrypt_native)
381
382
383typedef struct QCryptoNettleSerpent {
384 QCryptoCipher base;
385 uint8_t iv[SERPENT_BLOCK_SIZE];
386 struct serpent_ctx key, key_xts;
387} QCryptoNettleSerpent;
388
389
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100390static void serpent_encrypt_native(const void *ctx, size_t length,
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +0000391 uint8_t *dst, const uint8_t *src)
392{
393 serpent_encrypt(ctx, length, dst, src);
394}
395
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100396static void serpent_decrypt_native(const void *ctx, size_t length,
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +0000397 uint8_t *dst, const uint8_t *src)
398{
399 serpent_decrypt(ctx, length, dst, src);
400}
401
Richard Henderson53ddad92020-08-28 10:05:22 -0700402DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_serpent,
403 QCryptoNettleSerpent, SERPENT_BLOCK_SIZE,
404 serpent_encrypt_native, serpent_decrypt_native)
405
406
407typedef struct QCryptoNettleTwofish {
408 QCryptoCipher base;
409 uint8_t iv[TWOFISH_BLOCK_SIZE];
410 struct twofish_ctx key, key_xts;
411} QCryptoNettleTwofish;
412
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100413static void twofish_encrypt_native(const void *ctx, size_t length,
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +0000414 uint8_t *dst, const uint8_t *src)
415{
416 twofish_encrypt(ctx, length, dst, src);
417}
418
Daniel P. Berrangé115e4b72021-05-14 13:04:07 +0100419static void twofish_decrypt_native(const void *ctx, size_t length,
Daniel P. Berrangef7ac78c2016-03-18 12:39:12 +0000420 uint8_t *dst, const uint8_t *src)
421{
422 twofish_decrypt(ctx, length, dst, src);
423}
424
Richard Henderson53ddad92020-08-28 10:05:22 -0700425DEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_twofish,
426 QCryptoNettleTwofish, TWOFISH_BLOCK_SIZE,
427 twofish_encrypt_native, twofish_decrypt_native)
Radim Krčmářd3462e32015-07-10 19:18:01 +0200428
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100429
Gongleif8448362016-09-26 17:23:21 +0800430bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
431 QCryptoCipherMode mode)
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100432{
433 switch (alg) {
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100434 case QCRYPTO_CIPHER_ALG_DES:
Longpeng(Mike)ffb7bf42016-12-08 10:33:28 +0800435 case QCRYPTO_CIPHER_ALG_3DES:
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100436 case QCRYPTO_CIPHER_ALG_AES_128:
437 case QCRYPTO_CIPHER_ALG_AES_192:
438 case QCRYPTO_CIPHER_ALG_AES_256:
Daniel P. Berrange084a85e2016-02-10 17:07:42 +0000439 case QCRYPTO_CIPHER_ALG_CAST5_128:
Daniel P. Berrange94318522016-02-10 17:07:42 +0000440 case QCRYPTO_CIPHER_ALG_SERPENT_128:
441 case QCRYPTO_CIPHER_ALG_SERPENT_192:
442 case QCRYPTO_CIPHER_ALG_SERPENT_256:
Daniel P. Berrange50f67532016-02-10 17:07:42 +0000443 case QCRYPTO_CIPHER_ALG_TWOFISH_128:
444 case QCRYPTO_CIPHER_ALG_TWOFISH_192:
445 case QCRYPTO_CIPHER_ALG_TWOFISH_256:
Gongleif8448362016-09-26 17:23:21 +0800446 break;
447 default:
448 return false;
449 }
450
451 switch (mode) {
452 case QCRYPTO_CIPHER_MODE_ECB:
453 case QCRYPTO_CIPHER_MODE_CBC:
454 case QCRYPTO_CIPHER_MODE_XTS:
455 case QCRYPTO_CIPHER_MODE_CTR:
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100456 return true;
457 default:
458 return false;
459 }
460}
461
Richard Henderson3eedf5c2020-08-28 10:05:14 -0700462static QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgorithm alg,
463 QCryptoCipherMode mode,
464 const uint8_t *key,
465 size_t nkey,
466 Error **errp)
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100467{
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100468 switch (mode) {
469 case QCRYPTO_CIPHER_MODE_ECB:
470 case QCRYPTO_CIPHER_MODE_CBC:
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +0000471 case QCRYPTO_CIPHER_MODE_XTS:
Gonglei3c282922016-09-26 17:23:22 +0800472 case QCRYPTO_CIPHER_MODE_CTR:
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100473 break;
474 default:
Richard Henderson53ddad92020-08-28 10:05:22 -0700475 goto bad_cipher_mode;
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100476 }
477
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +0000478 if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100479 return NULL;
480 }
481
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100482 switch (alg) {
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100483 case QCRYPTO_CIPHER_ALG_DES:
Richard Henderson53ddad92020-08-28 10:05:22 -0700484 {
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100485 QCryptoNettleDES *ctx;
Richard Henderson53ddad92020-08-28 10:05:22 -0700486 const QCryptoCipherDriver *drv;
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100487
Richard Henderson53ddad92020-08-28 10:05:22 -0700488 switch (mode) {
489 case QCRYPTO_CIPHER_MODE_ECB:
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100490 drv = &qcrypto_nettle_des_driver_ecb;
Richard Henderson53ddad92020-08-28 10:05:22 -0700491 break;
492 case QCRYPTO_CIPHER_MODE_CBC:
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100493 drv = &qcrypto_nettle_des_driver_cbc;
Richard Henderson53ddad92020-08-28 10:05:22 -0700494 break;
495 case QCRYPTO_CIPHER_MODE_CTR:
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100496 drv = &qcrypto_nettle_des_driver_ctr;
Richard Henderson53ddad92020-08-28 10:05:22 -0700497 break;
498 default:
499 goto bad_cipher_mode;
500 }
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100501
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100502 ctx = g_new0(QCryptoNettleDES, 1);
Richard Henderson53ddad92020-08-28 10:05:22 -0700503 ctx->base.driver = drv;
Daniel P. Berrangé83bee4b2021-06-29 14:25:32 +0100504 des_set_key(&ctx->key, key);
Richard Henderson53ddad92020-08-28 10:05:22 -0700505
506 return &ctx->base;
507 }
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100508
Longpeng(Mike)ffb7bf42016-12-08 10:33:28 +0800509 case QCRYPTO_CIPHER_ALG_3DES:
Richard Henderson53ddad92020-08-28 10:05:22 -0700510 {
511 QCryptoNettleDES3 *ctx;
512 const QCryptoCipherDriver *drv;
Longpeng(Mike)ffb7bf42016-12-08 10:33:28 +0800513
Richard Henderson53ddad92020-08-28 10:05:22 -0700514 switch (mode) {
515 case QCRYPTO_CIPHER_MODE_ECB:
516 drv = &qcrypto_nettle_des3_driver_ecb;
517 break;
518 case QCRYPTO_CIPHER_MODE_CBC:
519 drv = &qcrypto_nettle_des3_driver_cbc;
520 break;
521 case QCRYPTO_CIPHER_MODE_CTR:
522 drv = &qcrypto_nettle_des3_driver_ctr;
523 break;
524 default:
525 goto bad_cipher_mode;
526 }
Longpeng(Mike)ffb7bf42016-12-08 10:33:28 +0800527
Richard Henderson53ddad92020-08-28 10:05:22 -0700528 ctx = g_new0(QCryptoNettleDES3, 1);
529 ctx->base.driver = drv;
530 des3_set_key(&ctx->key, key);
531 return &ctx->base;
532 }
Longpeng(Mike)ffb7bf42016-12-08 10:33:28 +0800533
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100534 case QCRYPTO_CIPHER_ALG_AES_128:
Richard Henderson53ddad92020-08-28 10:05:22 -0700535 {
536 QCryptoNettleAES128 *ctx = g_new0(QCryptoNettleAES128, 1);
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100537
Richard Henderson53ddad92020-08-28 10:05:22 -0700538 switch (mode) {
539 case QCRYPTO_CIPHER_MODE_ECB:
540 ctx->base.driver = &qcrypto_nettle_aes128_driver_ecb;
541 break;
542 case QCRYPTO_CIPHER_MODE_CBC:
543 ctx->base.driver = &qcrypto_nettle_aes128_driver_cbc;
544 break;
545 case QCRYPTO_CIPHER_MODE_CTR:
546 ctx->base.driver = &qcrypto_nettle_aes128_driver_ctr;
547 break;
548 case QCRYPTO_CIPHER_MODE_XTS:
549 ctx->base.driver = &qcrypto_nettle_aes128_driver_xts;
550 nkey /= 2;
551 aes128_set_encrypt_key(&ctx->key_xts[0], key + nkey);
552 aes128_set_decrypt_key(&ctx->key_xts[1], key + nkey);
553 break;
554 default:
555 g_assert_not_reached();
556 }
557 aes128_set_encrypt_key(&ctx->key[0], key);
558 aes128_set_decrypt_key(&ctx->key[1], key);
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +0000559
Richard Henderson53ddad92020-08-28 10:05:22 -0700560 return &ctx->base;
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +0000561 }
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100562
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +0100563 case QCRYPTO_CIPHER_ALG_AES_192:
Richard Henderson53ddad92020-08-28 10:05:22 -0700564 {
565 QCryptoNettleAES192 *ctx = g_new0(QCryptoNettleAES192, 1);
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +0100566
Richard Henderson53ddad92020-08-28 10:05:22 -0700567 switch (mode) {
568 case QCRYPTO_CIPHER_MODE_ECB:
569 ctx->base.driver = &qcrypto_nettle_aes192_driver_ecb;
570 break;
571 case QCRYPTO_CIPHER_MODE_CBC:
572 ctx->base.driver = &qcrypto_nettle_aes192_driver_cbc;
573 break;
574 case QCRYPTO_CIPHER_MODE_CTR:
575 ctx->base.driver = &qcrypto_nettle_aes192_driver_ctr;
576 break;
577 case QCRYPTO_CIPHER_MODE_XTS:
578 ctx->base.driver = &qcrypto_nettle_aes192_driver_xts;
579 nkey /= 2;
580 aes192_set_encrypt_key(&ctx->key_xts[0], key + nkey);
581 aes192_set_decrypt_key(&ctx->key_xts[1], key + nkey);
582 break;
583 default:
584 g_assert_not_reached();
585 }
586 aes192_set_encrypt_key(&ctx->key[0], key);
587 aes192_set_decrypt_key(&ctx->key[1], key);
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +0100588
Richard Henderson53ddad92020-08-28 10:05:22 -0700589 return &ctx->base;
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +0100590 }
591
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +0100592 case QCRYPTO_CIPHER_ALG_AES_256:
Richard Henderson53ddad92020-08-28 10:05:22 -0700593 {
594 QCryptoNettleAES256 *ctx = g_new0(QCryptoNettleAES256, 1);
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +0100595
Richard Henderson53ddad92020-08-28 10:05:22 -0700596 switch (mode) {
597 case QCRYPTO_CIPHER_MODE_ECB:
598 ctx->base.driver = &qcrypto_nettle_aes256_driver_ecb;
599 break;
600 case QCRYPTO_CIPHER_MODE_CBC:
601 ctx->base.driver = &qcrypto_nettle_aes256_driver_cbc;
602 break;
603 case QCRYPTO_CIPHER_MODE_CTR:
604 ctx->base.driver = &qcrypto_nettle_aes256_driver_ctr;
605 break;
606 case QCRYPTO_CIPHER_MODE_XTS:
607 ctx->base.driver = &qcrypto_nettle_aes256_driver_xts;
608 nkey /= 2;
609 aes256_set_encrypt_key(&ctx->key_xts[0], key + nkey);
610 aes256_set_decrypt_key(&ctx->key_xts[1], key + nkey);
611 break;
612 default:
613 g_assert_not_reached();
614 }
615 aes256_set_encrypt_key(&ctx->key[0], key);
616 aes256_set_decrypt_key(&ctx->key[1], key);
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +0100617
Richard Henderson53ddad92020-08-28 10:05:22 -0700618 return &ctx->base;
Daniel P. Berrangée8e67ca2019-07-10 17:19:13 +0100619 }
620
Daniel P. Berrange084a85e2016-02-10 17:07:42 +0000621 case QCRYPTO_CIPHER_ALG_CAST5_128:
Richard Henderson53ddad92020-08-28 10:05:22 -0700622 {
623 QCryptoNettleCAST128 *ctx;
624 const QCryptoCipherDriver *drv;
Daniel P. Berrange084a85e2016-02-10 17:07:42 +0000625
Richard Henderson53ddad92020-08-28 10:05:22 -0700626 switch (mode) {
627 case QCRYPTO_CIPHER_MODE_ECB:
628 drv = &qcrypto_nettle_cast128_driver_ecb;
629 break;
630 case QCRYPTO_CIPHER_MODE_CBC:
631 drv = &qcrypto_nettle_cast128_driver_cbc;
632 break;
633 case QCRYPTO_CIPHER_MODE_CTR:
634 drv = &qcrypto_nettle_cast128_driver_ctr;
635 break;
636 default:
637 goto bad_cipher_mode;
638 }
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +0000639
Richard Henderson53ddad92020-08-28 10:05:22 -0700640 ctx = g_new0(QCryptoNettleCAST128, 1);
641 ctx->base.driver = drv;
642 cast5_set_key(&ctx->key, nkey, key);
643
644 return &ctx->base;
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +0000645 }
Daniel P. Berrange084a85e2016-02-10 17:07:42 +0000646
Daniel P. Berrange94318522016-02-10 17:07:42 +0000647 case QCRYPTO_CIPHER_ALG_SERPENT_128:
648 case QCRYPTO_CIPHER_ALG_SERPENT_192:
649 case QCRYPTO_CIPHER_ALG_SERPENT_256:
Richard Henderson53ddad92020-08-28 10:05:22 -0700650 {
651 QCryptoNettleSerpent *ctx = g_new0(QCryptoNettleSerpent, 1);
Daniel P. Berrange94318522016-02-10 17:07:42 +0000652
Richard Henderson53ddad92020-08-28 10:05:22 -0700653 switch (mode) {
654 case QCRYPTO_CIPHER_MODE_ECB:
655 ctx->base.driver = &qcrypto_nettle_serpent_driver_ecb;
656 break;
657 case QCRYPTO_CIPHER_MODE_CBC:
658 ctx->base.driver = &qcrypto_nettle_serpent_driver_cbc;
659 break;
660 case QCRYPTO_CIPHER_MODE_CTR:
661 ctx->base.driver = &qcrypto_nettle_serpent_driver_ctr;
662 break;
663 case QCRYPTO_CIPHER_MODE_XTS:
664 ctx->base.driver = &qcrypto_nettle_serpent_driver_xts;
665 nkey /= 2;
666 serpent_set_key(&ctx->key_xts, nkey, key + nkey);
667 break;
668 default:
669 g_assert_not_reached();
670 }
671 serpent_set_key(&ctx->key, nkey, key);
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +0000672
Richard Henderson53ddad92020-08-28 10:05:22 -0700673 return &ctx->base;
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +0000674 }
Daniel P. Berrange94318522016-02-10 17:07:42 +0000675
Daniel P. Berrange50f67532016-02-10 17:07:42 +0000676 case QCRYPTO_CIPHER_ALG_TWOFISH_128:
677 case QCRYPTO_CIPHER_ALG_TWOFISH_192:
678 case QCRYPTO_CIPHER_ALG_TWOFISH_256:
Richard Henderson53ddad92020-08-28 10:05:22 -0700679 {
680 QCryptoNettleTwofish *ctx = g_new0(QCryptoNettleTwofish, 1);
Daniel P. Berrange50f67532016-02-10 17:07:42 +0000681
Richard Henderson53ddad92020-08-28 10:05:22 -0700682 switch (mode) {
683 case QCRYPTO_CIPHER_MODE_ECB:
684 ctx->base.driver = &qcrypto_nettle_twofish_driver_ecb;
685 break;
686 case QCRYPTO_CIPHER_MODE_CBC:
687 ctx->base.driver = &qcrypto_nettle_twofish_driver_cbc;
688 break;
689 case QCRYPTO_CIPHER_MODE_CTR:
690 ctx->base.driver = &qcrypto_nettle_twofish_driver_ctr;
691 break;
692 case QCRYPTO_CIPHER_MODE_XTS:
693 ctx->base.driver = &qcrypto_nettle_twofish_driver_xts;
694 nkey /= 2;
695 twofish_set_key(&ctx->key_xts, nkey, key + nkey);
696 break;
697 default:
698 g_assert_not_reached();
699 }
700 twofish_set_key(&ctx->key, nkey, key);
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +0000701
Richard Henderson53ddad92020-08-28 10:05:22 -0700702 return &ctx->base;
Daniel P. Berrangeeaec9032016-02-11 14:05:21 +0000703 }
Daniel P. Berrange50f67532016-02-10 17:07:42 +0000704
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100705 default:
Daniel P. Berrange90d6f602016-09-05 18:02:05 +0100706 error_setg(errp, "Unsupported cipher algorithm %s",
Markus Armbruster977c7362017-08-24 10:46:08 +0200707 QCryptoCipherAlgorithm_str(alg));
Richard Henderson53ddad92020-08-28 10:05:22 -0700708 return NULL;
Daniel P. Berrangea5d2f442016-08-24 16:28:15 +0100709 }
710
Richard Henderson53ddad92020-08-28 10:05:22 -0700711 bad_cipher_mode:
712 error_setg(errp, "Unsupported cipher mode %s",
713 QCryptoCipherMode_str(mode));
Daniel P. Berrangeed754742015-07-01 18:10:34 +0100714 return NULL;
715}