chacha-block-generic.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * The "hash function" used as the core of the ChaCha stream cipher (RFC7539)
  4. *
  5. * Copyright (C) 2015 Martin Willi
  6. */
  7. #include <crypto/chacha.h>
  8. #include <linux/bitops.h>
  9. #include <linux/bug.h>
  10. #include <linux/export.h>
  11. #include <linux/kernel.h>
  12. #include <linux/string.h>
  13. #include <linux/unaligned.h>
  14. static void chacha_permute(struct chacha_state *state, int nrounds)
  15. {
  16. u32 *x = state->x;
  17. int i;
  18. /* whitelist the allowed round counts */
  19. WARN_ON_ONCE(nrounds != 20 && nrounds != 12);
  20. for (i = 0; i < nrounds; i += 2) {
  21. x[0] += x[4]; x[12] = rol32(x[12] ^ x[0], 16);
  22. x[1] += x[5]; x[13] = rol32(x[13] ^ x[1], 16);
  23. x[2] += x[6]; x[14] = rol32(x[14] ^ x[2], 16);
  24. x[3] += x[7]; x[15] = rol32(x[15] ^ x[3], 16);
  25. x[8] += x[12]; x[4] = rol32(x[4] ^ x[8], 12);
  26. x[9] += x[13]; x[5] = rol32(x[5] ^ x[9], 12);
  27. x[10] += x[14]; x[6] = rol32(x[6] ^ x[10], 12);
  28. x[11] += x[15]; x[7] = rol32(x[7] ^ x[11], 12);
  29. x[0] += x[4]; x[12] = rol32(x[12] ^ x[0], 8);
  30. x[1] += x[5]; x[13] = rol32(x[13] ^ x[1], 8);
  31. x[2] += x[6]; x[14] = rol32(x[14] ^ x[2], 8);
  32. x[3] += x[7]; x[15] = rol32(x[15] ^ x[3], 8);
  33. x[8] += x[12]; x[4] = rol32(x[4] ^ x[8], 7);
  34. x[9] += x[13]; x[5] = rol32(x[5] ^ x[9], 7);
  35. x[10] += x[14]; x[6] = rol32(x[6] ^ x[10], 7);
  36. x[11] += x[15]; x[7] = rol32(x[7] ^ x[11], 7);
  37. x[0] += x[5]; x[15] = rol32(x[15] ^ x[0], 16);
  38. x[1] += x[6]; x[12] = rol32(x[12] ^ x[1], 16);
  39. x[2] += x[7]; x[13] = rol32(x[13] ^ x[2], 16);
  40. x[3] += x[4]; x[14] = rol32(x[14] ^ x[3], 16);
  41. x[10] += x[15]; x[5] = rol32(x[5] ^ x[10], 12);
  42. x[11] += x[12]; x[6] = rol32(x[6] ^ x[11], 12);
  43. x[8] += x[13]; x[7] = rol32(x[7] ^ x[8], 12);
  44. x[9] += x[14]; x[4] = rol32(x[4] ^ x[9], 12);
  45. x[0] += x[5]; x[15] = rol32(x[15] ^ x[0], 8);
  46. x[1] += x[6]; x[12] = rol32(x[12] ^ x[1], 8);
  47. x[2] += x[7]; x[13] = rol32(x[13] ^ x[2], 8);
  48. x[3] += x[4]; x[14] = rol32(x[14] ^ x[3], 8);
  49. x[10] += x[15]; x[5] = rol32(x[5] ^ x[10], 7);
  50. x[11] += x[12]; x[6] = rol32(x[6] ^ x[11], 7);
  51. x[8] += x[13]; x[7] = rol32(x[7] ^ x[8], 7);
  52. x[9] += x[14]; x[4] = rol32(x[4] ^ x[9], 7);
  53. }
  54. }
  55. /**
  56. * chacha_block_generic - generate one keystream block and increment block counter
  57. * @state: input state matrix
  58. * @out: output keystream block
  59. * @nrounds: number of rounds (20 or 12; 20 is recommended)
  60. *
  61. * This is the ChaCha core, a function from 64-byte strings to 64-byte strings.
  62. * The caller has already converted the endianness of the input. This function
  63. * also handles incrementing the block counter in the input matrix.
  64. */
  65. void chacha_block_generic(struct chacha_state *state,
  66. u8 out[CHACHA_BLOCK_SIZE], int nrounds)
  67. {
  68. struct chacha_state permuted_state = *state;
  69. int i;
  70. chacha_permute(&permuted_state, nrounds);
  71. for (i = 0; i < ARRAY_SIZE(state->x); i++)
  72. put_unaligned_le32(permuted_state.x[i] + state->x[i],
  73. &out[i * sizeof(u32)]);
  74. state->x[12]++;
  75. chacha_zeroize_state(&permuted_state);
  76. }
  77. EXPORT_SYMBOL(chacha_block_generic);
  78. /**
  79. * hchacha_block_generic - abbreviated ChaCha core, for XChaCha
  80. * @state: input state matrix
  81. * @out: the output words
  82. * @nrounds: number of rounds (20 or 12; 20 is recommended)
  83. *
  84. * HChaCha is the ChaCha equivalent of HSalsa and is an intermediate step
  85. * towards XChaCha (see https://cr.yp.to/snuffle/xsalsa-20081128.pdf). HChaCha
  86. * skips the final addition of the initial state, and outputs only certain words
  87. * of the state. It should not be used for streaming directly.
  88. */
  89. void hchacha_block_generic(const struct chacha_state *state,
  90. u32 out[HCHACHA_OUT_WORDS], int nrounds)
  91. {
  92. struct chacha_state permuted_state = *state;
  93. chacha_permute(&permuted_state, nrounds);
  94. memcpy(&out[0], &permuted_state.x[0], 16);
  95. memcpy(&out[4], &permuted_state.x[12], 16);
  96. chacha_zeroize_state(&permuted_state);
  97. }
  98. EXPORT_SYMBOL(hchacha_block_generic);