ctr128.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright 2008-2020 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. #include <openssl/crypto.h>
  10. #include "modes_local.h"
  11. #include <string.h>
  12. #if defined(__GNUC__) && !defined(STRICT_ALIGNMENT)
  13. typedef size_t size_t_aX __attribute((__aligned__(1)));
  14. #else
  15. typedef size_t size_t_aX;
  16. #endif
  17. /*
  18. * NOTE: the IV/counter CTR mode is big-endian. The code itself is
  19. * endian-neutral.
  20. */
  21. /* increment counter (128-bit int) by 1 */
  22. static void ctr128_inc(unsigned char *counter)
  23. {
  24. u32 n = 16, c = 1;
  25. do {
  26. --n;
  27. c += counter[n];
  28. counter[n] = (u8)c;
  29. c >>= 8;
  30. } while (n);
  31. }
  32. #if !defined(OPENSSL_SMALL_FOOTPRINT)
  33. static void ctr128_inc_aligned(unsigned char *counter)
  34. {
  35. size_t *data, c, d, n;
  36. const union {
  37. long one;
  38. char little;
  39. } is_endian = {
  40. 1
  41. };
  42. if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) {
  43. ctr128_inc(counter);
  44. return;
  45. }
  46. data = (size_t *)counter;
  47. c = 1;
  48. n = 16 / sizeof(size_t);
  49. do {
  50. --n;
  51. d = data[n] += c;
  52. /* did addition carry? */
  53. c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1);
  54. } while (n);
  55. }
  56. #endif
  57. /*
  58. * The input encrypted as though 128bit counter mode is being used. The
  59. * extra state information to record how much of the 128bit block we have
  60. * used is contained in *num, and the encrypted counter is kept in
  61. * ecount_buf. Both *num and ecount_buf must be initialised with zeros
  62. * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes
  63. * that the counter is in the x lower bits of the IV (ivec), and that the
  64. * application has full control over overflow and the rest of the IV. This
  65. * implementation takes NO responsibility for checking that the counter
  66. * doesn't overflow into the rest of the IV when incremented.
  67. */
  68. void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
  69. size_t len, const void *key,
  70. unsigned char ivec[16],
  71. unsigned char ecount_buf[16], unsigned int *num,
  72. block128_f block)
  73. {
  74. unsigned int n;
  75. size_t l = 0;
  76. n = *num;
  77. #if !defined(OPENSSL_SMALL_FOOTPRINT)
  78. if (16 % sizeof(size_t) == 0) { /* always true actually */
  79. do {
  80. while (n && len) {
  81. *(out++) = *(in++) ^ ecount_buf[n];
  82. --len;
  83. n = (n + 1) % 16;
  84. }
  85. # if defined(STRICT_ALIGNMENT)
  86. if (((size_t)in | (size_t)out | (size_t)ecount_buf)
  87. % sizeof(size_t) != 0)
  88. break;
  89. # endif
  90. while (len >= 16) {
  91. (*block) (ivec, ecount_buf, key);
  92. ctr128_inc_aligned(ivec);
  93. for (n = 0; n < 16; n += sizeof(size_t))
  94. *(size_t_aX *)(out + n) =
  95. *(size_t_aX *)(in + n)
  96. ^ *(size_t_aX *)(ecount_buf + n);
  97. len -= 16;
  98. out += 16;
  99. in += 16;
  100. n = 0;
  101. }
  102. if (len) {
  103. (*block) (ivec, ecount_buf, key);
  104. ctr128_inc_aligned(ivec);
  105. while (len--) {
  106. out[n] = in[n] ^ ecount_buf[n];
  107. ++n;
  108. }
  109. }
  110. *num = n;
  111. return;
  112. } while (0);
  113. }
  114. /* the rest would be commonly eliminated by x86* compiler */
  115. #endif
  116. while (l < len) {
  117. if (n == 0) {
  118. (*block) (ivec, ecount_buf, key);
  119. ctr128_inc(ivec);
  120. }
  121. out[l] = in[l] ^ ecount_buf[n];
  122. ++l;
  123. n = (n + 1) % 16;
  124. }
  125. *num = n;
  126. }
  127. /* increment upper 96 bits of 128-bit counter by 1 */
  128. static void ctr96_inc(unsigned char *counter)
  129. {
  130. u32 n = 12, c = 1;
  131. do {
  132. --n;
  133. c += counter[n];
  134. counter[n] = (u8)c;
  135. c >>= 8;
  136. } while (n);
  137. }
  138. void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
  139. size_t len, const void *key,
  140. unsigned char ivec[16],
  141. unsigned char ecount_buf[16],
  142. unsigned int *num, ctr128_f func)
  143. {
  144. unsigned int n, ctr32;
  145. n = *num;
  146. while (n && len) {
  147. *(out++) = *(in++) ^ ecount_buf[n];
  148. --len;
  149. n = (n + 1) % 16;
  150. }
  151. ctr32 = GETU32(ivec + 12);
  152. while (len >= 16) {
  153. size_t blocks = len / 16;
  154. /*
  155. * 1<<28 is just a not-so-small yet not-so-large number...
  156. * Below condition is practically never met, but it has to
  157. * be checked for code correctness.
  158. */
  159. if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28))
  160. blocks = (1U << 28);
  161. /*
  162. * As (*func) operates on 32-bit counter, caller
  163. * has to handle overflow. 'if' below detects the
  164. * overflow, which is then handled by limiting the
  165. * amount of blocks to the exact overflow point...
  166. */
  167. ctr32 += (u32)blocks;
  168. if (ctr32 < blocks) {
  169. blocks -= ctr32;
  170. ctr32 = 0;
  171. }
  172. (*func) (in, out, blocks, key, ivec);
  173. /* (*ctr) does not update ivec, caller does: */
  174. PUTU32(ivec + 12, ctr32);
  175. /* ... overflow was detected, propagate carry. */
  176. if (ctr32 == 0)
  177. ctr96_inc(ivec);
  178. blocks *= 16;
  179. len -= blocks;
  180. out += blocks;
  181. in += blocks;
  182. }
  183. if (len) {
  184. memset(ecount_buf, 0, 16);
  185. (*func) (ecount_buf, ecount_buf, 1, key, ivec);
  186. ++ctr32;
  187. PUTU32(ivec + 12, ctr32);
  188. if (ctr32 == 0)
  189. ctr96_inc(ivec);
  190. while (len--) {
  191. out[n] = in[n] ^ ecount_buf[n];
  192. ++n;
  193. }
  194. }
  195. *num = n;
  196. }