1169425Sgnn/* camellia.h ver 1.1.0
2169425Sgnn *
3169425Sgnn * Copyright (c) 2006
4169425Sgnn * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
5169425Sgnn *
6169425Sgnn * Redistribution and use in source and binary forms, with or without
7169425Sgnn * modification, are permitted provided that the following conditions
8169425Sgnn * are met:
9169425Sgnn * 1. Redistributions of source code must retain the above copyright
10169425Sgnn *   notice, this list of conditions and the following disclaimer as
11169425Sgnn *   the first lines of this file unmodified.
12169425Sgnn * 2. Redistributions in binary form must reproduce the above copyright
13169425Sgnn *   notice, this list of conditions and the following disclaimer in the
14169425Sgnn *   documentation and/or other materials provided with the distribution.
15169425Sgnn *
16169425Sgnn * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR
17169425Sgnn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18169425Sgnn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19169425Sgnn * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,
20169425Sgnn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21169425Sgnn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22169425Sgnn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23169425Sgnn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24169425Sgnn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25169425Sgnn * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26169425Sgnn *
27169425Sgnn * $FreeBSD$
28169425Sgnn */
29169425Sgnn
30169425Sgnn/*
31169425Sgnn * Algorithm Specification
32169425Sgnn *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
33169425Sgnn */
34169425Sgnn
35169425Sgnn#include <sys/cdefs.h>
36169425Sgnn#include <sys/types.h>
37169425Sgnn#include <sys/endian.h>
38169425Sgnn#ifdef _KERNEL
39169425Sgnn#include <sys/systm.h>
40169425Sgnn#else
41169425Sgnn#include <string.h>
42169425Sgnn#include <assert.h>
43169425Sgnn#define KASSERT(exp, msg) assert(exp)
44169425Sgnn#endif
45169425Sgnn
46169425Sgnn#include <crypto/camellia/camellia.h>
47169425Sgnn
48169425Sgnn
49169425Sgnn/* key constants */
50169425Sgnn
51169425Sgnn#define CAMELLIA_SIGMA1L (0xA09E667FL)
52169425Sgnn#define CAMELLIA_SIGMA1R (0x3BCC908BL)
53169425Sgnn#define CAMELLIA_SIGMA2L (0xB67AE858L)
54169425Sgnn#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
55169425Sgnn#define CAMELLIA_SIGMA3L (0xC6EF372FL)
56169425Sgnn#define CAMELLIA_SIGMA3R (0xE94F82BEL)
57169425Sgnn#define CAMELLIA_SIGMA4L (0x54FF53A5L)
58169425Sgnn#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
59169425Sgnn#define CAMELLIA_SIGMA5L (0x10E527FAL)
60169425Sgnn#define CAMELLIA_SIGMA5R (0xDE682D1DL)
61169425Sgnn#define CAMELLIA_SIGMA6L (0xB05688C2L)
62169425Sgnn#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
63169425Sgnn
64169425Sgnn/*
65169425Sgnn *  macros
66169425Sgnn */
67169425Sgnn#define GETU32(pt) (((uint32_t)(pt)[0] << 24)		\
68169425Sgnn		     ^ ((uint32_t)(pt)[1] << 16)	\
69169425Sgnn		     ^ ((uint32_t)(pt)[2] <<  8)	\
70169425Sgnn		     ^ ((uint32_t)(pt)[3]))
71169425Sgnn
72169425Sgnn#define PUTU32(ct, st) {(ct)[0] = (uint8_t)((st) >> 24);	\
73169425Sgnn			(ct)[1] = (uint8_t)((st) >> 16);	\
74169425Sgnn			(ct)[2] = (uint8_t)((st) >>  8);	\
75169425Sgnn			(ct)[3] = (uint8_t)(st);}
76169425Sgnn
77169425Sgnn#define SUBL(INDEX) (subkey[(INDEX)*2+1])
78169425Sgnn#define SUBR(INDEX) (subkey[(INDEX)*2])
79169425Sgnn
80169425Sgnn#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
81169425Sgnn#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
82169425Sgnn#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
83169425Sgnn
84169425Sgnn#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)	\
85169425Sgnn    do {						\
86169425Sgnn	w0 = ll;					\
87169425Sgnn	ll = (ll << bits) + (lr >> (32 - bits));	\
88169425Sgnn	lr = (lr << bits) + (rl >> (32 - bits));	\
89169425Sgnn	rl = (rl << bits) + (rr >> (32 - bits));	\
90169425Sgnn	rr = (rr << bits) + (w0 >> (32 - bits));	\
91169425Sgnn    } while(0)
92169425Sgnn
93169425Sgnn#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits)	\
94169425Sgnn    do {						\
95169425Sgnn	w0 = ll;					\
96169425Sgnn	w1 = lr;					\
97169425Sgnn	ll = (lr << (bits - 32)) + (rl >> (64 - bits));	\
98169425Sgnn	lr = (rl << (bits - 32)) + (rr >> (64 - bits));	\
99169425Sgnn	rl = (rr << (bits - 32)) + (w0 >> (64 - bits));	\
100169425Sgnn	rr = (w0 << (bits - 32)) + (w1 >> (64 - bits));	\
101169425Sgnn    } while(0)
102169425Sgnn
103169425Sgnn#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
104169425Sgnn#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
105169425Sgnn#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
106169425Sgnn#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
107169425Sgnn
108169425Sgnn#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)	\
109169425Sgnn    do {							\
110169425Sgnn	il = xl ^ kl;						\
111169425Sgnn	ir = xr ^ kr;						\
112169425Sgnn	t0 = il >> 16;						\
113169425Sgnn	t1 = ir >> 16;						\
114169425Sgnn	yl = CAMELLIA_SP1110(ir & 0xff)				\
115169425Sgnn	    ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)			\
116169425Sgnn	    ^ CAMELLIA_SP3033(t1 & 0xff)			\
117169425Sgnn	    ^ CAMELLIA_SP4404((ir >> 8) & 0xff);		\
118169425Sgnn	yr = CAMELLIA_SP1110((t0 >> 8) & 0xff)			\
119169425Sgnn	    ^ CAMELLIA_SP0222(t0 & 0xff)			\
120169425Sgnn	    ^ CAMELLIA_SP3033((il >> 8) & 0xff)			\
121169425Sgnn	    ^ CAMELLIA_SP4404(il & 0xff);			\
122169425Sgnn	yl ^= yr;						\
123169425Sgnn	yr = CAMELLIA_RR8(yr);					\
124169425Sgnn	yr ^= yl;						\
125169425Sgnn    } while(0)
126169425Sgnn
127169425Sgnn
128169425Sgnn#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
129169425Sgnn    do {								\
130169425Sgnn	t0 = kll;							\
131169425Sgnn	t2 = krr;							\
132169425Sgnn	t0 &= ll;							\
133169425Sgnn	t2 |= rr;							\
134169425Sgnn	rl ^= t2;							\
135169425Sgnn	lr ^= CAMELLIA_RL1(t0);						\
136169425Sgnn	t3 = krl;							\
137169425Sgnn	t1 = klr;							\
138169425Sgnn	t3 &= rl;							\
139169425Sgnn	t1 |= lr;							\
140169425Sgnn	ll ^= t1;							\
141169425Sgnn	rr ^= CAMELLIA_RL1(t3);						\
142169425Sgnn    } while(0)
143169425Sgnn
144169425Sgnn#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)	\
145169425Sgnn    do {								\
146169425Sgnn	ir =  CAMELLIA_SP1110(xr & 0xff);				\
147169425Sgnn	il =  CAMELLIA_SP1110((xl>>24) & 0xff);				\
148169425Sgnn	ir ^= CAMELLIA_SP0222((xr>>24) & 0xff);				\
149169425Sgnn	il ^= CAMELLIA_SP0222((xl>>16) & 0xff);				\
150169425Sgnn	ir ^= CAMELLIA_SP3033((xr>>16) & 0xff);				\
151169425Sgnn	il ^= CAMELLIA_SP3033((xl>>8) & 0xff);				\
152169425Sgnn	ir ^= CAMELLIA_SP4404((xr>>8) & 0xff);				\
153169425Sgnn	il ^= CAMELLIA_SP4404(xl & 0xff);				\
154169425Sgnn	il ^= kl;							\
155169425Sgnn	ir ^= kr;							\
156169425Sgnn	ir ^= il;							\
157169425Sgnn	il = CAMELLIA_RR8(il);						\
158169425Sgnn	il ^= ir;							\
159169425Sgnn	yl ^= ir;							\
160169425Sgnn	yr ^= il;							\
161169425Sgnn    } while(0)
162169425Sgnn
163169425Sgnn
164169425Sgnnstatic const uint32_t camellia_sp1110[256] = {
165169425Sgnn    0x70707000,0x82828200,0x2c2c2c00,0xececec00,
166169425Sgnn    0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
167169425Sgnn    0xe4e4e400,0x85858500,0x57575700,0x35353500,
168169425Sgnn    0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
169169425Sgnn    0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
170169425Sgnn    0x45454500,0x19191900,0xa5a5a500,0x21212100,
171169425Sgnn    0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
172169425Sgnn    0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
173169425Sgnn    0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
174169425Sgnn    0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
175169425Sgnn    0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
176169425Sgnn    0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
177169425Sgnn    0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
178169425Sgnn    0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
179169425Sgnn    0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
180169425Sgnn    0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
181169425Sgnn    0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
182169425Sgnn    0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
183169425Sgnn    0x74747400,0x12121200,0x2b2b2b00,0x20202000,
184169425Sgnn    0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
185169425Sgnn    0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
186169425Sgnn    0x34343400,0x7e7e7e00,0x76767600,0x05050500,
187169425Sgnn    0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
188169425Sgnn    0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
189169425Sgnn    0x14141400,0x58585800,0x3a3a3a00,0x61616100,
190169425Sgnn    0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
191169425Sgnn    0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
192169425Sgnn    0x53535300,0x18181800,0xf2f2f200,0x22222200,
193169425Sgnn    0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
194169425Sgnn    0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
195169425Sgnn    0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
196169425Sgnn    0x60606000,0xfcfcfc00,0x69696900,0x50505000,
197169425Sgnn    0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
198169425Sgnn    0xa1a1a100,0x89898900,0x62626200,0x97979700,
199169425Sgnn    0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
200169425Sgnn    0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
201169425Sgnn    0x10101000,0xc4c4c400,0x00000000,0x48484800,
202169425Sgnn    0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
203169425Sgnn    0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
204169425Sgnn    0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
205169425Sgnn    0x87878700,0x5c5c5c00,0x83838300,0x02020200,
206169425Sgnn    0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
207169425Sgnn    0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
208169425Sgnn    0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
209169425Sgnn    0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
210169425Sgnn    0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
211169425Sgnn    0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
212169425Sgnn    0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
213169425Sgnn    0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
214169425Sgnn    0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
215169425Sgnn    0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
216169425Sgnn    0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
217169425Sgnn    0x78787800,0x98989800,0x06060600,0x6a6a6a00,
218169425Sgnn    0xe7e7e700,0x46464600,0x71717100,0xbababa00,
219169425Sgnn    0xd4d4d400,0x25252500,0xababab00,0x42424200,
220169425Sgnn    0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
221169425Sgnn    0x72727200,0x07070700,0xb9b9b900,0x55555500,
222169425Sgnn    0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
223169425Sgnn    0x36363600,0x49494900,0x2a2a2a00,0x68686800,
224169425Sgnn    0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
225169425Sgnn    0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
226169425Sgnn    0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
227169425Sgnn    0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
228169425Sgnn    0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
229169425Sgnn};
230169425Sgnn
231169425Sgnnstatic const uint32_t camellia_sp0222[256] = {
232169425Sgnn    0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
233169425Sgnn    0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
234169425Sgnn    0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
235169425Sgnn    0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
236169425Sgnn    0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
237169425Sgnn    0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
238169425Sgnn    0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
239169425Sgnn    0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
240169425Sgnn    0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
241169425Sgnn    0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
242169425Sgnn    0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
243169425Sgnn    0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
244169425Sgnn    0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
245169425Sgnn    0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
246169425Sgnn    0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
247169425Sgnn    0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
248169425Sgnn    0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
249169425Sgnn    0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
250169425Sgnn    0x00e8e8e8,0x00242424,0x00565656,0x00404040,
251169425Sgnn    0x00e1e1e1,0x00636363,0x00090909,0x00333333,
252169425Sgnn    0x00bfbfbf,0x00989898,0x00979797,0x00858585,
253169425Sgnn    0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
254169425Sgnn    0x00dadada,0x006f6f6f,0x00535353,0x00626262,
255169425Sgnn    0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
256169425Sgnn    0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
257169425Sgnn    0x00bdbdbd,0x00363636,0x00222222,0x00383838,
258169425Sgnn    0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
259169425Sgnn    0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
260169425Sgnn    0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
261169425Sgnn    0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
262169425Sgnn    0x00484848,0x00101010,0x00d1d1d1,0x00515151,
263169425Sgnn    0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
264169425Sgnn    0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
265169425Sgnn    0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
266169425Sgnn    0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
267169425Sgnn    0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
268169425Sgnn    0x00202020,0x00898989,0x00000000,0x00909090,
269169425Sgnn    0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
270169425Sgnn    0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
271169425Sgnn    0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
272169425Sgnn    0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
273169425Sgnn    0x009b9b9b,0x00949494,0x00212121,0x00666666,
274169425Sgnn    0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
275169425Sgnn    0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
276169425Sgnn    0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
277169425Sgnn    0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
278169425Sgnn    0x00030303,0x002d2d2d,0x00dedede,0x00969696,
279169425Sgnn    0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
280169425Sgnn    0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
281169425Sgnn    0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
282169425Sgnn    0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
283169425Sgnn    0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
284169425Sgnn    0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
285169425Sgnn    0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
286169425Sgnn    0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
287169425Sgnn    0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
288169425Sgnn    0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
289169425Sgnn    0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
290169425Sgnn    0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
291169425Sgnn    0x00787878,0x00707070,0x00e3e3e3,0x00494949,
292169425Sgnn    0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
293169425Sgnn    0x00777777,0x00939393,0x00868686,0x00838383,
294169425Sgnn    0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
295169425Sgnn    0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
296169425Sgnn};
297169425Sgnn
298169425Sgnnstatic const uint32_t camellia_sp3033[256] = {
299169425Sgnn    0x38003838,0x41004141,0x16001616,0x76007676,
300169425Sgnn    0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
301169425Sgnn    0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
302169425Sgnn    0x75007575,0x06000606,0x57005757,0xa000a0a0,
303169425Sgnn    0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
304169425Sgnn    0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
305169425Sgnn    0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
306169425Sgnn    0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
307169425Sgnn    0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
308169425Sgnn    0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
309169425Sgnn    0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
310169425Sgnn    0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
311169425Sgnn    0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
312169425Sgnn    0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
313169425Sgnn    0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
314169425Sgnn    0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
315169425Sgnn    0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
316169425Sgnn    0xfd00fdfd,0x66006666,0x58005858,0x96009696,
317169425Sgnn    0x3a003a3a,0x09000909,0x95009595,0x10001010,
318169425Sgnn    0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
319169425Sgnn    0xef00efef,0x26002626,0xe500e5e5,0x61006161,
320169425Sgnn    0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
321169425Sgnn    0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
322169425Sgnn    0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
323169425Sgnn    0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
324169425Sgnn    0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
325169425Sgnn    0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
326169425Sgnn    0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
327169425Sgnn    0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
328169425Sgnn    0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
329169425Sgnn    0x12001212,0x04000404,0x74007474,0x54005454,
330169425Sgnn    0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
331169425Sgnn    0x55005555,0x68006868,0x50005050,0xbe00bebe,
332169425Sgnn    0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
333169425Sgnn    0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
334169425Sgnn    0x70007070,0xff00ffff,0x32003232,0x69006969,
335169425Sgnn    0x08000808,0x62006262,0x00000000,0x24002424,
336169425Sgnn    0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
337169425Sgnn    0x45004545,0x81008181,0x73007373,0x6d006d6d,
338169425Sgnn    0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
339169425Sgnn    0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
340169425Sgnn    0xe600e6e6,0x25002525,0x48004848,0x99009999,
341169425Sgnn    0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
342169425Sgnn    0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
343169425Sgnn    0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
344169425Sgnn    0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
345169425Sgnn    0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
346169425Sgnn    0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
347169425Sgnn    0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
348169425Sgnn    0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
349169425Sgnn    0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
350169425Sgnn    0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
351169425Sgnn    0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
352169425Sgnn    0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
353169425Sgnn    0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
354169425Sgnn    0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
355169425Sgnn    0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
356169425Sgnn    0x7c007c7c,0x77007777,0x56005656,0x05000505,
357169425Sgnn    0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
358169425Sgnn    0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
359169425Sgnn    0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
360169425Sgnn    0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
361169425Sgnn    0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
362169425Sgnn    0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
363169425Sgnn};
364169425Sgnn
365169425Sgnnstatic const uint32_t camellia_sp4404[256] = {
366169425Sgnn    0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
367169425Sgnn    0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
368169425Sgnn    0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
369169425Sgnn    0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
370169425Sgnn    0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
371169425Sgnn    0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
372169425Sgnn    0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
373169425Sgnn    0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
374169425Sgnn    0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
375169425Sgnn    0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
376169425Sgnn    0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
377169425Sgnn    0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
378169425Sgnn    0x14140014,0x3a3a003a,0xdede00de,0x11110011,
379169425Sgnn    0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
380169425Sgnn    0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
381169425Sgnn    0x24240024,0xe8e800e8,0x60600060,0x69690069,
382169425Sgnn    0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
383169425Sgnn    0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
384169425Sgnn    0x10100010,0x00000000,0xa3a300a3,0x75750075,
385169425Sgnn    0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
386169425Sgnn    0x87870087,0x83830083,0xcdcd00cd,0x90900090,
387169425Sgnn    0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
388169425Sgnn    0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
389169425Sgnn    0x81810081,0x6f6f006f,0x13130013,0x63630063,
390169425Sgnn    0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
391169425Sgnn    0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
392169425Sgnn    0x78780078,0x06060006,0xe7e700e7,0x71710071,
393169425Sgnn    0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
394169425Sgnn    0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
395169425Sgnn    0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
396169425Sgnn    0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
397169425Sgnn    0x15150015,0xadad00ad,0x77770077,0x80800080,
398169425Sgnn    0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
399169425Sgnn    0x85850085,0x35350035,0x0c0c000c,0x41410041,
400169425Sgnn    0xefef00ef,0x93930093,0x19190019,0x21210021,
401169425Sgnn    0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
402169425Sgnn    0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
403169425Sgnn    0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
404169425Sgnn    0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
405169425Sgnn    0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
406169425Sgnn    0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
407169425Sgnn    0x12120012,0x20200020,0xb1b100b1,0x99990099,
408169425Sgnn    0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
409169425Sgnn    0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
410169425Sgnn    0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
411169425Sgnn    0x0f0f000f,0x16160016,0x18180018,0x22220022,
412169425Sgnn    0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
413169425Sgnn    0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
414169425Sgnn    0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
415169425Sgnn    0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
416169425Sgnn    0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
417169425Sgnn    0x03030003,0xdada00da,0x3f3f003f,0x94940094,
418169425Sgnn    0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
419169425Sgnn    0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
420169425Sgnn    0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
421169425Sgnn    0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
422169425Sgnn    0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
423169425Sgnn    0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
424169425Sgnn    0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
425169425Sgnn    0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
426169425Sgnn    0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
427169425Sgnn    0x49490049,0x68680068,0x38380038,0xa4a400a4,
428169425Sgnn    0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
429169425Sgnn    0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
430169425Sgnn};
431169425Sgnn
432169425Sgnn
433169425Sgnn/*
434169425Sgnn * Stuff related to the Camellia key schedule
435169425Sgnn */
436169425Sgnn#define subl(x) subL[(x)]
437169425Sgnn#define subr(x) subR[(x)]
438169425Sgnn
439169425Sgnnvoid
440169425Sgnncamellia_setup128(const unsigned char *key, uint32_t *subkey)
441169425Sgnn{
442169425Sgnn    uint32_t kll, klr, krl, krr;
443169425Sgnn    uint32_t il, ir, t0, t1, w0, w1;
444169425Sgnn    uint32_t kw4l, kw4r, dw, tl, tr;
445169425Sgnn    uint32_t subL[26];
446169425Sgnn    uint32_t subR[26];
447169425Sgnn
448169425Sgnn    /*
449169425Sgnn     *  k == kll || klr || krl || krr (|| is concatination)
450169425Sgnn     */
451169425Sgnn    kll = GETU32(key     );
452169425Sgnn    klr = GETU32(key +  4);
453169425Sgnn    krl = GETU32(key +  8);
454169425Sgnn    krr = GETU32(key + 12);
455169425Sgnn    /*
456169425Sgnn     * generate KL dependent subkeys
457169425Sgnn     */
458169425Sgnn    subl(0) = kll; subr(0) = klr;
459169425Sgnn    subl(1) = krl; subr(1) = krr;
460169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
461169425Sgnn    subl(4) = kll; subr(4) = klr;
462169425Sgnn    subl(5) = krl; subr(5) = krr;
463169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
464169425Sgnn    subl(10) = kll; subr(10) = klr;
465169425Sgnn    subl(11) = krl; subr(11) = krr;
466169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
467169425Sgnn    subl(13) = krl; subr(13) = krr;
468169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
469169425Sgnn    subl(16) = kll; subr(16) = klr;
470169425Sgnn    subl(17) = krl; subr(17) = krr;
471169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
472169425Sgnn    subl(18) = kll; subr(18) = klr;
473169425Sgnn    subl(19) = krl; subr(19) = krr;
474169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
475169425Sgnn    subl(22) = kll; subr(22) = klr;
476169425Sgnn    subl(23) = krl; subr(23) = krr;
477169425Sgnn
478169425Sgnn    /* generate KA */
479169425Sgnn    kll = subl(0); klr = subr(0);
480169425Sgnn    krl = subl(1); krr = subr(1);
481169425Sgnn    CAMELLIA_F(kll, klr, CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
482169425Sgnn	       w0, w1, il, ir, t0, t1);
483169425Sgnn    krl ^= w0; krr ^= w1;
484169425Sgnn    CAMELLIA_F(krl, krr, CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
485169425Sgnn	       kll, klr, il, ir, t0, t1);
486169425Sgnn    CAMELLIA_F(kll, klr, CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
487169425Sgnn	       krl, krr, il, ir, t0, t1);
488169425Sgnn    krl ^= w0; krr ^= w1;
489169425Sgnn    CAMELLIA_F(krl, krr, CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
490169425Sgnn	       w0, w1, il, ir, t0, t1);
491169425Sgnn    kll ^= w0; klr ^= w1;
492169425Sgnn
493169425Sgnn    /* generate KA dependent subkeys */
494169425Sgnn    subl(2) = kll; subr(2) = klr;
495169425Sgnn    subl(3) = krl; subr(3) = krr;
496169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
497169425Sgnn    subl(6) = kll; subr(6) = klr;
498169425Sgnn    subl(7) = krl; subr(7) = krr;
499169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
500169425Sgnn    subl(8) = kll; subr(8) = klr;
501169425Sgnn    subl(9) = krl; subr(9) = krr;
502169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
503169425Sgnn    subl(12) = kll; subr(12) = klr;
504169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
505169425Sgnn    subl(14) = kll; subr(14) = klr;
506169425Sgnn    subl(15) = krl; subr(15) = krr;
507169425Sgnn    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
508169425Sgnn    subl(20) = kll; subr(20) = klr;
509169425Sgnn    subl(21) = krl; subr(21) = krr;
510169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
511169425Sgnn    subl(24) = kll; subr(24) = klr;
512169425Sgnn    subl(25) = krl; subr(25) = krr;
513169425Sgnn
514169425Sgnn
515169425Sgnn    /* absorb kw2 to other subkeys */
516169425Sgnn    subl(3) ^= subl(1); subr(3) ^= subr(1);
517169425Sgnn    subl(5) ^= subl(1); subr(5) ^= subr(1);
518169425Sgnn    subl(7) ^= subl(1); subr(7) ^= subr(1);
519169425Sgnn    subl(1) ^= subr(1) & ~subr(9);
520169425Sgnn    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
521169425Sgnn    subl(11) ^= subl(1); subr(11) ^= subr(1);
522169425Sgnn    subl(13) ^= subl(1); subr(13) ^= subr(1);
523169425Sgnn    subl(15) ^= subl(1); subr(15) ^= subr(1);
524169425Sgnn    subl(1) ^= subr(1) & ~subr(17);
525169425Sgnn    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
526169425Sgnn    subl(19) ^= subl(1); subr(19) ^= subr(1);
527169425Sgnn    subl(21) ^= subl(1); subr(21) ^= subr(1);
528169425Sgnn    subl(23) ^= subl(1); subr(23) ^= subr(1);
529169425Sgnn    subl(24) ^= subl(1); subr(24) ^= subr(1);
530169425Sgnn
531169425Sgnn    /* absorb kw4 to other subkeys */
532169425Sgnn    kw4l = subl(25); kw4r = subr(25);
533169425Sgnn    subl(22) ^= kw4l; subr(22) ^= kw4r;
534169425Sgnn    subl(20) ^= kw4l; subr(20) ^= kw4r;
535169425Sgnn    subl(18) ^= kw4l; subr(18) ^= kw4r;
536169425Sgnn    kw4l ^= kw4r & ~subr(16);
537169425Sgnn    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
538169425Sgnn    subl(14) ^= kw4l; subr(14) ^= kw4r;
539169425Sgnn    subl(12) ^= kw4l; subr(12) ^= kw4r;
540169425Sgnn    subl(10) ^= kw4l; subr(10) ^= kw4r;
541169425Sgnn    kw4l ^= kw4r & ~subr(8);
542169425Sgnn    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
543169425Sgnn    subl(6) ^= kw4l; subr(6) ^= kw4r;
544169425Sgnn    subl(4) ^= kw4l; subr(4) ^= kw4r;
545169425Sgnn    subl(2) ^= kw4l; subr(2) ^= kw4r;
546169425Sgnn    subl(0) ^= kw4l; subr(0) ^= kw4r;
547169425Sgnn
548169425Sgnn    /* key XOR is end of F-function */
549169425Sgnn    SUBL(0) = subl(0) ^ subl(2);
550169425Sgnn    SUBR(0) = subr(0) ^ subr(2);
551169425Sgnn    SUBL(2) = subl(3);
552169425Sgnn    SUBR(2) = subr(3);
553169425Sgnn    SUBL(3) = subl(2) ^ subl(4);
554169425Sgnn    SUBR(3) = subr(2) ^ subr(4);
555169425Sgnn    SUBL(4) = subl(3) ^ subl(5);
556169425Sgnn    SUBR(4) = subr(3) ^ subr(5);
557169425Sgnn    SUBL(5) = subl(4) ^ subl(6);
558169425Sgnn    SUBR(5) = subr(4) ^ subr(6);
559169425Sgnn    SUBL(6) = subl(5) ^ subl(7);
560169425Sgnn    SUBR(6) = subr(5) ^ subr(7);
561169425Sgnn    tl = subl(10) ^ (subr(10) & ~subr(8));
562169425Sgnn    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
563169425Sgnn    SUBL(7) = subl(6) ^ tl;
564169425Sgnn    SUBR(7) = subr(6) ^ tr;
565169425Sgnn    SUBL(8) = subl(8);
566169425Sgnn    SUBR(8) = subr(8);
567169425Sgnn    SUBL(9) = subl(9);
568169425Sgnn    SUBR(9) = subr(9);
569169425Sgnn    tl = subl(7) ^ (subr(7) & ~subr(9));
570169425Sgnn    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
571169425Sgnn    SUBL(10) = tl ^ subl(11);
572169425Sgnn    SUBR(10) = tr ^ subr(11);
573169425Sgnn    SUBL(11) = subl(10) ^ subl(12);
574169425Sgnn    SUBR(11) = subr(10) ^ subr(12);
575169425Sgnn    SUBL(12) = subl(11) ^ subl(13);
576169425Sgnn    SUBR(12) = subr(11) ^ subr(13);
577169425Sgnn    SUBL(13) = subl(12) ^ subl(14);
578169425Sgnn    SUBR(13) = subr(12) ^ subr(14);
579169425Sgnn    SUBL(14) = subl(13) ^ subl(15);
580169425Sgnn    SUBR(14) = subr(13) ^ subr(15);
581169425Sgnn    tl = subl(18) ^ (subr(18) & ~subr(16));
582169425Sgnn    dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
583169425Sgnn    SUBL(15) = subl(14) ^ tl;
584169425Sgnn    SUBR(15) = subr(14) ^ tr;
585169425Sgnn    SUBL(16) = subl(16);
586169425Sgnn    SUBR(16) = subr(16);
587169425Sgnn    SUBL(17) = subl(17);
588169425Sgnn    SUBR(17) = subr(17);
589169425Sgnn    tl = subl(15) ^ (subr(15) & ~subr(17));
590169425Sgnn    dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
591169425Sgnn    SUBL(18) = tl ^ subl(19);
592169425Sgnn    SUBR(18) = tr ^ subr(19);
593169425Sgnn    SUBL(19) = subl(18) ^ subl(20);
594169425Sgnn    SUBR(19) = subr(18) ^ subr(20);
595169425Sgnn    SUBL(20) = subl(19) ^ subl(21);
596169425Sgnn    SUBR(20) = subr(19) ^ subr(21);
597169425Sgnn    SUBL(21) = subl(20) ^ subl(22);
598169425Sgnn    SUBR(21) = subr(20) ^ subr(22);
599169425Sgnn    SUBL(22) = subl(21) ^ subl(23);
600169425Sgnn    SUBR(22) = subr(21) ^ subr(23);
601169425Sgnn    SUBL(23) = subl(22);
602169425Sgnn    SUBR(23) = subr(22);
603169425Sgnn    SUBL(24) = subl(24) ^ subl(23);
604169425Sgnn    SUBR(24) = subr(24) ^ subr(23);
605169425Sgnn
606169425Sgnn    /* apply the inverse of the last half of P-function */
607169425Sgnn    dw = SUBL(2) ^ SUBR(2), dw = CAMELLIA_RL8(dw);
608169425Sgnn    SUBR(2) = SUBL(2) ^ dw, SUBL(2) = dw;
609169425Sgnn    dw = SUBL(3) ^ SUBR(3), dw = CAMELLIA_RL8(dw);
610169425Sgnn    SUBR(3) = SUBL(3) ^ dw, SUBL(3) = dw;
611169425Sgnn    dw = SUBL(4) ^ SUBR(4), dw = CAMELLIA_RL8(dw);
612169425Sgnn    SUBR(4) = SUBL(4) ^ dw, SUBL(4) = dw;
613169425Sgnn    dw = SUBL(5) ^ SUBR(5), dw = CAMELLIA_RL8(dw);
614169425Sgnn    SUBR(5) = SUBL(5) ^ dw, SUBL(5) = dw;
615169425Sgnn    dw = SUBL(6) ^ SUBR(6), dw = CAMELLIA_RL8(dw);
616169425Sgnn    SUBR(6) = SUBL(6) ^ dw, SUBL(6) = dw;
617169425Sgnn    dw = SUBL(7) ^ SUBR(7), dw = CAMELLIA_RL8(dw);
618169425Sgnn    SUBR(7) = SUBL(7) ^ dw, SUBL(7) = dw;
619169425Sgnn    dw = SUBL(10) ^ SUBR(10), dw = CAMELLIA_RL8(dw);
620169425Sgnn    SUBR(10) = SUBL(10) ^ dw, SUBL(10) = dw;
621169425Sgnn    dw = SUBL(11) ^ SUBR(11), dw = CAMELLIA_RL8(dw);
622169425Sgnn    SUBR(11) = SUBL(11) ^ dw, SUBL(11) = dw;
623169425Sgnn    dw = SUBL(12) ^ SUBR(12), dw = CAMELLIA_RL8(dw);
624169425Sgnn    SUBR(12) = SUBL(12) ^ dw, SUBL(12) = dw;
625169425Sgnn    dw = SUBL(13) ^ SUBR(13), dw = CAMELLIA_RL8(dw);
626169425Sgnn    SUBR(13) = SUBL(13) ^ dw, SUBL(13) = dw;
627169425Sgnn    dw = SUBL(14) ^ SUBR(14), dw = CAMELLIA_RL8(dw);
628169425Sgnn    SUBR(14) = SUBL(14) ^ dw, SUBL(14) = dw;
629169425Sgnn    dw = SUBL(15) ^ SUBR(15), dw = CAMELLIA_RL8(dw);
630169425Sgnn    SUBR(15) = SUBL(15) ^ dw, SUBL(15) = dw;
631169425Sgnn    dw = SUBL(18) ^ SUBR(18), dw = CAMELLIA_RL8(dw);
632169425Sgnn    SUBR(18) = SUBL(18) ^ dw, SUBL(18) = dw;
633169425Sgnn    dw = SUBL(19) ^ SUBR(19), dw = CAMELLIA_RL8(dw);
634169425Sgnn    SUBR(19) = SUBL(19) ^ dw, SUBL(19) = dw;
635169425Sgnn    dw = SUBL(20) ^ SUBR(20), dw = CAMELLIA_RL8(dw);
636169425Sgnn    SUBR(20) = SUBL(20) ^ dw, SUBL(20) = dw;
637169425Sgnn    dw = SUBL(21) ^ SUBR(21), dw = CAMELLIA_RL8(dw);
638169425Sgnn    SUBR(21) = SUBL(21) ^ dw, SUBL(21) = dw;
639169425Sgnn    dw = SUBL(22) ^ SUBR(22), dw = CAMELLIA_RL8(dw);
640169425Sgnn    SUBR(22) = SUBL(22) ^ dw, SUBL(22) = dw;
641169425Sgnn    dw = SUBL(23) ^ SUBR(23), dw = CAMELLIA_RL8(dw);
642169425Sgnn    SUBR(23) = SUBL(23) ^ dw, SUBL(23) = dw;
643169425Sgnn}
644169425Sgnn
645169425Sgnnvoid
646169425Sgnncamellia_setup256(const unsigned char *key, uint32_t *subkey)
647169425Sgnn{
648169425Sgnn    uint32_t kll,klr,krl,krr;           /* left half of key */
649169425Sgnn    uint32_t krll,krlr,krrl,krrr;       /* right half of key */
650169425Sgnn    uint32_t il, ir, t0, t1, w0, w1;    /* temporary variables */
651169425Sgnn    uint32_t kw4l, kw4r, dw, tl, tr;
652169425Sgnn    uint32_t subL[34];
653169425Sgnn    uint32_t subR[34];
654169425Sgnn
655169425Sgnn    /*
656169425Sgnn     *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
657169425Sgnn     *  (|| is concatination)
658169425Sgnn     */
659169425Sgnn
660169425Sgnn    kll  = GETU32(key     );
661169425Sgnn    klr  = GETU32(key +  4);
662169425Sgnn    krl  = GETU32(key +  8);
663169425Sgnn    krr  = GETU32(key + 12);
664169425Sgnn    krll = GETU32(key + 16);
665169425Sgnn    krlr = GETU32(key + 20);
666169425Sgnn    krrl = GETU32(key + 24);
667169425Sgnn    krrr = GETU32(key + 28);
668169425Sgnn
669169425Sgnn    /* generate KL dependent subkeys */
670169425Sgnn    subl(0) = kll; subr(0) = klr;
671169425Sgnn    subl(1) = krl; subr(1) = krr;
672169425Sgnn    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
673169425Sgnn    subl(12) = kll; subr(12) = klr;
674169425Sgnn    subl(13) = krl; subr(13) = krr;
675169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
676169425Sgnn    subl(16) = kll; subr(16) = klr;
677169425Sgnn    subl(17) = krl; subr(17) = krr;
678169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
679169425Sgnn    subl(22) = kll; subr(22) = klr;
680169425Sgnn    subl(23) = krl; subr(23) = krr;
681169425Sgnn    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
682169425Sgnn    subl(30) = kll; subr(30) = klr;
683169425Sgnn    subl(31) = krl; subr(31) = krr;
684169425Sgnn
685169425Sgnn    /* generate KR dependent subkeys */
686169425Sgnn    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
687169425Sgnn    subl(4) = krll; subr(4) = krlr;
688169425Sgnn    subl(5) = krrl; subr(5) = krrr;
689169425Sgnn    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
690169425Sgnn    subl(8) = krll; subr(8) = krlr;
691169425Sgnn    subl(9) = krrl; subr(9) = krrr;
692169425Sgnn    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
693169425Sgnn    subl(18) = krll; subr(18) = krlr;
694169425Sgnn    subl(19) = krrl; subr(19) = krrr;
695169425Sgnn    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
696169425Sgnn    subl(26) = krll; subr(26) = krlr;
697169425Sgnn    subl(27) = krrl; subr(27) = krrr;
698169425Sgnn    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
699169425Sgnn
700169425Sgnn    /* generate KA */
701169425Sgnn    kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
702169425Sgnn    krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
703169425Sgnn    CAMELLIA_F(kll, klr, CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
704169425Sgnn	       w0, w1, il, ir, t0, t1);
705169425Sgnn    krl ^= w0; krr ^= w1;
706169425Sgnn    CAMELLIA_F(krl, krr, CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
707169425Sgnn	       kll, klr, il, ir, t0, t1);
708169425Sgnn    kll ^= krll; klr ^= krlr;
709169425Sgnn    CAMELLIA_F(kll, klr, CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
710169425Sgnn	       krl, krr, il, ir, t0, t1);
711169425Sgnn    krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
712169425Sgnn    CAMELLIA_F(krl, krr, CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
713169425Sgnn	       w0, w1, il, ir, t0, t1);
714169425Sgnn    kll ^= w0; klr ^= w1;
715169425Sgnn
716169425Sgnn    /* generate KB */
717169425Sgnn    krll ^= kll; krlr ^= klr;
718169425Sgnn    krrl ^= krl; krrr ^= krr;
719169425Sgnn    CAMELLIA_F(krll, krlr, CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
720169425Sgnn	       w0, w1, il, ir, t0, t1);
721169425Sgnn    krrl ^= w0; krrr ^= w1;
722169425Sgnn    CAMELLIA_F(krrl, krrr, CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
723169425Sgnn	       w0, w1, il, ir, t0, t1);
724169425Sgnn    krll ^= w0; krlr ^= w1;
725169425Sgnn
726169425Sgnn    /* generate KA dependent subkeys */
727169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
728169425Sgnn    subl(6) = kll; subr(6) = klr;
729169425Sgnn    subl(7) = krl; subr(7) = krr;
730169425Sgnn    CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
731169425Sgnn    subl(14) = kll; subr(14) = klr;
732169425Sgnn    subl(15) = krl; subr(15) = krr;
733169425Sgnn    subl(24) = klr; subr(24) = krl;
734169425Sgnn    subl(25) = krr; subr(25) = kll;
735169425Sgnn    CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
736169425Sgnn    subl(28) = kll; subr(28) = klr;
737169425Sgnn    subl(29) = krl; subr(29) = krr;
738169425Sgnn
739169425Sgnn    /* generate KB dependent subkeys */
740169425Sgnn    subl(2) = krll; subr(2) = krlr;
741169425Sgnn    subl(3) = krrl; subr(3) = krrr;
742169425Sgnn    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
743169425Sgnn    subl(10) = krll; subr(10) = krlr;
744169425Sgnn    subl(11) = krrl; subr(11) = krrr;
745169425Sgnn    CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
746169425Sgnn    subl(20) = krll; subr(20) = krlr;
747169425Sgnn    subl(21) = krrl; subr(21) = krrr;
748169425Sgnn    CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
749169425Sgnn    subl(32) = krll; subr(32) = krlr;
750169425Sgnn    subl(33) = krrl; subr(33) = krrr;
751169425Sgnn
752169425Sgnn    /* absorb kw2 to other subkeys */
753169425Sgnn    subl(3) ^= subl(1); subr(3) ^= subr(1);
754169425Sgnn    subl(5) ^= subl(1); subr(5) ^= subr(1);
755169425Sgnn    subl(7) ^= subl(1); subr(7) ^= subr(1);
756169425Sgnn    subl(1) ^= subr(1) & ~subr(9);
757169425Sgnn    dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
758169425Sgnn    subl(11) ^= subl(1); subr(11) ^= subr(1);
759169425Sgnn    subl(13) ^= subl(1); subr(13) ^= subr(1);
760169425Sgnn    subl(15) ^= subl(1); subr(15) ^= subr(1);
761169425Sgnn    subl(1) ^= subr(1) & ~subr(17);
762169425Sgnn    dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
763169425Sgnn    subl(19) ^= subl(1); subr(19) ^= subr(1);
764169425Sgnn    subl(21) ^= subl(1); subr(21) ^= subr(1);
765169425Sgnn    subl(23) ^= subl(1); subr(23) ^= subr(1);
766169425Sgnn    subl(1) ^= subr(1) & ~subr(25);
767169425Sgnn    dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
768169425Sgnn    subl(27) ^= subl(1); subr(27) ^= subr(1);
769169425Sgnn    subl(29) ^= subl(1); subr(29) ^= subr(1);
770169425Sgnn    subl(31) ^= subl(1); subr(31) ^= subr(1);
771169425Sgnn    subl(32) ^= subl(1); subr(32) ^= subr(1);
772169425Sgnn
773169425Sgnn
774169425Sgnn    /* absorb kw4 to other subkeys */
775169425Sgnn    kw4l = subl(33); kw4r = subr(33);
776169425Sgnn    subl(30) ^= kw4l; subr(30) ^= kw4r;
777169425Sgnn    subl(28) ^= kw4l; subr(28) ^= kw4r;
778169425Sgnn    subl(26) ^= kw4l; subr(26) ^= kw4r;
779169425Sgnn    kw4l ^= kw4r & ~subr(24);
780169425Sgnn    dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
781169425Sgnn    subl(22) ^= kw4l; subr(22) ^= kw4r;
782169425Sgnn    subl(20) ^= kw4l; subr(20) ^= kw4r;
783169425Sgnn    subl(18) ^= kw4l; subr(18) ^= kw4r;
784169425Sgnn    kw4l ^= kw4r & ~subr(16);
785169425Sgnn    dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
786169425Sgnn    subl(14) ^= kw4l; subr(14) ^= kw4r;
787169425Sgnn    subl(12) ^= kw4l; subr(12) ^= kw4r;
788169425Sgnn    subl(10) ^= kw4l; subr(10) ^= kw4r;
789169425Sgnn    kw4l ^= kw4r & ~subr(8);
790169425Sgnn    dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
791169425Sgnn    subl(6) ^= kw4l; subr(6) ^= kw4r;
792169425Sgnn    subl(4) ^= kw4l; subr(4) ^= kw4r;
793169425Sgnn    subl(2) ^= kw4l; subr(2) ^= kw4r;
794169425Sgnn    subl(0) ^= kw4l; subr(0) ^= kw4r;
795169425Sgnn
796169425Sgnn    /* key XOR is end of F-function */
797169425Sgnn    SUBL(0) = subl(0) ^ subl(2);
798169425Sgnn    SUBR(0) = subr(0) ^ subr(2);
799169425Sgnn    SUBL(2) = subl(3);
800169425Sgnn    SUBR(2) = subr(3);
801169425Sgnn    SUBL(3) = subl(2) ^ subl(4);
802169425Sgnn    SUBR(3) = subr(2) ^ subr(4);
803169425Sgnn    SUBL(4) = subl(3) ^ subl(5);
804169425Sgnn    SUBR(4) = subr(3) ^ subr(5);
805169425Sgnn    SUBL(5) = subl(4) ^ subl(6);
806169425Sgnn    SUBR(5) = subr(4) ^ subr(6);
807169425Sgnn    SUBL(6) = subl(5) ^ subl(7);
808169425Sgnn    SUBR(6) = subr(5) ^ subr(7);
809169425Sgnn    tl = subl(10) ^ (subr(10) & ~subr(8));
810169425Sgnn    dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
811169425Sgnn    SUBL(7) = subl(6) ^ tl;
812169425Sgnn    SUBR(7) = subr(6) ^ tr;
813169425Sgnn    SUBL(8) = subl(8);
814169425Sgnn    SUBR(8) = subr(8);
815169425Sgnn    SUBL(9) = subl(9);
816169425Sgnn    SUBR(9) = subr(9);
817169425Sgnn    tl = subl(7) ^ (subr(7) & ~subr(9));
818169425Sgnn    dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
819169425Sgnn    SUBL(10) = tl ^ subl(11);
820169425Sgnn    SUBR(10) = tr ^ subr(11);
821169425Sgnn    SUBL(11) = subl(10) ^ subl(12);
822169425Sgnn    SUBR(11) = subr(10) ^ subr(12);
823169425Sgnn    SUBL(12) = subl(11) ^ subl(13);
824169425Sgnn    SUBR(12) = subr(11) ^ subr(13);
825169425Sgnn    SUBL(13) = subl(12) ^ subl(14);
826169425Sgnn    SUBR(13) = subr(12) ^ subr(14);
827169425Sgnn    SUBL(14) = subl(13) ^ subl(15);
828169425Sgnn    SUBR(14) = subr(13) ^ subr(15);
829169425Sgnn    tl = subl(18) ^ (subr(18) & ~subr(16));
830169425Sgnn    dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
831169425Sgnn    SUBL(15) = subl(14) ^ tl;
832169425Sgnn    SUBR(15) = subr(14) ^ tr;
833169425Sgnn    SUBL(16) = subl(16);
834169425Sgnn    SUBR(16) = subr(16);
835169425Sgnn    SUBL(17) = subl(17);
836169425Sgnn    SUBR(17) = subr(17);
837169425Sgnn    tl = subl(15) ^ (subr(15) & ~subr(17));
838169425Sgnn    dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
839169425Sgnn    SUBL(18) = tl ^ subl(19);
840169425Sgnn    SUBR(18) = tr ^ subr(19);
841169425Sgnn    SUBL(19) = subl(18) ^ subl(20);
842169425Sgnn    SUBR(19) = subr(18) ^ subr(20);
843169425Sgnn    SUBL(20) = subl(19) ^ subl(21);
844169425Sgnn    SUBR(20) = subr(19) ^ subr(21);
845169425Sgnn    SUBL(21) = subl(20) ^ subl(22);
846169425Sgnn    SUBR(21) = subr(20) ^ subr(22);
847169425Sgnn    SUBL(22) = subl(21) ^ subl(23);
848169425Sgnn    SUBR(22) = subr(21) ^ subr(23);
849169425Sgnn    tl = subl(26) ^ (subr(26) & ~subr(24));
850169425Sgnn    dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
851169425Sgnn    SUBL(23) = subl(22) ^ tl;
852169425Sgnn    SUBR(23) = subr(22) ^ tr;
853169425Sgnn    SUBL(24) = subl(24);
854169425Sgnn    SUBR(24) = subr(24);
855169425Sgnn    SUBL(25) = subl(25);
856169425Sgnn    SUBR(25) = subr(25);
857169425Sgnn    tl = subl(23) ^ (subr(23) & ~subr(25));
858169425Sgnn    dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
859169425Sgnn    SUBL(26) = tl ^ subl(27);
860169425Sgnn    SUBR(26) = tr ^ subr(27);
861169425Sgnn    SUBL(27) = subl(26) ^ subl(28);
862169425Sgnn    SUBR(27) = subr(26) ^ subr(28);
863169425Sgnn    SUBL(28) = subl(27) ^ subl(29);
864169425Sgnn    SUBR(28) = subr(27) ^ subr(29);
865169425Sgnn    SUBL(29) = subl(28) ^ subl(30);
866169425Sgnn    SUBR(29) = subr(28) ^ subr(30);
867169425Sgnn    SUBL(30) = subl(29) ^ subl(31);
868169425Sgnn    SUBR(30) = subr(29) ^ subr(31);
869169425Sgnn    SUBL(31) = subl(30);
870169425Sgnn    SUBR(31) = subr(30);
871169425Sgnn    SUBL(32) = subl(32) ^ subl(31);
872169425Sgnn    SUBR(32) = subr(32) ^ subr(31);
873169425Sgnn
874169425Sgnn    /* apply the inverse of the last half of P-function */
875169425Sgnn    dw = SUBL(2) ^ SUBR(2), dw = CAMELLIA_RL8(dw);
876169425Sgnn    SUBR(2) = SUBL(2) ^ dw, SUBL(2) = dw;
877169425Sgnn    dw = SUBL(3) ^ SUBR(3), dw = CAMELLIA_RL8(dw);
878169425Sgnn    SUBR(3) = SUBL(3) ^ dw, SUBL(3) = dw;
879169425Sgnn    dw = SUBL(4) ^ SUBR(4), dw = CAMELLIA_RL8(dw);
880169425Sgnn    SUBR(4) = SUBL(4) ^ dw, SUBL(4) = dw;
881169425Sgnn    dw = SUBL(5) ^ SUBR(5), dw = CAMELLIA_RL8(dw);
882169425Sgnn    SUBR(5) = SUBL(5) ^ dw, SUBL(5) = dw;
883169425Sgnn    dw = SUBL(6) ^ SUBR(6), dw = CAMELLIA_RL8(dw);
884169425Sgnn    SUBR(6) = SUBL(6) ^ dw, SUBL(6) = dw;
885169425Sgnn    dw = SUBL(7) ^ SUBR(7), dw = CAMELLIA_RL8(dw);
886169425Sgnn    SUBR(7) = SUBL(7) ^ dw, SUBL(7) = dw;
887169425Sgnn    dw = SUBL(10) ^ SUBR(10), dw = CAMELLIA_RL8(dw);
888169425Sgnn    SUBR(10) = SUBL(10) ^ dw, SUBL(10) = dw;
889169425Sgnn    dw = SUBL(11) ^ SUBR(11), dw = CAMELLIA_RL8(dw);
890169425Sgnn    SUBR(11) = SUBL(11) ^ dw, SUBL(11) = dw;
891169425Sgnn    dw = SUBL(12) ^ SUBR(12), dw = CAMELLIA_RL8(dw);
892169425Sgnn    SUBR(12) = SUBL(12) ^ dw, SUBL(12) = dw;
893169425Sgnn    dw = SUBL(13) ^ SUBR(13), dw = CAMELLIA_RL8(dw);
894169425Sgnn    SUBR(13) = SUBL(13) ^ dw, SUBL(13) = dw;
895169425Sgnn    dw = SUBL(14) ^ SUBR(14), dw = CAMELLIA_RL8(dw);
896169425Sgnn    SUBR(14) = SUBL(14) ^ dw, SUBL(14) = dw;
897169425Sgnn    dw = SUBL(15) ^ SUBR(15), dw = CAMELLIA_RL8(dw);
898169425Sgnn    SUBR(15) = SUBL(15) ^ dw, SUBL(15) = dw;
899169425Sgnn    dw = SUBL(18) ^ SUBR(18), dw = CAMELLIA_RL8(dw);
900169425Sgnn    SUBR(18) = SUBL(18) ^ dw, SUBL(18) = dw;
901169425Sgnn    dw = SUBL(19) ^ SUBR(19), dw = CAMELLIA_RL8(dw);
902169425Sgnn    SUBR(19) = SUBL(19) ^ dw, SUBL(19) = dw;
903169425Sgnn    dw = SUBL(20) ^ SUBR(20), dw = CAMELLIA_RL8(dw);
904169425Sgnn    SUBR(20) = SUBL(20) ^ dw, SUBL(20) = dw;
905169425Sgnn    dw = SUBL(21) ^ SUBR(21), dw = CAMELLIA_RL8(dw);
906169425Sgnn    SUBR(21) = SUBL(21) ^ dw, SUBL(21) = dw;
907169425Sgnn    dw = SUBL(22) ^ SUBR(22), dw = CAMELLIA_RL8(dw);
908169425Sgnn    SUBR(22) = SUBL(22) ^ dw, SUBL(22) = dw;
909169425Sgnn    dw = SUBL(23) ^ SUBR(23), dw = CAMELLIA_RL8(dw);
910169425Sgnn    SUBR(23) = SUBL(23) ^ dw, SUBL(23) = dw;
911169425Sgnn    dw = SUBL(26) ^ SUBR(26), dw = CAMELLIA_RL8(dw);
912169425Sgnn    SUBR(26) = SUBL(26) ^ dw, SUBL(26) = dw;
913169425Sgnn    dw = SUBL(27) ^ SUBR(27), dw = CAMELLIA_RL8(dw);
914169425Sgnn    SUBR(27) = SUBL(27) ^ dw, SUBL(27) = dw;
915169425Sgnn    dw = SUBL(28) ^ SUBR(28), dw = CAMELLIA_RL8(dw);
916169425Sgnn    SUBR(28) = SUBL(28) ^ dw, SUBL(28) = dw;
917169425Sgnn    dw = SUBL(29) ^ SUBR(29), dw = CAMELLIA_RL8(dw);
918169425Sgnn    SUBR(29) = SUBL(29) ^ dw, SUBL(29) = dw;
919169425Sgnn    dw = SUBL(30) ^ SUBR(30), dw = CAMELLIA_RL8(dw);
920169425Sgnn    SUBR(30) = SUBL(30) ^ dw, SUBL(30) = dw;
921169425Sgnn    dw = SUBL(31) ^ SUBR(31), dw = CAMELLIA_RL8(dw);
922169425Sgnn    SUBR(31) = SUBL(31) ^ dw, SUBL(31) = dw;
923169425Sgnn}
924169425Sgnn
925169425Sgnnvoid
926169425Sgnncamellia_setup192(const unsigned char *key, uint32_t *subkey)
927169425Sgnn{
928169425Sgnn    unsigned char kk[32];
929169425Sgnn    uint32_t krll, krlr, krrl,krrr;
930169425Sgnn
931169425Sgnn    memcpy(kk, key, 24);
932169425Sgnn    memcpy((unsigned char *)&krll, key+16,4);
933169425Sgnn    memcpy((unsigned char *)&krlr, key+20,4);
934169425Sgnn    krrl = ~krll;
935169425Sgnn    krrr = ~krlr;
936169425Sgnn    memcpy(kk+24, (unsigned char *)&krrl, 4);
937169425Sgnn    memcpy(kk+28, (unsigned char *)&krrr, 4);
938169425Sgnn    camellia_setup256(kk, subkey);
939169425Sgnn}
940169425Sgnn
941169425Sgnn
942169425Sgnn/**
943169425Sgnn * Stuff related to camellia encryption/decryption
944169425Sgnn */
945169425Sgnnvoid
946169425Sgnncamellia_encrypt128(const uint32_t *subkey, uint32_t *io)
947169425Sgnn{
948169425Sgnn    uint32_t il, ir, t0, t1;
949169425Sgnn
950169425Sgnn    /* pre whitening but absorb kw2*/
951169425Sgnn    io[0] ^= SUBL(0);
952169425Sgnn    io[1] ^= SUBR(0);
953169425Sgnn    /* main iteration */
954169425Sgnn
955169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(2),SUBR(2),
956169425Sgnn		     io[2],io[3],il,ir,t0,t1);
957169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(3),SUBR(3),
958169425Sgnn		     io[0],io[1],il,ir,t0,t1);
959169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(4),SUBR(4),
960169425Sgnn		     io[2],io[3],il,ir,t0,t1);
961169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(5),SUBR(5),
962169425Sgnn		     io[0],io[1],il,ir,t0,t1);
963169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(6),SUBR(6),
964169425Sgnn		     io[2],io[3],il,ir,t0,t1);
965169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(7),SUBR(7),
966169425Sgnn		     io[0],io[1],il,ir,t0,t1);
967169425Sgnn
968169425Sgnn    CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(8),SUBR(8), SUBL(9),SUBR(9),
969169425Sgnn		 t0,t1,il,ir);
970169425Sgnn
971169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(10),SUBR(10),
972169425Sgnn		     io[2],io[3],il,ir,t0,t1);
973169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(11),SUBR(11),
974169425Sgnn		     io[0],io[1],il,ir,t0,t1);
975169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(12),SUBR(12),
976169425Sgnn		     io[2],io[3],il,ir,t0,t1);
977169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(13),SUBR(13),
978169425Sgnn		     io[0],io[1],il,ir,t0,t1);
979169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(14),SUBR(14),
980169425Sgnn		     io[2],io[3],il,ir,t0,t1);
981169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(15),SUBR(15),
982169425Sgnn		     io[0],io[1],il,ir,t0,t1);
983169425Sgnn
984169425Sgnn    CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(16), SUBR(16), SUBL(17),SUBR(17),
985169425Sgnn		 t0,t1,il,ir);
986169425Sgnn
987169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(18),SUBR(18),
988169425Sgnn		     io[2],io[3],il,ir,t0,t1);
989169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(19),SUBR(19),
990169425Sgnn		     io[0],io[1],il,ir,t0,t1);
991169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(20),SUBR(20),
992169425Sgnn		     io[2],io[3],il,ir,t0,t1);
993169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(21),SUBR(21),
994169425Sgnn		     io[0],io[1],il,ir,t0,t1);
995169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(22),SUBR(22),
996169425Sgnn		     io[2],io[3],il,ir,t0,t1);
997169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(23),SUBR(23),
998169425Sgnn		     io[0],io[1],il,ir,t0,t1);
999169425Sgnn
1000169425Sgnn    /* post whitening but kw4 */
1001169425Sgnn    io[2] ^= SUBL(24);
1002169425Sgnn    io[3] ^= SUBR(24);
1003169425Sgnn
1004169425Sgnn    t0 = io[0];
1005169425Sgnn    t1 = io[1];
1006169425Sgnn    io[0] = io[2];
1007169425Sgnn    io[1] = io[3];
1008169425Sgnn    io[2] = t0;
1009169425Sgnn    io[3] = t1;
1010169425Sgnn}
1011169425Sgnn
1012169425Sgnnvoid
1013169425Sgnncamellia_decrypt128(const uint32_t *subkey, uint32_t *io)
1014169425Sgnn{
1015169425Sgnn    uint32_t il,ir,t0,t1;               /* temporary valiables */
1016169425Sgnn
1017169425Sgnn    /* pre whitening but absorb kw2*/
1018169425Sgnn    io[0] ^= SUBL(24);
1019169425Sgnn    io[1] ^= SUBR(24);
1020169425Sgnn
1021169425Sgnn    /* main iteration */
1022169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(23),SUBR(23),
1023169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1024169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(22),SUBR(22),
1025169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1026169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(21),SUBR(21),
1027169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1028169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(20),SUBR(20),
1029169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1030169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(19),SUBR(19),
1031169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1032169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(18),SUBR(18),
1033169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1034169425Sgnn
1035169425Sgnn    CAMELLIA_FLS(io[0],io[1],io[2],io[3],SUBL(17),SUBR(17),SUBL(16),SUBR(16),
1036169425Sgnn		 t0,t1,il,ir);
1037169425Sgnn
1038169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(15),SUBR(15),
1039169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1040169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(14),SUBR(14),
1041169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1042169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(13),SUBR(13),
1043169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1044169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(12),SUBR(12),
1045169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1046169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(11),SUBR(11),
1047169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1048169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(10),SUBR(10),
1049169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1050169425Sgnn
1051169425Sgnn    CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(9),SUBR(9), SUBL(8),SUBR(8),
1052169425Sgnn		 t0,t1,il,ir);
1053169425Sgnn
1054169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(7),SUBR(7),
1055169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1056169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(6),SUBR(6),
1057169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1058169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(5),SUBR(5),
1059169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1060169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(4),SUBR(4),
1061169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1062169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(3),SUBR(3),
1063169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1064169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(2),SUBR(2),
1065169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1066169425Sgnn
1067169425Sgnn    /* post whitening but kw4 */
1068169425Sgnn    io[2] ^= SUBL(0);
1069169425Sgnn    io[3] ^= SUBR(0);
1070169425Sgnn
1071169425Sgnn    t0 = io[0];
1072169425Sgnn    t1 = io[1];
1073169425Sgnn    io[0] = io[2];
1074169425Sgnn    io[1] = io[3];
1075169425Sgnn    io[2] = t0;
1076169425Sgnn    io[3] = t1;
1077169425Sgnn}
1078169425Sgnn
1079169425Sgnn/**
1080169425Sgnn * stuff for 192 and 256bit encryption/decryption
1081169425Sgnn */
1082169425Sgnnvoid
1083169425Sgnncamellia_encrypt256(const uint32_t *subkey, uint32_t *io)
1084169425Sgnn{
1085169425Sgnn    uint32_t il,ir,t0,t1;           /* temporary valiables */
1086169425Sgnn
1087169425Sgnn    /* pre whitening but absorb kw2*/
1088169425Sgnn    io[0] ^= SUBL(0);
1089169425Sgnn    io[1] ^= SUBR(0);
1090169425Sgnn
1091169425Sgnn    /* main iteration */
1092169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(2),SUBR(2),
1093169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1094169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(3),SUBR(3),
1095169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1096169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(4),SUBR(4),
1097169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1098169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(5),SUBR(5),
1099169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1100169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(6),SUBR(6),
1101169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1102169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(7),SUBR(7),
1103169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1104169425Sgnn
1105169425Sgnn    CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(8),SUBR(8), SUBL(9),SUBR(9),
1106169425Sgnn		 t0,t1,il,ir);
1107169425Sgnn
1108169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(10),SUBR(10),
1109169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1110169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(11),SUBR(11),
1111169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1112169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(12),SUBR(12),
1113169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1114169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(13),SUBR(13),
1115169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1116169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(14),SUBR(14),
1117169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1118169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(15),SUBR(15),
1119169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1120169425Sgnn
1121169425Sgnn    CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(16),SUBR(16), SUBL(17),SUBR(17),
1122169425Sgnn		 t0,t1,il,ir);
1123169425Sgnn
1124169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(18),SUBR(18),
1125169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1126169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(19),SUBR(19),
1127169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1128169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(20),SUBR(20),
1129169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1130169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(21),SUBR(21),
1131169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1132169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(22),SUBR(22),
1133169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1134169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(23),SUBR(23),
1135169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1136169425Sgnn
1137169425Sgnn    CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(24),SUBR(24), SUBL(25),SUBR(25),
1138169425Sgnn		 t0,t1,il,ir);
1139169425Sgnn
1140169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(26),SUBR(26),
1141169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1142169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(27),SUBR(27),
1143169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1144169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(28),SUBR(28),
1145169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1146169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(29),SUBR(29),
1147169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1148169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(30),SUBR(30),
1149169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1150169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(31),SUBR(31),
1151169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1152169425Sgnn
1153169425Sgnn    /* post whitening but kw4 */
1154169425Sgnn    io[2] ^= SUBL(32);
1155169425Sgnn    io[3] ^= SUBR(32);
1156169425Sgnn
1157169425Sgnn    t0 = io[0];
1158169425Sgnn    t1 = io[1];
1159169425Sgnn    io[0] = io[2];
1160169425Sgnn    io[1] = io[3];
1161169425Sgnn    io[2] = t0;
1162169425Sgnn    io[3] = t1;
1163169425Sgnn}
1164169425Sgnn
1165169425Sgnnvoid
1166169425Sgnncamellia_decrypt256(const uint32_t *subkey, uint32_t *io)
1167169425Sgnn{
1168169425Sgnn    uint32_t il,ir,t0,t1;           /* temporary valiables */
1169169425Sgnn
1170169425Sgnn    /* pre whitening but absorb kw2*/
1171169425Sgnn    io[0] ^= SUBL(32);
1172169425Sgnn    io[1] ^= SUBR(32);
1173169425Sgnn
1174169425Sgnn    /* main iteration */
1175169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(31),SUBR(31),
1176169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1177169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(30),SUBR(30),
1178169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1179169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(29),SUBR(29),
1180169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1181169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(28),SUBR(28),
1182169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1183169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(27),SUBR(27),
1184169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1185169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(26),SUBR(26),
1186169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1187169425Sgnn
1188169425Sgnn    CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(25),SUBR(25), SUBL(24),SUBR(24),
1189169425Sgnn		 t0,t1,il,ir);
1190169425Sgnn
1191169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(23),SUBR(23),
1192169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1193169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(22),SUBR(22),
1194169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1195169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(21),SUBR(21),
1196169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1197169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(20),SUBR(20),
1198169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1199169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(19),SUBR(19),
1200169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1201169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(18),SUBR(18),
1202169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1203169425Sgnn
1204169425Sgnn    CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(17),SUBR(17), SUBL(16),SUBR(16),
1205169425Sgnn		 t0,t1,il,ir);
1206169425Sgnn
1207169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(15),SUBR(15),
1208169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1209169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(14),SUBR(14),
1210169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1211169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(13),SUBR(13),
1212169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1213169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(12),SUBR(12),
1214169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1215169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(11),SUBR(11),
1216169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1217169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(10),SUBR(10),
1218169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1219169425Sgnn
1220169425Sgnn    CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(9),SUBR(9), SUBL(8),SUBR(8),
1221169425Sgnn		 t0,t1,il,ir);
1222169425Sgnn
1223169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(7),SUBR(7),
1224169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1225169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(6),SUBR(6),
1226169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1227169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(5),SUBR(5),
1228169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1229169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(4),SUBR(4),
1230169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1231169425Sgnn    CAMELLIA_ROUNDSM(io[0],io[1], SUBL(3),SUBR(3),
1232169425Sgnn		     io[2],io[3],il,ir,t0,t1);
1233169425Sgnn    CAMELLIA_ROUNDSM(io[2],io[3], SUBL(2),SUBR(2),
1234169425Sgnn		     io[0],io[1],il,ir,t0,t1);
1235169425Sgnn
1236169425Sgnn    /* post whitening but kw4 */
1237169425Sgnn    io[2] ^= SUBL(0);
1238169425Sgnn    io[3] ^= SUBR(0);
1239169425Sgnn
1240169425Sgnn    t0 = io[0];
1241169425Sgnn    t1 = io[1];
1242169425Sgnn    io[0] = io[2];
1243169425Sgnn    io[1] = io[3];
1244169425Sgnn    io[2] = t0;
1245169425Sgnn    io[3] = t1;
1246169425Sgnn}
1247169425Sgnn
1248169425Sgnnvoid
1249169425SgnnCamellia_Ekeygen(const int keyBitLength,
1250169425Sgnn		 const unsigned char *rawKey,
1251169425Sgnn		 uint32_t *subkey)
1252169425Sgnn{
1253169425Sgnn    KASSERT(keyBitLength == 128 || keyBitLength == 192 || keyBitLength == 256,
1254169425Sgnn	    ("Invalid key size (%d).", keyBitLength));
1255169425Sgnn
1256169425Sgnn    switch(keyBitLength) {
1257169425Sgnn    case 128:
1258169425Sgnn	camellia_setup128(rawKey, subkey);
1259169425Sgnn	break;
1260169425Sgnn    case 192:
1261169425Sgnn	camellia_setup192(rawKey, subkey);
1262169425Sgnn	break;
1263169425Sgnn    case 256:
1264169425Sgnn	camellia_setup256(rawKey, subkey);
1265169425Sgnn	break;
1266169425Sgnn    default:
1267169425Sgnn	break;
1268169425Sgnn    }
1269169425Sgnn}
1270169425Sgnnvoid
1271169425SgnnCamellia_EncryptBlock(const int keyBitLength,
1272169425Sgnn		      const unsigned char *plaintext,
1273169425Sgnn		      const uint32_t *subkey,
1274169425Sgnn		      unsigned char *ciphertext)
1275169425Sgnn{
1276169425Sgnn    uint32_t tmp[4];
1277169425Sgnn
1278169425Sgnn    tmp[0] = GETU32(plaintext);
1279169425Sgnn    tmp[1] = GETU32(plaintext + 4);
1280169425Sgnn    tmp[2] = GETU32(plaintext + 8);
1281169425Sgnn    tmp[3] = GETU32(plaintext + 12);
1282169425Sgnn
1283169425Sgnn    switch (keyBitLength) {
1284169425Sgnn    case 128:
1285169425Sgnn	camellia_encrypt128(subkey, tmp);
1286169425Sgnn	break;
1287169425Sgnn    case 192:
1288169425Sgnn	/* fall through */
1289169425Sgnn    case 256:
1290169425Sgnn	camellia_encrypt256(subkey, tmp);
1291169425Sgnn	break;
1292169425Sgnn    default:
1293169425Sgnn	break;
1294169425Sgnn    }
1295169425Sgnn
1296169425Sgnn    PUTU32(ciphertext,    tmp[0]);
1297169425Sgnn    PUTU32(ciphertext+4,  tmp[1]);
1298169425Sgnn    PUTU32(ciphertext+8,  tmp[2]);
1299169425Sgnn    PUTU32(ciphertext+12, tmp[3]);
1300169425Sgnn}
1301169425Sgnn
1302169425Sgnnvoid
1303169425SgnnCamellia_DecryptBlock(const int keyBitLength,
1304169425Sgnn		      const unsigned char *ciphertext,
1305169425Sgnn		      const uint32_t *subkey,
1306169425Sgnn		      unsigned char *plaintext)
1307169425Sgnn{
1308169425Sgnn    uint32_t tmp[4];
1309169425Sgnn
1310169425Sgnn    tmp[0] = GETU32(ciphertext);
1311169425Sgnn    tmp[1] = GETU32(ciphertext + 4);
1312169425Sgnn    tmp[2] = GETU32(ciphertext + 8);
1313169425Sgnn    tmp[3] = GETU32(ciphertext + 12);
1314169425Sgnn
1315169425Sgnn    switch (keyBitLength) {
1316169425Sgnn    case 128:
1317169425Sgnn	camellia_decrypt128(subkey, tmp);
1318169425Sgnn	break;
1319169425Sgnn    case 192:
1320169425Sgnn	/* fall through */
1321169425Sgnn    case 256:
1322169425Sgnn	camellia_decrypt256(subkey, tmp);
1323169425Sgnn	break;
1324169425Sgnn    default:
1325169425Sgnn	break;
1326169425Sgnn    }
1327169425Sgnn
1328169425Sgnn    PUTU32(plaintext,    tmp[0]);
1329169425Sgnn    PUTU32(plaintext+4,  tmp[1]);
1330169425Sgnn    PUTU32(plaintext+8,  tmp[2]);
1331169425Sgnn    PUTU32(plaintext+12, tmp[3]);
1332169425Sgnn}
1333