Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Glue Code for AVX assembler version of Twofish Cipher
0004  *
0005  * Copyright (C) 2012 Johannes Goetzfried
0006  *     <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
0007  *
0008  * Copyright © 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/twofish.h>
0018 
0019 #include "twofish.h"
0020 #include "ecb_cbc_helpers.h"
0021 
0022 #define TWOFISH_PARALLEL_BLOCKS 8
0023 
0024 /* 8-way parallel cipher functions */
0025 asmlinkage void twofish_ecb_enc_8way(const void *ctx, u8 *dst, const u8 *src);
0026 asmlinkage void twofish_ecb_dec_8way(const void *ctx, u8 *dst, const u8 *src);
0027 
0028 asmlinkage void twofish_cbc_dec_8way(const void *ctx, u8 *dst, const u8 *src);
0029 
0030 static int twofish_setkey_skcipher(struct crypto_skcipher *tfm,
0031                    const u8 *key, unsigned int keylen)
0032 {
0033     return twofish_setkey(&tfm->base, key, keylen);
0034 }
0035 
0036 static inline void twofish_enc_blk_3way(const void *ctx, u8 *dst, const u8 *src)
0037 {
0038     __twofish_enc_blk_3way(ctx, dst, src, false);
0039 }
0040 
0041 static int ecb_encrypt(struct skcipher_request *req)
0042 {
0043     ECB_WALK_START(req, TF_BLOCK_SIZE, TWOFISH_PARALLEL_BLOCKS);
0044     ECB_BLOCK(TWOFISH_PARALLEL_BLOCKS, twofish_ecb_enc_8way);
0045     ECB_BLOCK(3, twofish_enc_blk_3way);
0046     ECB_BLOCK(1, twofish_enc_blk);
0047     ECB_WALK_END();
0048 }
0049 
0050 static int ecb_decrypt(struct skcipher_request *req)
0051 {
0052     ECB_WALK_START(req, TF_BLOCK_SIZE, TWOFISH_PARALLEL_BLOCKS);
0053     ECB_BLOCK(TWOFISH_PARALLEL_BLOCKS, twofish_ecb_dec_8way);
0054     ECB_BLOCK(3, twofish_dec_blk_3way);
0055     ECB_BLOCK(1, twofish_dec_blk);
0056     ECB_WALK_END();
0057 }
0058 
0059 static int cbc_encrypt(struct skcipher_request *req)
0060 {
0061     CBC_WALK_START(req, TF_BLOCK_SIZE, -1);
0062     CBC_ENC_BLOCK(twofish_enc_blk);
0063     CBC_WALK_END();
0064 }
0065 
0066 static int cbc_decrypt(struct skcipher_request *req)
0067 {
0068     CBC_WALK_START(req, TF_BLOCK_SIZE, TWOFISH_PARALLEL_BLOCKS);
0069     CBC_DEC_BLOCK(TWOFISH_PARALLEL_BLOCKS, twofish_cbc_dec_8way);
0070     CBC_DEC_BLOCK(3, twofish_dec_blk_cbc_3way);
0071     CBC_DEC_BLOCK(1, twofish_dec_blk);
0072     CBC_WALK_END();
0073 }
0074 
0075 static struct skcipher_alg twofish_algs[] = {
0076     {
0077         .base.cra_name      = "__ecb(twofish)",
0078         .base.cra_driver_name   = "__ecb-twofish-avx",
0079         .base.cra_priority  = 400,
0080         .base.cra_flags     = CRYPTO_ALG_INTERNAL,
0081         .base.cra_blocksize = TF_BLOCK_SIZE,
0082         .base.cra_ctxsize   = sizeof(struct twofish_ctx),
0083         .base.cra_module    = THIS_MODULE,
0084         .min_keysize        = TF_MIN_KEY_SIZE,
0085         .max_keysize        = TF_MAX_KEY_SIZE,
0086         .setkey         = twofish_setkey_skcipher,
0087         .encrypt        = ecb_encrypt,
0088         .decrypt        = ecb_decrypt,
0089     }, {
0090         .base.cra_name      = "__cbc(twofish)",
0091         .base.cra_driver_name   = "__cbc-twofish-avx",
0092         .base.cra_priority  = 400,
0093         .base.cra_flags     = CRYPTO_ALG_INTERNAL,
0094         .base.cra_blocksize = TF_BLOCK_SIZE,
0095         .base.cra_ctxsize   = sizeof(struct twofish_ctx),
0096         .base.cra_module    = THIS_MODULE,
0097         .min_keysize        = TF_MIN_KEY_SIZE,
0098         .max_keysize        = TF_MAX_KEY_SIZE,
0099         .ivsize         = TF_BLOCK_SIZE,
0100         .setkey         = twofish_setkey_skcipher,
0101         .encrypt        = cbc_encrypt,
0102         .decrypt        = cbc_decrypt,
0103     },
0104 };
0105 
0106 static struct simd_skcipher_alg *twofish_simd_algs[ARRAY_SIZE(twofish_algs)];
0107 
0108 static int __init twofish_init(void)
0109 {
0110     const char *feature_name;
0111 
0112     if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM, &feature_name)) {
0113         pr_info("CPU feature '%s' is not supported.\n", feature_name);
0114         return -ENODEV;
0115     }
0116 
0117     return simd_register_skciphers_compat(twofish_algs,
0118                           ARRAY_SIZE(twofish_algs),
0119                           twofish_simd_algs);
0120 }
0121 
0122 static void __exit twofish_exit(void)
0123 {
0124     simd_unregister_skciphers(twofish_algs, ARRAY_SIZE(twofish_algs),
0125                   twofish_simd_algs);
0126 }
0127 
0128 module_init(twofish_init);
0129 module_exit(twofish_exit);
0130 
0131 MODULE_DESCRIPTION("Twofish Cipher Algorithm, AVX optimized");
0132 MODULE_LICENSE("GPL");
0133 MODULE_ALIAS_CRYPTO("twofish");