twofish_glue_3way.c revision 81559f9ad3d88c033e4ec3b6468012dbfda3b31d
18280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna/*
28280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * Glue Code for 3-way parallel assembler optimized version of Twofish
38280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna *
48280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
58280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna *
68280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
78280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna *   Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
88280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * CTR part based on code (crypto/ctr.c) by:
98280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna *   (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
108280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna *
118280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * This program is free software; you can redistribute it and/or modify
128280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * it under the terms of the GNU General Public License as published by
138280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * the Free Software Foundation; either version 2 of the License, or
148280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * (at your option) any later version.
158280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna *
168280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * This program is distributed in the hope that it will be useful,
178280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * but WITHOUT ANY WARRANTY; without even the implied warranty of
188280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
198280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * GNU General Public License for more details.
208280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna *
218280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * You should have received a copy of the GNU General Public License
228280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * along with this program; if not, write to the Free Software
238280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
248280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna * USA
258280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna *
268280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna */
278280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
288280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna#include <linux/crypto.h>
298280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna#include <linux/init.h>
308280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna#include <linux/module.h>
318280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna#include <linux/types.h>
328280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna#include <crypto/algapi.h>
338280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna#include <crypto/twofish.h>
348280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna#include <crypto/b128ops.h>
3581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#include <crypto/lrw.h>
3681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
3781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#if defined(CONFIG_CRYPTO_LRW) || defined(CONFIG_CRYPTO_LRW_MODULE)
3881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#define HAS_LRW
3981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#endif
408280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
418280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna/* regular block cipher functions from twofish_x86_64 module */
428280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnaasmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst,
438280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				const u8 *src);
448280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnaasmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst,
458280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				const u8 *src);
468280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
478280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna/* 3-way parallel cipher functions */
488280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnaasmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
498280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				       const u8 *src, bool xor);
508280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnaasmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst,
518280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				     const u8 *src);
528280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
538280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
548280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna					const u8 *src)
558280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
568280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	__twofish_enc_blk_3way(ctx, dst, src, false);
578280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
588280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
598280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst,
608280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna					    const u8 *src)
618280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
628280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	__twofish_enc_blk_3way(ctx, dst, src, true);
638280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
648280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
658280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk,
668280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		     void (*fn)(struct twofish_ctx *, u8 *, const u8 *),
678280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		     void (*fn_3way)(struct twofish_ctx *, u8 *, const u8 *))
688280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
698280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
708280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	unsigned int bsize = TF_BLOCK_SIZE;
718280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	unsigned int nbytes;
728280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	int err;
738280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
748280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	err = blkcipher_walk_virt(desc, walk);
758280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
768280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	while ((nbytes = walk->nbytes)) {
778280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		u8 *wsrc = walk->src.virt.addr;
788280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		u8 *wdst = walk->dst.virt.addr;
798280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
808280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		/* Process three block batch */
818280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		if (nbytes >= bsize * 3) {
828280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			do {
838280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				fn_3way(ctx, wdst, wsrc);
848280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
858280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				wsrc += bsize * 3;
868280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				wdst += bsize * 3;
878280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				nbytes -= bsize * 3;
888280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			} while (nbytes >= bsize * 3);
898280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
908280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			if (nbytes < bsize)
918280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				goto done;
928280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		}
938280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
948280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		/* Handle leftovers */
958280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		do {
968280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			fn(ctx, wdst, wsrc);
978280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
988280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			wsrc += bsize;
998280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			wdst += bsize;
1008280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			nbytes -= bsize;
1018280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		} while (nbytes >= bsize);
1028280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1038280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnadone:
1048280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		err = blkcipher_walk_done(desc, walk, nbytes);
1058280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	}
1068280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1078280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return err;
1088280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
1098280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1108280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
1118280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		       struct scatterlist *src, unsigned int nbytes)
1128280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
1138280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	struct blkcipher_walk walk;
1148280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1158280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	blkcipher_walk_init(&walk, dst, src, nbytes);
1168280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return ecb_crypt(desc, &walk, twofish_enc_blk, twofish_enc_blk_3way);
1178280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
1188280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1198280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
1208280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		       struct scatterlist *src, unsigned int nbytes)
1218280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
1228280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	struct blkcipher_walk walk;
1238280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1248280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	blkcipher_walk_init(&walk, dst, src, nbytes);
1258280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return ecb_crypt(desc, &walk, twofish_dec_blk, twofish_dec_blk_3way);
1268280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
1278280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1288280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic struct crypto_alg blk_ecb_alg = {
1298280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_name		= "ecb(twofish)",
1308280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_driver_name	= "ecb-twofish-3way",
1318280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_priority		= 300,
1328280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
1338280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_blocksize		= TF_BLOCK_SIZE,
1348280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_ctxsize		= sizeof(struct twofish_ctx),
1358280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_alignmask		= 0,
1368280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_type		= &crypto_blkcipher_type,
1378280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_module		= THIS_MODULE,
1388280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_list		= LIST_HEAD_INIT(blk_ecb_alg.cra_list),
1398280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_u = {
1408280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		.blkcipher = {
1418280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.min_keysize	= TF_MIN_KEY_SIZE,
1428280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.max_keysize	= TF_MAX_KEY_SIZE,
1438280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.setkey		= twofish_setkey,
1448280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.encrypt	= ecb_encrypt,
1458280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.decrypt	= ecb_decrypt,
1468280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		},
1478280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	},
1488280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna};
1498280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1508280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic unsigned int __cbc_encrypt(struct blkcipher_desc *desc,
1518280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				  struct blkcipher_walk *walk)
1528280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
1538280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
1548280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	unsigned int bsize = TF_BLOCK_SIZE;
1558280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	unsigned int nbytes = walk->nbytes;
1568280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128 *src = (u128 *)walk->src.virt.addr;
1578280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128 *dst = (u128 *)walk->dst.virt.addr;
1588280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128 *iv = (u128 *)walk->iv;
1598280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1608280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	do {
1618280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		u128_xor(dst, src, iv);
1628280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		twofish_enc_blk(ctx, (u8 *)dst, (u8 *)dst);
1638280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		iv = dst;
1648280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1658280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		src += 1;
1668280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		dst += 1;
1678280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		nbytes -= bsize;
1688280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	} while (nbytes >= bsize);
1698280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1708280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv);
1718280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return nbytes;
1728280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
1738280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1748280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
1758280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		       struct scatterlist *src, unsigned int nbytes)
1768280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
1778280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	struct blkcipher_walk walk;
1788280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	int err;
1798280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1808280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	blkcipher_walk_init(&walk, dst, src, nbytes);
1818280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	err = blkcipher_walk_virt(desc, &walk);
1828280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1838280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	while ((nbytes = walk.nbytes)) {
1848280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		nbytes = __cbc_encrypt(desc, &walk);
1858280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		err = blkcipher_walk_done(desc, &walk, nbytes);
1868280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	}
1878280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1888280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return err;
1898280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
1908280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
1918280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
1928280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				  struct blkcipher_walk *walk)
1938280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
1948280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
1958280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	unsigned int bsize = TF_BLOCK_SIZE;
1968280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	unsigned int nbytes = walk->nbytes;
1978280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128 *src = (u128 *)walk->src.virt.addr;
1988280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128 *dst = (u128 *)walk->dst.virt.addr;
1998280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128 ivs[3 - 1];
2008280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128 last_iv;
2018280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2028280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	/* Start of the last block. */
2038280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	src += nbytes / bsize - 1;
2048280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	dst += nbytes / bsize - 1;
2058280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2068280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	last_iv = *src;
2078280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2088280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	/* Process three block batch */
2098280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	if (nbytes >= bsize * 3) {
2108280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		do {
2118280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			nbytes -= bsize * (3 - 1);
2128280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			src -= 3 - 1;
2138280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			dst -= 3 - 1;
2148280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2158280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			ivs[0] = src[0];
2168280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			ivs[1] = src[1];
2178280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2188280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src);
2198280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2208280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			u128_xor(dst + 1, dst + 1, ivs + 0);
2218280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			u128_xor(dst + 2, dst + 2, ivs + 1);
2228280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2238280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			nbytes -= bsize;
2248280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			if (nbytes < bsize)
2258280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				goto done;
2268280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2278280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			u128_xor(dst, dst, src - 1);
2288280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			src -= 1;
2298280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			dst -= 1;
2308280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		} while (nbytes >= bsize * 3);
2318280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2328280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		if (nbytes < bsize)
2338280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			goto done;
2348280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	}
2358280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2368280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	/* Handle leftovers */
2378280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	for (;;) {
2388280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		twofish_dec_blk(ctx, (u8 *)dst, (u8 *)src);
2398280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2408280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		nbytes -= bsize;
2418280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		if (nbytes < bsize)
2428280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			break;
2438280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2448280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		u128_xor(dst, dst, src - 1);
2458280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		src -= 1;
2468280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		dst -= 1;
2478280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	}
2488280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2498280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnadone:
2508280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128_xor(dst, dst, (u128 *)walk->iv);
2518280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	*(u128 *)walk->iv = last_iv;
2528280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2538280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return nbytes;
2548280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
2558280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2568280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
2578280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		       struct scatterlist *src, unsigned int nbytes)
2588280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
2598280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	struct blkcipher_walk walk;
2608280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	int err;
2618280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2628280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	blkcipher_walk_init(&walk, dst, src, nbytes);
2638280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	err = blkcipher_walk_virt(desc, &walk);
2648280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2658280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	while ((nbytes = walk.nbytes)) {
2668280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		nbytes = __cbc_decrypt(desc, &walk);
2678280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		err = blkcipher_walk_done(desc, &walk, nbytes);
2688280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	}
2698280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2708280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return err;
2718280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
2728280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2738280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic struct crypto_alg blk_cbc_alg = {
2748280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_name		= "cbc(twofish)",
2758280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_driver_name	= "cbc-twofish-3way",
2768280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_priority		= 300,
2778280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
2788280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_blocksize		= TF_BLOCK_SIZE,
2798280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_ctxsize		= sizeof(struct twofish_ctx),
2808280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_alignmask		= 0,
2818280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_type		= &crypto_blkcipher_type,
2828280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_module		= THIS_MODULE,
2838280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_list		= LIST_HEAD_INIT(blk_cbc_alg.cra_list),
2848280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_u = {
2858280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		.blkcipher = {
2868280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.min_keysize	= TF_MIN_KEY_SIZE,
2878280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.max_keysize	= TF_MAX_KEY_SIZE,
2888280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.ivsize		= TF_BLOCK_SIZE,
2898280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.setkey		= twofish_setkey,
2908280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.encrypt	= cbc_encrypt,
2918280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.decrypt	= cbc_decrypt,
2928280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		},
2938280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	},
2948280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna};
2958280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
2968280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic inline void u128_to_be128(be128 *dst, const u128 *src)
2978280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
2988280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	dst->a = cpu_to_be64(src->a);
2998280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	dst->b = cpu_to_be64(src->b);
3008280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
3018280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3028280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic inline void be128_to_u128(u128 *dst, const be128 *src)
3038280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
3048280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	dst->a = be64_to_cpu(src->a);
3058280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	dst->b = be64_to_cpu(src->b);
3068280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
3078280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3088280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic inline void u128_inc(u128 *i)
3098280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
3108280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	i->b++;
3118280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	if (!i->b)
3128280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		i->a++;
3138280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
3148280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3158280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic void ctr_crypt_final(struct blkcipher_desc *desc,
3168280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			    struct blkcipher_walk *walk)
3178280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
3188280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
3198280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u8 *ctrblk = walk->iv;
3208280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u8 keystream[TF_BLOCK_SIZE];
3218280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u8 *src = walk->src.virt.addr;
3228280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u8 *dst = walk->dst.virt.addr;
3238280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	unsigned int nbytes = walk->nbytes;
3248280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3258280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	twofish_enc_blk(ctx, keystream, ctrblk);
3268280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	crypto_xor(keystream, src, nbytes);
3278280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	memcpy(dst, keystream, nbytes);
3288280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3298280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	crypto_inc(ctrblk, TF_BLOCK_SIZE);
3308280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
3318280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3328280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic unsigned int __ctr_crypt(struct blkcipher_desc *desc,
3338280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				struct blkcipher_walk *walk)
3348280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
3358280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
3368280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	unsigned int bsize = TF_BLOCK_SIZE;
3378280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	unsigned int nbytes = walk->nbytes;
3388280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128 *src = (u128 *)walk->src.virt.addr;
3398280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128 *dst = (u128 *)walk->dst.virt.addr;
3408280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128 ctrblk;
3418280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	be128 ctrblocks[3];
3428280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3438280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	be128_to_u128(&ctrblk, (be128 *)walk->iv);
3448280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3458280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	/* Process three block batch */
3468280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	if (nbytes >= bsize * 3) {
3478280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		do {
3488280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			if (dst != src) {
3498280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				dst[0] = src[0];
3508280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				dst[1] = src[1];
3518280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna				dst[2] = src[2];
3528280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			}
3538280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3548280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			/* create ctrblks for parallel encrypt */
3558280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			u128_to_be128(&ctrblocks[0], &ctrblk);
3568280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			u128_inc(&ctrblk);
3578280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			u128_to_be128(&ctrblocks[1], &ctrblk);
3588280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			u128_inc(&ctrblk);
3598280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			u128_to_be128(&ctrblocks[2], &ctrblk);
3608280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			u128_inc(&ctrblk);
3618280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3628280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			twofish_enc_blk_xor_3way(ctx, (u8 *)dst,
3638280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna						 (u8 *)ctrblocks);
3648280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3658280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			src += 3;
3668280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			dst += 3;
3678280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			nbytes -= bsize * 3;
3688280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		} while (nbytes >= bsize * 3);
3698280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3708280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		if (nbytes < bsize)
3718280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			goto done;
3728280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	}
3738280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3748280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	/* Handle leftovers */
3758280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	do {
3768280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		if (dst != src)
3778280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			*dst = *src;
3788280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3798280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		u128_to_be128(&ctrblocks[0], &ctrblk);
3808280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		u128_inc(&ctrblk);
3818280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3828280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		twofish_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks);
3838280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		u128_xor(dst, dst, (u128 *)ctrblocks);
3848280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3858280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		src += 1;
3868280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		dst += 1;
3878280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		nbytes -= bsize;
3888280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	} while (nbytes >= bsize);
3898280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3908280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnadone:
3918280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	u128_to_be128((be128 *)walk->iv, &ctrblk);
3928280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return nbytes;
3938280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
3948280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
3958280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
3968280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		     struct scatterlist *src, unsigned int nbytes)
3978280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
3988280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	struct blkcipher_walk walk;
3998280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	int err;
4008280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
4018280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	blkcipher_walk_init(&walk, dst, src, nbytes);
4028280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	err = blkcipher_walk_virt_block(desc, &walk, TF_BLOCK_SIZE);
4038280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
4048280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	while ((nbytes = walk.nbytes) >= TF_BLOCK_SIZE) {
4058280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		nbytes = __ctr_crypt(desc, &walk);
4068280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		err = blkcipher_walk_done(desc, &walk, nbytes);
4078280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	}
4088280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
4098280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	if (walk.nbytes) {
4108280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		ctr_crypt_final(desc, &walk);
4118280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		err = blkcipher_walk_done(desc, &walk, 0);
4128280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	}
4138280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
4148280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return err;
4158280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
4168280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
4178280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnastatic struct crypto_alg blk_ctr_alg = {
4188280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_name		= "ctr(twofish)",
4198280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_driver_name	= "ctr-twofish-3way",
4208280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_priority		= 300,
4218280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
422906b2c9f2d9f395f5ca01b855b7c74b126517816Jussi Kivilinna	.cra_blocksize		= 1,
4238280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_ctxsize		= sizeof(struct twofish_ctx),
4248280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_alignmask		= 0,
4258280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_type		= &crypto_blkcipher_type,
4268280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_module		= THIS_MODULE,
4278280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_list		= LIST_HEAD_INIT(blk_ctr_alg.cra_list),
4288280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	.cra_u = {
4298280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		.blkcipher = {
4308280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.min_keysize	= TF_MIN_KEY_SIZE,
4318280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.max_keysize	= TF_MAX_KEY_SIZE,
4328280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.ivsize		= TF_BLOCK_SIZE,
4338280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.setkey		= twofish_setkey,
4348280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.encrypt	= ctr_crypt,
4358280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna			.decrypt	= ctr_crypt,
4368280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		},
4378280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	},
4388280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna};
4398280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
44081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#ifdef HAS_LRW
44181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
44281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinnastatic void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
44381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna{
44481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	const unsigned int bsize = TF_BLOCK_SIZE;
44581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	struct twofish_ctx *ctx = priv;
44681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	int i;
44781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
44881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	if (nbytes == 3 * bsize) {
44981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		twofish_enc_blk_3way(ctx, srcdst, srcdst);
45081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		return;
45181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	}
45281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
45381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
45481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		twofish_enc_blk(ctx, srcdst, srcdst);
45581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna}
45681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
45781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinnastatic void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
45881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna{
45981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	const unsigned int bsize = TF_BLOCK_SIZE;
46081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	struct twofish_ctx *ctx = priv;
46181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	int i;
46281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
46381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	if (nbytes == 3 * bsize) {
46481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		twofish_dec_blk_3way(ctx, srcdst, srcdst);
46581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		return;
46681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	}
46781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
46881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
46981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		twofish_dec_blk(ctx, srcdst, srcdst);
47081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna}
47181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
47281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinnastruct twofish_lrw_ctx {
47381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	struct lrw_table_ctx lrw_table;
47481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	struct twofish_ctx twofish_ctx;
47581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna};
47681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
47781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinnastatic int lrw_twofish_setkey(struct crypto_tfm *tfm, const u8 *key,
47881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna			      unsigned int keylen)
47981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna{
48081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
48181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	int err;
48281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
48381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	err = __twofish_setkey(&ctx->twofish_ctx, key, keylen - TF_BLOCK_SIZE,
48481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna			       &tfm->crt_flags);
48581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	if (err)
48681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		return err;
48781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
48881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	return lrw_init_table(&ctx->lrw_table, key + keylen - TF_BLOCK_SIZE);
48981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna}
49081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
49181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinnastatic int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
49281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		       struct scatterlist *src, unsigned int nbytes)
49381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna{
49481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
49581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	be128 buf[3];
49681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	struct lrw_crypt_req req = {
49781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.tbuf = buf,
49881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.tbuflen = sizeof(buf),
49981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
50081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.table_ctx = &ctx->lrw_table,
50181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.crypt_ctx = &ctx->twofish_ctx,
50281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.crypt_fn = encrypt_callback,
50381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	};
50481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
50581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	return lrw_crypt(desc, dst, src, nbytes, &req);
50681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna}
50781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
50881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinnastatic int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
50981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		       struct scatterlist *src, unsigned int nbytes)
51081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna{
51181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	struct twofish_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
51281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	be128 buf[3];
51381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	struct lrw_crypt_req req = {
51481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.tbuf = buf,
51581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.tbuflen = sizeof(buf),
51681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
51781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.table_ctx = &ctx->lrw_table,
51881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.crypt_ctx = &ctx->twofish_ctx,
51981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.crypt_fn = decrypt_callback,
52081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	};
52181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
52281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	return lrw_crypt(desc, dst, src, nbytes, &req);
52381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna}
52481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
52581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinnastatic void lrw_exit_tfm(struct crypto_tfm *tfm)
52681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna{
52781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	struct twofish_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
52881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
52981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	lrw_free_table(&ctx->lrw_table);
53081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna}
53181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
53281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinnastatic struct crypto_alg blk_lrw_alg = {
53381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_name		= "lrw(twofish)",
53481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_driver_name	= "lrw-twofish-3way",
53581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_priority		= 300,
53681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
53781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_blocksize		= TF_BLOCK_SIZE,
53881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_ctxsize		= sizeof(struct twofish_lrw_ctx),
53981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_alignmask		= 0,
54081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_type		= &crypto_blkcipher_type,
54181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_module		= THIS_MODULE,
54281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_list		= LIST_HEAD_INIT(blk_lrw_alg.cra_list),
54381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_exit		= lrw_exit_tfm,
54481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	.cra_u = {
54581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		.blkcipher = {
54681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna			.min_keysize	= TF_MIN_KEY_SIZE + TF_BLOCK_SIZE,
54781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna			.max_keysize	= TF_MAX_KEY_SIZE + TF_BLOCK_SIZE,
54881559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna			.ivsize		= TF_BLOCK_SIZE,
54981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna			.setkey		= lrw_twofish_setkey,
55081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna			.encrypt	= lrw_encrypt,
55181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna			.decrypt	= lrw_decrypt,
55281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		},
55381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	},
55481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna};
55581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
55681559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#endif
55781559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna
5588280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnaint __init init(void)
5598280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
5608280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	int err;
5618280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
5628280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	err = crypto_register_alg(&blk_ecb_alg);
5638280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	if (err)
5648280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		goto ecb_err;
5658280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	err = crypto_register_alg(&blk_cbc_alg);
5668280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	if (err)
5678280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		goto cbc_err;
5688280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	err = crypto_register_alg(&blk_ctr_alg);
5698280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	if (err)
5708280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna		goto ctr_err;
57181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#ifdef HAS_LRW
57281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	err = crypto_register_alg(&blk_lrw_alg);
57381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	if (err)
57481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna		goto blk_lrw_err;
57581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#endif
5768280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
5778280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return 0;
5788280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
57981559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#ifdef HAS_LRW
58081559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinnablk_lrw_err:
58181559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	crypto_unregister_alg(&blk_ctr_alg);
58281559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#endif
5838280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnactr_err:
5848280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	crypto_unregister_alg(&blk_cbc_alg);
5858280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnacbc_err:
5868280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	crypto_unregister_alg(&blk_ecb_alg);
5878280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnaecb_err:
5888280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	return err;
5898280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
5908280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
5918280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnavoid __exit fini(void)
5928280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna{
59381559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#ifdef HAS_LRW
59481559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna	crypto_unregister_alg(&blk_lrw_alg);
59581559f9ad3d88c033e4ec3b6468012dbfda3b31dJussi Kivilinna#endif
5968280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	crypto_unregister_alg(&blk_ctr_alg);
5978280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	crypto_unregister_alg(&blk_cbc_alg);
5988280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna	crypto_unregister_alg(&blk_ecb_alg);
5998280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna}
6008280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
6018280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnamodule_init(init);
6028280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinnamodule_exit(fini);
6038280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi Kivilinna
6048280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi KivilinnaMODULE_LICENSE("GPL");
6058280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi KivilinnaMODULE_DESCRIPTION("Twofish Cipher Algorithm, 3-way parallel asm optimized");
6068280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi KivilinnaMODULE_ALIAS("twofish");
6078280daad436edb7dd9e7e06fc13bcecb6b2a885cJussi KivilinnaMODULE_ALIAS("twofish-asm");
608