xref: /netbsd/sys/crypto/camellia/camellia.c (revision 8cf89151)
1*8cf89151Sgutteridge /* $NetBSD: camellia.c,v 1.3 2021/09/04 00:33:09 gutteridge Exp $ */
259188a09Sdrochner 
359188a09Sdrochner /* camellia.h ver 1.1.0
459188a09Sdrochner  *
559188a09Sdrochner  * Copyright (c) 2006
659188a09Sdrochner  * NTT (Nippon Telegraph and Telephone Corporation) . All rights reserved.
759188a09Sdrochner  *
859188a09Sdrochner  * Redistribution and use in source and binary forms, with or without
959188a09Sdrochner  * modification, are permitted provided that the following conditions
1059188a09Sdrochner  * are met:
1159188a09Sdrochner  * 1. Redistributions of source code must retain the above copyright
1259188a09Sdrochner  *   notice, this list of conditions and the following disclaimer as
1359188a09Sdrochner  *   the first lines of this file unmodified.
1459188a09Sdrochner  * 2. Redistributions in binary form must reproduce the above copyright
1559188a09Sdrochner  *   notice, this list of conditions and the following disclaimer in the
1659188a09Sdrochner  *   documentation and/or other materials provided with the distribution.
1759188a09Sdrochner  *
1859188a09Sdrochner  * THIS SOFTWARE IS PROVIDED BY NTT ``AS IS'' AND ANY EXPRESS OR
1959188a09Sdrochner  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2059188a09Sdrochner  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2159188a09Sdrochner  * IN NO EVENT SHALL NTT BE LIABLE FOR ANY DIRECT, INDIRECT,
2259188a09Sdrochner  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2359188a09Sdrochner  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2459188a09Sdrochner  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2559188a09Sdrochner  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2659188a09Sdrochner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2759188a09Sdrochner  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2859188a09Sdrochner  */
2959188a09Sdrochner 
3059188a09Sdrochner /*
3159188a09Sdrochner  * Algorithm Specification
3259188a09Sdrochner  *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
3359188a09Sdrochner  */
3459188a09Sdrochner 
3559188a09Sdrochner #include <sys/cdefs.h>
36*8cf89151Sgutteridge __KERNEL_RCSID(0, "$NetBSD: camellia.c,v 1.3 2021/09/04 00:33:09 gutteridge Exp $");
37*8cf89151Sgutteridge 
3859188a09Sdrochner #include <sys/types.h>
3959188a09Sdrochner #include <sys/systm.h>
402c510b81Spgoyette #include <sys/errno.h>
412c510b81Spgoyette #include <sys/module.h>
422c510b81Spgoyette 
4359188a09Sdrochner #include <crypto/camellia/camellia.h>
4459188a09Sdrochner 
4559188a09Sdrochner 
4659188a09Sdrochner /* key constants */
4759188a09Sdrochner 
4859188a09Sdrochner #define CAMELLIA_SIGMA1L (0xA09E667FL)
4959188a09Sdrochner #define CAMELLIA_SIGMA1R (0x3BCC908BL)
5059188a09Sdrochner #define CAMELLIA_SIGMA2L (0xB67AE858L)
5159188a09Sdrochner #define CAMELLIA_SIGMA2R (0x4CAA73B2L)
5259188a09Sdrochner #define CAMELLIA_SIGMA3L (0xC6EF372FL)
5359188a09Sdrochner #define CAMELLIA_SIGMA3R (0xE94F82BEL)
5459188a09Sdrochner #define CAMELLIA_SIGMA4L (0x54FF53A5L)
5559188a09Sdrochner #define CAMELLIA_SIGMA4R (0xF1D36F1CL)
5659188a09Sdrochner #define CAMELLIA_SIGMA5L (0x10E527FAL)
5759188a09Sdrochner #define CAMELLIA_SIGMA5R (0xDE682D1DL)
5859188a09Sdrochner #define CAMELLIA_SIGMA6L (0xB05688C2L)
5959188a09Sdrochner #define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
6059188a09Sdrochner 
6159188a09Sdrochner /*
6259188a09Sdrochner  *  macros
6359188a09Sdrochner  */
6459188a09Sdrochner #define GETU32(pt) (((uint32_t)(pt)[0] << 24)		\
6559188a09Sdrochner 		     ^ ((uint32_t)(pt)[1] << 16)	\
6659188a09Sdrochner 		     ^ ((uint32_t)(pt)[2] <<  8)	\
6759188a09Sdrochner 		     ^ ((uint32_t)(pt)[3]))
6859188a09Sdrochner 
6959188a09Sdrochner #define PUTU32(ct, st) {(ct)[0] = (uint8_t)((st) >> 24);	\
7059188a09Sdrochner 			(ct)[1] = (uint8_t)((st) >> 16);	\
7159188a09Sdrochner 			(ct)[2] = (uint8_t)((st) >>  8);	\
7259188a09Sdrochner 			(ct)[3] = (uint8_t)(st);}
7359188a09Sdrochner 
7459188a09Sdrochner #define SUBL(INDEX) (subkey[(INDEX)*2+1])
7559188a09Sdrochner #define SUBR(INDEX) (subkey[(INDEX)*2])
7659188a09Sdrochner 
7759188a09Sdrochner #define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
7859188a09Sdrochner #define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
7959188a09Sdrochner #define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
8059188a09Sdrochner 
8159188a09Sdrochner #define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits)	\
8259188a09Sdrochner     do {						\
8359188a09Sdrochner 	w0 = ll;					\
8459188a09Sdrochner 	ll = (ll << bits) + (lr >> (32 - bits));	\
8559188a09Sdrochner 	lr = (lr << bits) + (rl >> (32 - bits));	\
8659188a09Sdrochner 	rl = (rl << bits) + (rr >> (32 - bits));	\
8759188a09Sdrochner 	rr = (rr << bits) + (w0 >> (32 - bits));	\
8859188a09Sdrochner     } while(0)
8959188a09Sdrochner 
9059188a09Sdrochner #define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits)	\
9159188a09Sdrochner     do {						\
9259188a09Sdrochner 	w0 = ll;					\
9359188a09Sdrochner 	w1 = lr;					\
9459188a09Sdrochner 	ll = (lr << (bits - 32)) + (rl >> (64 - bits));	\
9559188a09Sdrochner 	lr = (rl << (bits - 32)) + (rr >> (64 - bits));	\
9659188a09Sdrochner 	rl = (rr << (bits - 32)) + (w0 >> (64 - bits));	\
9759188a09Sdrochner 	rr = (w0 << (bits - 32)) + (w1 >> (64 - bits));	\
9859188a09Sdrochner     } while(0)
9959188a09Sdrochner 
10059188a09Sdrochner #define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
10159188a09Sdrochner #define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
10259188a09Sdrochner #define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
10359188a09Sdrochner #define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
10459188a09Sdrochner 
10559188a09Sdrochner #define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)	\
10659188a09Sdrochner     do {							\
10759188a09Sdrochner 	il = xl ^ kl;						\
10859188a09Sdrochner 	ir = xr ^ kr;						\
10959188a09Sdrochner 	t0 = il >> 16;						\
11059188a09Sdrochner 	t1 = ir >> 16;						\
11159188a09Sdrochner 	yl = CAMELLIA_SP1110(ir & 0xff)				\
11259188a09Sdrochner 	    ^ CAMELLIA_SP0222((t1 >> 8) & 0xff)			\
11359188a09Sdrochner 	    ^ CAMELLIA_SP3033(t1 & 0xff)			\
11459188a09Sdrochner 	    ^ CAMELLIA_SP4404((ir >> 8) & 0xff);		\
11559188a09Sdrochner 	yr = CAMELLIA_SP1110((t0 >> 8) & 0xff)			\
11659188a09Sdrochner 	    ^ CAMELLIA_SP0222(t0 & 0xff)			\
11759188a09Sdrochner 	    ^ CAMELLIA_SP3033((il >> 8) & 0xff)			\
11859188a09Sdrochner 	    ^ CAMELLIA_SP4404(il & 0xff);			\
11959188a09Sdrochner 	yl ^= yr;						\
12059188a09Sdrochner 	yr = CAMELLIA_RR8(yr);					\
12159188a09Sdrochner 	yr ^= yl;						\
12259188a09Sdrochner     } while(0)
12359188a09Sdrochner 
12459188a09Sdrochner 
12559188a09Sdrochner #define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
12659188a09Sdrochner     do {								\
12759188a09Sdrochner 	t0 = kll;							\
12859188a09Sdrochner 	t2 = krr;							\
12959188a09Sdrochner 	t0 &= ll;							\
13059188a09Sdrochner 	t2 |= rr;							\
13159188a09Sdrochner 	rl ^= t2;							\
13259188a09Sdrochner 	lr ^= CAMELLIA_RL1(t0);						\
13359188a09Sdrochner 	t3 = krl;							\
13459188a09Sdrochner 	t1 = klr;							\
13559188a09Sdrochner 	t3 &= rl;							\
13659188a09Sdrochner 	t1 |= lr;							\
13759188a09Sdrochner 	ll ^= t1;							\
13859188a09Sdrochner 	rr ^= CAMELLIA_RL1(t3);						\
13959188a09Sdrochner     } while(0)
14059188a09Sdrochner 
14159188a09Sdrochner #define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)	\
14259188a09Sdrochner     do {								\
14359188a09Sdrochner 	ir =  CAMELLIA_SP1110(xr & 0xff);				\
14459188a09Sdrochner 	il =  CAMELLIA_SP1110((xl>>24) & 0xff);				\
14559188a09Sdrochner 	ir ^= CAMELLIA_SP0222((xr>>24) & 0xff);				\
14659188a09Sdrochner 	il ^= CAMELLIA_SP0222((xl>>16) & 0xff);				\
14759188a09Sdrochner 	ir ^= CAMELLIA_SP3033((xr>>16) & 0xff);				\
14859188a09Sdrochner 	il ^= CAMELLIA_SP3033((xl>>8) & 0xff);				\
14959188a09Sdrochner 	ir ^= CAMELLIA_SP4404((xr>>8) & 0xff);				\
15059188a09Sdrochner 	il ^= CAMELLIA_SP4404(xl & 0xff);				\
15159188a09Sdrochner 	il ^= kl;							\
15259188a09Sdrochner 	ir ^= kr;							\
15359188a09Sdrochner 	ir ^= il;							\
15459188a09Sdrochner 	il = CAMELLIA_RR8(il);						\
15559188a09Sdrochner 	il ^= ir;							\
15659188a09Sdrochner 	yl ^= ir;							\
15759188a09Sdrochner 	yr ^= il;							\
15859188a09Sdrochner     } while(0)
15959188a09Sdrochner 
16059188a09Sdrochner 
16159188a09Sdrochner static const uint32_t camellia_sp1110[256] = {
16259188a09Sdrochner     0x70707000,0x82828200,0x2c2c2c00,0xececec00,
16359188a09Sdrochner     0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
16459188a09Sdrochner     0xe4e4e400,0x85858500,0x57575700,0x35353500,
16559188a09Sdrochner     0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
16659188a09Sdrochner     0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
16759188a09Sdrochner     0x45454500,0x19191900,0xa5a5a500,0x21212100,
16859188a09Sdrochner     0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
16959188a09Sdrochner     0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
17059188a09Sdrochner     0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
17159188a09Sdrochner     0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
17259188a09Sdrochner     0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
17359188a09Sdrochner     0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
17459188a09Sdrochner     0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
17559188a09Sdrochner     0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
17659188a09Sdrochner     0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
17759188a09Sdrochner     0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
17859188a09Sdrochner     0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
17959188a09Sdrochner     0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
18059188a09Sdrochner     0x74747400,0x12121200,0x2b2b2b00,0x20202000,
18159188a09Sdrochner     0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
18259188a09Sdrochner     0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
18359188a09Sdrochner     0x34343400,0x7e7e7e00,0x76767600,0x05050500,
18459188a09Sdrochner     0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
18559188a09Sdrochner     0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
18659188a09Sdrochner     0x14141400,0x58585800,0x3a3a3a00,0x61616100,
18759188a09Sdrochner     0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
18859188a09Sdrochner     0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
18959188a09Sdrochner     0x53535300,0x18181800,0xf2f2f200,0x22222200,
19059188a09Sdrochner     0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
19159188a09Sdrochner     0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
19259188a09Sdrochner     0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
19359188a09Sdrochner     0x60606000,0xfcfcfc00,0x69696900,0x50505000,
19459188a09Sdrochner     0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
19559188a09Sdrochner     0xa1a1a100,0x89898900,0x62626200,0x97979700,
19659188a09Sdrochner     0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
19759188a09Sdrochner     0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
19859188a09Sdrochner     0x10101000,0xc4c4c400,0x00000000,0x48484800,
19959188a09Sdrochner     0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
20059188a09Sdrochner     0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
20159188a09Sdrochner     0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
20259188a09Sdrochner     0x87878700,0x5c5c5c00,0x83838300,0x02020200,
20359188a09Sdrochner     0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
20459188a09Sdrochner     0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
20559188a09Sdrochner     0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
20659188a09Sdrochner     0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
20759188a09Sdrochner     0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
20859188a09Sdrochner     0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
20959188a09Sdrochner     0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
21059188a09Sdrochner     0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
21159188a09Sdrochner     0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
21259188a09Sdrochner     0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
21359188a09Sdrochner     0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
21459188a09Sdrochner     0x78787800,0x98989800,0x06060600,0x6a6a6a00,
21559188a09Sdrochner     0xe7e7e700,0x46464600,0x71717100,0xbababa00,
21659188a09Sdrochner     0xd4d4d400,0x25252500,0xababab00,0x42424200,
21759188a09Sdrochner     0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
21859188a09Sdrochner     0x72727200,0x07070700,0xb9b9b900,0x55555500,
21959188a09Sdrochner     0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
22059188a09Sdrochner     0x36363600,0x49494900,0x2a2a2a00,0x68686800,
22159188a09Sdrochner     0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
22259188a09Sdrochner     0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
22359188a09Sdrochner     0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
22459188a09Sdrochner     0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
22559188a09Sdrochner     0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
22659188a09Sdrochner };
22759188a09Sdrochner 
22859188a09Sdrochner static const uint32_t camellia_sp0222[256] = {
22959188a09Sdrochner     0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
23059188a09Sdrochner     0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
23159188a09Sdrochner     0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
23259188a09Sdrochner     0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
23359188a09Sdrochner     0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
23459188a09Sdrochner     0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
23559188a09Sdrochner     0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
23659188a09Sdrochner     0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
23759188a09Sdrochner     0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
23859188a09Sdrochner     0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
23959188a09Sdrochner     0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
24059188a09Sdrochner     0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
24159188a09Sdrochner     0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
24259188a09Sdrochner     0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
24359188a09Sdrochner     0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
24459188a09Sdrochner     0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
24559188a09Sdrochner     0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
24659188a09Sdrochner     0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
24759188a09Sdrochner     0x00e8e8e8,0x00242424,0x00565656,0x00404040,
24859188a09Sdrochner     0x00e1e1e1,0x00636363,0x00090909,0x00333333,
24959188a09Sdrochner     0x00bfbfbf,0x00989898,0x00979797,0x00858585,
25059188a09Sdrochner     0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
25159188a09Sdrochner     0x00dadada,0x006f6f6f,0x00535353,0x00626262,
25259188a09Sdrochner     0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
25359188a09Sdrochner     0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
25459188a09Sdrochner     0x00bdbdbd,0x00363636,0x00222222,0x00383838,
25559188a09Sdrochner     0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
25659188a09Sdrochner     0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
25759188a09Sdrochner     0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
25859188a09Sdrochner     0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
25959188a09Sdrochner     0x00484848,0x00101010,0x00d1d1d1,0x00515151,
26059188a09Sdrochner     0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
26159188a09Sdrochner     0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
26259188a09Sdrochner     0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
26359188a09Sdrochner     0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
26459188a09Sdrochner     0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
26559188a09Sdrochner     0x00202020,0x00898989,0x00000000,0x00909090,
26659188a09Sdrochner     0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
26759188a09Sdrochner     0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
26859188a09Sdrochner     0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
26959188a09Sdrochner     0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
27059188a09Sdrochner     0x009b9b9b,0x00949494,0x00212121,0x00666666,
27159188a09Sdrochner     0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
27259188a09Sdrochner     0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
27359188a09Sdrochner     0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
27459188a09Sdrochner     0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
27559188a09Sdrochner     0x00030303,0x002d2d2d,0x00dedede,0x00969696,
27659188a09Sdrochner     0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
27759188a09Sdrochner     0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
27859188a09Sdrochner     0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
27959188a09Sdrochner     0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
28059188a09Sdrochner     0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
28159188a09Sdrochner     0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
28259188a09Sdrochner     0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
28359188a09Sdrochner     0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
28459188a09Sdrochner     0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
28559188a09Sdrochner     0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
28659188a09Sdrochner     0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
28759188a09Sdrochner     0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
28859188a09Sdrochner     0x00787878,0x00707070,0x00e3e3e3,0x00494949,
28959188a09Sdrochner     0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
29059188a09Sdrochner     0x00777777,0x00939393,0x00868686,0x00838383,
29159188a09Sdrochner     0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
29259188a09Sdrochner     0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
29359188a09Sdrochner };
29459188a09Sdrochner 
29559188a09Sdrochner static const uint32_t camellia_sp3033[256] = {
29659188a09Sdrochner     0x38003838,0x41004141,0x16001616,0x76007676,
29759188a09Sdrochner     0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
29859188a09Sdrochner     0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
29959188a09Sdrochner     0x75007575,0x06000606,0x57005757,0xa000a0a0,
30059188a09Sdrochner     0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
30159188a09Sdrochner     0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
30259188a09Sdrochner     0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
30359188a09Sdrochner     0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
30459188a09Sdrochner     0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
30559188a09Sdrochner     0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
30659188a09Sdrochner     0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
30759188a09Sdrochner     0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
30859188a09Sdrochner     0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
30959188a09Sdrochner     0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
31059188a09Sdrochner     0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
31159188a09Sdrochner     0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
31259188a09Sdrochner     0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
31359188a09Sdrochner     0xfd00fdfd,0x66006666,0x58005858,0x96009696,
31459188a09Sdrochner     0x3a003a3a,0x09000909,0x95009595,0x10001010,
31559188a09Sdrochner     0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
31659188a09Sdrochner     0xef00efef,0x26002626,0xe500e5e5,0x61006161,
31759188a09Sdrochner     0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
31859188a09Sdrochner     0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
31959188a09Sdrochner     0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
32059188a09Sdrochner     0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
32159188a09Sdrochner     0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
32259188a09Sdrochner     0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
32359188a09Sdrochner     0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
32459188a09Sdrochner     0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
32559188a09Sdrochner     0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
32659188a09Sdrochner     0x12001212,0x04000404,0x74007474,0x54005454,
32759188a09Sdrochner     0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
32859188a09Sdrochner     0x55005555,0x68006868,0x50005050,0xbe00bebe,
32959188a09Sdrochner     0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
33059188a09Sdrochner     0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
33159188a09Sdrochner     0x70007070,0xff00ffff,0x32003232,0x69006969,
33259188a09Sdrochner     0x08000808,0x62006262,0x00000000,0x24002424,
33359188a09Sdrochner     0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
33459188a09Sdrochner     0x45004545,0x81008181,0x73007373,0x6d006d6d,
33559188a09Sdrochner     0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
33659188a09Sdrochner     0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
33759188a09Sdrochner     0xe600e6e6,0x25002525,0x48004848,0x99009999,
33859188a09Sdrochner     0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
33959188a09Sdrochner     0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
34059188a09Sdrochner     0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
34159188a09Sdrochner     0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
34259188a09Sdrochner     0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
34359188a09Sdrochner     0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
34459188a09Sdrochner     0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
34559188a09Sdrochner     0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
34659188a09Sdrochner     0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
34759188a09Sdrochner     0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
34859188a09Sdrochner     0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
34959188a09Sdrochner     0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
35059188a09Sdrochner     0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
35159188a09Sdrochner     0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
35259188a09Sdrochner     0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
35359188a09Sdrochner     0x7c007c7c,0x77007777,0x56005656,0x05000505,
35459188a09Sdrochner     0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
35559188a09Sdrochner     0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
35659188a09Sdrochner     0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
35759188a09Sdrochner     0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
35859188a09Sdrochner     0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
35959188a09Sdrochner     0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
36059188a09Sdrochner };
36159188a09Sdrochner 
36259188a09Sdrochner static const uint32_t camellia_sp4404[256] = {
36359188a09Sdrochner     0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
36459188a09Sdrochner     0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
36559188a09Sdrochner     0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
36659188a09Sdrochner     0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
36759188a09Sdrochner     0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
36859188a09Sdrochner     0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
36959188a09Sdrochner     0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
37059188a09Sdrochner     0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
37159188a09Sdrochner     0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
37259188a09Sdrochner     0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
37359188a09Sdrochner     0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
37459188a09Sdrochner     0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
37559188a09Sdrochner     0x14140014,0x3a3a003a,0xdede00de,0x11110011,
37659188a09Sdrochner     0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
37759188a09Sdrochner     0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
37859188a09Sdrochner     0x24240024,0xe8e800e8,0x60600060,0x69690069,
37959188a09Sdrochner     0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
38059188a09Sdrochner     0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
38159188a09Sdrochner     0x10100010,0x00000000,0xa3a300a3,0x75750075,
38259188a09Sdrochner     0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
38359188a09Sdrochner     0x87870087,0x83830083,0xcdcd00cd,0x90900090,
38459188a09Sdrochner     0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
38559188a09Sdrochner     0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
38659188a09Sdrochner     0x81810081,0x6f6f006f,0x13130013,0x63630063,
38759188a09Sdrochner     0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
38859188a09Sdrochner     0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
38959188a09Sdrochner     0x78780078,0x06060006,0xe7e700e7,0x71710071,
39059188a09Sdrochner     0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
39159188a09Sdrochner     0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
39259188a09Sdrochner     0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
39359188a09Sdrochner     0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
39459188a09Sdrochner     0x15150015,0xadad00ad,0x77770077,0x80800080,
39559188a09Sdrochner     0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
39659188a09Sdrochner     0x85850085,0x35350035,0x0c0c000c,0x41410041,
39759188a09Sdrochner     0xefef00ef,0x93930093,0x19190019,0x21210021,
39859188a09Sdrochner     0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
39959188a09Sdrochner     0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
40059188a09Sdrochner     0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
40159188a09Sdrochner     0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
40259188a09Sdrochner     0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
40359188a09Sdrochner     0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
40459188a09Sdrochner     0x12120012,0x20200020,0xb1b100b1,0x99990099,
40559188a09Sdrochner     0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
40659188a09Sdrochner     0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
40759188a09Sdrochner     0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
40859188a09Sdrochner     0x0f0f000f,0x16160016,0x18180018,0x22220022,
40959188a09Sdrochner     0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
41059188a09Sdrochner     0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
41159188a09Sdrochner     0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
41259188a09Sdrochner     0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
41359188a09Sdrochner     0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
41459188a09Sdrochner     0x03030003,0xdada00da,0x3f3f003f,0x94940094,
41559188a09Sdrochner     0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
41659188a09Sdrochner     0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
41759188a09Sdrochner     0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
41859188a09Sdrochner     0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
41959188a09Sdrochner     0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
42059188a09Sdrochner     0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
42159188a09Sdrochner     0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
42259188a09Sdrochner     0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
42359188a09Sdrochner     0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
42459188a09Sdrochner     0x49490049,0x68680068,0x38380038,0xa4a400a4,
42559188a09Sdrochner     0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
42659188a09Sdrochner     0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
42759188a09Sdrochner };
42859188a09Sdrochner 
42959188a09Sdrochner 
43059188a09Sdrochner /*
43159188a09Sdrochner  * Stuff related to the Camellia key schedule
43259188a09Sdrochner  */
43359188a09Sdrochner #define subl(x) subL[(x)]
43459188a09Sdrochner #define subr(x) subR[(x)]
43559188a09Sdrochner 
43659188a09Sdrochner void
camellia_setup128(const unsigned char * key,uint32_t * subkey)43759188a09Sdrochner camellia_setup128(const unsigned char *key, uint32_t *subkey)
43859188a09Sdrochner {
43959188a09Sdrochner     uint32_t kll, klr, krl, krr;
44059188a09Sdrochner     uint32_t il, ir, t0, t1, w0, w1;
44159188a09Sdrochner     uint32_t kw4l, kw4r, dw, tl, tr;
44259188a09Sdrochner     uint32_t subL[26];
44359188a09Sdrochner     uint32_t subR[26];
44459188a09Sdrochner 
44559188a09Sdrochner     /*
44659188a09Sdrochner      *  k == kll || klr || krl || krr (|| is concatination)
44759188a09Sdrochner      */
44859188a09Sdrochner     kll = GETU32(key     );
44959188a09Sdrochner     klr = GETU32(key +  4);
45059188a09Sdrochner     krl = GETU32(key +  8);
45159188a09Sdrochner     krr = GETU32(key + 12);
45259188a09Sdrochner     /*
45359188a09Sdrochner      * generate KL dependent subkeys
45459188a09Sdrochner      */
45559188a09Sdrochner     subl(0) = kll; subr(0) = klr;
45659188a09Sdrochner     subl(1) = krl; subr(1) = krr;
45759188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
45859188a09Sdrochner     subl(4) = kll; subr(4) = klr;
45959188a09Sdrochner     subl(5) = krl; subr(5) = krr;
46059188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
46159188a09Sdrochner     subl(10) = kll; subr(10) = klr;
46259188a09Sdrochner     subl(11) = krl; subr(11) = krr;
46359188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
46459188a09Sdrochner     subl(13) = krl; subr(13) = krr;
46559188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
46659188a09Sdrochner     subl(16) = kll; subr(16) = klr;
46759188a09Sdrochner     subl(17) = krl; subr(17) = krr;
46859188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
46959188a09Sdrochner     subl(18) = kll; subr(18) = klr;
47059188a09Sdrochner     subl(19) = krl; subr(19) = krr;
47159188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
47259188a09Sdrochner     subl(22) = kll; subr(22) = klr;
47359188a09Sdrochner     subl(23) = krl; subr(23) = krr;
47459188a09Sdrochner 
47559188a09Sdrochner     /* generate KA */
47659188a09Sdrochner     kll = subl(0); klr = subr(0);
47759188a09Sdrochner     krl = subl(1); krr = subr(1);
47859188a09Sdrochner     CAMELLIA_F(kll, klr, CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
47959188a09Sdrochner 	       w0, w1, il, ir, t0, t1);
48059188a09Sdrochner     krl ^= w0; krr ^= w1;
48159188a09Sdrochner     CAMELLIA_F(krl, krr, CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
48259188a09Sdrochner 	       kll, klr, il, ir, t0, t1);
48359188a09Sdrochner     CAMELLIA_F(kll, klr, CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
48459188a09Sdrochner 	       krl, krr, il, ir, t0, t1);
48559188a09Sdrochner     krl ^= w0; krr ^= w1;
48659188a09Sdrochner     CAMELLIA_F(krl, krr, CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
48759188a09Sdrochner 	       w0, w1, il, ir, t0, t1);
48859188a09Sdrochner     kll ^= w0; klr ^= w1;
48959188a09Sdrochner 
49059188a09Sdrochner     /* generate KA dependent subkeys */
49159188a09Sdrochner     subl(2) = kll; subr(2) = klr;
49259188a09Sdrochner     subl(3) = krl; subr(3) = krr;
49359188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
49459188a09Sdrochner     subl(6) = kll; subr(6) = klr;
49559188a09Sdrochner     subl(7) = krl; subr(7) = krr;
49659188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
49759188a09Sdrochner     subl(8) = kll; subr(8) = klr;
49859188a09Sdrochner     subl(9) = krl; subr(9) = krr;
49959188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
50059188a09Sdrochner     subl(12) = kll; subr(12) = klr;
50159188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
50259188a09Sdrochner     subl(14) = kll; subr(14) = klr;
50359188a09Sdrochner     subl(15) = krl; subr(15) = krr;
50459188a09Sdrochner     CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
50559188a09Sdrochner     subl(20) = kll; subr(20) = klr;
50659188a09Sdrochner     subl(21) = krl; subr(21) = krr;
50759188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
50859188a09Sdrochner     subl(24) = kll; subr(24) = klr;
50959188a09Sdrochner     subl(25) = krl; subr(25) = krr;
51059188a09Sdrochner 
51159188a09Sdrochner 
51259188a09Sdrochner     /* absorb kw2 to other subkeys */
51359188a09Sdrochner     subl(3) ^= subl(1); subr(3) ^= subr(1);
51459188a09Sdrochner     subl(5) ^= subl(1); subr(5) ^= subr(1);
51559188a09Sdrochner     subl(7) ^= subl(1); subr(7) ^= subr(1);
51659188a09Sdrochner     subl(1) ^= subr(1) & ~subr(9);
51759188a09Sdrochner     dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
51859188a09Sdrochner     subl(11) ^= subl(1); subr(11) ^= subr(1);
51959188a09Sdrochner     subl(13) ^= subl(1); subr(13) ^= subr(1);
52059188a09Sdrochner     subl(15) ^= subl(1); subr(15) ^= subr(1);
52159188a09Sdrochner     subl(1) ^= subr(1) & ~subr(17);
52259188a09Sdrochner     dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
52359188a09Sdrochner     subl(19) ^= subl(1); subr(19) ^= subr(1);
52459188a09Sdrochner     subl(21) ^= subl(1); subr(21) ^= subr(1);
52559188a09Sdrochner     subl(23) ^= subl(1); subr(23) ^= subr(1);
52659188a09Sdrochner     subl(24) ^= subl(1); subr(24) ^= subr(1);
52759188a09Sdrochner 
52859188a09Sdrochner     /* absorb kw4 to other subkeys */
52959188a09Sdrochner     kw4l = subl(25); kw4r = subr(25);
53059188a09Sdrochner     subl(22) ^= kw4l; subr(22) ^= kw4r;
53159188a09Sdrochner     subl(20) ^= kw4l; subr(20) ^= kw4r;
53259188a09Sdrochner     subl(18) ^= kw4l; subr(18) ^= kw4r;
53359188a09Sdrochner     kw4l ^= kw4r & ~subr(16);
53459188a09Sdrochner     dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
53559188a09Sdrochner     subl(14) ^= kw4l; subr(14) ^= kw4r;
53659188a09Sdrochner     subl(12) ^= kw4l; subr(12) ^= kw4r;
53759188a09Sdrochner     subl(10) ^= kw4l; subr(10) ^= kw4r;
53859188a09Sdrochner     kw4l ^= kw4r & ~subr(8);
53959188a09Sdrochner     dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
54059188a09Sdrochner     subl(6) ^= kw4l; subr(6) ^= kw4r;
54159188a09Sdrochner     subl(4) ^= kw4l; subr(4) ^= kw4r;
54259188a09Sdrochner     subl(2) ^= kw4l; subr(2) ^= kw4r;
54359188a09Sdrochner     subl(0) ^= kw4l; subr(0) ^= kw4r;
54459188a09Sdrochner 
54559188a09Sdrochner     /* key XOR is end of F-function */
54659188a09Sdrochner     SUBL(0) = subl(0) ^ subl(2);
54759188a09Sdrochner     SUBR(0) = subr(0) ^ subr(2);
54859188a09Sdrochner     SUBL(2) = subl(3);
54959188a09Sdrochner     SUBR(2) = subr(3);
55059188a09Sdrochner     SUBL(3) = subl(2) ^ subl(4);
55159188a09Sdrochner     SUBR(3) = subr(2) ^ subr(4);
55259188a09Sdrochner     SUBL(4) = subl(3) ^ subl(5);
55359188a09Sdrochner     SUBR(4) = subr(3) ^ subr(5);
55459188a09Sdrochner     SUBL(5) = subl(4) ^ subl(6);
55559188a09Sdrochner     SUBR(5) = subr(4) ^ subr(6);
55659188a09Sdrochner     SUBL(6) = subl(5) ^ subl(7);
55759188a09Sdrochner     SUBR(6) = subr(5) ^ subr(7);
55859188a09Sdrochner     tl = subl(10) ^ (subr(10) & ~subr(8));
55959188a09Sdrochner     dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
56059188a09Sdrochner     SUBL(7) = subl(6) ^ tl;
56159188a09Sdrochner     SUBR(7) = subr(6) ^ tr;
56259188a09Sdrochner     SUBL(8) = subl(8);
56359188a09Sdrochner     SUBR(8) = subr(8);
56459188a09Sdrochner     SUBL(9) = subl(9);
56559188a09Sdrochner     SUBR(9) = subr(9);
56659188a09Sdrochner     tl = subl(7) ^ (subr(7) & ~subr(9));
56759188a09Sdrochner     dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
56859188a09Sdrochner     SUBL(10) = tl ^ subl(11);
56959188a09Sdrochner     SUBR(10) = tr ^ subr(11);
57059188a09Sdrochner     SUBL(11) = subl(10) ^ subl(12);
57159188a09Sdrochner     SUBR(11) = subr(10) ^ subr(12);
57259188a09Sdrochner     SUBL(12) = subl(11) ^ subl(13);
57359188a09Sdrochner     SUBR(12) = subr(11) ^ subr(13);
57459188a09Sdrochner     SUBL(13) = subl(12) ^ subl(14);
57559188a09Sdrochner     SUBR(13) = subr(12) ^ subr(14);
57659188a09Sdrochner     SUBL(14) = subl(13) ^ subl(15);
57759188a09Sdrochner     SUBR(14) = subr(13) ^ subr(15);
57859188a09Sdrochner     tl = subl(18) ^ (subr(18) & ~subr(16));
57959188a09Sdrochner     dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
58059188a09Sdrochner     SUBL(15) = subl(14) ^ tl;
58159188a09Sdrochner     SUBR(15) = subr(14) ^ tr;
58259188a09Sdrochner     SUBL(16) = subl(16);
58359188a09Sdrochner     SUBR(16) = subr(16);
58459188a09Sdrochner     SUBL(17) = subl(17);
58559188a09Sdrochner     SUBR(17) = subr(17);
58659188a09Sdrochner     tl = subl(15) ^ (subr(15) & ~subr(17));
58759188a09Sdrochner     dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
58859188a09Sdrochner     SUBL(18) = tl ^ subl(19);
58959188a09Sdrochner     SUBR(18) = tr ^ subr(19);
59059188a09Sdrochner     SUBL(19) = subl(18) ^ subl(20);
59159188a09Sdrochner     SUBR(19) = subr(18) ^ subr(20);
59259188a09Sdrochner     SUBL(20) = subl(19) ^ subl(21);
59359188a09Sdrochner     SUBR(20) = subr(19) ^ subr(21);
59459188a09Sdrochner     SUBL(21) = subl(20) ^ subl(22);
59559188a09Sdrochner     SUBR(21) = subr(20) ^ subr(22);
59659188a09Sdrochner     SUBL(22) = subl(21) ^ subl(23);
59759188a09Sdrochner     SUBR(22) = subr(21) ^ subr(23);
59859188a09Sdrochner     SUBL(23) = subl(22);
59959188a09Sdrochner     SUBR(23) = subr(22);
60059188a09Sdrochner     SUBL(24) = subl(24) ^ subl(23);
60159188a09Sdrochner     SUBR(24) = subr(24) ^ subr(23);
60259188a09Sdrochner 
60359188a09Sdrochner     /* apply the inverse of the last half of P-function */
60459188a09Sdrochner     dw = SUBL(2) ^ SUBR(2), dw = CAMELLIA_RL8(dw);
60559188a09Sdrochner     SUBR(2) = SUBL(2) ^ dw, SUBL(2) = dw;
60659188a09Sdrochner     dw = SUBL(3) ^ SUBR(3), dw = CAMELLIA_RL8(dw);
60759188a09Sdrochner     SUBR(3) = SUBL(3) ^ dw, SUBL(3) = dw;
60859188a09Sdrochner     dw = SUBL(4) ^ SUBR(4), dw = CAMELLIA_RL8(dw);
60959188a09Sdrochner     SUBR(4) = SUBL(4) ^ dw, SUBL(4) = dw;
61059188a09Sdrochner     dw = SUBL(5) ^ SUBR(5), dw = CAMELLIA_RL8(dw);
61159188a09Sdrochner     SUBR(5) = SUBL(5) ^ dw, SUBL(5) = dw;
61259188a09Sdrochner     dw = SUBL(6) ^ SUBR(6), dw = CAMELLIA_RL8(dw);
61359188a09Sdrochner     SUBR(6) = SUBL(6) ^ dw, SUBL(6) = dw;
61459188a09Sdrochner     dw = SUBL(7) ^ SUBR(7), dw = CAMELLIA_RL8(dw);
61559188a09Sdrochner     SUBR(7) = SUBL(7) ^ dw, SUBL(7) = dw;
61659188a09Sdrochner     dw = SUBL(10) ^ SUBR(10), dw = CAMELLIA_RL8(dw);
61759188a09Sdrochner     SUBR(10) = SUBL(10) ^ dw, SUBL(10) = dw;
61859188a09Sdrochner     dw = SUBL(11) ^ SUBR(11), dw = CAMELLIA_RL8(dw);
61959188a09Sdrochner     SUBR(11) = SUBL(11) ^ dw, SUBL(11) = dw;
62059188a09Sdrochner     dw = SUBL(12) ^ SUBR(12), dw = CAMELLIA_RL8(dw);
62159188a09Sdrochner     SUBR(12) = SUBL(12) ^ dw, SUBL(12) = dw;
62259188a09Sdrochner     dw = SUBL(13) ^ SUBR(13), dw = CAMELLIA_RL8(dw);
62359188a09Sdrochner     SUBR(13) = SUBL(13) ^ dw, SUBL(13) = dw;
62459188a09Sdrochner     dw = SUBL(14) ^ SUBR(14), dw = CAMELLIA_RL8(dw);
62559188a09Sdrochner     SUBR(14) = SUBL(14) ^ dw, SUBL(14) = dw;
62659188a09Sdrochner     dw = SUBL(15) ^ SUBR(15), dw = CAMELLIA_RL8(dw);
62759188a09Sdrochner     SUBR(15) = SUBL(15) ^ dw, SUBL(15) = dw;
62859188a09Sdrochner     dw = SUBL(18) ^ SUBR(18), dw = CAMELLIA_RL8(dw);
62959188a09Sdrochner     SUBR(18) = SUBL(18) ^ dw, SUBL(18) = dw;
63059188a09Sdrochner     dw = SUBL(19) ^ SUBR(19), dw = CAMELLIA_RL8(dw);
63159188a09Sdrochner     SUBR(19) = SUBL(19) ^ dw, SUBL(19) = dw;
63259188a09Sdrochner     dw = SUBL(20) ^ SUBR(20), dw = CAMELLIA_RL8(dw);
63359188a09Sdrochner     SUBR(20) = SUBL(20) ^ dw, SUBL(20) = dw;
63459188a09Sdrochner     dw = SUBL(21) ^ SUBR(21), dw = CAMELLIA_RL8(dw);
63559188a09Sdrochner     SUBR(21) = SUBL(21) ^ dw, SUBL(21) = dw;
63659188a09Sdrochner     dw = SUBL(22) ^ SUBR(22), dw = CAMELLIA_RL8(dw);
63759188a09Sdrochner     SUBR(22) = SUBL(22) ^ dw, SUBL(22) = dw;
63859188a09Sdrochner     dw = SUBL(23) ^ SUBR(23), dw = CAMELLIA_RL8(dw);
63959188a09Sdrochner     SUBR(23) = SUBL(23) ^ dw, SUBL(23) = dw;
64059188a09Sdrochner }
64159188a09Sdrochner 
64259188a09Sdrochner void
camellia_setup256(const unsigned char * key,uint32_t * subkey)64359188a09Sdrochner camellia_setup256(const unsigned char *key, uint32_t *subkey)
64459188a09Sdrochner {
64559188a09Sdrochner     uint32_t kll,klr,krl,krr;           /* left half of key */
64659188a09Sdrochner     uint32_t krll,krlr,krrl,krrr;       /* right half of key */
64759188a09Sdrochner     uint32_t il, ir, t0, t1, w0, w1;    /* temporary variables */
64859188a09Sdrochner     uint32_t kw4l, kw4r, dw, tl, tr;
64959188a09Sdrochner     uint32_t subL[34];
65059188a09Sdrochner     uint32_t subR[34];
65159188a09Sdrochner 
65259188a09Sdrochner     /*
65359188a09Sdrochner      *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
65459188a09Sdrochner      *  (|| is concatination)
65559188a09Sdrochner      */
65659188a09Sdrochner 
65759188a09Sdrochner     kll  = GETU32(key     );
65859188a09Sdrochner     klr  = GETU32(key +  4);
65959188a09Sdrochner     krl  = GETU32(key +  8);
66059188a09Sdrochner     krr  = GETU32(key + 12);
66159188a09Sdrochner     krll = GETU32(key + 16);
66259188a09Sdrochner     krlr = GETU32(key + 20);
66359188a09Sdrochner     krrl = GETU32(key + 24);
66459188a09Sdrochner     krrr = GETU32(key + 28);
66559188a09Sdrochner 
66659188a09Sdrochner     /* generate KL dependent subkeys */
66759188a09Sdrochner     subl(0) = kll; subr(0) = klr;
66859188a09Sdrochner     subl(1) = krl; subr(1) = krr;
66959188a09Sdrochner     CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
67059188a09Sdrochner     subl(12) = kll; subr(12) = klr;
67159188a09Sdrochner     subl(13) = krl; subr(13) = krr;
67259188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
67359188a09Sdrochner     subl(16) = kll; subr(16) = klr;
67459188a09Sdrochner     subl(17) = krl; subr(17) = krr;
67559188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
67659188a09Sdrochner     subl(22) = kll; subr(22) = klr;
67759188a09Sdrochner     subl(23) = krl; subr(23) = krr;
67859188a09Sdrochner     CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
67959188a09Sdrochner     subl(30) = kll; subr(30) = klr;
68059188a09Sdrochner     subl(31) = krl; subr(31) = krr;
68159188a09Sdrochner 
68259188a09Sdrochner     /* generate KR dependent subkeys */
68359188a09Sdrochner     CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
68459188a09Sdrochner     subl(4) = krll; subr(4) = krlr;
68559188a09Sdrochner     subl(5) = krrl; subr(5) = krrr;
68659188a09Sdrochner     CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
68759188a09Sdrochner     subl(8) = krll; subr(8) = krlr;
68859188a09Sdrochner     subl(9) = krrl; subr(9) = krrr;
68959188a09Sdrochner     CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
69059188a09Sdrochner     subl(18) = krll; subr(18) = krlr;
69159188a09Sdrochner     subl(19) = krrl; subr(19) = krrr;
69259188a09Sdrochner     CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
69359188a09Sdrochner     subl(26) = krll; subr(26) = krlr;
69459188a09Sdrochner     subl(27) = krrl; subr(27) = krrr;
69559188a09Sdrochner     CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
69659188a09Sdrochner 
69759188a09Sdrochner     /* generate KA */
69859188a09Sdrochner     kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
69959188a09Sdrochner     krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
70059188a09Sdrochner     CAMELLIA_F(kll, klr, CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
70159188a09Sdrochner 	       w0, w1, il, ir, t0, t1);
70259188a09Sdrochner     krl ^= w0; krr ^= w1;
70359188a09Sdrochner     CAMELLIA_F(krl, krr, CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
70459188a09Sdrochner 	       kll, klr, il, ir, t0, t1);
70559188a09Sdrochner     kll ^= krll; klr ^= krlr;
70659188a09Sdrochner     CAMELLIA_F(kll, klr, CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
70759188a09Sdrochner 	       krl, krr, il, ir, t0, t1);
70859188a09Sdrochner     krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
70959188a09Sdrochner     CAMELLIA_F(krl, krr, CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
71059188a09Sdrochner 	       w0, w1, il, ir, t0, t1);
71159188a09Sdrochner     kll ^= w0; klr ^= w1;
71259188a09Sdrochner 
71359188a09Sdrochner     /* generate KB */
71459188a09Sdrochner     krll ^= kll; krlr ^= klr;
71559188a09Sdrochner     krrl ^= krl; krrr ^= krr;
71659188a09Sdrochner     CAMELLIA_F(krll, krlr, CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
71759188a09Sdrochner 	       w0, w1, il, ir, t0, t1);
71859188a09Sdrochner     krrl ^= w0; krrr ^= w1;
71959188a09Sdrochner     CAMELLIA_F(krrl, krrr, CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
72059188a09Sdrochner 	       w0, w1, il, ir, t0, t1);
72159188a09Sdrochner     krll ^= w0; krlr ^= w1;
72259188a09Sdrochner 
72359188a09Sdrochner     /* generate KA dependent subkeys */
72459188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
72559188a09Sdrochner     subl(6) = kll; subr(6) = klr;
72659188a09Sdrochner     subl(7) = krl; subr(7) = krr;
72759188a09Sdrochner     CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
72859188a09Sdrochner     subl(14) = kll; subr(14) = klr;
72959188a09Sdrochner     subl(15) = krl; subr(15) = krr;
73059188a09Sdrochner     subl(24) = klr; subr(24) = krl;
73159188a09Sdrochner     subl(25) = krr; subr(25) = kll;
73259188a09Sdrochner     CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
73359188a09Sdrochner     subl(28) = kll; subr(28) = klr;
73459188a09Sdrochner     subl(29) = krl; subr(29) = krr;
73559188a09Sdrochner 
73659188a09Sdrochner     /* generate KB dependent subkeys */
73759188a09Sdrochner     subl(2) = krll; subr(2) = krlr;
73859188a09Sdrochner     subl(3) = krrl; subr(3) = krrr;
73959188a09Sdrochner     CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
74059188a09Sdrochner     subl(10) = krll; subr(10) = krlr;
74159188a09Sdrochner     subl(11) = krrl; subr(11) = krrr;
74259188a09Sdrochner     CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
74359188a09Sdrochner     subl(20) = krll; subr(20) = krlr;
74459188a09Sdrochner     subl(21) = krrl; subr(21) = krrr;
74559188a09Sdrochner     CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
74659188a09Sdrochner     subl(32) = krll; subr(32) = krlr;
74759188a09Sdrochner     subl(33) = krrl; subr(33) = krrr;
74859188a09Sdrochner 
74959188a09Sdrochner     /* absorb kw2 to other subkeys */
75059188a09Sdrochner     subl(3) ^= subl(1); subr(3) ^= subr(1);
75159188a09Sdrochner     subl(5) ^= subl(1); subr(5) ^= subr(1);
75259188a09Sdrochner     subl(7) ^= subl(1); subr(7) ^= subr(1);
75359188a09Sdrochner     subl(1) ^= subr(1) & ~subr(9);
75459188a09Sdrochner     dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
75559188a09Sdrochner     subl(11) ^= subl(1); subr(11) ^= subr(1);
75659188a09Sdrochner     subl(13) ^= subl(1); subr(13) ^= subr(1);
75759188a09Sdrochner     subl(15) ^= subl(1); subr(15) ^= subr(1);
75859188a09Sdrochner     subl(1) ^= subr(1) & ~subr(17);
75959188a09Sdrochner     dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
76059188a09Sdrochner     subl(19) ^= subl(1); subr(19) ^= subr(1);
76159188a09Sdrochner     subl(21) ^= subl(1); subr(21) ^= subr(1);
76259188a09Sdrochner     subl(23) ^= subl(1); subr(23) ^= subr(1);
76359188a09Sdrochner     subl(1) ^= subr(1) & ~subr(25);
76459188a09Sdrochner     dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
76559188a09Sdrochner     subl(27) ^= subl(1); subr(27) ^= subr(1);
76659188a09Sdrochner     subl(29) ^= subl(1); subr(29) ^= subr(1);
76759188a09Sdrochner     subl(31) ^= subl(1); subr(31) ^= subr(1);
76859188a09Sdrochner     subl(32) ^= subl(1); subr(32) ^= subr(1);
76959188a09Sdrochner 
77059188a09Sdrochner 
77159188a09Sdrochner     /* absorb kw4 to other subkeys */
77259188a09Sdrochner     kw4l = subl(33); kw4r = subr(33);
77359188a09Sdrochner     subl(30) ^= kw4l; subr(30) ^= kw4r;
77459188a09Sdrochner     subl(28) ^= kw4l; subr(28) ^= kw4r;
77559188a09Sdrochner     subl(26) ^= kw4l; subr(26) ^= kw4r;
77659188a09Sdrochner     kw4l ^= kw4r & ~subr(24);
77759188a09Sdrochner     dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
77859188a09Sdrochner     subl(22) ^= kw4l; subr(22) ^= kw4r;
77959188a09Sdrochner     subl(20) ^= kw4l; subr(20) ^= kw4r;
78059188a09Sdrochner     subl(18) ^= kw4l; subr(18) ^= kw4r;
78159188a09Sdrochner     kw4l ^= kw4r & ~subr(16);
78259188a09Sdrochner     dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
78359188a09Sdrochner     subl(14) ^= kw4l; subr(14) ^= kw4r;
78459188a09Sdrochner     subl(12) ^= kw4l; subr(12) ^= kw4r;
78559188a09Sdrochner     subl(10) ^= kw4l; subr(10) ^= kw4r;
78659188a09Sdrochner     kw4l ^= kw4r & ~subr(8);
78759188a09Sdrochner     dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
78859188a09Sdrochner     subl(6) ^= kw4l; subr(6) ^= kw4r;
78959188a09Sdrochner     subl(4) ^= kw4l; subr(4) ^= kw4r;
79059188a09Sdrochner     subl(2) ^= kw4l; subr(2) ^= kw4r;
79159188a09Sdrochner     subl(0) ^= kw4l; subr(0) ^= kw4r;
79259188a09Sdrochner 
79359188a09Sdrochner     /* key XOR is end of F-function */
79459188a09Sdrochner     SUBL(0) = subl(0) ^ subl(2);
79559188a09Sdrochner     SUBR(0) = subr(0) ^ subr(2);
79659188a09Sdrochner     SUBL(2) = subl(3);
79759188a09Sdrochner     SUBR(2) = subr(3);
79859188a09Sdrochner     SUBL(3) = subl(2) ^ subl(4);
79959188a09Sdrochner     SUBR(3) = subr(2) ^ subr(4);
80059188a09Sdrochner     SUBL(4) = subl(3) ^ subl(5);
80159188a09Sdrochner     SUBR(4) = subr(3) ^ subr(5);
80259188a09Sdrochner     SUBL(5) = subl(4) ^ subl(6);
80359188a09Sdrochner     SUBR(5) = subr(4) ^ subr(6);
80459188a09Sdrochner     SUBL(6) = subl(5) ^ subl(7);
80559188a09Sdrochner     SUBR(6) = subr(5) ^ subr(7);
80659188a09Sdrochner     tl = subl(10) ^ (subr(10) & ~subr(8));
80759188a09Sdrochner     dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
80859188a09Sdrochner     SUBL(7) = subl(6) ^ tl;
80959188a09Sdrochner     SUBR(7) = subr(6) ^ tr;
81059188a09Sdrochner     SUBL(8) = subl(8);
81159188a09Sdrochner     SUBR(8) = subr(8);
81259188a09Sdrochner     SUBL(9) = subl(9);
81359188a09Sdrochner     SUBR(9) = subr(9);
81459188a09Sdrochner     tl = subl(7) ^ (subr(7) & ~subr(9));
81559188a09Sdrochner     dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
81659188a09Sdrochner     SUBL(10) = tl ^ subl(11);
81759188a09Sdrochner     SUBR(10) = tr ^ subr(11);
81859188a09Sdrochner     SUBL(11) = subl(10) ^ subl(12);
81959188a09Sdrochner     SUBR(11) = subr(10) ^ subr(12);
82059188a09Sdrochner     SUBL(12) = subl(11) ^ subl(13);
82159188a09Sdrochner     SUBR(12) = subr(11) ^ subr(13);
82259188a09Sdrochner     SUBL(13) = subl(12) ^ subl(14);
82359188a09Sdrochner     SUBR(13) = subr(12) ^ subr(14);
82459188a09Sdrochner     SUBL(14) = subl(13) ^ subl(15);
82559188a09Sdrochner     SUBR(14) = subr(13) ^ subr(15);
82659188a09Sdrochner     tl = subl(18) ^ (subr(18) & ~subr(16));
82759188a09Sdrochner     dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
82859188a09Sdrochner     SUBL(15) = subl(14) ^ tl;
82959188a09Sdrochner     SUBR(15) = subr(14) ^ tr;
83059188a09Sdrochner     SUBL(16) = subl(16);
83159188a09Sdrochner     SUBR(16) = subr(16);
83259188a09Sdrochner     SUBL(17) = subl(17);
83359188a09Sdrochner     SUBR(17) = subr(17);
83459188a09Sdrochner     tl = subl(15) ^ (subr(15) & ~subr(17));
83559188a09Sdrochner     dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
83659188a09Sdrochner     SUBL(18) = tl ^ subl(19);
83759188a09Sdrochner     SUBR(18) = tr ^ subr(19);
83859188a09Sdrochner     SUBL(19) = subl(18) ^ subl(20);
83959188a09Sdrochner     SUBR(19) = subr(18) ^ subr(20);
84059188a09Sdrochner     SUBL(20) = subl(19) ^ subl(21);
84159188a09Sdrochner     SUBR(20) = subr(19) ^ subr(21);
84259188a09Sdrochner     SUBL(21) = subl(20) ^ subl(22);
84359188a09Sdrochner     SUBR(21) = subr(20) ^ subr(22);
84459188a09Sdrochner     SUBL(22) = subl(21) ^ subl(23);
84559188a09Sdrochner     SUBR(22) = subr(21) ^ subr(23);
84659188a09Sdrochner     tl = subl(26) ^ (subr(26) & ~subr(24));
84759188a09Sdrochner     dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
84859188a09Sdrochner     SUBL(23) = subl(22) ^ tl;
84959188a09Sdrochner     SUBR(23) = subr(22) ^ tr;
85059188a09Sdrochner     SUBL(24) = subl(24);
85159188a09Sdrochner     SUBR(24) = subr(24);
85259188a09Sdrochner     SUBL(25) = subl(25);
85359188a09Sdrochner     SUBR(25) = subr(25);
85459188a09Sdrochner     tl = subl(23) ^ (subr(23) & ~subr(25));
85559188a09Sdrochner     dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
85659188a09Sdrochner     SUBL(26) = tl ^ subl(27);
85759188a09Sdrochner     SUBR(26) = tr ^ subr(27);
85859188a09Sdrochner     SUBL(27) = subl(26) ^ subl(28);
85959188a09Sdrochner     SUBR(27) = subr(26) ^ subr(28);
86059188a09Sdrochner     SUBL(28) = subl(27) ^ subl(29);
86159188a09Sdrochner     SUBR(28) = subr(27) ^ subr(29);
86259188a09Sdrochner     SUBL(29) = subl(28) ^ subl(30);
86359188a09Sdrochner     SUBR(29) = subr(28) ^ subr(30);
86459188a09Sdrochner     SUBL(30) = subl(29) ^ subl(31);
86559188a09Sdrochner     SUBR(30) = subr(29) ^ subr(31);
86659188a09Sdrochner     SUBL(31) = subl(30);
86759188a09Sdrochner     SUBR(31) = subr(30);
86859188a09Sdrochner     SUBL(32) = subl(32) ^ subl(31);
86959188a09Sdrochner     SUBR(32) = subr(32) ^ subr(31);
87059188a09Sdrochner 
87159188a09Sdrochner     /* apply the inverse of the last half of P-function */
87259188a09Sdrochner     dw = SUBL(2) ^ SUBR(2), dw = CAMELLIA_RL8(dw);
87359188a09Sdrochner     SUBR(2) = SUBL(2) ^ dw, SUBL(2) = dw;
87459188a09Sdrochner     dw = SUBL(3) ^ SUBR(3), dw = CAMELLIA_RL8(dw);
87559188a09Sdrochner     SUBR(3) = SUBL(3) ^ dw, SUBL(3) = dw;
87659188a09Sdrochner     dw = SUBL(4) ^ SUBR(4), dw = CAMELLIA_RL8(dw);
87759188a09Sdrochner     SUBR(4) = SUBL(4) ^ dw, SUBL(4) = dw;
87859188a09Sdrochner     dw = SUBL(5) ^ SUBR(5), dw = CAMELLIA_RL8(dw);
87959188a09Sdrochner     SUBR(5) = SUBL(5) ^ dw, SUBL(5) = dw;
88059188a09Sdrochner     dw = SUBL(6) ^ SUBR(6), dw = CAMELLIA_RL8(dw);
88159188a09Sdrochner     SUBR(6) = SUBL(6) ^ dw, SUBL(6) = dw;
88259188a09Sdrochner     dw = SUBL(7) ^ SUBR(7), dw = CAMELLIA_RL8(dw);
88359188a09Sdrochner     SUBR(7) = SUBL(7) ^ dw, SUBL(7) = dw;
88459188a09Sdrochner     dw = SUBL(10) ^ SUBR(10), dw = CAMELLIA_RL8(dw);
88559188a09Sdrochner     SUBR(10) = SUBL(10) ^ dw, SUBL(10) = dw;
88659188a09Sdrochner     dw = SUBL(11) ^ SUBR(11), dw = CAMELLIA_RL8(dw);
88759188a09Sdrochner     SUBR(11) = SUBL(11) ^ dw, SUBL(11) = dw;
88859188a09Sdrochner     dw = SUBL(12) ^ SUBR(12), dw = CAMELLIA_RL8(dw);
88959188a09Sdrochner     SUBR(12) = SUBL(12) ^ dw, SUBL(12) = dw;
89059188a09Sdrochner     dw = SUBL(13) ^ SUBR(13), dw = CAMELLIA_RL8(dw);
89159188a09Sdrochner     SUBR(13) = SUBL(13) ^ dw, SUBL(13) = dw;
89259188a09Sdrochner     dw = SUBL(14) ^ SUBR(14), dw = CAMELLIA_RL8(dw);
89359188a09Sdrochner     SUBR(14) = SUBL(14) ^ dw, SUBL(14) = dw;
89459188a09Sdrochner     dw = SUBL(15) ^ SUBR(15), dw = CAMELLIA_RL8(dw);
89559188a09Sdrochner     SUBR(15) = SUBL(15) ^ dw, SUBL(15) = dw;
89659188a09Sdrochner     dw = SUBL(18) ^ SUBR(18), dw = CAMELLIA_RL8(dw);
89759188a09Sdrochner     SUBR(18) = SUBL(18) ^ dw, SUBL(18) = dw;
89859188a09Sdrochner     dw = SUBL(19) ^ SUBR(19), dw = CAMELLIA_RL8(dw);
89959188a09Sdrochner     SUBR(19) = SUBL(19) ^ dw, SUBL(19) = dw;
90059188a09Sdrochner     dw = SUBL(20) ^ SUBR(20), dw = CAMELLIA_RL8(dw);
90159188a09Sdrochner     SUBR(20) = SUBL(20) ^ dw, SUBL(20) = dw;
90259188a09Sdrochner     dw = SUBL(21) ^ SUBR(21), dw = CAMELLIA_RL8(dw);
90359188a09Sdrochner     SUBR(21) = SUBL(21) ^ dw, SUBL(21) = dw;
90459188a09Sdrochner     dw = SUBL(22) ^ SUBR(22), dw = CAMELLIA_RL8(dw);
90559188a09Sdrochner     SUBR(22) = SUBL(22) ^ dw, SUBL(22) = dw;
90659188a09Sdrochner     dw = SUBL(23) ^ SUBR(23), dw = CAMELLIA_RL8(dw);
90759188a09Sdrochner     SUBR(23) = SUBL(23) ^ dw, SUBL(23) = dw;
90859188a09Sdrochner     dw = SUBL(26) ^ SUBR(26), dw = CAMELLIA_RL8(dw);
90959188a09Sdrochner     SUBR(26) = SUBL(26) ^ dw, SUBL(26) = dw;
91059188a09Sdrochner     dw = SUBL(27) ^ SUBR(27), dw = CAMELLIA_RL8(dw);
91159188a09Sdrochner     SUBR(27) = SUBL(27) ^ dw, SUBL(27) = dw;
91259188a09Sdrochner     dw = SUBL(28) ^ SUBR(28), dw = CAMELLIA_RL8(dw);
91359188a09Sdrochner     SUBR(28) = SUBL(28) ^ dw, SUBL(28) = dw;
91459188a09Sdrochner     dw = SUBL(29) ^ SUBR(29), dw = CAMELLIA_RL8(dw);
91559188a09Sdrochner     SUBR(29) = SUBL(29) ^ dw, SUBL(29) = dw;
91659188a09Sdrochner     dw = SUBL(30) ^ SUBR(30), dw = CAMELLIA_RL8(dw);
91759188a09Sdrochner     SUBR(30) = SUBL(30) ^ dw, SUBL(30) = dw;
91859188a09Sdrochner     dw = SUBL(31) ^ SUBR(31), dw = CAMELLIA_RL8(dw);
91959188a09Sdrochner     SUBR(31) = SUBL(31) ^ dw, SUBL(31) = dw;
92059188a09Sdrochner }
92159188a09Sdrochner 
92259188a09Sdrochner void
camellia_setup192(const unsigned char * key,uint32_t * subkey)92359188a09Sdrochner camellia_setup192(const unsigned char *key, uint32_t *subkey)
92459188a09Sdrochner {
92559188a09Sdrochner     unsigned char kk[32];
92659188a09Sdrochner     uint32_t krll, krlr, krrl,krrr;
92759188a09Sdrochner 
92859188a09Sdrochner     memcpy(kk, key, 24);
92959188a09Sdrochner     memcpy((unsigned char *)&krll, key+16,4);
93059188a09Sdrochner     memcpy((unsigned char *)&krlr, key+20,4);
93159188a09Sdrochner     krrl = ~krll;
93259188a09Sdrochner     krrr = ~krlr;
93359188a09Sdrochner     memcpy(kk+24, (unsigned char *)&krrl, 4);
93459188a09Sdrochner     memcpy(kk+28, (unsigned char *)&krrr, 4);
93559188a09Sdrochner     camellia_setup256(kk, subkey);
93659188a09Sdrochner }
93759188a09Sdrochner 
93859188a09Sdrochner 
93959188a09Sdrochner /**
94059188a09Sdrochner  * Stuff related to camellia encryption/decryption
94159188a09Sdrochner  */
94259188a09Sdrochner void
camellia_encrypt128(const uint32_t * subkey,uint32_t * io)94359188a09Sdrochner camellia_encrypt128(const uint32_t *subkey, uint32_t *io)
94459188a09Sdrochner {
94559188a09Sdrochner     uint32_t il, ir, t0, t1;
94659188a09Sdrochner 
94759188a09Sdrochner     /* pre whitening but absorb kw2*/
94859188a09Sdrochner     io[0] ^= SUBL(0);
94959188a09Sdrochner     io[1] ^= SUBR(0);
95059188a09Sdrochner     /* main iteration */
95159188a09Sdrochner 
95259188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(2),SUBR(2),
95359188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
95459188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(3),SUBR(3),
95559188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
95659188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(4),SUBR(4),
95759188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
95859188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(5),SUBR(5),
95959188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
96059188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(6),SUBR(6),
96159188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
96259188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(7),SUBR(7),
96359188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
96459188a09Sdrochner 
96559188a09Sdrochner     CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(8),SUBR(8), SUBL(9),SUBR(9),
96659188a09Sdrochner 		 t0,t1,il,ir);
96759188a09Sdrochner 
96859188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(10),SUBR(10),
96959188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
97059188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(11),SUBR(11),
97159188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
97259188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(12),SUBR(12),
97359188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
97459188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(13),SUBR(13),
97559188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
97659188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(14),SUBR(14),
97759188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
97859188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(15),SUBR(15),
97959188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
98059188a09Sdrochner 
98159188a09Sdrochner     CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(16), SUBR(16), SUBL(17),SUBR(17),
98259188a09Sdrochner 		 t0,t1,il,ir);
98359188a09Sdrochner 
98459188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(18),SUBR(18),
98559188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
98659188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(19),SUBR(19),
98759188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
98859188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(20),SUBR(20),
98959188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
99059188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(21),SUBR(21),
99159188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
99259188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(22),SUBR(22),
99359188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
99459188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(23),SUBR(23),
99559188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
99659188a09Sdrochner 
99759188a09Sdrochner     /* post whitening but kw4 */
99859188a09Sdrochner     io[2] ^= SUBL(24);
99959188a09Sdrochner     io[3] ^= SUBR(24);
100059188a09Sdrochner 
100159188a09Sdrochner     t0 = io[0];
100259188a09Sdrochner     t1 = io[1];
100359188a09Sdrochner     io[0] = io[2];
100459188a09Sdrochner     io[1] = io[3];
100559188a09Sdrochner     io[2] = t0;
100659188a09Sdrochner     io[3] = t1;
100759188a09Sdrochner }
100859188a09Sdrochner 
100959188a09Sdrochner void
camellia_decrypt128(const uint32_t * subkey,uint32_t * io)101059188a09Sdrochner camellia_decrypt128(const uint32_t *subkey, uint32_t *io)
101159188a09Sdrochner {
1012*8cf89151Sgutteridge     uint32_t il,ir,t0,t1;               /* temporary variables */
101359188a09Sdrochner 
101459188a09Sdrochner     /* pre whitening but absorb kw2*/
101559188a09Sdrochner     io[0] ^= SUBL(24);
101659188a09Sdrochner     io[1] ^= SUBR(24);
101759188a09Sdrochner 
101859188a09Sdrochner     /* main iteration */
101959188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(23),SUBR(23),
102059188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
102159188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(22),SUBR(22),
102259188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
102359188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(21),SUBR(21),
102459188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
102559188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(20),SUBR(20),
102659188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
102759188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(19),SUBR(19),
102859188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
102959188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(18),SUBR(18),
103059188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
103159188a09Sdrochner 
103259188a09Sdrochner     CAMELLIA_FLS(io[0],io[1],io[2],io[3],SUBL(17),SUBR(17),SUBL(16),SUBR(16),
103359188a09Sdrochner 		 t0,t1,il,ir);
103459188a09Sdrochner 
103559188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(15),SUBR(15),
103659188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
103759188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(14),SUBR(14),
103859188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
103959188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(13),SUBR(13),
104059188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
104159188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(12),SUBR(12),
104259188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
104359188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(11),SUBR(11),
104459188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
104559188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(10),SUBR(10),
104659188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
104759188a09Sdrochner 
104859188a09Sdrochner     CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(9),SUBR(9), SUBL(8),SUBR(8),
104959188a09Sdrochner 		 t0,t1,il,ir);
105059188a09Sdrochner 
105159188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(7),SUBR(7),
105259188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
105359188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(6),SUBR(6),
105459188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
105559188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(5),SUBR(5),
105659188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
105759188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(4),SUBR(4),
105859188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
105959188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(3),SUBR(3),
106059188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
106159188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(2),SUBR(2),
106259188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
106359188a09Sdrochner 
106459188a09Sdrochner     /* post whitening but kw4 */
106559188a09Sdrochner     io[2] ^= SUBL(0);
106659188a09Sdrochner     io[3] ^= SUBR(0);
106759188a09Sdrochner 
106859188a09Sdrochner     t0 = io[0];
106959188a09Sdrochner     t1 = io[1];
107059188a09Sdrochner     io[0] = io[2];
107159188a09Sdrochner     io[1] = io[3];
107259188a09Sdrochner     io[2] = t0;
107359188a09Sdrochner     io[3] = t1;
107459188a09Sdrochner }
107559188a09Sdrochner 
107659188a09Sdrochner /**
107759188a09Sdrochner  * stuff for 192 and 256bit encryption/decryption
107859188a09Sdrochner  */
107959188a09Sdrochner void
camellia_encrypt256(const uint32_t * subkey,uint32_t * io)108059188a09Sdrochner camellia_encrypt256(const uint32_t *subkey, uint32_t *io)
108159188a09Sdrochner {
1082*8cf89151Sgutteridge     uint32_t il,ir,t0,t1;           /* temporary variables */
108359188a09Sdrochner 
108459188a09Sdrochner     /* pre whitening but absorb kw2*/
108559188a09Sdrochner     io[0] ^= SUBL(0);
108659188a09Sdrochner     io[1] ^= SUBR(0);
108759188a09Sdrochner 
108859188a09Sdrochner     /* main iteration */
108959188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(2),SUBR(2),
109059188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
109159188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(3),SUBR(3),
109259188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
109359188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(4),SUBR(4),
109459188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
109559188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(5),SUBR(5),
109659188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
109759188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(6),SUBR(6),
109859188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
109959188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(7),SUBR(7),
110059188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
110159188a09Sdrochner 
110259188a09Sdrochner     CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(8),SUBR(8), SUBL(9),SUBR(9),
110359188a09Sdrochner 		 t0,t1,il,ir);
110459188a09Sdrochner 
110559188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(10),SUBR(10),
110659188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
110759188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(11),SUBR(11),
110859188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
110959188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(12),SUBR(12),
111059188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
111159188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(13),SUBR(13),
111259188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
111359188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(14),SUBR(14),
111459188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
111559188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(15),SUBR(15),
111659188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
111759188a09Sdrochner 
111859188a09Sdrochner     CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(16),SUBR(16), SUBL(17),SUBR(17),
111959188a09Sdrochner 		 t0,t1,il,ir);
112059188a09Sdrochner 
112159188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(18),SUBR(18),
112259188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
112359188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(19),SUBR(19),
112459188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
112559188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(20),SUBR(20),
112659188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
112759188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(21),SUBR(21),
112859188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
112959188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(22),SUBR(22),
113059188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
113159188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(23),SUBR(23),
113259188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
113359188a09Sdrochner 
113459188a09Sdrochner     CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(24),SUBR(24), SUBL(25),SUBR(25),
113559188a09Sdrochner 		 t0,t1,il,ir);
113659188a09Sdrochner 
113759188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(26),SUBR(26),
113859188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
113959188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(27),SUBR(27),
114059188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
114159188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(28),SUBR(28),
114259188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
114359188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(29),SUBR(29),
114459188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
114559188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(30),SUBR(30),
114659188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
114759188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(31),SUBR(31),
114859188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
114959188a09Sdrochner 
115059188a09Sdrochner     /* post whitening but kw4 */
115159188a09Sdrochner     io[2] ^= SUBL(32);
115259188a09Sdrochner     io[3] ^= SUBR(32);
115359188a09Sdrochner 
115459188a09Sdrochner     t0 = io[0];
115559188a09Sdrochner     t1 = io[1];
115659188a09Sdrochner     io[0] = io[2];
115759188a09Sdrochner     io[1] = io[3];
115859188a09Sdrochner     io[2] = t0;
115959188a09Sdrochner     io[3] = t1;
116059188a09Sdrochner }
116159188a09Sdrochner 
116259188a09Sdrochner void
camellia_decrypt256(const uint32_t * subkey,uint32_t * io)116359188a09Sdrochner camellia_decrypt256(const uint32_t *subkey, uint32_t *io)
116459188a09Sdrochner {
1165*8cf89151Sgutteridge     uint32_t il,ir,t0,t1;           /* temporary variables */
116659188a09Sdrochner 
116759188a09Sdrochner     /* pre whitening but absorb kw2*/
116859188a09Sdrochner     io[0] ^= SUBL(32);
116959188a09Sdrochner     io[1] ^= SUBR(32);
117059188a09Sdrochner 
117159188a09Sdrochner     /* main iteration */
117259188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(31),SUBR(31),
117359188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
117459188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(30),SUBR(30),
117559188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
117659188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(29),SUBR(29),
117759188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
117859188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(28),SUBR(28),
117959188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
118059188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(27),SUBR(27),
118159188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
118259188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(26),SUBR(26),
118359188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
118459188a09Sdrochner 
118559188a09Sdrochner     CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(25),SUBR(25), SUBL(24),SUBR(24),
118659188a09Sdrochner 		 t0,t1,il,ir);
118759188a09Sdrochner 
118859188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(23),SUBR(23),
118959188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
119059188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(22),SUBR(22),
119159188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
119259188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(21),SUBR(21),
119359188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
119459188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(20),SUBR(20),
119559188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
119659188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(19),SUBR(19),
119759188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
119859188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(18),SUBR(18),
119959188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
120059188a09Sdrochner 
120159188a09Sdrochner     CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(17),SUBR(17), SUBL(16),SUBR(16),
120259188a09Sdrochner 		 t0,t1,il,ir);
120359188a09Sdrochner 
120459188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(15),SUBR(15),
120559188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
120659188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(14),SUBR(14),
120759188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
120859188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(13),SUBR(13),
120959188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
121059188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(12),SUBR(12),
121159188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
121259188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(11),SUBR(11),
121359188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
121459188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(10),SUBR(10),
121559188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
121659188a09Sdrochner 
121759188a09Sdrochner     CAMELLIA_FLS(io[0],io[1],io[2],io[3], SUBL(9),SUBR(9), SUBL(8),SUBR(8),
121859188a09Sdrochner 		 t0,t1,il,ir);
121959188a09Sdrochner 
122059188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(7),SUBR(7),
122159188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
122259188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(6),SUBR(6),
122359188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
122459188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(5),SUBR(5),
122559188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
122659188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(4),SUBR(4),
122759188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
122859188a09Sdrochner     CAMELLIA_ROUNDSM(io[0],io[1], SUBL(3),SUBR(3),
122959188a09Sdrochner 		     io[2],io[3],il,ir,t0,t1);
123059188a09Sdrochner     CAMELLIA_ROUNDSM(io[2],io[3], SUBL(2),SUBR(2),
123159188a09Sdrochner 		     io[0],io[1],il,ir,t0,t1);
123259188a09Sdrochner 
123359188a09Sdrochner     /* post whitening but kw4 */
123459188a09Sdrochner     io[2] ^= SUBL(0);
123559188a09Sdrochner     io[3] ^= SUBR(0);
123659188a09Sdrochner 
123759188a09Sdrochner     t0 = io[0];
123859188a09Sdrochner     t1 = io[1];
123959188a09Sdrochner     io[0] = io[2];
124059188a09Sdrochner     io[1] = io[3];
124159188a09Sdrochner     io[2] = t0;
124259188a09Sdrochner     io[3] = t1;
124359188a09Sdrochner }
124459188a09Sdrochner 
124559188a09Sdrochner void
Camellia_Ekeygen(const int keyBitLength,const unsigned char * rawKey,uint32_t * subkey)124659188a09Sdrochner Camellia_Ekeygen(const int keyBitLength,
124759188a09Sdrochner 		 const unsigned char *rawKey,
124859188a09Sdrochner 		 uint32_t *subkey)
124959188a09Sdrochner {
125059188a09Sdrochner     KASSERT(keyBitLength == 128 || keyBitLength == 192 || keyBitLength == 256);
125159188a09Sdrochner 
125259188a09Sdrochner     switch(keyBitLength) {
125359188a09Sdrochner     case 128:
125459188a09Sdrochner 	camellia_setup128(rawKey, subkey);
125559188a09Sdrochner 	break;
125659188a09Sdrochner     case 192:
125759188a09Sdrochner 	camellia_setup192(rawKey, subkey);
125859188a09Sdrochner 	break;
125959188a09Sdrochner     case 256:
126059188a09Sdrochner 	camellia_setup256(rawKey, subkey);
126159188a09Sdrochner 	break;
126259188a09Sdrochner     default:
126359188a09Sdrochner 	break;
126459188a09Sdrochner     }
126559188a09Sdrochner }
126659188a09Sdrochner void
Camellia_EncryptBlock(const int keyBitLength,const unsigned char * plaintext,const uint32_t * subkey,unsigned char * ciphertext)126759188a09Sdrochner Camellia_EncryptBlock(const int keyBitLength,
126859188a09Sdrochner 		      const unsigned char *plaintext,
126959188a09Sdrochner 		      const uint32_t *subkey,
127059188a09Sdrochner 		      unsigned char *ciphertext)
127159188a09Sdrochner {
127259188a09Sdrochner     uint32_t tmp[4];
127359188a09Sdrochner 
127459188a09Sdrochner     tmp[0] = GETU32(plaintext);
127559188a09Sdrochner     tmp[1] = GETU32(plaintext + 4);
127659188a09Sdrochner     tmp[2] = GETU32(plaintext + 8);
127759188a09Sdrochner     tmp[3] = GETU32(plaintext + 12);
127859188a09Sdrochner 
127959188a09Sdrochner     switch (keyBitLength) {
128059188a09Sdrochner     case 128:
128159188a09Sdrochner 	camellia_encrypt128(subkey, tmp);
128259188a09Sdrochner 	break;
128359188a09Sdrochner     case 192:
128459188a09Sdrochner 	/* fall through */
128559188a09Sdrochner     case 256:
128659188a09Sdrochner 	camellia_encrypt256(subkey, tmp);
128759188a09Sdrochner 	break;
128859188a09Sdrochner     default:
128959188a09Sdrochner 	break;
129059188a09Sdrochner     }
129159188a09Sdrochner 
129259188a09Sdrochner     PUTU32(ciphertext,    tmp[0]);
129359188a09Sdrochner     PUTU32(ciphertext+4,  tmp[1]);
129459188a09Sdrochner     PUTU32(ciphertext+8,  tmp[2]);
129559188a09Sdrochner     PUTU32(ciphertext+12, tmp[3]);
129659188a09Sdrochner }
129759188a09Sdrochner 
129859188a09Sdrochner void
Camellia_DecryptBlock(const int keyBitLength,const unsigned char * ciphertext,const uint32_t * subkey,unsigned char * plaintext)129959188a09Sdrochner Camellia_DecryptBlock(const int keyBitLength,
130059188a09Sdrochner 		      const unsigned char *ciphertext,
130159188a09Sdrochner 		      const uint32_t *subkey,
130259188a09Sdrochner 		      unsigned char *plaintext)
130359188a09Sdrochner {
130459188a09Sdrochner     uint32_t tmp[4];
130559188a09Sdrochner 
130659188a09Sdrochner     tmp[0] = GETU32(ciphertext);
130759188a09Sdrochner     tmp[1] = GETU32(ciphertext + 4);
130859188a09Sdrochner     tmp[2] = GETU32(ciphertext + 8);
130959188a09Sdrochner     tmp[3] = GETU32(ciphertext + 12);
131059188a09Sdrochner 
131159188a09Sdrochner     switch (keyBitLength) {
131259188a09Sdrochner     case 128:
131359188a09Sdrochner 	camellia_decrypt128(subkey, tmp);
131459188a09Sdrochner 	break;
131559188a09Sdrochner     case 192:
131659188a09Sdrochner 	/* fall through */
131759188a09Sdrochner     case 256:
131859188a09Sdrochner 	camellia_decrypt256(subkey, tmp);
131959188a09Sdrochner 	break;
132059188a09Sdrochner     default:
132159188a09Sdrochner 	break;
132259188a09Sdrochner     }
132359188a09Sdrochner 
132459188a09Sdrochner     PUTU32(plaintext,    tmp[0]);
132559188a09Sdrochner     PUTU32(plaintext+4,  tmp[1]);
132659188a09Sdrochner     PUTU32(plaintext+8,  tmp[2]);
132759188a09Sdrochner     PUTU32(plaintext+12, tmp[3]);
132859188a09Sdrochner }
13292c510b81Spgoyette 
13302c510b81Spgoyette MODULE(MODULE_CLASS_MISC, camellia, NULL);
13312c510b81Spgoyette 
13322c510b81Spgoyette static int
camellia_modcmd(modcmd_t cmd,void * opaque)13332c510b81Spgoyette camellia_modcmd(modcmd_t cmd, void *opaque)
13342c510b81Spgoyette {
13352c510b81Spgoyette 
13362c510b81Spgoyette 	switch (cmd) {
13372c510b81Spgoyette 	case MODULE_CMD_INIT:
13382c510b81Spgoyette 		return 0;
13392c510b81Spgoyette 	case MODULE_CMD_FINI:
13402c510b81Spgoyette 		return 0;
13412c510b81Spgoyette 	default:
13422c510b81Spgoyette 		return ENOTTY;
13432c510b81Spgoyette 	}
13442c510b81Spgoyette }
1345