linux/arch/x86/include/asm/crypto/glue_helper.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * Shared glue code for 128bit block ciphers
   4 */
   5
   6#ifndef _CRYPTO_GLUE_HELPER_H
   7#define _CRYPTO_GLUE_HELPER_H
   8
   9#include <crypto/internal/skcipher.h>
  10#include <linux/kernel.h>
  11#include <asm/fpu/api.h>
  12#include <crypto/b128ops.h>
  13
  14typedef void (*common_glue_func_t)(void *ctx, u8 *dst, const u8 *src);
  15typedef void (*common_glue_cbc_func_t)(void *ctx, u128 *dst, const u128 *src);
  16typedef void (*common_glue_ctr_func_t)(void *ctx, u128 *dst, const u128 *src,
  17                                       le128 *iv);
  18typedef void (*common_glue_xts_func_t)(void *ctx, u128 *dst, const u128 *src,
  19                                       le128 *iv);
  20
  21#define GLUE_FUNC_CAST(fn) ((common_glue_func_t)(fn))
  22#define GLUE_CBC_FUNC_CAST(fn) ((common_glue_cbc_func_t)(fn))
  23#define GLUE_CTR_FUNC_CAST(fn) ((common_glue_ctr_func_t)(fn))
  24#define GLUE_XTS_FUNC_CAST(fn) ((common_glue_xts_func_t)(fn))
  25
  26struct common_glue_func_entry {
  27        unsigned int num_blocks; /* number of blocks that @fn will process */
  28        union {
  29                common_glue_func_t ecb;
  30                common_glue_cbc_func_t cbc;
  31                common_glue_ctr_func_t ctr;
  32                common_glue_xts_func_t xts;
  33        } fn_u;
  34};
  35
  36struct common_glue_ctx {
  37        unsigned int num_funcs;
  38        int fpu_blocks_limit; /* -1 means fpu not needed at all */
  39
  40        /*
  41         * First funcs entry must have largest num_blocks and last funcs entry
  42         * must have num_blocks == 1!
  43         */
  44        struct common_glue_func_entry funcs[];
  45};
  46
  47static inline bool glue_fpu_begin(unsigned int bsize, int fpu_blocks_limit,
  48                                  struct blkcipher_desc *desc,
  49                                  bool fpu_enabled, unsigned int nbytes)
  50{
  51        if (likely(fpu_blocks_limit < 0))
  52                return false;
  53
  54        if (fpu_enabled)
  55                return true;
  56
  57        /*
  58         * Vector-registers are only used when chunk to be processed is large
  59         * enough, so do not enable FPU until it is necessary.
  60         */
  61        if (nbytes < bsize * (unsigned int)fpu_blocks_limit)
  62                return false;
  63
  64        if (desc) {
  65                /* prevent sleeping if FPU is in use */
  66                desc->flags &= ~CRYPTO_TFM_REQ_MAY_SLEEP;
  67        }
  68
  69        kernel_fpu_begin();
  70        return true;
  71}
  72
  73static inline bool glue_skwalk_fpu_begin(unsigned int bsize,
  74                                         int fpu_blocks_limit,
  75                                         struct skcipher_walk *walk,
  76                                         bool fpu_enabled, unsigned int nbytes)
  77{
  78        if (likely(fpu_blocks_limit < 0))
  79                return false;
  80
  81        if (fpu_enabled)
  82                return true;
  83
  84        /*
  85         * Vector-registers are only used when chunk to be processed is large
  86         * enough, so do not enable FPU until it is necessary.
  87         */
  88        if (nbytes < bsize * (unsigned int)fpu_blocks_limit)
  89                return false;
  90
  91        /* prevent sleeping if FPU is in use */
  92        skcipher_walk_atomise(walk);
  93
  94        kernel_fpu_begin();
  95        return true;
  96}
  97
  98static inline void glue_fpu_end(bool fpu_enabled)
  99{
 100        if (fpu_enabled)
 101                kernel_fpu_end();
 102}
 103
 104static inline void le128_to_be128(be128 *dst, const le128 *src)
 105{
 106        dst->a = cpu_to_be64(le64_to_cpu(src->a));
 107        dst->b = cpu_to_be64(le64_to_cpu(src->b));
 108}
 109
 110static inline void be128_to_le128(le128 *dst, const be128 *src)
 111{
 112        dst->a = cpu_to_le64(be64_to_cpu(src->a));
 113        dst->b = cpu_to_le64(be64_to_cpu(src->b));
 114}
 115
 116static inline void le128_inc(le128 *i)
 117{
 118        u64 a = le64_to_cpu(i->a);
 119        u64 b = le64_to_cpu(i->b);
 120
 121        b++;
 122        if (!b)
 123                a++;
 124
 125        i->a = cpu_to_le64(a);
 126        i->b = cpu_to_le64(b);
 127}
 128
 129extern int glue_ecb_crypt_128bit(const struct common_glue_ctx *gctx,
 130                                 struct blkcipher_desc *desc,
 131                                 struct scatterlist *dst,
 132                                 struct scatterlist *src, unsigned int nbytes);
 133
 134extern int glue_cbc_encrypt_128bit(const common_glue_func_t fn,
 135                                   struct blkcipher_desc *desc,
 136                                   struct scatterlist *dst,
 137                                   struct scatterlist *src,
 138                                   unsigned int nbytes);
 139
 140extern int glue_cbc_decrypt_128bit(const struct common_glue_ctx *gctx,
 141                                   struct blkcipher_desc *desc,
 142                                   struct scatterlist *dst,
 143                                   struct scatterlist *src,
 144                                   unsigned int nbytes);
 145
 146extern int glue_ctr_crypt_128bit(const struct common_glue_ctx *gctx,
 147                                 struct blkcipher_desc *desc,
 148                                 struct scatterlist *dst,
 149                                 struct scatterlist *src, unsigned int nbytes);
 150
 151extern int glue_xts_crypt_128bit(const struct common_glue_ctx *gctx,
 152                                 struct blkcipher_desc *desc,
 153                                 struct scatterlist *dst,
 154                                 struct scatterlist *src, unsigned int nbytes,
 155                                 common_glue_func_t tweak_fn, void *tweak_ctx,
 156                                 void *crypt_ctx);
 157
 158extern int glue_xts_crypt_128bit(const struct common_glue_ctx *gctx,
 159                                 struct blkcipher_desc *desc,
 160                                 struct scatterlist *dst,
 161                                 struct scatterlist *src, unsigned int nbytes,
 162                                 common_glue_func_t tweak_fn, void *tweak_ctx,
 163                                 void *crypt_ctx);
 164
 165extern int glue_xts_req_128bit(const struct common_glue_ctx *gctx,
 166                               struct skcipher_request *req,
 167                               common_glue_func_t tweak_fn, void *tweak_ctx,
 168                               void *crypt_ctx);
 169
 170extern void glue_xts_crypt_128bit_one(void *ctx, u128 *dst, const u128 *src,
 171                                      le128 *iv, common_glue_func_t fn);
 172
 173#endif /* _CRYPTO_GLUE_HELPER_H */
 174