xref: /openbmc/linux/arch/x86/crypto/serpent_avx_glue.c (revision d0034a7a4ac7fae708146ac0059b9c47a1543f0d)
11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
27efe4076SJohannes Goetzfried /*
37efe4076SJohannes Goetzfried  * Glue Code for AVX assembler versions of Serpent Cipher
47efe4076SJohannes Goetzfried  *
57efe4076SJohannes Goetzfried  * Copyright (C) 2012 Johannes Goetzfried
67efe4076SJohannes Goetzfried  *     <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
77efe4076SJohannes Goetzfried  *
8a05248edSJussi Kivilinna  * Copyright © 2011-2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
97efe4076SJohannes Goetzfried  */
107efe4076SJohannes Goetzfried 
117efe4076SJohannes Goetzfried #include <linux/module.h>
127efe4076SJohannes Goetzfried #include <linux/types.h>
137efe4076SJohannes Goetzfried #include <linux/crypto.h>
147efe4076SJohannes Goetzfried #include <linux/err.h>
157efe4076SJohannes Goetzfried #include <crypto/algapi.h>
16e16bf974SEric Biggers #include <crypto/internal/simd.h>
177efe4076SJohannes Goetzfried #include <crypto/serpent.h>
187efe4076SJohannes Goetzfried 
19*a04ea6f7SArd Biesheuvel #include "serpent-avx.h"
209ad58b46SArd Biesheuvel #include "ecb_cbc_helpers.h"
219ad58b46SArd Biesheuvel 
2256d76c96SJussi Kivilinna /* 8-way parallel cipher functions */
239c1e8836SKees Cook asmlinkage void serpent_ecb_enc_8way_avx(const void *ctx, u8 *dst,
2456d76c96SJussi Kivilinna 					 const u8 *src);
2556d76c96SJussi Kivilinna EXPORT_SYMBOL_GPL(serpent_ecb_enc_8way_avx);
2656d76c96SJussi Kivilinna 
279c1e8836SKees Cook asmlinkage void serpent_ecb_dec_8way_avx(const void *ctx, u8 *dst,
2856d76c96SJussi Kivilinna 					 const u8 *src);
2956d76c96SJussi Kivilinna EXPORT_SYMBOL_GPL(serpent_ecb_dec_8way_avx);
3056d76c96SJussi Kivilinna 
319c1e8836SKees Cook asmlinkage void serpent_cbc_dec_8way_avx(const void *ctx, u8 *dst,
3256d76c96SJussi Kivilinna 					 const u8 *src);
3356d76c96SJussi Kivilinna EXPORT_SYMBOL_GPL(serpent_cbc_dec_8way_avx);
3456d76c96SJussi Kivilinna 
serpent_setkey_skcipher(struct crypto_skcipher * tfm,const u8 * key,unsigned int keylen)35e16bf974SEric Biggers static int serpent_setkey_skcipher(struct crypto_skcipher *tfm,
36e16bf974SEric Biggers 				   const u8 *key, unsigned int keylen)
37e16bf974SEric Biggers {
38e16bf974SEric Biggers 	return __serpent_setkey(crypto_skcipher_ctx(tfm), key, keylen);
39e16bf974SEric Biggers }
40e16bf974SEric Biggers 
ecb_encrypt(struct skcipher_request * req)41e16bf974SEric Biggers static int ecb_encrypt(struct skcipher_request *req)
427efe4076SJohannes Goetzfried {
439ad58b46SArd Biesheuvel 	ECB_WALK_START(req, SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS);
449ad58b46SArd Biesheuvel 	ECB_BLOCK(SERPENT_PARALLEL_BLOCKS, serpent_ecb_enc_8way_avx);
459ad58b46SArd Biesheuvel 	ECB_BLOCK(1, __serpent_encrypt);
469ad58b46SArd Biesheuvel 	ECB_WALK_END();
477efe4076SJohannes Goetzfried }
487efe4076SJohannes Goetzfried 
ecb_decrypt(struct skcipher_request * req)49e16bf974SEric Biggers static int ecb_decrypt(struct skcipher_request *req)
507efe4076SJohannes Goetzfried {
519ad58b46SArd Biesheuvel 	ECB_WALK_START(req, SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS);
529ad58b46SArd Biesheuvel 	ECB_BLOCK(SERPENT_PARALLEL_BLOCKS, serpent_ecb_dec_8way_avx);
539ad58b46SArd Biesheuvel 	ECB_BLOCK(1, __serpent_decrypt);
549ad58b46SArd Biesheuvel 	ECB_WALK_END();
557efe4076SJohannes Goetzfried }
567efe4076SJohannes Goetzfried 
cbc_encrypt(struct skcipher_request * req)57e16bf974SEric Biggers static int cbc_encrypt(struct skcipher_request *req)
587efe4076SJohannes Goetzfried {
599ad58b46SArd Biesheuvel 	CBC_WALK_START(req, SERPENT_BLOCK_SIZE, -1);
609ad58b46SArd Biesheuvel 	CBC_ENC_BLOCK(__serpent_encrypt);
619ad58b46SArd Biesheuvel 	CBC_WALK_END();
627efe4076SJohannes Goetzfried }
637efe4076SJohannes Goetzfried 
cbc_decrypt(struct skcipher_request * req)64e16bf974SEric Biggers static int cbc_decrypt(struct skcipher_request *req)
657efe4076SJohannes Goetzfried {
669ad58b46SArd Biesheuvel 	CBC_WALK_START(req, SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS);
679ad58b46SArd Biesheuvel 	CBC_DEC_BLOCK(SERPENT_PARALLEL_BLOCKS, serpent_cbc_dec_8way_avx);
689ad58b46SArd Biesheuvel 	CBC_DEC_BLOCK(1, __serpent_decrypt);
699ad58b46SArd Biesheuvel 	CBC_WALK_END();
707efe4076SJohannes Goetzfried }
717efe4076SJohannes Goetzfried 
72e16bf974SEric Biggers static struct skcipher_alg serpent_algs[] = {
73e16bf974SEric Biggers 	{
74e16bf974SEric Biggers 		.base.cra_name		= "__ecb(serpent)",
75e16bf974SEric Biggers 		.base.cra_driver_name	= "__ecb-serpent-avx",
76e16bf974SEric Biggers 		.base.cra_priority	= 500,
77e16bf974SEric Biggers 		.base.cra_flags		= CRYPTO_ALG_INTERNAL,
78e16bf974SEric Biggers 		.base.cra_blocksize	= SERPENT_BLOCK_SIZE,
79e16bf974SEric Biggers 		.base.cra_ctxsize	= sizeof(struct serpent_ctx),
80e16bf974SEric Biggers 		.base.cra_module	= THIS_MODULE,
817efe4076SJohannes Goetzfried 		.min_keysize		= SERPENT_MIN_KEY_SIZE,
827efe4076SJohannes Goetzfried 		.max_keysize		= SERPENT_MAX_KEY_SIZE,
83e16bf974SEric Biggers 		.setkey			= serpent_setkey_skcipher,
847efe4076SJohannes Goetzfried 		.encrypt		= ecb_encrypt,
857efe4076SJohannes Goetzfried 		.decrypt		= ecb_decrypt,
867efe4076SJohannes Goetzfried 	}, {
87e16bf974SEric Biggers 		.base.cra_name		= "__cbc(serpent)",
88e16bf974SEric Biggers 		.base.cra_driver_name	= "__cbc-serpent-avx",
89e16bf974SEric Biggers 		.base.cra_priority	= 500,
90e16bf974SEric Biggers 		.base.cra_flags		= CRYPTO_ALG_INTERNAL,
91e16bf974SEric Biggers 		.base.cra_blocksize	= SERPENT_BLOCK_SIZE,
92e16bf974SEric Biggers 		.base.cra_ctxsize	= sizeof(struct serpent_ctx),
93e16bf974SEric Biggers 		.base.cra_module	= THIS_MODULE,
947efe4076SJohannes Goetzfried 		.min_keysize		= SERPENT_MIN_KEY_SIZE,
957efe4076SJohannes Goetzfried 		.max_keysize		= SERPENT_MAX_KEY_SIZE,
967efe4076SJohannes Goetzfried 		.ivsize			= SERPENT_BLOCK_SIZE,
97e16bf974SEric Biggers 		.setkey			= serpent_setkey_skcipher,
98e16bf974SEric Biggers 		.encrypt		= cbc_encrypt,
99e16bf974SEric Biggers 		.decrypt		= cbc_decrypt,
1007efe4076SJohannes Goetzfried 	},
101e16bf974SEric Biggers };
102e16bf974SEric Biggers 
103e16bf974SEric Biggers static struct simd_skcipher_alg *serpent_simd_algs[ARRAY_SIZE(serpent_algs)];
1047efe4076SJohannes Goetzfried 
serpent_init(void)1057efe4076SJohannes Goetzfried static int __init serpent_init(void)
1067efe4076SJohannes Goetzfried {
107c1c23f7eSIngo Molnar 	const char *feature_name;
1087efe4076SJohannes Goetzfried 
109d91cab78SDave Hansen 	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
110d91cab78SDave Hansen 				&feature_name)) {
111c1c23f7eSIngo Molnar 		pr_info("CPU feature '%s' is not supported.\n", feature_name);
1127efe4076SJohannes Goetzfried 		return -ENODEV;
1137efe4076SJohannes Goetzfried 	}
1147efe4076SJohannes Goetzfried 
115e16bf974SEric Biggers 	return simd_register_skciphers_compat(serpent_algs,
116e16bf974SEric Biggers 					      ARRAY_SIZE(serpent_algs),
117e16bf974SEric Biggers 					      serpent_simd_algs);
1187efe4076SJohannes Goetzfried }
1197efe4076SJohannes Goetzfried 
serpent_exit(void)1207efe4076SJohannes Goetzfried static void __exit serpent_exit(void)
1217efe4076SJohannes Goetzfried {
122e16bf974SEric Biggers 	simd_unregister_skciphers(serpent_algs, ARRAY_SIZE(serpent_algs),
123e16bf974SEric Biggers 				  serpent_simd_algs);
1247efe4076SJohannes Goetzfried }
1257efe4076SJohannes Goetzfried 
1267efe4076SJohannes Goetzfried module_init(serpent_init);
1277efe4076SJohannes Goetzfried module_exit(serpent_exit);
1287efe4076SJohannes Goetzfried 
1297efe4076SJohannes Goetzfried MODULE_DESCRIPTION("Serpent Cipher Algorithm, AVX optimized");
1307efe4076SJohannes Goetzfried MODULE_LICENSE("GPL");
1315d26a105SKees Cook MODULE_ALIAS_CRYPTO("serpent");
132