xref: /linux/crypto/camellia_generic.c (revision 0bbdb4258bd116d8cd5d209e8d5b29bae516e5b3)
1d64beac0SNoriaki TAKAMIYA /*
2d64beac0SNoriaki TAKAMIYA  * Copyright (C) 2006
3d64beac0SNoriaki TAKAMIYA  * NTT (Nippon Telegraph and Telephone Corporation).
4d64beac0SNoriaki TAKAMIYA  *
5d64beac0SNoriaki TAKAMIYA  * This program is free software; you can redistribute it and/or
6d64beac0SNoriaki TAKAMIYA  * modify it under the terms of the GNU General Public License
7d64beac0SNoriaki TAKAMIYA  * as published by the Free Software Foundation; either version 2
8d64beac0SNoriaki TAKAMIYA  * of the License, or (at your option) any later version.
9d64beac0SNoriaki TAKAMIYA  *
10d64beac0SNoriaki TAKAMIYA  * This program is distributed in the hope that it will be useful,
11d64beac0SNoriaki TAKAMIYA  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12d64beac0SNoriaki TAKAMIYA  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13d64beac0SNoriaki TAKAMIYA  * GNU General Public License for more details.
14d64beac0SNoriaki TAKAMIYA  *
15d64beac0SNoriaki TAKAMIYA  * You should have received a copy of the GNU General Public License
16d64beac0SNoriaki TAKAMIYA  * along with this program; if not, write to the Free Software
17d64beac0SNoriaki TAKAMIYA  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18d64beac0SNoriaki TAKAMIYA  */
19d64beac0SNoriaki TAKAMIYA 
20d64beac0SNoriaki TAKAMIYA /*
21d64beac0SNoriaki TAKAMIYA  * Algorithm Specification
22d64beac0SNoriaki TAKAMIYA  *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
23d64beac0SNoriaki TAKAMIYA  */
24d64beac0SNoriaki TAKAMIYA 
25d64beac0SNoriaki TAKAMIYA /*
26d64beac0SNoriaki TAKAMIYA  *
27d64beac0SNoriaki TAKAMIYA  * NOTE --- NOTE --- NOTE --- NOTE
28d64beac0SNoriaki TAKAMIYA  * This implementation assumes that all memory addresses passed
29d64beac0SNoriaki TAKAMIYA  * as parameters are four-byte aligned.
30d64beac0SNoriaki TAKAMIYA  *
31d64beac0SNoriaki TAKAMIYA  */
32d64beac0SNoriaki TAKAMIYA 
33d64beac0SNoriaki TAKAMIYA #include <linux/crypto.h>
34d64beac0SNoriaki TAKAMIYA #include <linux/errno.h>
35d64beac0SNoriaki TAKAMIYA #include <linux/init.h>
36d64beac0SNoriaki TAKAMIYA #include <linux/kernel.h>
37d64beac0SNoriaki TAKAMIYA #include <linux/module.h>
3832bd78e0SHarvey Harrison #include <linux/bitops.h>
3932bd78e0SHarvey Harrison #include <asm/unaligned.h>
40d64beac0SNoriaki TAKAMIYA 
41d64beac0SNoriaki TAKAMIYA static const u32 camellia_sp1110[256] = {
42d64beac0SNoriaki TAKAMIYA 	0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00,
43d64beac0SNoriaki TAKAMIYA 	0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500,
44d64beac0SNoriaki TAKAMIYA 	0xe4e4e400, 0x85858500, 0x57575700, 0x35353500,
45d64beac0SNoriaki TAKAMIYA 	0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100,
46d64beac0SNoriaki TAKAMIYA 	0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300,
47d64beac0SNoriaki TAKAMIYA 	0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
48d64beac0SNoriaki TAKAMIYA 	0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00,
49d64beac0SNoriaki TAKAMIYA 	0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00,
50d64beac0SNoriaki TAKAMIYA 	0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00,
51d64beac0SNoriaki TAKAMIYA 	0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00,
52d64beac0SNoriaki TAKAMIYA 	0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00,
53d64beac0SNoriaki TAKAMIYA 	0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
54d64beac0SNoriaki TAKAMIYA 	0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00,
55d64beac0SNoriaki TAKAMIYA 	0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00,
56d64beac0SNoriaki TAKAMIYA 	0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600,
57d64beac0SNoriaki TAKAMIYA 	0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00,
58d64beac0SNoriaki TAKAMIYA 	0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600,
59d64beac0SNoriaki TAKAMIYA 	0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
60d64beac0SNoriaki TAKAMIYA 	0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000,
61d64beac0SNoriaki TAKAMIYA 	0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900,
62d64beac0SNoriaki TAKAMIYA 	0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200,
63d64beac0SNoriaki TAKAMIYA 	0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500,
64d64beac0SNoriaki TAKAMIYA 	0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100,
65d64beac0SNoriaki TAKAMIYA 	0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
66d64beac0SNoriaki TAKAMIYA 	0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100,
67d64beac0SNoriaki TAKAMIYA 	0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00,
68d64beac0SNoriaki TAKAMIYA 	0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600,
69d64beac0SNoriaki TAKAMIYA 	0x53535300, 0x18181800, 0xf2f2f200, 0x22222200,
70d64beac0SNoriaki TAKAMIYA 	0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200,
71d64beac0SNoriaki TAKAMIYA 	0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
72d64beac0SNoriaki TAKAMIYA 	0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800,
73d64beac0SNoriaki TAKAMIYA 	0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000,
74d64beac0SNoriaki TAKAMIYA 	0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00,
75d64beac0SNoriaki TAKAMIYA 	0xa1a1a100, 0x89898900, 0x62626200, 0x97979700,
76d64beac0SNoriaki TAKAMIYA 	0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500,
77d64beac0SNoriaki TAKAMIYA 	0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
78d64beac0SNoriaki TAKAMIYA 	0x10101000, 0xc4c4c400, 0x00000000, 0x48484800,
79d64beac0SNoriaki TAKAMIYA 	0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00,
80d64beac0SNoriaki TAKAMIYA 	0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00,
81d64beac0SNoriaki TAKAMIYA 	0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400,
82d64beac0SNoriaki TAKAMIYA 	0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200,
83d64beac0SNoriaki TAKAMIYA 	0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
84d64beac0SNoriaki TAKAMIYA 	0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300,
85d64beac0SNoriaki TAKAMIYA 	0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200,
86d64beac0SNoriaki TAKAMIYA 	0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600,
87d64beac0SNoriaki TAKAMIYA 	0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00,
88d64beac0SNoriaki TAKAMIYA 	0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00,
89d64beac0SNoriaki TAKAMIYA 	0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
90d64beac0SNoriaki TAKAMIYA 	0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00,
91d64beac0SNoriaki TAKAMIYA 	0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00,
92d64beac0SNoriaki TAKAMIYA 	0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600,
93d64beac0SNoriaki TAKAMIYA 	0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900,
94d64beac0SNoriaki TAKAMIYA 	0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00,
95d64beac0SNoriaki TAKAMIYA 	0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
96d64beac0SNoriaki TAKAMIYA 	0xd4d4d400, 0x25252500, 0xababab00, 0x42424200,
97d64beac0SNoriaki TAKAMIYA 	0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00,
98d64beac0SNoriaki TAKAMIYA 	0x72727200, 0x07070700, 0xb9b9b900, 0x55555500,
99d64beac0SNoriaki TAKAMIYA 	0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00,
100d64beac0SNoriaki TAKAMIYA 	0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800,
101d64beac0SNoriaki TAKAMIYA 	0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
102d64beac0SNoriaki TAKAMIYA 	0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00,
103d64beac0SNoriaki TAKAMIYA 	0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100,
104d64beac0SNoriaki TAKAMIYA 	0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
105d64beac0SNoriaki TAKAMIYA 	0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00,
106d64beac0SNoriaki TAKAMIYA };
107d64beac0SNoriaki TAKAMIYA 
108d64beac0SNoriaki TAKAMIYA static const u32 camellia_sp0222[256] = {
109d64beac0SNoriaki TAKAMIYA 	0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9,
110d64beac0SNoriaki TAKAMIYA 	0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb,
111d64beac0SNoriaki TAKAMIYA 	0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a,
112d64beac0SNoriaki TAKAMIYA 	0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282,
113d64beac0SNoriaki TAKAMIYA 	0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727,
114d64beac0SNoriaki TAKAMIYA 	0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
115d64beac0SNoriaki TAKAMIYA 	0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c,
116d64beac0SNoriaki TAKAMIYA 	0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b,
117d64beac0SNoriaki TAKAMIYA 	0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f,
118d64beac0SNoriaki TAKAMIYA 	0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d,
119d64beac0SNoriaki TAKAMIYA 	0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe,
120d64beac0SNoriaki TAKAMIYA 	0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
121d64beac0SNoriaki TAKAMIYA 	0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595,
122d64beac0SNoriaki TAKAMIYA 	0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a,
123d64beac0SNoriaki TAKAMIYA 	0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad,
124d64beac0SNoriaki TAKAMIYA 	0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a,
125d64beac0SNoriaki TAKAMIYA 	0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc,
126d64beac0SNoriaki TAKAMIYA 	0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
127d64beac0SNoriaki TAKAMIYA 	0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040,
128d64beac0SNoriaki TAKAMIYA 	0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333,
129d64beac0SNoriaki TAKAMIYA 	0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585,
130d64beac0SNoriaki TAKAMIYA 	0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a,
131d64beac0SNoriaki TAKAMIYA 	0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262,
132d64beac0SNoriaki TAKAMIYA 	0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
133d64beac0SNoriaki TAKAMIYA 	0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2,
134d64beac0SNoriaki TAKAMIYA 	0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838,
135d64beac0SNoriaki TAKAMIYA 	0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c,
136d64beac0SNoriaki TAKAMIYA 	0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444,
137d64beac0SNoriaki TAKAMIYA 	0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565,
138d64beac0SNoriaki TAKAMIYA 	0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
139d64beac0SNoriaki TAKAMIYA 	0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151,
140d64beac0SNoriaki TAKAMIYA 	0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0,
141d64beac0SNoriaki TAKAMIYA 	0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa,
142d64beac0SNoriaki TAKAMIYA 	0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f,
143d64beac0SNoriaki TAKAMIYA 	0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b,
144d64beac0SNoriaki TAKAMIYA 	0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
145d64beac0SNoriaki TAKAMIYA 	0x00202020, 0x00898989, 0x00000000, 0x00909090,
146d64beac0SNoriaki TAKAMIYA 	0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7,
147d64beac0SNoriaki TAKAMIYA 	0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5,
148d64beac0SNoriaki TAKAMIYA 	0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929,
149d64beac0SNoriaki TAKAMIYA 	0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404,
150d64beac0SNoriaki TAKAMIYA 	0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
151d64beac0SNoriaki TAKAMIYA 	0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7,
152d64beac0SNoriaki TAKAMIYA 	0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5,
153d64beac0SNoriaki TAKAMIYA 	0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c,
154d64beac0SNoriaki TAKAMIYA 	0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676,
155d64beac0SNoriaki TAKAMIYA 	0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696,
156d64beac0SNoriaki TAKAMIYA 	0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
157d64beac0SNoriaki TAKAMIYA 	0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919,
158d64beac0SNoriaki TAKAMIYA 	0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d,
159d64beac0SNoriaki TAKAMIYA 	0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d,
160d64beac0SNoriaki TAKAMIYA 	0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2,
161d64beac0SNoriaki TAKAMIYA 	0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4,
162d64beac0SNoriaki TAKAMIYA 	0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
163d64beac0SNoriaki TAKAMIYA 	0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484,
164d64beac0SNoriaki TAKAMIYA 	0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5,
165d64beac0SNoriaki TAKAMIYA 	0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa,
166d64beac0SNoriaki TAKAMIYA 	0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414,
167d64beac0SNoriaki TAKAMIYA 	0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0,
168d64beac0SNoriaki TAKAMIYA 	0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
169d64beac0SNoriaki TAKAMIYA 	0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6,
170d64beac0SNoriaki TAKAMIYA 	0x00777777, 0x00939393, 0x00868686, 0x00838383,
171d64beac0SNoriaki TAKAMIYA 	0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
172d64beac0SNoriaki TAKAMIYA 	0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d,
173d64beac0SNoriaki TAKAMIYA };
174d64beac0SNoriaki TAKAMIYA 
175d64beac0SNoriaki TAKAMIYA static const u32 camellia_sp3033[256] = {
176d64beac0SNoriaki TAKAMIYA 	0x38003838, 0x41004141, 0x16001616, 0x76007676,
177d64beac0SNoriaki TAKAMIYA 	0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2,
178d64beac0SNoriaki TAKAMIYA 	0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a,
179d64beac0SNoriaki TAKAMIYA 	0x75007575, 0x06000606, 0x57005757, 0xa000a0a0,
180d64beac0SNoriaki TAKAMIYA 	0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9,
181d64beac0SNoriaki TAKAMIYA 	0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
182d64beac0SNoriaki TAKAMIYA 	0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727,
183d64beac0SNoriaki TAKAMIYA 	0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede,
184d64beac0SNoriaki TAKAMIYA 	0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7,
185d64beac0SNoriaki TAKAMIYA 	0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767,
186d64beac0SNoriaki TAKAMIYA 	0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf,
187d64beac0SNoriaki TAKAMIYA 	0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
188d64beac0SNoriaki TAKAMIYA 	0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565,
189d64beac0SNoriaki TAKAMIYA 	0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e,
190d64beac0SNoriaki TAKAMIYA 	0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b,
191d64beac0SNoriaki TAKAMIYA 	0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6,
192d64beac0SNoriaki TAKAMIYA 	0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333,
193d64beac0SNoriaki TAKAMIYA 	0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
194d64beac0SNoriaki TAKAMIYA 	0x3a003a3a, 0x09000909, 0x95009595, 0x10001010,
195d64beac0SNoriaki TAKAMIYA 	0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc,
196d64beac0SNoriaki TAKAMIYA 	0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161,
197d64beac0SNoriaki TAKAMIYA 	0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282,
198d64beac0SNoriaki TAKAMIYA 	0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898,
199d64beac0SNoriaki TAKAMIYA 	0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
200d64beac0SNoriaki TAKAMIYA 	0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0,
201d64beac0SNoriaki TAKAMIYA 	0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e,
202d64beac0SNoriaki TAKAMIYA 	0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b,
203d64beac0SNoriaki TAKAMIYA 	0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111,
204d64beac0SNoriaki TAKAMIYA 	0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959,
205d64beac0SNoriaki TAKAMIYA 	0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
206d64beac0SNoriaki TAKAMIYA 	0x12001212, 0x04000404, 0x74007474, 0x54005454,
207d64beac0SNoriaki TAKAMIYA 	0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828,
208d64beac0SNoriaki TAKAMIYA 	0x55005555, 0x68006868, 0x50005050, 0xbe00bebe,
209d64beac0SNoriaki TAKAMIYA 	0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb,
210d64beac0SNoriaki TAKAMIYA 	0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca,
211d64beac0SNoriaki TAKAMIYA 	0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
212d64beac0SNoriaki TAKAMIYA 	0x08000808, 0x62006262, 0x00000000, 0x24002424,
213d64beac0SNoriaki TAKAMIYA 	0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded,
214d64beac0SNoriaki TAKAMIYA 	0x45004545, 0x81008181, 0x73007373, 0x6d006d6d,
215d64beac0SNoriaki TAKAMIYA 	0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a,
216d64beac0SNoriaki TAKAMIYA 	0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101,
217d64beac0SNoriaki TAKAMIYA 	0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
218d64beac0SNoriaki TAKAMIYA 	0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9,
219d64beac0SNoriaki TAKAMIYA 	0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171,
220d64beac0SNoriaki TAKAMIYA 	0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313,
221d64beac0SNoriaki TAKAMIYA 	0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d,
222d64beac0SNoriaki TAKAMIYA 	0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5,
223d64beac0SNoriaki TAKAMIYA 	0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
224d64beac0SNoriaki TAKAMIYA 	0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646,
225d64beac0SNoriaki TAKAMIYA 	0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747,
226d64beac0SNoriaki TAKAMIYA 	0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b,
227d64beac0SNoriaki TAKAMIYA 	0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac,
228d64beac0SNoriaki TAKAMIYA 	0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535,
229d64beac0SNoriaki TAKAMIYA 	0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
230d64beac0SNoriaki TAKAMIYA 	0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121,
231d64beac0SNoriaki TAKAMIYA 	0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d,
232d64beac0SNoriaki TAKAMIYA 	0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa,
233d64beac0SNoriaki TAKAMIYA 	0x7c007c7c, 0x77007777, 0x56005656, 0x05000505,
234d64beac0SNoriaki TAKAMIYA 	0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434,
235d64beac0SNoriaki TAKAMIYA 	0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
236d64beac0SNoriaki TAKAMIYA 	0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd,
237d64beac0SNoriaki TAKAMIYA 	0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0,
238d64beac0SNoriaki TAKAMIYA 	0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
239d64beac0SNoriaki TAKAMIYA 	0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f,
240d64beac0SNoriaki TAKAMIYA };
241d64beac0SNoriaki TAKAMIYA 
242d64beac0SNoriaki TAKAMIYA static const u32 camellia_sp4404[256] = {
243d64beac0SNoriaki TAKAMIYA 	0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0,
244d64beac0SNoriaki TAKAMIYA 	0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae,
245d64beac0SNoriaki TAKAMIYA 	0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5,
246d64beac0SNoriaki TAKAMIYA 	0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092,
247d64beac0SNoriaki TAKAMIYA 	0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f,
248d64beac0SNoriaki TAKAMIYA 	0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
249d64beac0SNoriaki TAKAMIYA 	0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d,
250d64beac0SNoriaki TAKAMIYA 	0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c,
251d64beac0SNoriaki TAKAMIYA 	0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0,
252d64beac0SNoriaki TAKAMIYA 	0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084,
253d64beac0SNoriaki TAKAMIYA 	0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076,
254d64beac0SNoriaki TAKAMIYA 	0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
255d64beac0SNoriaki TAKAMIYA 	0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011,
256d64beac0SNoriaki TAKAMIYA 	0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2,
257d64beac0SNoriaki TAKAMIYA 	0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a,
258d64beac0SNoriaki TAKAMIYA 	0x24240024, 0xe8e800e8, 0x60600060, 0x69690069,
259d64beac0SNoriaki TAKAMIYA 	0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062,
260d64beac0SNoriaki TAKAMIYA 	0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
261d64beac0SNoriaki TAKAMIYA 	0x10100010, 0x00000000, 0xa3a300a3, 0x75750075,
262d64beac0SNoriaki TAKAMIYA 	0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd,
263d64beac0SNoriaki TAKAMIYA 	0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090,
264d64beac0SNoriaki TAKAMIYA 	0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf,
265d64beac0SNoriaki TAKAMIYA 	0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6,
266d64beac0SNoriaki TAKAMIYA 	0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
267d64beac0SNoriaki TAKAMIYA 	0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc,
268d64beac0SNoriaki TAKAMIYA 	0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4,
269d64beac0SNoriaki TAKAMIYA 	0x78780078, 0x06060006, 0xe7e700e7, 0x71710071,
270d64beac0SNoriaki TAKAMIYA 	0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d,
271d64beac0SNoriaki TAKAMIYA 	0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac,
272d64beac0SNoriaki TAKAMIYA 	0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
273d64beac0SNoriaki TAKAMIYA 	0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043,
274d64beac0SNoriaki TAKAMIYA 	0x15150015, 0xadad00ad, 0x77770077, 0x80800080,
275d64beac0SNoriaki TAKAMIYA 	0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5,
276d64beac0SNoriaki TAKAMIYA 	0x85850085, 0x35350035, 0x0c0c000c, 0x41410041,
277d64beac0SNoriaki TAKAMIYA 	0xefef00ef, 0x93930093, 0x19190019, 0x21210021,
278d64beac0SNoriaki TAKAMIYA 	0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
279d64beac0SNoriaki TAKAMIYA 	0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce,
280d64beac0SNoriaki TAKAMIYA 	0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a,
281d64beac0SNoriaki TAKAMIYA 	0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d,
282d64beac0SNoriaki TAKAMIYA 	0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d,
283d64beac0SNoriaki TAKAMIYA 	0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d,
284d64beac0SNoriaki TAKAMIYA 	0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
285d64beac0SNoriaki TAKAMIYA 	0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005,
286d64beac0SNoriaki TAKAMIYA 	0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7,
287d64beac0SNoriaki TAKAMIYA 	0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c,
288d64beac0SNoriaki TAKAMIYA 	0x0f0f000f, 0x16160016, 0x18180018, 0x22220022,
289d64beac0SNoriaki TAKAMIYA 	0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091,
290d64beac0SNoriaki TAKAMIYA 	0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
291d64beac0SNoriaki TAKAMIYA 	0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097,
292d64beac0SNoriaki TAKAMIYA 	0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2,
293d64beac0SNoriaki TAKAMIYA 	0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db,
294d64beac0SNoriaki TAKAMIYA 	0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094,
295d64beac0SNoriaki TAKAMIYA 	0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033,
296d64beac0SNoriaki TAKAMIYA 	0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
297d64beac0SNoriaki TAKAMIYA 	0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b,
298d64beac0SNoriaki TAKAMIYA 	0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e,
299d64beac0SNoriaki TAKAMIYA 	0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e,
300d64beac0SNoriaki TAKAMIYA 	0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059,
301d64beac0SNoriaki TAKAMIYA 	0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba,
302d64beac0SNoriaki TAKAMIYA 	0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
303d64beac0SNoriaki TAKAMIYA 	0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a,
304d64beac0SNoriaki TAKAMIYA 	0x49490049, 0x68680068, 0x38380038, 0xa4a400a4,
305d64beac0SNoriaki TAKAMIYA 	0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
306d64beac0SNoriaki TAKAMIYA 	0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e,
307d64beac0SNoriaki TAKAMIYA };
308d64beac0SNoriaki TAKAMIYA 
309d64beac0SNoriaki TAKAMIYA 
3101721a812SDenys Vlasenko #define CAMELLIA_MIN_KEY_SIZE        16
3111721a812SDenys Vlasenko #define CAMELLIA_MAX_KEY_SIZE        32
3121721a812SDenys Vlasenko #define CAMELLIA_BLOCK_SIZE          16
3131721a812SDenys Vlasenko #define CAMELLIA_TABLE_BYTE_LEN     272
3141721a812SDenys Vlasenko 
3152ddae4a6SDenys Vlasenko /*
3162ddae4a6SDenys Vlasenko  * NB: L and R below stand for 'left' and 'right' as in written numbers.
3172ddae4a6SDenys Vlasenko  * That is, in (xxxL,xxxR) pair xxxL holds most significant digits,
3182ddae4a6SDenys Vlasenko  * _not_ least significant ones!
3192ddae4a6SDenys Vlasenko  */
3202ddae4a6SDenys Vlasenko 
3211721a812SDenys Vlasenko 
3221721a812SDenys Vlasenko /* key constants */
3231721a812SDenys Vlasenko 
3241721a812SDenys Vlasenko #define CAMELLIA_SIGMA1L (0xA09E667FL)
3251721a812SDenys Vlasenko #define CAMELLIA_SIGMA1R (0x3BCC908BL)
3261721a812SDenys Vlasenko #define CAMELLIA_SIGMA2L (0xB67AE858L)
3271721a812SDenys Vlasenko #define CAMELLIA_SIGMA2R (0x4CAA73B2L)
3281721a812SDenys Vlasenko #define CAMELLIA_SIGMA3L (0xC6EF372FL)
3291721a812SDenys Vlasenko #define CAMELLIA_SIGMA3R (0xE94F82BEL)
3301721a812SDenys Vlasenko #define CAMELLIA_SIGMA4L (0x54FF53A5L)
3311721a812SDenys Vlasenko #define CAMELLIA_SIGMA4R (0xF1D36F1CL)
3321721a812SDenys Vlasenko #define CAMELLIA_SIGMA5L (0x10E527FAL)
3331721a812SDenys Vlasenko #define CAMELLIA_SIGMA5R (0xDE682D1DL)
3341721a812SDenys Vlasenko #define CAMELLIA_SIGMA6L (0xB05688C2L)
3351721a812SDenys Vlasenko #define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
3361721a812SDenys Vlasenko 
3371721a812SDenys Vlasenko /*
3381721a812SDenys Vlasenko  *  macros
3391721a812SDenys Vlasenko  */
340e2861a71SJussi Kivilinna #define ROLDQ(ll, lr, rl, rr, w0, w1, bits) ({		\
3411721a812SDenys Vlasenko 	w0 = ll;					\
3421721a812SDenys Vlasenko 	ll = (ll << bits) + (lr >> (32 - bits));	\
3431721a812SDenys Vlasenko 	lr = (lr << bits) + (rl >> (32 - bits));	\
3441721a812SDenys Vlasenko 	rl = (rl << bits) + (rr >> (32 - bits));	\
3451721a812SDenys Vlasenko 	rr = (rr << bits) + (w0 >> (32 - bits));	\
346e2861a71SJussi Kivilinna })
3471721a812SDenys Vlasenko 
348e2861a71SJussi Kivilinna #define ROLDQo32(ll, lr, rl, rr, w0, w1, bits) ({	\
3491721a812SDenys Vlasenko 	w0 = ll;					\
3501721a812SDenys Vlasenko 	w1 = lr;					\
3511721a812SDenys Vlasenko 	ll = (lr << (bits - 32)) + (rl >> (64 - bits));	\
3521721a812SDenys Vlasenko 	lr = (rl << (bits - 32)) + (rr >> (64 - bits));	\
3531721a812SDenys Vlasenko 	rl = (rr << (bits - 32)) + (w0 >> (64 - bits));	\
3541721a812SDenys Vlasenko 	rr = (w0 << (bits - 32)) + (w1 >> (64 - bits));	\
355e2861a71SJussi Kivilinna })
3561721a812SDenys Vlasenko 
357e2861a71SJussi Kivilinna #define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) ({	\
3581721a812SDenys Vlasenko 	il = xl ^ kl;						\
3591721a812SDenys Vlasenko 	ir = xr ^ kr;						\
3601721a812SDenys Vlasenko 	t0 = il >> 16;						\
3611721a812SDenys Vlasenko 	t1 = ir >> 16;						\
3622ddae4a6SDenys Vlasenko 	yl = camellia_sp1110[(u8)(ir)]				\
363e2861a71SJussi Kivilinna 	   ^ camellia_sp0222[(u8)(t1 >> 8)]			\
3642ddae4a6SDenys Vlasenko 	   ^ camellia_sp3033[(u8)(t1)]				\
3652ddae4a6SDenys Vlasenko 	   ^ camellia_sp4404[(u8)(ir >> 8)];			\
366e2861a71SJussi Kivilinna 	yr = camellia_sp1110[(u8)(t0 >> 8)]			\
3672ddae4a6SDenys Vlasenko 	   ^ camellia_sp0222[(u8)(t0)]				\
3682ddae4a6SDenys Vlasenko 	   ^ camellia_sp3033[(u8)(il >> 8)]			\
3692ddae4a6SDenys Vlasenko 	   ^ camellia_sp4404[(u8)(il)];				\
3701721a812SDenys Vlasenko 	yl ^= yr;						\
37132bd78e0SHarvey Harrison 	yr = ror32(yr, 8);					\
3721721a812SDenys Vlasenko 	yr ^= yl;						\
373e2861a71SJussi Kivilinna })
3741721a812SDenys Vlasenko 
3753a5e5f81SDenys Vlasenko #define SUBKEY_L(INDEX) (subkey[(INDEX)*2])
3763a5e5f81SDenys Vlasenko #define SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1])
377d64beac0SNoriaki TAKAMIYA 
378dedcf8b0SDenys Vlasenko static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
379d3e74805SDenys Vlasenko {
380dedcf8b0SDenys Vlasenko 	u32 dw, tl, tr;
381ff85a808SDenys Vlasenko 	u32 kw4l, kw4r;
382dedcf8b0SDenys Vlasenko 
383ff85a808SDenys Vlasenko 	/* absorb kw2 to other subkeys */
384ff85a808SDenys Vlasenko 	/* round 2 */
385ff85a808SDenys Vlasenko 	subL[3] ^= subL[1]; subR[3] ^= subR[1];
386ff85a808SDenys Vlasenko 	/* round 4 */
387ff85a808SDenys Vlasenko 	subL[5] ^= subL[1]; subR[5] ^= subR[1];
388ff85a808SDenys Vlasenko 	/* round 6 */
389ff85a808SDenys Vlasenko 	subL[7] ^= subL[1]; subR[7] ^= subR[1];
390ff85a808SDenys Vlasenko 	subL[1] ^= subR[1] & ~subR[9];
391452ec049SJulia Lawall 	dw = subL[1] & subL[9];
39232bd78e0SHarvey Harrison 	subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl2) */
393ff85a808SDenys Vlasenko 	/* round 8 */
394ff85a808SDenys Vlasenko 	subL[11] ^= subL[1]; subR[11] ^= subR[1];
395ff85a808SDenys Vlasenko 	/* round 10 */
396ff85a808SDenys Vlasenko 	subL[13] ^= subL[1]; subR[13] ^= subR[1];
397ff85a808SDenys Vlasenko 	/* round 12 */
398ff85a808SDenys Vlasenko 	subL[15] ^= subL[1]; subR[15] ^= subR[1];
399ff85a808SDenys Vlasenko 	subL[1] ^= subR[1] & ~subR[17];
400452ec049SJulia Lawall 	dw = subL[1] & subL[17];
40132bd78e0SHarvey Harrison 	subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl4) */
402ff85a808SDenys Vlasenko 	/* round 14 */
403ff85a808SDenys Vlasenko 	subL[19] ^= subL[1]; subR[19] ^= subR[1];
404ff85a808SDenys Vlasenko 	/* round 16 */
405ff85a808SDenys Vlasenko 	subL[21] ^= subL[1]; subR[21] ^= subR[1];
406ff85a808SDenys Vlasenko 	/* round 18 */
407ff85a808SDenys Vlasenko 	subL[23] ^= subL[1]; subR[23] ^= subR[1];
408ff85a808SDenys Vlasenko 	if (max == 24) {
409ff85a808SDenys Vlasenko 		/* kw3 */
410ff85a808SDenys Vlasenko 		subL[24] ^= subL[1]; subR[24] ^= subR[1];
411ff85a808SDenys Vlasenko 
412ff85a808SDenys Vlasenko 	/* absorb kw4 to other subkeys */
413ff85a808SDenys Vlasenko 		kw4l = subL[25]; kw4r = subR[25];
414ff85a808SDenys Vlasenko 	} else {
415ff85a808SDenys Vlasenko 		subL[1] ^= subR[1] & ~subR[25];
416452ec049SJulia Lawall 		dw = subL[1] & subL[25];
41732bd78e0SHarvey Harrison 		subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl6) */
418ff85a808SDenys Vlasenko 		/* round 20 */
419ff85a808SDenys Vlasenko 		subL[27] ^= subL[1]; subR[27] ^= subR[1];
420ff85a808SDenys Vlasenko 		/* round 22 */
421ff85a808SDenys Vlasenko 		subL[29] ^= subL[1]; subR[29] ^= subR[1];
422ff85a808SDenys Vlasenko 		/* round 24 */
423ff85a808SDenys Vlasenko 		subL[31] ^= subL[1]; subR[31] ^= subR[1];
424ff85a808SDenys Vlasenko 		/* kw3 */
425ff85a808SDenys Vlasenko 		subL[32] ^= subL[1]; subR[32] ^= subR[1];
426ff85a808SDenys Vlasenko 
427ff85a808SDenys Vlasenko 	/* absorb kw4 to other subkeys */
428ff85a808SDenys Vlasenko 		kw4l = subL[33]; kw4r = subR[33];
429ff85a808SDenys Vlasenko 		/* round 23 */
430ff85a808SDenys Vlasenko 		subL[30] ^= kw4l; subR[30] ^= kw4r;
431ff85a808SDenys Vlasenko 		/* round 21 */
432ff85a808SDenys Vlasenko 		subL[28] ^= kw4l; subR[28] ^= kw4r;
433ff85a808SDenys Vlasenko 		/* round 19 */
434ff85a808SDenys Vlasenko 		subL[26] ^= kw4l; subR[26] ^= kw4r;
435ff85a808SDenys Vlasenko 		kw4l ^= kw4r & ~subR[24];
436452ec049SJulia Lawall 		dw = kw4l & subL[24];
43732bd78e0SHarvey Harrison 		kw4r ^= rol32(dw, 1); /* modified for FL(kl5) */
438ff85a808SDenys Vlasenko 	}
439ff85a808SDenys Vlasenko 	/* round 17 */
440ff85a808SDenys Vlasenko 	subL[22] ^= kw4l; subR[22] ^= kw4r;
441ff85a808SDenys Vlasenko 	/* round 15 */
442ff85a808SDenys Vlasenko 	subL[20] ^= kw4l; subR[20] ^= kw4r;
443ff85a808SDenys Vlasenko 	/* round 13 */
444ff85a808SDenys Vlasenko 	subL[18] ^= kw4l; subR[18] ^= kw4r;
445ff85a808SDenys Vlasenko 	kw4l ^= kw4r & ~subR[16];
446452ec049SJulia Lawall 	dw = kw4l & subL[16];
44732bd78e0SHarvey Harrison 	kw4r ^= rol32(dw, 1); /* modified for FL(kl3) */
448ff85a808SDenys Vlasenko 	/* round 11 */
449ff85a808SDenys Vlasenko 	subL[14] ^= kw4l; subR[14] ^= kw4r;
450ff85a808SDenys Vlasenko 	/* round 9 */
451ff85a808SDenys Vlasenko 	subL[12] ^= kw4l; subR[12] ^= kw4r;
452ff85a808SDenys Vlasenko 	/* round 7 */
453ff85a808SDenys Vlasenko 	subL[10] ^= kw4l; subR[10] ^= kw4r;
454ff85a808SDenys Vlasenko 	kw4l ^= kw4r & ~subR[8];
455452ec049SJulia Lawall 	dw = kw4l & subL[8];
45632bd78e0SHarvey Harrison 	kw4r ^= rol32(dw, 1); /* modified for FL(kl1) */
457ff85a808SDenys Vlasenko 	/* round 5 */
458ff85a808SDenys Vlasenko 	subL[6] ^= kw4l; subR[6] ^= kw4r;
459ff85a808SDenys Vlasenko 	/* round 3 */
460ff85a808SDenys Vlasenko 	subL[4] ^= kw4l; subR[4] ^= kw4r;
461ff85a808SDenys Vlasenko 	/* round 1 */
462ff85a808SDenys Vlasenko 	subL[2] ^= kw4l; subR[2] ^= kw4r;
463ff85a808SDenys Vlasenko 	/* kw1 */
464ff85a808SDenys Vlasenko 	subL[0] ^= kw4l; subR[0] ^= kw4r;
465ff85a808SDenys Vlasenko 
466dedcf8b0SDenys Vlasenko 	/* key XOR is end of F-function */
467dedcf8b0SDenys Vlasenko 	SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
468dedcf8b0SDenys Vlasenko 	SUBKEY_R(0) = subR[0] ^ subR[2];
469dedcf8b0SDenys Vlasenko 	SUBKEY_L(2) = subL[3];       /* round 1 */
470dedcf8b0SDenys Vlasenko 	SUBKEY_R(2) = subR[3];
471dedcf8b0SDenys Vlasenko 	SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
472dedcf8b0SDenys Vlasenko 	SUBKEY_R(3) = subR[2] ^ subR[4];
473dedcf8b0SDenys Vlasenko 	SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
474dedcf8b0SDenys Vlasenko 	SUBKEY_R(4) = subR[3] ^ subR[5];
475dedcf8b0SDenys Vlasenko 	SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
476dedcf8b0SDenys Vlasenko 	SUBKEY_R(5) = subR[4] ^ subR[6];
477dedcf8b0SDenys Vlasenko 	SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
478dedcf8b0SDenys Vlasenko 	SUBKEY_R(6) = subR[5] ^ subR[7];
479dedcf8b0SDenys Vlasenko 	tl = subL[10] ^ (subR[10] & ~subR[8]);
480452ec049SJulia Lawall 	dw = tl & subL[8];  /* FL(kl1) */
48132bd78e0SHarvey Harrison 	tr = subR[10] ^ rol32(dw, 1);
482dedcf8b0SDenys Vlasenko 	SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
483dedcf8b0SDenys Vlasenko 	SUBKEY_R(7) = subR[6] ^ tr;
484dedcf8b0SDenys Vlasenko 	SUBKEY_L(8) = subL[8];       /* FL(kl1) */
485dedcf8b0SDenys Vlasenko 	SUBKEY_R(8) = subR[8];
486dedcf8b0SDenys Vlasenko 	SUBKEY_L(9) = subL[9];       /* FLinv(kl2) */
487dedcf8b0SDenys Vlasenko 	SUBKEY_R(9) = subR[9];
488dedcf8b0SDenys Vlasenko 	tl = subL[7] ^ (subR[7] & ~subR[9]);
489452ec049SJulia Lawall 	dw = tl & subL[9];  /* FLinv(kl2) */
49032bd78e0SHarvey Harrison 	tr = subR[7] ^ rol32(dw, 1);
491dedcf8b0SDenys Vlasenko 	SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
492dedcf8b0SDenys Vlasenko 	SUBKEY_R(10) = tr ^ subR[11];
493dedcf8b0SDenys Vlasenko 	SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
494dedcf8b0SDenys Vlasenko 	SUBKEY_R(11) = subR[10] ^ subR[12];
495dedcf8b0SDenys Vlasenko 	SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
496dedcf8b0SDenys Vlasenko 	SUBKEY_R(12) = subR[11] ^ subR[13];
497dedcf8b0SDenys Vlasenko 	SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
498dedcf8b0SDenys Vlasenko 	SUBKEY_R(13) = subR[12] ^ subR[14];
499dedcf8b0SDenys Vlasenko 	SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
500dedcf8b0SDenys Vlasenko 	SUBKEY_R(14) = subR[13] ^ subR[15];
501dedcf8b0SDenys Vlasenko 	tl = subL[18] ^ (subR[18] & ~subR[16]);
502452ec049SJulia Lawall 	dw = tl & subL[16]; /* FL(kl3) */
50332bd78e0SHarvey Harrison 	tr = subR[18] ^ rol32(dw, 1);
504dedcf8b0SDenys Vlasenko 	SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
505dedcf8b0SDenys Vlasenko 	SUBKEY_R(15) = subR[14] ^ tr;
506dedcf8b0SDenys Vlasenko 	SUBKEY_L(16) = subL[16];     /* FL(kl3) */
507dedcf8b0SDenys Vlasenko 	SUBKEY_R(16) = subR[16];
508dedcf8b0SDenys Vlasenko 	SUBKEY_L(17) = subL[17];     /* FLinv(kl4) */
509dedcf8b0SDenys Vlasenko 	SUBKEY_R(17) = subR[17];
510dedcf8b0SDenys Vlasenko 	tl = subL[15] ^ (subR[15] & ~subR[17]);
511452ec049SJulia Lawall 	dw = tl & subL[17]; /* FLinv(kl4) */
51232bd78e0SHarvey Harrison 	tr = subR[15] ^ rol32(dw, 1);
513dedcf8b0SDenys Vlasenko 	SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
514dedcf8b0SDenys Vlasenko 	SUBKEY_R(18) = tr ^ subR[19];
515dedcf8b0SDenys Vlasenko 	SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
516dedcf8b0SDenys Vlasenko 	SUBKEY_R(19) = subR[18] ^ subR[20];
517dedcf8b0SDenys Vlasenko 	SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
518dedcf8b0SDenys Vlasenko 	SUBKEY_R(20) = subR[19] ^ subR[21];
519dedcf8b0SDenys Vlasenko 	SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
520dedcf8b0SDenys Vlasenko 	SUBKEY_R(21) = subR[20] ^ subR[22];
521dedcf8b0SDenys Vlasenko 	SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
522dedcf8b0SDenys Vlasenko 	SUBKEY_R(22) = subR[21] ^ subR[23];
523dedcf8b0SDenys Vlasenko 	if (max == 24) {
524dedcf8b0SDenys Vlasenko 		SUBKEY_L(23) = subL[22];     /* round 18 */
525dedcf8b0SDenys Vlasenko 		SUBKEY_R(23) = subR[22];
526dedcf8b0SDenys Vlasenko 		SUBKEY_L(24) = subL[24] ^ subL[23]; /* kw3 */
527dedcf8b0SDenys Vlasenko 		SUBKEY_R(24) = subR[24] ^ subR[23];
528dedcf8b0SDenys Vlasenko 	} else {
529dedcf8b0SDenys Vlasenko 		tl = subL[26] ^ (subR[26] & ~subR[24]);
530452ec049SJulia Lawall 		dw = tl & subL[24]; /* FL(kl5) */
53132bd78e0SHarvey Harrison 		tr = subR[26] ^ rol32(dw, 1);
532dedcf8b0SDenys Vlasenko 		SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
533dedcf8b0SDenys Vlasenko 		SUBKEY_R(23) = subR[22] ^ tr;
534dedcf8b0SDenys Vlasenko 		SUBKEY_L(24) = subL[24];     /* FL(kl5) */
535dedcf8b0SDenys Vlasenko 		SUBKEY_R(24) = subR[24];
536dedcf8b0SDenys Vlasenko 		SUBKEY_L(25) = subL[25];     /* FLinv(kl6) */
537dedcf8b0SDenys Vlasenko 		SUBKEY_R(25) = subR[25];
538dedcf8b0SDenys Vlasenko 		tl = subL[23] ^ (subR[23] & ~subR[25]);
539452ec049SJulia Lawall 		dw = tl & subL[25]; /* FLinv(kl6) */
54032bd78e0SHarvey Harrison 		tr = subR[23] ^ rol32(dw, 1);
541dedcf8b0SDenys Vlasenko 		SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
542dedcf8b0SDenys Vlasenko 		SUBKEY_R(26) = tr ^ subR[27];
543dedcf8b0SDenys Vlasenko 		SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
544dedcf8b0SDenys Vlasenko 		SUBKEY_R(27) = subR[26] ^ subR[28];
545dedcf8b0SDenys Vlasenko 		SUBKEY_L(28) = subL[27] ^ subL[29]; /* round 21 */
546dedcf8b0SDenys Vlasenko 		SUBKEY_R(28) = subR[27] ^ subR[29];
547dedcf8b0SDenys Vlasenko 		SUBKEY_L(29) = subL[28] ^ subL[30]; /* round 22 */
548dedcf8b0SDenys Vlasenko 		SUBKEY_R(29) = subR[28] ^ subR[30];
549dedcf8b0SDenys Vlasenko 		SUBKEY_L(30) = subL[29] ^ subL[31]; /* round 23 */
550dedcf8b0SDenys Vlasenko 		SUBKEY_R(30) = subR[29] ^ subR[31];
551dedcf8b0SDenys Vlasenko 		SUBKEY_L(31) = subL[30];     /* round 24 */
552dedcf8b0SDenys Vlasenko 		SUBKEY_R(31) = subR[30];
553dedcf8b0SDenys Vlasenko 		SUBKEY_L(32) = subL[32] ^ subL[31]; /* kw3 */
554dedcf8b0SDenys Vlasenko 		SUBKEY_R(32) = subR[32] ^ subR[31];
555dedcf8b0SDenys Vlasenko 	}
556d3e74805SDenys Vlasenko }
557d3e74805SDenys Vlasenko 
558d64beac0SNoriaki TAKAMIYA static void camellia_setup128(const unsigned char *key, u32 *subkey)
559d64beac0SNoriaki TAKAMIYA {
560d64beac0SNoriaki TAKAMIYA 	u32 kll, klr, krl, krr;
561d64beac0SNoriaki TAKAMIYA 	u32 il, ir, t0, t1, w0, w1;
562d64beac0SNoriaki TAKAMIYA 	u32 subL[26];
563d64beac0SNoriaki TAKAMIYA 	u32 subR[26];
564d64beac0SNoriaki TAKAMIYA 
565d64beac0SNoriaki TAKAMIYA 	/**
566dedcf8b0SDenys Vlasenko 	 *  k == kll || klr || krl || krr (|| is concatenation)
567d64beac0SNoriaki TAKAMIYA 	 */
56832bd78e0SHarvey Harrison 	kll = get_unaligned_be32(key);
56932bd78e0SHarvey Harrison 	klr = get_unaligned_be32(key + 4);
57032bd78e0SHarvey Harrison 	krl = get_unaligned_be32(key + 8);
57132bd78e0SHarvey Harrison 	krr = get_unaligned_be32(key + 12);
5721ce73e8dSDenys Vlasenko 
573dedcf8b0SDenys Vlasenko 	/* generate KL dependent subkeys */
574d64beac0SNoriaki TAKAMIYA 	/* kw1 */
5751721a812SDenys Vlasenko 	subL[0] = kll; subR[0] = klr;
576d64beac0SNoriaki TAKAMIYA 	/* kw2 */
5771721a812SDenys Vlasenko 	subL[1] = krl; subR[1] = krr;
578d64beac0SNoriaki TAKAMIYA 	/* rotation left shift 15bit */
5793a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 15);
580d64beac0SNoriaki TAKAMIYA 	/* k3 */
5811721a812SDenys Vlasenko 	subL[4] = kll; subR[4] = klr;
582d64beac0SNoriaki TAKAMIYA 	/* k4 */
5831721a812SDenys Vlasenko 	subL[5] = krl; subR[5] = krr;
584d64beac0SNoriaki TAKAMIYA 	/* rotation left shift 15+30bit */
5853a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 30);
586d64beac0SNoriaki TAKAMIYA 	/* k7 */
5871721a812SDenys Vlasenko 	subL[10] = kll; subR[10] = klr;
588d64beac0SNoriaki TAKAMIYA 	/* k8 */
5891721a812SDenys Vlasenko 	subL[11] = krl; subR[11] = krr;
590d64beac0SNoriaki TAKAMIYA 	/* rotation left shift 15+30+15bit */
5913a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 15);
592d64beac0SNoriaki TAKAMIYA 	/* k10 */
5931721a812SDenys Vlasenko 	subL[13] = krl; subR[13] = krr;
594d64beac0SNoriaki TAKAMIYA 	/* rotation left shift 15+30+15+17 bit */
5953a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 17);
596d64beac0SNoriaki TAKAMIYA 	/* kl3 */
5971721a812SDenys Vlasenko 	subL[16] = kll; subR[16] = klr;
598d64beac0SNoriaki TAKAMIYA 	/* kl4 */
5991721a812SDenys Vlasenko 	subL[17] = krl; subR[17] = krr;
600d64beac0SNoriaki TAKAMIYA 	/* rotation left shift 15+30+15+17+17 bit */
6013a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 17);
602d64beac0SNoriaki TAKAMIYA 	/* k13 */
6031721a812SDenys Vlasenko 	subL[18] = kll; subR[18] = klr;
604d64beac0SNoriaki TAKAMIYA 	/* k14 */
6051721a812SDenys Vlasenko 	subL[19] = krl; subR[19] = krr;
606d64beac0SNoriaki TAKAMIYA 	/* rotation left shift 15+30+15+17+17+17 bit */
6073a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 17);
608d64beac0SNoriaki TAKAMIYA 	/* k17 */
6091721a812SDenys Vlasenko 	subL[22] = kll; subR[22] = klr;
610d64beac0SNoriaki TAKAMIYA 	/* k18 */
6111721a812SDenys Vlasenko 	subL[23] = krl; subR[23] = krr;
612d64beac0SNoriaki TAKAMIYA 
613d64beac0SNoriaki TAKAMIYA 	/* generate KA */
6141721a812SDenys Vlasenko 	kll = subL[0]; klr = subR[0];
6151721a812SDenys Vlasenko 	krl = subL[1]; krr = subR[1];
616d64beac0SNoriaki TAKAMIYA 	CAMELLIA_F(kll, klr,
617d64beac0SNoriaki TAKAMIYA 		   CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
618d64beac0SNoriaki TAKAMIYA 		   w0, w1, il, ir, t0, t1);
619d64beac0SNoriaki TAKAMIYA 	krl ^= w0; krr ^= w1;
620d64beac0SNoriaki TAKAMIYA 	CAMELLIA_F(krl, krr,
621d64beac0SNoriaki TAKAMIYA 		   CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
622d64beac0SNoriaki TAKAMIYA 		   kll, klr, il, ir, t0, t1);
623d64beac0SNoriaki TAKAMIYA 	/* current status == (kll, klr, w0, w1) */
624d64beac0SNoriaki TAKAMIYA 	CAMELLIA_F(kll, klr,
625d64beac0SNoriaki TAKAMIYA 		   CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
626d64beac0SNoriaki TAKAMIYA 		   krl, krr, il, ir, t0, t1);
627d64beac0SNoriaki TAKAMIYA 	krl ^= w0; krr ^= w1;
628d64beac0SNoriaki TAKAMIYA 	CAMELLIA_F(krl, krr,
629d64beac0SNoriaki TAKAMIYA 		   CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
630d64beac0SNoriaki TAKAMIYA 		   w0, w1, il, ir, t0, t1);
631d64beac0SNoriaki TAKAMIYA 	kll ^= w0; klr ^= w1;
632d64beac0SNoriaki TAKAMIYA 
633d64beac0SNoriaki TAKAMIYA 	/* generate KA dependent subkeys */
634d64beac0SNoriaki TAKAMIYA 	/* k1, k2 */
6351721a812SDenys Vlasenko 	subL[2] = kll; subR[2] = klr;
6361721a812SDenys Vlasenko 	subL[3] = krl; subR[3] = krr;
6373a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 15);
638d64beac0SNoriaki TAKAMIYA 	/* k5,k6 */
6391721a812SDenys Vlasenko 	subL[6] = kll; subR[6] = klr;
6401721a812SDenys Vlasenko 	subL[7] = krl; subR[7] = krr;
6413a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 15);
642d64beac0SNoriaki TAKAMIYA 	/* kl1, kl2 */
6431721a812SDenys Vlasenko 	subL[8] = kll; subR[8] = klr;
6441721a812SDenys Vlasenko 	subL[9] = krl; subR[9] = krr;
6453a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 15);
646d64beac0SNoriaki TAKAMIYA 	/* k9 */
6471721a812SDenys Vlasenko 	subL[12] = kll; subR[12] = klr;
6483a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 15);
649d64beac0SNoriaki TAKAMIYA 	/* k11, k12 */
6501721a812SDenys Vlasenko 	subL[14] = kll; subR[14] = klr;
6511721a812SDenys Vlasenko 	subL[15] = krl; subR[15] = krr;
6523a5e5f81SDenys Vlasenko 	ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
653d64beac0SNoriaki TAKAMIYA 	/* k15, k16 */
6541721a812SDenys Vlasenko 	subL[20] = kll; subR[20] = klr;
6551721a812SDenys Vlasenko 	subL[21] = krl; subR[21] = krr;
6563a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 17);
657d64beac0SNoriaki TAKAMIYA 	/* kw3, kw4 */
6581721a812SDenys Vlasenko 	subL[24] = kll; subR[24] = klr;
6591721a812SDenys Vlasenko 	subL[25] = krl; subR[25] = krr;
660d64beac0SNoriaki TAKAMIYA 
661dedcf8b0SDenys Vlasenko 	camellia_setup_tail(subkey, subL, subR, 24);
662d64beac0SNoriaki TAKAMIYA }
663d64beac0SNoriaki TAKAMIYA 
664d64beac0SNoriaki TAKAMIYA static void camellia_setup256(const unsigned char *key, u32 *subkey)
665d64beac0SNoriaki TAKAMIYA {
666d64beac0SNoriaki TAKAMIYA 	u32 kll, klr, krl, krr;        /* left half of key */
667d64beac0SNoriaki TAKAMIYA 	u32 krll, krlr, krrl, krrr;    /* right half of key */
668d64beac0SNoriaki TAKAMIYA 	u32 il, ir, t0, t1, w0, w1;    /* temporary variables */
669d64beac0SNoriaki TAKAMIYA 	u32 subL[34];
670d64beac0SNoriaki TAKAMIYA 	u32 subR[34];
671d64beac0SNoriaki TAKAMIYA 
672d64beac0SNoriaki TAKAMIYA 	/**
673d64beac0SNoriaki TAKAMIYA 	 *  key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
674dedcf8b0SDenys Vlasenko 	 *  (|| is concatenation)
675d64beac0SNoriaki TAKAMIYA 	 */
67632bd78e0SHarvey Harrison 	kll = get_unaligned_be32(key);
67732bd78e0SHarvey Harrison 	klr = get_unaligned_be32(key + 4);
67832bd78e0SHarvey Harrison 	krl = get_unaligned_be32(key + 8);
67932bd78e0SHarvey Harrison 	krr = get_unaligned_be32(key + 12);
68032bd78e0SHarvey Harrison 	krll = get_unaligned_be32(key + 16);
68132bd78e0SHarvey Harrison 	krlr = get_unaligned_be32(key + 20);
68232bd78e0SHarvey Harrison 	krrl = get_unaligned_be32(key + 24);
68332bd78e0SHarvey Harrison 	krrr = get_unaligned_be32(key + 28);
684d64beac0SNoriaki TAKAMIYA 
685d64beac0SNoriaki TAKAMIYA 	/* generate KL dependent subkeys */
686d64beac0SNoriaki TAKAMIYA 	/* kw1 */
6871721a812SDenys Vlasenko 	subL[0] = kll; subR[0] = klr;
688d64beac0SNoriaki TAKAMIYA 	/* kw2 */
6891721a812SDenys Vlasenko 	subL[1] = krl; subR[1] = krr;
6903a5e5f81SDenys Vlasenko 	ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
691d64beac0SNoriaki TAKAMIYA 	/* k9 */
6921721a812SDenys Vlasenko 	subL[12] = kll; subR[12] = klr;
693d64beac0SNoriaki TAKAMIYA 	/* k10 */
6941721a812SDenys Vlasenko 	subL[13] = krl; subR[13] = krr;
6953a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 15);
696d64beac0SNoriaki TAKAMIYA 	/* kl3 */
6971721a812SDenys Vlasenko 	subL[16] = kll; subR[16] = klr;
698d64beac0SNoriaki TAKAMIYA 	/* kl4 */
6991721a812SDenys Vlasenko 	subL[17] = krl; subR[17] = krr;
7003a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 17);
701d64beac0SNoriaki TAKAMIYA 	/* k17 */
7021721a812SDenys Vlasenko 	subL[22] = kll; subR[22] = klr;
703d64beac0SNoriaki TAKAMIYA 	/* k18 */
7041721a812SDenys Vlasenko 	subL[23] = krl; subR[23] = krr;
7053a5e5f81SDenys Vlasenko 	ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
706d64beac0SNoriaki TAKAMIYA 	/* k23 */
7071721a812SDenys Vlasenko 	subL[30] = kll; subR[30] = klr;
708d64beac0SNoriaki TAKAMIYA 	/* k24 */
7091721a812SDenys Vlasenko 	subL[31] = krl; subR[31] = krr;
710d64beac0SNoriaki TAKAMIYA 
711d64beac0SNoriaki TAKAMIYA 	/* generate KR dependent subkeys */
7123a5e5f81SDenys Vlasenko 	ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
713d64beac0SNoriaki TAKAMIYA 	/* k3 */
7141721a812SDenys Vlasenko 	subL[4] = krll; subR[4] = krlr;
715d64beac0SNoriaki TAKAMIYA 	/* k4 */
7161721a812SDenys Vlasenko 	subL[5] = krrl; subR[5] = krrr;
7173a5e5f81SDenys Vlasenko 	ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
718d64beac0SNoriaki TAKAMIYA 	/* kl1 */
7191721a812SDenys Vlasenko 	subL[8] = krll; subR[8] = krlr;
720d64beac0SNoriaki TAKAMIYA 	/* kl2 */
7211721a812SDenys Vlasenko 	subL[9] = krrl; subR[9] = krrr;
7223a5e5f81SDenys Vlasenko 	ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
723d64beac0SNoriaki TAKAMIYA 	/* k13 */
7241721a812SDenys Vlasenko 	subL[18] = krll; subR[18] = krlr;
725d64beac0SNoriaki TAKAMIYA 	/* k14 */
7261721a812SDenys Vlasenko 	subL[19] = krrl; subR[19] = krrr;
7273a5e5f81SDenys Vlasenko 	ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
728d64beac0SNoriaki TAKAMIYA 	/* k19 */
7291721a812SDenys Vlasenko 	subL[26] = krll; subR[26] = krlr;
730d64beac0SNoriaki TAKAMIYA 	/* k20 */
7311721a812SDenys Vlasenko 	subL[27] = krrl; subR[27] = krrr;
7323a5e5f81SDenys Vlasenko 	ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
733d64beac0SNoriaki TAKAMIYA 
734d64beac0SNoriaki TAKAMIYA 	/* generate KA */
7351721a812SDenys Vlasenko 	kll = subL[0] ^ krll; klr = subR[0] ^ krlr;
7361721a812SDenys Vlasenko 	krl = subL[1] ^ krrl; krr = subR[1] ^ krrr;
737d64beac0SNoriaki TAKAMIYA 	CAMELLIA_F(kll, klr,
738d64beac0SNoriaki TAKAMIYA 		   CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
739d64beac0SNoriaki TAKAMIYA 		   w0, w1, il, ir, t0, t1);
740d64beac0SNoriaki TAKAMIYA 	krl ^= w0; krr ^= w1;
741d64beac0SNoriaki TAKAMIYA 	CAMELLIA_F(krl, krr,
742d64beac0SNoriaki TAKAMIYA 		   CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
743d64beac0SNoriaki TAKAMIYA 		   kll, klr, il, ir, t0, t1);
744d64beac0SNoriaki TAKAMIYA 	kll ^= krll; klr ^= krlr;
745d64beac0SNoriaki TAKAMIYA 	CAMELLIA_F(kll, klr,
746d64beac0SNoriaki TAKAMIYA 		   CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
747d64beac0SNoriaki TAKAMIYA 		   krl, krr, il, ir, t0, t1);
748d64beac0SNoriaki TAKAMIYA 	krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
749d64beac0SNoriaki TAKAMIYA 	CAMELLIA_F(krl, krr,
750d64beac0SNoriaki TAKAMIYA 		   CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
751d64beac0SNoriaki TAKAMIYA 		   w0, w1, il, ir, t0, t1);
752d64beac0SNoriaki TAKAMIYA 	kll ^= w0; klr ^= w1;
753d64beac0SNoriaki TAKAMIYA 
754d64beac0SNoriaki TAKAMIYA 	/* generate KB */
755d64beac0SNoriaki TAKAMIYA 	krll ^= kll; krlr ^= klr;
756d64beac0SNoriaki TAKAMIYA 	krrl ^= krl; krrr ^= krr;
757d64beac0SNoriaki TAKAMIYA 	CAMELLIA_F(krll, krlr,
758d64beac0SNoriaki TAKAMIYA 		   CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
759d64beac0SNoriaki TAKAMIYA 		   w0, w1, il, ir, t0, t1);
760d64beac0SNoriaki TAKAMIYA 	krrl ^= w0; krrr ^= w1;
761d64beac0SNoriaki TAKAMIYA 	CAMELLIA_F(krrl, krrr,
762d64beac0SNoriaki TAKAMIYA 		   CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
763d64beac0SNoriaki TAKAMIYA 		   w0, w1, il, ir, t0, t1);
764d64beac0SNoriaki TAKAMIYA 	krll ^= w0; krlr ^= w1;
765d64beac0SNoriaki TAKAMIYA 
766d64beac0SNoriaki TAKAMIYA 	/* generate KA dependent subkeys */
7673a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 15);
768d64beac0SNoriaki TAKAMIYA 	/* k5 */
7691721a812SDenys Vlasenko 	subL[6] = kll; subR[6] = klr;
770d64beac0SNoriaki TAKAMIYA 	/* k6 */
7711721a812SDenys Vlasenko 	subL[7] = krl; subR[7] = krr;
7723a5e5f81SDenys Vlasenko 	ROLDQ(kll, klr, krl, krr, w0, w1, 30);
773d64beac0SNoriaki TAKAMIYA 	/* k11 */
7741721a812SDenys Vlasenko 	subL[14] = kll; subR[14] = klr;
775d64beac0SNoriaki TAKAMIYA 	/* k12 */
7761721a812SDenys Vlasenko 	subL[15] = krl; subR[15] = krr;
777d64beac0SNoriaki TAKAMIYA 	/* rotation left shift 32bit */
778d64beac0SNoriaki TAKAMIYA 	/* kl5 */
7791721a812SDenys Vlasenko 	subL[24] = klr; subR[24] = krl;
780d64beac0SNoriaki TAKAMIYA 	/* kl6 */
7811721a812SDenys Vlasenko 	subL[25] = krr; subR[25] = kll;
782d64beac0SNoriaki TAKAMIYA 	/* rotation left shift 49 from k11,k12 -> k21,k22 */
7833a5e5f81SDenys Vlasenko 	ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
784d64beac0SNoriaki TAKAMIYA 	/* k21 */
7851721a812SDenys Vlasenko 	subL[28] = kll; subR[28] = klr;
786d64beac0SNoriaki TAKAMIYA 	/* k22 */
7871721a812SDenys Vlasenko 	subL[29] = krl; subR[29] = krr;
788d64beac0SNoriaki TAKAMIYA 
789d64beac0SNoriaki TAKAMIYA 	/* generate KB dependent subkeys */
790d64beac0SNoriaki TAKAMIYA 	/* k1 */
7911721a812SDenys Vlasenko 	subL[2] = krll; subR[2] = krlr;
792d64beac0SNoriaki TAKAMIYA 	/* k2 */
7931721a812SDenys Vlasenko 	subL[3] = krrl; subR[3] = krrr;
7943a5e5f81SDenys Vlasenko 	ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
795d64beac0SNoriaki TAKAMIYA 	/* k7 */
7961721a812SDenys Vlasenko 	subL[10] = krll; subR[10] = krlr;
797d64beac0SNoriaki TAKAMIYA 	/* k8 */
7981721a812SDenys Vlasenko 	subL[11] = krrl; subR[11] = krrr;
7993a5e5f81SDenys Vlasenko 	ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
800d64beac0SNoriaki TAKAMIYA 	/* k15 */
8011721a812SDenys Vlasenko 	subL[20] = krll; subR[20] = krlr;
802d64beac0SNoriaki TAKAMIYA 	/* k16 */
8031721a812SDenys Vlasenko 	subL[21] = krrl; subR[21] = krrr;
8043a5e5f81SDenys Vlasenko 	ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
805d64beac0SNoriaki TAKAMIYA 	/* kw3 */
8061721a812SDenys Vlasenko 	subL[32] = krll; subR[32] = krlr;
807d64beac0SNoriaki TAKAMIYA 	/* kw4 */
8081721a812SDenys Vlasenko 	subL[33] = krrl; subR[33] = krrr;
809d64beac0SNoriaki TAKAMIYA 
810dedcf8b0SDenys Vlasenko 	camellia_setup_tail(subkey, subL, subR, 32);
811d64beac0SNoriaki TAKAMIYA }
812d64beac0SNoriaki TAKAMIYA 
813d64beac0SNoriaki TAKAMIYA static void camellia_setup192(const unsigned char *key, u32 *subkey)
814d64beac0SNoriaki TAKAMIYA {
815d64beac0SNoriaki TAKAMIYA 	unsigned char kk[32];
816d64beac0SNoriaki TAKAMIYA 	u32 krll, krlr, krrl, krrr;
817d64beac0SNoriaki TAKAMIYA 
818d64beac0SNoriaki TAKAMIYA 	memcpy(kk, key, 24);
819d64beac0SNoriaki TAKAMIYA 	memcpy((unsigned char *)&krll, key+16, 4);
820d64beac0SNoriaki TAKAMIYA 	memcpy((unsigned char *)&krlr, key+20, 4);
821d64beac0SNoriaki TAKAMIYA 	krrl = ~krll;
822d64beac0SNoriaki TAKAMIYA 	krrr = ~krlr;
823d64beac0SNoriaki TAKAMIYA 	memcpy(kk+24, (unsigned char *)&krrl, 4);
824d64beac0SNoriaki TAKAMIYA 	memcpy(kk+28, (unsigned char *)&krrr, 4);
825d64beac0SNoriaki TAKAMIYA 	camellia_setup256(kk, subkey);
826d64beac0SNoriaki TAKAMIYA }
827d64beac0SNoriaki TAKAMIYA 
828d64beac0SNoriaki TAKAMIYA 
8292ddae4a6SDenys Vlasenko /*
8302ddae4a6SDenys Vlasenko  * Encrypt/decrypt
8312ddae4a6SDenys Vlasenko  */
832e2861a71SJussi Kivilinna #define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) ({ \
8332ddae4a6SDenys Vlasenko 	t0 = kll;							\
8342ddae4a6SDenys Vlasenko 	t2 = krr;							\
8352ddae4a6SDenys Vlasenko 	t0 &= ll;							\
8362ddae4a6SDenys Vlasenko 	t2 |= rr;							\
8372ddae4a6SDenys Vlasenko 	rl ^= t2;							\
83832bd78e0SHarvey Harrison 	lr ^= rol32(t0, 1);						\
8392ddae4a6SDenys Vlasenko 	t3 = krl;							\
8402ddae4a6SDenys Vlasenko 	t1 = klr;							\
8412ddae4a6SDenys Vlasenko 	t3 &= rl;							\
8422ddae4a6SDenys Vlasenko 	t1 |= lr;							\
8432ddae4a6SDenys Vlasenko 	ll ^= t1;							\
84432bd78e0SHarvey Harrison 	rr ^= rol32(t3, 1);						\
845e2861a71SJussi Kivilinna })
8462ddae4a6SDenys Vlasenko 
847e2861a71SJussi Kivilinna #define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) ({		\
848c9b56d33SJussi Kivilinna 	yl ^= kl;							\
849c9b56d33SJussi Kivilinna 	yr ^= kr;							\
8502ddae4a6SDenys Vlasenko 	ir =  camellia_sp1110[(u8)xr];					\
851e2861a71SJussi Kivilinna 	il =  camellia_sp1110[(u8)(xl >> 24)];				\
852e2861a71SJussi Kivilinna 	ir ^= camellia_sp0222[(u8)(xr >> 24)];				\
8532ddae4a6SDenys Vlasenko 	il ^= camellia_sp0222[(u8)(xl >> 16)];				\
8542ddae4a6SDenys Vlasenko 	ir ^= camellia_sp3033[(u8)(xr >> 16)];				\
8552ddae4a6SDenys Vlasenko 	il ^= camellia_sp3033[(u8)(xl >> 8)];				\
8562ddae4a6SDenys Vlasenko 	ir ^= camellia_sp4404[(u8)(xr >> 8)];				\
8572ddae4a6SDenys Vlasenko 	il ^= camellia_sp4404[(u8)xl];					\
858c9b56d33SJussi Kivilinna 	ir ^= il;							\
8592ddae4a6SDenys Vlasenko 	yl ^= ir;							\
86032bd78e0SHarvey Harrison 	yr ^= ror32(il, 8) ^ ir;					\
861e2861a71SJussi Kivilinna })
8622ddae4a6SDenys Vlasenko 
863acca79a6SDenys Vlasenko /* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
864acca79a6SDenys Vlasenko static void camellia_do_encrypt(const u32 *subkey, u32 *io, unsigned max)
865d64beac0SNoriaki TAKAMIYA {
8663a5e5f81SDenys Vlasenko 	u32 il, ir, t0, t1;            /* temporary variables */
867d64beac0SNoriaki TAKAMIYA 
868d64beac0SNoriaki TAKAMIYA 	/* pre whitening but absorb kw2 */
869acca79a6SDenys Vlasenko 	io[0] ^= SUBKEY_L(0);
870acca79a6SDenys Vlasenko 	io[1] ^= SUBKEY_R(0);
871d64beac0SNoriaki TAKAMIYA 
8721721a812SDenys Vlasenko 	/* main iteration */
873e2861a71SJussi Kivilinna #define ROUNDS(i) ({ \
874acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[0], io[1], \
875acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 2), SUBKEY_R(i + 2), \
876acca79a6SDenys Vlasenko 			 io[2], io[3], il, ir); \
877acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[2], io[3], \
878acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 3), SUBKEY_R(i + 3), \
879acca79a6SDenys Vlasenko 			 io[0], io[1], il, ir); \
880acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[0], io[1], \
881acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 4), SUBKEY_R(i + 4), \
882acca79a6SDenys Vlasenko 			 io[2], io[3], il, ir); \
883acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[2], io[3], \
884acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 5), SUBKEY_R(i + 5), \
885acca79a6SDenys Vlasenko 			 io[0], io[1], il, ir); \
886acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[0], io[1], \
887acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 6), SUBKEY_R(i + 6), \
888acca79a6SDenys Vlasenko 			 io[2], io[3], il, ir); \
889acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[2], io[3], \
890acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 7), SUBKEY_R(i + 7), \
891acca79a6SDenys Vlasenko 			 io[0], io[1], il, ir); \
892e2861a71SJussi Kivilinna })
893e2861a71SJussi Kivilinna #define FLS(i) ({ \
894acca79a6SDenys Vlasenko 	CAMELLIA_FLS(io[0], io[1], io[2], io[3], \
895acca79a6SDenys Vlasenko 		     SUBKEY_L(i + 0), SUBKEY_R(i + 0), \
896acca79a6SDenys Vlasenko 		     SUBKEY_L(i + 1), SUBKEY_R(i + 1), \
897acca79a6SDenys Vlasenko 		     t0, t1, il, ir); \
898e2861a71SJussi Kivilinna })
899d64beac0SNoriaki TAKAMIYA 
900acca79a6SDenys Vlasenko 	ROUNDS(0);
901acca79a6SDenys Vlasenko 	FLS(8);
902acca79a6SDenys Vlasenko 	ROUNDS(8);
903acca79a6SDenys Vlasenko 	FLS(16);
904acca79a6SDenys Vlasenko 	ROUNDS(16);
905acca79a6SDenys Vlasenko 	if (max == 32) {
906acca79a6SDenys Vlasenko 		FLS(24);
907acca79a6SDenys Vlasenko 		ROUNDS(24);
908d64beac0SNoriaki TAKAMIYA 	}
909d64beac0SNoriaki TAKAMIYA 
910acca79a6SDenys Vlasenko #undef ROUNDS
911acca79a6SDenys Vlasenko #undef FLS
912d64beac0SNoriaki TAKAMIYA 
913d64beac0SNoriaki TAKAMIYA 	/* post whitening but kw4 */
914acca79a6SDenys Vlasenko 	io[2] ^= SUBKEY_L(max);
915acca79a6SDenys Vlasenko 	io[3] ^= SUBKEY_R(max);
916acca79a6SDenys Vlasenko 	/* NB: io[0],[1] should be swapped with [2],[3] by caller! */
917d64beac0SNoriaki TAKAMIYA }
918d64beac0SNoriaki TAKAMIYA 
919acca79a6SDenys Vlasenko static void camellia_do_decrypt(const u32 *subkey, u32 *io, unsigned i)
920d64beac0SNoriaki TAKAMIYA {
9213a5e5f81SDenys Vlasenko 	u32 il, ir, t0, t1;            /* temporary variables */
922d64beac0SNoriaki TAKAMIYA 
923d64beac0SNoriaki TAKAMIYA 	/* pre whitening but absorb kw2 */
924acca79a6SDenys Vlasenko 	io[0] ^= SUBKEY_L(i);
925acca79a6SDenys Vlasenko 	io[1] ^= SUBKEY_R(i);
926d64beac0SNoriaki TAKAMIYA 
927d64beac0SNoriaki TAKAMIYA 	/* main iteration */
928e2861a71SJussi Kivilinna #define ROUNDS(i) ({ \
929acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[0], io[1], \
930acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 7), SUBKEY_R(i + 7), \
931acca79a6SDenys Vlasenko 			 io[2], io[3], il, ir); \
932acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[2], io[3], \
933acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 6), SUBKEY_R(i + 6), \
934acca79a6SDenys Vlasenko 			 io[0], io[1], il, ir); \
935acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[0], io[1], \
936acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 5), SUBKEY_R(i + 5), \
937acca79a6SDenys Vlasenko 			 io[2], io[3], il, ir); \
938acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[2], io[3], \
939acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 4), SUBKEY_R(i + 4), \
940acca79a6SDenys Vlasenko 			 io[0], io[1], il, ir); \
941acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[0], io[1], \
942acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 3), SUBKEY_R(i + 3), \
943acca79a6SDenys Vlasenko 			 io[2], io[3], il, ir); \
944acca79a6SDenys Vlasenko 	CAMELLIA_ROUNDSM(io[2], io[3], \
945acca79a6SDenys Vlasenko 			 SUBKEY_L(i + 2), SUBKEY_R(i + 2), \
946acca79a6SDenys Vlasenko 			 io[0], io[1], il, ir); \
947e2861a71SJussi Kivilinna })
948e2861a71SJussi Kivilinna #define FLS(i) ({ \
949acca79a6SDenys Vlasenko 	CAMELLIA_FLS(io[0], io[1], io[2], io[3], \
950acca79a6SDenys Vlasenko 		     SUBKEY_L(i + 1), SUBKEY_R(i + 1), \
951acca79a6SDenys Vlasenko 		     SUBKEY_L(i + 0), SUBKEY_R(i + 0), \
952acca79a6SDenys Vlasenko 		     t0, t1, il, ir); \
953e2861a71SJussi Kivilinna })
954d64beac0SNoriaki TAKAMIYA 
955acca79a6SDenys Vlasenko 	if (i == 32) {
956acca79a6SDenys Vlasenko 		ROUNDS(24);
957acca79a6SDenys Vlasenko 		FLS(24);
958d64beac0SNoriaki TAKAMIYA 	}
959acca79a6SDenys Vlasenko 	ROUNDS(16);
960acca79a6SDenys Vlasenko 	FLS(16);
961acca79a6SDenys Vlasenko 	ROUNDS(8);
962acca79a6SDenys Vlasenko 	FLS(8);
963acca79a6SDenys Vlasenko 	ROUNDS(0);
964d64beac0SNoriaki TAKAMIYA 
965acca79a6SDenys Vlasenko #undef ROUNDS
966acca79a6SDenys Vlasenko #undef FLS
967d64beac0SNoriaki TAKAMIYA 
968d64beac0SNoriaki TAKAMIYA 	/* post whitening but kw4 */
969acca79a6SDenys Vlasenko 	io[2] ^= SUBKEY_L(0);
970acca79a6SDenys Vlasenko 	io[3] ^= SUBKEY_R(0);
971acca79a6SDenys Vlasenko 	/* NB: 0,1 should be swapped with 2,3 by caller! */
972d64beac0SNoriaki TAKAMIYA }
973d64beac0SNoriaki TAKAMIYA 
974d64beac0SNoriaki TAKAMIYA 
9751721a812SDenys Vlasenko struct camellia_ctx {
9761721a812SDenys Vlasenko 	int key_length;
9772ddae4a6SDenys Vlasenko 	u32 key_table[CAMELLIA_TABLE_BYTE_LEN / sizeof(u32)];
9781721a812SDenys Vlasenko };
9791721a812SDenys Vlasenko 
980d64beac0SNoriaki TAKAMIYA static int
981d64beac0SNoriaki TAKAMIYA camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
982d64beac0SNoriaki TAKAMIYA 		 unsigned int key_len)
983d64beac0SNoriaki TAKAMIYA {
984d64beac0SNoriaki TAKAMIYA 	struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
985d64beac0SNoriaki TAKAMIYA 	const unsigned char *key = (const unsigned char *)in_key;
986d64beac0SNoriaki TAKAMIYA 	u32 *flags = &tfm->crt_flags;
987d64beac0SNoriaki TAKAMIYA 
988d64beac0SNoriaki TAKAMIYA 	if (key_len != 16 && key_len != 24 && key_len != 32) {
989d64beac0SNoriaki TAKAMIYA 		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
990d64beac0SNoriaki TAKAMIYA 		return -EINVAL;
991d64beac0SNoriaki TAKAMIYA 	}
992d64beac0SNoriaki TAKAMIYA 
993d64beac0SNoriaki TAKAMIYA 	cctx->key_length = key_len;
994d64beac0SNoriaki TAKAMIYA 
995d64beac0SNoriaki TAKAMIYA 	switch (key_len) {
996d64beac0SNoriaki TAKAMIYA 	case 16:
997d64beac0SNoriaki TAKAMIYA 		camellia_setup128(key, cctx->key_table);
998d64beac0SNoriaki TAKAMIYA 		break;
999d64beac0SNoriaki TAKAMIYA 	case 24:
1000d64beac0SNoriaki TAKAMIYA 		camellia_setup192(key, cctx->key_table);
1001d64beac0SNoriaki TAKAMIYA 		break;
1002d64beac0SNoriaki TAKAMIYA 	case 32:
1003d64beac0SNoriaki TAKAMIYA 		camellia_setup256(key, cctx->key_table);
1004d64beac0SNoriaki TAKAMIYA 		break;
1005d64beac0SNoriaki TAKAMIYA 	}
1006d64beac0SNoriaki TAKAMIYA 
1007d64beac0SNoriaki TAKAMIYA 	return 0;
1008d64beac0SNoriaki TAKAMIYA }
1009d64beac0SNoriaki TAKAMIYA 
1010d64beac0SNoriaki TAKAMIYA static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1011d64beac0SNoriaki TAKAMIYA {
1012d64beac0SNoriaki TAKAMIYA 	const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1013d64beac0SNoriaki TAKAMIYA 	const __be32 *src = (const __be32 *)in;
1014d64beac0SNoriaki TAKAMIYA 	__be32 *dst = (__be32 *)out;
1015e2861a71SJussi Kivilinna 	unsigned int max;
1016d64beac0SNoriaki TAKAMIYA 
10173a5e5f81SDenys Vlasenko 	u32 tmp[4];
1018d64beac0SNoriaki TAKAMIYA 
10193a5e5f81SDenys Vlasenko 	tmp[0] = be32_to_cpu(src[0]);
10203a5e5f81SDenys Vlasenko 	tmp[1] = be32_to_cpu(src[1]);
10213a5e5f81SDenys Vlasenko 	tmp[2] = be32_to_cpu(src[2]);
10223a5e5f81SDenys Vlasenko 	tmp[3] = be32_to_cpu(src[3]);
1023d64beac0SNoriaki TAKAMIYA 
1024e2861a71SJussi Kivilinna 	if (cctx->key_length == 16)
1025e2861a71SJussi Kivilinna 		max = 24;
1026e2861a71SJussi Kivilinna 	else
1027e2861a71SJussi Kivilinna 		max = 32; /* for key lengths of 24 and 32 */
1028e2861a71SJussi Kivilinna 
1029e2861a71SJussi Kivilinna 	camellia_do_encrypt(cctx->key_table, tmp, max);
1030d64beac0SNoriaki TAKAMIYA 
1031acca79a6SDenys Vlasenko 	/* do_encrypt returns 0,1 swapped with 2,3 */
1032acca79a6SDenys Vlasenko 	dst[0] = cpu_to_be32(tmp[2]);
1033acca79a6SDenys Vlasenko 	dst[1] = cpu_to_be32(tmp[3]);
1034acca79a6SDenys Vlasenko 	dst[2] = cpu_to_be32(tmp[0]);
1035acca79a6SDenys Vlasenko 	dst[3] = cpu_to_be32(tmp[1]);
1036d64beac0SNoriaki TAKAMIYA }
1037d64beac0SNoriaki TAKAMIYA 
1038d64beac0SNoriaki TAKAMIYA static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1039d64beac0SNoriaki TAKAMIYA {
1040d64beac0SNoriaki TAKAMIYA 	const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1041d64beac0SNoriaki TAKAMIYA 	const __be32 *src = (const __be32 *)in;
1042d64beac0SNoriaki TAKAMIYA 	__be32 *dst = (__be32 *)out;
1043e2861a71SJussi Kivilinna 	unsigned int max;
1044d64beac0SNoriaki TAKAMIYA 
10453a5e5f81SDenys Vlasenko 	u32 tmp[4];
1046d64beac0SNoriaki TAKAMIYA 
10473a5e5f81SDenys Vlasenko 	tmp[0] = be32_to_cpu(src[0]);
10483a5e5f81SDenys Vlasenko 	tmp[1] = be32_to_cpu(src[1]);
10493a5e5f81SDenys Vlasenko 	tmp[2] = be32_to_cpu(src[2]);
10503a5e5f81SDenys Vlasenko 	tmp[3] = be32_to_cpu(src[3]);
1051d64beac0SNoriaki TAKAMIYA 
1052e2861a71SJussi Kivilinna 	if (cctx->key_length == 16)
1053e2861a71SJussi Kivilinna 		max = 24;
1054e2861a71SJussi Kivilinna 	else
1055e2861a71SJussi Kivilinna 		max = 32; /* for key lengths of 24 and 32 */
1056e2861a71SJussi Kivilinna 
1057e2861a71SJussi Kivilinna 	camellia_do_decrypt(cctx->key_table, tmp, max);
1058d64beac0SNoriaki TAKAMIYA 
1059acca79a6SDenys Vlasenko 	/* do_decrypt returns 0,1 swapped with 2,3 */
1060acca79a6SDenys Vlasenko 	dst[0] = cpu_to_be32(tmp[2]);
1061acca79a6SDenys Vlasenko 	dst[1] = cpu_to_be32(tmp[3]);
1062acca79a6SDenys Vlasenko 	dst[2] = cpu_to_be32(tmp[0]);
1063acca79a6SDenys Vlasenko 	dst[3] = cpu_to_be32(tmp[1]);
1064d64beac0SNoriaki TAKAMIYA }
1065d64beac0SNoriaki TAKAMIYA 
1066d64beac0SNoriaki TAKAMIYA static struct crypto_alg camellia_alg = {
1067d64beac0SNoriaki TAKAMIYA 	.cra_name		=	"camellia",
1068d64beac0SNoriaki TAKAMIYA 	.cra_driver_name	=	"camellia-generic",
1069d64beac0SNoriaki TAKAMIYA 	.cra_priority		=	100,
1070d64beac0SNoriaki TAKAMIYA 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
1071d64beac0SNoriaki TAKAMIYA 	.cra_blocksize		=	CAMELLIA_BLOCK_SIZE,
1072d64beac0SNoriaki TAKAMIYA 	.cra_ctxsize		=	sizeof(struct camellia_ctx),
1073d64beac0SNoriaki TAKAMIYA 	.cra_alignmask		=	3,
1074d64beac0SNoriaki TAKAMIYA 	.cra_module		=	THIS_MODULE,
1075d64beac0SNoriaki TAKAMIYA 	.cra_u			=	{
1076d64beac0SNoriaki TAKAMIYA 		.cipher = {
1077d64beac0SNoriaki TAKAMIYA 			.cia_min_keysize	=	CAMELLIA_MIN_KEY_SIZE,
1078d64beac0SNoriaki TAKAMIYA 			.cia_max_keysize	=	CAMELLIA_MAX_KEY_SIZE,
1079d64beac0SNoriaki TAKAMIYA 			.cia_setkey		=	camellia_set_key,
1080d64beac0SNoriaki TAKAMIYA 			.cia_encrypt		=	camellia_encrypt,
1081d64beac0SNoriaki TAKAMIYA 			.cia_decrypt		=	camellia_decrypt
1082d64beac0SNoriaki TAKAMIYA 		}
1083d64beac0SNoriaki TAKAMIYA 	}
1084d64beac0SNoriaki TAKAMIYA };
1085d64beac0SNoriaki TAKAMIYA 
1086d64beac0SNoriaki TAKAMIYA static int __init camellia_init(void)
1087d64beac0SNoriaki TAKAMIYA {
1088d64beac0SNoriaki TAKAMIYA 	return crypto_register_alg(&camellia_alg);
1089d64beac0SNoriaki TAKAMIYA }
1090d64beac0SNoriaki TAKAMIYA 
1091d64beac0SNoriaki TAKAMIYA static void __exit camellia_fini(void)
1092d64beac0SNoriaki TAKAMIYA {
1093d64beac0SNoriaki TAKAMIYA 	crypto_unregister_alg(&camellia_alg);
1094d64beac0SNoriaki TAKAMIYA }
1095d64beac0SNoriaki TAKAMIYA 
1096d64beac0SNoriaki TAKAMIYA module_init(camellia_init);
1097d64beac0SNoriaki TAKAMIYA module_exit(camellia_fini);
1098d64beac0SNoriaki TAKAMIYA 
1099d64beac0SNoriaki TAKAMIYA MODULE_DESCRIPTION("Camellia Cipher Algorithm");
1100d64beac0SNoriaki TAKAMIYA MODULE_LICENSE("GPL");
11015d26a105SKees Cook MODULE_ALIAS_CRYPTO("camellia");
11023e14dcf7SMathias Krause MODULE_ALIAS_CRYPTO("camellia-generic");
1103