chacha.h 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * ChaCha stream cipher (P10 accelerated)
  4. *
  5. * Copyright 2023- IBM Corp. All rights reserved.
  6. */
  7. #include <crypto/internal/simd.h>
  8. #include <linux/kernel.h>
  9. #include <linux/cpufeature.h>
  10. #include <linux/sizes.h>
  11. #include <asm/simd.h>
  12. #include <asm/switch_to.h>
  13. asmlinkage void chacha_p10le_8x(const struct chacha_state *state, u8 *dst,
  14. const u8 *src, unsigned int len, int nrounds);
  15. static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_p10);
  16. static void vsx_begin(void)
  17. {
  18. preempt_disable();
  19. enable_kernel_vsx();
  20. }
  21. static void vsx_end(void)
  22. {
  23. disable_kernel_vsx();
  24. preempt_enable();
  25. }
  26. static void chacha_p10_do_8x(struct chacha_state *state, u8 *dst, const u8 *src,
  27. unsigned int bytes, int nrounds)
  28. {
  29. unsigned int l = bytes & ~0x0FF;
  30. if (l > 0) {
  31. chacha_p10le_8x(state, dst, src, l, nrounds);
  32. bytes -= l;
  33. src += l;
  34. dst += l;
  35. state->x[12] += l / CHACHA_BLOCK_SIZE;
  36. }
  37. if (bytes > 0)
  38. chacha_crypt_generic(state, dst, src, bytes, nrounds);
  39. }
  40. #define hchacha_block_arch hchacha_block_generic /* not implemented yet */
  41. static void chacha_crypt_arch(struct chacha_state *state, u8 *dst,
  42. const u8 *src, unsigned int bytes, int nrounds)
  43. {
  44. if (!static_branch_likely(&have_p10) || bytes <= CHACHA_BLOCK_SIZE ||
  45. !crypto_simd_usable())
  46. return chacha_crypt_generic(state, dst, src, bytes, nrounds);
  47. do {
  48. unsigned int todo = min_t(unsigned int, bytes, SZ_4K);
  49. vsx_begin();
  50. chacha_p10_do_8x(state, dst, src, todo, nrounds);
  51. vsx_end();
  52. bytes -= todo;
  53. src += todo;
  54. dst += todo;
  55. } while (bytes);
  56. }
  57. #define chacha_mod_init_arch chacha_mod_init_arch
  58. static void chacha_mod_init_arch(void)
  59. {
  60. if (cpu_has_feature(CPU_FTR_ARCH_31))
  61. static_branch_enable(&have_p10);
  62. }