xref: /openbmc/qemu/crypto/cipher-nettle.c.inc (revision 3148a16b306485c5b6fb30c06f369b4bba476030)
16d92bdf4SRichard Henderson/*
26d92bdf4SRichard Henderson * QEMU Crypto cipher nettle algorithms
36d92bdf4SRichard Henderson *
46d92bdf4SRichard Henderson * Copyright (c) 2015 Red Hat, Inc.
56d92bdf4SRichard Henderson *
66d92bdf4SRichard Henderson * This library is free software; you can redistribute it and/or
76d92bdf4SRichard Henderson * modify it under the terms of the GNU Lesser General Public
86d92bdf4SRichard Henderson * License as published by the Free Software Foundation; either
96d92bdf4SRichard Henderson * version 2.1 of the License, or (at your option) any later version.
106d92bdf4SRichard Henderson *
116d92bdf4SRichard Henderson * This library is distributed in the hope that it will be useful,
126d92bdf4SRichard Henderson * but WITHOUT ANY WARRANTY; without even the implied warranty of
136d92bdf4SRichard Henderson * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
146d92bdf4SRichard Henderson * Lesser General Public License for more details.
156d92bdf4SRichard Henderson *
166d92bdf4SRichard Henderson * You should have received a copy of the GNU Lesser General Public
176d92bdf4SRichard Henderson * License along with this library; if not, see <http://www.gnu.org/licenses/>.
186d92bdf4SRichard Henderson *
196d92bdf4SRichard Henderson */
206d92bdf4SRichard Henderson
216d92bdf4SRichard Henderson#ifdef CONFIG_QEMU_PRIVATE_XTS
226d92bdf4SRichard Henderson#include "crypto/xts.h"
236d92bdf4SRichard Henderson#endif
246d92bdf4SRichard Henderson
256d92bdf4SRichard Henderson#include <nettle/nettle-types.h>
266d92bdf4SRichard Henderson#include <nettle/aes.h>
276d92bdf4SRichard Henderson#include <nettle/des.h>
286d92bdf4SRichard Henderson#include <nettle/cbc.h>
296d92bdf4SRichard Henderson#include <nettle/cast128.h>
306d92bdf4SRichard Henderson#include <nettle/serpent.h>
316d92bdf4SRichard Henderson#include <nettle/twofish.h>
326d92bdf4SRichard Henderson#include <nettle/ctr.h>
336d92bdf4SRichard Henderson#ifndef CONFIG_QEMU_PRIVATE_XTS
346d92bdf4SRichard Henderson#include <nettle/xts.h>
356d92bdf4SRichard Henderson#endif
3652ed9f45SHyman Huang#ifdef CONFIG_CRYPTO_SM4
3752ed9f45SHyman Huang#include <nettle/sm4.h>
3852ed9f45SHyman Huang#endif
396d92bdf4SRichard Henderson
4053ddad9bSRichard Hendersonstatic inline bool qcrypto_length_check(size_t len, size_t blocksize,
4153ddad9bSRichard Henderson                                        Error **errp)
426d92bdf4SRichard Henderson{
4353ddad9bSRichard Henderson    if (unlikely(len & (blocksize - 1))) {
4453ddad9bSRichard Henderson        error_setg(errp, "Length %zu must be a multiple of block size %zu",
4553ddad9bSRichard Henderson                   len, blocksize);
4653ddad9bSRichard Henderson        return false;
4753ddad9bSRichard Henderson    }
4853ddad9bSRichard Henderson    return true;
496d92bdf4SRichard Henderson}
506d92bdf4SRichard Henderson
5153ddad9bSRichard Henderson
5253ddad9bSRichard Hendersonstatic void qcrypto_cipher_ctx_free(QCryptoCipher *ctx)
536d92bdf4SRichard Henderson{
5453ddad9bSRichard Henderson    g_free(ctx);
556d92bdf4SRichard Henderson}
566d92bdf4SRichard Henderson
5753ddad9bSRichard Hendersonstatic int qcrypto_cipher_no_setiv(QCryptoCipher *cipher,
5853ddad9bSRichard Henderson                                   const uint8_t *iv, size_t niv,
5953ddad9bSRichard Henderson                                   Error **errp)
606d92bdf4SRichard Henderson{
6153ddad9bSRichard Henderson    error_setg(errp, "Setting IV is not supported");
6253ddad9bSRichard Henderson    return -1;
636d92bdf4SRichard Henderson}
646d92bdf4SRichard Henderson
6553ddad9bSRichard Henderson
6653ddad9bSRichard Henderson#define DEFINE_SETIV(NAME, TYPE, BLEN)                                  \
6753ddad9bSRichard Hendersonstatic int NAME##_setiv(QCryptoCipher *cipher, const uint8_t *iv,       \
6853ddad9bSRichard Henderson                        size_t niv, Error **errp)                       \
6953ddad9bSRichard Henderson{                                                                       \
7053ddad9bSRichard Henderson    TYPE *ctx = container_of(cipher, TYPE, base);                       \
7153ddad9bSRichard Henderson    if (niv != BLEN) {                                                  \
7253ddad9bSRichard Henderson        error_setg(errp, "Expected IV size %d not %zu", BLEN, niv);     \
7353ddad9bSRichard Henderson        return -1;                                                      \
7453ddad9bSRichard Henderson    }                                                                   \
7553ddad9bSRichard Henderson    memcpy(ctx->iv, iv, niv);                                           \
7653ddad9bSRichard Henderson    return 0;                                                           \
776d92bdf4SRichard Henderson}
786d92bdf4SRichard Henderson
796d92bdf4SRichard Henderson
8053ddad9bSRichard Henderson#define DEFINE_ECB(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)                  \
8153ddad9bSRichard Hendersonstatic int NAME##_encrypt_ecb(QCryptoCipher *cipher, const void *in,    \
8253ddad9bSRichard Henderson                              void *out, size_t len, Error **errp)      \
8353ddad9bSRichard Henderson{                                                                       \
8453ddad9bSRichard Henderson    TYPE *ctx = container_of(cipher, TYPE, base);                       \
8553ddad9bSRichard Henderson    if (!qcrypto_length_check(len, BLEN, errp)) {                       \
8653ddad9bSRichard Henderson        return -1;                                                      \
8753ddad9bSRichard Henderson    }                                                                   \
8853ddad9bSRichard Henderson    ENCRYPT(&ctx->key, len, out, in);                                   \
8953ddad9bSRichard Henderson    return 0;                                                           \
9053ddad9bSRichard Henderson}                                                                       \
9153ddad9bSRichard Hendersonstatic int NAME##_decrypt_ecb(QCryptoCipher *cipher, const void *in,    \
9253ddad9bSRichard Henderson                              void *out, size_t len, Error **errp)      \
9353ddad9bSRichard Henderson{                                                                       \
9453ddad9bSRichard Henderson    TYPE *ctx = container_of(cipher, TYPE, base);                       \
9553ddad9bSRichard Henderson    if (!qcrypto_length_check(len, BLEN, errp)) {                       \
9653ddad9bSRichard Henderson        return -1;                                                      \
9753ddad9bSRichard Henderson    }                                                                   \
9853ddad9bSRichard Henderson    DECRYPT(&ctx->key, len, out, in);                                   \
9953ddad9bSRichard Henderson    return 0;                                                           \
10053ddad9bSRichard Henderson}                                                                       \
10153ddad9bSRichard Hendersonstatic const struct QCryptoCipherDriver NAME##_driver_ecb = {           \
10253ddad9bSRichard Henderson    .cipher_encrypt = NAME##_encrypt_ecb,                               \
10353ddad9bSRichard Henderson    .cipher_decrypt = NAME##_decrypt_ecb,                               \
10453ddad9bSRichard Henderson    .cipher_setiv = qcrypto_cipher_no_setiv,                            \
10553ddad9bSRichard Henderson    .cipher_free = qcrypto_cipher_ctx_free,                             \
10653ddad9bSRichard Henderson};
10753ddad9bSRichard Henderson
10853ddad9bSRichard Henderson
10953ddad9bSRichard Henderson#define DEFINE_CBC(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)                  \
11053ddad9bSRichard Hendersonstatic int NAME##_encrypt_cbc(QCryptoCipher *cipher, const void *in,    \
11153ddad9bSRichard Henderson                              void *out, size_t len, Error **errp)      \
11253ddad9bSRichard Henderson{                                                                       \
11353ddad9bSRichard Henderson    TYPE *ctx = container_of(cipher, TYPE, base);                       \
11453ddad9bSRichard Henderson    if (!qcrypto_length_check(len, BLEN, errp)) {                       \
11553ddad9bSRichard Henderson        return -1;                                                      \
11653ddad9bSRichard Henderson    }                                                                   \
11753ddad9bSRichard Henderson    cbc_encrypt(&ctx->key, ENCRYPT, BLEN, ctx->iv, len, out, in);       \
11853ddad9bSRichard Henderson    return 0;                                                           \
11953ddad9bSRichard Henderson}                                                                       \
12053ddad9bSRichard Hendersonstatic int NAME##_decrypt_cbc(QCryptoCipher *cipher, const void *in,    \
12153ddad9bSRichard Henderson                              void *out, size_t len, Error **errp)      \
12253ddad9bSRichard Henderson{                                                                       \
12353ddad9bSRichard Henderson    TYPE *ctx = container_of(cipher, TYPE, base);                       \
12453ddad9bSRichard Henderson    if (!qcrypto_length_check(len, BLEN, errp)) {                       \
12553ddad9bSRichard Henderson        return -1;                                                      \
12653ddad9bSRichard Henderson    }                                                                   \
12753ddad9bSRichard Henderson    cbc_decrypt(&ctx->key, DECRYPT, BLEN, ctx->iv, len, out, in);       \
12853ddad9bSRichard Henderson    return 0;                                                           \
12953ddad9bSRichard Henderson}                                                                       \
13053ddad9bSRichard Hendersonstatic const struct QCryptoCipherDriver NAME##_driver_cbc = {           \
13153ddad9bSRichard Henderson    .cipher_encrypt = NAME##_encrypt_cbc,                               \
13253ddad9bSRichard Henderson    .cipher_decrypt = NAME##_decrypt_cbc,                               \
13353ddad9bSRichard Henderson    .cipher_setiv = NAME##_setiv,                                       \
13453ddad9bSRichard Henderson    .cipher_free = qcrypto_cipher_ctx_free,                             \
13553ddad9bSRichard Henderson};
13653ddad9bSRichard Henderson
13753ddad9bSRichard Henderson
13853ddad9bSRichard Henderson#define DEFINE_CTR(NAME, TYPE, BLEN, ENCRYPT)                           \
13953ddad9bSRichard Hendersonstatic int NAME##_encrypt_ctr(QCryptoCipher *cipher, const void *in,    \
14053ddad9bSRichard Henderson                              void *out, size_t len, Error **errp)      \
14153ddad9bSRichard Henderson{                                                                       \
14253ddad9bSRichard Henderson    TYPE *ctx = container_of(cipher, TYPE, base);                       \
14353ddad9bSRichard Henderson    if (!qcrypto_length_check(len, BLEN, errp)) {                       \
14453ddad9bSRichard Henderson        return -1;                                                      \
14553ddad9bSRichard Henderson    }                                                                   \
14653ddad9bSRichard Henderson    ctr_crypt(&ctx->key, ENCRYPT, BLEN, ctx->iv, len, out, in);         \
14753ddad9bSRichard Henderson    return 0;                                                           \
14853ddad9bSRichard Henderson}                                                                       \
14953ddad9bSRichard Hendersonstatic const struct QCryptoCipherDriver NAME##_driver_ctr = {           \
15053ddad9bSRichard Henderson    .cipher_encrypt = NAME##_encrypt_ctr,                               \
15153ddad9bSRichard Henderson    .cipher_decrypt = NAME##_encrypt_ctr,                               \
15253ddad9bSRichard Henderson    .cipher_setiv = NAME##_setiv,                                       \
15353ddad9bSRichard Henderson    .cipher_free = qcrypto_cipher_ctx_free,                             \
15453ddad9bSRichard Henderson};
15553ddad9bSRichard Henderson
15653ddad9bSRichard Henderson
15753ddad9bSRichard Henderson#ifdef CONFIG_QEMU_PRIVATE_XTS
15853ddad9bSRichard Henderson#define DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)                 \
15953ddad9bSRichard Hendersonstatic void NAME##_xts_wrape(const void *ctx, size_t length,            \
16053ddad9bSRichard Henderson                             uint8_t *dst, const uint8_t *src)          \
16153ddad9bSRichard Henderson{                                                                       \
162115e4b70SDaniel P. Berrangé    ENCRYPT((const void *)ctx, length, dst, src);                       \
16353ddad9bSRichard Henderson}                                                                       \
16453ddad9bSRichard Hendersonstatic void NAME##_xts_wrapd(const void *ctx, size_t length,            \
16553ddad9bSRichard Henderson                             uint8_t *dst, const uint8_t *src)          \
16653ddad9bSRichard Henderson{                                                                       \
167115e4b70SDaniel P. Berrangé    DECRYPT((const void *)ctx, length, dst, src);                       \
16853ddad9bSRichard Henderson}                                                                       \
16953ddad9bSRichard Hendersonstatic int NAME##_encrypt_xts(QCryptoCipher *cipher, const void *in,    \
17053ddad9bSRichard Henderson                              void *out, size_t len, Error **errp)      \
17153ddad9bSRichard Henderson{                                                                       \
17253ddad9bSRichard Henderson    TYPE *ctx = container_of(cipher, TYPE, base);                       \
17353ddad9bSRichard Henderson    if (!qcrypto_length_check(len, BLEN, errp)) {                       \
17453ddad9bSRichard Henderson        return -1;                                                      \
17553ddad9bSRichard Henderson    }                                                                   \
17653ddad9bSRichard Henderson    xts_encrypt(&ctx->key, &ctx->key_xts,                               \
17753ddad9bSRichard Henderson                NAME##_xts_wrape, NAME##_xts_wrapd,                     \
17853ddad9bSRichard Henderson                ctx->iv, len, out, in);                                 \
17953ddad9bSRichard Henderson    return 0;                                                           \
18053ddad9bSRichard Henderson}                                                                       \
18153ddad9bSRichard Hendersonstatic int NAME##_decrypt_xts(QCryptoCipher *cipher, const void *in,    \
18253ddad9bSRichard Henderson                              void *out, size_t len, Error **errp)      \
18353ddad9bSRichard Henderson{                                                                       \
18453ddad9bSRichard Henderson    TYPE *ctx = container_of(cipher, TYPE, base);                       \
18553ddad9bSRichard Henderson    if (!qcrypto_length_check(len, BLEN, errp)) {                       \
18653ddad9bSRichard Henderson        return -1;                                                      \
18753ddad9bSRichard Henderson    }                                                                   \
18853ddad9bSRichard Henderson    xts_decrypt(&ctx->key, &ctx->key_xts,                               \
18953ddad9bSRichard Henderson                NAME##_xts_wrape, NAME##_xts_wrapd,                     \
19053ddad9bSRichard Henderson                ctx->iv, len, out, in);                                 \
19153ddad9bSRichard Henderson    return 0;                                                           \
1926d92bdf4SRichard Henderson}
19353ddad9bSRichard Henderson#else
19453ddad9bSRichard Henderson#define DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)                 \
19553ddad9bSRichard Hendersonstatic int NAME##_encrypt_xts(QCryptoCipher *cipher, const void *in,    \
19653ddad9bSRichard Henderson                              void *out, size_t len, Error **errp)      \
19753ddad9bSRichard Henderson{                                                                       \
19853ddad9bSRichard Henderson    TYPE *ctx = container_of(cipher, TYPE, base);                       \
19953ddad9bSRichard Henderson    if (!qcrypto_length_check(len, BLEN, errp)) {                       \
20053ddad9bSRichard Henderson        return -1;                                                      \
20153ddad9bSRichard Henderson    }                                                                   \
20253ddad9bSRichard Henderson    xts_encrypt_message(&ctx->key, &ctx->key_xts, ENCRYPT,              \
20353ddad9bSRichard Henderson                        ctx->iv, len, out, in);                         \
20453ddad9bSRichard Henderson    return 0;                                                           \
20553ddad9bSRichard Henderson}                                                                       \
20653ddad9bSRichard Hendersonstatic int NAME##_decrypt_xts(QCryptoCipher *cipher, const void *in,    \
20753ddad9bSRichard Henderson                              void *out, size_t len, Error **errp)      \
20853ddad9bSRichard Henderson{                                                                       \
20953ddad9bSRichard Henderson    TYPE *ctx = container_of(cipher, TYPE, base);                       \
21053ddad9bSRichard Henderson    if (!qcrypto_length_check(len, BLEN, errp)) {                       \
21153ddad9bSRichard Henderson        return -1;                                                      \
21253ddad9bSRichard Henderson    }                                                                   \
21353ddad9bSRichard Henderson    xts_decrypt_message(&ctx->key, &ctx->key_xts, DECRYPT, ENCRYPT,     \
21453ddad9bSRichard Henderson                        ctx->iv, len, out, in);                         \
21553ddad9bSRichard Henderson    return 0;                                                           \
21653ddad9bSRichard Henderson}
21753ddad9bSRichard Henderson#endif
21853ddad9bSRichard Henderson
21953ddad9bSRichard Henderson#define DEFINE_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)          \
22053ddad9bSRichard Henderson    QEMU_BUILD_BUG_ON(BLEN != XTS_BLOCK_SIZE);                  \
22153ddad9bSRichard Henderson    DEFINE__XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)             \
22253ddad9bSRichard Hendersonstatic const struct QCryptoCipherDriver NAME##_driver_xts = {   \
22353ddad9bSRichard Henderson    .cipher_encrypt = NAME##_encrypt_xts,                       \
22453ddad9bSRichard Henderson    .cipher_decrypt = NAME##_decrypt_xts,                       \
22553ddad9bSRichard Henderson    .cipher_setiv = NAME##_setiv,                               \
22653ddad9bSRichard Henderson    .cipher_free = qcrypto_cipher_ctx_free,                     \
22753ddad9bSRichard Henderson};
22853ddad9bSRichard Henderson
22953ddad9bSRichard Henderson
23053ddad9bSRichard Henderson#define DEFINE_ECB_CBC_CTR(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)  \
23153ddad9bSRichard Henderson    DEFINE_SETIV(NAME, TYPE, BLEN)                              \
23253ddad9bSRichard Henderson    DEFINE_ECB(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)              \
23353ddad9bSRichard Henderson    DEFINE_CBC(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)              \
23453ddad9bSRichard Henderson    DEFINE_CTR(NAME, TYPE, BLEN, ENCRYPT)
23553ddad9bSRichard Henderson
23653ddad9bSRichard Henderson#define DEFINE_ECB_CBC_CTR_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)      \
23753ddad9bSRichard Henderson    DEFINE_ECB_CBC_CTR(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)              \
23853ddad9bSRichard Henderson    DEFINE_XTS(NAME, TYPE, BLEN, ENCRYPT, DECRYPT)
23953ddad9bSRichard Henderson
24053ddad9bSRichard Henderson
24183bee4b5SDaniel P. Berrangétypedef struct QCryptoNettleDES {
24253ddad9bSRichard Henderson    QCryptoCipher base;
24353ddad9bSRichard Henderson    struct des_ctx key;
24453ddad9bSRichard Henderson    uint8_t iv[DES_BLOCK_SIZE];
24583bee4b5SDaniel P. Berrangé} QCryptoNettleDES;
2466d92bdf4SRichard Henderson
247115e4b70SDaniel P. Berrangéstatic void des_encrypt_native(const void *ctx, size_t length,
2486d92bdf4SRichard Henderson                               uint8_t *dst, const uint8_t *src)
2496d92bdf4SRichard Henderson{
2506d92bdf4SRichard Henderson    des_encrypt(ctx, length, dst, src);
2516d92bdf4SRichard Henderson}
2526d92bdf4SRichard Henderson
253115e4b70SDaniel P. Berrangéstatic void des_decrypt_native(const void *ctx, size_t length,
2546d92bdf4SRichard Henderson                               uint8_t *dst, const uint8_t *src)
2556d92bdf4SRichard Henderson{
2566d92bdf4SRichard Henderson    des_decrypt(ctx, length, dst, src);
2576d92bdf4SRichard Henderson}
2586d92bdf4SRichard Henderson
25983bee4b5SDaniel P. BerrangéDEFINE_ECB_CBC_CTR(qcrypto_nettle_des, QCryptoNettleDES,
26053ddad9bSRichard Henderson                   DES_BLOCK_SIZE, des_encrypt_native, des_decrypt_native)
26153ddad9bSRichard Henderson
26253ddad9bSRichard Henderson
26353ddad9bSRichard Hendersontypedef struct QCryptoNettleDES3 {
26453ddad9bSRichard Henderson    QCryptoCipher base;
26553ddad9bSRichard Henderson    struct des3_ctx key;
26653ddad9bSRichard Henderson    uint8_t iv[DES3_BLOCK_SIZE];
26753ddad9bSRichard Henderson} QCryptoNettleDES3;
26853ddad9bSRichard Henderson
269115e4b70SDaniel P. Berrangéstatic void des3_encrypt_native(const void *ctx, size_t length,
2706d92bdf4SRichard Henderson                                uint8_t *dst, const uint8_t *src)
2716d92bdf4SRichard Henderson{
2726d92bdf4SRichard Henderson    des3_encrypt(ctx, length, dst, src);
2736d92bdf4SRichard Henderson}
2746d92bdf4SRichard Henderson
275115e4b70SDaniel P. Berrangéstatic void des3_decrypt_native(const void *ctx, size_t length,
2766d92bdf4SRichard Henderson                                uint8_t *dst, const uint8_t *src)
2776d92bdf4SRichard Henderson{
2786d92bdf4SRichard Henderson    des3_decrypt(ctx, length, dst, src);
2796d92bdf4SRichard Henderson}
2806d92bdf4SRichard Henderson
28153ddad9bSRichard HendersonDEFINE_ECB_CBC_CTR(qcrypto_nettle_des3, QCryptoNettleDES3, DES3_BLOCK_SIZE,
28253ddad9bSRichard Henderson                   des3_encrypt_native, des3_decrypt_native)
28353ddad9bSRichard Henderson
28453ddad9bSRichard Henderson
28553ddad9bSRichard Hendersontypedef struct QCryptoNettleAES128 {
28653ddad9bSRichard Henderson    QCryptoCipher base;
28753ddad9bSRichard Henderson    uint8_t iv[AES_BLOCK_SIZE];
28853ddad9bSRichard Henderson    /* First key from pair is encode, second key is decode. */
28953ddad9bSRichard Henderson    struct aes128_ctx key[2], key_xts[2];
29053ddad9bSRichard Henderson} QCryptoNettleAES128;
29153ddad9bSRichard Henderson
292115e4b70SDaniel P. Berrangéstatic void aes128_encrypt_native(const void *ctx, size_t length,
29353ddad9bSRichard Henderson                                  uint8_t *dst, const uint8_t *src)
29453ddad9bSRichard Henderson{
295115e4b70SDaniel P. Berrangé    const struct aes128_ctx *keys = ctx;
29653ddad9bSRichard Henderson    aes128_encrypt(&keys[0], length, dst, src);
29753ddad9bSRichard Henderson}
29853ddad9bSRichard Henderson
299115e4b70SDaniel P. Berrangéstatic void aes128_decrypt_native(const void *ctx, size_t length,
30053ddad9bSRichard Henderson                                  uint8_t *dst, const uint8_t *src)
30153ddad9bSRichard Henderson{
302115e4b70SDaniel P. Berrangé    const struct aes128_ctx *keys = ctx;
30353ddad9bSRichard Henderson    aes128_decrypt(&keys[1], length, dst, src);
30453ddad9bSRichard Henderson}
30553ddad9bSRichard Henderson
30653ddad9bSRichard HendersonDEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes128,
30753ddad9bSRichard Henderson                       QCryptoNettleAES128, AES_BLOCK_SIZE,
30853ddad9bSRichard Henderson                       aes128_encrypt_native, aes128_decrypt_native)
30953ddad9bSRichard Henderson
31053ddad9bSRichard Henderson
31153ddad9bSRichard Hendersontypedef struct QCryptoNettleAES192 {
31253ddad9bSRichard Henderson    QCryptoCipher base;
31353ddad9bSRichard Henderson    uint8_t iv[AES_BLOCK_SIZE];
31453ddad9bSRichard Henderson    /* First key from pair is encode, second key is decode. */
31553ddad9bSRichard Henderson    struct aes192_ctx key[2], key_xts[2];
31653ddad9bSRichard Henderson} QCryptoNettleAES192;
31753ddad9bSRichard Henderson
318115e4b70SDaniel P. Berrangéstatic void aes192_encrypt_native(const void *ctx, size_t length,
31953ddad9bSRichard Henderson                                  uint8_t *dst, const uint8_t *src)
32053ddad9bSRichard Henderson{
321115e4b70SDaniel P. Berrangé    const struct aes192_ctx *keys = ctx;
32253ddad9bSRichard Henderson    aes192_encrypt(&keys[0], length, dst, src);
32353ddad9bSRichard Henderson}
32453ddad9bSRichard Henderson
325115e4b70SDaniel P. Berrangéstatic void aes192_decrypt_native(const void *ctx, size_t length,
32653ddad9bSRichard Henderson                                  uint8_t *dst, const uint8_t *src)
32753ddad9bSRichard Henderson{
328115e4b70SDaniel P. Berrangé    const struct aes192_ctx *keys = ctx;
32953ddad9bSRichard Henderson    aes192_decrypt(&keys[1], length, dst, src);
33053ddad9bSRichard Henderson}
33153ddad9bSRichard Henderson
33253ddad9bSRichard HendersonDEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes192,
33353ddad9bSRichard Henderson                       QCryptoNettleAES192, AES_BLOCK_SIZE,
33453ddad9bSRichard Henderson                       aes192_encrypt_native, aes192_decrypt_native)
33553ddad9bSRichard Henderson
33653ddad9bSRichard Henderson
33753ddad9bSRichard Hendersontypedef struct QCryptoNettleAES256 {
33853ddad9bSRichard Henderson    QCryptoCipher base;
33953ddad9bSRichard Henderson    uint8_t iv[AES_BLOCK_SIZE];
34053ddad9bSRichard Henderson    /* First key from pair is encode, second key is decode. */
34153ddad9bSRichard Henderson    struct aes256_ctx key[2], key_xts[2];
34253ddad9bSRichard Henderson} QCryptoNettleAES256;
34353ddad9bSRichard Henderson
344115e4b70SDaniel P. Berrangéstatic void aes256_encrypt_native(const void *ctx, size_t length,
34553ddad9bSRichard Henderson                                  uint8_t *dst, const uint8_t *src)
34653ddad9bSRichard Henderson{
347115e4b70SDaniel P. Berrangé    const struct aes256_ctx *keys = ctx;
34853ddad9bSRichard Henderson    aes256_encrypt(&keys[0], length, dst, src);
34953ddad9bSRichard Henderson}
35053ddad9bSRichard Henderson
351115e4b70SDaniel P. Berrangéstatic void aes256_decrypt_native(const void *ctx, size_t length,
35253ddad9bSRichard Henderson                                  uint8_t *dst, const uint8_t *src)
35353ddad9bSRichard Henderson{
354115e4b70SDaniel P. Berrangé    const struct aes256_ctx *keys = ctx;
35553ddad9bSRichard Henderson    aes256_decrypt(&keys[1], length, dst, src);
35653ddad9bSRichard Henderson}
35753ddad9bSRichard Henderson
35853ddad9bSRichard HendersonDEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_aes256,
35953ddad9bSRichard Henderson                       QCryptoNettleAES256, AES_BLOCK_SIZE,
36053ddad9bSRichard Henderson                       aes256_encrypt_native, aes256_decrypt_native)
36153ddad9bSRichard Henderson
36253ddad9bSRichard Henderson
36353ddad9bSRichard Hendersontypedef struct QCryptoNettleCAST128 {
36453ddad9bSRichard Henderson    QCryptoCipher base;
36553ddad9bSRichard Henderson    uint8_t iv[CAST128_BLOCK_SIZE];
36653ddad9bSRichard Henderson    struct cast128_ctx key, key_xts;
36753ddad9bSRichard Henderson} QCryptoNettleCAST128;
36853ddad9bSRichard Henderson
369115e4b70SDaniel P. Berrangéstatic void cast128_encrypt_native(const void *ctx, size_t length,
3706d92bdf4SRichard Henderson                                   uint8_t *dst, const uint8_t *src)
3716d92bdf4SRichard Henderson{
3726d92bdf4SRichard Henderson    cast128_encrypt(ctx, length, dst, src);
3736d92bdf4SRichard Henderson}
3746d92bdf4SRichard Henderson
375115e4b70SDaniel P. Berrangéstatic void cast128_decrypt_native(const void *ctx, size_t length,
3766d92bdf4SRichard Henderson                                   uint8_t *dst, const uint8_t *src)
3776d92bdf4SRichard Henderson{
3786d92bdf4SRichard Henderson    cast128_decrypt(ctx, length, dst, src);
3796d92bdf4SRichard Henderson}
3806d92bdf4SRichard Henderson
38153ddad9bSRichard HendersonDEFINE_ECB_CBC_CTR(qcrypto_nettle_cast128,
38253ddad9bSRichard Henderson                   QCryptoNettleCAST128, CAST128_BLOCK_SIZE,
38353ddad9bSRichard Henderson                   cast128_encrypt_native, cast128_decrypt_native)
38453ddad9bSRichard Henderson
38553ddad9bSRichard Henderson
38653ddad9bSRichard Hendersontypedef struct QCryptoNettleSerpent {
38753ddad9bSRichard Henderson    QCryptoCipher base;
38853ddad9bSRichard Henderson    uint8_t iv[SERPENT_BLOCK_SIZE];
38953ddad9bSRichard Henderson    struct serpent_ctx key, key_xts;
39053ddad9bSRichard Henderson} QCryptoNettleSerpent;
39153ddad9bSRichard Henderson
39253ddad9bSRichard Henderson
393115e4b70SDaniel P. Berrangéstatic void serpent_encrypt_native(const void *ctx, size_t length,
3946d92bdf4SRichard Henderson                                   uint8_t *dst, const uint8_t *src)
3956d92bdf4SRichard Henderson{
3966d92bdf4SRichard Henderson    serpent_encrypt(ctx, length, dst, src);
3976d92bdf4SRichard Henderson}
3986d92bdf4SRichard Henderson
399115e4b70SDaniel P. Berrangéstatic void serpent_decrypt_native(const void *ctx, size_t length,
4006d92bdf4SRichard Henderson                                   uint8_t *dst, const uint8_t *src)
4016d92bdf4SRichard Henderson{
4026d92bdf4SRichard Henderson    serpent_decrypt(ctx, length, dst, src);
4036d92bdf4SRichard Henderson}
4046d92bdf4SRichard Henderson
40553ddad9bSRichard HendersonDEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_serpent,
40653ddad9bSRichard Henderson                       QCryptoNettleSerpent, SERPENT_BLOCK_SIZE,
40753ddad9bSRichard Henderson                       serpent_encrypt_native, serpent_decrypt_native)
40853ddad9bSRichard Henderson
40953ddad9bSRichard Henderson
41053ddad9bSRichard Hendersontypedef struct QCryptoNettleTwofish {
41153ddad9bSRichard Henderson    QCryptoCipher base;
41253ddad9bSRichard Henderson    uint8_t iv[TWOFISH_BLOCK_SIZE];
41353ddad9bSRichard Henderson    struct twofish_ctx key, key_xts;
41453ddad9bSRichard Henderson} QCryptoNettleTwofish;
41553ddad9bSRichard Henderson
416115e4b70SDaniel P. Berrangéstatic void twofish_encrypt_native(const void *ctx, size_t length,
4176d92bdf4SRichard Henderson                                   uint8_t *dst, const uint8_t *src)
4186d92bdf4SRichard Henderson{
4196d92bdf4SRichard Henderson    twofish_encrypt(ctx, length, dst, src);
4206d92bdf4SRichard Henderson}
4216d92bdf4SRichard Henderson
422115e4b70SDaniel P. Berrangéstatic void twofish_decrypt_native(const void *ctx, size_t length,
4236d92bdf4SRichard Henderson                                   uint8_t *dst, const uint8_t *src)
4246d92bdf4SRichard Henderson{
4256d92bdf4SRichard Henderson    twofish_decrypt(ctx, length, dst, src);
4266d92bdf4SRichard Henderson}
4276d92bdf4SRichard Henderson
42853ddad9bSRichard HendersonDEFINE_ECB_CBC_CTR_XTS(qcrypto_nettle_twofish,
42953ddad9bSRichard Henderson                       QCryptoNettleTwofish, TWOFISH_BLOCK_SIZE,
43053ddad9bSRichard Henderson                       twofish_encrypt_native, twofish_decrypt_native)
4316d92bdf4SRichard Henderson
43252ed9f45SHyman Huang#ifdef CONFIG_CRYPTO_SM4
43352ed9f45SHyman Huangtypedef struct QCryptoNettleSm4 {
43452ed9f45SHyman Huang    QCryptoCipher base;
43552ed9f45SHyman Huang    struct sm4_ctx key[2];
43652ed9f45SHyman Huang} QCryptoNettleSm4;
43752ed9f45SHyman Huang
43852ed9f45SHyman Huangstatic void sm4_encrypt_native(void *ctx, size_t length,
43952ed9f45SHyman Huang                               uint8_t *dst, const uint8_t *src)
44052ed9f45SHyman Huang{
44152ed9f45SHyman Huang    struct sm4_ctx *keys = ctx;
44252ed9f45SHyman Huang    sm4_crypt(&keys[0], length, dst, src);
44352ed9f45SHyman Huang}
44452ed9f45SHyman Huang
44552ed9f45SHyman Huangstatic void sm4_decrypt_native(void *ctx, size_t length,
44652ed9f45SHyman Huang                               uint8_t *dst, const uint8_t *src)
44752ed9f45SHyman Huang{
44852ed9f45SHyman Huang    struct sm4_ctx *keys = ctx;
44952ed9f45SHyman Huang    sm4_crypt(&keys[1], length, dst, src);
45052ed9f45SHyman Huang}
45152ed9f45SHyman Huang
45252ed9f45SHyman HuangDEFINE_ECB(qcrypto_nettle_sm4,
45352ed9f45SHyman Huang           QCryptoNettleSm4, SM4_BLOCK_SIZE,
45452ed9f45SHyman Huang           sm4_encrypt_native, sm4_decrypt_native)
45552ed9f45SHyman Huang#endif
4566d92bdf4SRichard Henderson
4576d92bdf4SRichard Hendersonbool qcrypto_cipher_supports(QCryptoCipherAlgo alg,
4586d92bdf4SRichard Henderson                             QCryptoCipherMode mode)
4596d92bdf4SRichard Henderson{
4606d92bdf4SRichard Henderson    switch (alg) {
46183bee4b5SDaniel P. Berrangé    case QCRYPTO_CIPHER_ALGO_DES:
4626d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_3DES:
4636d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_AES_128:
4646d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_AES_192:
4656d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_AES_256:
4666d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_CAST5_128:
4676d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_SERPENT_128:
4686d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_SERPENT_192:
4696d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_SERPENT_256:
4706d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_TWOFISH_128:
4716d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_TWOFISH_192:
4726d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_TWOFISH_256:
47352ed9f45SHyman Huang#ifdef CONFIG_CRYPTO_SM4
47452ed9f45SHyman Huang    case QCRYPTO_CIPHER_ALGO_SM4:
47552ed9f45SHyman Huang#endif
4766d92bdf4SRichard Henderson        break;
4776d92bdf4SRichard Henderson    default:
4786d92bdf4SRichard Henderson        return false;
4796d92bdf4SRichard Henderson    }
4806d92bdf4SRichard Henderson
4816d92bdf4SRichard Henderson    switch (mode) {
4826d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_MODE_ECB:
4836d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_MODE_CBC:
4846d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_MODE_XTS:
4856d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_MODE_CTR:
4866d92bdf4SRichard Henderson        return true;
4876d92bdf4SRichard Henderson    default:
4886d92bdf4SRichard Henderson        return false;
4896d92bdf4SRichard Henderson    }
4906d92bdf4SRichard Henderson}
4916d92bdf4SRichard Henderson
4923eedf5ccSRichard Hendersonstatic QCryptoCipher *qcrypto_cipher_ctx_new(QCryptoCipherAlgo alg,
4936d92bdf4SRichard Henderson                                             QCryptoCipherMode mode,
4946d92bdf4SRichard Henderson                                             const uint8_t *key,
4956d92bdf4SRichard Henderson                                             size_t nkey,
4966d92bdf4SRichard Henderson                                             Error **errp)
4976d92bdf4SRichard Henderson{
4986d92bdf4SRichard Henderson    switch (mode) {
4996d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_MODE_ECB:
5006d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_MODE_CBC:
5016d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_MODE_XTS:
5026d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_MODE_CTR:
5036d92bdf4SRichard Henderson        break;
5046d92bdf4SRichard Henderson    default:
50553ddad9bSRichard Henderson        goto bad_cipher_mode;
5066d92bdf4SRichard Henderson    }
5076d92bdf4SRichard Henderson
5086d92bdf4SRichard Henderson    if (!qcrypto_cipher_validate_key_length(alg, mode, nkey, errp)) {
5096d92bdf4SRichard Henderson        return NULL;
5106d92bdf4SRichard Henderson    }
5116d92bdf4SRichard Henderson
5126d92bdf4SRichard Henderson    switch (alg) {
51383bee4b5SDaniel P. Berrangé    case QCRYPTO_CIPHER_ALGO_DES:
51453ddad9bSRichard Henderson        {
51583bee4b5SDaniel P. Berrangé            QCryptoNettleDES *ctx;
51653ddad9bSRichard Henderson            const QCryptoCipherDriver *drv;
51753ddad9bSRichard Henderson
51853ddad9bSRichard Henderson            switch (mode) {
51953ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_ECB:
52083bee4b5SDaniel P. Berrangé                drv = &qcrypto_nettle_des_driver_ecb;
52153ddad9bSRichard Henderson                break;
52253ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CBC:
52383bee4b5SDaniel P. Berrangé                drv = &qcrypto_nettle_des_driver_cbc;
52453ddad9bSRichard Henderson                break;
52553ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CTR:
52683bee4b5SDaniel P. Berrangé                drv = &qcrypto_nettle_des_driver_ctr;
52753ddad9bSRichard Henderson                break;
52853ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_XTS:
52953ddad9bSRichard Henderson                goto bad_cipher_mode;
53053ddad9bSRichard Henderson            default:
53153ddad9bSRichard Henderson                g_assert_not_reached();
53283bee4b5SDaniel P. Berrangé            }
53353ddad9bSRichard Henderson
53483bee4b5SDaniel P. Berrangé            ctx = g_new0(QCryptoNettleDES, 1);
5356d92bdf4SRichard Henderson            ctx->base.driver = drv;
53653ddad9bSRichard Henderson            des_set_key(&ctx->key, key);
53753ddad9bSRichard Henderson
5386d92bdf4SRichard Henderson            return &ctx->base;
5396d92bdf4SRichard Henderson        }
54053ddad9bSRichard Henderson
54153ddad9bSRichard Henderson    case QCRYPTO_CIPHER_ALGO_3DES:
54253ddad9bSRichard Henderson        {
5436d92bdf4SRichard Henderson            QCryptoNettleDES3 *ctx;
54453ddad9bSRichard Henderson            const QCryptoCipherDriver *drv;
54553ddad9bSRichard Henderson
54653ddad9bSRichard Henderson            switch (mode) {
5476d92bdf4SRichard Henderson            case QCRYPTO_CIPHER_MODE_ECB:
54853ddad9bSRichard Henderson                drv = &qcrypto_nettle_des3_driver_ecb;
54953ddad9bSRichard Henderson                break;
55053ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CBC:
55153ddad9bSRichard Henderson                drv = &qcrypto_nettle_des3_driver_cbc;
55253ddad9bSRichard Henderson                break;
55353ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CTR:
55453ddad9bSRichard Henderson                drv = &qcrypto_nettle_des3_driver_ctr;
55553ddad9bSRichard Henderson                break;
55653ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_XTS:
55753ddad9bSRichard Henderson                goto bad_cipher_mode;
55853ddad9bSRichard Henderson            default:
55953ddad9bSRichard Henderson                g_assert_not_reached();
56053ddad9bSRichard Henderson            }
56153ddad9bSRichard Henderson
56253ddad9bSRichard Henderson            ctx = g_new0(QCryptoNettleDES3, 1);
5636d92bdf4SRichard Henderson            ctx->base.driver = drv;
5646d92bdf4SRichard Henderson            des3_set_key(&ctx->key, key);
56553ddad9bSRichard Henderson            return &ctx->base;
56653ddad9bSRichard Henderson        }
5676d92bdf4SRichard Henderson
56853ddad9bSRichard Henderson    case QCRYPTO_CIPHER_ALGO_AES_128:
56953ddad9bSRichard Henderson        {
57053ddad9bSRichard Henderson            QCryptoNettleAES128 *ctx = g_new0(QCryptoNettleAES128, 1);
5716d92bdf4SRichard Henderson
57253ddad9bSRichard Henderson            switch (mode) {
57353ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_ECB:
57453ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes128_driver_ecb;
57553ddad9bSRichard Henderson                break;
57653ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CBC:
57753ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes128_driver_cbc;
57853ddad9bSRichard Henderson                break;
57953ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CTR:
58053ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes128_driver_ctr;
58153ddad9bSRichard Henderson                break;
58253ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_XTS:
58353ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes128_driver_xts;
58453ddad9bSRichard Henderson                nkey /= 2;
58553ddad9bSRichard Henderson                aes128_set_encrypt_key(&ctx->key_xts[0], key + nkey);
58653ddad9bSRichard Henderson                aes128_set_decrypt_key(&ctx->key_xts[1], key + nkey);
58753ddad9bSRichard Henderson                break;
58853ddad9bSRichard Henderson            default:
58953ddad9bSRichard Henderson                g_assert_not_reached();
59053ddad9bSRichard Henderson            }
59153ddad9bSRichard Henderson            aes128_set_encrypt_key(&ctx->key[0], key);
5926d92bdf4SRichard Henderson            aes128_set_decrypt_key(&ctx->key[1], key);
5936d92bdf4SRichard Henderson
59453ddad9bSRichard Henderson            return &ctx->base;
59553ddad9bSRichard Henderson        }
5966d92bdf4SRichard Henderson
59753ddad9bSRichard Henderson    case QCRYPTO_CIPHER_ALGO_AES_192:
59853ddad9bSRichard Henderson        {
59953ddad9bSRichard Henderson            QCryptoNettleAES192 *ctx = g_new0(QCryptoNettleAES192, 1);
6006d92bdf4SRichard Henderson
60153ddad9bSRichard Henderson            switch (mode) {
60253ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_ECB:
60353ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes192_driver_ecb;
60453ddad9bSRichard Henderson                break;
60553ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CBC:
60653ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes192_driver_cbc;
60753ddad9bSRichard Henderson                break;
60853ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CTR:
60953ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes192_driver_ctr;
61053ddad9bSRichard Henderson                break;
61153ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_XTS:
61253ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes192_driver_xts;
61353ddad9bSRichard Henderson                nkey /= 2;
61453ddad9bSRichard Henderson                aes192_set_encrypt_key(&ctx->key_xts[0], key + nkey);
61553ddad9bSRichard Henderson                aes192_set_decrypt_key(&ctx->key_xts[1], key + nkey);
61653ddad9bSRichard Henderson                break;
61753ddad9bSRichard Henderson            default:
61853ddad9bSRichard Henderson                g_assert_not_reached();
61953ddad9bSRichard Henderson            }
62053ddad9bSRichard Henderson            aes192_set_encrypt_key(&ctx->key[0], key);
6216d92bdf4SRichard Henderson            aes192_set_decrypt_key(&ctx->key[1], key);
6226d92bdf4SRichard Henderson
62353ddad9bSRichard Henderson            return &ctx->base;
62453ddad9bSRichard Henderson        }
6256d92bdf4SRichard Henderson
62653ddad9bSRichard Henderson    case QCRYPTO_CIPHER_ALGO_AES_256:
62753ddad9bSRichard Henderson        {
62853ddad9bSRichard Henderson            QCryptoNettleAES256 *ctx = g_new0(QCryptoNettleAES256, 1);
6296d92bdf4SRichard Henderson
63053ddad9bSRichard Henderson            switch (mode) {
63153ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_ECB:
63253ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes256_driver_ecb;
63353ddad9bSRichard Henderson                break;
63453ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CBC:
63553ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes256_driver_cbc;
63653ddad9bSRichard Henderson                break;
63753ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CTR:
63853ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes256_driver_ctr;
63953ddad9bSRichard Henderson                break;
64053ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_XTS:
64153ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_aes256_driver_xts;
64253ddad9bSRichard Henderson                nkey /= 2;
64353ddad9bSRichard Henderson                aes256_set_encrypt_key(&ctx->key_xts[0], key + nkey);
64453ddad9bSRichard Henderson                aes256_set_decrypt_key(&ctx->key_xts[1], key + nkey);
64553ddad9bSRichard Henderson                break;
64653ddad9bSRichard Henderson            default:
64753ddad9bSRichard Henderson                g_assert_not_reached();
64853ddad9bSRichard Henderson            }
64953ddad9bSRichard Henderson            aes256_set_encrypt_key(&ctx->key[0], key);
6506d92bdf4SRichard Henderson            aes256_set_decrypt_key(&ctx->key[1], key);
6516d92bdf4SRichard Henderson
65253ddad9bSRichard Henderson            return &ctx->base;
65353ddad9bSRichard Henderson        }
65453ddad9bSRichard Henderson
6556d92bdf4SRichard Henderson    case QCRYPTO_CIPHER_ALGO_CAST5_128:
65653ddad9bSRichard Henderson        {
65753ddad9bSRichard Henderson            QCryptoNettleCAST128 *ctx;
65853ddad9bSRichard Henderson            const QCryptoCipherDriver *drv;
65953ddad9bSRichard Henderson
66053ddad9bSRichard Henderson            switch (mode) {
66153ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_ECB:
66253ddad9bSRichard Henderson                drv = &qcrypto_nettle_cast128_driver_ecb;
66353ddad9bSRichard Henderson                break;
66453ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CBC:
66553ddad9bSRichard Henderson                drv = &qcrypto_nettle_cast128_driver_cbc;
66653ddad9bSRichard Henderson                break;
66753ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CTR:
6686d92bdf4SRichard Henderson                drv = &qcrypto_nettle_cast128_driver_ctr;
6696d92bdf4SRichard Henderson                break;
67053ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_XTS:
67153ddad9bSRichard Henderson                goto bad_cipher_mode;
67253ddad9bSRichard Henderson            default:
6736d92bdf4SRichard Henderson                g_assert_not_reached();
67453ddad9bSRichard Henderson            }
67553ddad9bSRichard Henderson
6766d92bdf4SRichard Henderson            ctx = g_new0(QCryptoNettleCAST128, 1);
6776d92bdf4SRichard Henderson            ctx->base.driver = drv;
6786d92bdf4SRichard Henderson            cast5_set_key(&ctx->key, nkey, key);
6796d92bdf4SRichard Henderson
68053ddad9bSRichard Henderson            return &ctx->base;
68153ddad9bSRichard Henderson        }
6826d92bdf4SRichard Henderson
68353ddad9bSRichard Henderson    case QCRYPTO_CIPHER_ALGO_SERPENT_128:
68453ddad9bSRichard Henderson    case QCRYPTO_CIPHER_ALGO_SERPENT_192:
68553ddad9bSRichard Henderson    case QCRYPTO_CIPHER_ALGO_SERPENT_256:
6866d92bdf4SRichard Henderson        {
68753ddad9bSRichard Henderson            QCryptoNettleSerpent *ctx = g_new0(QCryptoNettleSerpent, 1);
68853ddad9bSRichard Henderson
68953ddad9bSRichard Henderson            switch (mode) {
69053ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_ECB:
69153ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_serpent_driver_ecb;
69253ddad9bSRichard Henderson                break;
69353ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CBC:
69453ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_serpent_driver_cbc;
69553ddad9bSRichard Henderson                break;
69653ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CTR:
69753ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_serpent_driver_ctr;
69853ddad9bSRichard Henderson                break;
69953ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_XTS:
70053ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_serpent_driver_xts;
70153ddad9bSRichard Henderson                nkey /= 2;
70253ddad9bSRichard Henderson                serpent_set_key(&ctx->key_xts, nkey, key + nkey);
70353ddad9bSRichard Henderson                break;
70453ddad9bSRichard Henderson            default:
7056d92bdf4SRichard Henderson                g_assert_not_reached();
7066d92bdf4SRichard Henderson            }
7076d92bdf4SRichard Henderson            serpent_set_key(&ctx->key, nkey, key);
7086d92bdf4SRichard Henderson
70953ddad9bSRichard Henderson            return &ctx->base;
71053ddad9bSRichard Henderson        }
7116d92bdf4SRichard Henderson
71253ddad9bSRichard Henderson    case QCRYPTO_CIPHER_ALGO_TWOFISH_128:
71353ddad9bSRichard Henderson    case QCRYPTO_CIPHER_ALGO_TWOFISH_192:
71453ddad9bSRichard Henderson    case QCRYPTO_CIPHER_ALGO_TWOFISH_256:
7156d92bdf4SRichard Henderson        {
71653ddad9bSRichard Henderson            QCryptoNettleTwofish *ctx = g_new0(QCryptoNettleTwofish, 1);
71753ddad9bSRichard Henderson
71853ddad9bSRichard Henderson            switch (mode) {
71953ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_ECB:
72053ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_twofish_driver_ecb;
72153ddad9bSRichard Henderson                break;
72253ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CBC:
72353ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_twofish_driver_cbc;
72453ddad9bSRichard Henderson                break;
72553ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_CTR:
72653ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_twofish_driver_ctr;
72753ddad9bSRichard Henderson                break;
72853ddad9bSRichard Henderson            case QCRYPTO_CIPHER_MODE_XTS:
72953ddad9bSRichard Henderson                ctx->base.driver = &qcrypto_nettle_twofish_driver_xts;
73053ddad9bSRichard Henderson                nkey /= 2;
73153ddad9bSRichard Henderson                twofish_set_key(&ctx->key_xts, nkey, key + nkey);
73253ddad9bSRichard Henderson                break;
73353ddad9bSRichard Henderson            default:
73452ed9f45SHyman Huang                g_assert_not_reached();
73552ed9f45SHyman Huang            }
73652ed9f45SHyman Huang            twofish_set_key(&ctx->key, nkey, key);
737*3148a16bSDaniel P. Berrangé
738*3148a16bSDaniel P. Berrangé            return &ctx->base;
73952ed9f45SHyman Huang        }
74052ed9f45SHyman Huang#ifdef CONFIG_CRYPTO_SM4
74152ed9f45SHyman Huang    case QCRYPTO_CIPHER_ALGO_SM4:
742*3148a16bSDaniel P. Berrangé        {
74352ed9f45SHyman Huang            QCryptoNettleSm4 *ctx;
74452ed9f45SHyman Huang            const QCryptoCipherDriver *drv;
74552ed9f45SHyman Huang
74652ed9f45SHyman Huang            switch (mode) {
74752ed9f45SHyman Huang            case QCRYPTO_CIPHER_MODE_ECB:
748*3148a16bSDaniel P. Berrangé                drv = &qcrypto_nettle_sm4_driver_ecb;
749*3148a16bSDaniel P. Berrangé                break;
75052ed9f45SHyman Huang            case QCRYPTO_CIPHER_MODE_CBC:
75152ed9f45SHyman Huang            case QCRYPTO_CIPHER_MODE_CTR:
75252ed9f45SHyman Huang            case QCRYPTO_CIPHER_MODE_XTS:
75352ed9f45SHyman Huang                goto bad_cipher_mode;
75452ed9f45SHyman Huang            default:
75552ed9f45SHyman Huang                g_assert_not_reached();
7566d92bdf4SRichard Henderson            }
7576d92bdf4SRichard Henderson
7586d92bdf4SRichard Henderson            ctx = g_new0(QCryptoNettleSm4, 1);
7596d92bdf4SRichard Henderson            ctx->base.driver = drv;
7606d92bdf4SRichard Henderson            sm4_set_encrypt_key(&ctx->key[0], key);
7616d92bdf4SRichard Henderson            sm4_set_decrypt_key(&ctx->key[1], key);
7626d92bdf4SRichard Henderson
76353ddad9bSRichard Henderson            return &ctx->base;
7646d92bdf4SRichard Henderson        }
76553ddad9bSRichard Henderson#endif
76653ddad9bSRichard Henderson
7676d92bdf4SRichard Henderson    default:
768        error_setg(errp, "Unsupported cipher algorithm %s",
769                   QCryptoCipherAlgo_str(alg));
770        return NULL;
771    }
772
773 bad_cipher_mode:
774    error_setg(errp, "Unsupported cipher mode %s",
775               QCryptoCipherMode_str(mode));
776    return NULL;
777}
778