Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Glue Code for AVX assembler versions of Serpent Cipher
0004  *
0005  * Copyright (C) 2012 Johannes Goetzfried
0006  *     <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
0007  *
0008  * Copyright © 2011-2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
0009  */
0010 
0011 #include <linux/module.h>
0012 #include <linux/types.h>
0013 #include <linux/crypto.h>
0014 #include <linux/err.h>
0015 #include <crypto/algapi.h>
0016 #include <crypto/internal/simd.h>
0017 #include <crypto/serpent.h>
0018 
0019 #include "serpent-avx.h"
0020 #include "ecb_cbc_helpers.h"
0021 
0022 /* 8-way parallel cipher functions */
0023 asmlinkage void serpent_ecb_enc_8way_avx(const void *ctx, u8 *dst,
0024                      const u8 *src);
0025 EXPORT_SYMBOL_GPL(serpent_ecb_enc_8way_avx);
0026 
0027 asmlinkage void serpent_ecb_dec_8way_avx(const void *ctx, u8 *dst,
0028                      const u8 *src);
0029 EXPORT_SYMBOL_GPL(serpent_ecb_dec_8way_avx);
0030 
0031 asmlinkage void serpent_cbc_dec_8way_avx(const void *ctx, u8 *dst,
0032                      const u8 *src);
0033 EXPORT_SYMBOL_GPL(serpent_cbc_dec_8way_avx);
0034 
0035 static int serpent_setkey_skcipher(struct crypto_skcipher *tfm,
0036                    const u8 *key, unsigned int keylen)
0037 {
0038     return __serpent_setkey(crypto_skcipher_ctx(tfm), key, keylen);
0039 }
0040 
0041 static int ecb_encrypt(struct skcipher_request *req)
0042 {
0043     ECB_WALK_START(req, SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS);
0044     ECB_BLOCK(SERPENT_PARALLEL_BLOCKS, serpent_ecb_enc_8way_avx);
0045     ECB_BLOCK(1, __serpent_encrypt);
0046     ECB_WALK_END();
0047 }
0048 
0049 static int ecb_decrypt(struct skcipher_request *req)
0050 {
0051     ECB_WALK_START(req, SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS);
0052     ECB_BLOCK(SERPENT_PARALLEL_BLOCKS, serpent_ecb_dec_8way_avx);
0053     ECB_BLOCK(1, __serpent_decrypt);
0054     ECB_WALK_END();
0055 }
0056 
0057 static int cbc_encrypt(struct skcipher_request *req)
0058 {
0059     CBC_WALK_START(req, SERPENT_BLOCK_SIZE, -1);
0060     CBC_ENC_BLOCK(__serpent_encrypt);
0061     CBC_WALK_END();
0062 }
0063 
0064 static int cbc_decrypt(struct skcipher_request *req)
0065 {
0066     CBC_WALK_START(req, SERPENT_BLOCK_SIZE, SERPENT_PARALLEL_BLOCKS);
0067     CBC_DEC_BLOCK(SERPENT_PARALLEL_BLOCKS, serpent_cbc_dec_8way_avx);
0068     CBC_DEC_BLOCK(1, __serpent_decrypt);
0069     CBC_WALK_END();
0070 }
0071 
0072 static struct skcipher_alg serpent_algs[] = {
0073     {
0074         .base.cra_name      = "__ecb(serpent)",
0075         .base.cra_driver_name   = "__ecb-serpent-avx",
0076         .base.cra_priority  = 500,
0077         .base.cra_flags     = CRYPTO_ALG_INTERNAL,
0078         .base.cra_blocksize = SERPENT_BLOCK_SIZE,
0079         .base.cra_ctxsize   = sizeof(struct serpent_ctx),
0080         .base.cra_module    = THIS_MODULE,
0081         .min_keysize        = SERPENT_MIN_KEY_SIZE,
0082         .max_keysize        = SERPENT_MAX_KEY_SIZE,
0083         .setkey         = serpent_setkey_skcipher,
0084         .encrypt        = ecb_encrypt,
0085         .decrypt        = ecb_decrypt,
0086     }, {
0087         .base.cra_name      = "__cbc(serpent)",
0088         .base.cra_driver_name   = "__cbc-serpent-avx",
0089         .base.cra_priority  = 500,
0090         .base.cra_flags     = CRYPTO_ALG_INTERNAL,
0091         .base.cra_blocksize = SERPENT_BLOCK_SIZE,
0092         .base.cra_ctxsize   = sizeof(struct serpent_ctx),
0093         .base.cra_module    = THIS_MODULE,
0094         .min_keysize        = SERPENT_MIN_KEY_SIZE,
0095         .max_keysize        = SERPENT_MAX_KEY_SIZE,
0096         .ivsize         = SERPENT_BLOCK_SIZE,
0097         .setkey         = serpent_setkey_skcipher,
0098         .encrypt        = cbc_encrypt,
0099         .decrypt        = cbc_decrypt,
0100     },
0101 };
0102 
0103 static struct simd_skcipher_alg *serpent_simd_algs[ARRAY_SIZE(serpent_algs)];
0104 
0105 static int __init serpent_init(void)
0106 {
0107     const char *feature_name;
0108 
0109     if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
0110                 &feature_name)) {
0111         pr_info("CPU feature '%s' is not supported.\n", feature_name);
0112         return -ENODEV;
0113     }
0114 
0115     return simd_register_skciphers_compat(serpent_algs,
0116                           ARRAY_SIZE(serpent_algs),
0117                           serpent_simd_algs);
0118 }
0119 
0120 static void __exit serpent_exit(void)
0121 {
0122     simd_unregister_skciphers(serpent_algs, ARRAY_SIZE(serpent_algs),
0123                   serpent_simd_algs);
0124 }
0125 
0126 module_init(serpent_init);
0127 module_exit(serpent_exit);
0128 
0129 MODULE_DESCRIPTION("Serpent Cipher Algorithm, AVX optimized");
0130 MODULE_LICENSE("GPL");
0131 MODULE_ALIAS_CRYPTO("serpent");