blob: ac372e43e2a3e17e18011a3a942a54189cdee9a6 [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
313
314/* key constants */
315
316#define CAMELLIA_SIGMA1L (0xA09E667FL)
317#define CAMELLIA_SIGMA1R (0x3BCC908BL)
318#define CAMELLIA_SIGMA2L (0xB67AE858L)
319#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
320#define CAMELLIA_SIGMA3L (0xC6EF372FL)
321#define CAMELLIA_SIGMA3R (0xE94F82BEL)
322#define CAMELLIA_SIGMA4L (0x54FF53A5L)
323#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
324#define CAMELLIA_SIGMA5L (0x10E527FAL)
325#define CAMELLIA_SIGMA5R (0xDE682D1DL)
326#define CAMELLIA_SIGMA6L (0xB05688C2L)
327#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
328
329/*
330 * macros
331 */
332
333# define GETU32(pt) (((u32)(pt)[0] << 24) \
334 ^ ((u32)(pt)[1] << 16) \
335 ^ ((u32)(pt)[2] << 8) \
336 ^ ((u32)(pt)[3]))
337
338/* rotation right shift 1byte */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800339#define ROR8(x) (((x) >> 8) + ((x) << 24))
Denys Vlasenko1721a812007-11-06 22:01:20 +0800340/* rotation left shift 1bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800341#define ROL1(x) (((x) << 1) + ((x) >> 31))
Denys Vlasenko1721a812007-11-06 22:01:20 +0800342/* rotation left shift 1byte */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800343#define ROL8(x) (((x) << 8) + ((x) >> 24))
Denys Vlasenko1721a812007-11-06 22:01:20 +0800344
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800345#define ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800346 do { \
347 w0 = ll; \
348 ll = (ll << bits) + (lr >> (32 - bits)); \
349 lr = (lr << bits) + (rl >> (32 - bits)); \
350 rl = (rl << bits) + (rr >> (32 - bits)); \
351 rr = (rr << bits) + (w0 >> (32 - bits)); \
352 } while(0)
353
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800354#define ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800355 do { \
356 w0 = ll; \
357 w1 = lr; \
358 ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
359 lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
360 rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
361 rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
362 } while(0)
363
364
365#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
366 do { \
367 il = xl ^ kl; \
368 ir = xr ^ kr; \
369 t0 = il >> 16; \
370 t1 = ir >> 16; \
371 yl = camellia_sp1110[ir & 0xff] \
372 ^ camellia_sp0222[(t1 >> 8) & 0xff] \
373 ^ camellia_sp3033[t1 & 0xff] \
374 ^ camellia_sp4404[(ir >> 8) & 0xff]; \
375 yr = camellia_sp1110[(t0 >> 8) & 0xff] \
376 ^ camellia_sp0222[t0 & 0xff] \
377 ^ camellia_sp3033[(il >> 8) & 0xff] \
378 ^ camellia_sp4404[il & 0xff]; \
379 yl ^= yr; \
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800380 yr = ROR8(yr); \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800381 yr ^= yl; \
382 } while(0)
383
384
385/*
386 * for speed up
387 *
388 */
389#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
390 do { \
391 t0 = kll; \
392 t2 = krr; \
393 t0 &= ll; \
394 t2 |= rr; \
395 rl ^= t2; \
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800396 lr ^= ROL1(t0); \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800397 t3 = krl; \
398 t1 = klr; \
399 t3 &= rl; \
400 t1 |= lr; \
401 ll ^= t1; \
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800402 rr ^= ROL1(t3); \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800403 } while(0)
404
405#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
406 do { \
407 ir = camellia_sp1110[xr & 0xff]; \
408 il = camellia_sp1110[(xl>>24) & 0xff]; \
409 ir ^= camellia_sp0222[(xr>>24) & 0xff]; \
410 il ^= camellia_sp0222[(xl>>16) & 0xff]; \
411 ir ^= camellia_sp3033[(xr>>16) & 0xff]; \
412 il ^= camellia_sp3033[(xl>>8) & 0xff]; \
413 ir ^= camellia_sp4404[(xr>>8) & 0xff]; \
414 il ^= camellia_sp4404[xl & 0xff]; \
415 il ^= kl; \
416 ir ^= il ^ kr; \
417 yl ^= ir; \
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800418 yr ^= ROR8(il) ^ ir; \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800419 } while(0)
420
421
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800422#define SUBKEY_L(INDEX) (subkey[(INDEX)*2])
423#define SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1])
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100424
425static void camellia_setup128(const unsigned char *key, u32 *subkey)
426{
427 u32 kll, klr, krl, krr;
428 u32 il, ir, t0, t1, w0, w1;
429 u32 kw4l, kw4r, dw, tl, tr;
430 u32 subL[26];
431 u32 subR[26];
432
433 /**
434 * k == kll || klr || krl || krr (|| is concatination)
435 */
436 kll = GETU32(key );
437 klr = GETU32(key + 4);
438 krl = GETU32(key + 8);
439 krr = GETU32(key + 12);
440 /**
441 * generate KL dependent subkeys
442 */
443 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800444 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100445 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800446 subL[1] = krl; subR[1] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100447 /* rotation left shift 15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800448 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100449 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800450 subL[4] = kll; subR[4] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100451 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800452 subL[5] = krl; subR[5] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100453 /* rotation left shift 15+30bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800454 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100455 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800456 subL[10] = kll; subR[10] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100457 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800458 subL[11] = krl; subR[11] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100459 /* rotation left shift 15+30+15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800460 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100461 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800462 subL[13] = krl; subR[13] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100463 /* rotation left shift 15+30+15+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800464 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100465 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800466 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100467 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800468 subL[17] = krl; subR[17] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100469 /* rotation left shift 15+30+15+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800470 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100471 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800472 subL[18] = kll; subR[18] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100473 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800474 subL[19] = krl; subR[19] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100475 /* rotation left shift 15+30+15+17+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800476 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100477 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800478 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100479 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800480 subL[23] = krl; subR[23] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100481
482 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800483 kll = subL[0]; klr = subR[0];
484 krl = subL[1]; krr = subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100485 CAMELLIA_F(kll, klr,
486 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
487 w0, w1, il, ir, t0, t1);
488 krl ^= w0; krr ^= w1;
489 CAMELLIA_F(krl, krr,
490 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
491 kll, klr, il, ir, t0, t1);
492 /* current status == (kll, klr, w0, w1) */
493 CAMELLIA_F(kll, klr,
494 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
495 krl, krr, il, ir, t0, t1);
496 krl ^= w0; krr ^= w1;
497 CAMELLIA_F(krl, krr,
498 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
499 w0, w1, il, ir, t0, t1);
500 kll ^= w0; klr ^= w1;
501
502 /* generate KA dependent subkeys */
503 /* k1, k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800504 subL[2] = kll; subR[2] = klr;
505 subL[3] = krl; subR[3] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800506 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100507 /* k5,k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800508 subL[6] = kll; subR[6] = klr;
509 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800510 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100511 /* kl1, kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800512 subL[8] = kll; subR[8] = klr;
513 subL[9] = krl; subR[9] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800514 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100515 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800516 subL[12] = kll; subR[12] = klr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800517 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100518 /* k11, k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800519 subL[14] = kll; subR[14] = klr;
520 subL[15] = krl; subR[15] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800521 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100522 /* k15, k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800523 subL[20] = kll; subR[20] = klr;
524 subL[21] = krl; subR[21] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800525 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100526 /* kw3, kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800527 subL[24] = kll; subR[24] = klr;
528 subL[25] = krl; subR[25] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100529
530 /* absorb kw2 to other subkeys */
531 /* round 2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800532 subL[3] ^= subL[1]; subR[3] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100533 /* round 4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800534 subL[5] ^= subL[1]; subR[5] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100535 /* round 6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800536 subL[7] ^= subL[1]; subR[7] ^= subR[1];
537 subL[1] ^= subR[1] & ~subR[9];
538 dw = subL[1] & subL[9],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800539 subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100540 /* round 8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800541 subL[11] ^= subL[1]; subR[11] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100542 /* round 10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800543 subL[13] ^= subL[1]; subR[13] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100544 /* round 12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800545 subL[15] ^= subL[1]; subR[15] ^= subR[1];
546 subL[1] ^= subR[1] & ~subR[17];
547 dw = subL[1] & subL[17],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800548 subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100549 /* round 14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800550 subL[19] ^= subL[1]; subR[19] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100551 /* round 16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800552 subL[21] ^= subL[1]; subR[21] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100553 /* round 18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800554 subL[23] ^= subL[1]; subR[23] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100555 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800556 subL[24] ^= subL[1]; subR[24] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100557
558 /* absorb kw4 to other subkeys */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800559 kw4l = subL[25]; kw4r = subR[25];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100560 /* round 17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800561 subL[22] ^= kw4l; subR[22] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100562 /* round 15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800563 subL[20] ^= kw4l; subR[20] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100564 /* round 13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800565 subL[18] ^= kw4l; subR[18] ^= kw4r;
566 kw4l ^= kw4r & ~subR[16];
567 dw = kw4l & subL[16],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800568 kw4r ^= ROL1(dw); /* modified for FL(kl3) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100569 /* round 11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800570 subL[14] ^= kw4l; subR[14] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100571 /* round 9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800572 subL[12] ^= kw4l; subR[12] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100573 /* round 7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800574 subL[10] ^= kw4l; subR[10] ^= kw4r;
575 kw4l ^= kw4r & ~subR[8];
576 dw = kw4l & subL[8],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800577 kw4r ^= ROL1(dw); /* modified for FL(kl1) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100578 /* round 5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800579 subL[6] ^= kw4l; subR[6] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100580 /* round 3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800581 subL[4] ^= kw4l; subR[4] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100582 /* round 1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800583 subL[2] ^= kw4l; subR[2] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100584 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800585 subL[0] ^= kw4l; subR[0] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100586
587 /* key XOR is end of F-function */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800588 SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
589 SUBKEY_R(0) = subR[0] ^ subR[2];
590 SUBKEY_L(2) = subL[3]; /* round 1 */
591 SUBKEY_R(2) = subR[3];
592 SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
593 SUBKEY_R(3) = subR[2] ^ subR[4];
594 SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
595 SUBKEY_R(4) = subR[3] ^ subR[5];
596 SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
597 SUBKEY_R(5) = subR[4] ^ subR[6];
598 SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
599 SUBKEY_R(6) = subR[5] ^ subR[7];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800600 tl = subL[10] ^ (subR[10] & ~subR[8]);
601 dw = tl & subL[8], /* FL(kl1) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800602 tr = subR[10] ^ ROL1(dw);
603 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
604 SUBKEY_R(7) = subR[6] ^ tr;
605 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
606 SUBKEY_R(8) = subR[8];
607 SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
608 SUBKEY_R(9) = subR[9];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800609 tl = subL[7] ^ (subR[7] & ~subR[9]);
610 dw = tl & subL[9], /* FLinv(kl2) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800611 tr = subR[7] ^ ROL1(dw);
612 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
613 SUBKEY_R(10) = tr ^ subR[11];
614 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
615 SUBKEY_R(11) = subR[10] ^ subR[12];
616 SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
617 SUBKEY_R(12) = subR[11] ^ subR[13];
618 SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
619 SUBKEY_R(13) = subR[12] ^ subR[14];
620 SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
621 SUBKEY_R(14) = subR[13] ^ subR[15];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800622 tl = subL[18] ^ (subR[18] & ~subR[16]);
623 dw = tl & subL[16], /* FL(kl3) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800624 tr = subR[18] ^ ROL1(dw);
625 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
626 SUBKEY_R(15) = subR[14] ^ tr;
627 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
628 SUBKEY_R(16) = subR[16];
629 SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
630 SUBKEY_R(17) = subR[17];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800631 tl = subL[15] ^ (subR[15] & ~subR[17]);
632 dw = tl & subL[17], /* FLinv(kl4) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800633 tr = subR[15] ^ ROL1(dw);
634 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
635 SUBKEY_R(18) = tr ^ subR[19];
636 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
637 SUBKEY_R(19) = subR[18] ^ subR[20];
638 SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
639 SUBKEY_R(20) = subR[19] ^ subR[21];
640 SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
641 SUBKEY_R(21) = subR[20] ^ subR[22];
642 SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
643 SUBKEY_R(22) = subR[21] ^ subR[23];
644 SUBKEY_L(23) = subL[22]; /* round 18 */
645 SUBKEY_R(23) = subR[22];
646 SUBKEY_L(24) = subL[24] ^ subL[23]; /* kw3 */
647 SUBKEY_R(24) = subR[24] ^ subR[23];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100648
649 /* apply the inverse of the last half of P-function */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800650 dw = SUBKEY_L(2) ^ SUBKEY_R(2); dw = ROL8(dw);/* round 1 */
651 SUBKEY_R(2) = SUBKEY_L(2) ^ dw; SUBKEY_L(2) = dw;
652 dw = SUBKEY_L(3) ^ SUBKEY_R(3); dw = ROL8(dw);/* round 2 */
653 SUBKEY_R(3) = SUBKEY_L(3) ^ dw; SUBKEY_L(3) = dw;
654 dw = SUBKEY_L(4) ^ SUBKEY_R(4); dw = ROL8(dw);/* round 3 */
655 SUBKEY_R(4) = SUBKEY_L(4) ^ dw; SUBKEY_L(4) = dw;
656 dw = SUBKEY_L(5) ^ SUBKEY_R(5); dw = ROL8(dw);/* round 4 */
657 SUBKEY_R(5) = SUBKEY_L(5) ^ dw; SUBKEY_L(5) = dw;
658 dw = SUBKEY_L(6) ^ SUBKEY_R(6); dw = ROL8(dw);/* round 5 */
659 SUBKEY_R(6) = SUBKEY_L(6) ^ dw; SUBKEY_L(6) = dw;
660 dw = SUBKEY_L(7) ^ SUBKEY_R(7); dw = ROL8(dw);/* round 6 */
661 SUBKEY_R(7) = SUBKEY_L(7) ^ dw; SUBKEY_L(7) = dw;
662 dw = SUBKEY_L(10) ^ SUBKEY_R(10); dw = ROL8(dw);/* round 7 */
663 SUBKEY_R(10) = SUBKEY_L(10) ^ dw; SUBKEY_L(10) = dw;
664 dw = SUBKEY_L(11) ^ SUBKEY_R(11); dw = ROL8(dw);/* round 8 */
665 SUBKEY_R(11) = SUBKEY_L(11) ^ dw; SUBKEY_L(11) = dw;
666 dw = SUBKEY_L(12) ^ SUBKEY_R(12); dw = ROL8(dw);/* round 9 */
667 SUBKEY_R(12) = SUBKEY_L(12) ^ dw; SUBKEY_L(12) = dw;
668 dw = SUBKEY_L(13) ^ SUBKEY_R(13); dw = ROL8(dw);/* round 10 */
669 SUBKEY_R(13) = SUBKEY_L(13) ^ dw; SUBKEY_L(13) = dw;
670 dw = SUBKEY_L(14) ^ SUBKEY_R(14); dw = ROL8(dw);/* round 11 */
671 SUBKEY_R(14) = SUBKEY_L(14) ^ dw; SUBKEY_L(14) = dw;
672 dw = SUBKEY_L(15) ^ SUBKEY_R(15); dw = ROL8(dw);/* round 12 */
673 SUBKEY_R(15) = SUBKEY_L(15) ^ dw; SUBKEY_L(15) = dw;
674 dw = SUBKEY_L(18) ^ SUBKEY_R(18); dw = ROL8(dw);/* round 13 */
675 SUBKEY_R(18) = SUBKEY_L(18) ^ dw; SUBKEY_L(18) = dw;
676 dw = SUBKEY_L(19) ^ SUBKEY_R(19); dw = ROL8(dw);/* round 14 */
677 SUBKEY_R(19) = SUBKEY_L(19) ^ dw; SUBKEY_L(19) = dw;
678 dw = SUBKEY_L(20) ^ SUBKEY_R(20); dw = ROL8(dw);/* round 15 */
679 SUBKEY_R(20) = SUBKEY_L(20) ^ dw; SUBKEY_L(20) = dw;
680 dw = SUBKEY_L(21) ^ SUBKEY_R(21); dw = ROL8(dw);/* round 16 */
681 SUBKEY_R(21) = SUBKEY_L(21) ^ dw; SUBKEY_L(21) = dw;
682 dw = SUBKEY_L(22) ^ SUBKEY_R(22); dw = ROL8(dw);/* round 17 */
683 SUBKEY_R(22) = SUBKEY_L(22) ^ dw; SUBKEY_L(22) = dw;
684 dw = SUBKEY_L(23) ^ SUBKEY_R(23); dw = ROL8(dw);/* round 18 */
685 SUBKEY_R(23) = SUBKEY_L(23) ^ dw; SUBKEY_L(23) = dw;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100686}
687
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100688static void camellia_setup256(const unsigned char *key, u32 *subkey)
689{
690 u32 kll,klr,krl,krr; /* left half of key */
691 u32 krll,krlr,krrl,krrr; /* right half of key */
692 u32 il, ir, t0, t1, w0, w1; /* temporary variables */
693 u32 kw4l, kw4r, dw, tl, tr;
694 u32 subL[34];
695 u32 subR[34];
696
697 /**
698 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
699 * (|| is concatination)
700 */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100701 kll = GETU32(key );
702 klr = GETU32(key + 4);
703 krl = GETU32(key + 8);
704 krr = GETU32(key + 12);
705 krll = GETU32(key + 16);
706 krlr = GETU32(key + 20);
707 krrl = GETU32(key + 24);
708 krrr = GETU32(key + 28);
709
710 /* generate KL dependent subkeys */
711 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800712 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100713 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800714 subL[1] = krl; subR[1] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800715 ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100716 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800717 subL[12] = kll; subR[12] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100718 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800719 subL[13] = krl; subR[13] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800720 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100721 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800722 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100723 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800724 subL[17] = krl; subR[17] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800725 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100726 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800727 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100728 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800729 subL[23] = krl; subR[23] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800730 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100731 /* k23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800732 subL[30] = kll; subR[30] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100733 /* k24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800734 subL[31] = krl; subR[31] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100735
736 /* generate KR dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800737 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100738 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800739 subL[4] = krll; subR[4] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100740 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800741 subL[5] = krrl; subR[5] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800742 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100743 /* kl1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800744 subL[8] = krll; subR[8] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100745 /* kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800746 subL[9] = krrl; subR[9] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800747 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100748 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800749 subL[18] = krll; subR[18] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100750 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800751 subL[19] = krrl; subR[19] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800752 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100753 /* k19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800754 subL[26] = krll; subR[26] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100755 /* k20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800756 subL[27] = krrl; subR[27] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800757 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100758
759 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800760 kll = subL[0] ^ krll; klr = subR[0] ^ krlr;
761 krl = subL[1] ^ krrl; krr = subR[1] ^ krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100762 CAMELLIA_F(kll, klr,
763 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
764 w0, w1, il, ir, t0, t1);
765 krl ^= w0; krr ^= w1;
766 CAMELLIA_F(krl, krr,
767 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
768 kll, klr, il, ir, t0, t1);
769 kll ^= krll; klr ^= krlr;
770 CAMELLIA_F(kll, klr,
771 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
772 krl, krr, il, ir, t0, t1);
773 krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
774 CAMELLIA_F(krl, krr,
775 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
776 w0, w1, il, ir, t0, t1);
777 kll ^= w0; klr ^= w1;
778
779 /* generate KB */
780 krll ^= kll; krlr ^= klr;
781 krrl ^= krl; krrr ^= krr;
782 CAMELLIA_F(krll, krlr,
783 CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
784 w0, w1, il, ir, t0, t1);
785 krrl ^= w0; krrr ^= w1;
786 CAMELLIA_F(krrl, krrr,
787 CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
788 w0, w1, il, ir, t0, t1);
789 krll ^= w0; krlr ^= w1;
790
791 /* generate KA dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800792 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100793 /* k5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800794 subL[6] = kll; subR[6] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100795 /* k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800796 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800797 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100798 /* k11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800799 subL[14] = kll; subR[14] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100800 /* k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800801 subL[15] = krl; subR[15] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100802 /* rotation left shift 32bit */
803 /* kl5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800804 subL[24] = klr; subR[24] = krl;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100805 /* kl6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800806 subL[25] = krr; subR[25] = kll;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100807 /* rotation left shift 49 from k11,k12 -> k21,k22 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800808 ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100809 /* k21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800810 subL[28] = kll; subR[28] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100811 /* k22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800812 subL[29] = krl; subR[29] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100813
814 /* generate KB dependent subkeys */
815 /* k1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800816 subL[2] = krll; subR[2] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100817 /* k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800818 subL[3] = krrl; subR[3] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800819 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100820 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800821 subL[10] = krll; subR[10] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100822 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800823 subL[11] = krrl; subR[11] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800824 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100825 /* k15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800826 subL[20] = krll; subR[20] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100827 /* k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800828 subL[21] = krrl; subR[21] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800829 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100830 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800831 subL[32] = krll; subR[32] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100832 /* kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800833 subL[33] = krrl; subR[33] = krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100834
835 /* absorb kw2 to other subkeys */
836 /* round 2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800837 subL[3] ^= subL[1]; subR[3] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100838 /* round 4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800839 subL[5] ^= subL[1]; subR[5] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100840 /* round 6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800841 subL[7] ^= subL[1]; subR[7] ^= subR[1];
842 subL[1] ^= subR[1] & ~subR[9];
843 dw = subL[1] & subL[9],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800844 subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100845 /* round 8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800846 subL[11] ^= subL[1]; subR[11] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100847 /* round 10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800848 subL[13] ^= subL[1]; subR[13] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100849 /* round 12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800850 subL[15] ^= subL[1]; subR[15] ^= subR[1];
851 subL[1] ^= subR[1] & ~subR[17];
852 dw = subL[1] & subL[17],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800853 subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100854 /* round 14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800855 subL[19] ^= subL[1]; subR[19] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100856 /* round 16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800857 subL[21] ^= subL[1]; subR[21] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100858 /* round 18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800859 subL[23] ^= subL[1]; subR[23] ^= subR[1];
860 subL[1] ^= subR[1] & ~subR[25];
861 dw = subL[1] & subL[25],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800862 subR[1] ^= ROL1(dw); /* modified for FLinv(kl6) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100863 /* round 20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800864 subL[27] ^= subL[1]; subR[27] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100865 /* round 22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800866 subL[29] ^= subL[1]; subR[29] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100867 /* round 24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800868 subL[31] ^= subL[1]; subR[31] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100869 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800870 subL[32] ^= subL[1]; subR[32] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100871
872 /* absorb kw4 to other subkeys */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800873 kw4l = subL[33]; kw4r = subR[33];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100874 /* round 23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800875 subL[30] ^= kw4l; subR[30] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100876 /* round 21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800877 subL[28] ^= kw4l; subR[28] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100878 /* round 19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800879 subL[26] ^= kw4l; subR[26] ^= kw4r;
880 kw4l ^= kw4r & ~subR[24];
881 dw = kw4l & subL[24],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800882 kw4r ^= ROL1(dw); /* modified for FL(kl5) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100883 /* round 17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800884 subL[22] ^= kw4l; subR[22] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100885 /* round 15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800886 subL[20] ^= kw4l; subR[20] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100887 /* round 13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800888 subL[18] ^= kw4l; subR[18] ^= kw4r;
889 kw4l ^= kw4r & ~subR[16];
890 dw = kw4l & subL[16],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800891 kw4r ^= ROL1(dw); /* modified for FL(kl3) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100892 /* round 11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800893 subL[14] ^= kw4l; subR[14] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100894 /* round 9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800895 subL[12] ^= kw4l; subR[12] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100896 /* round 7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800897 subL[10] ^= kw4l; subR[10] ^= kw4r;
898 kw4l ^= kw4r & ~subR[8];
899 dw = kw4l & subL[8],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800900 kw4r ^= ROL1(dw); /* modified for FL(kl1) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100901 /* round 5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800902 subL[6] ^= kw4l; subR[6] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100903 /* round 3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800904 subL[4] ^= kw4l; subR[4] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100905 /* round 1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800906 subL[2] ^= kw4l; subR[2] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100907 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800908 subL[0] ^= kw4l; subR[0] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100909
910 /* key XOR is end of F-function */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800911 SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
912 SUBKEY_R(0) = subR[0] ^ subR[2];
913 SUBKEY_L(2) = subL[3]; /* round 1 */
914 SUBKEY_R(2) = subR[3];
915 SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
916 SUBKEY_R(3) = subR[2] ^ subR[4];
917 SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
918 SUBKEY_R(4) = subR[3] ^ subR[5];
919 SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
920 SUBKEY_R(5) = subR[4] ^ subR[6];
921 SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
922 SUBKEY_R(6) = subR[5] ^ subR[7];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800923 tl = subL[10] ^ (subR[10] & ~subR[8]);
924 dw = tl & subL[8], /* FL(kl1) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800925 tr = subR[10] ^ ROL1(dw);
926 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
927 SUBKEY_R(7) = subR[6] ^ tr;
928 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
929 SUBKEY_R(8) = subR[8];
930 SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
931 SUBKEY_R(9) = subR[9];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800932 tl = subL[7] ^ (subR[7] & ~subR[9]);
933 dw = tl & subL[9], /* FLinv(kl2) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800934 tr = subR[7] ^ ROL1(dw);
935 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
936 SUBKEY_R(10) = tr ^ subR[11];
937 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
938 SUBKEY_R(11) = subR[10] ^ subR[12];
939 SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
940 SUBKEY_R(12) = subR[11] ^ subR[13];
941 SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
942 SUBKEY_R(13) = subR[12] ^ subR[14];
943 SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
944 SUBKEY_R(14) = subR[13] ^ subR[15];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800945 tl = subL[18] ^ (subR[18] & ~subR[16]);
946 dw = tl & subL[16], /* FL(kl3) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800947 tr = subR[18] ^ ROL1(dw);
948 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
949 SUBKEY_R(15) = subR[14] ^ tr;
950 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
951 SUBKEY_R(16) = subR[16];
952 SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
953 SUBKEY_R(17) = subR[17];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800954 tl = subL[15] ^ (subR[15] & ~subR[17]);
955 dw = tl & subL[17], /* FLinv(kl4) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800956 tr = subR[15] ^ ROL1(dw);
957 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
958 SUBKEY_R(18) = tr ^ subR[19];
959 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
960 SUBKEY_R(19) = subR[18] ^ subR[20];
961 SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
962 SUBKEY_R(20) = subR[19] ^ subR[21];
963 SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
964 SUBKEY_R(21) = subR[20] ^ subR[22];
965 SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
966 SUBKEY_R(22) = subR[21] ^ subR[23];
967 tl = subL[26] ^ (subR[26] & ~subR[24]);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800968 dw = tl & subL[24], /* FL(kl5) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800969 tr = subR[26] ^ ROL1(dw);
970 SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
971 SUBKEY_R(23) = subR[22] ^ tr;
972 SUBKEY_L(24) = subL[24]; /* FL(kl5) */
973 SUBKEY_R(24) = subR[24];
974 SUBKEY_L(25) = subL[25]; /* FLinv(kl6) */
975 SUBKEY_R(25) = subR[25];
976 tl = subL[23] ^ (subR[23] & ~subR[25]);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800977 dw = tl & subL[25], /* FLinv(kl6) */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800978 tr = subR[23] ^ ROL1(dw);
979 SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
980 SUBKEY_R(26) = tr ^ subR[27];
981 SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
982 SUBKEY_R(27) = subR[26] ^ subR[28];
983 SUBKEY_L(28) = subL[27] ^ subL[29]; /* round 21 */
984 SUBKEY_R(28) = subR[27] ^ subR[29];
985 SUBKEY_L(29) = subL[28] ^ subL[30]; /* round 22 */
986 SUBKEY_R(29) = subR[28] ^ subR[30];
987 SUBKEY_L(30) = subL[29] ^ subL[31]; /* round 23 */
988 SUBKEY_R(30) = subR[29] ^ subR[31];
989 SUBKEY_L(31) = subL[30]; /* round 24 */
990 SUBKEY_R(31) = subR[30];
991 SUBKEY_L(32) = subL[32] ^ subL[31]; /* kw3 */
992 SUBKEY_R(32) = subR[32] ^ subR[31];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100993
994 /* apply the inverse of the last half of P-function */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800995 dw = SUBKEY_L(2) ^ SUBKEY_R(2); dw = ROL8(dw);/* round 1 */
996 SUBKEY_R(2) = SUBKEY_L(2) ^ dw; SUBKEY_L(2) = dw;
997 dw = SUBKEY_L(3) ^ SUBKEY_R(3); dw = ROL8(dw);/* round 2 */
998 SUBKEY_R(3) = SUBKEY_L(3) ^ dw; SUBKEY_L(3) = dw;
999 dw = SUBKEY_L(4) ^ SUBKEY_R(4); dw = ROL8(dw);/* round 3 */
1000 SUBKEY_R(4) = SUBKEY_L(4) ^ dw; SUBKEY_L(4) = dw;
1001 dw = SUBKEY_L(5) ^ SUBKEY_R(5); dw = ROL8(dw);/* round 4 */
1002 SUBKEY_R(5) = SUBKEY_L(5) ^ dw; SUBKEY_L(5) = dw;
1003 dw = SUBKEY_L(6) ^ SUBKEY_R(6); dw = ROL8(dw);/* round 5 */
1004 SUBKEY_R(6) = SUBKEY_L(6) ^ dw; SUBKEY_L(6) = dw;
1005 dw = SUBKEY_L(7) ^ SUBKEY_R(7); dw = ROL8(dw);/* round 6 */
1006 SUBKEY_R(7) = SUBKEY_L(7) ^ dw; SUBKEY_L(7) = dw;
1007 dw = SUBKEY_L(10) ^ SUBKEY_R(10); dw = ROL8(dw);/* round 7 */
1008 SUBKEY_R(10) = SUBKEY_L(10) ^ dw; SUBKEY_L(10) = dw;
1009 dw = SUBKEY_L(11) ^ SUBKEY_R(11); dw = ROL8(dw);/* round 8 */
1010 SUBKEY_R(11) = SUBKEY_L(11) ^ dw; SUBKEY_L(11) = dw;
1011 dw = SUBKEY_L(12) ^ SUBKEY_R(12); dw = ROL8(dw);/* round 9 */
1012 SUBKEY_R(12) = SUBKEY_L(12) ^ dw; SUBKEY_L(12) = dw;
1013 dw = SUBKEY_L(13) ^ SUBKEY_R(13); dw = ROL8(dw);/* round 10 */
1014 SUBKEY_R(13) = SUBKEY_L(13) ^ dw; SUBKEY_L(13) = dw;
1015 dw = SUBKEY_L(14) ^ SUBKEY_R(14); dw = ROL8(dw);/* round 11 */
1016 SUBKEY_R(14) = SUBKEY_L(14) ^ dw; SUBKEY_L(14) = dw;
1017 dw = SUBKEY_L(15) ^ SUBKEY_R(15); dw = ROL8(dw);/* round 12 */
1018 SUBKEY_R(15) = SUBKEY_L(15) ^ dw; SUBKEY_L(15) = dw;
1019 dw = SUBKEY_L(18) ^ SUBKEY_R(18); dw = ROL8(dw);/* round 13 */
1020 SUBKEY_R(18) = SUBKEY_L(18) ^ dw; SUBKEY_L(18) = dw;
1021 dw = SUBKEY_L(19) ^ SUBKEY_R(19); dw = ROL8(dw);/* round 14 */
1022 SUBKEY_R(19) = SUBKEY_L(19) ^ dw; SUBKEY_L(19) = dw;
1023 dw = SUBKEY_L(20) ^ SUBKEY_R(20); dw = ROL8(dw);/* round 15 */
1024 SUBKEY_R(20) = SUBKEY_L(20) ^ dw; SUBKEY_L(20) = dw;
1025 dw = SUBKEY_L(21) ^ SUBKEY_R(21); dw = ROL8(dw);/* round 16 */
1026 SUBKEY_R(21) = SUBKEY_L(21) ^ dw; SUBKEY_L(21) = dw;
1027 dw = SUBKEY_L(22) ^ SUBKEY_R(22); dw = ROL8(dw);/* round 17 */
1028 SUBKEY_R(22) = SUBKEY_L(22) ^ dw; SUBKEY_L(22) = dw;
1029 dw = SUBKEY_L(23) ^ SUBKEY_R(23); dw = ROL8(dw);/* round 18 */
1030 SUBKEY_R(23) = SUBKEY_L(23) ^ dw; SUBKEY_L(23) = dw;
1031 dw = SUBKEY_L(26) ^ SUBKEY_R(26); dw = ROL8(dw);/* round 19 */
1032 SUBKEY_R(26) = SUBKEY_L(26) ^ dw; SUBKEY_L(26) = dw;
1033 dw = SUBKEY_L(27) ^ SUBKEY_R(27); dw = ROL8(dw);/* round 20 */
1034 SUBKEY_R(27) = SUBKEY_L(27) ^ dw; SUBKEY_L(27) = dw;
1035 dw = SUBKEY_L(28) ^ SUBKEY_R(28); dw = ROL8(dw);/* round 21 */
1036 SUBKEY_R(28) = SUBKEY_L(28) ^ dw; SUBKEY_L(28) = dw;
1037 dw = SUBKEY_L(29) ^ SUBKEY_R(29); dw = ROL8(dw);/* round 22 */
1038 SUBKEY_R(29) = SUBKEY_L(29) ^ dw; SUBKEY_L(29) = dw;
1039 dw = SUBKEY_L(30) ^ SUBKEY_R(30); dw = ROL8(dw);/* round 23 */
1040 SUBKEY_R(30) = SUBKEY_L(30) ^ dw; SUBKEY_L(30) = dw;
1041 dw = SUBKEY_L(31) ^ SUBKEY_R(31); dw = ROL8(dw);/* round 24 */
1042 SUBKEY_R(31) = SUBKEY_L(31) ^ dw; SUBKEY_L(31) = dw;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001043}
1044
1045static void camellia_setup192(const unsigned char *key, u32 *subkey)
1046{
1047 unsigned char kk[32];
1048 u32 krll, krlr, krrl,krrr;
1049
1050 memcpy(kk, key, 24);
Denys Vlasenko1721a812007-11-06 22:01:20 +08001051 memcpy((unsigned char *)&krll, key+16, 4);
1052 memcpy((unsigned char *)&krlr, key+20, 4);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001053 krrl = ~krll;
1054 krrr = ~krlr;
1055 memcpy(kk+24, (unsigned char *)&krrl, 4);
1056 memcpy(kk+28, (unsigned char *)&krrr, 4);
1057 camellia_setup256(kk, subkey);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001058}
1059
1060
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001061static void camellia_encrypt128(const u32 *subkey, u32 *io_text)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001062{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001063 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001064
1065 u32 io[4];
1066
Denys Vlasenko1721a812007-11-06 22:01:20 +08001067 /* pre whitening but absorb kw2 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001068 io[0] = io_text[0] ^ SUBKEY_L(0);
1069 io[1] = io_text[1] ^ SUBKEY_R(0);
1070 io[2] = io_text[2];
1071 io[3] = io_text[3];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001072
Denys Vlasenko1721a812007-11-06 22:01:20 +08001073 /* main iteration */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001074 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001075 SUBKEY_L(2),SUBKEY_R(2),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001076 io[2],io[3],il,ir,t0,t1);
1077 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001078 SUBKEY_L(3),SUBKEY_R(3),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001079 io[0],io[1],il,ir,t0,t1);
1080 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001081 SUBKEY_L(4),SUBKEY_R(4),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001082 io[2],io[3],il,ir,t0,t1);
1083 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001084 SUBKEY_L(5),SUBKEY_R(5),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001085 io[0],io[1],il,ir,t0,t1);
1086 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001087 SUBKEY_L(6),SUBKEY_R(6),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001088 io[2],io[3],il,ir,t0,t1);
1089 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001090 SUBKEY_L(7),SUBKEY_R(7),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001091 io[0],io[1],il,ir,t0,t1);
1092
1093 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001094 SUBKEY_L(8),SUBKEY_R(8),
1095 SUBKEY_L(9),SUBKEY_R(9),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001096 t0,t1,il,ir);
1097
1098 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001099 SUBKEY_L(10),SUBKEY_R(10),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001100 io[2],io[3],il,ir,t0,t1);
1101 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001102 SUBKEY_L(11),SUBKEY_R(11),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001103 io[0],io[1],il,ir,t0,t1);
1104 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001105 SUBKEY_L(12),SUBKEY_R(12),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001106 io[2],io[3],il,ir,t0,t1);
1107 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001108 SUBKEY_L(13),SUBKEY_R(13),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001109 io[0],io[1],il,ir,t0,t1);
1110 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001111 SUBKEY_L(14),SUBKEY_R(14),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001112 io[2],io[3],il,ir,t0,t1);
1113 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001114 SUBKEY_L(15),SUBKEY_R(15),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001115 io[0],io[1],il,ir,t0,t1);
1116
1117 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001118 SUBKEY_L(16),SUBKEY_R(16),
1119 SUBKEY_L(17),SUBKEY_R(17),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001120 t0,t1,il,ir);
1121
1122 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001123 SUBKEY_L(18),SUBKEY_R(18),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001124 io[2],io[3],il,ir,t0,t1);
1125 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001126 SUBKEY_L(19),SUBKEY_R(19),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001127 io[0],io[1],il,ir,t0,t1);
1128 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001129 SUBKEY_L(20),SUBKEY_R(20),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001130 io[2],io[3],il,ir,t0,t1);
1131 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001132 SUBKEY_L(21),SUBKEY_R(21),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001133 io[0],io[1],il,ir,t0,t1);
1134 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001135 SUBKEY_L(22),SUBKEY_R(22),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001136 io[2],io[3],il,ir,t0,t1);
1137 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001138 SUBKEY_L(23),SUBKEY_R(23),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001139 io[0],io[1],il,ir,t0,t1);
1140
1141 /* post whitening but kw4 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001142 io_text[0] = io[2] ^ SUBKEY_L(24);
1143 io_text[1] = io[3] ^ SUBKEY_R(24);
1144 io_text[2] = io[0];
1145 io_text[3] = io[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001146}
1147
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001148static void camellia_decrypt128(const u32 *subkey, u32 *io_text)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001149{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001150 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001151
1152 u32 io[4];
1153
Denys Vlasenko1721a812007-11-06 22:01:20 +08001154 /* pre whitening but absorb kw2 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001155 io[0] = io_text[0] ^ SUBKEY_L(24);
1156 io[1] = io_text[1] ^ SUBKEY_R(24);
1157 io[2] = io_text[2];
1158 io[3] = io_text[3];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001159
1160 /* main iteration */
1161 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001162 SUBKEY_L(23),SUBKEY_R(23),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001163 io[2],io[3],il,ir,t0,t1);
1164 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001165 SUBKEY_L(22),SUBKEY_R(22),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001166 io[0],io[1],il,ir,t0,t1);
1167 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001168 SUBKEY_L(21),SUBKEY_R(21),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001169 io[2],io[3],il,ir,t0,t1);
1170 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001171 SUBKEY_L(20),SUBKEY_R(20),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001172 io[0],io[1],il,ir,t0,t1);
1173 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001174 SUBKEY_L(19),SUBKEY_R(19),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001175 io[2],io[3],il,ir,t0,t1);
1176 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001177 SUBKEY_L(18),SUBKEY_R(18),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001178 io[0],io[1],il,ir,t0,t1);
1179
1180 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001181 SUBKEY_L(17),SUBKEY_R(17),
1182 SUBKEY_L(16),SUBKEY_R(16),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001183 t0,t1,il,ir);
1184
1185 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001186 SUBKEY_L(15),SUBKEY_R(15),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001187 io[2],io[3],il,ir,t0,t1);
1188 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001189 SUBKEY_L(14),SUBKEY_R(14),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001190 io[0],io[1],il,ir,t0,t1);
1191 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001192 SUBKEY_L(13),SUBKEY_R(13),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001193 io[2],io[3],il,ir,t0,t1);
1194 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001195 SUBKEY_L(12),SUBKEY_R(12),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001196 io[0],io[1],il,ir,t0,t1);
1197 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001198 SUBKEY_L(11),SUBKEY_R(11),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001199 io[2],io[3],il,ir,t0,t1);
1200 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001201 SUBKEY_L(10),SUBKEY_R(10),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001202 io[0],io[1],il,ir,t0,t1);
1203
1204 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001205 SUBKEY_L(9),SUBKEY_R(9),
1206 SUBKEY_L(8),SUBKEY_R(8),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001207 t0,t1,il,ir);
1208
1209 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001210 SUBKEY_L(7),SUBKEY_R(7),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001211 io[2],io[3],il,ir,t0,t1);
1212 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001213 SUBKEY_L(6),SUBKEY_R(6),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001214 io[0],io[1],il,ir,t0,t1);
1215 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001216 SUBKEY_L(5),SUBKEY_R(5),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001217 io[2],io[3],il,ir,t0,t1);
1218 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001219 SUBKEY_L(4),SUBKEY_R(4),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001220 io[0],io[1],il,ir,t0,t1);
1221 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001222 SUBKEY_L(3),SUBKEY_R(3),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001223 io[2],io[3],il,ir,t0,t1);
1224 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001225 SUBKEY_L(2),SUBKEY_R(2),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001226 io[0],io[1],il,ir,t0,t1);
1227
1228 /* post whitening but kw4 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001229 io_text[0] = io[2] ^ SUBKEY_L(0);
1230 io_text[1] = io[3] ^ SUBKEY_R(0);
1231 io_text[2] = io[0];
1232 io_text[3] = io[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001233}
1234
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001235static void camellia_encrypt256(const u32 *subkey, u32 *io_text)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001236{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001237 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001238
1239 u32 io[4];
1240
Denys Vlasenko1721a812007-11-06 22:01:20 +08001241 /* pre whitening but absorb kw2 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001242 io[0] = io_text[0] ^ SUBKEY_L(0);
1243 io[1] = io_text[1] ^ SUBKEY_R(0);
1244 io[2] = io_text[2];
1245 io[3] = io_text[3];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001246
1247 /* main iteration */
1248 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001249 SUBKEY_L(2),SUBKEY_R(2),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001250 io[2],io[3],il,ir,t0,t1);
1251 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001252 SUBKEY_L(3),SUBKEY_R(3),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001253 io[0],io[1],il,ir,t0,t1);
1254 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001255 SUBKEY_L(4),SUBKEY_R(4),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001256 io[2],io[3],il,ir,t0,t1);
1257 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001258 SUBKEY_L(5),SUBKEY_R(5),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001259 io[0],io[1],il,ir,t0,t1);
1260 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001261 SUBKEY_L(6),SUBKEY_R(6),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001262 io[2],io[3],il,ir,t0,t1);
1263 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001264 SUBKEY_L(7),SUBKEY_R(7),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001265 io[0],io[1],il,ir,t0,t1);
1266
1267 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001268 SUBKEY_L(8),SUBKEY_R(8),
1269 SUBKEY_L(9),SUBKEY_R(9),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001270 t0,t1,il,ir);
1271
1272 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001273 SUBKEY_L(10),SUBKEY_R(10),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001274 io[2],io[3],il,ir,t0,t1);
1275 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001276 SUBKEY_L(11),SUBKEY_R(11),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001277 io[0],io[1],il,ir,t0,t1);
1278 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001279 SUBKEY_L(12),SUBKEY_R(12),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001280 io[2],io[3],il,ir,t0,t1);
1281 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001282 SUBKEY_L(13),SUBKEY_R(13),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001283 io[0],io[1],il,ir,t0,t1);
1284 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001285 SUBKEY_L(14),SUBKEY_R(14),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001286 io[2],io[3],il,ir,t0,t1);
1287 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001288 SUBKEY_L(15),SUBKEY_R(15),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001289 io[0],io[1],il,ir,t0,t1);
1290
1291 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001292 SUBKEY_L(16),SUBKEY_R(16),
1293 SUBKEY_L(17),SUBKEY_R(17),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001294 t0,t1,il,ir);
1295
1296 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001297 SUBKEY_L(18),SUBKEY_R(18),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001298 io[2],io[3],il,ir,t0,t1);
1299 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001300 SUBKEY_L(19),SUBKEY_R(19),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001301 io[0],io[1],il,ir,t0,t1);
1302 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001303 SUBKEY_L(20),SUBKEY_R(20),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001304 io[2],io[3],il,ir,t0,t1);
1305 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001306 SUBKEY_L(21),SUBKEY_R(21),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001307 io[0],io[1],il,ir,t0,t1);
1308 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001309 SUBKEY_L(22),SUBKEY_R(22),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001310 io[2],io[3],il,ir,t0,t1);
1311 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001312 SUBKEY_L(23),SUBKEY_R(23),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001313 io[0],io[1],il,ir,t0,t1);
1314
1315 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001316 SUBKEY_L(24),SUBKEY_R(24),
1317 SUBKEY_L(25),SUBKEY_R(25),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001318 t0,t1,il,ir);
1319
1320 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001321 SUBKEY_L(26),SUBKEY_R(26),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001322 io[2],io[3],il,ir,t0,t1);
1323 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001324 SUBKEY_L(27),SUBKEY_R(27),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001325 io[0],io[1],il,ir,t0,t1);
1326 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001327 SUBKEY_L(28),SUBKEY_R(28),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001328 io[2],io[3],il,ir,t0,t1);
1329 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001330 SUBKEY_L(29),SUBKEY_R(29),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001331 io[0],io[1],il,ir,t0,t1);
1332 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001333 SUBKEY_L(30),SUBKEY_R(30),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001334 io[2],io[3],il,ir,t0,t1);
1335 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001336 SUBKEY_L(31),SUBKEY_R(31),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001337 io[0],io[1],il,ir,t0,t1);
1338
1339 /* post whitening but kw4 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001340 io_text[0] = io[2] ^ SUBKEY_L(32);
1341 io_text[1] = io[3] ^ SUBKEY_R(32);
1342 io_text[2] = io[0];
1343 io_text[3] = io[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001344}
1345
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001346static void camellia_decrypt256(const u32 *subkey, u32 *io_text)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001347{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001348 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001349
1350 u32 io[4];
1351
Denys Vlasenko1721a812007-11-06 22:01:20 +08001352 /* pre whitening but absorb kw2 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001353 io[0] = io_text[0] ^ SUBKEY_L(32);
1354 io[1] = io_text[1] ^ SUBKEY_R(32);
1355 io[2] = io_text[2];
1356 io[3] = io_text[3];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001357
1358 /* main iteration */
1359 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001360 SUBKEY_L(31),SUBKEY_R(31),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001361 io[2],io[3],il,ir,t0,t1);
1362 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001363 SUBKEY_L(30),SUBKEY_R(30),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001364 io[0],io[1],il,ir,t0,t1);
1365 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001366 SUBKEY_L(29),SUBKEY_R(29),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001367 io[2],io[3],il,ir,t0,t1);
1368 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001369 SUBKEY_L(28),SUBKEY_R(28),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001370 io[0],io[1],il,ir,t0,t1);
1371 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001372 SUBKEY_L(27),SUBKEY_R(27),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001373 io[2],io[3],il,ir,t0,t1);
1374 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001375 SUBKEY_L(26),SUBKEY_R(26),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001376 io[0],io[1],il,ir,t0,t1);
1377
1378 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001379 SUBKEY_L(25),SUBKEY_R(25),
1380 SUBKEY_L(24),SUBKEY_R(24),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001381 t0,t1,il,ir);
1382
1383 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001384 SUBKEY_L(23),SUBKEY_R(23),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001385 io[2],io[3],il,ir,t0,t1);
1386 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001387 SUBKEY_L(22),SUBKEY_R(22),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001388 io[0],io[1],il,ir,t0,t1);
1389 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001390 SUBKEY_L(21),SUBKEY_R(21),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001391 io[2],io[3],il,ir,t0,t1);
1392 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001393 SUBKEY_L(20),SUBKEY_R(20),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001394 io[0],io[1],il,ir,t0,t1);
1395 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001396 SUBKEY_L(19),SUBKEY_R(19),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001397 io[2],io[3],il,ir,t0,t1);
1398 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001399 SUBKEY_L(18),SUBKEY_R(18),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001400 io[0],io[1],il,ir,t0,t1);
1401
1402 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001403 SUBKEY_L(17),SUBKEY_R(17),
1404 SUBKEY_L(16),SUBKEY_R(16),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001405 t0,t1,il,ir);
1406
1407 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001408 SUBKEY_L(15),SUBKEY_R(15),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001409 io[2],io[3],il,ir,t0,t1);
1410 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001411 SUBKEY_L(14),SUBKEY_R(14),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001412 io[0],io[1],il,ir,t0,t1);
1413 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001414 SUBKEY_L(13),SUBKEY_R(13),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001415 io[2],io[3],il,ir,t0,t1);
1416 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001417 SUBKEY_L(12),SUBKEY_R(12),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001418 io[0],io[1],il,ir,t0,t1);
1419 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001420 SUBKEY_L(11),SUBKEY_R(11),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001421 io[2],io[3],il,ir,t0,t1);
1422 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001423 SUBKEY_L(10),SUBKEY_R(10),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001424 io[0],io[1],il,ir,t0,t1);
1425
1426 CAMELLIA_FLS(io[0],io[1],io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001427 SUBKEY_L(9),SUBKEY_R(9),
1428 SUBKEY_L(8),SUBKEY_R(8),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001429 t0,t1,il,ir);
1430
1431 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001432 SUBKEY_L(7),SUBKEY_R(7),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001433 io[2],io[3],il,ir,t0,t1);
1434 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001435 SUBKEY_L(6),SUBKEY_R(6),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001436 io[0],io[1],il,ir,t0,t1);
1437 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001438 SUBKEY_L(5),SUBKEY_R(5),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001439 io[2],io[3],il,ir,t0,t1);
1440 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001441 SUBKEY_L(4),SUBKEY_R(4),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001442 io[0],io[1],il,ir,t0,t1);
1443 CAMELLIA_ROUNDSM(io[0],io[1],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001444 SUBKEY_L(3),SUBKEY_R(3),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001445 io[2],io[3],il,ir,t0,t1);
1446 CAMELLIA_ROUNDSM(io[2],io[3],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001447 SUBKEY_L(2),SUBKEY_R(2),
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001448 io[0],io[1],il,ir,t0,t1);
1449
1450 /* post whitening but kw4 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001451 io_text[0] = io[2] ^ SUBKEY_L(0);
1452 io_text[1] = io[3] ^ SUBKEY_R(0);
1453 io_text[2] = io[0];
1454 io_text[3] = io[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001455}
1456
1457
Denys Vlasenko1721a812007-11-06 22:01:20 +08001458struct camellia_ctx {
1459 int key_length;
1460 u32 key_table[CAMELLIA_TABLE_BYTE_LEN / 4];
1461};
1462
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001463static int
1464camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
1465 unsigned int key_len)
1466{
1467 struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1468 const unsigned char *key = (const unsigned char *)in_key;
1469 u32 *flags = &tfm->crt_flags;
1470
1471 if (key_len != 16 && key_len != 24 && key_len != 32) {
1472 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
1473 return -EINVAL;
1474 }
1475
1476 cctx->key_length = key_len;
1477
Denys Vlasenko1721a812007-11-06 22:01:20 +08001478 switch (key_len) {
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001479 case 16:
1480 camellia_setup128(key, cctx->key_table);
1481 break;
1482 case 24:
1483 camellia_setup192(key, cctx->key_table);
1484 break;
1485 case 32:
1486 camellia_setup256(key, cctx->key_table);
1487 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001488 }
1489
1490 return 0;
1491}
1492
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001493static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1494{
1495 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1496 const __be32 *src = (const __be32 *)in;
1497 __be32 *dst = (__be32 *)out;
1498
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001499 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001500
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001501 tmp[0] = be32_to_cpu(src[0]);
1502 tmp[1] = be32_to_cpu(src[1]);
1503 tmp[2] = be32_to_cpu(src[2]);
1504 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001505
1506 switch (cctx->key_length) {
1507 case 16:
1508 camellia_encrypt128(cctx->key_table, tmp);
1509 break;
1510 case 24:
1511 /* fall through */
1512 case 32:
1513 camellia_encrypt256(cctx->key_table, tmp);
1514 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001515 }
1516
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001517 dst[0] = cpu_to_be32(tmp[0]);
1518 dst[1] = cpu_to_be32(tmp[1]);
1519 dst[2] = cpu_to_be32(tmp[2]);
1520 dst[3] = cpu_to_be32(tmp[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001521}
1522
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001523static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1524{
1525 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1526 const __be32 *src = (const __be32 *)in;
1527 __be32 *dst = (__be32 *)out;
1528
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001529 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001530
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001531 tmp[0] = be32_to_cpu(src[0]);
1532 tmp[1] = be32_to_cpu(src[1]);
1533 tmp[2] = be32_to_cpu(src[2]);
1534 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001535
1536 switch (cctx->key_length) {
1537 case 16:
1538 camellia_decrypt128(cctx->key_table, tmp);
1539 break;
1540 case 24:
1541 /* fall through */
1542 case 32:
1543 camellia_decrypt256(cctx->key_table, tmp);
1544 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001545 }
1546
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001547 dst[0] = cpu_to_be32(tmp[0]);
1548 dst[1] = cpu_to_be32(tmp[1]);
1549 dst[2] = cpu_to_be32(tmp[2]);
1550 dst[3] = cpu_to_be32(tmp[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001551}
1552
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001553static struct crypto_alg camellia_alg = {
1554 .cra_name = "camellia",
1555 .cra_driver_name = "camellia-generic",
1556 .cra_priority = 100,
1557 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
1558 .cra_blocksize = CAMELLIA_BLOCK_SIZE,
1559 .cra_ctxsize = sizeof(struct camellia_ctx),
1560 .cra_alignmask = 3,
1561 .cra_module = THIS_MODULE,
1562 .cra_list = LIST_HEAD_INIT(camellia_alg.cra_list),
1563 .cra_u = {
1564 .cipher = {
1565 .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
1566 .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
1567 .cia_setkey = camellia_set_key,
1568 .cia_encrypt = camellia_encrypt,
1569 .cia_decrypt = camellia_decrypt
1570 }
1571 }
1572};
1573
1574static int __init camellia_init(void)
1575{
1576 return crypto_register_alg(&camellia_alg);
1577}
1578
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001579static void __exit camellia_fini(void)
1580{
1581 crypto_unregister_alg(&camellia_alg);
1582}
1583
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001584module_init(camellia_init);
1585module_exit(camellia_fini);
1586
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001587MODULE_DESCRIPTION("Camellia Cipher Algorithm");
1588MODULE_LICENSE("GPL");