blob: 9b1f068e45cc3d20d4c9499b10c80fb54f32de60 [file] [log] [blame]
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001/*
2 * Copyright (C) 2006
3 * NTT (Nippon Telegraph and Telephone Corporation).
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/*
21 * Algorithm Specification
22 * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
23 */
24
25/*
26 *
27 * NOTE --- NOTE --- NOTE --- NOTE
28 * This implementation assumes that all memory addresses passed
29 * as parameters are four-byte aligned.
30 *
31 */
32
33#include <linux/crypto.h>
34#include <linux/errno.h>
35#include <linux/init.h>
36#include <linux/kernel.h>
37#include <linux/module.h>
38
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +110039static const u32 camellia_sp1110[256] = {
40 0x70707000,0x82828200,0x2c2c2c00,0xececec00,
41 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
42 0xe4e4e400,0x85858500,0x57575700,0x35353500,
43 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
44 0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
45 0x45454500,0x19191900,0xa5a5a500,0x21212100,
46 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
47 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
48 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
49 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
50 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
51 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
52 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
53 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
54 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
55 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
56 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
57 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
58 0x74747400,0x12121200,0x2b2b2b00,0x20202000,
59 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
60 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
61 0x34343400,0x7e7e7e00,0x76767600,0x05050500,
62 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
63 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
64 0x14141400,0x58585800,0x3a3a3a00,0x61616100,
65 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
66 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
67 0x53535300,0x18181800,0xf2f2f200,0x22222200,
68 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
69 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
70 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
71 0x60606000,0xfcfcfc00,0x69696900,0x50505000,
72 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
73 0xa1a1a100,0x89898900,0x62626200,0x97979700,
74 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
75 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
76 0x10101000,0xc4c4c400,0x00000000,0x48484800,
77 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
78 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
79 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
80 0x87878700,0x5c5c5c00,0x83838300,0x02020200,
81 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
82 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
83 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
84 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
85 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
86 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
87 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
88 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
89 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
90 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
91 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
92 0x78787800,0x98989800,0x06060600,0x6a6a6a00,
93 0xe7e7e700,0x46464600,0x71717100,0xbababa00,
94 0xd4d4d400,0x25252500,0xababab00,0x42424200,
95 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
96 0x72727200,0x07070700,0xb9b9b900,0x55555500,
97 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
98 0x36363600,0x49494900,0x2a2a2a00,0x68686800,
99 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
100 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
101 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
102 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
103 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
104};
105
106static const u32 camellia_sp0222[256] = {
107 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
108 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
109 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
110 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
111 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
112 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
113 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
114 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
115 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
116 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
117 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
118 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
119 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
120 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
121 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
122 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
123 0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
124 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
125 0x00e8e8e8,0x00242424,0x00565656,0x00404040,
126 0x00e1e1e1,0x00636363,0x00090909,0x00333333,
127 0x00bfbfbf,0x00989898,0x00979797,0x00858585,
128 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
129 0x00dadada,0x006f6f6f,0x00535353,0x00626262,
130 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
131 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
132 0x00bdbdbd,0x00363636,0x00222222,0x00383838,
133 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
134 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
135 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
136 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
137 0x00484848,0x00101010,0x00d1d1d1,0x00515151,
138 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
139 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
140 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
141 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
142 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
143 0x00202020,0x00898989,0x00000000,0x00909090,
144 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
145 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
146 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
147 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
148 0x009b9b9b,0x00949494,0x00212121,0x00666666,
149 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
150 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
151 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
152 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
153 0x00030303,0x002d2d2d,0x00dedede,0x00969696,
154 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
155 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
156 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
157 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
158 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
159 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
160 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
161 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
162 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
163 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
164 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
165 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
166 0x00787878,0x00707070,0x00e3e3e3,0x00494949,
167 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
168 0x00777777,0x00939393,0x00868686,0x00838383,
169 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
170 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
171};
172
173static const u32 camellia_sp3033[256] = {
174 0x38003838,0x41004141,0x16001616,0x76007676,
175 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
176 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
177 0x75007575,0x06000606,0x57005757,0xa000a0a0,
178 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
179 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
180 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
181 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
182 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
183 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
184 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
185 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
186 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
187 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
188 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
189 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
190 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
191 0xfd00fdfd,0x66006666,0x58005858,0x96009696,
192 0x3a003a3a,0x09000909,0x95009595,0x10001010,
193 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
194 0xef00efef,0x26002626,0xe500e5e5,0x61006161,
195 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
196 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
197 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
198 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
199 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
200 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
201 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
202 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
203 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
204 0x12001212,0x04000404,0x74007474,0x54005454,
205 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
206 0x55005555,0x68006868,0x50005050,0xbe00bebe,
207 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
208 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
209 0x70007070,0xff00ffff,0x32003232,0x69006969,
210 0x08000808,0x62006262,0x00000000,0x24002424,
211 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
212 0x45004545,0x81008181,0x73007373,0x6d006d6d,
213 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
214 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
215 0xe600e6e6,0x25002525,0x48004848,0x99009999,
216 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
217 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
218 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
219 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
220 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
221 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
222 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
223 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
224 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
225 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
226 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
227 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
228 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
229 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
230 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
231 0x7c007c7c,0x77007777,0x56005656,0x05000505,
232 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
233 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
234 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
235 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
236 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
237 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
238};
239
240static const u32 camellia_sp4404[256] = {
241 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
242 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
243 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
244 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
245 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
246 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
247 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
248 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
249 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
250 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
251 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
252 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
253 0x14140014,0x3a3a003a,0xdede00de,0x11110011,
254 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
255 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
256 0x24240024,0xe8e800e8,0x60600060,0x69690069,
257 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
258 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
259 0x10100010,0x00000000,0xa3a300a3,0x75750075,
260 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
261 0x87870087,0x83830083,0xcdcd00cd,0x90900090,
262 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
263 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
264 0x81810081,0x6f6f006f,0x13130013,0x63630063,
265 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
266 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
267 0x78780078,0x06060006,0xe7e700e7,0x71710071,
268 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
269 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
270 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
271 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
272 0x15150015,0xadad00ad,0x77770077,0x80800080,
273 0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
274 0x85850085,0x35350035,0x0c0c000c,0x41410041,
275 0xefef00ef,0x93930093,0x19190019,0x21210021,
276 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
277 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
278 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
279 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
280 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
281 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
282 0x12120012,0x20200020,0xb1b100b1,0x99990099,
283 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
284 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
285 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
286 0x0f0f000f,0x16160016,0x18180018,0x22220022,
287 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
288 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
289 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
290 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
291 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
292 0x03030003,0xdada00da,0x3f3f003f,0x94940094,
293 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
294 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
295 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
296 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
297 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
298 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
299 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
300 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
301 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
302 0x49490049,0x68680068,0x38380038,0xa4a400a4,
303 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
304 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
305};
306
307
Denys Vlasenko1721a812007-11-06 22:01:20 +0800308#define CAMELLIA_MIN_KEY_SIZE 16
309#define CAMELLIA_MAX_KEY_SIZE 32
310#define CAMELLIA_BLOCK_SIZE 16
311#define CAMELLIA_TABLE_BYTE_LEN 272
312
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800313/*
314 * NB: L and R below stand for 'left' and 'right' as in written numbers.
315 * That is, in (xxxL,xxxR) pair xxxL holds most significant digits,
316 * _not_ least significant ones!
317 */
318
Denys Vlasenko1721a812007-11-06 22:01:20 +0800319
320/* key constants */
321
322#define CAMELLIA_SIGMA1L (0xA09E667FL)
323#define CAMELLIA_SIGMA1R (0x3BCC908BL)
324#define CAMELLIA_SIGMA2L (0xB67AE858L)
325#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
326#define CAMELLIA_SIGMA3L (0xC6EF372FL)
327#define CAMELLIA_SIGMA3R (0xE94F82BEL)
328#define CAMELLIA_SIGMA4L (0x54FF53A5L)
329#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
330#define CAMELLIA_SIGMA5L (0x10E527FAL)
331#define CAMELLIA_SIGMA5R (0xDE682D1DL)
332#define CAMELLIA_SIGMA6L (0xB05688C2L)
333#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
334
335/*
336 * macros
337 */
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800338#define GETU32(v, pt) \
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800339 do { \
340 /* latest breed of gcc is clever enough to use move */ \
341 memcpy(&(v), (pt), 4); \
342 (v) = be32_to_cpu(v); \
343 } while(0)
Denys Vlasenko1721a812007-11-06 22:01:20 +0800344
345/* rotation right shift 1byte */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800346#define ROR8(x) (((x) >> 8) + ((x) << 24))
Denys Vlasenko1721a812007-11-06 22:01:20 +0800347/* rotation left shift 1bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800348#define ROL1(x) (((x) << 1) + ((x) >> 31))
Denys Vlasenko1721a812007-11-06 22:01:20 +0800349/* rotation left shift 1byte */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800350#define ROL8(x) (((x) << 8) + ((x) >> 24))
Denys Vlasenko1721a812007-11-06 22:01:20 +0800351
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800352#define ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800353 do { \
354 w0 = ll; \
355 ll = (ll << bits) + (lr >> (32 - bits)); \
356 lr = (lr << bits) + (rl >> (32 - bits)); \
357 rl = (rl << bits) + (rr >> (32 - bits)); \
358 rr = (rr << bits) + (w0 >> (32 - bits)); \
359 } while(0)
360
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800361#define ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800362 do { \
363 w0 = ll; \
364 w1 = lr; \
365 ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
366 lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
367 rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
368 rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
369 } while(0)
370
Denys Vlasenko1721a812007-11-06 22:01:20 +0800371#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
372 do { \
373 il = xl ^ kl; \
374 ir = xr ^ kr; \
375 t0 = il >> 16; \
376 t1 = ir >> 16; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800377 yl = camellia_sp1110[(u8)(ir )] \
378 ^ camellia_sp0222[ (t1 >> 8)] \
379 ^ camellia_sp3033[(u8)(t1 )] \
380 ^ camellia_sp4404[(u8)(ir >> 8)]; \
381 yr = camellia_sp1110[ (t0 >> 8)] \
382 ^ camellia_sp0222[(u8)(t0 )] \
383 ^ camellia_sp3033[(u8)(il >> 8)] \
384 ^ camellia_sp4404[(u8)(il )]; \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800385 yl ^= yr; \
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800386 yr = ROR8(yr); \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800387 yr ^= yl; \
388 } while(0)
389
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800390#define SUBKEY_L(INDEX) (subkey[(INDEX)*2])
391#define SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1])
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100392
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800393static void camellia_setup_tail(u32 *subkey, int max)
394{
395 u32 dw;
396 int i = 2;
397 do {
398 dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = ROL8(dw);/* round 1 */
399 SUBKEY_R(i + 0) = SUBKEY_L(i + 0) ^ dw; SUBKEY_L(i + 0) = dw;
400 dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = ROL8(dw);/* round 2 */
401 SUBKEY_R(i + 1) = SUBKEY_L(i + 1) ^ dw; SUBKEY_L(i + 1) = dw;
402 dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = ROL8(dw);/* round 3 */
403 SUBKEY_R(i + 2) = SUBKEY_L(i + 2) ^ dw; SUBKEY_L(i + 2) = dw;
404 dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = ROL8(dw);/* round 4 */
405 SUBKEY_R(i + 3) = SUBKEY_L(i + 3) ^ dw; SUBKEY_L(i + 3) = dw;
406 dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = ROL8(dw);/* round 5 */
407 SUBKEY_R(i + 4) = SUBKEY_L(i + 4) ^ dw; SUBKEY_L(i + 4) = dw;
408 dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = ROL8(dw);/* round 6 */
409 SUBKEY_R(i + 5) = SUBKEY_L(i + 5) ^ dw; SUBKEY_L(i + 5) = dw;
410 i += 8;
411 } while (i < max);
412}
413
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100414static void camellia_setup128(const unsigned char *key, u32 *subkey)
415{
416 u32 kll, klr, krl, krr;
417 u32 il, ir, t0, t1, w0, w1;
418 u32 kw4l, kw4r, dw, tl, tr;
419 u32 subL[26];
420 u32 subR[26];
421
422 /**
423 * k == kll || klr || krl || krr (|| is concatination)
424 */
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800425 GETU32(kll, key );
426 GETU32(klr, key + 4);
427 GETU32(krl, key + 8);
428 GETU32(krr, key + 12);
429
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100430 /**
431 * generate KL dependent subkeys
432 */
433 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800434 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100435 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800436 subL[1] = krl; subR[1] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100437 /* rotation left shift 15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800438 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100439 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800440 subL[4] = kll; subR[4] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100441 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800442 subL[5] = krl; subR[5] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100443 /* rotation left shift 15+30bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800444 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100445 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800446 subL[10] = kll; subR[10] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100447 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800448 subL[11] = krl; subR[11] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100449 /* rotation left shift 15+30+15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800450 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100451 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800452 subL[13] = krl; subR[13] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100453 /* rotation left shift 15+30+15+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800454 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100455 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800456 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100457 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800458 subL[17] = krl; subR[17] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100459 /* rotation left shift 15+30+15+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800460 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100461 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800462 subL[18] = kll; subR[18] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100463 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800464 subL[19] = krl; subR[19] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100465 /* rotation left shift 15+30+15+17+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800466 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100467 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800468 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100469 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800470 subL[23] = krl; subR[23] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100471
472 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800473 kll = subL[0]; klr = subR[0];
474 krl = subL[1]; krr = subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100475 CAMELLIA_F(kll, klr,
476 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
477 w0, w1, il, ir, t0, t1);
478 krl ^= w0; krr ^= w1;
479 CAMELLIA_F(krl, krr,
480 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
481 kll, klr, il, ir, t0, t1);
482 /* current status == (kll, klr, w0, w1) */
483 CAMELLIA_F(kll, klr,
484 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
485 krl, krr, il, ir, t0, t1);
486 krl ^= w0; krr ^= w1;
487 CAMELLIA_F(krl, krr,
488 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
489 w0, w1, il, ir, t0, t1);
490 kll ^= w0; klr ^= w1;
491
492 /* generate KA dependent subkeys */
493 /* k1, k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800494 subL[2] = kll; subR[2] = klr;
495 subL[3] = krl; subR[3] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800496 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100497 /* k5,k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800498 subL[6] = kll; subR[6] = klr;
499 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800500 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100501 /* kl1, kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800502 subL[8] = kll; subR[8] = klr;
503 subL[9] = krl; subR[9] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800504 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100505 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800506 subL[12] = kll; subR[12] = klr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800507 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100508 /* k11, k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800509 subL[14] = kll; subR[14] = klr;
510 subL[15] = krl; subR[15] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800511 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100512 /* k15, k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800513 subL[20] = kll; subR[20] = klr;
514 subL[21] = krl; subR[21] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800515 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100516 /* kw3, kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800517 subL[24] = kll; subR[24] = klr;
518 subL[25] = krl; subR[25] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100519
520 /* absorb kw2 to other subkeys */
521 /* round 2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800522 subL[3] ^= subL[1]; subR[3] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100523 /* round 4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800524 subL[5] ^= subL[1]; subR[5] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100525 /* round 6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800526 subL[7] ^= subL[1]; subR[7] ^= subR[1];
527 subL[1] ^= subR[1] & ~subR[9];
528 dw = subL[1] & subL[9],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800529 subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100530 /* round 8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800531 subL[11] ^= subL[1]; subR[11] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100532 /* round 10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800533 subL[13] ^= subL[1]; subR[13] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100534 /* round 12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800535 subL[15] ^= subL[1]; subR[15] ^= subR[1];
536 subL[1] ^= subR[1] & ~subR[17];
537 dw = subL[1] & subL[17],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800538 subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100539 /* round 14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800540 subL[19] ^= subL[1]; subR[19] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100541 /* round 16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800542 subL[21] ^= subL[1]; subR[21] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100543 /* round 18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800544 subL[23] ^= subL[1]; subR[23] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100545 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800546 subL[24] ^= subL[1]; subR[24] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100547
548 /* absorb kw4 to other subkeys */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800549 kw4l = subL[25]; kw4r = subR[25];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100550 /* round 17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800551 subL[22] ^= kw4l; subR[22] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100552 /* round 15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800553 subL[20] ^= kw4l; subR[20] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100554 /* round 13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800555 subL[18] ^= kw4l; subR[18] ^= kw4r;
556 kw4l ^= kw4r & ~subR[16];
557 dw = kw4l & subL[16],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800558 kw4r ^= ROL1(dw); /* modified for FL(kl3) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100559 /* round 11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800560 subL[14] ^= kw4l; subR[14] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100561 /* round 9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800562 subL[12] ^= kw4l; subR[12] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100563 /* round 7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800564 subL[10] ^= kw4l; subR[10] ^= kw4r;
565 kw4l ^= kw4r & ~subR[8];
566 dw = kw4l & subL[8],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800567 kw4r ^= ROL1(dw); /* modified for FL(kl1) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100568 /* round 5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800569 subL[6] ^= kw4l; subR[6] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100570 /* round 3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800571 subL[4] ^= kw4l; subR[4] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100572 /* round 1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800573 subL[2] ^= kw4l; subR[2] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100574 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800575 subL[0] ^= kw4l; subR[0] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100576
577 /* key XOR is end of F-function */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800578 SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
579 SUBKEY_R(0) = subR[0] ^ subR[2];
580 SUBKEY_L(2) = subL[3]; /* round 1 */
581 SUBKEY_R(2) = subR[3];
582 SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
583 SUBKEY_R(3) = subR[2] ^ subR[4];
584 SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
585 SUBKEY_R(4) = subR[3] ^ subR[5];
586 SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
587 SUBKEY_R(5) = subR[4] ^ subR[6];
588 SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
589 SUBKEY_R(6) = subR[5] ^ subR[7];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800590 tl = subL[10] ^ (subR[10] & ~subR[8]);
591 dw = tl & subL[8], /* FL(kl1) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800592 tr = subR[10] ^ ROL1(dw);
593 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
594 SUBKEY_R(7) = subR[6] ^ tr;
595 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
596 SUBKEY_R(8) = subR[8];
597 SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
598 SUBKEY_R(9) = subR[9];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800599 tl = subL[7] ^ (subR[7] & ~subR[9]);
600 dw = tl & subL[9], /* FLinv(kl2) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800601 tr = subR[7] ^ ROL1(dw);
602 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
603 SUBKEY_R(10) = tr ^ subR[11];
604 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
605 SUBKEY_R(11) = subR[10] ^ subR[12];
606 SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
607 SUBKEY_R(12) = subR[11] ^ subR[13];
608 SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
609 SUBKEY_R(13) = subR[12] ^ subR[14];
610 SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
611 SUBKEY_R(14) = subR[13] ^ subR[15];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800612 tl = subL[18] ^ (subR[18] & ~subR[16]);
613 dw = tl & subL[16], /* FL(kl3) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800614 tr = subR[18] ^ ROL1(dw);
615 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
616 SUBKEY_R(15) = subR[14] ^ tr;
617 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
618 SUBKEY_R(16) = subR[16];
619 SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
620 SUBKEY_R(17) = subR[17];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800621 tl = subL[15] ^ (subR[15] & ~subR[17]);
622 dw = tl & subL[17], /* FLinv(kl4) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800623 tr = subR[15] ^ ROL1(dw);
624 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
625 SUBKEY_R(18) = tr ^ subR[19];
626 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
627 SUBKEY_R(19) = subR[18] ^ subR[20];
628 SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
629 SUBKEY_R(20) = subR[19] ^ subR[21];
630 SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
631 SUBKEY_R(21) = subR[20] ^ subR[22];
632 SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
633 SUBKEY_R(22) = subR[21] ^ subR[23];
634 SUBKEY_L(23) = subL[22]; /* round 18 */
635 SUBKEY_R(23) = subR[22];
636 SUBKEY_L(24) = subL[24] ^ subL[23]; /* kw3 */
637 SUBKEY_R(24) = subR[24] ^ subR[23];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100638
639 /* apply the inverse of the last half of P-function */
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800640 camellia_setup_tail(subkey, 24);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100641}
642
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100643static void camellia_setup256(const unsigned char *key, u32 *subkey)
644{
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800645 u32 kll, klr, krl, krr; /* left half of key */
646 u32 krll, krlr, krrl, krrr; /* right half of key */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100647 u32 il, ir, t0, t1, w0, w1; /* temporary variables */
648 u32 kw4l, kw4r, dw, tl, tr;
649 u32 subL[34];
650 u32 subR[34];
651
652 /**
653 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
654 * (|| is concatination)
655 */
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800656 GETU32(kll, key );
657 GETU32(klr, key + 4);
658 GETU32(krl, key + 8);
659 GETU32(krr, key + 12);
660 GETU32(krll, key + 16);
661 GETU32(krlr, key + 20);
662 GETU32(krrl, key + 24);
663 GETU32(krrr, key + 28);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100664
665 /* generate KL dependent subkeys */
666 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800667 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100668 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800669 subL[1] = krl; subR[1] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800670 ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100671 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800672 subL[12] = kll; subR[12] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100673 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800674 subL[13] = krl; subR[13] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800675 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100676 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800677 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100678 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800679 subL[17] = krl; subR[17] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800680 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100681 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800682 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100683 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800684 subL[23] = krl; subR[23] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800685 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100686 /* k23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800687 subL[30] = kll; subR[30] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100688 /* k24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800689 subL[31] = krl; subR[31] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100690
691 /* generate KR dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800692 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100693 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800694 subL[4] = krll; subR[4] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100695 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800696 subL[5] = krrl; subR[5] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800697 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100698 /* kl1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800699 subL[8] = krll; subR[8] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100700 /* kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800701 subL[9] = krrl; subR[9] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800702 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100703 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800704 subL[18] = krll; subR[18] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100705 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800706 subL[19] = krrl; subR[19] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800707 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100708 /* k19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800709 subL[26] = krll; subR[26] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100710 /* k20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800711 subL[27] = krrl; subR[27] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800712 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100713
714 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800715 kll = subL[0] ^ krll; klr = subR[0] ^ krlr;
716 krl = subL[1] ^ krrl; krr = subR[1] ^ krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100717 CAMELLIA_F(kll, klr,
718 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
719 w0, w1, il, ir, t0, t1);
720 krl ^= w0; krr ^= w1;
721 CAMELLIA_F(krl, krr,
722 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
723 kll, klr, il, ir, t0, t1);
724 kll ^= krll; klr ^= krlr;
725 CAMELLIA_F(kll, klr,
726 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
727 krl, krr, il, ir, t0, t1);
728 krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
729 CAMELLIA_F(krl, krr,
730 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
731 w0, w1, il, ir, t0, t1);
732 kll ^= w0; klr ^= w1;
733
734 /* generate KB */
735 krll ^= kll; krlr ^= klr;
736 krrl ^= krl; krrr ^= krr;
737 CAMELLIA_F(krll, krlr,
738 CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
739 w0, w1, il, ir, t0, t1);
740 krrl ^= w0; krrr ^= w1;
741 CAMELLIA_F(krrl, krrr,
742 CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
743 w0, w1, il, ir, t0, t1);
744 krll ^= w0; krlr ^= w1;
745
746 /* generate KA dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800747 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100748 /* k5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800749 subL[6] = kll; subR[6] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100750 /* k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800751 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800752 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100753 /* k11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800754 subL[14] = kll; subR[14] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100755 /* k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800756 subL[15] = krl; subR[15] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100757 /* rotation left shift 32bit */
758 /* kl5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800759 subL[24] = klr; subR[24] = krl;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100760 /* kl6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800761 subL[25] = krr; subR[25] = kll;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100762 /* rotation left shift 49 from k11,k12 -> k21,k22 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800763 ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100764 /* k21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800765 subL[28] = kll; subR[28] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100766 /* k22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800767 subL[29] = krl; subR[29] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100768
769 /* generate KB dependent subkeys */
770 /* k1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800771 subL[2] = krll; subR[2] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100772 /* k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800773 subL[3] = krrl; subR[3] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800774 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100775 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800776 subL[10] = krll; subR[10] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100777 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800778 subL[11] = krrl; subR[11] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800779 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100780 /* k15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800781 subL[20] = krll; subR[20] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100782 /* k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800783 subL[21] = krrl; subR[21] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800784 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100785 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800786 subL[32] = krll; subR[32] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100787 /* kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800788 subL[33] = krrl; subR[33] = krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100789
790 /* absorb kw2 to other subkeys */
791 /* round 2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800792 subL[3] ^= subL[1]; subR[3] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100793 /* round 4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800794 subL[5] ^= subL[1]; subR[5] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100795 /* round 6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800796 subL[7] ^= subL[1]; subR[7] ^= subR[1];
797 subL[1] ^= subR[1] & ~subR[9];
798 dw = subL[1] & subL[9],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800799 subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100800 /* round 8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800801 subL[11] ^= subL[1]; subR[11] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100802 /* round 10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800803 subL[13] ^= subL[1]; subR[13] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100804 /* round 12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800805 subL[15] ^= subL[1]; subR[15] ^= subR[1];
806 subL[1] ^= subR[1] & ~subR[17];
807 dw = subL[1] & subL[17],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800808 subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100809 /* round 14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800810 subL[19] ^= subL[1]; subR[19] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100811 /* round 16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800812 subL[21] ^= subL[1]; subR[21] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100813 /* round 18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800814 subL[23] ^= subL[1]; subR[23] ^= subR[1];
815 subL[1] ^= subR[1] & ~subR[25];
816 dw = subL[1] & subL[25],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800817 subR[1] ^= ROL1(dw); /* modified for FLinv(kl6) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100818 /* round 20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800819 subL[27] ^= subL[1]; subR[27] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100820 /* round 22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800821 subL[29] ^= subL[1]; subR[29] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100822 /* round 24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800823 subL[31] ^= subL[1]; subR[31] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100824 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800825 subL[32] ^= subL[1]; subR[32] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100826
827 /* absorb kw4 to other subkeys */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800828 kw4l = subL[33]; kw4r = subR[33];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100829 /* round 23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800830 subL[30] ^= kw4l; subR[30] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100831 /* round 21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800832 subL[28] ^= kw4l; subR[28] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100833 /* round 19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800834 subL[26] ^= kw4l; subR[26] ^= kw4r;
835 kw4l ^= kw4r & ~subR[24];
836 dw = kw4l & subL[24],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800837 kw4r ^= ROL1(dw); /* modified for FL(kl5) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100838 /* round 17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800839 subL[22] ^= kw4l; subR[22] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100840 /* round 15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800841 subL[20] ^= kw4l; subR[20] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100842 /* round 13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800843 subL[18] ^= kw4l; subR[18] ^= kw4r;
844 kw4l ^= kw4r & ~subR[16];
845 dw = kw4l & subL[16],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800846 kw4r ^= ROL1(dw); /* modified for FL(kl3) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100847 /* round 11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800848 subL[14] ^= kw4l; subR[14] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100849 /* round 9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800850 subL[12] ^= kw4l; subR[12] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100851 /* round 7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800852 subL[10] ^= kw4l; subR[10] ^= kw4r;
853 kw4l ^= kw4r & ~subR[8];
854 dw = kw4l & subL[8],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800855 kw4r ^= ROL1(dw); /* modified for FL(kl1) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100856 /* round 5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800857 subL[6] ^= kw4l; subR[6] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100858 /* round 3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800859 subL[4] ^= kw4l; subR[4] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100860 /* round 1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800861 subL[2] ^= kw4l; subR[2] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100862 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800863 subL[0] ^= kw4l; subR[0] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100864
865 /* key XOR is end of F-function */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800866 SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
867 SUBKEY_R(0) = subR[0] ^ subR[2];
868 SUBKEY_L(2) = subL[3]; /* round 1 */
869 SUBKEY_R(2) = subR[3];
870 SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
871 SUBKEY_R(3) = subR[2] ^ subR[4];
872 SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
873 SUBKEY_R(4) = subR[3] ^ subR[5];
874 SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
875 SUBKEY_R(5) = subR[4] ^ subR[6];
876 SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
877 SUBKEY_R(6) = subR[5] ^ subR[7];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800878 tl = subL[10] ^ (subR[10] & ~subR[8]);
879 dw = tl & subL[8], /* FL(kl1) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800880 tr = subR[10] ^ ROL1(dw);
881 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
882 SUBKEY_R(7) = subR[6] ^ tr;
883 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
884 SUBKEY_R(8) = subR[8];
885 SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
886 SUBKEY_R(9) = subR[9];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800887 tl = subL[7] ^ (subR[7] & ~subR[9]);
888 dw = tl & subL[9], /* FLinv(kl2) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800889 tr = subR[7] ^ ROL1(dw);
890 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
891 SUBKEY_R(10) = tr ^ subR[11];
892 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
893 SUBKEY_R(11) = subR[10] ^ subR[12];
894 SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
895 SUBKEY_R(12) = subR[11] ^ subR[13];
896 SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
897 SUBKEY_R(13) = subR[12] ^ subR[14];
898 SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
899 SUBKEY_R(14) = subR[13] ^ subR[15];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800900 tl = subL[18] ^ (subR[18] & ~subR[16]);
901 dw = tl & subL[16], /* FL(kl3) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800902 tr = subR[18] ^ ROL1(dw);
903 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
904 SUBKEY_R(15) = subR[14] ^ tr;
905 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
906 SUBKEY_R(16) = subR[16];
907 SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
908 SUBKEY_R(17) = subR[17];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800909 tl = subL[15] ^ (subR[15] & ~subR[17]);
910 dw = tl & subL[17], /* FLinv(kl4) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800911 tr = subR[15] ^ ROL1(dw);
912 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
913 SUBKEY_R(18) = tr ^ subR[19];
914 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
915 SUBKEY_R(19) = subR[18] ^ subR[20];
916 SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
917 SUBKEY_R(20) = subR[19] ^ subR[21];
918 SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
919 SUBKEY_R(21) = subR[20] ^ subR[22];
920 SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
921 SUBKEY_R(22) = subR[21] ^ subR[23];
922 tl = subL[26] ^ (subR[26] & ~subR[24]);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800923 dw = tl & subL[24], /* FL(kl5) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800924 tr = subR[26] ^ ROL1(dw);
925 SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
926 SUBKEY_R(23) = subR[22] ^ tr;
927 SUBKEY_L(24) = subL[24]; /* FL(kl5) */
928 SUBKEY_R(24) = subR[24];
929 SUBKEY_L(25) = subL[25]; /* FLinv(kl6) */
930 SUBKEY_R(25) = subR[25];
931 tl = subL[23] ^ (subR[23] & ~subR[25]);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800932 dw = tl & subL[25], /* FLinv(kl6) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800933 tr = subR[23] ^ ROL1(dw);
934 SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
935 SUBKEY_R(26) = tr ^ subR[27];
936 SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
937 SUBKEY_R(27) = subR[26] ^ subR[28];
938 SUBKEY_L(28) = subL[27] ^ subL[29]; /* round 21 */
939 SUBKEY_R(28) = subR[27] ^ subR[29];
940 SUBKEY_L(29) = subL[28] ^ subL[30]; /* round 22 */
941 SUBKEY_R(29) = subR[28] ^ subR[30];
942 SUBKEY_L(30) = subL[29] ^ subL[31]; /* round 23 */
943 SUBKEY_R(30) = subR[29] ^ subR[31];
944 SUBKEY_L(31) = subL[30]; /* round 24 */
945 SUBKEY_R(31) = subR[30];
946 SUBKEY_L(32) = subL[32] ^ subL[31]; /* kw3 */
947 SUBKEY_R(32) = subR[32] ^ subR[31];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100948
949 /* apply the inverse of the last half of P-function */
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800950 camellia_setup_tail(subkey, 32);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100951}
952
953static void camellia_setup192(const unsigned char *key, u32 *subkey)
954{
955 unsigned char kk[32];
956 u32 krll, krlr, krrl,krrr;
957
958 memcpy(kk, key, 24);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800959 memcpy((unsigned char *)&krll, key+16, 4);
960 memcpy((unsigned char *)&krlr, key+20, 4);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100961 krrl = ~krll;
962 krrr = ~krlr;
963 memcpy(kk+24, (unsigned char *)&krrl, 4);
964 memcpy(kk+28, (unsigned char *)&krrr, 4);
965 camellia_setup256(kk, subkey);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100966}
967
968
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800969/*
970 * Encrypt/decrypt
971 */
972#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
973 do { \
974 t0 = kll; \
975 t2 = krr; \
976 t0 &= ll; \
977 t2 |= rr; \
978 rl ^= t2; \
979 lr ^= ROL1(t0); \
980 t3 = krl; \
981 t1 = klr; \
982 t3 &= rl; \
983 t1 |= lr; \
984 ll ^= t1; \
985 rr ^= ROL1(t3); \
986 } while(0)
987
988#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) \
989 do { \
990 ir = camellia_sp1110[(u8)xr]; \
991 il = camellia_sp1110[ (xl >> 24)]; \
992 ir ^= camellia_sp0222[ (xr >> 24)]; \
993 il ^= camellia_sp0222[(u8)(xl >> 16)]; \
994 ir ^= camellia_sp3033[(u8)(xr >> 16)]; \
995 il ^= camellia_sp3033[(u8)(xl >> 8)]; \
996 ir ^= camellia_sp4404[(u8)(xr >> 8)]; \
997 il ^= camellia_sp4404[(u8)xl]; \
998 il ^= kl; \
999 ir ^= il ^ kr; \
1000 yl ^= ir; \
1001 yr ^= ROR8(il) ^ ir; \
1002 } while(0)
1003
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001004static void camellia_encrypt128(const u32 *subkey, u32 *io_text)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001005{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001006 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001007
1008 u32 io[4];
1009
Denys Vlasenko1721a812007-11-06 22:01:20 +08001010 /* pre whitening but absorb kw2 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001011 io[0] = io_text[0] ^ SUBKEY_L(0);
1012 io[1] = io_text[1] ^ SUBKEY_R(0);
1013 io[2] = io_text[2];
1014 io[3] = io_text[3];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001015
Denys Vlasenko1721a812007-11-06 22:01:20 +08001016 /* main iteration */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001017 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001018 SUBKEY_L(2),SUBKEY_R(2),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001019 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001020 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001021 SUBKEY_L(3),SUBKEY_R(3),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001022 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001023 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001024 SUBKEY_L(4),SUBKEY_R(4),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001025 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001026 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001027 SUBKEY_L(5),SUBKEY_R(5),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001028 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001029 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001030 SUBKEY_L(6),SUBKEY_R(6),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001031 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001032 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001033 SUBKEY_L(7),SUBKEY_R(7),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001034 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001035
1036 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001037 SUBKEY_L(8),SUBKEY_R(8),
1038 SUBKEY_L(9),SUBKEY_R(9),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001039 t0,t1,il,ir);
1040
1041 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001042 SUBKEY_L(10),SUBKEY_R(10),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001043 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001044 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001045 SUBKEY_L(11),SUBKEY_R(11),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001046 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001047 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001048 SUBKEY_L(12),SUBKEY_R(12),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001049 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001050 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001051 SUBKEY_L(13),SUBKEY_R(13),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001052 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001053 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001054 SUBKEY_L(14),SUBKEY_R(14),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001055 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001056 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001057 SUBKEY_L(15),SUBKEY_R(15),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001058 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001059
1060 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001061 SUBKEY_L(16),SUBKEY_R(16),
1062 SUBKEY_L(17),SUBKEY_R(17),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001063 t0,t1,il,ir);
1064
1065 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001066 SUBKEY_L(18),SUBKEY_R(18),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001067 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001068 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001069 SUBKEY_L(19),SUBKEY_R(19),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001070 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001071 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001072 SUBKEY_L(20),SUBKEY_R(20),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001073 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001074 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001075 SUBKEY_L(21),SUBKEY_R(21),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001076 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001077 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001078 SUBKEY_L(22),SUBKEY_R(22),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001079 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001080 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001081 SUBKEY_L(23),SUBKEY_R(23),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001082 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001083
1084 /* post whitening but kw4 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001085 io_text[0] = io[2] ^ SUBKEY_L(24);
1086 io_text[1] = io[3] ^ SUBKEY_R(24);
1087 io_text[2] = io[0];
1088 io_text[3] = io[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001089}
1090
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001091static void camellia_decrypt128(const u32 *subkey, u32 *io_text)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001092{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001093 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001094
1095 u32 io[4];
1096
Denys Vlasenko1721a812007-11-06 22:01:20 +08001097 /* pre whitening but absorb kw2 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001098 io[0] = io_text[0] ^ SUBKEY_L(24);
1099 io[1] = io_text[1] ^ SUBKEY_R(24);
1100 io[2] = io_text[2];
1101 io[3] = io_text[3];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001102
1103 /* main iteration */
1104 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001105 SUBKEY_L(23),SUBKEY_R(23),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001106 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001107 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001108 SUBKEY_L(22),SUBKEY_R(22),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001109 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001110 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001111 SUBKEY_L(21),SUBKEY_R(21),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001112 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001113 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001114 SUBKEY_L(20),SUBKEY_R(20),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001115 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001116 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001117 SUBKEY_L(19),SUBKEY_R(19),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001118 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001119 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001120 SUBKEY_L(18),SUBKEY_R(18),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001121 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001122
1123 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001124 SUBKEY_L(17),SUBKEY_R(17),
1125 SUBKEY_L(16),SUBKEY_R(16),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001126 t0,t1,il,ir);
1127
1128 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001129 SUBKEY_L(15),SUBKEY_R(15),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001130 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001131 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001132 SUBKEY_L(14),SUBKEY_R(14),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001133 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001134 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001135 SUBKEY_L(13),SUBKEY_R(13),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001136 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001137 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001138 SUBKEY_L(12),SUBKEY_R(12),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001139 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001140 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001141 SUBKEY_L(11),SUBKEY_R(11),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001142 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001143 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001144 SUBKEY_L(10),SUBKEY_R(10),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001145 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001146
1147 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001148 SUBKEY_L(9),SUBKEY_R(9),
1149 SUBKEY_L(8),SUBKEY_R(8),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001150 t0,t1,il,ir);
1151
1152 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001153 SUBKEY_L(7),SUBKEY_R(7),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001154 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001155 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001156 SUBKEY_L(6),SUBKEY_R(6),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001157 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001158 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001159 SUBKEY_L(5),SUBKEY_R(5),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001160 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001161 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001162 SUBKEY_L(4),SUBKEY_R(4),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001163 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001164 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001165 SUBKEY_L(3),SUBKEY_R(3),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001166 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001167 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001168 SUBKEY_L(2),SUBKEY_R(2),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001169 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001170
1171 /* post whitening but kw4 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001172 io_text[0] = io[2] ^ SUBKEY_L(0);
1173 io_text[1] = io[3] ^ SUBKEY_R(0);
1174 io_text[2] = io[0];
1175 io_text[3] = io[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001176}
1177
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001178static void camellia_encrypt256(const u32 *subkey, u32 *io_text)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001179{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001180 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001181
1182 u32 io[4];
1183
Denys Vlasenko1721a812007-11-06 22:01:20 +08001184 /* pre whitening but absorb kw2 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001185 io[0] = io_text[0] ^ SUBKEY_L(0);
1186 io[1] = io_text[1] ^ SUBKEY_R(0);
1187 io[2] = io_text[2];
1188 io[3] = io_text[3];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001189
1190 /* main iteration */
1191 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001192 SUBKEY_L(2),SUBKEY_R(2),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001193 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001194 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001195 SUBKEY_L(3),SUBKEY_R(3),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001196 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001197 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001198 SUBKEY_L(4),SUBKEY_R(4),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001199 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001200 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001201 SUBKEY_L(5),SUBKEY_R(5),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001202 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001203 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001204 SUBKEY_L(6),SUBKEY_R(6),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001205 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001206 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001207 SUBKEY_L(7),SUBKEY_R(7),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001208 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001209
1210 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001211 SUBKEY_L(8),SUBKEY_R(8),
1212 SUBKEY_L(9),SUBKEY_R(9),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001213 t0,t1,il,ir);
1214
1215 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001216 SUBKEY_L(10),SUBKEY_R(10),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001217 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001218 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001219 SUBKEY_L(11),SUBKEY_R(11),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001220 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001221 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001222 SUBKEY_L(12),SUBKEY_R(12),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001223 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001224 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001225 SUBKEY_L(13),SUBKEY_R(13),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001226 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001227 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001228 SUBKEY_L(14),SUBKEY_R(14),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001229 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001230 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001231 SUBKEY_L(15),SUBKEY_R(15),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001232 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001233
1234 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001235 SUBKEY_L(16),SUBKEY_R(16),
1236 SUBKEY_L(17),SUBKEY_R(17),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001237 t0,t1,il,ir);
1238
1239 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001240 SUBKEY_L(18),SUBKEY_R(18),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001241 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001242 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001243 SUBKEY_L(19),SUBKEY_R(19),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001244 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001245 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001246 SUBKEY_L(20),SUBKEY_R(20),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001247 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001248 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001249 SUBKEY_L(21),SUBKEY_R(21),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001250 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001251 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001252 SUBKEY_L(22),SUBKEY_R(22),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001253 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001254 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001255 SUBKEY_L(23),SUBKEY_R(23),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001256 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001257
1258 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001259 SUBKEY_L(24),SUBKEY_R(24),
1260 SUBKEY_L(25),SUBKEY_R(25),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001261 t0,t1,il,ir);
1262
1263 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001264 SUBKEY_L(26),SUBKEY_R(26),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001265 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001266 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001267 SUBKEY_L(27),SUBKEY_R(27),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001268 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001269 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001270 SUBKEY_L(28),SUBKEY_R(28),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001271 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001272 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001273 SUBKEY_L(29),SUBKEY_R(29),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001274 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001275 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001276 SUBKEY_L(30),SUBKEY_R(30),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001277 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001278 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001279 SUBKEY_L(31),SUBKEY_R(31),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001280 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001281
1282 /* post whitening but kw4 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001283 io_text[0] = io[2] ^ SUBKEY_L(32);
1284 io_text[1] = io[3] ^ SUBKEY_R(32);
1285 io_text[2] = io[0];
1286 io_text[3] = io[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001287}
1288
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001289static void camellia_decrypt256(const u32 *subkey, u32 *io_text)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001290{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001291 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001292
1293 u32 io[4];
1294
Denys Vlasenko1721a812007-11-06 22:01:20 +08001295 /* pre whitening but absorb kw2 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001296 io[0] = io_text[0] ^ SUBKEY_L(32);
1297 io[1] = io_text[1] ^ SUBKEY_R(32);
1298 io[2] = io_text[2];
1299 io[3] = io_text[3];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001300
1301 /* main iteration */
1302 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001303 SUBKEY_L(31),SUBKEY_R(31),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001304 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001305 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001306 SUBKEY_L(30),SUBKEY_R(30),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001307 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001308 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001309 SUBKEY_L(29),SUBKEY_R(29),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001310 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001311 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001312 SUBKEY_L(28),SUBKEY_R(28),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001313 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001314 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001315 SUBKEY_L(27),SUBKEY_R(27),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001316 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001317 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001318 SUBKEY_L(26),SUBKEY_R(26),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001319 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001320
1321 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001322 SUBKEY_L(25),SUBKEY_R(25),
1323 SUBKEY_L(24),SUBKEY_R(24),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001324 t0,t1,il,ir);
1325
1326 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001327 SUBKEY_L(23),SUBKEY_R(23),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001328 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001329 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001330 SUBKEY_L(22),SUBKEY_R(22),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001331 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001332 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001333 SUBKEY_L(21),SUBKEY_R(21),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001334 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001335 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001336 SUBKEY_L(20),SUBKEY_R(20),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001337 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001338 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001339 SUBKEY_L(19),SUBKEY_R(19),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001340 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001341 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001342 SUBKEY_L(18),SUBKEY_R(18),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001343 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001344
1345 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001346 SUBKEY_L(17),SUBKEY_R(17),
1347 SUBKEY_L(16),SUBKEY_R(16),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001348 t0,t1,il,ir);
1349
1350 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001351 SUBKEY_L(15),SUBKEY_R(15),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001352 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001353 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001354 SUBKEY_L(14),SUBKEY_R(14),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001355 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001356 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001357 SUBKEY_L(13),SUBKEY_R(13),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001358 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001359 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001360 SUBKEY_L(12),SUBKEY_R(12),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001361 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001362 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001363 SUBKEY_L(11),SUBKEY_R(11),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001364 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001365 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001366 SUBKEY_L(10),SUBKEY_R(10),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001367 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001368
1369 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001370 SUBKEY_L(9),SUBKEY_R(9),
1371 SUBKEY_L(8),SUBKEY_R(8),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001372 t0,t1,il,ir);
1373
1374 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001375 SUBKEY_L(7),SUBKEY_R(7),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001376 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001377 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001378 SUBKEY_L(6),SUBKEY_R(6),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001379 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001380 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001381 SUBKEY_L(5),SUBKEY_R(5),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001382 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001383 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001384 SUBKEY_L(4),SUBKEY_R(4),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001385 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001386 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001387 SUBKEY_L(3),SUBKEY_R(3),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001388 io[2],io[3],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001389 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001390 SUBKEY_L(2),SUBKEY_R(2),
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001391 io[0],io[1],il,ir);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001392
1393 /* post whitening but kw4 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001394 io_text[0] = io[2] ^ SUBKEY_L(0);
1395 io_text[1] = io[3] ^ SUBKEY_R(0);
1396 io_text[2] = io[0];
1397 io_text[3] = io[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001398}
1399
1400
Denys Vlasenko1721a812007-11-06 22:01:20 +08001401struct camellia_ctx {
1402 int key_length;
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001403 u32 key_table[CAMELLIA_TABLE_BYTE_LEN / sizeof(u32)];
Denys Vlasenko1721a812007-11-06 22:01:20 +08001404};
1405
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001406static int
1407camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
1408 unsigned int key_len)
1409{
1410 struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1411 const unsigned char *key = (const unsigned char *)in_key;
1412 u32 *flags = &tfm->crt_flags;
1413
1414 if (key_len != 16 && key_len != 24 && key_len != 32) {
1415 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
1416 return -EINVAL;
1417 }
1418
1419 cctx->key_length = key_len;
1420
Denys Vlasenko1721a812007-11-06 22:01:20 +08001421 switch (key_len) {
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001422 case 16:
1423 camellia_setup128(key, cctx->key_table);
1424 break;
1425 case 24:
1426 camellia_setup192(key, cctx->key_table);
1427 break;
1428 case 32:
1429 camellia_setup256(key, cctx->key_table);
1430 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001431 }
1432
1433 return 0;
1434}
1435
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001436static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1437{
1438 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1439 const __be32 *src = (const __be32 *)in;
1440 __be32 *dst = (__be32 *)out;
1441
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001442 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001443
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001444 tmp[0] = be32_to_cpu(src[0]);
1445 tmp[1] = be32_to_cpu(src[1]);
1446 tmp[2] = be32_to_cpu(src[2]);
1447 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001448
1449 switch (cctx->key_length) {
1450 case 16:
1451 camellia_encrypt128(cctx->key_table, tmp);
1452 break;
1453 case 24:
1454 /* fall through */
1455 case 32:
1456 camellia_encrypt256(cctx->key_table, tmp);
1457 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001458 }
1459
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001460 dst[0] = cpu_to_be32(tmp[0]);
1461 dst[1] = cpu_to_be32(tmp[1]);
1462 dst[2] = cpu_to_be32(tmp[2]);
1463 dst[3] = cpu_to_be32(tmp[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001464}
1465
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001466static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1467{
1468 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1469 const __be32 *src = (const __be32 *)in;
1470 __be32 *dst = (__be32 *)out;
1471
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001472 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001473
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001474 tmp[0] = be32_to_cpu(src[0]);
1475 tmp[1] = be32_to_cpu(src[1]);
1476 tmp[2] = be32_to_cpu(src[2]);
1477 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001478
1479 switch (cctx->key_length) {
1480 case 16:
1481 camellia_decrypt128(cctx->key_table, tmp);
1482 break;
1483 case 24:
1484 /* fall through */
1485 case 32:
1486 camellia_decrypt256(cctx->key_table, tmp);
1487 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001488 }
1489
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001490 dst[0] = cpu_to_be32(tmp[0]);
1491 dst[1] = cpu_to_be32(tmp[1]);
1492 dst[2] = cpu_to_be32(tmp[2]);
1493 dst[3] = cpu_to_be32(tmp[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001494}
1495
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001496static struct crypto_alg camellia_alg = {
1497 .cra_name = "camellia",
1498 .cra_driver_name = "camellia-generic",
1499 .cra_priority = 100,
1500 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
1501 .cra_blocksize = CAMELLIA_BLOCK_SIZE,
1502 .cra_ctxsize = sizeof(struct camellia_ctx),
1503 .cra_alignmask = 3,
1504 .cra_module = THIS_MODULE,
1505 .cra_list = LIST_HEAD_INIT(camellia_alg.cra_list),
1506 .cra_u = {
1507 .cipher = {
1508 .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
1509 .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
1510 .cia_setkey = camellia_set_key,
1511 .cia_encrypt = camellia_encrypt,
1512 .cia_decrypt = camellia_decrypt
1513 }
1514 }
1515};
1516
1517static int __init camellia_init(void)
1518{
1519 return crypto_register_alg(&camellia_alg);
1520}
1521
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001522static void __exit camellia_fini(void)
1523{
1524 crypto_unregister_alg(&camellia_alg);
1525}
1526
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001527module_init(camellia_init);
1528module_exit(camellia_fini);
1529
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001530MODULE_DESCRIPTION("Camellia Cipher Algorithm");
1531MODULE_LICENSE("GPL");