2
0

chacha_enc.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /* Adapted from the public domain code by D. Bernstein from SUPERCOP. */
  10. #include <string.h>
  11. #include "crypto/chacha.h"
  12. #include "crypto/ctype.h"
  13. typedef unsigned int u32;
  14. typedef unsigned char u8;
  15. typedef union {
  16. u32 u[16];
  17. u8 c[64];
  18. } chacha_buf;
  19. # define ROTATE(v, n) (((v) << (n)) | ((v) >> (32 - (n))))
  20. # define U32TO8_LITTLE(p, v) do { \
  21. (p)[0] = (u8)(v >> 0); \
  22. (p)[1] = (u8)(v >> 8); \
  23. (p)[2] = (u8)(v >> 16); \
  24. (p)[3] = (u8)(v >> 24); \
  25. } while(0)
  26. /* QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. */
  27. # define QUARTERROUND(a,b,c,d) ( \
  28. x[a] += x[b], x[d] = ROTATE((x[d] ^ x[a]),16), \
  29. x[c] += x[d], x[b] = ROTATE((x[b] ^ x[c]),12), \
  30. x[a] += x[b], x[d] = ROTATE((x[d] ^ x[a]), 8), \
  31. x[c] += x[d], x[b] = ROTATE((x[b] ^ x[c]), 7) )
  32. /* chacha_core performs 20 rounds of ChaCha on the input words in
  33. * |input| and writes the 64 output bytes to |output|. */
  34. static void chacha20_core(chacha_buf *output, const u32 input[16])
  35. {
  36. u32 x[16];
  37. int i;
  38. const union {
  39. long one;
  40. char little;
  41. } is_endian = { 1 };
  42. memcpy(x, input, sizeof(x));
  43. for (i = 20; i > 0; i -= 2) {
  44. QUARTERROUND(0, 4, 8, 12);
  45. QUARTERROUND(1, 5, 9, 13);
  46. QUARTERROUND(2, 6, 10, 14);
  47. QUARTERROUND(3, 7, 11, 15);
  48. QUARTERROUND(0, 5, 10, 15);
  49. QUARTERROUND(1, 6, 11, 12);
  50. QUARTERROUND(2, 7, 8, 13);
  51. QUARTERROUND(3, 4, 9, 14);
  52. }
  53. if (is_endian.little) {
  54. for (i = 0; i < 16; ++i)
  55. output->u[i] = x[i] + input[i];
  56. } else {
  57. for (i = 0; i < 16; ++i)
  58. U32TO8_LITTLE(output->c + 4 * i, (x[i] + input[i]));
  59. }
  60. }
  61. void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
  62. size_t len, const unsigned int key[8],
  63. const unsigned int counter[4])
  64. {
  65. u32 input[16];
  66. chacha_buf buf;
  67. size_t todo, i;
  68. /* sigma constant "expand 32-byte k" in little-endian encoding */
  69. input[0] = ((u32)ossl_toascii('e')) | ((u32)ossl_toascii('x') << 8)
  70. | ((u32)ossl_toascii('p') << 16)
  71. | ((u32)ossl_toascii('a') << 24);
  72. input[1] = ((u32)ossl_toascii('n')) | ((u32)ossl_toascii('d') << 8)
  73. | ((u32)ossl_toascii(' ') << 16)
  74. | ((u32)ossl_toascii('3') << 24);
  75. input[2] = ((u32)ossl_toascii('2')) | ((u32)ossl_toascii('-') << 8)
  76. | ((u32)ossl_toascii('b') << 16)
  77. | ((u32)ossl_toascii('y') << 24);
  78. input[3] = ((u32)ossl_toascii('t')) | ((u32)ossl_toascii('e') << 8)
  79. | ((u32)ossl_toascii(' ') << 16)
  80. | ((u32)ossl_toascii('k') << 24);
  81. input[4] = key[0];
  82. input[5] = key[1];
  83. input[6] = key[2];
  84. input[7] = key[3];
  85. input[8] = key[4];
  86. input[9] = key[5];
  87. input[10] = key[6];
  88. input[11] = key[7];
  89. input[12] = counter[0];
  90. input[13] = counter[1];
  91. input[14] = counter[2];
  92. input[15] = counter[3];
  93. while (len > 0) {
  94. todo = sizeof(buf);
  95. if (len < todo)
  96. todo = len;
  97. chacha20_core(&buf, input);
  98. for (i = 0; i < todo; i++)
  99. out[i] = inp[i] ^ buf.c[i];
  100. out += todo;
  101. inp += todo;
  102. len -= todo;
  103. /*
  104. * Advance 32-bit counter. Note that as subroutine is so to
  105. * say nonce-agnostic, this limited counter width doesn't
  106. * prevent caller from implementing wider counter. It would
  107. * simply take two calls split on counter overflow...
  108. */
  109. input[12]++;
  110. }
  111. }