Use shishi_time.
[shishi.git] / crypto / cbc.c
blobf28c9f21b5f158510f2fb3ece876938eb0746e0c
1 /* cbc.c
3 * Cipher block chaining mode.
4 */
6 /* nettle, low-level cryptographics library
8 * Copyright (C) 2001 Niels Möller
9 *
10 * The nettle library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or (at your
13 * option) any later version.
15 * The nettle library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with the nettle library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 * MA 02111-1307, USA.
26 #if HAVE_CONFIG_H
27 # include "config.h"
28 #endif
30 #include <assert.h>
31 #include <stdlib.h>
32 #include <string.h>
34 #include "cbc.h"
36 #include "memxor.h"
38 void
39 cbc_encrypt(void *ctx, void (*f)(void *ctx,
40 unsigned length, uint8_t *dst,
41 const uint8_t *src),
42 unsigned block_size, uint8_t *iv,
43 unsigned length, uint8_t *dst,
44 const uint8_t *src)
46 assert(!(length % block_size));
48 for ( ; length; length -= block_size, src += block_size, dst += block_size)
50 memxor(iv, src, block_size);
51 f(ctx, block_size, dst, iv);
52 memcpy(iv, dst, block_size);
56 /* Reqires that dst != src */
57 static void
58 cbc_decrypt_internal(void *ctx, void (*f)(void *ctx,
59 unsigned length, uint8_t *dst,
60 const uint8_t *src),
61 unsigned block_size, uint8_t *iv,
62 unsigned length, uint8_t *dst,
63 const uint8_t *src)
65 assert(length);
66 assert( !(length % block_size) );
67 assert(src != dst);
69 /* Decrypt in ECB mode */
70 f(ctx, length, dst, src);
72 /* XOR the cryptotext, shifted one block */
73 memxor(dst, iv, block_size);
74 memxor(dst + block_size, src, length - block_size);
75 memcpy(iv, src + length - block_size, block_size);
78 /* Don't allocate any more space than this on the stack */
79 #define CBC_BUFFER_LIMIT 4096
81 void
82 cbc_decrypt(void *ctx, void (*f)(void *ctx,
83 unsigned length, uint8_t *dst,
84 const uint8_t *src),
85 unsigned block_size, uint8_t *iv,
86 unsigned length, uint8_t *dst,
87 const uint8_t *src)
89 assert(!(length % block_size));
91 if (!length)
92 return;
94 if (src != dst)
95 cbc_decrypt_internal(ctx, f, block_size, iv,
96 length, dst, src);
97 else
99 /* We need a copy of the ciphertext, so we can't ECB decrypt in
100 * place.
102 * If length is small, we allocate a complete copy of src on the
103 * stack. Otherwise, we allocate a block of size at most
104 * CBC_BUFFER_LIMIT, and process that amount of data at a
105 * time.
107 * NOTE: We assume that block_size <= CBC_BUFFER_LIMIT. */
109 uint8_t *buffer;
111 if (length <= CBC_BUFFER_LIMIT)
112 buffer = alloca(length);
113 else
115 /* The buffer size must be an integral number of blocks. */
116 unsigned buffer_size
117 = CBC_BUFFER_LIMIT - (CBC_BUFFER_LIMIT % block_size);
119 buffer = alloca(buffer_size);
121 for ( ; length >= buffer_size;
122 length -= buffer_size, dst += buffer_size, src += buffer_size)
124 memcpy(buffer, src, buffer_size);
125 cbc_decrypt_internal(ctx, f, block_size, iv,
126 buffer_size, dst, buffer);
128 if (!length)
129 return;
131 /* Now, we have at most CBC_BUFFER_LIMIT octets left */
132 memcpy(buffer, src, length);
134 cbc_decrypt_internal(ctx, f, block_size, iv,
135 length, dst, buffer);
139 #if 0
140 #include "twofish.h"
141 #include "aes.h"
143 static void foo(void)
145 struct CBC_CTX(struct twofish_ctx, TWOFISH_BLOCK_SIZE) ctx;
146 uint8_t src[TWOFISH_BLOCK_SIZE];
147 uint8_t dst[TWOFISH_BLOCK_SIZE];
149 CBC_ENCRYPT(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, dst, src);
151 /* Should result in a warning */
152 CBC_ENCRYPT(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, dst, src);
156 static void foo2(void)
158 struct twofish_ctx ctx;
159 uint8_t iv[TWOFISH_BLOCK_SIZE];
160 uint8_t src[TWOFISH_BLOCK_SIZE];
161 uint8_t dst[TWOFISH_BLOCK_SIZE];
163 CBC_ENCRYPT2(&ctx, twofish_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src);
164 /* Should result in a warning */
165 CBC_ENCRYPT2(&ctx, aes_encrypt, TWOFISH_BLOCK_SIZE, iv, TWOFISH_BLOCK_SIZE, dst, src);
168 #endif