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;
72 u32 t32[CAMELLIA_BLOCK_SIZE/sizeof(u32)];
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|(size_t)out|(size_t)ivec) % sizeof(u32) == 0)
81 if (CAMELLIA_ENCRYPT == enc)
83 while (len >= CAMELLIA_BLOCK_SIZE)
86 (u32 *)in, (u32 *)iv);
87 if (camellia_endian.little)
88 SWAP4WORD((u32 *)out);
89 key->enc(key->rd_key, (u32 *)out);
90 if (camellia_endian.little)
91 SWAP4WORD((u32 *)out);
93 len -= CAMELLIA_BLOCK_SIZE;
94 in += CAMELLIA_BLOCK_SIZE;
95 out += CAMELLIA_BLOCK_SIZE;
99 for(n=0; n < len; ++n)
100 out[n] = in[n] ^ iv[n];
101 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
103 if (camellia_endian.little)
104 SWAP4WORD((u32 *)out);
105 key->enc(key->rd_key, (u32 *)out);
106 if (camellia_endian.little)
107 SWAP4WORD((u32 *)out);
110 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
114 while (len >= CAMELLIA_BLOCK_SIZE)
116 memcpy(out,in,CAMELLIA_BLOCK_SIZE);
117 if (camellia_endian.little)
118 SWAP4WORD((u32 *)out);
119 key->dec(key->rd_key,(u32 *)out);
120 if (camellia_endian.little)
121 SWAP4WORD((u32 *)out);
122 XOR4WORD((u32 *)out, (u32 *)iv);
124 len -= CAMELLIA_BLOCK_SIZE;
125 in += CAMELLIA_BLOCK_SIZE;
126 out += CAMELLIA_BLOCK_SIZE;
130 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
131 if (camellia_endian.little)
132 SWAP4WORD((u32 *)tmp);
133 key->dec(key->rd_key, (u32 *)tmp);
134 if (camellia_endian.little)
135 SWAP4WORD((u32 *)tmp);
136 for(n=0; n < len; ++n)
137 out[n] = tmp[n] ^ iv[n];
140 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
144 while (len >= CAMELLIA_BLOCK_SIZE)
146 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
147 if (camellia_endian.little)
148 SWAP4WORD((u32 *)out);
149 key->dec(key->rd_key, (u32 *)out);
150 if (camellia_endian.little)
151 SWAP4WORD((u32 *)out);
152 XOR4WORD((u32 *)out, (u32 *)ivec);
153 memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
154 len -= CAMELLIA_BLOCK_SIZE;
155 in += CAMELLIA_BLOCK_SIZE;
156 out += CAMELLIA_BLOCK_SIZE;
160 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
161 if (camellia_endian.little)
162 SWAP4WORD((u32 *)out);
163 key->dec(key->rd_key,(u32 *)out);
164 if (camellia_endian.little)
165 SWAP4WORD((u32 *)out);
166 for(n=0; n < len; ++n)
168 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
170 memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
174 else /* no aligned */
176 if (CAMELLIA_ENCRYPT == enc)
178 while (len >= CAMELLIA_BLOCK_SIZE)
180 for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
181 out[n] = in[n] ^ iv[n];
182 memcpy(t32, out, CAMELLIA_BLOCK_SIZE);
183 if (camellia_endian.little)
185 key->enc(key->rd_key, t32);
186 if (camellia_endian.little)
188 memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
190 len -= CAMELLIA_BLOCK_SIZE;
191 in += CAMELLIA_BLOCK_SIZE;
192 out += CAMELLIA_BLOCK_SIZE;
196 for(n=0; n < len; ++n)
197 out[n] = in[n] ^ iv[n];
198 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
200 memcpy(t32, out, CAMELLIA_BLOCK_SIZE);
201 if (camellia_endian.little)
203 key->enc(key->rd_key, t32);
204 if (camellia_endian.little)
206 memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
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(t32, in, CAMELLIA_BLOCK_SIZE);
232 if (camellia_endian.little)
234 key->dec(key->rd_key, t32);
235 if (camellia_endian.little)
237 memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
238 for(n=0; n < len; ++n)
242 memcpy(ivec,iv,CAMELLIA_BLOCK_SIZE);
246 while (len >= CAMELLIA_BLOCK_SIZE)
248 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
249 memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
250 if (camellia_endian.little)
252 key->dec(key->rd_key, t32);
253 if (camellia_endian.little)
255 memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
256 for(n=0; n < CAMELLIA_BLOCK_SIZE; ++n)
258 memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);
259 len -= CAMELLIA_BLOCK_SIZE;
260 in += CAMELLIA_BLOCK_SIZE;
261 out += CAMELLIA_BLOCK_SIZE;
265 memcpy(tmp, in, CAMELLIA_BLOCK_SIZE);
266 memcpy(t32, in, CAMELLIA_BLOCK_SIZE);
267 if (camellia_endian.little)
269 key->dec(key->rd_key,t32);
270 if (camellia_endian.little)
272 memcpy(out, t32, CAMELLIA_BLOCK_SIZE);
273 for(n=0; n < len; ++n)
275 for(n=len; n < CAMELLIA_BLOCK_SIZE; ++n)
277 memcpy(ivec, tmp, CAMELLIA_BLOCK_SIZE);