cfb8: Fix decrypt path
[gd/nettle] / cbc.c
1 /* cbc.c
2
3    Cipher block chaining mode.
4
5    Copyright (C) 2001, 2011 Niels Möller
6
7    This file is part of GNU Nettle.
8
9    GNU Nettle is free software: you can redistribute it and/or
10    modify it under the terms of either:
11
12      * the GNU Lesser General Public License as published by the Free
13        Software Foundation; either version 3 of the License, or (at your
14        option) any later version.
15
16    or
17
18      * the GNU General Public License as published by the Free
19        Software Foundation; either version 2 of the License, or (at your
20        option) any later version.
21
22    or both in parallel, as here.
23
24    GNU Nettle is distributed in the hope that it will be useful,
25    but WITHOUT ANY WARRANTY; without even the implied warranty of
26    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27    General Public License for more details.
28
29    You should have received copies of the GNU General Public License and
30    the GNU Lesser General Public License along with this program.  If
31    not, see http://www.gnu.org/licenses/.
32 */
33
34 #if HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <assert.h>
39 #include <stdlib.h>
40 #include <string.h>
41
42 #include "cbc.h"
43
44 #include "memxor.h"
45 #include "nettle-internal.h"
46
47 void
48 cbc_encrypt(const void *ctx, nettle_cipher_func *f,
49             size_t block_size, uint8_t *iv,
50             size_t length, uint8_t *dst,
51             const uint8_t *src)
52 {
53   assert(!(length % block_size));
54
55   for ( ; length; length -= block_size, src += block_size, dst += block_size)
56     {
57       memxor(iv, src, block_size);
58       f(ctx, block_size, dst, iv);
59       memcpy(iv, dst, block_size);
60     }
61 }
62
63 /* Don't allocate any more space than this on the stack */
64 #define CBC_BUFFER_LIMIT 512
65
66 void
67 cbc_decrypt(const void *ctx, nettle_cipher_func *f,
68             size_t block_size, uint8_t *iv,
69             size_t length, uint8_t *dst,
70             const uint8_t *src)
71 {
72   assert(!(length % block_size));
73
74   if (!length)
75     return;
76
77   if (src != dst)
78     {
79       /* Decrypt in ECB mode */
80       f(ctx, length, dst, src);
81
82       /* XOR the cryptotext, shifted one block */
83       memxor(dst, iv, block_size);
84       memxor(dst + block_size, src, length - block_size);
85       memcpy(iv, src + length - block_size, block_size);
86     }
87
88   else
89     {
90       /* For in-place CBC, we decrypt into a temporary buffer of size
91        * at most CBC_BUFFER_LIMIT, and process that amount of data at
92        * a time. */
93       
94       /* NOTE: We assume that block_size <= CBC_BUFFER_LIMIT, and we
95          depend on memxor3 working from the end of the area, allowing
96          certain overlapping operands. */ 
97
98       TMP_DECL(buffer, uint8_t, CBC_BUFFER_LIMIT);
99       TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
100
101       size_t buffer_size;
102
103       if (length <= CBC_BUFFER_LIMIT)
104         buffer_size = length;
105       else
106         buffer_size
107           = CBC_BUFFER_LIMIT - (CBC_BUFFER_LIMIT % block_size);
108
109       TMP_ALLOC(buffer, buffer_size);
110       TMP_ALLOC(initial_iv, block_size);
111
112       for ( ; length > buffer_size; length -= buffer_size, dst += buffer_size)
113         {
114           f(ctx, buffer_size, buffer, dst);
115           memcpy(initial_iv, iv, block_size);
116           memcpy(iv, dst + buffer_size - block_size, block_size);
117           memxor3(dst + block_size, buffer + block_size, dst,
118                   buffer_size - block_size);
119           memxor3(dst, buffer, initial_iv, block_size);
120         }
121
122       f(ctx, length, buffer, dst);
123       memcpy(initial_iv, iv, block_size);
124       /* Copies last block */
125       memcpy(iv, dst + length - block_size, block_size);
126       /* Writes all but first block, reads all but last block. */
127       memxor3(dst + block_size, buffer + block_size, dst,
128               length - block_size);
129       /* Writes first block. */
130       memxor3(dst, buffer, initial_iv, block_size);
131     }
132 }
133
134 #if 0
135 #include "twofish.h"
136 #include "aes.h"
137
138 static void foo(void)
139 {
140   struct CBC_CTX(struct twofish_ctx, TWOFISH_BLOCK_SIZE) ctx;
141   uint8_t src[TWOFISH_BLOCK_SIZE];
142   uint8_t dst[TWOFISH_BLOCK_SIZE];
143   
144   CBC_ENCRYPT(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, dst, src);
145
146   /* Should result in a warning */
147   CBC_ENCRYPT(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, dst, src);
148   
149 }
150
151 static void foo2(void)
152 {
153   struct twofish_ctx ctx;
154   uint8_t iv[TWOFISH_BLOCK_SIZE];
155   uint8_t src[TWOFISH_BLOCK_SIZE];
156   uint8_t dst[TWOFISH_BLOCK_SIZE];
157   
158   CBC_ENCRYPT2(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src);
159   /* Should result in a warning */
160   CBC_ENCRYPT2(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src);
161 }
162
163 #endif