Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 
0003 #ifndef _CRYPTO_ECB_CBC_HELPER_H
0004 #define _CRYPTO_ECB_CBC_HELPER_H
0005 
0006 #include <crypto/internal/skcipher.h>
0007 #include <asm/fpu/api.h>
0008 
0009 /*
0010  * Mode helpers to instantiate parameterized skcipher ECB/CBC modes without
0011  * having to rely on indirect calls and retpolines.
0012  */
0013 
0014 #define ECB_WALK_START(req, bsize, fpu_blocks) do {         \
0015     void *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));   \
0016     const int __bsize = (bsize);                    \
0017     struct skcipher_walk walk;                  \
0018     int err = skcipher_walk_virt(&walk, (req), false);      \
0019     while (walk.nbytes > 0) {                   \
0020         unsigned int nbytes = walk.nbytes;          \
0021         bool do_fpu = (fpu_blocks) != -1 &&         \
0022                   nbytes >= (fpu_blocks) * __bsize;     \
0023         const u8 *src = walk.src.virt.addr;         \
0024         u8 *dst = walk.dst.virt.addr;               \
0025         u8 __maybe_unused buf[(bsize)];             \
0026         if (do_fpu) kernel_fpu_begin()
0027 
0028 #define CBC_WALK_START(req, bsize, fpu_blocks)              \
0029     ECB_WALK_START(req, bsize, fpu_blocks)
0030 
0031 #define ECB_WALK_ADVANCE(blocks) do {                   \
0032     dst += (blocks) * __bsize;                  \
0033     src += (blocks) * __bsize;                  \
0034     nbytes -= (blocks) * __bsize;                   \
0035 } while (0)
0036 
0037 #define ECB_BLOCK(blocks, func) do {                    \
0038     while (nbytes >= (blocks) * __bsize) {              \
0039         (func)(ctx, dst, src);                  \
0040         ECB_WALK_ADVANCE(blocks);               \
0041     }                               \
0042 } while (0)
0043 
0044 #define CBC_ENC_BLOCK(func) do {                    \
0045     const u8 *__iv = walk.iv;                   \
0046     while (nbytes >= __bsize) {                 \
0047         crypto_xor_cpy(dst, src, __iv, __bsize);        \
0048         (func)(ctx, dst, dst);                  \
0049         __iv = dst;                     \
0050         ECB_WALK_ADVANCE(1);                    \
0051     }                               \
0052     memcpy(walk.iv, __iv, __bsize);                 \
0053 } while (0)
0054 
0055 #define CBC_DEC_BLOCK(blocks, func) do {                \
0056     while (nbytes >= (blocks) * __bsize) {              \
0057         const u8 *__iv = src + ((blocks) - 1) * __bsize;    \
0058         if (dst == src)                     \
0059             __iv = memcpy(buf, __iv, __bsize);      \
0060         (func)(ctx, dst, src);                  \
0061         crypto_xor(dst, walk.iv, __bsize);          \
0062         memcpy(walk.iv, __iv, __bsize);             \
0063         ECB_WALK_ADVANCE(blocks);               \
0064     }                               \
0065 } while (0)
0066 
0067 #define ECB_WALK_END()                          \
0068         if (do_fpu) kernel_fpu_end();               \
0069         err = skcipher_walk_done(&walk, nbytes);        \
0070     }                               \
0071     return err;                         \
0072 } while (0)
0073 
0074 #define CBC_WALK_END() ECB_WALK_END()
0075 
0076 #endif