linux/arch/x86/crypto/cast6_avx_glue.c
<<
>>
Prefs
   1/*
   2 * Glue Code for the AVX assembler implemention of the Cast6 Cipher
   3 *
   4 * Copyright (C) 2012 Johannes Goetzfried
   5 *     <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
   6 *
   7 * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  22 * USA
  23 *
  24 */
  25
  26#include <linux/module.h>
  27#include <linux/hardirq.h>
  28#include <linux/types.h>
  29#include <linux/crypto.h>
  30#include <linux/err.h>
  31#include <crypto/ablk_helper.h>
  32#include <crypto/algapi.h>
  33#include <crypto/cast6.h>
  34#include <crypto/cryptd.h>
  35#include <crypto/b128ops.h>
  36#include <crypto/ctr.h>
  37#include <crypto/lrw.h>
  38#include <crypto/xts.h>
  39#include <asm/fpu/api.h>
  40#include <asm/crypto/glue_helper.h>
  41
  42#define CAST6_PARALLEL_BLOCKS 8
  43
  44asmlinkage void cast6_ecb_enc_8way(struct cast6_ctx *ctx, u8 *dst,
  45                                   const u8 *src);
  46asmlinkage void cast6_ecb_dec_8way(struct cast6_ctx *ctx, u8 *dst,
  47                                   const u8 *src);
  48
  49asmlinkage void cast6_cbc_dec_8way(struct cast6_ctx *ctx, u8 *dst,
  50                                   const u8 *src);
  51asmlinkage void cast6_ctr_8way(struct cast6_ctx *ctx, u8 *dst, const u8 *src,
  52                               le128 *iv);
  53
  54asmlinkage void cast6_xts_enc_8way(struct cast6_ctx *ctx, u8 *dst,
  55                                   const u8 *src, le128 *iv);
  56asmlinkage void cast6_xts_dec_8way(struct cast6_ctx *ctx, u8 *dst,
  57                                   const u8 *src, le128 *iv);
  58
  59static void cast6_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv)
  60{
  61        glue_xts_crypt_128bit_one(ctx, dst, src, iv,
  62                                  GLUE_FUNC_CAST(__cast6_encrypt));
  63}
  64
  65static void cast6_xts_dec(void *ctx, u128 *dst, const u128 *src, le128 *iv)
  66{
  67        glue_xts_crypt_128bit_one(ctx, dst, src, iv,
  68                                  GLUE_FUNC_CAST(__cast6_decrypt));
  69}
  70
  71static void cast6_crypt_ctr(void *ctx, u128 *dst, const u128 *src, le128 *iv)
  72{
  73        be128 ctrblk;
  74
  75        le128_to_be128(&ctrblk, iv);
  76        le128_inc(iv);
  77
  78        __cast6_encrypt(ctx, (u8 *)&ctrblk, (u8 *)&ctrblk);
  79        u128_xor(dst, src, (u128 *)&ctrblk);
  80}
  81
  82static const struct common_glue_ctx cast6_enc = {
  83        .num_funcs = 2,
  84        .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
  85
  86        .funcs = { {
  87                .num_blocks = CAST6_PARALLEL_BLOCKS,
  88                .fn_u = { .ecb = GLUE_FUNC_CAST(cast6_ecb_enc_8way) }
  89        }, {
  90                .num_blocks = 1,
  91                .fn_u = { .ecb = GLUE_FUNC_CAST(__cast6_encrypt) }
  92        } }
  93};
  94
  95static const struct common_glue_ctx cast6_ctr = {
  96        .num_funcs = 2,
  97        .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
  98
  99        .funcs = { {
 100                .num_blocks = CAST6_PARALLEL_BLOCKS,
 101                .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(cast6_ctr_8way) }
 102        }, {
 103                .num_blocks = 1,
 104                .fn_u = { .ctr = GLUE_CTR_FUNC_CAST(cast6_crypt_ctr) }
 105        } }
 106};
 107
 108static const struct common_glue_ctx cast6_enc_xts = {
 109        .num_funcs = 2,
 110        .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
 111
 112        .funcs = { {
 113                .num_blocks = CAST6_PARALLEL_BLOCKS,
 114                .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_enc_8way) }
 115        }, {
 116                .num_blocks = 1,
 117                .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_enc) }
 118        } }
 119};
 120
 121static const struct common_glue_ctx cast6_dec = {
 122        .num_funcs = 2,
 123        .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
 124
 125        .funcs = { {
 126                .num_blocks = CAST6_PARALLEL_BLOCKS,
 127                .fn_u = { .ecb = GLUE_FUNC_CAST(cast6_ecb_dec_8way) }
 128        }, {
 129                .num_blocks = 1,
 130                .fn_u = { .ecb = GLUE_FUNC_CAST(__cast6_decrypt) }
 131        } }
 132};
 133
 134static const struct common_glue_ctx cast6_dec_cbc = {
 135        .num_funcs = 2,
 136        .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
 137
 138        .funcs = { {
 139                .num_blocks = CAST6_PARALLEL_BLOCKS,
 140                .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(cast6_cbc_dec_8way) }
 141        }, {
 142                .num_blocks = 1,
 143                .fn_u = { .cbc = GLUE_CBC_FUNC_CAST(__cast6_decrypt) }
 144        } }
 145};
 146
 147static const struct common_glue_ctx cast6_dec_xts = {
 148        .num_funcs = 2,
 149        .fpu_blocks_limit = CAST6_PARALLEL_BLOCKS,
 150
 151        .funcs = { {
 152                .num_blocks = CAST6_PARALLEL_BLOCKS,
 153                .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_dec_8way) }
 154        }, {
 155                .num_blocks = 1,
 156                .fn_u = { .xts = GLUE_XTS_FUNC_CAST(cast6_xts_dec) }
 157        } }
 158};
 159
 160static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 161                       struct scatterlist *src, unsigned int nbytes)
 162{
 163        return glue_ecb_crypt_128bit(&cast6_enc, desc, dst, src, nbytes);
 164}
 165
 166static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 167                       struct scatterlist *src, unsigned int nbytes)
 168{
 169        return glue_ecb_crypt_128bit(&cast6_dec, desc, dst, src, nbytes);
 170}
 171
 172static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 173                       struct scatterlist *src, unsigned int nbytes)
 174{
 175        return glue_cbc_encrypt_128bit(GLUE_FUNC_CAST(__cast6_encrypt), desc,
 176                                       dst, src, nbytes);
 177}
 178
 179static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 180                       struct scatterlist *src, unsigned int nbytes)
 181{
 182        return glue_cbc_decrypt_128bit(&cast6_dec_cbc, desc, dst, src,
 183                                       nbytes);
 184}
 185
 186static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 187                     struct scatterlist *src, unsigned int nbytes)
 188{
 189        return glue_ctr_crypt_128bit(&cast6_ctr, desc, dst, src, nbytes);
 190}
 191
 192static inline bool cast6_fpu_begin(bool fpu_enabled, unsigned int nbytes)
 193{
 194        return glue_fpu_begin(CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS,
 195                              NULL, fpu_enabled, nbytes);
 196}
 197
 198static inline void cast6_fpu_end(bool fpu_enabled)
 199{
 200        glue_fpu_end(fpu_enabled);
 201}
 202
 203struct crypt_priv {
 204        struct cast6_ctx *ctx;
 205        bool fpu_enabled;
 206};
 207
 208static void encrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
 209{
 210        const unsigned int bsize = CAST6_BLOCK_SIZE;
 211        struct crypt_priv *ctx = priv;
 212        int i;
 213
 214        ctx->fpu_enabled = cast6_fpu_begin(ctx->fpu_enabled, nbytes);
 215
 216        if (nbytes == bsize * CAST6_PARALLEL_BLOCKS) {
 217                cast6_ecb_enc_8way(ctx->ctx, srcdst, srcdst);
 218                return;
 219        }
 220
 221        for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
 222                __cast6_encrypt(ctx->ctx, srcdst, srcdst);
 223}
 224
 225static void decrypt_callback(void *priv, u8 *srcdst, unsigned int nbytes)
 226{
 227        const unsigned int bsize = CAST6_BLOCK_SIZE;
 228        struct crypt_priv *ctx = priv;
 229        int i;
 230
 231        ctx->fpu_enabled = cast6_fpu_begin(ctx->fpu_enabled, nbytes);
 232
 233        if (nbytes == bsize * CAST6_PARALLEL_BLOCKS) {
 234                cast6_ecb_dec_8way(ctx->ctx, srcdst, srcdst);
 235                return;
 236        }
 237
 238        for (i = 0; i < nbytes / bsize; i++, srcdst += bsize)
 239                __cast6_decrypt(ctx->ctx, srcdst, srcdst);
 240}
 241
 242struct cast6_lrw_ctx {
 243        struct lrw_table_ctx lrw_table;
 244        struct cast6_ctx cast6_ctx;
 245};
 246
 247static int lrw_cast6_setkey(struct crypto_tfm *tfm, const u8 *key,
 248                              unsigned int keylen)
 249{
 250        struct cast6_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
 251        int err;
 252
 253        err = __cast6_setkey(&ctx->cast6_ctx, key, keylen - CAST6_BLOCK_SIZE,
 254                             &tfm->crt_flags);
 255        if (err)
 256                return err;
 257
 258        return lrw_init_table(&ctx->lrw_table, key + keylen - CAST6_BLOCK_SIZE);
 259}
 260
 261static int lrw_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 262                       struct scatterlist *src, unsigned int nbytes)
 263{
 264        struct cast6_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 265        be128 buf[CAST6_PARALLEL_BLOCKS];
 266        struct crypt_priv crypt_ctx = {
 267                .ctx = &ctx->cast6_ctx,
 268                .fpu_enabled = false,
 269        };
 270        struct lrw_crypt_req req = {
 271                .tbuf = buf,
 272                .tbuflen = sizeof(buf),
 273
 274                .table_ctx = &ctx->lrw_table,
 275                .crypt_ctx = &crypt_ctx,
 276                .crypt_fn = encrypt_callback,
 277        };
 278        int ret;
 279
 280        desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 281        ret = lrw_crypt(desc, dst, src, nbytes, &req);
 282        cast6_fpu_end(crypt_ctx.fpu_enabled);
 283
 284        return ret;
 285}
 286
 287static int lrw_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 288                       struct scatterlist *src, unsigned int nbytes)
 289{
 290        struct cast6_lrw_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 291        be128 buf[CAST6_PARALLEL_BLOCKS];
 292        struct crypt_priv crypt_ctx = {
 293                .ctx = &ctx->cast6_ctx,
 294                .fpu_enabled = false,
 295        };
 296        struct lrw_crypt_req req = {
 297                .tbuf = buf,
 298                .tbuflen = sizeof(buf),
 299
 300                .table_ctx = &ctx->lrw_table,
 301                .crypt_ctx = &crypt_ctx,
 302                .crypt_fn = decrypt_callback,
 303        };
 304        int ret;
 305
 306        desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
 307        ret = lrw_crypt(desc, dst, src, nbytes, &req);
 308        cast6_fpu_end(crypt_ctx.fpu_enabled);
 309
 310        return ret;
 311}
 312
 313static void lrw_exit_tfm(struct crypto_tfm *tfm)
 314{
 315        struct cast6_lrw_ctx *ctx = crypto_tfm_ctx(tfm);
 316
 317        lrw_free_table(&ctx->lrw_table);
 318}
 319
 320struct cast6_xts_ctx {
 321        struct cast6_ctx tweak_ctx;
 322        struct cast6_ctx crypt_ctx;
 323};
 324
 325static int xts_cast6_setkey(struct crypto_tfm *tfm, const u8 *key,
 326                              unsigned int keylen)
 327{
 328        struct cast6_xts_ctx *ctx = crypto_tfm_ctx(tfm);
 329        u32 *flags = &tfm->crt_flags;
 330        int err;
 331
 332        err = xts_check_key(tfm, key, keylen);
 333        if (err)
 334                return err;
 335
 336        /* first half of xts-key is for crypt */
 337        err = __cast6_setkey(&ctx->crypt_ctx, key, keylen / 2, flags);
 338        if (err)
 339                return err;
 340
 341        /* second half of xts-key is for tweak */
 342        return __cast6_setkey(&ctx->tweak_ctx, key + keylen / 2, keylen / 2,
 343                              flags);
 344}
 345
 346static int xts_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 347                       struct scatterlist *src, unsigned int nbytes)
 348{
 349        struct cast6_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 350
 351        return glue_xts_crypt_128bit(&cast6_enc_xts, desc, dst, src, nbytes,
 352                                     XTS_TWEAK_CAST(__cast6_encrypt),
 353                                     &ctx->tweak_ctx, &ctx->crypt_ctx);
 354}
 355
 356static int xts_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
 357                       struct scatterlist *src, unsigned int nbytes)
 358{
 359        struct cast6_xts_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 360
 361        return glue_xts_crypt_128bit(&cast6_dec_xts, desc, dst, src, nbytes,
 362                                     XTS_TWEAK_CAST(__cast6_encrypt),
 363                                     &ctx->tweak_ctx, &ctx->crypt_ctx);
 364}
 365
 366static struct crypto_alg cast6_algs[10] = { {
 367        .cra_name               = "__ecb-cast6-avx",
 368        .cra_driver_name        = "__driver-ecb-cast6-avx",
 369        .cra_priority           = 0,
 370        .cra_flags              = CRYPTO_ALG_TYPE_BLKCIPHER |
 371                                  CRYPTO_ALG_INTERNAL,
 372        .cra_blocksize          = CAST6_BLOCK_SIZE,
 373        .cra_ctxsize            = sizeof(struct cast6_ctx),
 374        .cra_alignmask          = 0,
 375        .cra_type               = &crypto_blkcipher_type,
 376        .cra_module             = THIS_MODULE,
 377        .cra_u = {
 378                .blkcipher = {
 379                        .min_keysize    = CAST6_MIN_KEY_SIZE,
 380                        .max_keysize    = CAST6_MAX_KEY_SIZE,
 381                        .setkey         = cast6_setkey,
 382                        .encrypt        = ecb_encrypt,
 383                        .decrypt        = ecb_decrypt,
 384                },
 385        },
 386}, {
 387        .cra_name               = "__cbc-cast6-avx",
 388        .cra_driver_name        = "__driver-cbc-cast6-avx",
 389        .cra_priority           = 0,
 390        .cra_flags              = CRYPTO_ALG_TYPE_BLKCIPHER |
 391                                  CRYPTO_ALG_INTERNAL,
 392        .cra_blocksize          = CAST6_BLOCK_SIZE,
 393        .cra_ctxsize            = sizeof(struct cast6_ctx),
 394        .cra_alignmask          = 0,
 395        .cra_type               = &crypto_blkcipher_type,
 396        .cra_module             = THIS_MODULE,
 397        .cra_u = {
 398                .blkcipher = {
 399                        .min_keysize    = CAST6_MIN_KEY_SIZE,
 400                        .max_keysize    = CAST6_MAX_KEY_SIZE,
 401                        .setkey         = cast6_setkey,
 402                        .encrypt        = cbc_encrypt,
 403                        .decrypt        = cbc_decrypt,
 404                },
 405        },
 406}, {
 407        .cra_name               = "__ctr-cast6-avx",
 408        .cra_driver_name        = "__driver-ctr-cast6-avx",
 409        .cra_priority           = 0,
 410        .cra_flags              = CRYPTO_ALG_TYPE_BLKCIPHER |
 411                                  CRYPTO_ALG_INTERNAL,
 412        .cra_blocksize          = 1,
 413        .cra_ctxsize            = sizeof(struct cast6_ctx),
 414        .cra_alignmask          = 0,
 415        .cra_type               = &crypto_blkcipher_type,
 416        .cra_module             = THIS_MODULE,
 417        .cra_u = {
 418                .blkcipher = {
 419                        .min_keysize    = CAST6_MIN_KEY_SIZE,
 420                        .max_keysize    = CAST6_MAX_KEY_SIZE,
 421                        .ivsize         = CAST6_BLOCK_SIZE,
 422                        .setkey         = cast6_setkey,
 423                        .encrypt        = ctr_crypt,
 424                        .decrypt        = ctr_crypt,
 425                },
 426        },
 427}, {
 428        .cra_name               = "__lrw-cast6-avx",
 429        .cra_driver_name        = "__driver-lrw-cast6-avx",
 430        .cra_priority           = 0,
 431        .cra_flags              = CRYPTO_ALG_TYPE_BLKCIPHER |
 432                                  CRYPTO_ALG_INTERNAL,
 433        .cra_blocksize          = CAST6_BLOCK_SIZE,
 434        .cra_ctxsize            = sizeof(struct cast6_lrw_ctx),
 435        .cra_alignmask          = 0,
 436        .cra_type               = &crypto_blkcipher_type,
 437        .cra_module             = THIS_MODULE,
 438        .cra_exit               = lrw_exit_tfm,
 439        .cra_u = {
 440                .blkcipher = {
 441                        .min_keysize    = CAST6_MIN_KEY_SIZE +
 442                                          CAST6_BLOCK_SIZE,
 443                        .max_keysize    = CAST6_MAX_KEY_SIZE +
 444                                          CAST6_BLOCK_SIZE,
 445                        .ivsize         = CAST6_BLOCK_SIZE,
 446                        .setkey         = lrw_cast6_setkey,
 447                        .encrypt        = lrw_encrypt,
 448                        .decrypt        = lrw_decrypt,
 449                },
 450        },
 451}, {
 452        .cra_name               = "__xts-cast6-avx",
 453        .cra_driver_name        = "__driver-xts-cast6-avx",
 454        .cra_priority           = 0,
 455        .cra_flags              = CRYPTO_ALG_TYPE_BLKCIPHER |
 456                                  CRYPTO_ALG_INTERNAL,
 457        .cra_blocksize          = CAST6_BLOCK_SIZE,
 458        .cra_ctxsize            = sizeof(struct cast6_xts_ctx),
 459        .cra_alignmask          = 0,
 460        .cra_type               = &crypto_blkcipher_type,
 461        .cra_module             = THIS_MODULE,
 462        .cra_u = {
 463                .blkcipher = {
 464                        .min_keysize    = CAST6_MIN_KEY_SIZE * 2,
 465                        .max_keysize    = CAST6_MAX_KEY_SIZE * 2,
 466                        .ivsize         = CAST6_BLOCK_SIZE,
 467                        .setkey         = xts_cast6_setkey,
 468                        .encrypt        = xts_encrypt,
 469                        .decrypt        = xts_decrypt,
 470                },
 471        },
 472}, {
 473        .cra_name               = "ecb(cast6)",
 474        .cra_driver_name        = "ecb-cast6-avx",
 475        .cra_priority           = 200,
 476        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 477        .cra_blocksize          = CAST6_BLOCK_SIZE,
 478        .cra_ctxsize            = sizeof(struct async_helper_ctx),
 479        .cra_alignmask          = 0,
 480        .cra_type               = &crypto_ablkcipher_type,
 481        .cra_module             = THIS_MODULE,
 482        .cra_init               = ablk_init,
 483        .cra_exit               = ablk_exit,
 484        .cra_u = {
 485                .ablkcipher = {
 486                        .min_keysize    = CAST6_MIN_KEY_SIZE,
 487                        .max_keysize    = CAST6_MAX_KEY_SIZE,
 488                        .setkey         = ablk_set_key,
 489                        .encrypt        = ablk_encrypt,
 490                        .decrypt        = ablk_decrypt,
 491                },
 492        },
 493}, {
 494        .cra_name               = "cbc(cast6)",
 495        .cra_driver_name        = "cbc-cast6-avx",
 496        .cra_priority           = 200,
 497        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 498        .cra_blocksize          = CAST6_BLOCK_SIZE,
 499        .cra_ctxsize            = sizeof(struct async_helper_ctx),
 500        .cra_alignmask          = 0,
 501        .cra_type               = &crypto_ablkcipher_type,
 502        .cra_module             = THIS_MODULE,
 503        .cra_init               = ablk_init,
 504        .cra_exit               = ablk_exit,
 505        .cra_u = {
 506                .ablkcipher = {
 507                        .min_keysize    = CAST6_MIN_KEY_SIZE,
 508                        .max_keysize    = CAST6_MAX_KEY_SIZE,
 509                        .ivsize         = CAST6_BLOCK_SIZE,
 510                        .setkey         = ablk_set_key,
 511                        .encrypt        = __ablk_encrypt,
 512                        .decrypt        = ablk_decrypt,
 513                },
 514        },
 515}, {
 516        .cra_name               = "ctr(cast6)",
 517        .cra_driver_name        = "ctr-cast6-avx",
 518        .cra_priority           = 200,
 519        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 520        .cra_blocksize          = 1,
 521        .cra_ctxsize            = sizeof(struct async_helper_ctx),
 522        .cra_alignmask          = 0,
 523        .cra_type               = &crypto_ablkcipher_type,
 524        .cra_module             = THIS_MODULE,
 525        .cra_init               = ablk_init,
 526        .cra_exit               = ablk_exit,
 527        .cra_u = {
 528                .ablkcipher = {
 529                        .min_keysize    = CAST6_MIN_KEY_SIZE,
 530                        .max_keysize    = CAST6_MAX_KEY_SIZE,
 531                        .ivsize         = CAST6_BLOCK_SIZE,
 532                        .setkey         = ablk_set_key,
 533                        .encrypt        = ablk_encrypt,
 534                        .decrypt        = ablk_encrypt,
 535                        .geniv          = "chainiv",
 536                },
 537        },
 538}, {
 539        .cra_name               = "lrw(cast6)",
 540        .cra_driver_name        = "lrw-cast6-avx",
 541        .cra_priority           = 200,
 542        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 543        .cra_blocksize          = CAST6_BLOCK_SIZE,
 544        .cra_ctxsize            = sizeof(struct async_helper_ctx),
 545        .cra_alignmask          = 0,
 546        .cra_type               = &crypto_ablkcipher_type,
 547        .cra_module             = THIS_MODULE,
 548        .cra_init               = ablk_init,
 549        .cra_exit               = ablk_exit,
 550        .cra_u = {
 551                .ablkcipher = {
 552                        .min_keysize    = CAST6_MIN_KEY_SIZE +
 553                                          CAST6_BLOCK_SIZE,
 554                        .max_keysize    = CAST6_MAX_KEY_SIZE +
 555                                          CAST6_BLOCK_SIZE,
 556                        .ivsize         = CAST6_BLOCK_SIZE,
 557                        .setkey         = ablk_set_key,
 558                        .encrypt        = ablk_encrypt,
 559                        .decrypt        = ablk_decrypt,
 560                },
 561        },
 562}, {
 563        .cra_name               = "xts(cast6)",
 564        .cra_driver_name        = "xts-cast6-avx",
 565        .cra_priority           = 200,
 566        .cra_flags              = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC,
 567        .cra_blocksize          = CAST6_BLOCK_SIZE,
 568        .cra_ctxsize            = sizeof(struct async_helper_ctx),
 569        .cra_alignmask          = 0,
 570        .cra_type               = &crypto_ablkcipher_type,
 571        .cra_module             = THIS_MODULE,
 572        .cra_init               = ablk_init,
 573        .cra_exit               = ablk_exit,
 574        .cra_u = {
 575                .ablkcipher = {
 576                        .min_keysize    = CAST6_MIN_KEY_SIZE * 2,
 577                        .max_keysize    = CAST6_MAX_KEY_SIZE * 2,
 578                        .ivsize         = CAST6_BLOCK_SIZE,
 579                        .setkey         = ablk_set_key,
 580                        .encrypt        = ablk_encrypt,
 581                        .decrypt        = ablk_decrypt,
 582                },
 583        },
 584} };
 585
 586static int __init cast6_init(void)
 587{
 588        const char *feature_name;
 589
 590        if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
 591                                &feature_name)) {
 592                pr_info("CPU feature '%s' is not supported.\n", feature_name);
 593                return -ENODEV;
 594        }
 595
 596        return crypto_register_algs(cast6_algs, ARRAY_SIZE(cast6_algs));
 597}
 598
 599static void __exit cast6_exit(void)
 600{
 601        crypto_unregister_algs(cast6_algs, ARRAY_SIZE(cast6_algs));
 602}
 603
 604module_init(cast6_init);
 605module_exit(cast6_exit);
 606
 607MODULE_DESCRIPTION("Cast6 Cipher Algorithm, AVX optimized");
 608MODULE_LICENSE("GPL");
 609MODULE_ALIAS_CRYPTO("cast6");
 610