1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Glue Code for AVX assembler versions of Serpent Cipher
5 * Copyright (C) 2012 Johannes Goetzfried
6 * <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
8 * Copyright © 2011-2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
11 #include <linux/module.h>
12 #include <linux/types.h>
13 #include <linux/crypto.h>
14 #include <linux/err.h>
15 #include <crypto/algapi.h>
16 #include <crypto/internal/simd.h>
17 #include <crypto/serpent.h>
19 #include "serpent-avx.h"
20 #include "ecb_cbc_helpers.h"
22 /* 8-way parallel cipher functions */
23 asmlinkage
void serpent_ecb_enc_8way_avx(const void *ctx
, u8
*dst
,
25 EXPORT_SYMBOL_GPL(serpent_ecb_enc_8way_avx
);
27 asmlinkage
void serpent_ecb_dec_8way_avx(const void *ctx
, u8
*dst
,
29 EXPORT_SYMBOL_GPL(serpent_ecb_dec_8way_avx
);
31 asmlinkage
void serpent_cbc_dec_8way_avx(const void *ctx
, u8
*dst
,
33 EXPORT_SYMBOL_GPL(serpent_cbc_dec_8way_avx
);
35 static int serpent_setkey_skcipher(struct crypto_skcipher
*tfm
,
36 const u8
*key
, unsigned int keylen
)
38 return __serpent_setkey(crypto_skcipher_ctx(tfm
), key
, keylen
);
41 static int ecb_encrypt(struct skcipher_request
*req
)
43 ECB_WALK_START(req
, SERPENT_BLOCK_SIZE
, SERPENT_PARALLEL_BLOCKS
);
44 ECB_BLOCK(SERPENT_PARALLEL_BLOCKS
, serpent_ecb_enc_8way_avx
);
45 ECB_BLOCK(1, __serpent_encrypt
);
49 static int ecb_decrypt(struct skcipher_request
*req
)
51 ECB_WALK_START(req
, SERPENT_BLOCK_SIZE
, SERPENT_PARALLEL_BLOCKS
);
52 ECB_BLOCK(SERPENT_PARALLEL_BLOCKS
, serpent_ecb_dec_8way_avx
);
53 ECB_BLOCK(1, __serpent_decrypt
);
57 static int cbc_encrypt(struct skcipher_request
*req
)
59 CBC_WALK_START(req
, SERPENT_BLOCK_SIZE
, -1);
60 CBC_ENC_BLOCK(__serpent_encrypt
);
64 static int cbc_decrypt(struct skcipher_request
*req
)
66 CBC_WALK_START(req
, SERPENT_BLOCK_SIZE
, SERPENT_PARALLEL_BLOCKS
);
67 CBC_DEC_BLOCK(SERPENT_PARALLEL_BLOCKS
, serpent_cbc_dec_8way_avx
);
68 CBC_DEC_BLOCK(1, __serpent_decrypt
);
72 static struct skcipher_alg serpent_algs
[] = {
74 .base
.cra_name
= "__ecb(serpent)",
75 .base
.cra_driver_name
= "__ecb-serpent-avx",
76 .base
.cra_priority
= 500,
77 .base
.cra_flags
= CRYPTO_ALG_INTERNAL
,
78 .base
.cra_blocksize
= SERPENT_BLOCK_SIZE
,
79 .base
.cra_ctxsize
= sizeof(struct serpent_ctx
),
80 .base
.cra_module
= THIS_MODULE
,
81 .min_keysize
= SERPENT_MIN_KEY_SIZE
,
82 .max_keysize
= SERPENT_MAX_KEY_SIZE
,
83 .setkey
= serpent_setkey_skcipher
,
84 .encrypt
= ecb_encrypt
,
85 .decrypt
= ecb_decrypt
,
87 .base
.cra_name
= "__cbc(serpent)",
88 .base
.cra_driver_name
= "__cbc-serpent-avx",
89 .base
.cra_priority
= 500,
90 .base
.cra_flags
= CRYPTO_ALG_INTERNAL
,
91 .base
.cra_blocksize
= SERPENT_BLOCK_SIZE
,
92 .base
.cra_ctxsize
= sizeof(struct serpent_ctx
),
93 .base
.cra_module
= THIS_MODULE
,
94 .min_keysize
= SERPENT_MIN_KEY_SIZE
,
95 .max_keysize
= SERPENT_MAX_KEY_SIZE
,
96 .ivsize
= SERPENT_BLOCK_SIZE
,
97 .setkey
= serpent_setkey_skcipher
,
98 .encrypt
= cbc_encrypt
,
99 .decrypt
= cbc_decrypt
,
103 static struct simd_skcipher_alg
*serpent_simd_algs
[ARRAY_SIZE(serpent_algs
)];
105 static int __init
serpent_init(void)
107 const char *feature_name
;
109 if (!cpu_has_xfeatures(XFEATURE_MASK_SSE
| XFEATURE_MASK_YMM
,
111 pr_info("CPU feature '%s' is not supported.\n", feature_name
);
115 return simd_register_skciphers_compat(serpent_algs
,
116 ARRAY_SIZE(serpent_algs
),
120 static void __exit
serpent_exit(void)
122 simd_unregister_skciphers(serpent_algs
, ARRAY_SIZE(serpent_algs
),
126 module_init(serpent_init
);
127 module_exit(serpent_exit
);
129 MODULE_DESCRIPTION("Serpent Cipher Algorithm, AVX optimized");
130 MODULE_LICENSE("GPL");
131 MODULE_ALIAS_CRYPTO("serpent");