blob: 86af42e92916d726281de005977cb59134b66e83 [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 Vlasenkodedcf8b2007-11-23 21:14:24 +0800393static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800394{
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800395 u32 dw, tl, tr;
396 int i;
397
398 /* key XOR is end of F-function */
399 SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
400 SUBKEY_R(0) = subR[0] ^ subR[2];
401 SUBKEY_L(2) = subL[3]; /* round 1 */
402 SUBKEY_R(2) = subR[3];
403 SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
404 SUBKEY_R(3) = subR[2] ^ subR[4];
405 SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
406 SUBKEY_R(4) = subR[3] ^ subR[5];
407 SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
408 SUBKEY_R(5) = subR[4] ^ subR[6];
409 SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
410 SUBKEY_R(6) = subR[5] ^ subR[7];
411 tl = subL[10] ^ (subR[10] & ~subR[8]);
412 dw = tl & subL[8], /* FL(kl1) */
413 tr = subR[10] ^ ROL1(dw);
414 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
415 SUBKEY_R(7) = subR[6] ^ tr;
416 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
417 SUBKEY_R(8) = subR[8];
418 SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
419 SUBKEY_R(9) = subR[9];
420 tl = subL[7] ^ (subR[7] & ~subR[9]);
421 dw = tl & subL[9], /* FLinv(kl2) */
422 tr = subR[7] ^ ROL1(dw);
423 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
424 SUBKEY_R(10) = tr ^ subR[11];
425 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
426 SUBKEY_R(11) = subR[10] ^ subR[12];
427 SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
428 SUBKEY_R(12) = subR[11] ^ subR[13];
429 SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
430 SUBKEY_R(13) = subR[12] ^ subR[14];
431 SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
432 SUBKEY_R(14) = subR[13] ^ subR[15];
433 tl = subL[18] ^ (subR[18] & ~subR[16]);
434 dw = tl & subL[16], /* FL(kl3) */
435 tr = subR[18] ^ ROL1(dw);
436 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
437 SUBKEY_R(15) = subR[14] ^ tr;
438 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
439 SUBKEY_R(16) = subR[16];
440 SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
441 SUBKEY_R(17) = subR[17];
442 tl = subL[15] ^ (subR[15] & ~subR[17]);
443 dw = tl & subL[17], /* FLinv(kl4) */
444 tr = subR[15] ^ ROL1(dw);
445 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
446 SUBKEY_R(18) = tr ^ subR[19];
447 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
448 SUBKEY_R(19) = subR[18] ^ subR[20];
449 SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
450 SUBKEY_R(20) = subR[19] ^ subR[21];
451 SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
452 SUBKEY_R(21) = subR[20] ^ subR[22];
453 SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
454 SUBKEY_R(22) = subR[21] ^ subR[23];
455 if (max == 24) {
456 SUBKEY_L(23) = subL[22]; /* round 18 */
457 SUBKEY_R(23) = subR[22];
458 SUBKEY_L(24) = subL[24] ^ subL[23]; /* kw3 */
459 SUBKEY_R(24) = subR[24] ^ subR[23];
460 } else {
461 tl = subL[26] ^ (subR[26] & ~subR[24]);
462 dw = tl & subL[24], /* FL(kl5) */
463 tr = subR[26] ^ ROL1(dw);
464 SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
465 SUBKEY_R(23) = subR[22] ^ tr;
466 SUBKEY_L(24) = subL[24]; /* FL(kl5) */
467 SUBKEY_R(24) = subR[24];
468 SUBKEY_L(25) = subL[25]; /* FLinv(kl6) */
469 SUBKEY_R(25) = subR[25];
470 tl = subL[23] ^ (subR[23] & ~subR[25]);
471 dw = tl & subL[25], /* FLinv(kl6) */
472 tr = subR[23] ^ ROL1(dw);
473 SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
474 SUBKEY_R(26) = tr ^ subR[27];
475 SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
476 SUBKEY_R(27) = subR[26] ^ subR[28];
477 SUBKEY_L(28) = subL[27] ^ subL[29]; /* round 21 */
478 SUBKEY_R(28) = subR[27] ^ subR[29];
479 SUBKEY_L(29) = subL[28] ^ subL[30]; /* round 22 */
480 SUBKEY_R(29) = subR[28] ^ subR[30];
481 SUBKEY_L(30) = subL[29] ^ subL[31]; /* round 23 */
482 SUBKEY_R(30) = subR[29] ^ subR[31];
483 SUBKEY_L(31) = subL[30]; /* round 24 */
484 SUBKEY_R(31) = subR[30];
485 SUBKEY_L(32) = subL[32] ^ subL[31]; /* kw3 */
486 SUBKEY_R(32) = subR[32] ^ subR[31];
487 }
488
489 /* apply the inverse of the last half of P-function */
490 i = 2;
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800491 do {
492 dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = ROL8(dw);/* round 1 */
493 SUBKEY_R(i + 0) = SUBKEY_L(i + 0) ^ dw; SUBKEY_L(i + 0) = dw;
494 dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = ROL8(dw);/* round 2 */
495 SUBKEY_R(i + 1) = SUBKEY_L(i + 1) ^ dw; SUBKEY_L(i + 1) = dw;
496 dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = ROL8(dw);/* round 3 */
497 SUBKEY_R(i + 2) = SUBKEY_L(i + 2) ^ dw; SUBKEY_L(i + 2) = dw;
498 dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = ROL8(dw);/* round 4 */
499 SUBKEY_R(i + 3) = SUBKEY_L(i + 3) ^ dw; SUBKEY_L(i + 3) = dw;
500 dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = ROL8(dw);/* round 5 */
501 SUBKEY_R(i + 4) = SUBKEY_L(i + 4) ^ dw; SUBKEY_L(i + 4) = dw;
502 dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = ROL8(dw);/* round 6 */
503 SUBKEY_R(i + 5) = SUBKEY_L(i + 5) ^ dw; SUBKEY_L(i + 5) = dw;
504 i += 8;
505 } while (i < max);
506}
507
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100508static void camellia_setup128(const unsigned char *key, u32 *subkey)
509{
510 u32 kll, klr, krl, krr;
511 u32 il, ir, t0, t1, w0, w1;
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800512 u32 kw4l, kw4r, dw;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100513 u32 subL[26];
514 u32 subR[26];
515
516 /**
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800517 * k == kll || klr || krl || krr (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100518 */
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800519 GETU32(kll, key );
520 GETU32(klr, key + 4);
521 GETU32(krl, key + 8);
522 GETU32(krr, key + 12);
523
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800524 /* generate KL dependent subkeys */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100525 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800526 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100527 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800528 subL[1] = krl; subR[1] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100529 /* rotation left shift 15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800530 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100531 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800532 subL[4] = kll; subR[4] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100533 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800534 subL[5] = krl; subR[5] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100535 /* rotation left shift 15+30bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800536 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100537 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800538 subL[10] = kll; subR[10] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100539 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800540 subL[11] = krl; subR[11] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100541 /* rotation left shift 15+30+15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800542 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100543 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800544 subL[13] = krl; subR[13] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100545 /* rotation left shift 15+30+15+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800546 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100547 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800548 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100549 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800550 subL[17] = krl; subR[17] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100551 /* rotation left shift 15+30+15+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800552 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100553 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800554 subL[18] = kll; subR[18] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100555 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800556 subL[19] = krl; subR[19] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100557 /* rotation left shift 15+30+15+17+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800558 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100559 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800560 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100561 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800562 subL[23] = krl; subR[23] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100563
564 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800565 kll = subL[0]; klr = subR[0];
566 krl = subL[1]; krr = subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100567 CAMELLIA_F(kll, klr,
568 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
569 w0, w1, il, ir, t0, t1);
570 krl ^= w0; krr ^= w1;
571 CAMELLIA_F(krl, krr,
572 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
573 kll, klr, il, ir, t0, t1);
574 /* current status == (kll, klr, w0, w1) */
575 CAMELLIA_F(kll, klr,
576 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
577 krl, krr, il, ir, t0, t1);
578 krl ^= w0; krr ^= w1;
579 CAMELLIA_F(krl, krr,
580 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
581 w0, w1, il, ir, t0, t1);
582 kll ^= w0; klr ^= w1;
583
584 /* generate KA dependent subkeys */
585 /* k1, k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800586 subL[2] = kll; subR[2] = klr;
587 subL[3] = krl; subR[3] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800588 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100589 /* k5,k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800590 subL[6] = kll; subR[6] = klr;
591 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800592 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100593 /* kl1, kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800594 subL[8] = kll; subR[8] = klr;
595 subL[9] = krl; subR[9] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800596 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100597 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800598 subL[12] = kll; subR[12] = klr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800599 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100600 /* k11, k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800601 subL[14] = kll; subR[14] = klr;
602 subL[15] = krl; subR[15] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800603 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100604 /* k15, k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800605 subL[20] = kll; subR[20] = klr;
606 subL[21] = krl; subR[21] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800607 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100608 /* kw3, kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800609 subL[24] = kll; subR[24] = klr;
610 subL[25] = krl; subR[25] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100611
612 /* absorb kw2 to other subkeys */
613 /* round 2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800614 subL[3] ^= subL[1]; subR[3] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100615 /* round 4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800616 subL[5] ^= subL[1]; subR[5] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100617 /* round 6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800618 subL[7] ^= subL[1]; subR[7] ^= subR[1];
619 subL[1] ^= subR[1] & ~subR[9];
620 dw = subL[1] & subL[9],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800621 subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100622 /* round 8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800623 subL[11] ^= subL[1]; subR[11] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100624 /* round 10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800625 subL[13] ^= subL[1]; subR[13] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100626 /* round 12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800627 subL[15] ^= subL[1]; subR[15] ^= subR[1];
628 subL[1] ^= subR[1] & ~subR[17];
629 dw = subL[1] & subL[17],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800630 subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100631 /* round 14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800632 subL[19] ^= subL[1]; subR[19] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100633 /* round 16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800634 subL[21] ^= subL[1]; subR[21] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100635 /* round 18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800636 subL[23] ^= subL[1]; subR[23] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100637 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800638 subL[24] ^= subL[1]; subR[24] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100639
640 /* absorb kw4 to other subkeys */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800641 kw4l = subL[25]; kw4r = subR[25];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100642 /* round 17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800643 subL[22] ^= kw4l; subR[22] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100644 /* round 15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800645 subL[20] ^= kw4l; subR[20] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100646 /* round 13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800647 subL[18] ^= kw4l; subR[18] ^= kw4r;
648 kw4l ^= kw4r & ~subR[16];
649 dw = kw4l & subL[16],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800650 kw4r ^= ROL1(dw); /* modified for FL(kl3) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100651 /* round 11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800652 subL[14] ^= kw4l; subR[14] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100653 /* round 9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800654 subL[12] ^= kw4l; subR[12] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100655 /* round 7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800656 subL[10] ^= kw4l; subR[10] ^= kw4r;
657 kw4l ^= kw4r & ~subR[8];
658 dw = kw4l & subL[8],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800659 kw4r ^= ROL1(dw); /* modified for FL(kl1) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100660 /* round 5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800661 subL[6] ^= kw4l; subR[6] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100662 /* round 3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800663 subL[4] ^= kw4l; subR[4] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100664 /* round 1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800665 subL[2] ^= kw4l; subR[2] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100666 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800667 subL[0] ^= kw4l; subR[0] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100668
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800669 camellia_setup_tail(subkey, subL, subR, 24);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100670}
671
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100672static void camellia_setup256(const unsigned char *key, u32 *subkey)
673{
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800674 u32 kll, klr, krl, krr; /* left half of key */
675 u32 krll, krlr, krrl, krrr; /* right half of key */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100676 u32 il, ir, t0, t1, w0, w1; /* temporary variables */
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800677 u32 kw4l, kw4r, dw;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100678 u32 subL[34];
679 u32 subR[34];
680
681 /**
682 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800683 * (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100684 */
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800685 GETU32(kll, key );
686 GETU32(klr, key + 4);
687 GETU32(krl, key + 8);
688 GETU32(krr, key + 12);
689 GETU32(krll, key + 16);
690 GETU32(krlr, key + 20);
691 GETU32(krrl, key + 24);
692 GETU32(krrr, key + 28);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100693
694 /* generate KL dependent subkeys */
695 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800696 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100697 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800698 subL[1] = krl; subR[1] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800699 ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100700 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800701 subL[12] = kll; subR[12] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100702 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800703 subL[13] = krl; subR[13] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800704 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100705 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800706 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100707 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800708 subL[17] = krl; subR[17] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800709 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100710 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800711 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100712 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800713 subL[23] = krl; subR[23] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800714 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100715 /* k23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800716 subL[30] = kll; subR[30] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100717 /* k24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800718 subL[31] = krl; subR[31] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100719
720 /* generate KR dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800721 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100722 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800723 subL[4] = krll; subR[4] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100724 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800725 subL[5] = krrl; subR[5] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800726 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100727 /* kl1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800728 subL[8] = krll; subR[8] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100729 /* kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800730 subL[9] = krrl; subR[9] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800731 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100732 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800733 subL[18] = krll; subR[18] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100734 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800735 subL[19] = krrl; subR[19] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800736 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100737 /* k19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800738 subL[26] = krll; subR[26] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100739 /* k20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800740 subL[27] = krrl; subR[27] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800741 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100742
743 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800744 kll = subL[0] ^ krll; klr = subR[0] ^ krlr;
745 krl = subL[1] ^ krrl; krr = subR[1] ^ krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100746 CAMELLIA_F(kll, klr,
747 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
748 w0, w1, il, ir, t0, t1);
749 krl ^= w0; krr ^= w1;
750 CAMELLIA_F(krl, krr,
751 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
752 kll, klr, il, ir, t0, t1);
753 kll ^= krll; klr ^= krlr;
754 CAMELLIA_F(kll, klr,
755 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
756 krl, krr, il, ir, t0, t1);
757 krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
758 CAMELLIA_F(krl, krr,
759 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
760 w0, w1, il, ir, t0, t1);
761 kll ^= w0; klr ^= w1;
762
763 /* generate KB */
764 krll ^= kll; krlr ^= klr;
765 krrl ^= krl; krrr ^= krr;
766 CAMELLIA_F(krll, krlr,
767 CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
768 w0, w1, il, ir, t0, t1);
769 krrl ^= w0; krrr ^= w1;
770 CAMELLIA_F(krrl, krrr,
771 CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
772 w0, w1, il, ir, t0, t1);
773 krll ^= w0; krlr ^= w1;
774
775 /* generate KA dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800776 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100777 /* k5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800778 subL[6] = kll; subR[6] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100779 /* k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800780 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800781 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100782 /* k11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800783 subL[14] = kll; subR[14] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100784 /* k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800785 subL[15] = krl; subR[15] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100786 /* rotation left shift 32bit */
787 /* kl5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800788 subL[24] = klr; subR[24] = krl;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100789 /* kl6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800790 subL[25] = krr; subR[25] = kll;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100791 /* rotation left shift 49 from k11,k12 -> k21,k22 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800792 ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100793 /* k21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800794 subL[28] = kll; subR[28] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100795 /* k22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800796 subL[29] = krl; subR[29] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100797
798 /* generate KB dependent subkeys */
799 /* k1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800800 subL[2] = krll; subR[2] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100801 /* k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800802 subL[3] = krrl; subR[3] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800803 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100804 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800805 subL[10] = krll; subR[10] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100806 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800807 subL[11] = krrl; subR[11] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800808 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100809 /* k15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800810 subL[20] = krll; subR[20] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100811 /* k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800812 subL[21] = krrl; subR[21] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800813 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100814 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800815 subL[32] = krll; subR[32] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100816 /* kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800817 subL[33] = krrl; subR[33] = krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100818
819 /* absorb kw2 to other subkeys */
820 /* round 2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800821 subL[3] ^= subL[1]; subR[3] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100822 /* round 4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800823 subL[5] ^= subL[1]; subR[5] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100824 /* round 6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800825 subL[7] ^= subL[1]; subR[7] ^= subR[1];
826 subL[1] ^= subR[1] & ~subR[9];
827 dw = subL[1] & subL[9],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800828 subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100829 /* round 8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800830 subL[11] ^= subL[1]; subR[11] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100831 /* round 10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800832 subL[13] ^= subL[1]; subR[13] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100833 /* round 12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800834 subL[15] ^= subL[1]; subR[15] ^= subR[1];
835 subL[1] ^= subR[1] & ~subR[17];
836 dw = subL[1] & subL[17],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800837 subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100838 /* round 14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800839 subL[19] ^= subL[1]; subR[19] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100840 /* round 16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800841 subL[21] ^= subL[1]; subR[21] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100842 /* round 18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800843 subL[23] ^= subL[1]; subR[23] ^= subR[1];
844 subL[1] ^= subR[1] & ~subR[25];
845 dw = subL[1] & subL[25],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800846 subR[1] ^= ROL1(dw); /* modified for FLinv(kl6) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100847 /* round 20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800848 subL[27] ^= subL[1]; subR[27] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100849 /* round 22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800850 subL[29] ^= subL[1]; subR[29] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100851 /* round 24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800852 subL[31] ^= subL[1]; subR[31] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100853 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800854 subL[32] ^= subL[1]; subR[32] ^= subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100855
856 /* absorb kw4 to other subkeys */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800857 kw4l = subL[33]; kw4r = subR[33];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100858 /* round 23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800859 subL[30] ^= kw4l; subR[30] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100860 /* round 21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800861 subL[28] ^= kw4l; subR[28] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100862 /* round 19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800863 subL[26] ^= kw4l; subR[26] ^= kw4r;
864 kw4l ^= kw4r & ~subR[24];
865 dw = kw4l & subL[24],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800866 kw4r ^= ROL1(dw); /* modified for FL(kl5) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100867 /* round 17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800868 subL[22] ^= kw4l; subR[22] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100869 /* round 15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800870 subL[20] ^= kw4l; subR[20] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100871 /* round 13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800872 subL[18] ^= kw4l; subR[18] ^= kw4r;
873 kw4l ^= kw4r & ~subR[16];
874 dw = kw4l & subL[16],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800875 kw4r ^= ROL1(dw); /* modified for FL(kl3) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100876 /* round 11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800877 subL[14] ^= kw4l; subR[14] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100878 /* round 9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800879 subL[12] ^= kw4l; subR[12] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100880 /* round 7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800881 subL[10] ^= kw4l; subR[10] ^= kw4r;
882 kw4l ^= kw4r & ~subR[8];
883 dw = kw4l & subL[8],
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800884 kw4r ^= ROL1(dw); /* modified for FL(kl1) */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100885 /* round 5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800886 subL[6] ^= kw4l; subR[6] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100887 /* round 3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800888 subL[4] ^= kw4l; subR[4] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100889 /* round 1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800890 subL[2] ^= kw4l; subR[2] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100891 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800892 subL[0] ^= kw4l; subR[0] ^= kw4r;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100893
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800894 camellia_setup_tail(subkey, subL, subR, 32);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100895}
896
897static void camellia_setup192(const unsigned char *key, u32 *subkey)
898{
899 unsigned char kk[32];
900 u32 krll, krlr, krrl,krrr;
901
902 memcpy(kk, key, 24);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800903 memcpy((unsigned char *)&krll, key+16, 4);
904 memcpy((unsigned char *)&krlr, key+20, 4);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100905 krrl = ~krll;
906 krrr = ~krlr;
907 memcpy(kk+24, (unsigned char *)&krrl, 4);
908 memcpy(kk+28, (unsigned char *)&krrr, 4);
909 camellia_setup256(kk, subkey);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100910}
911
912
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800913/*
914 * Encrypt/decrypt
915 */
916#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
917 do { \
918 t0 = kll; \
919 t2 = krr; \
920 t0 &= ll; \
921 t2 |= rr; \
922 rl ^= t2; \
923 lr ^= ROL1(t0); \
924 t3 = krl; \
925 t1 = klr; \
926 t3 &= rl; \
927 t1 |= lr; \
928 ll ^= t1; \
929 rr ^= ROL1(t3); \
930 } while(0)
931
932#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) \
933 do { \
934 ir = camellia_sp1110[(u8)xr]; \
935 il = camellia_sp1110[ (xl >> 24)]; \
936 ir ^= camellia_sp0222[ (xr >> 24)]; \
937 il ^= camellia_sp0222[(u8)(xl >> 16)]; \
938 ir ^= camellia_sp3033[(u8)(xr >> 16)]; \
939 il ^= camellia_sp3033[(u8)(xl >> 8)]; \
940 ir ^= camellia_sp4404[(u8)(xr >> 8)]; \
941 il ^= camellia_sp4404[(u8)xl]; \
942 il ^= kl; \
943 ir ^= il ^ kr; \
944 yl ^= ir; \
945 yr ^= ROR8(il) ^ ir; \
946 } while(0)
947
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800948/* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
949static void camellia_do_encrypt(const u32 *subkey, u32 *io, unsigned max)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100950{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800951 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100952
Denys Vlasenko1721a812007-11-06 22:01:20 +0800953 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800954 io[0] ^= SUBKEY_L(0);
955 io[1] ^= SUBKEY_R(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100956
Denys Vlasenko1721a812007-11-06 22:01:20 +0800957 /* main iteration */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800958#define ROUNDS(i) do { \
959 CAMELLIA_ROUNDSM(io[0],io[1], \
960 SUBKEY_L(i + 2),SUBKEY_R(i + 2), \
961 io[2],io[3],il,ir); \
962 CAMELLIA_ROUNDSM(io[2],io[3], \
963 SUBKEY_L(i + 3),SUBKEY_R(i + 3), \
964 io[0],io[1],il,ir); \
965 CAMELLIA_ROUNDSM(io[0],io[1], \
966 SUBKEY_L(i + 4),SUBKEY_R(i + 4), \
967 io[2],io[3],il,ir); \
968 CAMELLIA_ROUNDSM(io[2],io[3], \
969 SUBKEY_L(i + 5),SUBKEY_R(i + 5), \
970 io[0],io[1],il,ir); \
971 CAMELLIA_ROUNDSM(io[0],io[1], \
972 SUBKEY_L(i + 6),SUBKEY_R(i + 6), \
973 io[2],io[3],il,ir); \
974 CAMELLIA_ROUNDSM(io[2],io[3], \
975 SUBKEY_L(i + 7),SUBKEY_R(i + 7), \
976 io[0],io[1],il,ir); \
977} while (0)
978#define FLS(i) do { \
979 CAMELLIA_FLS(io[0],io[1],io[2],io[3], \
980 SUBKEY_L(i + 0),SUBKEY_R(i + 0), \
981 SUBKEY_L(i + 1),SUBKEY_R(i + 1), \
982 t0,t1,il,ir); \
983} while (0)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100984
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800985 ROUNDS(0);
986 FLS(8);
987 ROUNDS(8);
988 FLS(16);
989 ROUNDS(16);
990 if (max == 32) {
991 FLS(24);
992 ROUNDS(24);
993 }
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100994
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800995#undef ROUNDS
996#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100997
998 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800999 io[2] ^= SUBKEY_L(max);
1000 io[3] ^= SUBKEY_R(max);
1001 /* NB: io[0],[1] should be swapped with [2],[3] by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001002}
1003
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001004static void camellia_do_decrypt(const u32 *subkey, u32 *io, unsigned i)
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
Denys Vlasenko1721a812007-11-06 22:01:20 +08001008 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001009 io[0] ^= SUBKEY_L(i);
1010 io[1] ^= SUBKEY_R(i);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001011
1012 /* main iteration */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001013#define ROUNDS(i) do { \
1014 CAMELLIA_ROUNDSM(io[0],io[1], \
1015 SUBKEY_L(i + 7),SUBKEY_R(i + 7), \
1016 io[2],io[3],il,ir); \
1017 CAMELLIA_ROUNDSM(io[2],io[3], \
1018 SUBKEY_L(i + 6),SUBKEY_R(i + 6), \
1019 io[0],io[1],il,ir); \
1020 CAMELLIA_ROUNDSM(io[0],io[1], \
1021 SUBKEY_L(i + 5),SUBKEY_R(i + 5), \
1022 io[2],io[3],il,ir); \
1023 CAMELLIA_ROUNDSM(io[2],io[3], \
1024 SUBKEY_L(i + 4),SUBKEY_R(i + 4), \
1025 io[0],io[1],il,ir); \
1026 CAMELLIA_ROUNDSM(io[0],io[1], \
1027 SUBKEY_L(i + 3),SUBKEY_R(i + 3), \
1028 io[2],io[3],il,ir); \
1029 CAMELLIA_ROUNDSM(io[2],io[3], \
1030 SUBKEY_L(i + 2),SUBKEY_R(i + 2), \
1031 io[0],io[1],il,ir); \
1032} while (0)
1033#define FLS(i) do { \
1034 CAMELLIA_FLS(io[0],io[1],io[2],io[3], \
1035 SUBKEY_L(i + 1),SUBKEY_R(i + 1), \
1036 SUBKEY_L(i + 0),SUBKEY_R(i + 0), \
1037 t0,t1,il,ir); \
1038} while (0)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001039
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001040 if (i == 32) {
1041 ROUNDS(24);
1042 FLS(24);
1043 }
1044 ROUNDS(16);
1045 FLS(16);
1046 ROUNDS(8);
1047 FLS(8);
1048 ROUNDS(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001049
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001050#undef ROUNDS
1051#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001052
1053 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001054 io[2] ^= SUBKEY_L(0);
1055 io[3] ^= SUBKEY_R(0);
1056 /* NB: 0,1 should be swapped with 2,3 by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001057}
1058
1059
Denys Vlasenko1721a812007-11-06 22:01:20 +08001060struct camellia_ctx {
1061 int key_length;
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001062 u32 key_table[CAMELLIA_TABLE_BYTE_LEN / sizeof(u32)];
Denys Vlasenko1721a812007-11-06 22:01:20 +08001063};
1064
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001065static int
1066camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
1067 unsigned int key_len)
1068{
1069 struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1070 const unsigned char *key = (const unsigned char *)in_key;
1071 u32 *flags = &tfm->crt_flags;
1072
1073 if (key_len != 16 && key_len != 24 && key_len != 32) {
1074 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
1075 return -EINVAL;
1076 }
1077
1078 cctx->key_length = key_len;
1079
Denys Vlasenko1721a812007-11-06 22:01:20 +08001080 switch (key_len) {
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001081 case 16:
1082 camellia_setup128(key, cctx->key_table);
1083 break;
1084 case 24:
1085 camellia_setup192(key, cctx->key_table);
1086 break;
1087 case 32:
1088 camellia_setup256(key, cctx->key_table);
1089 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001090 }
1091
1092 return 0;
1093}
1094
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001095static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1096{
1097 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1098 const __be32 *src = (const __be32 *)in;
1099 __be32 *dst = (__be32 *)out;
1100
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001101 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001102
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001103 tmp[0] = be32_to_cpu(src[0]);
1104 tmp[1] = be32_to_cpu(src[1]);
1105 tmp[2] = be32_to_cpu(src[2]);
1106 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001107
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001108 camellia_do_encrypt(cctx->key_table, tmp,
1109 cctx->key_length == 16 ? 24 : 32 /* for key lengths of 24 and 32 */
1110 );
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001111
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001112 /* do_encrypt returns 0,1 swapped with 2,3 */
1113 dst[0] = cpu_to_be32(tmp[2]);
1114 dst[1] = cpu_to_be32(tmp[3]);
1115 dst[2] = cpu_to_be32(tmp[0]);
1116 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001117}
1118
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001119static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1120{
1121 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1122 const __be32 *src = (const __be32 *)in;
1123 __be32 *dst = (__be32 *)out;
1124
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001125 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001126
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001127 tmp[0] = be32_to_cpu(src[0]);
1128 tmp[1] = be32_to_cpu(src[1]);
1129 tmp[2] = be32_to_cpu(src[2]);
1130 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001131
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001132 camellia_do_decrypt(cctx->key_table, tmp,
1133 cctx->key_length == 16 ? 24 : 32 /* for key lengths of 24 and 32 */
1134 );
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001135
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001136 /* do_decrypt returns 0,1 swapped with 2,3 */
1137 dst[0] = cpu_to_be32(tmp[2]);
1138 dst[1] = cpu_to_be32(tmp[3]);
1139 dst[2] = cpu_to_be32(tmp[0]);
1140 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001141}
1142
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001143static struct crypto_alg camellia_alg = {
1144 .cra_name = "camellia",
1145 .cra_driver_name = "camellia-generic",
1146 .cra_priority = 100,
1147 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
1148 .cra_blocksize = CAMELLIA_BLOCK_SIZE,
1149 .cra_ctxsize = sizeof(struct camellia_ctx),
1150 .cra_alignmask = 3,
1151 .cra_module = THIS_MODULE,
1152 .cra_list = LIST_HEAD_INIT(camellia_alg.cra_list),
1153 .cra_u = {
1154 .cipher = {
1155 .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
1156 .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
1157 .cia_setkey = camellia_set_key,
1158 .cia_encrypt = camellia_encrypt,
1159 .cia_decrypt = camellia_decrypt
1160 }
1161 }
1162};
1163
1164static int __init camellia_init(void)
1165{
1166 return crypto_register_alg(&camellia_alg);
1167}
1168
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001169static void __exit camellia_fini(void)
1170{
1171 crypto_unregister_alg(&camellia_alg);
1172}
1173
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001174module_init(camellia_init);
1175module_exit(camellia_fini);
1176
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001177MODULE_DESCRIPTION("Camellia Cipher Algorithm");
1178MODULE_LICENSE("GPL");