ecb_cbc_helpers.h 2.1 KB

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