Merge branch 'upstream' into tizen
[platform/upstream/nettle.git] / 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;
113             length -= buffer_size, src += buffer_size, dst += buffer_size)
114         {
115           f(ctx, buffer_size, buffer, src);
116           memcpy(initial_iv, iv, block_size);
117           memcpy(iv, src + buffer_size - block_size, block_size);
118           memxor3(dst + block_size, buffer + block_size, src,
119                   buffer_size - block_size);
120           memxor3(dst, buffer, initial_iv, block_size);
121         }
122
123       f(ctx, length, buffer, src);
124       memcpy(initial_iv, iv, block_size);
125       /* Copies last block */
126       memcpy(iv, src + length - block_size, block_size);
127       /* Writes all but first block, reads all but last block. */
128       memxor3(dst + block_size, buffer + block_size, src,
129               length - block_size);
130       /* Writes first block. */
131       memxor3(dst, buffer, initial_iv, block_size);
132     }
133 }
134
135 #if 0
136 #include "twofish.h"
137 #include "aes.h"
138
139 static void foo(void)
140 {
141   struct CBC_CTX(struct twofish_ctx, TWOFISH_BLOCK_SIZE) ctx;
142   uint8_t src[TWOFISH_BLOCK_SIZE];
143   uint8_t dst[TWOFISH_BLOCK_SIZE];
144   
145   CBC_ENCRYPT(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, dst, src);
146
147   /* Should result in a warning */
148   CBC_ENCRYPT(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, dst, src);
149   
150 }
151
152 static void foo2(void)
153 {
154   struct twofish_ctx ctx;
155   uint8_t iv[TWOFISH_BLOCK_SIZE];
156   uint8_t src[TWOFISH_BLOCK_SIZE];
157   uint8_t dst[TWOFISH_BLOCK_SIZE];
158   
159   CBC_ENCRYPT2(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src);
160   /* Should result in a warning */
161   CBC_ENCRYPT2(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src);
162 }
163
164 #endif