linux/arch/x86/crypto/cast6_avx_glue.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Glue Code for the AVX assembler implementation of the Cast6 Cipher
   4 *
   5 * Copyright (C) 2012 Johannes Goetzfried
   6 *     <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
   7 *
   8 * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
   9 */
  10
  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/cast6.h>
  17#include <crypto/internal/simd.h>
  18
  19#include "ecb_cbc_helpers.h"
  20
  21#define CAST6_PARALLEL_BLOCKS 8
  22
  23asmlinkage void cast6_ecb_enc_8way(const void *ctx, u8 *dst, const u8 *src);
  24asmlinkage void cast6_ecb_dec_8way(const void *ctx, u8 *dst, const u8 *src);
  25
  26asmlinkage void cast6_cbc_dec_8way(const void *ctx, u8 *dst, const u8 *src);
  27
  28static int cast6_setkey_skcipher(struct crypto_skcipher *tfm,
  29                                 const u8 *key, unsigned int keylen)
  30{
  31        return cast6_setkey(&tfm->base, key, keylen);
  32}
  33
  34static int ecb_encrypt(struct skcipher_request *req)
  35{
  36        ECB_WALK_START(req, CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS);
  37        ECB_BLOCK(CAST6_PARALLEL_BLOCKS, cast6_ecb_enc_8way);
  38        ECB_BLOCK(1, __cast6_encrypt);
  39        ECB_WALK_END();
  40}
  41
  42static int ecb_decrypt(struct skcipher_request *req)
  43{
  44        ECB_WALK_START(req, CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS);
  45        ECB_BLOCK(CAST6_PARALLEL_BLOCKS, cast6_ecb_dec_8way);
  46        ECB_BLOCK(1, __cast6_decrypt);
  47        ECB_WALK_END();
  48}
  49
  50static int cbc_encrypt(struct skcipher_request *req)
  51{
  52        CBC_WALK_START(req, CAST6_BLOCK_SIZE, -1);
  53        CBC_ENC_BLOCK(__cast6_encrypt);
  54        CBC_WALK_END();
  55}
  56
  57static int cbc_decrypt(struct skcipher_request *req)
  58{
  59        CBC_WALK_START(req, CAST6_BLOCK_SIZE, CAST6_PARALLEL_BLOCKS);
  60        CBC_DEC_BLOCK(CAST6_PARALLEL_BLOCKS, cast6_cbc_dec_8way);
  61        CBC_DEC_BLOCK(1, __cast6_decrypt);
  62        CBC_WALK_END();
  63}
  64
  65static struct skcipher_alg cast6_algs[] = {
  66        {
  67                .base.cra_name          = "__ecb(cast6)",
  68                .base.cra_driver_name   = "__ecb-cast6-avx",
  69                .base.cra_priority      = 200,
  70                .base.cra_flags         = CRYPTO_ALG_INTERNAL,
  71                .base.cra_blocksize     = CAST6_BLOCK_SIZE,
  72                .base.cra_ctxsize       = sizeof(struct cast6_ctx),
  73                .base.cra_module        = THIS_MODULE,
  74                .min_keysize            = CAST6_MIN_KEY_SIZE,
  75                .max_keysize            = CAST6_MAX_KEY_SIZE,
  76                .setkey                 = cast6_setkey_skcipher,
  77                .encrypt                = ecb_encrypt,
  78                .decrypt                = ecb_decrypt,
  79        }, {
  80                .base.cra_name          = "__cbc(cast6)",
  81                .base.cra_driver_name   = "__cbc-cast6-avx",
  82                .base.cra_priority      = 200,
  83                .base.cra_flags         = CRYPTO_ALG_INTERNAL,
  84                .base.cra_blocksize     = CAST6_BLOCK_SIZE,
  85                .base.cra_ctxsize       = sizeof(struct cast6_ctx),
  86                .base.cra_module        = THIS_MODULE,
  87                .min_keysize            = CAST6_MIN_KEY_SIZE,
  88                .max_keysize            = CAST6_MAX_KEY_SIZE,
  89                .ivsize                 = CAST6_BLOCK_SIZE,
  90                .setkey                 = cast6_setkey_skcipher,
  91                .encrypt                = cbc_encrypt,
  92                .decrypt                = cbc_decrypt,
  93        },
  94};
  95
  96static struct simd_skcipher_alg *cast6_simd_algs[ARRAY_SIZE(cast6_algs)];
  97
  98static int __init cast6_init(void)
  99{
 100        const char *feature_name;
 101
 102        if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
 103                                &feature_name)) {
 104                pr_info("CPU feature '%s' is not supported.\n", feature_name);
 105                return -ENODEV;
 106        }
 107
 108        return simd_register_skciphers_compat(cast6_algs,
 109                                              ARRAY_SIZE(cast6_algs),
 110                                              cast6_simd_algs);
 111}
 112
 113static void __exit cast6_exit(void)
 114{
 115        simd_unregister_skciphers(cast6_algs, ARRAY_SIZE(cast6_algs),
 116                                  cast6_simd_algs);
 117}
 118
 119module_init(cast6_init);
 120module_exit(cast6_exit);
 121
 122MODULE_DESCRIPTION("Cast6 Cipher Algorithm, AVX optimized");
 123MODULE_LICENSE("GPL");
 124MODULE_ALIAS_CRYPTO("cast6");
 125