blob: 7ae4bcddd1de336dfbabf8c1ad18c7e113d2e7c9 [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 Harrison32bd78e2008-10-12 20:40:12 +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] = {
Richard Hartmann621dd362010-02-16 20:27:57 +080042 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,
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100106};
107
108static const u32 camellia_sp0222[256] = {
Richard Hartmann621dd362010-02-16 20:27:57 +0800109 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,
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100173};
174
175static const u32 camellia_sp3033[256] = {
Richard Hartmann621dd362010-02-16 20:27:57 +0800176 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,
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100240};
241
242static const u32 camellia_sp4404[256] = {
Richard Hartmann621dd362010-02-16 20:27:57 +0800243 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,
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100307};
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)); \
Richard Hartmann621dd362010-02-16 20:27:57 +0800347 } while (0)
Denys Vlasenko1721a812007-11-06 22:01:20 +0800348
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)); \
Richard Hartmann621dd362010-02-16 20:27:57 +0800357 } while (0)
Denys Vlasenko1721a812007-11-06 22:01:20 +0800358
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 Harrison32bd78e2008-10-12 20:40:12 +0800374 yr = ror32(yr, 8); \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800375 yr ^= yl; \
Richard Hartmann621dd362010-02-16 20:27:57 +0800376 } while (0)
Denys Vlasenko1721a812007-11-06 22:01:20 +0800377
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
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800386 /* absorb kw2 to other subkeys */
387 /* round 2 */
388 subL[3] ^= subL[1]; subR[3] ^= subR[1];
389 /* round 4 */
390 subL[5] ^= subL[1]; subR[5] ^= subR[1];
391 /* round 6 */
392 subL[7] ^= subL[1]; subR[7] ^= subR[1];
393 subL[1] ^= subR[1] & ~subR[9];
394 dw = subL[1] & subL[9],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800395 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl2) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800396 /* round 8 */
397 subL[11] ^= subL[1]; subR[11] ^= subR[1];
398 /* round 10 */
399 subL[13] ^= subL[1]; subR[13] ^= subR[1];
400 /* round 12 */
401 subL[15] ^= subL[1]; subR[15] ^= subR[1];
402 subL[1] ^= subR[1] & ~subR[17];
403 dw = subL[1] & subL[17],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800404 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl4) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800405 /* round 14 */
406 subL[19] ^= subL[1]; subR[19] ^= subR[1];
407 /* round 16 */
408 subL[21] ^= subL[1]; subR[21] ^= subR[1];
409 /* round 18 */
410 subL[23] ^= subL[1]; subR[23] ^= subR[1];
411 if (max == 24) {
412 /* kw3 */
413 subL[24] ^= subL[1]; subR[24] ^= subR[1];
414
415 /* absorb kw4 to other subkeys */
416 kw4l = subL[25]; kw4r = subR[25];
417 } else {
418 subL[1] ^= subR[1] & ~subR[25];
419 dw = subL[1] & subL[25],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800420 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl6) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800421 /* round 20 */
422 subL[27] ^= subL[1]; subR[27] ^= subR[1];
423 /* round 22 */
424 subL[29] ^= subL[1]; subR[29] ^= subR[1];
425 /* round 24 */
426 subL[31] ^= subL[1]; subR[31] ^= subR[1];
427 /* kw3 */
428 subL[32] ^= subL[1]; subR[32] ^= subR[1];
429
430 /* absorb kw4 to other subkeys */
431 kw4l = subL[33]; kw4r = subR[33];
432 /* round 23 */
433 subL[30] ^= kw4l; subR[30] ^= kw4r;
434 /* round 21 */
435 subL[28] ^= kw4l; subR[28] ^= kw4r;
436 /* round 19 */
437 subL[26] ^= kw4l; subR[26] ^= kw4r;
438 kw4l ^= kw4r & ~subR[24];
439 dw = kw4l & subL[24],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800440 kw4r ^= rol32(dw, 1); /* modified for FL(kl5) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800441 }
442 /* round 17 */
443 subL[22] ^= kw4l; subR[22] ^= kw4r;
444 /* round 15 */
445 subL[20] ^= kw4l; subR[20] ^= kw4r;
446 /* round 13 */
447 subL[18] ^= kw4l; subR[18] ^= kw4r;
448 kw4l ^= kw4r & ~subR[16];
449 dw = kw4l & subL[16],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800450 kw4r ^= rol32(dw, 1); /* modified for FL(kl3) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800451 /* round 11 */
452 subL[14] ^= kw4l; subR[14] ^= kw4r;
453 /* round 9 */
454 subL[12] ^= kw4l; subR[12] ^= kw4r;
455 /* round 7 */
456 subL[10] ^= kw4l; subR[10] ^= kw4r;
457 kw4l ^= kw4r & ~subR[8];
458 dw = kw4l & subL[8],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800459 kw4r ^= rol32(dw, 1); /* modified for FL(kl1) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800460 /* round 5 */
461 subL[6] ^= kw4l; subR[6] ^= kw4r;
462 /* round 3 */
463 subL[4] ^= kw4l; subR[4] ^= kw4r;
464 /* round 1 */
465 subL[2] ^= kw4l; subR[2] ^= kw4r;
466 /* kw1 */
467 subL[0] ^= kw4l; subR[0] ^= kw4r;
468
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800469 /* key XOR is end of F-function */
470 SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
471 SUBKEY_R(0) = subR[0] ^ subR[2];
472 SUBKEY_L(2) = subL[3]; /* round 1 */
473 SUBKEY_R(2) = subR[3];
474 SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
475 SUBKEY_R(3) = subR[2] ^ subR[4];
476 SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
477 SUBKEY_R(4) = subR[3] ^ subR[5];
478 SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
479 SUBKEY_R(5) = subR[4] ^ subR[6];
480 SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
481 SUBKEY_R(6) = subR[5] ^ subR[7];
482 tl = subL[10] ^ (subR[10] & ~subR[8]);
483 dw = tl & subL[8], /* FL(kl1) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800484 tr = subR[10] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800485 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
486 SUBKEY_R(7) = subR[6] ^ tr;
487 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
488 SUBKEY_R(8) = subR[8];
489 SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
490 SUBKEY_R(9) = subR[9];
491 tl = subL[7] ^ (subR[7] & ~subR[9]);
492 dw = tl & subL[9], /* FLinv(kl2) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800493 tr = subR[7] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800494 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
495 SUBKEY_R(10) = tr ^ subR[11];
496 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
497 SUBKEY_R(11) = subR[10] ^ subR[12];
498 SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
499 SUBKEY_R(12) = subR[11] ^ subR[13];
500 SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
501 SUBKEY_R(13) = subR[12] ^ subR[14];
502 SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
503 SUBKEY_R(14) = subR[13] ^ subR[15];
504 tl = subL[18] ^ (subR[18] & ~subR[16]);
505 dw = tl & subL[16], /* FL(kl3) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800506 tr = subR[18] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800507 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
508 SUBKEY_R(15) = subR[14] ^ tr;
509 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
510 SUBKEY_R(16) = subR[16];
511 SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
512 SUBKEY_R(17) = subR[17];
513 tl = subL[15] ^ (subR[15] & ~subR[17]);
514 dw = tl & subL[17], /* FLinv(kl4) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800515 tr = subR[15] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800516 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
517 SUBKEY_R(18) = tr ^ subR[19];
518 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
519 SUBKEY_R(19) = subR[18] ^ subR[20];
520 SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
521 SUBKEY_R(20) = subR[19] ^ subR[21];
522 SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
523 SUBKEY_R(21) = subR[20] ^ subR[22];
524 SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
525 SUBKEY_R(22) = subR[21] ^ subR[23];
526 if (max == 24) {
527 SUBKEY_L(23) = subL[22]; /* round 18 */
528 SUBKEY_R(23) = subR[22];
529 SUBKEY_L(24) = subL[24] ^ subL[23]; /* kw3 */
530 SUBKEY_R(24) = subR[24] ^ subR[23];
531 } else {
532 tl = subL[26] ^ (subR[26] & ~subR[24]);
533 dw = tl & subL[24], /* FL(kl5) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800534 tr = subR[26] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800535 SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
536 SUBKEY_R(23) = subR[22] ^ tr;
537 SUBKEY_L(24) = subL[24]; /* FL(kl5) */
538 SUBKEY_R(24) = subR[24];
539 SUBKEY_L(25) = subL[25]; /* FLinv(kl6) */
540 SUBKEY_R(25) = subR[25];
541 tl = subL[23] ^ (subR[23] & ~subR[25]);
542 dw = tl & subL[25], /* FLinv(kl6) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800543 tr = subR[23] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800544 SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
545 SUBKEY_R(26) = tr ^ subR[27];
546 SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
547 SUBKEY_R(27) = subR[26] ^ subR[28];
548 SUBKEY_L(28) = subL[27] ^ subL[29]; /* round 21 */
549 SUBKEY_R(28) = subR[27] ^ subR[29];
550 SUBKEY_L(29) = subL[28] ^ subL[30]; /* round 22 */
551 SUBKEY_R(29) = subR[28] ^ subR[30];
552 SUBKEY_L(30) = subL[29] ^ subL[31]; /* round 23 */
553 SUBKEY_R(30) = subR[29] ^ subR[31];
554 SUBKEY_L(31) = subL[30]; /* round 24 */
555 SUBKEY_R(31) = subR[30];
556 SUBKEY_L(32) = subL[32] ^ subL[31]; /* kw3 */
557 SUBKEY_R(32) = subR[32] ^ subR[31];
558 }
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800559}
560
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100561static void camellia_setup128(const unsigned char *key, u32 *subkey)
562{
563 u32 kll, klr, krl, krr;
564 u32 il, ir, t0, t1, w0, w1;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100565 u32 subL[26];
566 u32 subR[26];
567
568 /**
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800569 * k == kll || klr || krl || krr (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100570 */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800571 kll = get_unaligned_be32(key);
572 klr = get_unaligned_be32(key + 4);
573 krl = get_unaligned_be32(key + 8);
574 krr = get_unaligned_be32(key + 12);
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800575
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800576 /* generate KL dependent subkeys */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100577 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800578 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100579 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800580 subL[1] = krl; subR[1] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100581 /* rotation left shift 15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800582 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100583 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800584 subL[4] = kll; subR[4] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100585 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800586 subL[5] = krl; subR[5] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100587 /* rotation left shift 15+30bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800588 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100589 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800590 subL[10] = kll; subR[10] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100591 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800592 subL[11] = krl; subR[11] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100593 /* rotation left shift 15+30+15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800594 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100595 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800596 subL[13] = krl; subR[13] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100597 /* rotation left shift 15+30+15+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800598 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100599 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800600 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100601 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800602 subL[17] = krl; subR[17] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100603 /* rotation left shift 15+30+15+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800604 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100605 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800606 subL[18] = kll; subR[18] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100607 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800608 subL[19] = krl; subR[19] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100609 /* rotation left shift 15+30+15+17+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800610 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100611 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800612 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100613 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800614 subL[23] = krl; subR[23] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100615
616 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800617 kll = subL[0]; klr = subR[0];
618 krl = subL[1]; krr = subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100619 CAMELLIA_F(kll, klr,
620 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
621 w0, w1, il, ir, t0, t1);
622 krl ^= w0; krr ^= w1;
623 CAMELLIA_F(krl, krr,
624 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
625 kll, klr, il, ir, t0, t1);
626 /* current status == (kll, klr, w0, w1) */
627 CAMELLIA_F(kll, klr,
628 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
629 krl, krr, il, ir, t0, t1);
630 krl ^= w0; krr ^= w1;
631 CAMELLIA_F(krl, krr,
632 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
633 w0, w1, il, ir, t0, t1);
634 kll ^= w0; klr ^= w1;
635
636 /* generate KA dependent subkeys */
637 /* k1, k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800638 subL[2] = kll; subR[2] = klr;
639 subL[3] = krl; subR[3] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800640 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100641 /* k5,k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800642 subL[6] = kll; subR[6] = klr;
643 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800644 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100645 /* kl1, kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800646 subL[8] = kll; subR[8] = klr;
647 subL[9] = krl; subR[9] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800648 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100649 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800650 subL[12] = kll; subR[12] = klr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800651 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100652 /* k11, k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800653 subL[14] = kll; subR[14] = klr;
654 subL[15] = krl; subR[15] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800655 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100656 /* k15, k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800657 subL[20] = kll; subR[20] = klr;
658 subL[21] = krl; subR[21] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800659 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100660 /* kw3, kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800661 subL[24] = kll; subR[24] = klr;
662 subL[25] = krl; subR[25] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100663
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800664 camellia_setup_tail(subkey, subL, subR, 24);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100665}
666
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100667static void camellia_setup256(const unsigned char *key, u32 *subkey)
668{
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800669 u32 kll, klr, krl, krr; /* left half of key */
670 u32 krll, krlr, krrl, krrr; /* right half of key */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100671 u32 il, ir, t0, t1, w0, w1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100672 u32 subL[34];
673 u32 subR[34];
674
675 /**
676 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800677 * (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100678 */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800679 kll = get_unaligned_be32(key);
680 klr = get_unaligned_be32(key + 4);
681 krl = get_unaligned_be32(key + 8);
682 krr = get_unaligned_be32(key + 12);
683 krll = get_unaligned_be32(key + 16);
684 krlr = get_unaligned_be32(key + 20);
685 krrl = get_unaligned_be32(key + 24);
686 krrr = get_unaligned_be32(key + 28);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100687
688 /* generate KL dependent subkeys */
689 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800690 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100691 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800692 subL[1] = krl; subR[1] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800693 ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100694 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800695 subL[12] = kll; subR[12] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100696 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800697 subL[13] = krl; subR[13] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800698 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100699 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800700 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100701 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800702 subL[17] = krl; subR[17] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800703 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100704 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800705 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100706 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800707 subL[23] = krl; subR[23] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800708 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100709 /* k23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800710 subL[30] = kll; subR[30] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100711 /* k24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800712 subL[31] = krl; subR[31] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100713
714 /* generate KR dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800715 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100716 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800717 subL[4] = krll; subR[4] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100718 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800719 subL[5] = krrl; subR[5] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800720 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100721 /* kl1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800722 subL[8] = krll; subR[8] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100723 /* kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800724 subL[9] = krrl; subR[9] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800725 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100726 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800727 subL[18] = krll; subR[18] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100728 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800729 subL[19] = krrl; subR[19] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800730 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100731 /* k19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800732 subL[26] = krll; subR[26] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100733 /* k20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800734 subL[27] = krrl; subR[27] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800735 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100736
737 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800738 kll = subL[0] ^ krll; klr = subR[0] ^ krlr;
739 krl = subL[1] ^ krrl; krr = subR[1] ^ krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100740 CAMELLIA_F(kll, klr,
741 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
742 w0, w1, il, ir, t0, t1);
743 krl ^= w0; krr ^= w1;
744 CAMELLIA_F(krl, krr,
745 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
746 kll, klr, il, ir, t0, t1);
747 kll ^= krll; klr ^= krlr;
748 CAMELLIA_F(kll, klr,
749 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
750 krl, krr, il, ir, t0, t1);
751 krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
752 CAMELLIA_F(krl, krr,
753 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
754 w0, w1, il, ir, t0, t1);
755 kll ^= w0; klr ^= w1;
756
757 /* generate KB */
758 krll ^= kll; krlr ^= klr;
759 krrl ^= krl; krrr ^= krr;
760 CAMELLIA_F(krll, krlr,
761 CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
762 w0, w1, il, ir, t0, t1);
763 krrl ^= w0; krrr ^= w1;
764 CAMELLIA_F(krrl, krrr,
765 CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
766 w0, w1, il, ir, t0, t1);
767 krll ^= w0; krlr ^= w1;
768
769 /* generate KA dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800770 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100771 /* k5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800772 subL[6] = kll; subR[6] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100773 /* k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800774 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800775 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100776 /* k11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800777 subL[14] = kll; subR[14] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100778 /* k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800779 subL[15] = krl; subR[15] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100780 /* rotation left shift 32bit */
781 /* kl5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800782 subL[24] = klr; subR[24] = krl;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100783 /* kl6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800784 subL[25] = krr; subR[25] = kll;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100785 /* rotation left shift 49 from k11,k12 -> k21,k22 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800786 ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100787 /* k21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800788 subL[28] = kll; subR[28] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100789 /* k22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800790 subL[29] = krl; subR[29] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100791
792 /* generate KB dependent subkeys */
793 /* k1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800794 subL[2] = krll; subR[2] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100795 /* k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800796 subL[3] = krrl; subR[3] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800797 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100798 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800799 subL[10] = krll; subR[10] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100800 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800801 subL[11] = krrl; subR[11] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800802 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100803 /* k15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800804 subL[20] = krll; subR[20] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100805 /* k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800806 subL[21] = krrl; subR[21] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800807 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100808 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800809 subL[32] = krll; subR[32] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100810 /* kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800811 subL[33] = krrl; subR[33] = krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100812
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800813 camellia_setup_tail(subkey, subL, subR, 32);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100814}
815
816static void camellia_setup192(const unsigned char *key, u32 *subkey)
817{
818 unsigned char kk[32];
Richard Hartmann621dd362010-02-16 20:27:57 +0800819 u32 krll, krlr, krrl, krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100820
821 memcpy(kk, key, 24);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800822 memcpy((unsigned char *)&krll, key+16, 4);
823 memcpy((unsigned char *)&krlr, key+20, 4);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100824 krrl = ~krll;
825 krrr = ~krlr;
826 memcpy(kk+24, (unsigned char *)&krrl, 4);
827 memcpy(kk+28, (unsigned char *)&krrr, 4);
828 camellia_setup256(kk, subkey);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100829}
830
831
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800832/*
833 * Encrypt/decrypt
834 */
835#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
836 do { \
837 t0 = kll; \
838 t2 = krr; \
839 t0 &= ll; \
840 t2 |= rr; \
841 rl ^= t2; \
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800842 lr ^= rol32(t0, 1); \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800843 t3 = krl; \
844 t1 = klr; \
845 t3 &= rl; \
846 t1 |= lr; \
847 ll ^= t1; \
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800848 rr ^= rol32(t3, 1); \
Richard Hartmann621dd362010-02-16 20:27:57 +0800849 } while (0)
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800850
851#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) \
852 do { \
Jussi Kivilinnac9b56d32012-03-03 13:59:00 +0200853 yl ^= kl; \
854 yr ^= kr; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800855 ir = camellia_sp1110[(u8)xr]; \
856 il = camellia_sp1110[ (xl >> 24)]; \
857 ir ^= camellia_sp0222[ (xr >> 24)]; \
858 il ^= camellia_sp0222[(u8)(xl >> 16)]; \
859 ir ^= camellia_sp3033[(u8)(xr >> 16)]; \
860 il ^= camellia_sp3033[(u8)(xl >> 8)]; \
861 ir ^= camellia_sp4404[(u8)(xr >> 8)]; \
862 il ^= camellia_sp4404[(u8)xl]; \
Jussi Kivilinnac9b56d32012-03-03 13:59:00 +0200863 ir ^= il; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800864 yl ^= ir; \
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800865 yr ^= ror32(il, 8) ^ ir; \
Richard Hartmann621dd362010-02-16 20:27:57 +0800866 } while (0)
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800867
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800868/* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
869static void camellia_do_encrypt(const u32 *subkey, u32 *io, unsigned max)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100870{
Richard Hartmann621dd362010-02-16 20:27:57 +0800871 u32 il, ir, t0, t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100872
Denys Vlasenko1721a812007-11-06 22:01:20 +0800873 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800874 io[0] ^= SUBKEY_L(0);
875 io[1] ^= SUBKEY_R(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100876
Denys Vlasenko1721a812007-11-06 22:01:20 +0800877 /* main iteration */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800878#define ROUNDS(i) do { \
Richard Hartmann621dd362010-02-16 20:27:57 +0800879 CAMELLIA_ROUNDSM(io[0], io[1], \
880 SUBKEY_L(i + 2), SUBKEY_R(i + 2), \
881 io[2], io[3], il, ir); \
882 CAMELLIA_ROUNDSM(io[2], io[3], \
883 SUBKEY_L(i + 3), SUBKEY_R(i + 3), \
884 io[0], io[1], il, ir); \
885 CAMELLIA_ROUNDSM(io[0], io[1], \
886 SUBKEY_L(i + 4), SUBKEY_R(i + 4), \
887 io[2], io[3], il, ir); \
888 CAMELLIA_ROUNDSM(io[2], io[3], \
889 SUBKEY_L(i + 5), SUBKEY_R(i + 5), \
890 io[0], io[1], il, ir); \
891 CAMELLIA_ROUNDSM(io[0], io[1], \
892 SUBKEY_L(i + 6), SUBKEY_R(i + 6), \
893 io[2], io[3], il, ir); \
894 CAMELLIA_ROUNDSM(io[2], io[3], \
895 SUBKEY_L(i + 7), SUBKEY_R(i + 7), \
896 io[0], io[1], il, ir); \
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800897} while (0)
898#define FLS(i) do { \
Richard Hartmann621dd362010-02-16 20:27:57 +0800899 CAMELLIA_FLS(io[0], io[1], io[2], io[3], \
900 SUBKEY_L(i + 0), SUBKEY_R(i + 0), \
901 SUBKEY_L(i + 1), SUBKEY_R(i + 1), \
902 t0, t1, il, ir); \
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800903} while (0)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100904
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800905 ROUNDS(0);
906 FLS(8);
907 ROUNDS(8);
908 FLS(16);
909 ROUNDS(16);
910 if (max == 32) {
911 FLS(24);
912 ROUNDS(24);
913 }
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100914
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800915#undef ROUNDS
916#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100917
918 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800919 io[2] ^= SUBKEY_L(max);
920 io[3] ^= SUBKEY_R(max);
921 /* NB: io[0],[1] should be swapped with [2],[3] by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100922}
923
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800924static void camellia_do_decrypt(const u32 *subkey, u32 *io, unsigned i)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100925{
Richard Hartmann621dd362010-02-16 20:27:57 +0800926 u32 il, ir, t0, t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100927
Denys Vlasenko1721a812007-11-06 22:01:20 +0800928 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800929 io[0] ^= SUBKEY_L(i);
930 io[1] ^= SUBKEY_R(i);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100931
932 /* main iteration */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800933#define ROUNDS(i) do { \
Richard Hartmann621dd362010-02-16 20:27:57 +0800934 CAMELLIA_ROUNDSM(io[0], io[1], \
935 SUBKEY_L(i + 7), SUBKEY_R(i + 7), \
936 io[2], io[3], il, ir); \
937 CAMELLIA_ROUNDSM(io[2], io[3], \
938 SUBKEY_L(i + 6), SUBKEY_R(i + 6), \
939 io[0], io[1], il, ir); \
940 CAMELLIA_ROUNDSM(io[0], io[1], \
941 SUBKEY_L(i + 5), SUBKEY_R(i + 5), \
942 io[2], io[3], il, ir); \
943 CAMELLIA_ROUNDSM(io[2], io[3], \
944 SUBKEY_L(i + 4), SUBKEY_R(i + 4), \
945 io[0], io[1], il, ir); \
946 CAMELLIA_ROUNDSM(io[0], io[1], \
947 SUBKEY_L(i + 3), SUBKEY_R(i + 3), \
948 io[2], io[3], il, ir); \
949 CAMELLIA_ROUNDSM(io[2], io[3], \
950 SUBKEY_L(i + 2), SUBKEY_R(i + 2), \
951 io[0], io[1], il, ir); \
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800952} while (0)
953#define FLS(i) do { \
Richard Hartmann621dd362010-02-16 20:27:57 +0800954 CAMELLIA_FLS(io[0], io[1], io[2], io[3], \
955 SUBKEY_L(i + 1), SUBKEY_R(i + 1), \
956 SUBKEY_L(i + 0), SUBKEY_R(i + 0), \
957 t0, t1, il, ir); \
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800958} while (0)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100959
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800960 if (i == 32) {
961 ROUNDS(24);
962 FLS(24);
963 }
964 ROUNDS(16);
965 FLS(16);
966 ROUNDS(8);
967 FLS(8);
968 ROUNDS(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100969
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800970#undef ROUNDS
971#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100972
973 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800974 io[2] ^= SUBKEY_L(0);
975 io[3] ^= SUBKEY_R(0);
976 /* NB: 0,1 should be swapped with 2,3 by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100977}
978
979
Denys Vlasenko1721a812007-11-06 22:01:20 +0800980struct camellia_ctx {
981 int key_length;
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800982 u32 key_table[CAMELLIA_TABLE_BYTE_LEN / sizeof(u32)];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800983};
984
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100985static int
986camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
987 unsigned int key_len)
988{
989 struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
990 const unsigned char *key = (const unsigned char *)in_key;
991 u32 *flags = &tfm->crt_flags;
992
993 if (key_len != 16 && key_len != 24 && key_len != 32) {
994 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
995 return -EINVAL;
996 }
997
998 cctx->key_length = key_len;
999
Denys Vlasenko1721a812007-11-06 22:01:20 +08001000 switch (key_len) {
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001001 case 16:
1002 camellia_setup128(key, cctx->key_table);
1003 break;
1004 case 24:
1005 camellia_setup192(key, cctx->key_table);
1006 break;
1007 case 32:
1008 camellia_setup256(key, cctx->key_table);
1009 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001010 }
1011
1012 return 0;
1013}
1014
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001015static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1016{
1017 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1018 const __be32 *src = (const __be32 *)in;
1019 __be32 *dst = (__be32 *)out;
1020
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001021 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001022
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001023 tmp[0] = be32_to_cpu(src[0]);
1024 tmp[1] = be32_to_cpu(src[1]);
1025 tmp[2] = be32_to_cpu(src[2]);
1026 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001027
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001028 camellia_do_encrypt(cctx->key_table, tmp,
1029 cctx->key_length == 16 ? 24 : 32 /* for key lengths of 24 and 32 */
1030 );
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001031
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001032 /* do_encrypt returns 0,1 swapped with 2,3 */
1033 dst[0] = cpu_to_be32(tmp[2]);
1034 dst[1] = cpu_to_be32(tmp[3]);
1035 dst[2] = cpu_to_be32(tmp[0]);
1036 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001037}
1038
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001039static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1040{
1041 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1042 const __be32 *src = (const __be32 *)in;
1043 __be32 *dst = (__be32 *)out;
1044
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001045 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001046
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001047 tmp[0] = be32_to_cpu(src[0]);
1048 tmp[1] = be32_to_cpu(src[1]);
1049 tmp[2] = be32_to_cpu(src[2]);
1050 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001051
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001052 camellia_do_decrypt(cctx->key_table, tmp,
1053 cctx->key_length == 16 ? 24 : 32 /* for key lengths of 24 and 32 */
1054 );
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001055
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001056 /* do_decrypt returns 0,1 swapped with 2,3 */
1057 dst[0] = cpu_to_be32(tmp[2]);
1058 dst[1] = cpu_to_be32(tmp[3]);
1059 dst[2] = cpu_to_be32(tmp[0]);
1060 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001061}
1062
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001063static struct crypto_alg camellia_alg = {
1064 .cra_name = "camellia",
1065 .cra_driver_name = "camellia-generic",
1066 .cra_priority = 100,
1067 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
1068 .cra_blocksize = CAMELLIA_BLOCK_SIZE,
1069 .cra_ctxsize = sizeof(struct camellia_ctx),
1070 .cra_alignmask = 3,
1071 .cra_module = THIS_MODULE,
1072 .cra_list = LIST_HEAD_INIT(camellia_alg.cra_list),
1073 .cra_u = {
1074 .cipher = {
1075 .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
1076 .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
1077 .cia_setkey = camellia_set_key,
1078 .cia_encrypt = camellia_encrypt,
1079 .cia_decrypt = camellia_decrypt
1080 }
1081 }
1082};
1083
1084static int __init camellia_init(void)
1085{
1086 return crypto_register_alg(&camellia_alg);
1087}
1088
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001089static void __exit camellia_fini(void)
1090{
1091 crypto_unregister_alg(&camellia_alg);
1092}
1093
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001094module_init(camellia_init);
1095module_exit(camellia_fini);
1096
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001097MODULE_DESCRIPTION("Camellia Cipher Algorithm");
1098MODULE_LICENSE("GPL");