5bdbbcf764ea2288cb4e762927be50da242cecb3
[openssl.git] / crypto / modes / ctr128.c
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
51 #include <openssl/crypto.h>
52 #include "modes_lcl.h"
53 #include <string.h>
54
55 /*
56  * NOTE: the IV/counter CTR mode is big-endian.  The code itself is
57  * endian-neutral.
58  */
59
60 /* increment counter (128-bit int) by 1 */
61 static void ctr128_inc(unsigned char *counter)
62 {
63     u32 n = 16, c = 1;
64
65     do {
66         --n;
67         c += counter[n];
68         counter[n] = (u8)c;
69         c >>= 8;
70     } while (n);
71 }
72
73 #if !defined(OPENSSL_SMALL_FOOTPRINT)
74 static void ctr128_inc_aligned(unsigned char *counter)
75 {
76     size_t *data, c, d, n;
77     const union {
78         long one;
79         char little;
80     } is_endian = {
81         1
82     };
83
84     if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) {
85         ctr128_inc(counter);
86         return;
87     }
88
89     data = (size_t *)counter;
90     c = 1;
91     n = 16 / sizeof(size_t);
92     do {
93         --n;
94         d = data[n] += c;
95         /* did addition carry? */
96         c = ((d - c) ^ d) >> (sizeof(size_t) * 8 - 1);
97     } while (n);
98 }
99 #endif
100
101 /*
102  * The input encrypted as though 128bit counter mode is being used.  The
103  * extra state information to record how much of the 128bit block we have
104  * used is contained in *num, and the encrypted counter is kept in
105  * ecount_buf.  Both *num and ecount_buf must be initialised with zeros
106  * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes
107  * that the counter is in the x lower bits of the IV (ivec), and that the
108  * application has full control over overflow and the rest of the IV.  This
109  * implementation takes NO responsibility for checking that the counter
110  * doesn't overflow into the rest of the IV when incremented.
111  */
112 void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out,
113                            size_t len, const void *key,
114                            unsigned char ivec[16],
115                            unsigned char ecount_buf[16], unsigned int *num,
116                            block128_f block)
117 {
118     unsigned int n;
119     size_t l = 0;
120
121     n = *num;
122
123 #if !defined(OPENSSL_SMALL_FOOTPRINT)
124     if (16 % sizeof(size_t) == 0) { /* always true actually */
125         do {
126             while (n && len) {
127                 *(out++) = *(in++) ^ ecount_buf[n];
128                 --len;
129                 n = (n + 1) % 16;
130             }
131
132 # if defined(STRICT_ALIGNMENT)
133             if (((size_t)in | (size_t)out | (size_t)ecount_buf)
134                 % sizeof(size_t) != 0)
135                 break;
136 # endif
137             while (len >= 16) {
138                 (*block) (ivec, ecount_buf, key);
139                 ctr128_inc_aligned(ivec);
140                 for (n = 0; n < 16; n += sizeof(size_t))
141                     *(size_t *)(out + n) =
142                         *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n);
143                 len -= 16;
144                 out += 16;
145                 in += 16;
146                 n = 0;
147             }
148             if (len) {
149                 (*block) (ivec, ecount_buf, key);
150                 ctr128_inc_aligned(ivec);
151                 while (len--) {
152                     out[n] = in[n] ^ ecount_buf[n];
153                     ++n;
154                 }
155             }
156             *num = n;
157             return;
158         } while (0);
159     }
160     /* the rest would be commonly eliminated by x86* compiler */
161 #endif
162     while (l < len) {
163         if (n == 0) {
164             (*block) (ivec, ecount_buf, key);
165             ctr128_inc(ivec);
166         }
167         out[l] = in[l] ^ ecount_buf[n];
168         ++l;
169         n = (n + 1) % 16;
170     }
171
172     *num = n;
173 }
174
175 /* increment upper 96 bits of 128-bit counter by 1 */
176 static void ctr96_inc(unsigned char *counter)
177 {
178     u32 n = 12, c = 1;
179
180     do {
181         --n;
182         c += counter[n];
183         counter[n] = (u8)c;
184         c >>= 8;
185     } while (n);
186 }
187
188 void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out,
189                                  size_t len, const void *key,
190                                  unsigned char ivec[16],
191                                  unsigned char ecount_buf[16],
192                                  unsigned int *num, ctr128_f func)
193 {
194     unsigned int n, ctr32;
195
196     n = *num;
197
198     while (n && len) {
199         *(out++) = *(in++) ^ ecount_buf[n];
200         --len;
201         n = (n + 1) % 16;
202     }
203
204     ctr32 = GETU32(ivec + 12);
205     while (len >= 16) {
206         size_t blocks = len / 16;
207         /*
208          * 1<<28 is just a not-so-small yet not-so-large number...
209          * Below condition is practically never met, but it has to
210          * be checked for code correctness.
211          */
212         if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28))
213             blocks = (1U << 28);
214         /*
215          * As (*func) operates on 32-bit counter, caller
216          * has to handle overflow. 'if' below detects the
217          * overflow, which is then handled by limiting the
218          * amount of blocks to the exact overflow point...
219          */
220         ctr32 += (u32)blocks;
221         if (ctr32 < blocks) {
222             blocks -= ctr32;
223             ctr32 = 0;
224         }
225         (*func) (in, out, blocks, key, ivec);
226         /* (*ctr) does not update ivec, caller does: */
227         PUTU32(ivec + 12, ctr32);
228         /* ... overflow was detected, propagate carry. */
229         if (ctr32 == 0)
230             ctr96_inc(ivec);
231         blocks *= 16;
232         len -= blocks;
233         out += blocks;
234         in += blocks;
235     }
236     if (len) {
237         memset(ecount_buf, 0, 16);
238         (*func) (ecount_buf, ecount_buf, 1, key, ivec);
239         ++ctr32;
240         PUTU32(ivec + 12, ctr32);
241         if (ctr32 == 0)
242             ctr96_inc(ivec);
243         while (len--) {
244             out[n] = in[n] ^ ecount_buf[n];
245             ++n;
246         }
247     }
248
249     *num = n;
250 }