blob: f7aaaaf869829c553cc34c90403b81a367762894 [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 */
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200340#define ROLDQ(ll, lr, rl, rr, w0, w1, bits) ({ \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800341 w0 = ll; \
342 ll = (ll << bits) + (lr >> (32 - bits)); \
343 lr = (lr << bits) + (rl >> (32 - bits)); \
344 rl = (rl << bits) + (rr >> (32 - bits)); \
345 rr = (rr << bits) + (w0 >> (32 - bits)); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200346})
Denys Vlasenko1721a812007-11-06 22:01:20 +0800347
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200348#define ROLDQo32(ll, lr, rl, rr, w0, w1, bits) ({ \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800349 w0 = ll; \
350 w1 = lr; \
351 ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
352 lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
353 rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
354 rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200355})
Denys Vlasenko1721a812007-11-06 22:01:20 +0800356
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200357#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) ({ \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800358 il = xl ^ kl; \
359 ir = xr ^ kr; \
360 t0 = il >> 16; \
361 t1 = ir >> 16; \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200362 yl = camellia_sp1110[(u8)(ir)] \
363 ^ camellia_sp0222[(u8)(t1 >> 8)] \
364 ^ camellia_sp3033[(u8)(t1)] \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800365 ^ camellia_sp4404[(u8)(ir >> 8)]; \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200366 yr = camellia_sp1110[(u8)(t0 >> 8)] \
367 ^ camellia_sp0222[(u8)(t0)] \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800368 ^ camellia_sp3033[(u8)(il >> 8)] \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200369 ^ camellia_sp4404[(u8)(il)]; \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800370 yl ^= yr; \
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800371 yr = ror32(yr, 8); \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800372 yr ^= yl; \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200373})
Denys Vlasenko1721a812007-11-06 22:01:20 +0800374
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800375#define SUBKEY_L(INDEX) (subkey[(INDEX)*2])
376#define SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1])
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100377
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800378static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800379{
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800380 u32 dw, tl, tr;
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800381 u32 kw4l, kw4r;
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800382
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800383 /* absorb kw2 to other subkeys */
384 /* round 2 */
385 subL[3] ^= subL[1]; subR[3] ^= subR[1];
386 /* round 4 */
387 subL[5] ^= subL[1]; subR[5] ^= subR[1];
388 /* round 6 */
389 subL[7] ^= subL[1]; subR[7] ^= subR[1];
390 subL[1] ^= subR[1] & ~subR[9];
391 dw = subL[1] & subL[9],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800392 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl2) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800393 /* round 8 */
394 subL[11] ^= subL[1]; subR[11] ^= subR[1];
395 /* round 10 */
396 subL[13] ^= subL[1]; subR[13] ^= subR[1];
397 /* round 12 */
398 subL[15] ^= subL[1]; subR[15] ^= subR[1];
399 subL[1] ^= subR[1] & ~subR[17];
400 dw = subL[1] & subL[17],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800401 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl4) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800402 /* round 14 */
403 subL[19] ^= subL[1]; subR[19] ^= subR[1];
404 /* round 16 */
405 subL[21] ^= subL[1]; subR[21] ^= subR[1];
406 /* round 18 */
407 subL[23] ^= subL[1]; subR[23] ^= subR[1];
408 if (max == 24) {
409 /* kw3 */
410 subL[24] ^= subL[1]; subR[24] ^= subR[1];
411
412 /* absorb kw4 to other subkeys */
413 kw4l = subL[25]; kw4r = subR[25];
414 } else {
415 subL[1] ^= subR[1] & ~subR[25];
416 dw = subL[1] & subL[25],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800417 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl6) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800418 /* round 20 */
419 subL[27] ^= subL[1]; subR[27] ^= subR[1];
420 /* round 22 */
421 subL[29] ^= subL[1]; subR[29] ^= subR[1];
422 /* round 24 */
423 subL[31] ^= subL[1]; subR[31] ^= subR[1];
424 /* kw3 */
425 subL[32] ^= subL[1]; subR[32] ^= subR[1];
426
427 /* absorb kw4 to other subkeys */
428 kw4l = subL[33]; kw4r = subR[33];
429 /* round 23 */
430 subL[30] ^= kw4l; subR[30] ^= kw4r;
431 /* round 21 */
432 subL[28] ^= kw4l; subR[28] ^= kw4r;
433 /* round 19 */
434 subL[26] ^= kw4l; subR[26] ^= kw4r;
435 kw4l ^= kw4r & ~subR[24];
436 dw = kw4l & subL[24],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800437 kw4r ^= rol32(dw, 1); /* modified for FL(kl5) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800438 }
439 /* round 17 */
440 subL[22] ^= kw4l; subR[22] ^= kw4r;
441 /* round 15 */
442 subL[20] ^= kw4l; subR[20] ^= kw4r;
443 /* round 13 */
444 subL[18] ^= kw4l; subR[18] ^= kw4r;
445 kw4l ^= kw4r & ~subR[16];
446 dw = kw4l & subL[16],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800447 kw4r ^= rol32(dw, 1); /* modified for FL(kl3) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800448 /* round 11 */
449 subL[14] ^= kw4l; subR[14] ^= kw4r;
450 /* round 9 */
451 subL[12] ^= kw4l; subR[12] ^= kw4r;
452 /* round 7 */
453 subL[10] ^= kw4l; subR[10] ^= kw4r;
454 kw4l ^= kw4r & ~subR[8];
455 dw = kw4l & subL[8],
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800456 kw4r ^= rol32(dw, 1); /* modified for FL(kl1) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800457 /* round 5 */
458 subL[6] ^= kw4l; subR[6] ^= kw4r;
459 /* round 3 */
460 subL[4] ^= kw4l; subR[4] ^= kw4r;
461 /* round 1 */
462 subL[2] ^= kw4l; subR[2] ^= kw4r;
463 /* kw1 */
464 subL[0] ^= kw4l; subR[0] ^= kw4r;
465
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800466 /* key XOR is end of F-function */
467 SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
468 SUBKEY_R(0) = subR[0] ^ subR[2];
469 SUBKEY_L(2) = subL[3]; /* round 1 */
470 SUBKEY_R(2) = subR[3];
471 SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
472 SUBKEY_R(3) = subR[2] ^ subR[4];
473 SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
474 SUBKEY_R(4) = subR[3] ^ subR[5];
475 SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
476 SUBKEY_R(5) = subR[4] ^ subR[6];
477 SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
478 SUBKEY_R(6) = subR[5] ^ subR[7];
479 tl = subL[10] ^ (subR[10] & ~subR[8]);
480 dw = tl & subL[8], /* FL(kl1) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800481 tr = subR[10] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800482 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
483 SUBKEY_R(7) = subR[6] ^ tr;
484 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
485 SUBKEY_R(8) = subR[8];
486 SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
487 SUBKEY_R(9) = subR[9];
488 tl = subL[7] ^ (subR[7] & ~subR[9]);
489 dw = tl & subL[9], /* FLinv(kl2) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800490 tr = subR[7] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800491 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
492 SUBKEY_R(10) = tr ^ subR[11];
493 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
494 SUBKEY_R(11) = subR[10] ^ subR[12];
495 SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
496 SUBKEY_R(12) = subR[11] ^ subR[13];
497 SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
498 SUBKEY_R(13) = subR[12] ^ subR[14];
499 SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
500 SUBKEY_R(14) = subR[13] ^ subR[15];
501 tl = subL[18] ^ (subR[18] & ~subR[16]);
502 dw = tl & subL[16], /* FL(kl3) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800503 tr = subR[18] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800504 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
505 SUBKEY_R(15) = subR[14] ^ tr;
506 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
507 SUBKEY_R(16) = subR[16];
508 SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
509 SUBKEY_R(17) = subR[17];
510 tl = subL[15] ^ (subR[15] & ~subR[17]);
511 dw = tl & subL[17], /* FLinv(kl4) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800512 tr = subR[15] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800513 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
514 SUBKEY_R(18) = tr ^ subR[19];
515 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
516 SUBKEY_R(19) = subR[18] ^ subR[20];
517 SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
518 SUBKEY_R(20) = subR[19] ^ subR[21];
519 SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
520 SUBKEY_R(21) = subR[20] ^ subR[22];
521 SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
522 SUBKEY_R(22) = subR[21] ^ subR[23];
523 if (max == 24) {
524 SUBKEY_L(23) = subL[22]; /* round 18 */
525 SUBKEY_R(23) = subR[22];
526 SUBKEY_L(24) = subL[24] ^ subL[23]; /* kw3 */
527 SUBKEY_R(24) = subR[24] ^ subR[23];
528 } else {
529 tl = subL[26] ^ (subR[26] & ~subR[24]);
530 dw = tl & subL[24], /* FL(kl5) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800531 tr = subR[26] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800532 SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
533 SUBKEY_R(23) = subR[22] ^ tr;
534 SUBKEY_L(24) = subL[24]; /* FL(kl5) */
535 SUBKEY_R(24) = subR[24];
536 SUBKEY_L(25) = subL[25]; /* FLinv(kl6) */
537 SUBKEY_R(25) = subR[25];
538 tl = subL[23] ^ (subR[23] & ~subR[25]);
539 dw = tl & subL[25], /* FLinv(kl6) */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800540 tr = subR[23] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800541 SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
542 SUBKEY_R(26) = tr ^ subR[27];
543 SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
544 SUBKEY_R(27) = subR[26] ^ subR[28];
545 SUBKEY_L(28) = subL[27] ^ subL[29]; /* round 21 */
546 SUBKEY_R(28) = subR[27] ^ subR[29];
547 SUBKEY_L(29) = subL[28] ^ subL[30]; /* round 22 */
548 SUBKEY_R(29) = subR[28] ^ subR[30];
549 SUBKEY_L(30) = subL[29] ^ subL[31]; /* round 23 */
550 SUBKEY_R(30) = subR[29] ^ subR[31];
551 SUBKEY_L(31) = subL[30]; /* round 24 */
552 SUBKEY_R(31) = subR[30];
553 SUBKEY_L(32) = subL[32] ^ subL[31]; /* kw3 */
554 SUBKEY_R(32) = subR[32] ^ subR[31];
555 }
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800556}
557
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100558static void camellia_setup128(const unsigned char *key, u32 *subkey)
559{
560 u32 kll, klr, krl, krr;
561 u32 il, ir, t0, t1, w0, w1;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100562 u32 subL[26];
563 u32 subR[26];
564
565 /**
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800566 * k == kll || klr || krl || krr (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100567 */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800568 kll = get_unaligned_be32(key);
569 klr = get_unaligned_be32(key + 4);
570 krl = get_unaligned_be32(key + 8);
571 krr = get_unaligned_be32(key + 12);
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800572
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800573 /* generate KL dependent subkeys */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100574 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800575 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100576 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800577 subL[1] = krl; subR[1] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100578 /* rotation left shift 15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800579 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100580 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800581 subL[4] = kll; subR[4] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100582 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800583 subL[5] = krl; subR[5] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100584 /* rotation left shift 15+30bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800585 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100586 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800587 subL[10] = kll; subR[10] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100588 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800589 subL[11] = krl; subR[11] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100590 /* rotation left shift 15+30+15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800591 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100592 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800593 subL[13] = krl; subR[13] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100594 /* rotation left shift 15+30+15+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800595 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100596 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800597 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100598 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800599 subL[17] = krl; subR[17] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100600 /* rotation left shift 15+30+15+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800601 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100602 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800603 subL[18] = kll; subR[18] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100604 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800605 subL[19] = krl; subR[19] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100606 /* rotation left shift 15+30+15+17+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800607 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100608 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800609 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100610 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800611 subL[23] = krl; subR[23] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100612
613 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800614 kll = subL[0]; klr = subR[0];
615 krl = subL[1]; krr = subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100616 CAMELLIA_F(kll, klr,
617 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
618 w0, w1, il, ir, t0, t1);
619 krl ^= w0; krr ^= w1;
620 CAMELLIA_F(krl, krr,
621 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
622 kll, klr, il, ir, t0, t1);
623 /* current status == (kll, klr, w0, w1) */
624 CAMELLIA_F(kll, klr,
625 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
626 krl, krr, il, ir, t0, t1);
627 krl ^= w0; krr ^= w1;
628 CAMELLIA_F(krl, krr,
629 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
630 w0, w1, il, ir, t0, t1);
631 kll ^= w0; klr ^= w1;
632
633 /* generate KA dependent subkeys */
634 /* k1, k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800635 subL[2] = kll; subR[2] = klr;
636 subL[3] = krl; subR[3] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800637 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100638 /* k5,k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800639 subL[6] = kll; subR[6] = klr;
640 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800641 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100642 /* kl1, kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800643 subL[8] = kll; subR[8] = klr;
644 subL[9] = krl; subR[9] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800645 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100646 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800647 subL[12] = kll; subR[12] = klr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800648 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100649 /* k11, k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800650 subL[14] = kll; subR[14] = klr;
651 subL[15] = krl; subR[15] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800652 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100653 /* k15, k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800654 subL[20] = kll; subR[20] = klr;
655 subL[21] = krl; subR[21] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800656 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100657 /* kw3, kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800658 subL[24] = kll; subR[24] = klr;
659 subL[25] = krl; subR[25] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100660
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800661 camellia_setup_tail(subkey, subL, subR, 24);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100662}
663
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100664static void camellia_setup256(const unsigned char *key, u32 *subkey)
665{
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800666 u32 kll, klr, krl, krr; /* left half of key */
667 u32 krll, krlr, krrl, krrr; /* right half of key */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100668 u32 il, ir, t0, t1, w0, w1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100669 u32 subL[34];
670 u32 subR[34];
671
672 /**
673 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800674 * (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100675 */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800676 kll = get_unaligned_be32(key);
677 klr = get_unaligned_be32(key + 4);
678 krl = get_unaligned_be32(key + 8);
679 krr = get_unaligned_be32(key + 12);
680 krll = get_unaligned_be32(key + 16);
681 krlr = get_unaligned_be32(key + 20);
682 krrl = get_unaligned_be32(key + 24);
683 krrr = get_unaligned_be32(key + 28);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100684
685 /* generate KL dependent subkeys */
686 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800687 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100688 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800689 subL[1] = krl; subR[1] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800690 ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100691 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800692 subL[12] = kll; subR[12] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100693 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800694 subL[13] = krl; subR[13] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800695 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100696 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800697 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100698 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800699 subL[17] = krl; subR[17] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800700 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100701 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800702 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100703 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800704 subL[23] = krl; subR[23] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800705 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100706 /* k23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800707 subL[30] = kll; subR[30] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100708 /* k24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800709 subL[31] = krl; subR[31] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100710
711 /* generate KR dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800712 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100713 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800714 subL[4] = krll; subR[4] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100715 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800716 subL[5] = krrl; subR[5] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800717 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100718 /* kl1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800719 subL[8] = krll; subR[8] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100720 /* kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800721 subL[9] = krrl; subR[9] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800722 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100723 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800724 subL[18] = krll; subR[18] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100725 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800726 subL[19] = krrl; subR[19] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800727 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100728 /* k19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800729 subL[26] = krll; subR[26] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100730 /* k20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800731 subL[27] = krrl; subR[27] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800732 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100733
734 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800735 kll = subL[0] ^ krll; klr = subR[0] ^ krlr;
736 krl = subL[1] ^ krrl; krr = subR[1] ^ krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100737 CAMELLIA_F(kll, klr,
738 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
739 w0, w1, il, ir, t0, t1);
740 krl ^= w0; krr ^= w1;
741 CAMELLIA_F(krl, krr,
742 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
743 kll, klr, il, ir, t0, t1);
744 kll ^= krll; klr ^= krlr;
745 CAMELLIA_F(kll, klr,
746 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
747 krl, krr, il, ir, t0, t1);
748 krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
749 CAMELLIA_F(krl, krr,
750 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
751 w0, w1, il, ir, t0, t1);
752 kll ^= w0; klr ^= w1;
753
754 /* generate KB */
755 krll ^= kll; krlr ^= klr;
756 krrl ^= krl; krrr ^= krr;
757 CAMELLIA_F(krll, krlr,
758 CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
759 w0, w1, il, ir, t0, t1);
760 krrl ^= w0; krrr ^= w1;
761 CAMELLIA_F(krrl, krrr,
762 CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
763 w0, w1, il, ir, t0, t1);
764 krll ^= w0; krlr ^= w1;
765
766 /* generate KA dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800767 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100768 /* k5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800769 subL[6] = kll; subR[6] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100770 /* k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800771 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800772 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100773 /* k11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800774 subL[14] = kll; subR[14] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100775 /* k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800776 subL[15] = krl; subR[15] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100777 /* rotation left shift 32bit */
778 /* kl5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800779 subL[24] = klr; subR[24] = krl;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100780 /* kl6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800781 subL[25] = krr; subR[25] = kll;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100782 /* rotation left shift 49 from k11,k12 -> k21,k22 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800783 ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100784 /* k21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800785 subL[28] = kll; subR[28] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100786 /* k22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800787 subL[29] = krl; subR[29] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100788
789 /* generate KB dependent subkeys */
790 /* k1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800791 subL[2] = krll; subR[2] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100792 /* k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800793 subL[3] = krrl; subR[3] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800794 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100795 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800796 subL[10] = krll; subR[10] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100797 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800798 subL[11] = krrl; subR[11] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800799 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100800 /* k15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800801 subL[20] = krll; subR[20] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100802 /* k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800803 subL[21] = krrl; subR[21] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800804 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100805 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800806 subL[32] = krll; subR[32] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100807 /* kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800808 subL[33] = krrl; subR[33] = krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100809
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800810 camellia_setup_tail(subkey, subL, subR, 32);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100811}
812
813static void camellia_setup192(const unsigned char *key, u32 *subkey)
814{
815 unsigned char kk[32];
Richard Hartmann621dd362010-02-16 20:27:57 +0800816 u32 krll, krlr, krrl, krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100817
818 memcpy(kk, key, 24);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800819 memcpy((unsigned char *)&krll, key+16, 4);
820 memcpy((unsigned char *)&krlr, key+20, 4);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100821 krrl = ~krll;
822 krrr = ~krlr;
823 memcpy(kk+24, (unsigned char *)&krrl, 4);
824 memcpy(kk+28, (unsigned char *)&krrr, 4);
825 camellia_setup256(kk, subkey);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100826}
827
828
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800829/*
830 * Encrypt/decrypt
831 */
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200832#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) ({ \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800833 t0 = kll; \
834 t2 = krr; \
835 t0 &= ll; \
836 t2 |= rr; \
837 rl ^= t2; \
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800838 lr ^= rol32(t0, 1); \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800839 t3 = krl; \
840 t1 = klr; \
841 t3 &= rl; \
842 t1 |= lr; \
843 ll ^= t1; \
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800844 rr ^= rol32(t3, 1); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200845})
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800846
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200847#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) ({ \
Jussi Kivilinnac9b56d32012-03-03 13:59:00 +0200848 yl ^= kl; \
849 yr ^= kr; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800850 ir = camellia_sp1110[(u8)xr]; \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200851 il = camellia_sp1110[(u8)(xl >> 24)]; \
852 ir ^= camellia_sp0222[(u8)(xr >> 24)]; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800853 il ^= camellia_sp0222[(u8)(xl >> 16)]; \
854 ir ^= camellia_sp3033[(u8)(xr >> 16)]; \
855 il ^= camellia_sp3033[(u8)(xl >> 8)]; \
856 ir ^= camellia_sp4404[(u8)(xr >> 8)]; \
857 il ^= camellia_sp4404[(u8)xl]; \
Jussi Kivilinnac9b56d32012-03-03 13:59:00 +0200858 ir ^= il; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800859 yl ^= ir; \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200860 yr ^= ror32(il, 8) ^ ir; \
861})
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800862
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800863/* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
864static void camellia_do_encrypt(const u32 *subkey, u32 *io, unsigned max)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100865{
Richard Hartmann621dd362010-02-16 20:27:57 +0800866 u32 il, ir, t0, t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100867
Denys Vlasenko1721a812007-11-06 22:01:20 +0800868 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800869 io[0] ^= SUBKEY_L(0);
870 io[1] ^= SUBKEY_R(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100871
Denys Vlasenko1721a812007-11-06 22:01:20 +0800872 /* main iteration */
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200873#define ROUNDS(i) ({ \
Richard Hartmann621dd362010-02-16 20:27:57 +0800874 CAMELLIA_ROUNDSM(io[0], io[1], \
875 SUBKEY_L(i + 2), SUBKEY_R(i + 2), \
876 io[2], io[3], il, ir); \
877 CAMELLIA_ROUNDSM(io[2], io[3], \
878 SUBKEY_L(i + 3), SUBKEY_R(i + 3), \
879 io[0], io[1], il, ir); \
880 CAMELLIA_ROUNDSM(io[0], io[1], \
881 SUBKEY_L(i + 4), SUBKEY_R(i + 4), \
882 io[2], io[3], il, ir); \
883 CAMELLIA_ROUNDSM(io[2], io[3], \
884 SUBKEY_L(i + 5), SUBKEY_R(i + 5), \
885 io[0], io[1], il, ir); \
886 CAMELLIA_ROUNDSM(io[0], io[1], \
887 SUBKEY_L(i + 6), SUBKEY_R(i + 6), \
888 io[2], io[3], il, ir); \
889 CAMELLIA_ROUNDSM(io[2], io[3], \
890 SUBKEY_L(i + 7), SUBKEY_R(i + 7), \
891 io[0], io[1], il, ir); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200892})
893#define FLS(i) ({ \
Richard Hartmann621dd362010-02-16 20:27:57 +0800894 CAMELLIA_FLS(io[0], io[1], io[2], io[3], \
895 SUBKEY_L(i + 0), SUBKEY_R(i + 0), \
896 SUBKEY_L(i + 1), SUBKEY_R(i + 1), \
897 t0, t1, il, ir); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200898})
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100899
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800900 ROUNDS(0);
901 FLS(8);
902 ROUNDS(8);
903 FLS(16);
904 ROUNDS(16);
905 if (max == 32) {
906 FLS(24);
907 ROUNDS(24);
908 }
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100909
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800910#undef ROUNDS
911#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100912
913 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800914 io[2] ^= SUBKEY_L(max);
915 io[3] ^= SUBKEY_R(max);
916 /* NB: io[0],[1] should be swapped with [2],[3] by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100917}
918
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800919static void camellia_do_decrypt(const u32 *subkey, u32 *io, unsigned i)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100920{
Richard Hartmann621dd362010-02-16 20:27:57 +0800921 u32 il, ir, t0, t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100922
Denys Vlasenko1721a812007-11-06 22:01:20 +0800923 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800924 io[0] ^= SUBKEY_L(i);
925 io[1] ^= SUBKEY_R(i);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100926
927 /* main iteration */
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200928#define ROUNDS(i) ({ \
Richard Hartmann621dd362010-02-16 20:27:57 +0800929 CAMELLIA_ROUNDSM(io[0], io[1], \
930 SUBKEY_L(i + 7), SUBKEY_R(i + 7), \
931 io[2], io[3], il, ir); \
932 CAMELLIA_ROUNDSM(io[2], io[3], \
933 SUBKEY_L(i + 6), SUBKEY_R(i + 6), \
934 io[0], io[1], il, ir); \
935 CAMELLIA_ROUNDSM(io[0], io[1], \
936 SUBKEY_L(i + 5), SUBKEY_R(i + 5), \
937 io[2], io[3], il, ir); \
938 CAMELLIA_ROUNDSM(io[2], io[3], \
939 SUBKEY_L(i + 4), SUBKEY_R(i + 4), \
940 io[0], io[1], il, ir); \
941 CAMELLIA_ROUNDSM(io[0], io[1], \
942 SUBKEY_L(i + 3), SUBKEY_R(i + 3), \
943 io[2], io[3], il, ir); \
944 CAMELLIA_ROUNDSM(io[2], io[3], \
945 SUBKEY_L(i + 2), SUBKEY_R(i + 2), \
946 io[0], io[1], il, ir); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200947})
948#define FLS(i) ({ \
Richard Hartmann621dd362010-02-16 20:27:57 +0800949 CAMELLIA_FLS(io[0], io[1], io[2], io[3], \
950 SUBKEY_L(i + 1), SUBKEY_R(i + 1), \
951 SUBKEY_L(i + 0), SUBKEY_R(i + 0), \
952 t0, t1, il, ir); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200953})
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100954
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800955 if (i == 32) {
956 ROUNDS(24);
957 FLS(24);
958 }
959 ROUNDS(16);
960 FLS(16);
961 ROUNDS(8);
962 FLS(8);
963 ROUNDS(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100964
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800965#undef ROUNDS
966#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100967
968 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800969 io[2] ^= SUBKEY_L(0);
970 io[3] ^= SUBKEY_R(0);
971 /* NB: 0,1 should be swapped with 2,3 by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100972}
973
974
Denys Vlasenko1721a812007-11-06 22:01:20 +0800975struct camellia_ctx {
976 int key_length;
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800977 u32 key_table[CAMELLIA_TABLE_BYTE_LEN / sizeof(u32)];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800978};
979
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100980static int
981camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
982 unsigned int key_len)
983{
984 struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
985 const unsigned char *key = (const unsigned char *)in_key;
986 u32 *flags = &tfm->crt_flags;
987
988 if (key_len != 16 && key_len != 24 && key_len != 32) {
989 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
990 return -EINVAL;
991 }
992
993 cctx->key_length = key_len;
994
Denys Vlasenko1721a812007-11-06 22:01:20 +0800995 switch (key_len) {
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100996 case 16:
997 camellia_setup128(key, cctx->key_table);
998 break;
999 case 24:
1000 camellia_setup192(key, cctx->key_table);
1001 break;
1002 case 32:
1003 camellia_setup256(key, cctx->key_table);
1004 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001005 }
1006
1007 return 0;
1008}
1009
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001010static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1011{
1012 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1013 const __be32 *src = (const __be32 *)in;
1014 __be32 *dst = (__be32 *)out;
Jussi Kivilinnae2861a72012-03-05 20:26:37 +02001015 unsigned int max;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001016
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001017 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001018
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001019 tmp[0] = be32_to_cpu(src[0]);
1020 tmp[1] = be32_to_cpu(src[1]);
1021 tmp[2] = be32_to_cpu(src[2]);
1022 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001023
Jussi Kivilinnae2861a72012-03-05 20:26:37 +02001024 if (cctx->key_length == 16)
1025 max = 24;
1026 else
1027 max = 32; /* for key lengths of 24 and 32 */
1028
1029 camellia_do_encrypt(cctx->key_table, tmp, max);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001030
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001031 /* do_encrypt returns 0,1 swapped with 2,3 */
1032 dst[0] = cpu_to_be32(tmp[2]);
1033 dst[1] = cpu_to_be32(tmp[3]);
1034 dst[2] = cpu_to_be32(tmp[0]);
1035 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001036}
1037
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001038static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1039{
1040 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1041 const __be32 *src = (const __be32 *)in;
1042 __be32 *dst = (__be32 *)out;
Jussi Kivilinnae2861a72012-03-05 20:26:37 +02001043 unsigned int max;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001044
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
Jussi Kivilinnae2861a72012-03-05 20:26:37 +02001052 if (cctx->key_length == 16)
1053 max = 24;
1054 else
1055 max = 32; /* for key lengths of 24 and 32 */
1056
1057 camellia_do_decrypt(cctx->key_table, tmp, max);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001058
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001059 /* do_decrypt returns 0,1 swapped with 2,3 */
1060 dst[0] = cpu_to_be32(tmp[2]);
1061 dst[1] = cpu_to_be32(tmp[3]);
1062 dst[2] = cpu_to_be32(tmp[0]);
1063 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001064}
1065
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001066static struct crypto_alg camellia_alg = {
1067 .cra_name = "camellia",
1068 .cra_driver_name = "camellia-generic",
1069 .cra_priority = 100,
1070 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
1071 .cra_blocksize = CAMELLIA_BLOCK_SIZE,
1072 .cra_ctxsize = sizeof(struct camellia_ctx),
1073 .cra_alignmask = 3,
1074 .cra_module = THIS_MODULE,
1075 .cra_list = LIST_HEAD_INIT(camellia_alg.cra_list),
1076 .cra_u = {
1077 .cipher = {
1078 .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
1079 .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
1080 .cia_setkey = camellia_set_key,
1081 .cia_encrypt = camellia_encrypt,
1082 .cia_decrypt = camellia_decrypt
1083 }
1084 }
1085};
1086
1087static int __init camellia_init(void)
1088{
1089 return crypto_register_alg(&camellia_alg);
1090}
1091
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001092static void __exit camellia_fini(void)
1093{
1094 crypto_unregister_alg(&camellia_alg);
1095}
1096
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001097module_init(camellia_init);
1098module_exit(camellia_fini);
1099
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001100MODULE_DESCRIPTION("Camellia Cipher Algorithm");
1101MODULE_LICENSE("GPL");
Jussi Kivilinna075e39d2012-03-05 20:26:32 +02001102MODULE_ALIAS("camellia");