1 /* crypto/camellia/camellia_cbc.c -*- mode:C; c-file-style: "eay" -*- */
2 /* ====================================================================
3 * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
31 * 6. Redistributions of any form whatsoever must retain the following
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
52 #ifndef CAMELLIA_DEBUG
61 #include <openssl/camellia.h>
62 #include "cmll_locl.h"
64 void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out,
65 const unsigned long length, const CAMELLIA_KEY *key,
66 unsigned char *ivec, const int enc) {
69 unsigned long len = length;
70 unsigned char tmp[CAMELLIA_BLOCK_SIZE];
71 const unsigned char *iv = ivec;
73 const union { long one; char little; } camellia_endian = {1};
76 assert(in && out && key && ivec);
77 assert((CAMELLIA_ENCRYPT == enc)||(CAMELLIA_DECRYPT == enc));
79 if(((size_t)in) % ALIGN == 0
80 && ((size_t)out) % ALIGN == 0
81 && ((size_t)ivec) % ALIGN == 0)
83 if (CAMELLIA_ENCRYPT == enc)
85 while (len >= CAMELLIA_BLOCK_SIZE)
88 (u32 *)in, (u32 *)iv);
89 if (camellia_endian.little)
90 SWAP4WORD((u32 *)out);
91 key->enc(key->rd_key, (u32 *)out);
92 if (camellia_endian.little)
93 SWAP4WORD((u32 *)out);
95 len -= CAMELLIA_BLOCK_SIZE;
96 in += CAMELLIA_BLOCK_SIZE;
97 out += CAMELLIA_BLOCK_SIZE;
101 for(n=0; n < len; ++n)
102 out[n] = in[n] ^ iv[n];
103 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
105 if (camellia_endian.little)
106 SWAP4WORD((u32 *)out);
107 key->enc(key->rd_key, (u32 *)out);
108 if (camellia_endian.little)
109 SWAP4WORD((u32 *)out);
112 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
116 while (len >= CAMELLIA_BLOCK_SIZE)
118 memcpy(out,in,CAMELLIA_BLOCK_SIZE);
119 if (camellia_endian.little)
120 SWAP4WORD((u32 *)out);
121 key->dec(key->rd_key,(u32 *)out);
122 if (camellia_endian.little)
123 SWAP4WORD((u32 *)out);
124 XOR4WORD((u32 *)out, (u32 *)iv);
126 len -= CAMELLIA_BLOCK_SIZE;
127 in += CAMELLIA_BLOCK_SIZE;
128 out += CAMELLIA_BLOCK_SIZE;
132 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
133 if (camellia_endian.little)
134 SWAP4WORD((u32 *)tmp);
135 key->dec(key->rd_key, (u32 *)tmp);
136 if (camellia_endian.little)
137 SWAP4WORD((u32 *)tmp);
138 for(n=0; n < len; ++n)
139 out[n] = tmp[n] ^ iv[n];
142 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
146 while (len >= CAMELLIA_BLOCK_SIZE)
148 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
149 if (camellia_endian.little)
150 SWAP4WORD((u32 *)out);
151 key->dec(key->rd_key, (u32 *)out);
152 if (camellia_endian.little)
153 SWAP4WORD((u32 *)out);
154 XOR4WORD((u32 *)out, (u32 *)ivec);
155 memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
156 len -= CAMELLIA_BLOCK_SIZE;
157 in += CAMELLIA_BLOCK_SIZE;
158 out += CAMELLIA_BLOCK_SIZE;
162 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
163 if (camellia_endian.little)
164 SWAP4WORD((u32 *)out);
165 key->dec(key->rd_key,(u32 *)out);
166 if (camellia_endian.little)
167 SWAP4WORD((u32 *)out);
168 for(n=0; n < len; ++n)
170 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
172 memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
176 else /* no aligned */
178 if (CAMELLIA_ENCRYPT == enc)
180 while (len >= CAMELLIA_BLOCK_SIZE)
182 for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
183 out[n] = in[n] ^ iv[n];
184 memcpy(t32, out, CAMELLIA_BLOCK_SIZE);
185 if (camellia_endian.little)
187 key->enc(key->rd_key, t32);
188 if (camellia_endian.little)
190 memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
192 len -= CAMELLIA_BLOCK_SIZE;
193 in += CAMELLIA_BLOCK_SIZE;
194 out += CAMELLIA_BLOCK_SIZE;
198 for(n=0; n < len; ++n)
199 out[n] = in[n] ^ iv[n];
200 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
202 if (camellia_endian.little)
203 SWAP4WORD((u32 *)out);
204 key->enc(key->rd_key, (u32 *)out);
205 if (camellia_endian.little)
206 SWAP4WORD((u32 *)out);
209 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
213 while (len >= CAMELLIA_BLOCK_SIZE)
215 memcpy(t32,in,CAMELLIA_BLOCK_SIZE);
216 if (camellia_endian.little)
218 key->dec(key->rd_key,t32);
219 if (camellia_endian.little)
221 memcpy(out,t32,CAMELLIA_BLOCK_SIZE);
222 for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
225 len -= CAMELLIA_BLOCK_SIZE;
226 in += CAMELLIA_BLOCK_SIZE;
227 out += CAMELLIA_BLOCK_SIZE;
231 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
232 memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
233 if (camellia_endian.little)
235 key->dec(key->rd_key, t32);
236 if (camellia_endian.little)
238 memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
239 for(n=0; n < len; ++n)
240 out[n] = tmp[n] ^ iv[n];
243 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
247 while (len >= CAMELLIA_BLOCK_SIZE)
249 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
250 memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
251 if (camellia_endian.little)
253 key->dec(key->rd_key, t32);
254 if (camellia_endian.little)
256 memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
257 for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
259 memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
260 len -= CAMELLIA_BLOCK_SIZE;
261 in += CAMELLIA_BLOCK_SIZE;
262 out += CAMELLIA_BLOCK_SIZE;
266 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
267 memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
268 if (camellia_endian.little)
270 key->dec(key->rd_key,t32);
271 if (camellia_endian.little)
273 memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
274 for(n=0; n < len; ++n)
276 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
278 memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);