ctr128.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /* ====================================================================
  2. * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in
  13. * the documentation and/or other materials provided with the
  14. * distribution.
  15. *
  16. * 3. All advertising materials mentioning features or use of this
  17. * software must display the following acknowledgment:
  18. * "This product includes software developed by the OpenSSL Project
  19. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  20. *
  21. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  22. * endorse or promote products derived from this software without
  23. * prior written permission. For written permission, please contact
  24. * openssl-core@openssl.org.
  25. *
  26. * 5. Products derived from this software may not be called "OpenSSL"
  27. * nor may "OpenSSL" appear in their names without prior written
  28. * permission of the OpenSSL Project.
  29. *
  30. * 6. Redistributions of any form whatsoever must retain the following
  31. * acknowledgment:
  32. * "This product includes software developed by the OpenSSL Project
  33. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  34. *
  35. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  36. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  38. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  41. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  43. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  44. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  45. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  46. * OF THE POSSIBILITY OF SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. */
  50. #include <openssl/crypto.h>
  51. #include "modes_lcl.h"
  52. #include <string.h>
  53. #ifndef MODES_DEBUG
  54. # ifndef NDEBUG
  55. # define NDEBUG
  56. # endif
  57. #endif
  58. #include <assert.h>
  59. /*
  60. * NOTE: the IV/counter CTR mode is big-endian. The code itself is
  61. * endian-neutral.
  62. */
  63. /* increment counter (128-bit int) by 1 */
  64. static void ctr128_inc(unsigned char *counter)
  65. {
  66. u32 n = 16, c = 1;
  67. do {
  68. --n;
  69. c += counter[n];
  70. counter[n] = (u8)c;
  71. c >>= 8;
  72. } while (n);
  73. }
  74. #if !defined(OPENSSL_SMALL_FOOTPRINT)
  75. static void ctr128_inc_aligned(unsigned char *counter)
  76. {
  77. size_t *data, c, d, n;
  78. const union {
  79. long one;
  80. char little;
  81. } is_endian = {
  82. 1
  83. };
  84. if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) {
  85. ctr128_inc(counter);
  86. return;
  87. }
  88. data = (size_t *)counter;
  89. c = 1;
  90. n = 16 / sizeof(size_t);
  91. do {
  92. --n;
  93. d = data[n] += c;
  94. /* did addition carry? */
  95. c = ((d - c) ^ d) >> (sizeof(size_t) * 8 - 1);
  96. } while (n);
  97. }
  98. #endif
  99. /*
  100. * The input encrypted as though 128bit counter mode is being used. The
  101. * extra state information to record how much of the 128bit block we have
  102. * used is contained in *num, and the encrypted counter is kept in
  103. * ecount_buf. Both *num and ecount_buf must be initialised with zeros
  104. * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes
  105. * that the counter is in the x lower bits of the IV (ivec), and that the
  106. * application has full control over overflow and the rest of the IV. This
  107. * implementation takes NO responsability for checking that the counter
  108. * doesn't overflow into the rest of the IV when incremented.
  109. */
  110. void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
  111. size_t len, const void *key,
  112. unsigned char ivec[16],
  113. unsigned char ecount_buf[16], unsigned int *num,
  114. block128_f block)
  115. {
  116. unsigned int n;
  117. size_t l = 0;
  118. assert(in && out && key && ecount_buf && num);
  119. assert(*num < 16);
  120. n = *num;
  121. #if !defined(OPENSSL_SMALL_FOOTPRINT)
  122. if (16 % sizeof(size_t) == 0) { /* always true actually */
  123. do {
  124. while (n && len) {
  125. *(out++) = *(in++) ^ ecount_buf[n];
  126. --len;
  127. n = (n + 1) % 16;
  128. }
  129. # if defined(STRICT_ALIGNMENT)
  130. if (((size_t)in | (size_t)out | (size_t)ecount_buf)
  131. % sizeof(size_t) != 0)
  132. break;
  133. # endif
  134. while (len >= 16) {
  135. (*block) (ivec, ecount_buf, key);
  136. ctr128_inc_aligned(ivec);
  137. for (n = 0; n < 16; n += sizeof(size_t))
  138. *(size_t *)(out + n) =
  139. *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
  140. len -= 16;
  141. out += 16;
  142. in += 16;
  143. n = 0;
  144. }
  145. if (len) {
  146. (*block) (ivec, ecount_buf, key);
  147. ctr128_inc_aligned(ivec);
  148. while (len--) {
  149. out[n] = in[n] ^ ecount_buf[n];
  150. ++n;
  151. }
  152. }
  153. *num = n;
  154. return;
  155. } while (0);
  156. }
  157. /* the rest would be commonly eliminated by x86* compiler */
  158. #endif
  159. while (l < len) {
  160. if (n == 0) {
  161. (*block) (ivec, ecount_buf, key);
  162. ctr128_inc(ivec);
  163. }
  164. out[l] = in[l] ^ ecount_buf[n];
  165. ++l;
  166. n = (n + 1) % 16;
  167. }
  168. *num = n;
  169. }
  170. /* increment upper 96 bits of 128-bit counter by 1 */
  171. static void ctr96_inc(unsigned char *counter)
  172. {
  173. u32 n = 12, c = 1;
  174. do {
  175. --n;
  176. c += counter[n];
  177. counter[n] = (u8)c;
  178. c >>= 8;
  179. } while (n);
  180. }
  181. void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
  182. size_t len, const void *key,
  183. unsigned char ivec[16],
  184. unsigned char ecount_buf[16],
  185. unsigned int *num, ctr128_f func)
  186. {
  187. unsigned int n, ctr32;
  188. assert(in && out && key && ecount_buf && num);
  189. assert(*num < 16);
  190. n = *num;
  191. while (n && len) {
  192. *(out++) = *(in++) ^ ecount_buf[n];
  193. --len;
  194. n = (n + 1) % 16;
  195. }
  196. ctr32 = GETU32(ivec + 12);
  197. while (len >= 16) {
  198. size_t blocks = len / 16;
  199. /*
  200. * 1<<28 is just a not-so-small yet not-so-large number...
  201. * Below condition is practically never met, but it has to
  202. * be checked for code correctness.
  203. */
  204. if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28))
  205. blocks = (1U << 28);
  206. /*
  207. * As (*func) operates on 32-bit counter, caller
  208. * has to handle overflow. 'if' below detects the
  209. * overflow, which is then handled by limiting the
  210. * amount of blocks to the exact overflow point...
  211. */
  212. ctr32 += (u32)blocks;
  213. if (ctr32 < blocks) {
  214. blocks -= ctr32;
  215. ctr32 = 0;
  216. }
  217. (*func) (in, out, blocks, key, ivec);
  218. /* (*ctr) does not update ivec, caller does: */
  219. PUTU32(ivec + 12, ctr32);
  220. /* ... overflow was detected, propogate carry. */
  221. if (ctr32 == 0)
  222. ctr96_inc(ivec);
  223. blocks *= 16;
  224. len -= blocks;
  225. out += blocks;
  226. in += blocks;
  227. }
  228. if (len) {
  229. memset(ecount_buf, 0, 16);
  230. (*func) (ecount_buf, ecount_buf, 1, key, ivec);
  231. ++ctr32;
  232. PUTU32(ivec + 12, ctr32);
  233. if (ctr32 == 0)
  234. ctr96_inc(ivec);
  235. while (len--) {
  236. out[n] = in[n] ^ ecount_buf[n];
  237. ++n;
  238. }
  239. }
  240. *num = n;
  241. }