1937c30d7SJussi Kivilinna /*
2937c30d7SJussi Kivilinna  * Glue Code for SSE2 assembler versions of Serpent Cipher
3937c30d7SJussi Kivilinna  *
4937c30d7SJussi Kivilinna  * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
5937c30d7SJussi Kivilinna  *
6937c30d7SJussi Kivilinna  * Glue code based on aesni-intel_glue.c by:
7937c30d7SJussi Kivilinna  *  Copyright (C) 2008, Intel Corp.
8937c30d7SJussi Kivilinna  *    Author: Huang Ying <ying.huang@intel.com>
9937c30d7SJussi Kivilinna  *
10937c30d7SJussi Kivilinna  * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
11937c30d7SJussi Kivilinna  *   Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
12937c30d7SJussi Kivilinna  * CTR part based on code (crypto/ctr.c) by:
13937c30d7SJussi Kivilinna  *   (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
14937c30d7SJussi Kivilinna  *
15937c30d7SJussi Kivilinna  * This program is free software; you can redistribute it and/or modify
16937c30d7SJussi Kivilinna  * it under the terms of the GNU General Public License as published by
17937c30d7SJussi Kivilinna  * the Free Software Foundation; either version 2 of the License, or
18937c30d7SJussi Kivilinna  * (at your option) any later version.
19937c30d7SJussi Kivilinna  *
20937c30d7SJussi Kivilinna  * This program is distributed in the hope that it will be useful,
21937c30d7SJussi Kivilinna  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22937c30d7SJussi Kivilinna  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23937c30d7SJussi Kivilinna  * GNU General Public License for more details.
24937c30d7SJussi Kivilinna  *
25937c30d7SJussi Kivilinna  * You should have received a copy of the GNU General Public License
26937c30d7SJussi Kivilinna  * along with this program; if not, write to the Free Software
27937c30d7SJussi Kivilinna  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
28937c30d7SJussi Kivilinna  * USA
29937c30d7SJussi Kivilinna  *
30937c30d7SJussi Kivilinna  */
31937c30d7SJussi Kivilinna 
32937c30d7SJussi Kivilinna #include <linux/module.h>
33937c30d7SJussi Kivilinna #include <linux/hardirq.h>
34937c30d7SJussi Kivilinna #include <linux/types.h>
35937c30d7SJussi Kivilinna #include <linux/crypto.h>
36937c30d7SJussi Kivilinna #include <linux/err.h>
37801201aaSArd Biesheuvel #include <crypto/ablk_helper.h>
38937c30d7SJussi Kivilinna #include <crypto/algapi.h>
39937c30d7SJussi Kivilinna #include <crypto/serpent.h>
40937c30d7SJussi Kivilinna #include <crypto/cryptd.h>
41937c30d7SJussi Kivilinna #include <crypto/b128ops.h>
42937c30d7SJussi Kivilinna #include <crypto/ctr.h>
4318482053SJussi Kivilinna #include <crypto/lrw.h>
445962f8b6SJussi Kivilinna #include <crypto/xts.h>
45d4af0e9dSJussi Kivilinna #include <asm/crypto/serpent-sse2.h>
46596d8750SJussi Kivilinna #include <asm/crypto/glue_helper.h>
47937c30d7SJussi Kivilinna 
48e81792fbSJussi Kivilinna static void serpent_decrypt_cbc_xway(void *ctx, u128 *dst, const u128 *src)
49e81792fbSJussi Kivilinna {
50e81792fbSJussi Kivilinna 	u128 ivs[SERPENT_PARALLEL_BLOCKS - 1];
51e81792fbSJussi Kivilinna 	unsigned int j;
52e81792fbSJussi Kivilinna 
53e81792fbSJussi Kivilinna 	for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++)
54e81792fbSJussi Kivilinna 		ivs[j] = src[j];
55e81792fbSJussi Kivilinna 
56e81792fbSJussi Kivilinna 	serpent_dec_blk_xway(ctx, (u8 *)dst, (u8 *)src);
57e81792fbSJussi Kivilinna 
58e81792fbSJussi Kivilinna 	for (j = 0; j < SERPENT_PARALLEL_BLOCKS - 1; j++)
59e81792fbSJussi Kivilinna 		u128_xor(dst + (j + 1), dst + (j + 1), ivs + j);
60e81792fbSJussi Kivilinna }
61e81792fbSJussi Kivilinna 
6258990986SJussi Kivilinna static void serpent_crypt_ctr(void *ctx, u128 *dst, const u128 *src, le128 *iv)
63e81792fbSJussi Kivilinna {
64e81792fbSJussi Kivilinna 	be128 ctrblk;
65e81792fbSJussi Kivilinna 
6658990986SJussi Kivilinna 	le128_to_be128(&ctrblk, iv);
6758990986SJussi Kivilinna 	le128_inc(iv);
68e81792fbSJussi Kivilinna 
69e81792fbSJussi Kivilinna 	__serpent_encrypt(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk);
70e81792fbSJussi Kivilinna 	u128_xor(dst, src, (u128 *)&ctrblk);
71e81792fbSJussi Kivilinna }
72e81792fbSJussi Kivilinna 
73e81792fbSJussi Kivilinna static void serpent_crypt_ctr_xway(void *ctx, u128 *dst, const u128 *src,
7458990986SJussi Kivilinna 				   le128 *iv)
75e81792fbSJussi Kivilinna {
76e81792fbSJussi Kivilinna 	be128 ctrblks[SERPENT_PARALLEL_BLOCKS];
77e81792fbSJussi Kivilinna 	unsigned int i;
78e81792fbSJussi Kivilinna 
79e81792fbSJussi Kivilinna 	for (i = 0; i < SERPENT_PARALLEL_BLOCKS; i++) {
80e81792fbSJussi Kivilinna 		if (dst != src)
81e81792fbSJussi Kivilinna 			dst[i] = src[i];
82e81792fbSJussi Kivilinna 
8358990986SJussi Kivilinna 		le128_to_be128(&ctrblks[i], iv);
8458990986SJussi Kivilinna 		le128_inc(iv);
85e81792fbSJussi Kivilinna 	}
86e81792fbSJussi Kivilinna 
87e81792fbSJussi Kivilinna 	serpent_enc_blk_xway_xor(ctx, (u8 *)dst, (u8 *)ctrblks);
88e81792fbSJussi Kivilinna }
89e81792fbSJussi Kivilinna 
90e81792fbSJussi Kivilinna static const struct common_glue_ctx serpent_enc = {
91e81792fbSJussi Kivilinna 	.num_funcs = 2,
92e81792fbSJussi Kivilinna 	.fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS,
93e81792fbSJussi Kivilinna 
94e81792fbSJussi Kivilinna 	.funcs = { {
95e81792fbSJussi Kivilinna 		.num_blocks = SERPENT_PARALLEL_BLOCKS,
96e81792fbSJussi Kivilinna 		.fn_u = { .ecb = GLUE_FUNC_CAST(serpent_enc_blk_xway) }
97e81792fbSJussi Kivilinna 	}, {
98e81792fbSJussi Kivilinna 		.num_blocks = 1,
99e81792fbSJussi Kivilinna 		.fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_encrypt) }
100e81792fbSJussi Kivilinna 	} }
101e81792fbSJussi Kivilinna };
102e81792fbSJussi Kivilinna 
103e81792fbSJussi Kivilinna static const struct common_glue_ctx serpent_ctr = {
104e81792fbSJussi Kivilinna 	.num_funcs = 2,
105e81792fbSJussi Kivilinna 	.fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS,
106e81792fbSJussi Kivilinna 
107e81792fbSJussi Kivilinna 	.funcs = { {
108e81792fbSJussi Kivilinna 		.num_blocks = SERPENT_PARALLEL_BLOCKS,
109e81792fbSJussi Kivilinna 		.fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr_xway) }
110e81792fbSJussi Kivilinna 	}, {
111e81792fbSJussi Kivilinna 		.num_blocks = 1,
112e81792fbSJussi Kivilinna 		.fn_u = { .ctr = GLUE_CTR_FUNC_CAST(serpent_crypt_ctr) }
113e81792fbSJussi Kivilinna 	} }
114e81792fbSJussi Kivilinna };
115e81792fbSJussi Kivilinna 
116e81792fbSJussi Kivilinna static const struct common_glue_ctx serpent_dec = {
117e81792fbSJussi Kivilinna 	.num_funcs = 2,
118e81792fbSJussi Kivilinna 	.fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS,
119e81792fbSJussi Kivilinna 
120e81792fbSJussi Kivilinna 	.funcs = { {
121e81792fbSJussi Kivilinna 		.num_blocks = SERPENT_PARALLEL_BLOCKS,
122e81792fbSJussi Kivilinna 		.fn_u = { .ecb = GLUE_FUNC_CAST(serpent_dec_blk_xway) }
123e81792fbSJussi Kivilinna 	}, {
124e81792fbSJussi Kivilinna 		.num_blocks = 1,
125e81792fbSJussi Kivilinna 		.fn_u = { .ecb = GLUE_FUNC_CAST(__serpent_decrypt) }
126e81792fbSJussi Kivilinna 	} }
127e81792fbSJussi Kivilinna };
128e81792fbSJussi Kivilinna 
129e81792fbSJussi Kivilinna static const struct common_glue_ctx serpent_dec_cbc = {
130e81792fbSJussi Kivilinna 	.num_funcs = 2,
131e81792fbSJussi Kivilinna 	.fpu_blocks_limit = SERPENT_PARALLEL_BLOCKS,
132e81792fbSJussi Kivilinna 
133e81792fbSJussi Kivilinna 	.funcs = { {
134e81792fbSJussi Kivilinna 		.num_blocks = SERPENT_PARALLEL_BLOCKS,
135e81792fbSJussi Kivilinna 		.fn_u = { .cbc = GLUE_CBC_FUNC_CAST(serpent_decrypt_cbc_xway) }
136e81792fbSJussi Kivilinna 	}, {
137e81792fbSJussi Kivilinna 		.num_blocks = 1,
138e81792fbSJussi Kivilinna 		.fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__serpent_decrypt) }
139e81792fbSJussi Kivilinna 	} }
140e81792fbSJussi Kivilinna };
141e81792fbSJussi Kivilinna 
142e81792fbSJussi Kivilinna static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
143e81792fbSJussi Kivilinna 		       struct scatterlist *src, unsigned int nbytes)
144e81792fbSJussi Kivilinna {
145e81792fbSJussi Kivilinna 	return glue_ecb_crypt_128bit(&serpent_enc, desc, dst, src, nbytes);
146e81792fbSJussi Kivilinna }
147e81792fbSJussi Kivilinna 
148e81792fbSJussi Kivilinna static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
149e81792fbSJussi Kivilinna 		       struct scatterlist *src, unsigned int nbytes)
150e81792fbSJussi Kivilinna {
151e81792fbSJussi Kivilinna 	return glue_ecb_crypt_128bit(&serpent_dec, desc, dst, src, nbytes);
152e81792fbSJussi Kivilinna }
153e81792fbSJussi Kivilinna 
154e81792fbSJussi Kivilinna static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
155e81792fbSJussi Kivilinna 		       struct scatterlist *src, unsigned int nbytes)
156e81792fbSJussi Kivilinna {
157e81792fbSJussi Kivilinna 	return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(__serpent_encrypt), desc,
158e81792fbSJussi Kivilinna 				     dst, src, nbytes);
159e81792fbSJussi Kivilinna }
160e81792fbSJussi Kivilinna 
161e81792fbSJussi Kivilinna static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
162e81792fbSJussi Kivilinna 		       struct scatterlist *src, unsigned int nbytes)
163e81792fbSJussi Kivilinna {
164e81792fbSJussi Kivilinna 	return glue_cbc_decrypt_128bit(&serpent_dec_cbc, desc, dst, src,
165e81792fbSJussi Kivilinna 				       nbytes);
166e81792fbSJussi Kivilinna }
167e81792fbSJussi Kivilinna 
168e81792fbSJussi Kivilinna static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
169e81792fbSJussi Kivilinna 		     struct scatterlist *src, unsigned int nbytes)
170e81792fbSJussi Kivilinna {
171e81792fbSJussi Kivilinna 	return glue_ctr_crypt_128bit(&serpent_ctr, desc, dst, src, nbytes);
172e81792fbSJussi Kivilinna }
173e81792fbSJussi Kivilinna 
174e81792fbSJussi Kivilinna static inline bool serpent_fpu_begin(bool fpu_enabled, unsigned int nbytes)
175e81792fbSJussi Kivilinna {
176e81792fbSJussi Kivilinna 	return glue_fpu_begin(SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS,
177e81792fbSJussi Kivilinna 			      NULL, fpu_enabled, nbytes);
178e81792fbSJussi Kivilinna }
179e81792fbSJussi Kivilinna 
180e81792fbSJussi Kivilinna static inline void serpent_fpu_end(bool fpu_enabled)
181e81792fbSJussi Kivilinna {
182e81792fbSJussi Kivilinna 	glue_fpu_end(fpu_enabled);
183e81792fbSJussi Kivilinna }
184e81792fbSJussi Kivilinna 
18518482053SJussi Kivilinna struct crypt_priv {
18618482053SJussi Kivilinna 	struct serpent_ctx *ctx;
18718482053SJussi Kivilinna 	bool fpu_enabled;
18818482053SJussi Kivilinna };
18918482053SJussi Kivilinna 
19018482053SJussi Kivilinna static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
19118482053SJussi Kivilinna {
19218482053SJussi Kivilinna 	const unsigned int bsize = SERPENT_BLOCK_SIZE;
19318482053SJussi Kivilinna 	struct crypt_priv *ctx = priv;
19418482053SJussi Kivilinna 	int i;
19518482053SJussi Kivilinna 
19618482053SJussi Kivilinna 	ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes);
19718482053SJussi Kivilinna 
19818482053SJussi Kivilinna 	if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) {
19918482053SJussi Kivilinna 		serpent_enc_blk_xway(ctx->ctx, srcdst, srcdst);
20018482053SJussi Kivilinna 		return;
20118482053SJussi Kivilinna 	}
20218482053SJussi Kivilinna 
20318482053SJussi Kivilinna 	for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
20418482053SJussi Kivilinna 		__serpent_encrypt(ctx->ctx, srcdst, srcdst);
20518482053SJussi Kivilinna }
20618482053SJussi Kivilinna 
20718482053SJussi Kivilinna static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
20818482053SJussi Kivilinna {
20918482053SJussi Kivilinna 	const unsigned int bsize = SERPENT_BLOCK_SIZE;
21018482053SJussi Kivilinna 	struct crypt_priv *ctx = priv;
21118482053SJussi Kivilinna 	int i;
21218482053SJussi Kivilinna 
21318482053SJussi Kivilinna 	ctx->fpu_enabled = serpent_fpu_begin(ctx->fpu_enabled, nbytes);
21418482053SJussi Kivilinna 
21518482053SJussi Kivilinna 	if (nbytes == bsize * SERPENT_PARALLEL_BLOCKS) {
21618482053SJussi Kivilinna 		serpent_dec_blk_xway(ctx->ctx, srcdst, srcdst);
21718482053SJussi Kivilinna 		return;
21818482053SJussi Kivilinna 	}
21918482053SJussi Kivilinna 
22018482053SJussi Kivilinna 	for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
22118482053SJussi Kivilinna 		__serpent_decrypt(ctx->ctx, srcdst, srcdst);
22218482053SJussi Kivilinna }
22318482053SJussi Kivilinna 
22418482053SJussi Kivilinna struct serpent_lrw_ctx {
22518482053SJussi Kivilinna 	struct lrw_table_ctx lrw_table;
22618482053SJussi Kivilinna 	struct serpent_ctx serpent_ctx;
22718482053SJussi Kivilinna };
22818482053SJussi Kivilinna 
22918482053SJussi Kivilinna static int lrw_serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
23018482053SJussi Kivilinna 			      unsigned int keylen)
23118482053SJussi Kivilinna {
23218482053SJussi Kivilinna 	struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
23318482053SJussi Kivilinna 	int err;
23418482053SJussi Kivilinna 
23518482053SJussi Kivilinna 	err = __serpent_setkey(&ctx->serpent_ctx, key, keylen -
23618482053SJussi Kivilinna 							SERPENT_BLOCK_SIZE);
23718482053SJussi Kivilinna 	if (err)
23818482053SJussi Kivilinna 		return err;
23918482053SJussi Kivilinna 
24018482053SJussi Kivilinna 	return lrw_init_table(&ctx->lrw_table, key + keylen -
24118482053SJussi Kivilinna 						SERPENT_BLOCK_SIZE);
24218482053SJussi Kivilinna }
24318482053SJussi Kivilinna 
24418482053SJussi Kivilinna static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
24518482053SJussi Kivilinna 		       struct scatterlist *src, unsigned int nbytes)
24618482053SJussi Kivilinna {
24718482053SJussi Kivilinna 	struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
24818482053SJussi Kivilinna 	be128 buf[SERPENT_PARALLEL_BLOCKS];
24918482053SJussi Kivilinna 	struct crypt_priv crypt_ctx = {
25018482053SJussi Kivilinna 		.ctx = &ctx->serpent_ctx,
25118482053SJussi Kivilinna 		.fpu_enabled = false,
25218482053SJussi Kivilinna 	};
25318482053SJussi Kivilinna 	struct lrw_crypt_req req = {
25418482053SJussi Kivilinna 		.tbuf = buf,
25518482053SJussi Kivilinna 		.tbuflen = sizeof(buf),
25618482053SJussi Kivilinna 
25718482053SJussi Kivilinna 		.table_ctx = &ctx->lrw_table,
25818482053SJussi Kivilinna 		.crypt_ctx = &crypt_ctx,
25918482053SJussi Kivilinna 		.crypt_fn = encrypt_callback,
26018482053SJussi Kivilinna 	};
26118482053SJussi Kivilinna 	int ret;
26218482053SJussi Kivilinna 
263d3564338SJussi Kivilinna 	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
26418482053SJussi Kivilinna 	ret = lrw_crypt(desc, dst, src, nbytes, &req);
26518482053SJussi Kivilinna 	serpent_fpu_end(crypt_ctx.fpu_enabled);
26618482053SJussi Kivilinna 
26718482053SJussi Kivilinna 	return ret;
26818482053SJussi Kivilinna }
26918482053SJussi Kivilinna 
27018482053SJussi Kivilinna static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
27118482053SJussi Kivilinna 		       struct scatterlist *src, unsigned int nbytes)
27218482053SJussi Kivilinna {
27318482053SJussi Kivilinna 	struct serpent_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
27418482053SJussi Kivilinna 	be128 buf[SERPENT_PARALLEL_BLOCKS];
27518482053SJussi Kivilinna 	struct crypt_priv crypt_ctx = {
27618482053SJussi Kivilinna 		.ctx = &ctx->serpent_ctx,
27718482053SJussi Kivilinna 		.fpu_enabled = false,
27818482053SJussi Kivilinna 	};
27918482053SJussi Kivilinna 	struct lrw_crypt_req req = {
28018482053SJussi Kivilinna 		.tbuf = buf,
28118482053SJussi Kivilinna 		.tbuflen = sizeof(buf),
28218482053SJussi Kivilinna 
28318482053SJussi Kivilinna 		.table_ctx = &ctx->lrw_table,
28418482053SJussi Kivilinna 		.crypt_ctx = &crypt_ctx,
28518482053SJussi Kivilinna 		.crypt_fn = decrypt_callback,
28618482053SJussi Kivilinna 	};
28718482053SJussi Kivilinna 	int ret;
28818482053SJussi Kivilinna 
289d3564338SJussi Kivilinna 	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
29018482053SJussi Kivilinna 	ret = lrw_crypt(desc, dst, src, nbytes, &req);
29118482053SJussi Kivilinna 	serpent_fpu_end(crypt_ctx.fpu_enabled);
29218482053SJussi Kivilinna 
29318482053SJussi Kivilinna 	return ret;
29418482053SJussi Kivilinna }
29518482053SJussi Kivilinna 
29618482053SJussi Kivilinna static void lrw_exit_tfm(struct crypto_tfm *tfm)
29718482053SJussi Kivilinna {
29818482053SJussi Kivilinna 	struct serpent_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
29918482053SJussi Kivilinna 
30018482053SJussi Kivilinna 	lrw_free_table(&ctx->lrw_table);
30118482053SJussi Kivilinna }
30218482053SJussi Kivilinna 
3035962f8b6SJussi Kivilinna struct serpent_xts_ctx {
3045962f8b6SJussi Kivilinna 	struct serpent_ctx tweak_ctx;
3055962f8b6SJussi Kivilinna 	struct serpent_ctx crypt_ctx;
3065962f8b6SJussi Kivilinna };
3075962f8b6SJussi Kivilinna 
3085962f8b6SJussi Kivilinna static int xts_serpent_setkey(struct crypto_tfm *tfm, const u8 *key,
3095962f8b6SJussi Kivilinna 			      unsigned int keylen)
3105962f8b6SJussi Kivilinna {
3115962f8b6SJussi Kivilinna 	struct serpent_xts_ctx *ctx = crypto_tfm_ctx(tfm);
3125962f8b6SJussi Kivilinna 	u32 *flags = &tfm->crt_flags;
3135962f8b6SJussi Kivilinna 	int err;
3145962f8b6SJussi Kivilinna 
3155962f8b6SJussi Kivilinna 	/* key consists of keys of equal size concatenated, therefore
3165962f8b6SJussi Kivilinna 	 * the length must be even
3175962f8b6SJussi Kivilinna 	 */
3185962f8b6SJussi Kivilinna 	if (keylen % 2) {
3195962f8b6SJussi Kivilinna 		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
3205962f8b6SJussi Kivilinna 		return -EINVAL;
3215962f8b6SJussi Kivilinna 	}
3225962f8b6SJussi Kivilinna 
3235962f8b6SJussi Kivilinna 	/* first half of xts-key is for crypt */
3245962f8b6SJussi Kivilinna 	err = __serpent_setkey(&ctx->crypt_ctx, key, keylen / 2);
3255962f8b6SJussi Kivilinna 	if (err)
3265962f8b6SJussi Kivilinna 		return err;
3275962f8b6SJussi Kivilinna 
3285962f8b6SJussi Kivilinna 	/* second half of xts-key is for tweak */
3295962f8b6SJussi Kivilinna 	return __serpent_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2);
3305962f8b6SJussi Kivilinna }
3315962f8b6SJussi Kivilinna 
3325962f8b6SJussi Kivilinna static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
3335962f8b6SJussi Kivilinna 		       struct scatterlist *src, unsigned int nbytes)
3345962f8b6SJussi Kivilinna {
3355962f8b6SJussi Kivilinna 	struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
3365962f8b6SJussi Kivilinna 	be128 buf[SERPENT_PARALLEL_BLOCKS];
3375962f8b6SJussi Kivilinna 	struct crypt_priv crypt_ctx = {
3385962f8b6SJussi Kivilinna 		.ctx = &ctx->crypt_ctx,
3395962f8b6SJussi Kivilinna 		.fpu_enabled = false,
3405962f8b6SJussi Kivilinna 	};
3415962f8b6SJussi Kivilinna 	struct xts_crypt_req req = {
3425962f8b6SJussi Kivilinna 		.tbuf = buf,
3435962f8b6SJussi Kivilinna 		.tbuflen = sizeof(buf),
3445962f8b6SJussi Kivilinna 
3455962f8b6SJussi Kivilinna 		.tweak_ctx = &ctx->tweak_ctx,
3465962f8b6SJussi Kivilinna 		.tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt),
3475962f8b6SJussi Kivilinna 		.crypt_ctx = &crypt_ctx,
3485962f8b6SJussi Kivilinna 		.crypt_fn = encrypt_callback,
3495962f8b6SJussi Kivilinna 	};
3505962f8b6SJussi Kivilinna 	int ret;
3515962f8b6SJussi Kivilinna 
352d3564338SJussi Kivilinna 	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
3535962f8b6SJussi Kivilinna 	ret = xts_crypt(desc, dst, src, nbytes, &req);
3545962f8b6SJussi Kivilinna 	serpent_fpu_end(crypt_ctx.fpu_enabled);
3555962f8b6SJussi Kivilinna 
3565962f8b6SJussi Kivilinna 	return ret;
3575962f8b6SJussi Kivilinna }
3585962f8b6SJussi Kivilinna 
3595962f8b6SJussi Kivilinna static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
3605962f8b6SJussi Kivilinna 		       struct scatterlist *src, unsigned int nbytes)
3615962f8b6SJussi Kivilinna {
3625962f8b6SJussi Kivilinna 	struct serpent_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
3635962f8b6SJussi Kivilinna 	be128 buf[SERPENT_PARALLEL_BLOCKS];
3645962f8b6SJussi Kivilinna 	struct crypt_priv crypt_ctx = {
3655962f8b6SJussi Kivilinna 		.ctx = &ctx->crypt_ctx,
3665962f8b6SJussi Kivilinna 		.fpu_enabled = false,
3675962f8b6SJussi Kivilinna 	};
3685962f8b6SJussi Kivilinna 	struct xts_crypt_req req = {
3695962f8b6SJussi Kivilinna 		.tbuf = buf,
3705962f8b6SJussi Kivilinna 		.tbuflen = sizeof(buf),
3715962f8b6SJussi Kivilinna 
3725962f8b6SJussi Kivilinna 		.tweak_ctx = &ctx->tweak_ctx,
3735962f8b6SJussi Kivilinna 		.tweak_fn = XTS_TWEAK_CAST(__serpent_encrypt),
3745962f8b6SJussi Kivilinna 		.crypt_ctx = &crypt_ctx,
3755962f8b6SJussi Kivilinna 		.crypt_fn = decrypt_callback,
3765962f8b6SJussi Kivilinna 	};
3775962f8b6SJussi Kivilinna 	int ret;
3785962f8b6SJussi Kivilinna 
379d3564338SJussi Kivilinna 	desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
3805962f8b6SJussi Kivilinna 	ret = xts_crypt(desc, dst, src, nbytes, &req);
3815962f8b6SJussi Kivilinna 	serpent_fpu_end(crypt_ctx.fpu_enabled);
3825962f8b6SJussi Kivilinna 
3835962f8b6SJussi Kivilinna 	return ret;
3845962f8b6SJussi Kivilinna }
3855962f8b6SJussi Kivilinna 
38635474c3bSJussi Kivilinna static struct crypto_alg serpent_algs[10] = { {
38735474c3bSJussi Kivilinna 	.cra_name		= "__ecb-serpent-sse2",
38835474c3bSJussi Kivilinna 	.cra_driver_name	= "__driver-ecb-serpent-sse2",
38935474c3bSJussi Kivilinna 	.cra_priority		= 0,
39035474c3bSJussi Kivilinna 	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
39135474c3bSJussi Kivilinna 	.cra_blocksize		= SERPENT_BLOCK_SIZE,
39235474c3bSJussi Kivilinna 	.cra_ctxsize		= sizeof(struct serpent_ctx),
39335474c3bSJussi Kivilinna 	.cra_alignmask		= 0,
39435474c3bSJussi Kivilinna 	.cra_type		= &crypto_blkcipher_type,
39535474c3bSJussi Kivilinna 	.cra_module		= THIS_MODULE,
39635474c3bSJussi Kivilinna 	.cra_u = {
39735474c3bSJussi Kivilinna 		.blkcipher = {
39835474c3bSJussi Kivilinna 			.min_keysize	= SERPENT_MIN_KEY_SIZE,
39935474c3bSJussi Kivilinna 			.max_keysize	= SERPENT_MAX_KEY_SIZE,
40035474c3bSJussi Kivilinna 			.setkey		= serpent_setkey,
40135474c3bSJussi Kivilinna 			.encrypt	= ecb_encrypt,
40235474c3bSJussi Kivilinna 			.decrypt	= ecb_decrypt,
40335474c3bSJussi Kivilinna 		},
40435474c3bSJussi Kivilinna 	},
40535474c3bSJussi Kivilinna }, {
40635474c3bSJussi Kivilinna 	.cra_name		= "__cbc-serpent-sse2",
40735474c3bSJussi Kivilinna 	.cra_driver_name	= "__driver-cbc-serpent-sse2",
40835474c3bSJussi Kivilinna 	.cra_priority		= 0,
40935474c3bSJussi Kivilinna 	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
41035474c3bSJussi Kivilinna 	.cra_blocksize		= SERPENT_BLOCK_SIZE,
41135474c3bSJussi Kivilinna 	.cra_ctxsize		= sizeof(struct serpent_ctx),
41235474c3bSJussi Kivilinna 	.cra_alignmask		= 0,
41335474c3bSJussi Kivilinna 	.cra_type		= &crypto_blkcipher_type,
41435474c3bSJussi Kivilinna 	.cra_module		= THIS_MODULE,
41535474c3bSJussi Kivilinna 	.cra_u = {
41635474c3bSJussi Kivilinna 		.blkcipher = {
41735474c3bSJussi Kivilinna 			.min_keysize	= SERPENT_MIN_KEY_SIZE,
41835474c3bSJussi Kivilinna 			.max_keysize	= SERPENT_MAX_KEY_SIZE,
41935474c3bSJussi Kivilinna 			.setkey		= serpent_setkey,
42035474c3bSJussi Kivilinna 			.encrypt	= cbc_encrypt,
42135474c3bSJussi Kivilinna 			.decrypt	= cbc_decrypt,
42235474c3bSJussi Kivilinna 		},
42335474c3bSJussi Kivilinna 	},
42435474c3bSJussi Kivilinna }, {
42535474c3bSJussi Kivilinna 	.cra_name		= "__ctr-serpent-sse2",
42635474c3bSJussi Kivilinna 	.cra_driver_name	= "__driver-ctr-serpent-sse2",
42735474c3bSJussi Kivilinna 	.cra_priority		= 0,
42835474c3bSJussi Kivilinna 	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
42935474c3bSJussi Kivilinna 	.cra_blocksize		= 1,
43035474c3bSJussi Kivilinna 	.cra_ctxsize		= sizeof(struct serpent_ctx),
43135474c3bSJussi Kivilinna 	.cra_alignmask		= 0,
43235474c3bSJussi Kivilinna 	.cra_type		= &crypto_blkcipher_type,
43335474c3bSJussi Kivilinna 	.cra_module		= THIS_MODULE,
43435474c3bSJussi Kivilinna 	.cra_u = {
43535474c3bSJussi Kivilinna 		.blkcipher = {
43635474c3bSJussi Kivilinna 			.min_keysize	= SERPENT_MIN_KEY_SIZE,
43735474c3bSJussi Kivilinna 			.max_keysize	= SERPENT_MAX_KEY_SIZE,
43835474c3bSJussi Kivilinna 			.ivsize		= SERPENT_BLOCK_SIZE,
43935474c3bSJussi Kivilinna 			.setkey		= serpent_setkey,
44035474c3bSJussi Kivilinna 			.encrypt	= ctr_crypt,
44135474c3bSJussi Kivilinna 			.decrypt	= ctr_crypt,
44235474c3bSJussi Kivilinna 		},
44335474c3bSJussi Kivilinna 	},
44435474c3bSJussi Kivilinna }, {
44535474c3bSJussi Kivilinna 	.cra_name		= "__lrw-serpent-sse2",
44635474c3bSJussi Kivilinna 	.cra_driver_name	= "__driver-lrw-serpent-sse2",
44735474c3bSJussi Kivilinna 	.cra_priority		= 0,
44835474c3bSJussi Kivilinna 	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
44935474c3bSJussi Kivilinna 	.cra_blocksize		= SERPENT_BLOCK_SIZE,
45035474c3bSJussi Kivilinna 	.cra_ctxsize		= sizeof(struct serpent_lrw_ctx),
45135474c3bSJussi Kivilinna 	.cra_alignmask		= 0,
45235474c3bSJussi Kivilinna 	.cra_type		= &crypto_blkcipher_type,
45335474c3bSJussi Kivilinna 	.cra_module		= THIS_MODULE,
45435474c3bSJussi Kivilinna 	.cra_exit		= lrw_exit_tfm,
45535474c3bSJussi Kivilinna 	.cra_u = {
45635474c3bSJussi Kivilinna 		.blkcipher = {
45735474c3bSJussi Kivilinna 			.min_keysize	= SERPENT_MIN_KEY_SIZE +
45835474c3bSJussi Kivilinna 					  SERPENT_BLOCK_SIZE,
45935474c3bSJussi Kivilinna 			.max_keysize	= SERPENT_MAX_KEY_SIZE +
46035474c3bSJussi Kivilinna 					  SERPENT_BLOCK_SIZE,
46135474c3bSJussi Kivilinna 			.ivsize		= SERPENT_BLOCK_SIZE,
46235474c3bSJussi Kivilinna 			.setkey		= lrw_serpent_setkey,
46335474c3bSJussi Kivilinna 			.encrypt	= lrw_encrypt,
46435474c3bSJussi Kivilinna 			.decrypt	= lrw_decrypt,
46535474c3bSJussi Kivilinna 		},
46635474c3bSJussi Kivilinna 	},
46735474c3bSJussi Kivilinna }, {
46835474c3bSJussi Kivilinna 	.cra_name		= "__xts-serpent-sse2",
46935474c3bSJussi Kivilinna 	.cra_driver_name	= "__driver-xts-serpent-sse2",
47035474c3bSJussi Kivilinna 	.cra_priority		= 0,
47135474c3bSJussi Kivilinna 	.cra_flags		= CRYPTO_ALG_TYPE_BLKCIPHER,
47235474c3bSJussi Kivilinna 	.cra_blocksize		= SERPENT_BLOCK_SIZE,
47335474c3bSJussi Kivilinna 	.cra_ctxsize		= sizeof(struct serpent_xts_ctx),
47435474c3bSJussi Kivilinna 	.cra_alignmask		= 0,
47535474c3bSJussi Kivilinna 	.cra_type		= &crypto_blkcipher_type,
47635474c3bSJussi Kivilinna 	.cra_module		= THIS_MODULE,
47735474c3bSJussi Kivilinna 	.cra_u = {
47835474c3bSJussi Kivilinna 		.blkcipher = {
47935474c3bSJussi Kivilinna 			.min_keysize	= SERPENT_MIN_KEY_SIZE * 2,
48035474c3bSJussi Kivilinna 			.max_keysize	= SERPENT_MAX_KEY_SIZE * 2,
48135474c3bSJussi Kivilinna 			.ivsize		= SERPENT_BLOCK_SIZE,
48235474c3bSJussi Kivilinna 			.setkey		= xts_serpent_setkey,
48335474c3bSJussi Kivilinna 			.encrypt	= xts_encrypt,
48435474c3bSJussi Kivilinna 			.decrypt	= xts_decrypt,
48535474c3bSJussi Kivilinna 		},
48635474c3bSJussi Kivilinna 	},
48735474c3bSJussi Kivilinna }, {
48835474c3bSJussi Kivilinna 	.cra_name		= "ecb(serpent)",
48935474c3bSJussi Kivilinna 	.cra_driver_name	= "ecb-serpent-sse2",
49035474c3bSJussi Kivilinna 	.cra_priority		= 400,
49135474c3bSJussi Kivilinna 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
49235474c3bSJussi Kivilinna 	.cra_blocksize		= SERPENT_BLOCK_SIZE,
493ffaf9156SJussi Kivilinna 	.cra_ctxsize		= sizeof(struct async_helper_ctx),
49435474c3bSJussi Kivilinna 	.cra_alignmask		= 0,
49535474c3bSJussi Kivilinna 	.cra_type		= &crypto_ablkcipher_type,
49635474c3bSJussi Kivilinna 	.cra_module		= THIS_MODULE,
497435d3e51SJussi Kivilinna 	.cra_init		= ablk_init,
49835474c3bSJussi Kivilinna 	.cra_exit		= ablk_exit,
49935474c3bSJussi Kivilinna 	.cra_u = {
50035474c3bSJussi Kivilinna 		.ablkcipher = {
50135474c3bSJussi Kivilinna 			.min_keysize	= SERPENT_MIN_KEY_SIZE,
50235474c3bSJussi Kivilinna 			.max_keysize	= SERPENT_MAX_KEY_SIZE,
50335474c3bSJussi Kivilinna 			.setkey		= ablk_set_key,
50435474c3bSJussi Kivilinna 			.encrypt	= ablk_encrypt,
50535474c3bSJussi Kivilinna 			.decrypt	= ablk_decrypt,
50635474c3bSJussi Kivilinna 		},
50735474c3bSJussi Kivilinna 	},
50835474c3bSJussi Kivilinna }, {
50935474c3bSJussi Kivilinna 	.cra_name		= "cbc(serpent)",
51035474c3bSJussi Kivilinna 	.cra_driver_name	= "cbc-serpent-sse2",
51135474c3bSJussi Kivilinna 	.cra_priority		= 400,
51235474c3bSJussi Kivilinna 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
51335474c3bSJussi Kivilinna 	.cra_blocksize		= SERPENT_BLOCK_SIZE,
514ffaf9156SJussi Kivilinna 	.cra_ctxsize		= sizeof(struct async_helper_ctx),
51535474c3bSJussi Kivilinna 	.cra_alignmask		= 0,
51635474c3bSJussi Kivilinna 	.cra_type		= &crypto_ablkcipher_type,
51735474c3bSJussi Kivilinna 	.cra_module		= THIS_MODULE,
518435d3e51SJussi Kivilinna 	.cra_init		= ablk_init,
51935474c3bSJussi Kivilinna 	.cra_exit		= ablk_exit,
52035474c3bSJussi Kivilinna 	.cra_u = {
52135474c3bSJussi Kivilinna 		.ablkcipher = {
52235474c3bSJussi Kivilinna 			.min_keysize	= SERPENT_MIN_KEY_SIZE,
52335474c3bSJussi Kivilinna 			.max_keysize	= SERPENT_MAX_KEY_SIZE,
52435474c3bSJussi Kivilinna 			.ivsize		= SERPENT_BLOCK_SIZE,
52535474c3bSJussi Kivilinna 			.setkey		= ablk_set_key,
52635474c3bSJussi Kivilinna 			.encrypt	= __ablk_encrypt,
52735474c3bSJussi Kivilinna 			.decrypt	= ablk_decrypt,
52835474c3bSJussi Kivilinna 		},
52935474c3bSJussi Kivilinna 	},
53035474c3bSJussi Kivilinna }, {
531937c30d7SJussi Kivilinna 	.cra_name		= "ctr(serpent)",
532937c30d7SJussi Kivilinna 	.cra_driver_name	= "ctr-serpent-sse2",
533937c30d7SJussi Kivilinna 	.cra_priority		= 400,
534937c30d7SJussi Kivilinna 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
535937c30d7SJussi Kivilinna 	.cra_blocksize		= 1,
536ffaf9156SJussi Kivilinna 	.cra_ctxsize		= sizeof(struct async_helper_ctx),
537937c30d7SJussi Kivilinna 	.cra_alignmask		= 0,
538937c30d7SJussi Kivilinna 	.cra_type		= &crypto_ablkcipher_type,
539937c30d7SJussi Kivilinna 	.cra_module		= THIS_MODULE,
540435d3e51SJussi Kivilinna 	.cra_init		= ablk_init,
541937c30d7SJussi Kivilinna 	.cra_exit		= ablk_exit,
542937c30d7SJussi Kivilinna 	.cra_u = {
543937c30d7SJussi Kivilinna 		.ablkcipher = {
544937c30d7SJussi Kivilinna 			.min_keysize	= SERPENT_MIN_KEY_SIZE,
545937c30d7SJussi Kivilinna 			.max_keysize	= SERPENT_MAX_KEY_SIZE,
546937c30d7SJussi Kivilinna 			.ivsize		= SERPENT_BLOCK_SIZE,
547937c30d7SJussi Kivilinna 			.setkey		= ablk_set_key,
548937c30d7SJussi Kivilinna 			.encrypt	= ablk_encrypt,
549937c30d7SJussi Kivilinna 			.decrypt	= ablk_encrypt,
550937c30d7SJussi Kivilinna 			.geniv		= "chainiv",
551937c30d7SJussi Kivilinna 		},
552937c30d7SJussi Kivilinna 	},
55335474c3bSJussi Kivilinna }, {
55418482053SJussi Kivilinna 	.cra_name		= "lrw(serpent)",
55518482053SJussi Kivilinna 	.cra_driver_name	= "lrw-serpent-sse2",
55618482053SJussi Kivilinna 	.cra_priority		= 400,
55718482053SJussi Kivilinna 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
55818482053SJussi Kivilinna 	.cra_blocksize		= SERPENT_BLOCK_SIZE,
559ffaf9156SJussi Kivilinna 	.cra_ctxsize		= sizeof(struct async_helper_ctx),
56018482053SJussi Kivilinna 	.cra_alignmask		= 0,
56118482053SJussi Kivilinna 	.cra_type		= &crypto_ablkcipher_type,
56218482053SJussi Kivilinna 	.cra_module		= THIS_MODULE,
563435d3e51SJussi Kivilinna 	.cra_init		= ablk_init,
56418482053SJussi Kivilinna 	.cra_exit		= ablk_exit,
56518482053SJussi Kivilinna 	.cra_u = {
56618482053SJussi Kivilinna 		.ablkcipher = {
56718482053SJussi Kivilinna 			.min_keysize	= SERPENT_MIN_KEY_SIZE +
56818482053SJussi Kivilinna 					  SERPENT_BLOCK_SIZE,
56918482053SJussi Kivilinna 			.max_keysize	= SERPENT_MAX_KEY_SIZE +
57018482053SJussi Kivilinna 					  SERPENT_BLOCK_SIZE,
57118482053SJussi Kivilinna 			.ivsize		= SERPENT_BLOCK_SIZE,
57218482053SJussi Kivilinna 			.setkey		= ablk_set_key,
57318482053SJussi Kivilinna 			.encrypt	= ablk_encrypt,
57418482053SJussi Kivilinna 			.decrypt	= ablk_decrypt,
57518482053SJussi Kivilinna 		},
57618482053SJussi Kivilinna 	},
57735474c3bSJussi Kivilinna }, {
5785962f8b6SJussi Kivilinna 	.cra_name		= "xts(serpent)",
5795962f8b6SJussi Kivilinna 	.cra_driver_name	= "xts-serpent-sse2",
5805962f8b6SJussi Kivilinna 	.cra_priority		= 400,
5815962f8b6SJussi Kivilinna 	.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
5825962f8b6SJussi Kivilinna 	.cra_blocksize		= SERPENT_BLOCK_SIZE,
583ffaf9156SJussi Kivilinna 	.cra_ctxsize		= sizeof(struct async_helper_ctx),
5845962f8b6SJussi Kivilinna 	.cra_alignmask		= 0,
5855962f8b6SJussi Kivilinna 	.cra_type		= &crypto_ablkcipher_type,
5865962f8b6SJussi Kivilinna 	.cra_module		= THIS_MODULE,
587435d3e51SJussi Kivilinna 	.cra_init		= ablk_init,
5885962f8b6SJussi Kivilinna 	.cra_exit		= ablk_exit,
5895962f8b6SJussi Kivilinna 	.cra_u = {
5905962f8b6SJussi Kivilinna 		.ablkcipher = {
5915962f8b6SJussi Kivilinna 			.min_keysize	= SERPENT_MIN_KEY_SIZE * 2,
5925962f8b6SJussi Kivilinna 			.max_keysize	= SERPENT_MAX_KEY_SIZE * 2,
5935962f8b6SJussi Kivilinna 			.ivsize		= SERPENT_BLOCK_SIZE,
5945962f8b6SJussi Kivilinna 			.setkey		= ablk_set_key,
5955962f8b6SJussi Kivilinna 			.encrypt	= ablk_encrypt,
5965962f8b6SJussi Kivilinna 			.decrypt	= ablk_decrypt,
5975962f8b6SJussi Kivilinna 		},
5985962f8b6SJussi Kivilinna 	},
59935474c3bSJussi Kivilinna } };
6005962f8b6SJussi Kivilinna 
601937c30d7SJussi Kivilinna static int __init serpent_sse2_init(void)
602937c30d7SJussi Kivilinna {
603937c30d7SJussi Kivilinna 	if (!cpu_has_xmm2) {
604937c30d7SJussi Kivilinna 		printk(KERN_INFO "SSE2 instructions are not detected.\n");
605937c30d7SJussi Kivilinna 		return -ENODEV;
606937c30d7SJussi Kivilinna 	}
607937c30d7SJussi Kivilinna 
60835474c3bSJussi Kivilinna 	return crypto_register_algs(serpent_algs, ARRAY_SIZE(serpent_algs));
609937c30d7SJussi Kivilinna }
610937c30d7SJussi Kivilinna 
611937c30d7SJussi Kivilinna static void __exit serpent_sse2_exit(void)
612937c30d7SJussi Kivilinna {
61335474c3bSJussi Kivilinna 	crypto_unregister_algs(serpent_algs, ARRAY_SIZE(serpent_algs));
614937c30d7SJussi Kivilinna }
615937c30d7SJussi Kivilinna 
616937c30d7SJussi Kivilinna module_init(serpent_sse2_init);
617937c30d7SJussi Kivilinna module_exit(serpent_sse2_exit);
618937c30d7SJussi Kivilinna 
619937c30d7SJussi Kivilinna MODULE_DESCRIPTION("Serpent Cipher Algorithm, SSE2 optimized");
620937c30d7SJussi Kivilinna MODULE_LICENSE("GPL");
6215d26a105SKees Cook MODULE_ALIAS_CRYPTO("serpent");
622