linux/arch/x86/crypto/ecb_cbc_helpers.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2
   3#ifndef _CRYPTO_ECB_CBC_HELPER_H
   4#define _CRYPTO_ECB_CBC_HELPER_H
   5
   6#include <crypto/internal/skcipher.h>
   7#include <asm/fpu/api.h>
   8
   9/*
  10 * Mode helpers to instantiate parameterized skcipher ECB/CBC modes without
  11 * having to rely on indirect calls and retpolines.
  12 */
  13
  14#define ECB_WALK_START(req, bsize, fpu_blocks) do {                     \
  15        void *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));   \
  16        const int __bsize = (bsize);                                    \
  17        struct skcipher_walk walk;                                      \
  18        int err = skcipher_walk_virt(&walk, (req), false);              \
  19        while (walk.nbytes > 0) {                                       \
  20                unsigned int nbytes = walk.nbytes;                      \
  21                bool do_fpu = (fpu_blocks) != -1 &&                     \
  22                              nbytes >= (fpu_blocks) * __bsize;         \
  23                const u8 *src = walk.src.virt.addr;                     \
  24                u8 *dst = walk.dst.virt.addr;                           \
  25                u8 __maybe_unused buf[(bsize)];                         \
  26                if (do_fpu) kernel_fpu_begin()
  27
  28#define CBC_WALK_START(req, bsize, fpu_blocks)                          \
  29        ECB_WALK_START(req, bsize, fpu_blocks)
  30
  31#define ECB_WALK_ADVANCE(blocks) do {                                   \
  32        dst += (blocks) * __bsize;                                      \
  33        src += (blocks) * __bsize;                                      \
  34        nbytes -= (blocks) * __bsize;                                   \
  35} while (0)
  36
  37#define ECB_BLOCK(blocks, func) do {                                    \
  38        while (nbytes >= (blocks) * __bsize) {                          \
  39                (func)(ctx, dst, src);                                  \
  40                ECB_WALK_ADVANCE(blocks);                               \
  41        }                                                               \
  42} while (0)
  43
  44#define CBC_ENC_BLOCK(func) do {                                        \
  45        const u8 *__iv = walk.iv;                                       \
  46        while (nbytes >= __bsize) {                                     \
  47                crypto_xor_cpy(dst, src, __iv, __bsize);                \
  48                (func)(ctx, dst, dst);                                  \
  49                __iv = dst;                                             \
  50                ECB_WALK_ADVANCE(1);                                    \
  51        }                                                               \
  52        memcpy(walk.iv, __iv, __bsize);                                 \
  53} while (0)
  54
  55#define CBC_DEC_BLOCK(blocks, func) do {                                \
  56        while (nbytes >= (blocks) * __bsize) {                          \
  57                const u8 *__iv = src + ((blocks) - 1) * __bsize;        \
  58                if (dst == src)                                         \
  59                        __iv = memcpy(buf, __iv, __bsize);              \
  60                (func)(ctx, dst, src);                                  \
  61                crypto_xor(dst, walk.iv, __bsize);                      \
  62                memcpy(walk.iv, __iv, __bsize);                         \
  63                ECB_WALK_ADVANCE(blocks);                               \
  64        }                                                               \
  65} while (0)
  66
  67#define ECB_WALK_END()                                                  \
  68                if (do_fpu) kernel_fpu_end();                           \
  69                err = skcipher_walk_done(&walk, nbytes);                \
  70        }                                                               \
  71        return err;                                                     \
  72} while (0)
  73
  74#define CBC_WALK_END() ECB_WALK_END()
  75
  76#endif
  77