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