blob: 493fee7e0a8b46bbd9933d92681e0a7c16d0ab81 [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;
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800396 u32 kw4l, kw4r;
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800397 int i;
398
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800399 /* absorb kw2 to other subkeys */
400 /* round 2 */
401 subL[3] ^= subL[1]; subR[3] ^= subR[1];
402 /* round 4 */
403 subL[5] ^= subL[1]; subR[5] ^= subR[1];
404 /* round 6 */
405 subL[7] ^= subL[1]; subR[7] ^= subR[1];
406 subL[1] ^= subR[1] & ~subR[9];
407 dw = subL[1] & subL[9],
408 subR[1] ^= ROL1(dw); /* modified for FLinv(kl2) */
409 /* round 8 */
410 subL[11] ^= subL[1]; subR[11] ^= subR[1];
411 /* round 10 */
412 subL[13] ^= subL[1]; subR[13] ^= subR[1];
413 /* round 12 */
414 subL[15] ^= subL[1]; subR[15] ^= subR[1];
415 subL[1] ^= subR[1] & ~subR[17];
416 dw = subL[1] & subL[17],
417 subR[1] ^= ROL1(dw); /* modified for FLinv(kl4) */
418 /* round 14 */
419 subL[19] ^= subL[1]; subR[19] ^= subR[1];
420 /* round 16 */
421 subL[21] ^= subL[1]; subR[21] ^= subR[1];
422 /* round 18 */
423 subL[23] ^= subL[1]; subR[23] ^= subR[1];
424 if (max == 24) {
425 /* kw3 */
426 subL[24] ^= subL[1]; subR[24] ^= subR[1];
427
428 /* absorb kw4 to other subkeys */
429 kw4l = subL[25]; kw4r = subR[25];
430 } else {
431 subL[1] ^= subR[1] & ~subR[25];
432 dw = subL[1] & subL[25],
433 subR[1] ^= ROL1(dw); /* modified for FLinv(kl6) */
434 /* round 20 */
435 subL[27] ^= subL[1]; subR[27] ^= subR[1];
436 /* round 22 */
437 subL[29] ^= subL[1]; subR[29] ^= subR[1];
438 /* round 24 */
439 subL[31] ^= subL[1]; subR[31] ^= subR[1];
440 /* kw3 */
441 subL[32] ^= subL[1]; subR[32] ^= subR[1];
442
443 /* absorb kw4 to other subkeys */
444 kw4l = subL[33]; kw4r = subR[33];
445 /* round 23 */
446 subL[30] ^= kw4l; subR[30] ^= kw4r;
447 /* round 21 */
448 subL[28] ^= kw4l; subR[28] ^= kw4r;
449 /* round 19 */
450 subL[26] ^= kw4l; subR[26] ^= kw4r;
451 kw4l ^= kw4r & ~subR[24];
452 dw = kw4l & subL[24],
453 kw4r ^= ROL1(dw); /* modified for FL(kl5) */
454 }
455 /* round 17 */
456 subL[22] ^= kw4l; subR[22] ^= kw4r;
457 /* round 15 */
458 subL[20] ^= kw4l; subR[20] ^= kw4r;
459 /* round 13 */
460 subL[18] ^= kw4l; subR[18] ^= kw4r;
461 kw4l ^= kw4r & ~subR[16];
462 dw = kw4l & subL[16],
463 kw4r ^= ROL1(dw); /* modified for FL(kl3) */
464 /* round 11 */
465 subL[14] ^= kw4l; subR[14] ^= kw4r;
466 /* round 9 */
467 subL[12] ^= kw4l; subR[12] ^= kw4r;
468 /* round 7 */
469 subL[10] ^= kw4l; subR[10] ^= kw4r;
470 kw4l ^= kw4r & ~subR[8];
471 dw = kw4l & subL[8],
472 kw4r ^= ROL1(dw); /* modified for FL(kl1) */
473 /* round 5 */
474 subL[6] ^= kw4l; subR[6] ^= kw4r;
475 /* round 3 */
476 subL[4] ^= kw4l; subR[4] ^= kw4r;
477 /* round 1 */
478 subL[2] ^= kw4l; subR[2] ^= kw4r;
479 /* kw1 */
480 subL[0] ^= kw4l; subR[0] ^= kw4r;
481
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800482 /* key XOR is end of F-function */
483 SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
484 SUBKEY_R(0) = subR[0] ^ subR[2];
485 SUBKEY_L(2) = subL[3]; /* round 1 */
486 SUBKEY_R(2) = subR[3];
487 SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
488 SUBKEY_R(3) = subR[2] ^ subR[4];
489 SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
490 SUBKEY_R(4) = subR[3] ^ subR[5];
491 SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
492 SUBKEY_R(5) = subR[4] ^ subR[6];
493 SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
494 SUBKEY_R(6) = subR[5] ^ subR[7];
495 tl = subL[10] ^ (subR[10] & ~subR[8]);
496 dw = tl & subL[8], /* FL(kl1) */
497 tr = subR[10] ^ ROL1(dw);
498 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
499 SUBKEY_R(7) = subR[6] ^ tr;
500 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
501 SUBKEY_R(8) = subR[8];
502 SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
503 SUBKEY_R(9) = subR[9];
504 tl = subL[7] ^ (subR[7] & ~subR[9]);
505 dw = tl & subL[9], /* FLinv(kl2) */
506 tr = subR[7] ^ ROL1(dw);
507 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
508 SUBKEY_R(10) = tr ^ subR[11];
509 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
510 SUBKEY_R(11) = subR[10] ^ subR[12];
511 SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
512 SUBKEY_R(12) = subR[11] ^ subR[13];
513 SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
514 SUBKEY_R(13) = subR[12] ^ subR[14];
515 SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
516 SUBKEY_R(14) = subR[13] ^ subR[15];
517 tl = subL[18] ^ (subR[18] & ~subR[16]);
518 dw = tl & subL[16], /* FL(kl3) */
519 tr = subR[18] ^ ROL1(dw);
520 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
521 SUBKEY_R(15) = subR[14] ^ tr;
522 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
523 SUBKEY_R(16) = subR[16];
524 SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
525 SUBKEY_R(17) = subR[17];
526 tl = subL[15] ^ (subR[15] & ~subR[17]);
527 dw = tl & subL[17], /* FLinv(kl4) */
528 tr = subR[15] ^ ROL1(dw);
529 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
530 SUBKEY_R(18) = tr ^ subR[19];
531 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
532 SUBKEY_R(19) = subR[18] ^ subR[20];
533 SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
534 SUBKEY_R(20) = subR[19] ^ subR[21];
535 SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
536 SUBKEY_R(21) = subR[20] ^ subR[22];
537 SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
538 SUBKEY_R(22) = subR[21] ^ subR[23];
539 if (max == 24) {
540 SUBKEY_L(23) = subL[22]; /* round 18 */
541 SUBKEY_R(23) = subR[22];
542 SUBKEY_L(24) = subL[24] ^ subL[23]; /* kw3 */
543 SUBKEY_R(24) = subR[24] ^ subR[23];
544 } else {
545 tl = subL[26] ^ (subR[26] & ~subR[24]);
546 dw = tl & subL[24], /* FL(kl5) */
547 tr = subR[26] ^ ROL1(dw);
548 SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
549 SUBKEY_R(23) = subR[22] ^ tr;
550 SUBKEY_L(24) = subL[24]; /* FL(kl5) */
551 SUBKEY_R(24) = subR[24];
552 SUBKEY_L(25) = subL[25]; /* FLinv(kl6) */
553 SUBKEY_R(25) = subR[25];
554 tl = subL[23] ^ (subR[23] & ~subR[25]);
555 dw = tl & subL[25], /* FLinv(kl6) */
556 tr = subR[23] ^ ROL1(dw);
557 SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
558 SUBKEY_R(26) = tr ^ subR[27];
559 SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
560 SUBKEY_R(27) = subR[26] ^ subR[28];
561 SUBKEY_L(28) = subL[27] ^ subL[29]; /* round 21 */
562 SUBKEY_R(28) = subR[27] ^ subR[29];
563 SUBKEY_L(29) = subL[28] ^ subL[30]; /* round 22 */
564 SUBKEY_R(29) = subR[28] ^ subR[30];
565 SUBKEY_L(30) = subL[29] ^ subL[31]; /* round 23 */
566 SUBKEY_R(30) = subR[29] ^ subR[31];
567 SUBKEY_L(31) = subL[30]; /* round 24 */
568 SUBKEY_R(31) = subR[30];
569 SUBKEY_L(32) = subL[32] ^ subL[31]; /* kw3 */
570 SUBKEY_R(32) = subR[32] ^ subR[31];
571 }
572
573 /* apply the inverse of the last half of P-function */
574 i = 2;
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800575 do {
576 dw = SUBKEY_L(i + 0) ^ SUBKEY_R(i + 0); dw = ROL8(dw);/* round 1 */
577 SUBKEY_R(i + 0) = SUBKEY_L(i + 0) ^ dw; SUBKEY_L(i + 0) = dw;
578 dw = SUBKEY_L(i + 1) ^ SUBKEY_R(i + 1); dw = ROL8(dw);/* round 2 */
579 SUBKEY_R(i + 1) = SUBKEY_L(i + 1) ^ dw; SUBKEY_L(i + 1) = dw;
580 dw = SUBKEY_L(i + 2) ^ SUBKEY_R(i + 2); dw = ROL8(dw);/* round 3 */
581 SUBKEY_R(i + 2) = SUBKEY_L(i + 2) ^ dw; SUBKEY_L(i + 2) = dw;
582 dw = SUBKEY_L(i + 3) ^ SUBKEY_R(i + 3); dw = ROL8(dw);/* round 4 */
583 SUBKEY_R(i + 3) = SUBKEY_L(i + 3) ^ dw; SUBKEY_L(i + 3) = dw;
584 dw = SUBKEY_L(i + 4) ^ SUBKEY_R(i + 4); dw = ROL8(dw);/* round 5 */
585 SUBKEY_R(i + 4) = SUBKEY_L(i + 4) ^ dw; SUBKEY_L(i + 4) = dw;
586 dw = SUBKEY_L(i + 5) ^ SUBKEY_R(i + 5); dw = ROL8(dw);/* round 6 */
587 SUBKEY_R(i + 5) = SUBKEY_L(i + 5) ^ dw; SUBKEY_L(i + 5) = dw;
588 i += 8;
589 } while (i < max);
590}
591
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100592static void camellia_setup128(const unsigned char *key, u32 *subkey)
593{
594 u32 kll, klr, krl, krr;
595 u32 il, ir, t0, t1, w0, w1;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100596 u32 subL[26];
597 u32 subR[26];
598
599 /**
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800600 * k == kll || klr || krl || krr (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100601 */
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800602 GETU32(kll, key );
603 GETU32(klr, key + 4);
604 GETU32(krl, key + 8);
605 GETU32(krr, key + 12);
606
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800607 /* generate KL dependent subkeys */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100608 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800609 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100610 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800611 subL[1] = krl; subR[1] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100612 /* rotation left shift 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 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800615 subL[4] = kll; subR[4] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100616 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800617 subL[5] = krl; subR[5] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100618 /* rotation left shift 15+30bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800619 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100620 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800621 subL[10] = kll; subR[10] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100622 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800623 subL[11] = krl; subR[11] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100624 /* rotation left shift 15+30+15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800625 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100626 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800627 subL[13] = krl; subR[13] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100628 /* rotation left shift 15+30+15+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 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800631 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100632 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800633 subL[17] = krl; subR[17] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100634 /* rotation left shift 15+30+15+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800635 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100636 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800637 subL[18] = kll; subR[18] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100638 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800639 subL[19] = krl; subR[19] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100640 /* rotation left shift 15+30+15+17+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800641 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100642 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800643 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100644 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800645 subL[23] = krl; subR[23] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100646
647 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800648 kll = subL[0]; klr = subR[0];
649 krl = subL[1]; krr = subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100650 CAMELLIA_F(kll, klr,
651 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
652 w0, w1, il, ir, t0, t1);
653 krl ^= w0; krr ^= w1;
654 CAMELLIA_F(krl, krr,
655 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
656 kll, klr, il, ir, t0, t1);
657 /* current status == (kll, klr, w0, w1) */
658 CAMELLIA_F(kll, klr,
659 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
660 krl, krr, il, ir, t0, t1);
661 krl ^= w0; krr ^= w1;
662 CAMELLIA_F(krl, krr,
663 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
664 w0, w1, il, ir, t0, t1);
665 kll ^= w0; klr ^= w1;
666
667 /* generate KA dependent subkeys */
668 /* k1, k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800669 subL[2] = kll; subR[2] = klr;
670 subL[3] = krl; subR[3] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800671 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100672 /* k5,k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800673 subL[6] = kll; subR[6] = klr;
674 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800675 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100676 /* kl1, kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800677 subL[8] = kll; subR[8] = klr;
678 subL[9] = krl; subR[9] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800679 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100680 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800681 subL[12] = kll; subR[12] = klr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800682 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100683 /* k11, k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800684 subL[14] = kll; subR[14] = klr;
685 subL[15] = krl; subR[15] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800686 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100687 /* k15, k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800688 subL[20] = kll; subR[20] = klr;
689 subL[21] = krl; subR[21] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800690 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100691 /* kw3, kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800692 subL[24] = kll; subR[24] = klr;
693 subL[25] = krl; subR[25] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100694
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800695 camellia_setup_tail(subkey, subL, subR, 24);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100696}
697
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100698static void camellia_setup256(const unsigned char *key, u32 *subkey)
699{
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800700 u32 kll, klr, krl, krr; /* left half of key */
701 u32 krll, krlr, krrl, krrr; /* right half of key */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100702 u32 il, ir, t0, t1, w0, w1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100703 u32 subL[34];
704 u32 subR[34];
705
706 /**
707 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800708 * (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100709 */
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800710 GETU32(kll, key );
711 GETU32(klr, key + 4);
712 GETU32(krl, key + 8);
713 GETU32(krr, key + 12);
714 GETU32(krll, key + 16);
715 GETU32(krlr, key + 20);
716 GETU32(krrl, key + 24);
717 GETU32(krrr, key + 28);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100718
719 /* generate KL dependent subkeys */
720 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800721 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100722 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800723 subL[1] = krl; subR[1] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800724 ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100725 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800726 subL[12] = kll; subR[12] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100727 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800728 subL[13] = krl; subR[13] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800729 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100730 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800731 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100732 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800733 subL[17] = krl; subR[17] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800734 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100735 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800736 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100737 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800738 subL[23] = krl; subR[23] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800739 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100740 /* k23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800741 subL[30] = kll; subR[30] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100742 /* k24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800743 subL[31] = krl; subR[31] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100744
745 /* generate KR dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800746 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100747 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800748 subL[4] = krll; subR[4] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100749 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800750 subL[5] = krrl; subR[5] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800751 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100752 /* kl1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800753 subL[8] = krll; subR[8] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100754 /* kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800755 subL[9] = krrl; subR[9] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800756 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100757 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800758 subL[18] = krll; subR[18] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100759 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800760 subL[19] = krrl; subR[19] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800761 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100762 /* k19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800763 subL[26] = krll; subR[26] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100764 /* k20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800765 subL[27] = krrl; subR[27] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800766 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100767
768 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800769 kll = subL[0] ^ krll; klr = subR[0] ^ krlr;
770 krl = subL[1] ^ krrl; krr = subR[1] ^ krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100771 CAMELLIA_F(kll, klr,
772 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
773 w0, w1, il, ir, t0, t1);
774 krl ^= w0; krr ^= w1;
775 CAMELLIA_F(krl, krr,
776 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
777 kll, klr, il, ir, t0, t1);
778 kll ^= krll; klr ^= krlr;
779 CAMELLIA_F(kll, klr,
780 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
781 krl, krr, il, ir, t0, t1);
782 krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
783 CAMELLIA_F(krl, krr,
784 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
785 w0, w1, il, ir, t0, t1);
786 kll ^= w0; klr ^= w1;
787
788 /* generate KB */
789 krll ^= kll; krlr ^= klr;
790 krrl ^= krl; krrr ^= krr;
791 CAMELLIA_F(krll, krlr,
792 CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
793 w0, w1, il, ir, t0, t1);
794 krrl ^= w0; krrr ^= w1;
795 CAMELLIA_F(krrl, krrr,
796 CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
797 w0, w1, il, ir, t0, t1);
798 krll ^= w0; krlr ^= w1;
799
800 /* generate KA dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800801 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100802 /* k5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800803 subL[6] = kll; subR[6] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100804 /* k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800805 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800806 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100807 /* k11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800808 subL[14] = kll; subR[14] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100809 /* k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800810 subL[15] = krl; subR[15] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100811 /* rotation left shift 32bit */
812 /* kl5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800813 subL[24] = klr; subR[24] = krl;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100814 /* kl6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800815 subL[25] = krr; subR[25] = kll;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100816 /* rotation left shift 49 from k11,k12 -> k21,k22 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800817 ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100818 /* k21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800819 subL[28] = kll; subR[28] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100820 /* k22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800821 subL[29] = krl; subR[29] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100822
823 /* generate KB dependent subkeys */
824 /* k1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800825 subL[2] = krll; subR[2] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100826 /* k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800827 subL[3] = krrl; subR[3] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800828 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100829 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800830 subL[10] = krll; subR[10] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100831 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800832 subL[11] = krrl; subR[11] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800833 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100834 /* k15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800835 subL[20] = krll; subR[20] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100836 /* k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800837 subL[21] = krrl; subR[21] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800838 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100839 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800840 subL[32] = krll; subR[32] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100841 /* kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800842 subL[33] = krrl; subR[33] = krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100843
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800844 camellia_setup_tail(subkey, subL, subR, 32);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100845}
846
847static void camellia_setup192(const unsigned char *key, u32 *subkey)
848{
849 unsigned char kk[32];
850 u32 krll, krlr, krrl,krrr;
851
852 memcpy(kk, key, 24);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800853 memcpy((unsigned char *)&krll, key+16, 4);
854 memcpy((unsigned char *)&krlr, key+20, 4);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100855 krrl = ~krll;
856 krrr = ~krlr;
857 memcpy(kk+24, (unsigned char *)&krrl, 4);
858 memcpy(kk+28, (unsigned char *)&krrr, 4);
859 camellia_setup256(kk, subkey);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100860}
861
862
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800863/*
864 * Encrypt/decrypt
865 */
866#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
867 do { \
868 t0 = kll; \
869 t2 = krr; \
870 t0 &= ll; \
871 t2 |= rr; \
872 rl ^= t2; \
873 lr ^= ROL1(t0); \
874 t3 = krl; \
875 t1 = klr; \
876 t3 &= rl; \
877 t1 |= lr; \
878 ll ^= t1; \
879 rr ^= ROL1(t3); \
880 } while(0)
881
882#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) \
883 do { \
884 ir = camellia_sp1110[(u8)xr]; \
885 il = camellia_sp1110[ (xl >> 24)]; \
886 ir ^= camellia_sp0222[ (xr >> 24)]; \
887 il ^= camellia_sp0222[(u8)(xl >> 16)]; \
888 ir ^= camellia_sp3033[(u8)(xr >> 16)]; \
889 il ^= camellia_sp3033[(u8)(xl >> 8)]; \
890 ir ^= camellia_sp4404[(u8)(xr >> 8)]; \
891 il ^= camellia_sp4404[(u8)xl]; \
892 il ^= kl; \
893 ir ^= il ^ kr; \
894 yl ^= ir; \
895 yr ^= ROR8(il) ^ ir; \
896 } while(0)
897
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800898/* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
899static void camellia_do_encrypt(const u32 *subkey, u32 *io, unsigned max)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100900{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800901 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100902
Denys Vlasenko1721a812007-11-06 22:01:20 +0800903 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800904 io[0] ^= SUBKEY_L(0);
905 io[1] ^= SUBKEY_R(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100906
Denys Vlasenko1721a812007-11-06 22:01:20 +0800907 /* main iteration */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800908#define ROUNDS(i) do { \
909 CAMELLIA_ROUNDSM(io[0],io[1], \
910 SUBKEY_L(i + 2),SUBKEY_R(i + 2), \
911 io[2],io[3],il,ir); \
912 CAMELLIA_ROUNDSM(io[2],io[3], \
913 SUBKEY_L(i + 3),SUBKEY_R(i + 3), \
914 io[0],io[1],il,ir); \
915 CAMELLIA_ROUNDSM(io[0],io[1], \
916 SUBKEY_L(i + 4),SUBKEY_R(i + 4), \
917 io[2],io[3],il,ir); \
918 CAMELLIA_ROUNDSM(io[2],io[3], \
919 SUBKEY_L(i + 5),SUBKEY_R(i + 5), \
920 io[0],io[1],il,ir); \
921 CAMELLIA_ROUNDSM(io[0],io[1], \
922 SUBKEY_L(i + 6),SUBKEY_R(i + 6), \
923 io[2],io[3],il,ir); \
924 CAMELLIA_ROUNDSM(io[2],io[3], \
925 SUBKEY_L(i + 7),SUBKEY_R(i + 7), \
926 io[0],io[1],il,ir); \
927} while (0)
928#define FLS(i) do { \
929 CAMELLIA_FLS(io[0],io[1],io[2],io[3], \
930 SUBKEY_L(i + 0),SUBKEY_R(i + 0), \
931 SUBKEY_L(i + 1),SUBKEY_R(i + 1), \
932 t0,t1,il,ir); \
933} while (0)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100934
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800935 ROUNDS(0);
936 FLS(8);
937 ROUNDS(8);
938 FLS(16);
939 ROUNDS(16);
940 if (max == 32) {
941 FLS(24);
942 ROUNDS(24);
943 }
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100944
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800945#undef ROUNDS
946#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100947
948 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800949 io[2] ^= SUBKEY_L(max);
950 io[3] ^= SUBKEY_R(max);
951 /* NB: io[0],[1] should be swapped with [2],[3] by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100952}
953
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800954static void camellia_do_decrypt(const u32 *subkey, u32 *io, unsigned i)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100955{
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800956 u32 il,ir,t0,t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100957
Denys Vlasenko1721a812007-11-06 22:01:20 +0800958 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800959 io[0] ^= SUBKEY_L(i);
960 io[1] ^= SUBKEY_R(i);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100961
962 /* main iteration */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800963#define ROUNDS(i) do { \
964 CAMELLIA_ROUNDSM(io[0],io[1], \
965 SUBKEY_L(i + 7),SUBKEY_R(i + 7), \
966 io[2],io[3],il,ir); \
967 CAMELLIA_ROUNDSM(io[2],io[3], \
968 SUBKEY_L(i + 6),SUBKEY_R(i + 6), \
969 io[0],io[1],il,ir); \
970 CAMELLIA_ROUNDSM(io[0],io[1], \
971 SUBKEY_L(i + 5),SUBKEY_R(i + 5), \
972 io[2],io[3],il,ir); \
973 CAMELLIA_ROUNDSM(io[2],io[3], \
974 SUBKEY_L(i + 4),SUBKEY_R(i + 4), \
975 io[0],io[1],il,ir); \
976 CAMELLIA_ROUNDSM(io[0],io[1], \
977 SUBKEY_L(i + 3),SUBKEY_R(i + 3), \
978 io[2],io[3],il,ir); \
979 CAMELLIA_ROUNDSM(io[2],io[3], \
980 SUBKEY_L(i + 2),SUBKEY_R(i + 2), \
981 io[0],io[1],il,ir); \
982} while (0)
983#define FLS(i) do { \
984 CAMELLIA_FLS(io[0],io[1],io[2],io[3], \
985 SUBKEY_L(i + 1),SUBKEY_R(i + 1), \
986 SUBKEY_L(i + 0),SUBKEY_R(i + 0), \
987 t0,t1,il,ir); \
988} while (0)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100989
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800990 if (i == 32) {
991 ROUNDS(24);
992 FLS(24);
993 }
994 ROUNDS(16);
995 FLS(16);
996 ROUNDS(8);
997 FLS(8);
998 ROUNDS(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100999
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001000#undef ROUNDS
1001#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001002
1003 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001004 io[2] ^= SUBKEY_L(0);
1005 io[3] ^= SUBKEY_R(0);
1006 /* NB: 0,1 should be swapped with 2,3 by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001007}
1008
1009
Denys Vlasenko1721a812007-11-06 22:01:20 +08001010struct camellia_ctx {
1011 int key_length;
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +08001012 u32 key_table[CAMELLIA_TABLE_BYTE_LEN / sizeof(u32)];
Denys Vlasenko1721a812007-11-06 22:01:20 +08001013};
1014
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001015static int
1016camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
1017 unsigned int key_len)
1018{
1019 struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1020 const unsigned char *key = (const unsigned char *)in_key;
1021 u32 *flags = &tfm->crt_flags;
1022
1023 if (key_len != 16 && key_len != 24 && key_len != 32) {
1024 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
1025 return -EINVAL;
1026 }
1027
1028 cctx->key_length = key_len;
1029
Denys Vlasenko1721a812007-11-06 22:01:20 +08001030 switch (key_len) {
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001031 case 16:
1032 camellia_setup128(key, cctx->key_table);
1033 break;
1034 case 24:
1035 camellia_setup192(key, cctx->key_table);
1036 break;
1037 case 32:
1038 camellia_setup256(key, cctx->key_table);
1039 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001040 }
1041
1042 return 0;
1043}
1044
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001045static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1046{
1047 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1048 const __be32 *src = (const __be32 *)in;
1049 __be32 *dst = (__be32 *)out;
1050
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001051 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001052
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001053 tmp[0] = be32_to_cpu(src[0]);
1054 tmp[1] = be32_to_cpu(src[1]);
1055 tmp[2] = be32_to_cpu(src[2]);
1056 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001057
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001058 camellia_do_encrypt(cctx->key_table, tmp,
1059 cctx->key_length == 16 ? 24 : 32 /* for key lengths of 24 and 32 */
1060 );
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001061
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001062 /* do_encrypt returns 0,1 swapped with 2,3 */
1063 dst[0] = cpu_to_be32(tmp[2]);
1064 dst[1] = cpu_to_be32(tmp[3]);
1065 dst[2] = cpu_to_be32(tmp[0]);
1066 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001067}
1068
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001069static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1070{
1071 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1072 const __be32 *src = (const __be32 *)in;
1073 __be32 *dst = (__be32 *)out;
1074
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001075 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001076
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001077 tmp[0] = be32_to_cpu(src[0]);
1078 tmp[1] = be32_to_cpu(src[1]);
1079 tmp[2] = be32_to_cpu(src[2]);
1080 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001081
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001082 camellia_do_decrypt(cctx->key_table, tmp,
1083 cctx->key_length == 16 ? 24 : 32 /* for key lengths of 24 and 32 */
1084 );
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001085
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001086 /* do_decrypt returns 0,1 swapped with 2,3 */
1087 dst[0] = cpu_to_be32(tmp[2]);
1088 dst[1] = cpu_to_be32(tmp[3]);
1089 dst[2] = cpu_to_be32(tmp[0]);
1090 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001091}
1092
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001093static struct crypto_alg camellia_alg = {
1094 .cra_name = "camellia",
1095 .cra_driver_name = "camellia-generic",
1096 .cra_priority = 100,
1097 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
1098 .cra_blocksize = CAMELLIA_BLOCK_SIZE,
1099 .cra_ctxsize = sizeof(struct camellia_ctx),
1100 .cra_alignmask = 3,
1101 .cra_module = THIS_MODULE,
1102 .cra_list = LIST_HEAD_INIT(camellia_alg.cra_list),
1103 .cra_u = {
1104 .cipher = {
1105 .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
1106 .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
1107 .cia_setkey = camellia_set_key,
1108 .cia_encrypt = camellia_encrypt,
1109 .cia_decrypt = camellia_decrypt
1110 }
1111 }
1112};
1113
1114static int __init camellia_init(void)
1115{
1116 return crypto_register_alg(&camellia_alg);
1117}
1118
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001119static void __exit camellia_fini(void)
1120{
1121 crypto_unregister_alg(&camellia_alg);
1122}
1123
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001124module_init(camellia_init);
1125module_exit(camellia_fini);
1126
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001127MODULE_DESCRIPTION("Camellia Cipher Algorithm");
1128MODULE_LICENSE("GPL");