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 const unsigned char *iv
= ivec
;
71 union { u32 t32
[CAMELLIA_BLOCK_SIZE
/sizeof(u32
)];
72 u8 t8
[CAMELLIA_BLOCK_SIZE
]; } tmp
;
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
.t8
, in
, CAMELLIA_BLOCK_SIZE
);
131 if (camellia_endian
.little
)
133 key
->dec(key
->rd_key
, tmp
.t32
);
134 if (camellia_endian
.little
)
136 for(n
=0; n
< len
; ++n
)
137 out
[n
] = tmp
.t8
[n
] ^ iv
[n
];
140 memcpy(ivec
,iv
,CAMELLIA_BLOCK_SIZE
);
144 while (len
>= CAMELLIA_BLOCK_SIZE
)
146 memcpy(tmp
.t8
, 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
.t8
, CAMELLIA_BLOCK_SIZE
);
154 len
-= CAMELLIA_BLOCK_SIZE
;
155 in
+= CAMELLIA_BLOCK_SIZE
;
156 out
+= CAMELLIA_BLOCK_SIZE
;
160 memcpy(tmp
.t8
, 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
.t8
, 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 tmp
.t8
[n
] = in
[n
] ^ iv
[n
];
182 if (camellia_endian
.little
)
184 key
->enc(key
->rd_key
, tmp
.t32
);
185 if (camellia_endian
.little
)
187 memcpy(out
, tmp
.t8
, CAMELLIA_BLOCK_SIZE
);
189 len
-= CAMELLIA_BLOCK_SIZE
;
190 in
+= CAMELLIA_BLOCK_SIZE
;
191 out
+= CAMELLIA_BLOCK_SIZE
;
195 for(n
=0; n
< len
; ++n
)
196 tmp
.t8
[n
] = in
[n
] ^ iv
[n
];
197 for(n
=len
; n
< CAMELLIA_BLOCK_SIZE
; ++n
)
199 if (camellia_endian
.little
)
201 key
->enc(key
->rd_key
, tmp
.t32
);
202 if (camellia_endian
.little
)
204 memcpy(out
, tmp
.t8
, CAMELLIA_BLOCK_SIZE
);
207 memcpy(ivec
,iv
,CAMELLIA_BLOCK_SIZE
);
211 while (len
>= CAMELLIA_BLOCK_SIZE
)
213 memcpy(tmp
.t8
,in
,CAMELLIA_BLOCK_SIZE
);
214 if (camellia_endian
.little
)
216 key
->dec(key
->rd_key
,tmp
.t32
);
217 if (camellia_endian
.little
)
219 for(n
=0; n
< CAMELLIA_BLOCK_SIZE
; ++n
)
220 out
[n
] = tmp
.t8
[n
] ^ iv
[n
];
222 len
-= CAMELLIA_BLOCK_SIZE
;
223 in
+= CAMELLIA_BLOCK_SIZE
;
224 out
+= CAMELLIA_BLOCK_SIZE
;
228 memcpy(tmp
.t8
, in
, CAMELLIA_BLOCK_SIZE
);
229 if (camellia_endian
.little
)
231 key
->dec(key
->rd_key
, tmp
.t32
);
232 if (camellia_endian
.little
)
234 for(n
=0; n
< len
; ++n
)
235 out
[n
] = tmp
.t8
[n
] ^ iv
[n
];
238 memcpy(ivec
,iv
,CAMELLIA_BLOCK_SIZE
);
242 while (len
>= CAMELLIA_BLOCK_SIZE
)
244 memcpy(tmp
.t8
, in
, CAMELLIA_BLOCK_SIZE
);
245 if (camellia_endian
.little
)
247 key
->dec(key
->rd_key
, tmp
.t32
);
248 if (camellia_endian
.little
)
250 for(n
=0; n
< CAMELLIA_BLOCK_SIZE
; ++n
)
251 tmp
.t8
[n
] ^= ivec
[n
];
252 memcpy(ivec
, in
, CAMELLIA_BLOCK_SIZE
);
253 memcpy(out
, tmp
.t8
, CAMELLIA_BLOCK_SIZE
);
254 len
-= CAMELLIA_BLOCK_SIZE
;
255 in
+= CAMELLIA_BLOCK_SIZE
;
256 out
+= CAMELLIA_BLOCK_SIZE
;
260 memcpy(tmp
.t8
, in
, CAMELLIA_BLOCK_SIZE
);
261 if (camellia_endian
.little
)
263 key
->dec(key
->rd_key
,tmp
.t32
);
264 if (camellia_endian
.little
)
266 for(n
=0; n
< len
; ++n
)
267 tmp
.t8
[n
] ^= ivec
[n
];
268 memcpy(ivec
, in
, CAMELLIA_BLOCK_SIZE
);
269 memcpy(out
,tmp
.t8
,len
);