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