blob: b1cc4de6493cfa7604187e4f05429d84f6ad2e58 [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>
Harvey Harrisonbd699f22008-07-04 19:42:24 +080038#include <linux/bitops.h>
39#include <asm/unaligned.h>
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +110040
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +110041static const u32 camellia_sp1110[256] = {
42 0x70707000,0x82828200,0x2c2c2c00,0xececec00,
43 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
44 0xe4e4e400,0x85858500,0x57575700,0x35353500,
45 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
46 0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
47 0x45454500,0x19191900,0xa5a5a500,0x21212100,
48 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
49 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
50 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
51 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
52 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
53 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
54 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
55 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
56 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
57 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
58 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
59 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
60 0x74747400,0x12121200,0x2b2b2b00,0x20202000,
61 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
62 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
63 0x34343400,0x7e7e7e00,0x76767600,0x05050500,
64 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
65 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
66 0x14141400,0x58585800,0x3a3a3a00,0x61616100,
67 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
68 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
69 0x53535300,0x18181800,0xf2f2f200,0x22222200,
70 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
71 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
72 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
73 0x60606000,0xfcfcfc00,0x69696900,0x50505000,
74 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
75 0xa1a1a100,0x89898900,0x62626200,0x97979700,
76 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
77 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
78 0x10101000,0xc4c4c400,0x00000000,0x48484800,
79 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
80 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
81 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
82 0x87878700,0x5c5c5c00,0x83838300,0x02020200,
83 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
84 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
85 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
86 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
87 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
88 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
89 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
90 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
91 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
92 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
93 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
94 0x78787800,0x98989800,0x06060600,0x6a6a6a00,
95 0xe7e7e700,0x46464600,0x71717100,0xbababa00,
96 0xd4d4d400,0x25252500,0xababab00,0x42424200,
97 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
98 0x72727200,0x07070700,0xb9b9b900,0x55555500,
99 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
100 0x36363600,0x49494900,0x2a2a2a00,0x68686800,
101 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
102 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
103 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
104 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
105 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
106};
107
108static const u32 camellia_sp0222[256] = {
109 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
110 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
111 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
112 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
113 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
114 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
115 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
116 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
117 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
118 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
119 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
120 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
121 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
122 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
123 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
124 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
125 0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
126 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
127 0x00e8e8e8,0x00242424,0x00565656,0x00404040,
128 0x00e1e1e1,0x00636363,0x00090909,0x00333333,
129 0x00bfbfbf,0x00989898,0x00979797,0x00858585,
130 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
131 0x00dadada,0x006f6f6f,0x00535353,0x00626262,
132 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
133 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
134 0x00bdbdbd,0x00363636,0x00222222,0x00383838,
135 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
136 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
137 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
138 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
139 0x00484848,0x00101010,0x00d1d1d1,0x00515151,
140 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
141 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
142 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
143 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
144 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
145 0x00202020,0x00898989,0x00000000,0x00909090,
146 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
147 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
148 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
149 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
150 0x009b9b9b,0x00949494,0x00212121,0x00666666,
151 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
152 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
153 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
154 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
155 0x00030303,0x002d2d2d,0x00dedede,0x00969696,
156 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
157 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
158 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
159 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
160 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
161 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
162 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
163 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
164 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
165 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
166 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
167 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
168 0x00787878,0x00707070,0x00e3e3e3,0x00494949,
169 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
170 0x00777777,0x00939393,0x00868686,0x00838383,
171 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
172 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
173};
174
175static const u32 camellia_sp3033[256] = {
176 0x38003838,0x41004141,0x16001616,0x76007676,
177 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
178 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
179 0x75007575,0x06000606,0x57005757,0xa000a0a0,
180 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
181 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
182 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
183 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
184 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
185 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
186 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
187 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
188 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
189 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
190 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
191 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
192 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
193 0xfd00fdfd,0x66006666,0x58005858,0x96009696,
194 0x3a003a3a,0x09000909,0x95009595,0x10001010,
195 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
196 0xef00efef,0x26002626,0xe500e5e5,0x61006161,
197 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
198 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
199 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
200 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
201 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
202 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
203 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
204 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
205 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
206 0x12001212,0x04000404,0x74007474,0x54005454,
207 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
208 0x55005555,0x68006868,0x50005050,0xbe00bebe,
209 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
210 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
211 0x70007070,0xff00ffff,0x32003232,0x69006969,
212 0x08000808,0x62006262,0x00000000,0x24002424,
213 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
214 0x45004545,0x81008181,0x73007373,0x6d006d6d,
215 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
216 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
217 0xe600e6e6,0x25002525,0x48004848,0x99009999,
218 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
219 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
220 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
221 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
222 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
223 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
224 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
225 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
226 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
227 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
228 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
229 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
230 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
231 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
232 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
233 0x7c007c7c,0x77007777,0x56005656,0x05000505,
234 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
235 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
236 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
237 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
238 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
239 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
240};
241
242static const u32 camellia_sp4404[256] = {
243 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
244 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
245 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
246 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
247 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
248 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
249 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
250 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
251 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
252 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
253 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
254 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
255 0x14140014,0x3a3a003a,0xdede00de,0x11110011,
256 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
257 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
258 0x24240024,0xe8e800e8,0x60600060,0x69690069,
259 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
260 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
261 0x10100010,0x00000000,0xa3a300a3,0x75750075,
262 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
263 0x87870087,0x83830083,0xcdcd00cd,0x90900090,
264 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
265 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
266 0x81810081,0x6f6f006f,0x13130013,0x63630063,
267 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
268 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
269 0x78780078,0x06060006,0xe7e700e7,0x71710071,
270 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
271 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
272 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
273 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
274 0x15150015,0xadad00ad,0x77770077,0x80800080,
275 0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
276 0x85850085,0x35350035,0x0c0c000c,0x41410041,
277 0xefef00ef,0x93930093,0x19190019,0x21210021,
278 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
279 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
280 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
281 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
282 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
283 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
284 0x12120012,0x20200020,0xb1b100b1,0x99990099,
285 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
286 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
287 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
288 0x0f0f000f,0x16160016,0x18180018,0x22220022,
289 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
290 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
291 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
292 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
293 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
294 0x03030003,0xdada00da,0x3f3f003f,0x94940094,
295 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
296 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
297 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
298 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
299 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
300 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
301 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
302 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
303 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
304 0x49490049,0x68680068,0x38380038,0xa4a400a4,
305 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
306 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
307};
308
309
Denys Vlasenko1721a812007-11-06 22:01:20 +0800310#define CAMELLIA_MIN_KEY_SIZE 16
311#define CAMELLIA_MAX_KEY_SIZE 32
312#define CAMELLIA_BLOCK_SIZE 16
313#define CAMELLIA_TABLE_BYTE_LEN 272
314
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800315/*
316 * NB: L and R below stand for 'left' and 'right' as in written numbers.
317 * That is, in (xxxL,xxxR) pair xxxL holds most significant digits,
318 * _not_ least significant ones!
319 */
320
Denys Vlasenko1721a812007-11-06 22:01:20 +0800321
322/* key constants */
323
324#define CAMELLIA_SIGMA1L (0xA09E667FL)
325#define CAMELLIA_SIGMA1R (0x3BCC908BL)
326#define CAMELLIA_SIGMA2L (0xB67AE858L)
327#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
328#define CAMELLIA_SIGMA3L (0xC6EF372FL)
329#define CAMELLIA_SIGMA3R (0xE94F82BEL)
330#define CAMELLIA_SIGMA4L (0x54FF53A5L)
331#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
332#define CAMELLIA_SIGMA5L (0x10E527FAL)
333#define CAMELLIA_SIGMA5R (0xDE682D1DL)
334#define CAMELLIA_SIGMA6L (0xB05688C2L)
335#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
336
337/*
338 * macros
339 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800340#define ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800341 do { \
342 w0 = ll; \
343 ll = (ll << bits) + (lr >> (32 - bits)); \
344 lr = (lr << bits) + (rl >> (32 - bits)); \
345 rl = (rl << bits) + (rr >> (32 - bits)); \
346 rr = (rr << bits) + (w0 >> (32 - bits)); \
347 } while(0)
348
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800349#define ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800350 do { \
351 w0 = ll; \
352 w1 = lr; \
353 ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
354 lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
355 rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
356 rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
357 } while(0)
358
Denys Vlasenko1721a812007-11-06 22:01:20 +0800359#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
360 do { \
361 il = xl ^ kl; \
362 ir = xr ^ kr; \
363 t0 = il >> 16; \
364 t1 = ir >> 16; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800365 yl = camellia_sp1110[(u8)(ir )] \
366 ^ camellia_sp0222[ (t1 >> 8)] \
367 ^ camellia_sp3033[(u8)(t1 )] \
368 ^ camellia_sp4404[(u8)(ir >> 8)]; \
369 yr = camellia_sp1110[ (t0 >> 8)] \
370 ^ camellia_sp0222[(u8)(t0 )] \
371 ^ camellia_sp3033[(u8)(il >> 8)] \
372 ^ camellia_sp4404[(u8)(il )]; \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800373 yl ^= yr; \
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800374 yr = ror32(yr, 8); \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800375 yr ^= yl; \
376 } while(0)
377
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800378#define SUBKEY_L(INDEX) (subkey[(INDEX)*2])
379#define SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1])
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100380
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800381static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800382{
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800383 u32 dw, tl, tr;
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800384 u32 kw4l, kw4r;
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800385 int i;
386
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800387 /* absorb kw2 to other subkeys */
388 /* round 2 */
389 subL[3] ^= subL[1]; subR[3] ^= subR[1];
390 /* round 4 */
391 subL[5] ^= subL[1]; subR[5] ^= subR[1];
392 /* round 6 */
393 subL[7] ^= subL[1]; subR[7] ^= subR[1];
394 subL[1] ^= subR[1] & ~subR[9];
395 dw = subL[1] & subL[9],
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800396 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl2) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800397 /* round 8 */
398 subL[11] ^= subL[1]; subR[11] ^= subR[1];
399 /* round 10 */
400 subL[13] ^= subL[1]; subR[13] ^= subR[1];
401 /* round 12 */
402 subL[15] ^= subL[1]; subR[15] ^= subR[1];
403 subL[1] ^= subR[1] & ~subR[17];
404 dw = subL[1] & subL[17],
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800405 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl4) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800406 /* round 14 */
407 subL[19] ^= subL[1]; subR[19] ^= subR[1];
408 /* round 16 */
409 subL[21] ^= subL[1]; subR[21] ^= subR[1];
410 /* round 18 */
411 subL[23] ^= subL[1]; subR[23] ^= subR[1];
412 if (max == 24) {
413 /* kw3 */
414 subL[24] ^= subL[1]; subR[24] ^= subR[1];
415
416 /* absorb kw4 to other subkeys */
417 kw4l = subL[25]; kw4r = subR[25];
418 } else {
419 subL[1] ^= subR[1] & ~subR[25];
420 dw = subL[1] & subL[25],
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800421 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl6) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800422 /* round 20 */
423 subL[27] ^= subL[1]; subR[27] ^= subR[1];
424 /* round 22 */
425 subL[29] ^= subL[1]; subR[29] ^= subR[1];
426 /* round 24 */
427 subL[31] ^= subL[1]; subR[31] ^= subR[1];
428 /* kw3 */
429 subL[32] ^= subL[1]; subR[32] ^= subR[1];
430
431 /* absorb kw4 to other subkeys */
432 kw4l = subL[33]; kw4r = subR[33];
433 /* round 23 */
434 subL[30] ^= kw4l; subR[30] ^= kw4r;
435 /* round 21 */
436 subL[28] ^= kw4l; subR[28] ^= kw4r;
437 /* round 19 */
438 subL[26] ^= kw4l; subR[26] ^= kw4r;
439 kw4l ^= kw4r & ~subR[24];
440 dw = kw4l & subL[24],
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800441 kw4r ^= rol32(dw, 1); /* modified for FL(kl5) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800442 }
443 /* round 17 */
444 subL[22] ^= kw4l; subR[22] ^= kw4r;
445 /* round 15 */
446 subL[20] ^= kw4l; subR[20] ^= kw4r;
447 /* round 13 */
448 subL[18] ^= kw4l; subR[18] ^= kw4r;
449 kw4l ^= kw4r & ~subR[16];
450 dw = kw4l & subL[16],
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800451 kw4r ^= rol32(dw, 1); /* modified for FL(kl3) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800452 /* round 11 */
453 subL[14] ^= kw4l; subR[14] ^= kw4r;
454 /* round 9 */
455 subL[12] ^= kw4l; subR[12] ^= kw4r;
456 /* round 7 */
457 subL[10] ^= kw4l; subR[10] ^= kw4r;
458 kw4l ^= kw4r & ~subR[8];
459 dw = kw4l & subL[8],
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800460 kw4r ^= rol32(dw, 1); /* modified for FL(kl1) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800461 /* round 5 */
462 subL[6] ^= kw4l; subR[6] ^= kw4r;
463 /* round 3 */
464 subL[4] ^= kw4l; subR[4] ^= kw4r;
465 /* round 1 */
466 subL[2] ^= kw4l; subR[2] ^= kw4r;
467 /* kw1 */
468 subL[0] ^= kw4l; subR[0] ^= kw4r;
469
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800470 /* key XOR is end of F-function */
471 SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
472 SUBKEY_R(0) = subR[0] ^ subR[2];
473 SUBKEY_L(2) = subL[3]; /* round 1 */
474 SUBKEY_R(2) = subR[3];
475 SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
476 SUBKEY_R(3) = subR[2] ^ subR[4];
477 SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
478 SUBKEY_R(4) = subR[3] ^ subR[5];
479 SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
480 SUBKEY_R(5) = subR[4] ^ subR[6];
481 SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
482 SUBKEY_R(6) = subR[5] ^ subR[7];
483 tl = subL[10] ^ (subR[10] & ~subR[8]);
484 dw = tl & subL[8], /* FL(kl1) */
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800485 tr = subR[10] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800486 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
487 SUBKEY_R(7) = subR[6] ^ tr;
488 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
489 SUBKEY_R(8) = subR[8];
490 SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
491 SUBKEY_R(9) = subR[9];
492 tl = subL[7] ^ (subR[7] & ~subR[9]);
493 dw = tl & subL[9], /* FLinv(kl2) */
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800494 tr = subR[7] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800495 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
496 SUBKEY_R(10) = tr ^ subR[11];
497 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
498 SUBKEY_R(11) = subR[10] ^ subR[12];
499 SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
500 SUBKEY_R(12) = subR[11] ^ subR[13];
501 SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
502 SUBKEY_R(13) = subR[12] ^ subR[14];
503 SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
504 SUBKEY_R(14) = subR[13] ^ subR[15];
505 tl = subL[18] ^ (subR[18] & ~subR[16]);
506 dw = tl & subL[16], /* FL(kl3) */
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800507 tr = subR[18] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800508 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
509 SUBKEY_R(15) = subR[14] ^ tr;
510 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
511 SUBKEY_R(16) = subR[16];
512 SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
513 SUBKEY_R(17) = subR[17];
514 tl = subL[15] ^ (subR[15] & ~subR[17]);
515 dw = tl & subL[17], /* FLinv(kl4) */
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800516 tr = subR[15] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800517 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
518 SUBKEY_R(18) = tr ^ subR[19];
519 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
520 SUBKEY_R(19) = subR[18] ^ subR[20];
521 SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
522 SUBKEY_R(20) = subR[19] ^ subR[21];
523 SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
524 SUBKEY_R(21) = subR[20] ^ subR[22];
525 SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
526 SUBKEY_R(22) = subR[21] ^ subR[23];
527 if (max == 24) {
528 SUBKEY_L(23) = subL[22]; /* round 18 */
529 SUBKEY_R(23) = subR[22];
530 SUBKEY_L(24) = subL[24] ^ subL[23]; /* kw3 */
531 SUBKEY_R(24) = subR[24] ^ subR[23];
532 } else {
533 tl = subL[26] ^ (subR[26] & ~subR[24]);
534 dw = tl & subL[24], /* FL(kl5) */
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800535 tr = subR[26] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800536 SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
537 SUBKEY_R(23) = subR[22] ^ tr;
538 SUBKEY_L(24) = subL[24]; /* FL(kl5) */
539 SUBKEY_R(24) = subR[24];
540 SUBKEY_L(25) = subL[25]; /* FLinv(kl6) */
541 SUBKEY_R(25) = subR[25];
542 tl = subL[23] ^ (subR[23] & ~subR[25]);
543 dw = tl & subL[25], /* FLinv(kl6) */
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800544 tr = subR[23] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800545 SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
546 SUBKEY_R(26) = tr ^ subR[27];
547 SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
548 SUBKEY_R(27) = subR[26] ^ subR[28];
549 SUBKEY_L(28) = subL[27] ^ subL[29]; /* round 21 */
550 SUBKEY_R(28) = subR[27] ^ subR[29];
551 SUBKEY_L(29) = subL[28] ^ subL[30]; /* round 22 */
552 SUBKEY_R(29) = subR[28] ^ subR[30];
553 SUBKEY_L(30) = subL[29] ^ subL[31]; /* round 23 */
554 SUBKEY_R(30) = subR[29] ^ subR[31];
555 SUBKEY_L(31) = subL[30]; /* round 24 */
556 SUBKEY_R(31) = subR[30];
557 SUBKEY_L(32) = subL[32] ^ subL[31]; /* kw3 */
558 SUBKEY_R(32) = subR[32] ^ subR[31];
559 }
560
561 /* apply the inverse of the last half of P-function */
562 i = 2;
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800563 do {
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800564 dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = rol32(dw, 8);/* round 1 */
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800565 SUBKEY_R(i + 0) = SUBKEY_L(i + 0) ^ dw; SUBKEY_L(i + 0) = dw;
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800566 dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = rol32(dw, 8);/* round 2 */
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800567 SUBKEY_R(i + 1) = SUBKEY_L(i + 1) ^ dw; SUBKEY_L(i + 1) = dw;
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800568 dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = rol32(dw, 8);/* round 3 */
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800569 SUBKEY_R(i + 2) = SUBKEY_L(i + 2) ^ dw; SUBKEY_L(i + 2) = dw;
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800570 dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = rol32(dw, 8);/* round 4 */
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800571 SUBKEY_R(i + 3) = SUBKEY_L(i + 3) ^ dw; SUBKEY_L(i + 3) = dw;
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800572 dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = rol32(dw, 9);/* round 5 */
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800573 SUBKEY_R(i + 4) = SUBKEY_L(i + 4) ^ dw; SUBKEY_L(i + 4) = dw;
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800574 dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = rol32(dw, 8);/* round 6 */
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800575 SUBKEY_R(i + 5) = SUBKEY_L(i + 5) ^ dw; SUBKEY_L(i + 5) = dw;
576 i += 8;
577 } while (i < max);
578}
579
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100580static void camellia_setup128(const unsigned char *key, u32 *subkey)
581{
582 u32 kll, klr, krl, krr;
583 u32 il, ir, t0, t1, w0, w1;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100584 u32 subL[26];
585 u32 subR[26];
586
587 /**
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800588 * k == kll || klr || krl || krr (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100589 */
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800590 kll = get_unaligned_be32(key);
591 klr = get_unaligned_be32(key + 4);
592 krl = get_unaligned_be32(key + 8);
593 krr = get_unaligned_be32(key + 12);
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800594
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800595 /* generate KL dependent subkeys */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100596 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800597 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100598 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800599 subL[1] = krl; subR[1] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100600 /* rotation left shift 15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800601 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100602 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800603 subL[4] = kll; subR[4] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100604 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800605 subL[5] = krl; subR[5] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100606 /* rotation left shift 15+30bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800607 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100608 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800609 subL[10] = kll; subR[10] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100610 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800611 subL[11] = krl; subR[11] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100612 /* rotation left shift 15+30+15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800613 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100614 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800615 subL[13] = krl; subR[13] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100616 /* rotation left shift 15+30+15+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800617 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100618 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800619 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100620 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800621 subL[17] = krl; subR[17] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100622 /* rotation left shift 15+30+15+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800623 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100624 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800625 subL[18] = kll; subR[18] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100626 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800627 subL[19] = krl; subR[19] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100628 /* rotation left shift 15+30+15+17+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800629 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100630 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800631 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100632 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800633 subL[23] = krl; subR[23] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100634
635 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800636 kll = subL[0]; klr = subR[0];
637 krl = subL[1]; krr = subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100638 CAMELLIA_F(kll, klr,
639 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
640 w0, w1, il, ir, t0, t1);
641 krl ^= w0; krr ^= w1;
642 CAMELLIA_F(krl, krr,
643 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
644 kll, klr, il, ir, t0, t1);
645 /* current status == (kll, klr, w0, w1) */
646 CAMELLIA_F(kll, klr,
647 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
648 krl, krr, il, ir, t0, t1);
649 krl ^= w0; krr ^= w1;
650 CAMELLIA_F(krl, krr,
651 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
652 w0, w1, il, ir, t0, t1);
653 kll ^= w0; klr ^= w1;
654
655 /* generate KA dependent subkeys */
656 /* k1, k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800657 subL[2] = kll; subR[2] = klr;
658 subL[3] = krl; subR[3] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800659 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100660 /* k5,k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800661 subL[6] = kll; subR[6] = klr;
662 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800663 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100664 /* kl1, kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800665 subL[8] = kll; subR[8] = klr;
666 subL[9] = krl; subR[9] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800667 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100668 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800669 subL[12] = kll; subR[12] = klr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800670 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100671 /* k11, k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800672 subL[14] = kll; subR[14] = klr;
673 subL[15] = krl; subR[15] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800674 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100675 /* k15, k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800676 subL[20] = kll; subR[20] = klr;
677 subL[21] = krl; subR[21] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800678 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100679 /* kw3, kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800680 subL[24] = kll; subR[24] = klr;
681 subL[25] = krl; subR[25] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100682
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800683 camellia_setup_tail(subkey, subL, subR, 24);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100684}
685
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100686static void camellia_setup256(const unsigned char *key, u32 *subkey)
687{
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800688 u32 kll, klr, krl, krr; /* left half of key */
689 u32 krll, krlr, krrl, krrr; /* right half of key */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100690 u32 il, ir, t0, t1, w0, w1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100691 u32 subL[34];
692 u32 subR[34];
693
694 /**
695 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800696 * (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100697 */
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800698 kll = get_unaligned_be32(key);
699 klr = get_unaligned_be32(key + 4);
700 krl = get_unaligned_be32(key + 8);
701 krr = get_unaligned_be32(key + 12);
702 krll = get_unaligned_be32(key + 16);
703 krlr = get_unaligned_be32(key + 20);
704 krrl = get_unaligned_be32(key + 24);
705 krrr = get_unaligned_be32(key + 28);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100706
707 /* generate KL dependent subkeys */
708 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800709 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100710 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800711 subL[1] = krl; subR[1] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800712 ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100713 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800714 subL[12] = kll; subR[12] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100715 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800716 subL[13] = krl; subR[13] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800717 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100718 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800719 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100720 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800721 subL[17] = krl; subR[17] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800722 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100723 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800724 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100725 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800726 subL[23] = krl; subR[23] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800727 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100728 /* k23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800729 subL[30] = kll; subR[30] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100730 /* k24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800731 subL[31] = krl; subR[31] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100732
733 /* generate KR dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800734 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100735 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800736 subL[4] = krll; subR[4] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100737 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800738 subL[5] = krrl; subR[5] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800739 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100740 /* kl1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800741 subL[8] = krll; subR[8] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100742 /* kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800743 subL[9] = krrl; subR[9] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800744 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100745 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800746 subL[18] = krll; subR[18] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100747 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800748 subL[19] = krrl; subR[19] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800749 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100750 /* k19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800751 subL[26] = krll; subR[26] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100752 /* k20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800753 subL[27] = krrl; subR[27] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800754 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100755
756 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800757 kll = subL[0] ^ krll; klr = subR[0] ^ krlr;
758 krl = subL[1] ^ krrl; krr = subR[1] ^ krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100759 CAMELLIA_F(kll, klr,
760 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
761 w0, w1, il, ir, t0, t1);
762 krl ^= w0; krr ^= w1;
763 CAMELLIA_F(krl, krr,
764 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
765 kll, klr, il, ir, t0, t1);
766 kll ^= krll; klr ^= krlr;
767 CAMELLIA_F(kll, klr,
768 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
769 krl, krr, il, ir, t0, t1);
770 krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
771 CAMELLIA_F(krl, krr,
772 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
773 w0, w1, il, ir, t0, t1);
774 kll ^= w0; klr ^= w1;
775
776 /* generate KB */
777 krll ^= kll; krlr ^= klr;
778 krrl ^= krl; krrr ^= krr;
779 CAMELLIA_F(krll, krlr,
780 CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
781 w0, w1, il, ir, t0, t1);
782 krrl ^= w0; krrr ^= w1;
783 CAMELLIA_F(krrl, krrr,
784 CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
785 w0, w1, il, ir, t0, t1);
786 krll ^= w0; krlr ^= w1;
787
788 /* generate KA dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800789 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100790 /* k5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800791 subL[6] = kll; subR[6] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100792 /* k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800793 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800794 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100795 /* k11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800796 subL[14] = kll; subR[14] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100797 /* k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800798 subL[15] = krl; subR[15] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100799 /* rotation left shift 32bit */
800 /* kl5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800801 subL[24] = klr; subR[24] = krl;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100802 /* kl6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800803 subL[25] = krr; subR[25] = kll;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100804 /* rotation left shift 49 from k11,k12 -> k21,k22 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800805 ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100806 /* k21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800807 subL[28] = kll; subR[28] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100808 /* k22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800809 subL[29] = krl; subR[29] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100810
811 /* generate KB dependent subkeys */
812 /* k1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800813 subL[2] = krll; subR[2] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100814 /* k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800815 subL[3] = krrl; subR[3] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800816 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100817 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800818 subL[10] = krll; subR[10] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100819 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800820 subL[11] = krrl; subR[11] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800821 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100822 /* k15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800823 subL[20] = krll; subR[20] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100824 /* k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800825 subL[21] = krrl; subR[21] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800826 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100827 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800828 subL[32] = krll; subR[32] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100829 /* kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800830 subL[33] = krrl; subR[33] = krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100831
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800832 camellia_setup_tail(subkey, subL, subR, 32);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100833}
834
835static void camellia_setup192(const unsigned char *key, u32 *subkey)
836{
837 unsigned char kk[32];
838 u32 krll, krlr, krrl,krrr;
839
840 memcpy(kk, key, 24);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800841 memcpy((unsigned char *)&krll, key+16, 4);
842 memcpy((unsigned char *)&krlr, key+20, 4);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100843 krrl = ~krll;
844 krrr = ~krlr;
845 memcpy(kk+24, (unsigned char *)&krrl, 4);
846 memcpy(kk+28, (unsigned char *)&krrr, 4);
847 camellia_setup256(kk, subkey);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100848}
849
850
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800851/*
852 * Encrypt/decrypt
853 */
854#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
855 do { \
856 t0 = kll; \
857 t2 = krr; \
858 t0 &= ll; \
859 t2 |= rr; \
860 rl ^= t2; \
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800861 lr ^= rol32(t0, 1); \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800862 t3 = krl; \
863 t1 = klr; \
864 t3 &= rl; \
865 t1 |= lr; \
866 ll ^= t1; \
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800867 rr ^= rol32(t3, 1); \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800868 } while(0)
869
870#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) \
871 do { \
872 ir = camellia_sp1110[(u8)xr]; \
873 il = camellia_sp1110[ (xl >> 24)]; \
874 ir ^= camellia_sp0222[ (xr >> 24)]; \
875 il ^= camellia_sp0222[(u8)(xl >> 16)]; \
876 ir ^= camellia_sp3033[(u8)(xr >> 16)]; \
877 il ^= camellia_sp3033[(u8)(xl >> 8)]; \
878 ir ^= camellia_sp4404[(u8)(xr >> 8)]; \
879 il ^= camellia_sp4404[(u8)xl]; \
880 il ^= kl; \
881 ir ^= il ^ kr; \
882 yl ^= ir; \
Harvey Harrisonbd699f22008-07-04 19:42:24 +0800883 yr ^= ror32(il, 8) ^ ir; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800884 } while(0)
885
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800886/* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
887static void camellia_do_encrypt(const u32 *subkey, u32 *io, unsigned max)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100888{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800889 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100890
Denys Vlasenko1721a812007-11-06 22:01:20 +0800891 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800892 io[0] ^= SUBKEY_L(0);
893 io[1] ^= SUBKEY_R(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100894
Denys Vlasenko1721a812007-11-06 22:01:20 +0800895 /* main iteration */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800896#define ROUNDS(i) do { \
897 CAMELLIA_ROUNDSM(io[0],io[1], \
898 SUBKEY_L(i + 2),SUBKEY_R(i + 2), \
899 io[2],io[3],il,ir); \
900 CAMELLIA_ROUNDSM(io[2],io[3], \
901 SUBKEY_L(i + 3),SUBKEY_R(i + 3), \
902 io[0],io[1],il,ir); \
903 CAMELLIA_ROUNDSM(io[0],io[1], \
904 SUBKEY_L(i + 4),SUBKEY_R(i + 4), \
905 io[2],io[3],il,ir); \
906 CAMELLIA_ROUNDSM(io[2],io[3], \
907 SUBKEY_L(i + 5),SUBKEY_R(i + 5), \
908 io[0],io[1],il,ir); \
909 CAMELLIA_ROUNDSM(io[0],io[1], \
910 SUBKEY_L(i + 6),SUBKEY_R(i + 6), \
911 io[2],io[3],il,ir); \
912 CAMELLIA_ROUNDSM(io[2],io[3], \
913 SUBKEY_L(i + 7),SUBKEY_R(i + 7), \
914 io[0],io[1],il,ir); \
915} while (0)
916#define FLS(i) do { \
917 CAMELLIA_FLS(io[0],io[1],io[2],io[3], \
918 SUBKEY_L(i + 0),SUBKEY_R(i + 0), \
919 SUBKEY_L(i + 1),SUBKEY_R(i + 1), \
920 t0,t1,il,ir); \
921} while (0)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100922
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800923 ROUNDS(0);
924 FLS(8);
925 ROUNDS(8);
926 FLS(16);
927 ROUNDS(16);
928 if (max == 32) {
929 FLS(24);
930 ROUNDS(24);
931 }
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100932
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800933#undef ROUNDS
934#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100935
936 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800937 io[2] ^= SUBKEY_L(max);
938 io[3] ^= SUBKEY_R(max);
939 /* NB: io[0],[1] should be swapped with [2],[3] by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100940}
941
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800942static void camellia_do_decrypt(const u32 *subkey, u32 *io, unsigned i)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100943{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800944 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100945
Denys Vlasenko1721a812007-11-06 22:01:20 +0800946 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800947 io[0] ^= SUBKEY_L(i);
948 io[1] ^= SUBKEY_R(i);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100949
950 /* main iteration */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800951#define ROUNDS(i) do { \
952 CAMELLIA_ROUNDSM(io[0],io[1], \
953 SUBKEY_L(i + 7),SUBKEY_R(i + 7), \
954 io[2],io[3],il,ir); \
955 CAMELLIA_ROUNDSM(io[2],io[3], \
956 SUBKEY_L(i + 6),SUBKEY_R(i + 6), \
957 io[0],io[1],il,ir); \
958 CAMELLIA_ROUNDSM(io[0],io[1], \
959 SUBKEY_L(i + 5),SUBKEY_R(i + 5), \
960 io[2],io[3],il,ir); \
961 CAMELLIA_ROUNDSM(io[2],io[3], \
962 SUBKEY_L(i + 4),SUBKEY_R(i + 4), \
963 io[0],io[1],il,ir); \
964 CAMELLIA_ROUNDSM(io[0],io[1], \
965 SUBKEY_L(i + 3),SUBKEY_R(i + 3), \
966 io[2],io[3],il,ir); \
967 CAMELLIA_ROUNDSM(io[2],io[3], \
968 SUBKEY_L(i + 2),SUBKEY_R(i + 2), \
969 io[0],io[1],il,ir); \
970} while (0)
971#define FLS(i) do { \
972 CAMELLIA_FLS(io[0],io[1],io[2],io[3], \
973 SUBKEY_L(i + 1),SUBKEY_R(i + 1), \
974 SUBKEY_L(i + 0),SUBKEY_R(i + 0), \
975 t0,t1,il,ir); \
976} while (0)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100977
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800978 if (i == 32) {
979 ROUNDS(24);
980 FLS(24);
981 }
982 ROUNDS(16);
983 FLS(16);
984 ROUNDS(8);
985 FLS(8);
986 ROUNDS(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100987
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800988#undef ROUNDS
989#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100990
991 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800992 io[2] ^= SUBKEY_L(0);
993 io[3] ^= SUBKEY_R(0);
994 /* NB: 0,1 should be swapped with 2,3 by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100995}
996
997
Denys Vlasenko1721a812007-11-06 22:01:20 +0800998struct camellia_ctx {
999 int key_length;
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001000 u32 key_table[CAMELLIA_TABLE_BYTE_LEN / sizeof(u32)];
Denys Vlasenko1721a812007-11-06 22:01:20 +08001001};
1002
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001003static int
1004camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
1005 unsigned int key_len)
1006{
1007 struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1008 const unsigned char *key = (const unsigned char *)in_key;
1009 u32 *flags = &tfm->crt_flags;
1010
1011 if (key_len != 16 && key_len != 24 && key_len != 32) {
1012 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
1013 return -EINVAL;
1014 }
1015
1016 cctx->key_length = key_len;
1017
Denys Vlasenko1721a812007-11-06 22:01:20 +08001018 switch (key_len) {
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001019 case 16:
1020 camellia_setup128(key, cctx->key_table);
1021 break;
1022 case 24:
1023 camellia_setup192(key, cctx->key_table);
1024 break;
1025 case 32:
1026 camellia_setup256(key, cctx->key_table);
1027 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001028 }
1029
1030 return 0;
1031}
1032
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001033static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1034{
1035 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1036 const __be32 *src = (const __be32 *)in;
1037 __be32 *dst = (__be32 *)out;
1038
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001039 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001040
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001041 tmp[0] = be32_to_cpu(src[0]);
1042 tmp[1] = be32_to_cpu(src[1]);
1043 tmp[2] = be32_to_cpu(src[2]);
1044 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001045
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001046 camellia_do_encrypt(cctx->key_table, tmp,
1047 cctx->key_length == 16 ? 24 : 32 /* for key lengths of 24 and 32 */
1048 );
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001049
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001050 /* do_encrypt returns 0,1 swapped with 2,3 */
1051 dst[0] = cpu_to_be32(tmp[2]);
1052 dst[1] = cpu_to_be32(tmp[3]);
1053 dst[2] = cpu_to_be32(tmp[0]);
1054 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001055}
1056
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001057static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1058{
1059 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1060 const __be32 *src = (const __be32 *)in;
1061 __be32 *dst = (__be32 *)out;
1062
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001063 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001064
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001065 tmp[0] = be32_to_cpu(src[0]);
1066 tmp[1] = be32_to_cpu(src[1]);
1067 tmp[2] = be32_to_cpu(src[2]);
1068 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001069
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001070 camellia_do_decrypt(cctx->key_table, tmp,
1071 cctx->key_length == 16 ? 24 : 32 /* for key lengths of 24 and 32 */
1072 );
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001073
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001074 /* do_decrypt returns 0,1 swapped with 2,3 */
1075 dst[0] = cpu_to_be32(tmp[2]);
1076 dst[1] = cpu_to_be32(tmp[3]);
1077 dst[2] = cpu_to_be32(tmp[0]);
1078 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001079}
1080
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001081static struct crypto_alg camellia_alg = {
1082 .cra_name = "camellia",
1083 .cra_driver_name = "camellia-generic",
1084 .cra_priority = 100,
1085 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
1086 .cra_blocksize = CAMELLIA_BLOCK_SIZE,
1087 .cra_ctxsize = sizeof(struct camellia_ctx),
1088 .cra_alignmask = 3,
1089 .cra_module = THIS_MODULE,
1090 .cra_list = LIST_HEAD_INIT(camellia_alg.cra_list),
1091 .cra_u = {
1092 .cipher = {
1093 .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
1094 .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
1095 .cia_setkey = camellia_set_key,
1096 .cia_encrypt = camellia_encrypt,
1097 .cia_decrypt = camellia_decrypt
1098 }
1099 }
1100};
1101
1102static int __init camellia_init(void)
1103{
1104 return crypto_register_alg(&camellia_alg);
1105}
1106
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001107static void __exit camellia_fini(void)
1108{
1109 crypto_unregister_alg(&camellia_alg);
1110}
1111
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001112module_init(camellia_init);
1113module_exit(camellia_fini);
1114
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001115MODULE_DESCRIPTION("Camellia Cipher Algorithm");
1116MODULE_LICENSE("GPL");