blob: 32ddd4836ff5549c953987c86beaff69f9109a98 [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
Martin Kepplinger1af39da2017-11-14 10:25:15 +010016 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +110017 */
18
19/*
20 * Algorithm Specification
21 * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
22 */
23
24/*
25 *
26 * NOTE --- NOTE --- NOTE --- NOTE
27 * This implementation assumes that all memory addresses passed
28 * as parameters are four-byte aligned.
29 *
30 */
31
32#include <linux/crypto.h>
33#include <linux/errno.h>
34#include <linux/init.h>
35#include <linux/kernel.h>
36#include <linux/module.h>
Harvey Harrison32bd78e2008-10-12 20:40:12 +080037#include <linux/bitops.h>
38#include <asm/unaligned.h>
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +110039
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +110040static const u32 camellia_sp1110[256] = {
Richard Hartmann621dd362010-02-16 20:27:57 +080041 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00,
42 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500,
43 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500,
44 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100,
45 0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300,
46 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
47 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00,
48 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00,
49 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00,
50 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00,
51 0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00,
52 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
53 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00,
54 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00,
55 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600,
56 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00,
57 0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600,
58 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
59 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000,
60 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900,
61 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200,
62 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500,
63 0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100,
64 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
65 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100,
66 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00,
67 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600,
68 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200,
69 0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200,
70 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
71 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800,
72 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000,
73 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00,
74 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700,
75 0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500,
76 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
77 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800,
78 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00,
79 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00,
80 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400,
81 0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200,
82 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
83 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300,
84 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200,
85 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600,
86 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00,
87 0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00,
88 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
89 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00,
90 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00,
91 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600,
92 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900,
93 0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00,
94 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
95 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200,
96 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00,
97 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500,
98 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00,
99 0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800,
100 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
101 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00,
102 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100,
103 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
104 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00,
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100105};
106
107static const u32 camellia_sp0222[256] = {
Richard Hartmann621dd362010-02-16 20:27:57 +0800108 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9,
109 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb,
110 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a,
111 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282,
112 0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727,
113 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
114 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c,
115 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b,
116 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f,
117 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d,
118 0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe,
119 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
120 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595,
121 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a,
122 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad,
123 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a,
124 0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc,
125 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
126 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040,
127 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333,
128 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585,
129 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a,
130 0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262,
131 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
132 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2,
133 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838,
134 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c,
135 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444,
136 0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565,
137 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
138 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151,
139 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0,
140 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa,
141 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f,
142 0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b,
143 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
144 0x00202020, 0x00898989, 0x00000000, 0x00909090,
145 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7,
146 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5,
147 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929,
148 0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404,
149 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
150 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7,
151 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5,
152 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c,
153 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676,
154 0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696,
155 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
156 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919,
157 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d,
158 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d,
159 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2,
160 0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4,
161 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
162 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484,
163 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5,
164 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa,
165 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414,
166 0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0,
167 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
168 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6,
169 0x00777777, 0x00939393, 0x00868686, 0x00838383,
170 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
171 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d,
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100172};
173
174static const u32 camellia_sp3033[256] = {
Richard Hartmann621dd362010-02-16 20:27:57 +0800175 0x38003838, 0x41004141, 0x16001616, 0x76007676,
176 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2,
177 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a,
178 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0,
179 0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9,
180 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
181 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727,
182 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede,
183 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7,
184 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767,
185 0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf,
186 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
187 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565,
188 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e,
189 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b,
190 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6,
191 0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333,
192 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
193 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010,
194 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc,
195 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161,
196 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282,
197 0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898,
198 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
199 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0,
200 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e,
201 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b,
202 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111,
203 0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959,
204 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
205 0x12001212, 0x04000404, 0x74007474, 0x54005454,
206 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828,
207 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe,
208 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb,
209 0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca,
210 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
211 0x08000808, 0x62006262, 0x00000000, 0x24002424,
212 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded,
213 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d,
214 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a,
215 0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101,
216 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
217 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9,
218 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171,
219 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313,
220 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d,
221 0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5,
222 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
223 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646,
224 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747,
225 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b,
226 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac,
227 0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535,
228 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
229 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121,
230 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d,
231 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa,
232 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505,
233 0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434,
234 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
235 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd,
236 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0,
237 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
238 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f,
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100239};
240
241static const u32 camellia_sp4404[256] = {
Richard Hartmann621dd362010-02-16 20:27:57 +0800242 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0,
243 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae,
244 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5,
245 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092,
246 0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f,
247 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
248 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d,
249 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c,
250 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0,
251 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084,
252 0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076,
253 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
254 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011,
255 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2,
256 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a,
257 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069,
258 0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062,
259 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
260 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075,
261 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd,
262 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090,
263 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf,
264 0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6,
265 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
266 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc,
267 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4,
268 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071,
269 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d,
270 0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac,
271 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
272 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043,
273 0x15150015, 0xadad00ad, 0x77770077, 0x80800080,
274 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5,
275 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041,
276 0xefef00ef, 0x93930093, 0x19190019, 0x21210021,
277 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
278 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce,
279 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a,
280 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d,
281 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d,
282 0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d,
283 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
284 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005,
285 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7,
286 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c,
287 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022,
288 0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091,
289 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
290 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097,
291 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2,
292 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db,
293 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094,
294 0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033,
295 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
296 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b,
297 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e,
298 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e,
299 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059,
300 0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba,
301 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
302 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a,
303 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4,
304 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
305 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e,
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100306};
307
308
Denys Vlasenko1721a812007-11-06 22:01:20 +0800309#define CAMELLIA_MIN_KEY_SIZE 16
310#define CAMELLIA_MAX_KEY_SIZE 32
311#define CAMELLIA_BLOCK_SIZE 16
312#define CAMELLIA_TABLE_BYTE_LEN 272
313
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800314/*
315 * NB: L and R below stand for 'left' and 'right' as in written numbers.
316 * That is, in (xxxL,xxxR) pair xxxL holds most significant digits,
317 * _not_ least significant ones!
318 */
319
Denys Vlasenko1721a812007-11-06 22:01:20 +0800320
321/* key constants */
322
323#define CAMELLIA_SIGMA1L (0xA09E667FL)
324#define CAMELLIA_SIGMA1R (0x3BCC908BL)
325#define CAMELLIA_SIGMA2L (0xB67AE858L)
326#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
327#define CAMELLIA_SIGMA3L (0xC6EF372FL)
328#define CAMELLIA_SIGMA3R (0xE94F82BEL)
329#define CAMELLIA_SIGMA4L (0x54FF53A5L)
330#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
331#define CAMELLIA_SIGMA5L (0x10E527FAL)
332#define CAMELLIA_SIGMA5R (0xDE682D1DL)
333#define CAMELLIA_SIGMA6L (0xB05688C2L)
334#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
335
336/*
337 * macros
338 */
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200339#define ROLDQ(ll, lr, rl, rr, w0, w1, bits) ({ \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800340 w0 = ll; \
341 ll = (ll << bits) + (lr >> (32 - bits)); \
342 lr = (lr << bits) + (rl >> (32 - bits)); \
343 rl = (rl << bits) + (rr >> (32 - bits)); \
344 rr = (rr << bits) + (w0 >> (32 - bits)); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200345})
Denys Vlasenko1721a812007-11-06 22:01:20 +0800346
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200347#define ROLDQo32(ll, lr, rl, rr, w0, w1, bits) ({ \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800348 w0 = ll; \
349 w1 = lr; \
350 ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
351 lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
352 rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
353 rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200354})
Denys Vlasenko1721a812007-11-06 22:01:20 +0800355
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200356#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) ({ \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800357 il = xl ^ kl; \
358 ir = xr ^ kr; \
359 t0 = il >> 16; \
360 t1 = ir >> 16; \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200361 yl = camellia_sp1110[(u8)(ir)] \
362 ^ camellia_sp0222[(u8)(t1 >> 8)] \
363 ^ camellia_sp3033[(u8)(t1)] \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800364 ^ camellia_sp4404[(u8)(ir >> 8)]; \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200365 yr = camellia_sp1110[(u8)(t0 >> 8)] \
366 ^ camellia_sp0222[(u8)(t0)] \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800367 ^ camellia_sp3033[(u8)(il >> 8)] \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200368 ^ camellia_sp4404[(u8)(il)]; \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800369 yl ^= yr; \
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800370 yr = ror32(yr, 8); \
Denys Vlasenko1721a812007-11-06 22:01:20 +0800371 yr ^= yl; \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200372})
Denys Vlasenko1721a812007-11-06 22:01:20 +0800373
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800374#define SUBKEY_L(INDEX) (subkey[(INDEX)*2])
375#define SUBKEY_R(INDEX) (subkey[(INDEX)*2 + 1])
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100376
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800377static void camellia_setup_tail(u32 *subkey, u32 *subL, u32 *subR, int max)
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800378{
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800379 u32 dw, tl, tr;
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800380 u32 kw4l, kw4r;
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800381
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800382 /* absorb kw2 to other subkeys */
383 /* round 2 */
384 subL[3] ^= subL[1]; subR[3] ^= subR[1];
385 /* round 4 */
386 subL[5] ^= subL[1]; subR[5] ^= subR[1];
387 /* round 6 */
388 subL[7] ^= subL[1]; subR[7] ^= subR[1];
389 subL[1] ^= subR[1] & ~subR[9];
Julia Lawall452ec042013-08-14 15:52:58 +0200390 dw = subL[1] & subL[9];
391 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl2) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800392 /* round 8 */
393 subL[11] ^= subL[1]; subR[11] ^= subR[1];
394 /* round 10 */
395 subL[13] ^= subL[1]; subR[13] ^= subR[1];
396 /* round 12 */
397 subL[15] ^= subL[1]; subR[15] ^= subR[1];
398 subL[1] ^= subR[1] & ~subR[17];
Julia Lawall452ec042013-08-14 15:52:58 +0200399 dw = subL[1] & subL[17];
400 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl4) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800401 /* round 14 */
402 subL[19] ^= subL[1]; subR[19] ^= subR[1];
403 /* round 16 */
404 subL[21] ^= subL[1]; subR[21] ^= subR[1];
405 /* round 18 */
406 subL[23] ^= subL[1]; subR[23] ^= subR[1];
407 if (max == 24) {
408 /* kw3 */
409 subL[24] ^= subL[1]; subR[24] ^= subR[1];
410
411 /* absorb kw4 to other subkeys */
412 kw4l = subL[25]; kw4r = subR[25];
413 } else {
414 subL[1] ^= subR[1] & ~subR[25];
Julia Lawall452ec042013-08-14 15:52:58 +0200415 dw = subL[1] & subL[25];
416 subR[1] ^= rol32(dw, 1); /* modified for FLinv(kl6) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800417 /* round 20 */
418 subL[27] ^= subL[1]; subR[27] ^= subR[1];
419 /* round 22 */
420 subL[29] ^= subL[1]; subR[29] ^= subR[1];
421 /* round 24 */
422 subL[31] ^= subL[1]; subR[31] ^= subR[1];
423 /* kw3 */
424 subL[32] ^= subL[1]; subR[32] ^= subR[1];
425
426 /* absorb kw4 to other subkeys */
427 kw4l = subL[33]; kw4r = subR[33];
428 /* round 23 */
429 subL[30] ^= kw4l; subR[30] ^= kw4r;
430 /* round 21 */
431 subL[28] ^= kw4l; subR[28] ^= kw4r;
432 /* round 19 */
433 subL[26] ^= kw4l; subR[26] ^= kw4r;
434 kw4l ^= kw4r & ~subR[24];
Julia Lawall452ec042013-08-14 15:52:58 +0200435 dw = kw4l & subL[24];
436 kw4r ^= rol32(dw, 1); /* modified for FL(kl5) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800437 }
438 /* round 17 */
439 subL[22] ^= kw4l; subR[22] ^= kw4r;
440 /* round 15 */
441 subL[20] ^= kw4l; subR[20] ^= kw4r;
442 /* round 13 */
443 subL[18] ^= kw4l; subR[18] ^= kw4r;
444 kw4l ^= kw4r & ~subR[16];
Julia Lawall452ec042013-08-14 15:52:58 +0200445 dw = kw4l & subL[16];
446 kw4r ^= rol32(dw, 1); /* modified for FL(kl3) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800447 /* round 11 */
448 subL[14] ^= kw4l; subR[14] ^= kw4r;
449 /* round 9 */
450 subL[12] ^= kw4l; subR[12] ^= kw4r;
451 /* round 7 */
452 subL[10] ^= kw4l; subR[10] ^= kw4r;
453 kw4l ^= kw4r & ~subR[8];
Julia Lawall452ec042013-08-14 15:52:58 +0200454 dw = kw4l & subL[8];
455 kw4r ^= rol32(dw, 1); /* modified for FL(kl1) */
Denys Vlasenkoff85a802007-11-23 21:21:03 +0800456 /* round 5 */
457 subL[6] ^= kw4l; subR[6] ^= kw4r;
458 /* round 3 */
459 subL[4] ^= kw4l; subR[4] ^= kw4r;
460 /* round 1 */
461 subL[2] ^= kw4l; subR[2] ^= kw4r;
462 /* kw1 */
463 subL[0] ^= kw4l; subR[0] ^= kw4r;
464
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800465 /* key XOR is end of F-function */
466 SUBKEY_L(0) = subL[0] ^ subL[2];/* kw1 */
467 SUBKEY_R(0) = subR[0] ^ subR[2];
468 SUBKEY_L(2) = subL[3]; /* round 1 */
469 SUBKEY_R(2) = subR[3];
470 SUBKEY_L(3) = subL[2] ^ subL[4]; /* round 2 */
471 SUBKEY_R(3) = subR[2] ^ subR[4];
472 SUBKEY_L(4) = subL[3] ^ subL[5]; /* round 3 */
473 SUBKEY_R(4) = subR[3] ^ subR[5];
474 SUBKEY_L(5) = subL[4] ^ subL[6]; /* round 4 */
475 SUBKEY_R(5) = subR[4] ^ subR[6];
476 SUBKEY_L(6) = subL[5] ^ subL[7]; /* round 5 */
477 SUBKEY_R(6) = subR[5] ^ subR[7];
478 tl = subL[10] ^ (subR[10] & ~subR[8]);
Julia Lawall452ec042013-08-14 15:52:58 +0200479 dw = tl & subL[8]; /* FL(kl1) */
480 tr = subR[10] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800481 SUBKEY_L(7) = subL[6] ^ tl; /* round 6 */
482 SUBKEY_R(7) = subR[6] ^ tr;
483 SUBKEY_L(8) = subL[8]; /* FL(kl1) */
484 SUBKEY_R(8) = subR[8];
485 SUBKEY_L(9) = subL[9]; /* FLinv(kl2) */
486 SUBKEY_R(9) = subR[9];
487 tl = subL[7] ^ (subR[7] & ~subR[9]);
Julia Lawall452ec042013-08-14 15:52:58 +0200488 dw = tl & subL[9]; /* FLinv(kl2) */
489 tr = subR[7] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800490 SUBKEY_L(10) = tl ^ subL[11]; /* round 7 */
491 SUBKEY_R(10) = tr ^ subR[11];
492 SUBKEY_L(11) = subL[10] ^ subL[12]; /* round 8 */
493 SUBKEY_R(11) = subR[10] ^ subR[12];
494 SUBKEY_L(12) = subL[11] ^ subL[13]; /* round 9 */
495 SUBKEY_R(12) = subR[11] ^ subR[13];
496 SUBKEY_L(13) = subL[12] ^ subL[14]; /* round 10 */
497 SUBKEY_R(13) = subR[12] ^ subR[14];
498 SUBKEY_L(14) = subL[13] ^ subL[15]; /* round 11 */
499 SUBKEY_R(14) = subR[13] ^ subR[15];
500 tl = subL[18] ^ (subR[18] & ~subR[16]);
Julia Lawall452ec042013-08-14 15:52:58 +0200501 dw = tl & subL[16]; /* FL(kl3) */
502 tr = subR[18] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800503 SUBKEY_L(15) = subL[14] ^ tl; /* round 12 */
504 SUBKEY_R(15) = subR[14] ^ tr;
505 SUBKEY_L(16) = subL[16]; /* FL(kl3) */
506 SUBKEY_R(16) = subR[16];
507 SUBKEY_L(17) = subL[17]; /* FLinv(kl4) */
508 SUBKEY_R(17) = subR[17];
509 tl = subL[15] ^ (subR[15] & ~subR[17]);
Julia Lawall452ec042013-08-14 15:52:58 +0200510 dw = tl & subL[17]; /* FLinv(kl4) */
511 tr = subR[15] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800512 SUBKEY_L(18) = tl ^ subL[19]; /* round 13 */
513 SUBKEY_R(18) = tr ^ subR[19];
514 SUBKEY_L(19) = subL[18] ^ subL[20]; /* round 14 */
515 SUBKEY_R(19) = subR[18] ^ subR[20];
516 SUBKEY_L(20) = subL[19] ^ subL[21]; /* round 15 */
517 SUBKEY_R(20) = subR[19] ^ subR[21];
518 SUBKEY_L(21) = subL[20] ^ subL[22]; /* round 16 */
519 SUBKEY_R(21) = subR[20] ^ subR[22];
520 SUBKEY_L(22) = subL[21] ^ subL[23]; /* round 17 */
521 SUBKEY_R(22) = subR[21] ^ subR[23];
522 if (max == 24) {
523 SUBKEY_L(23) = subL[22]; /* round 18 */
524 SUBKEY_R(23) = subR[22];
525 SUBKEY_L(24) = subL[24] ^ subL[23]; /* kw3 */
526 SUBKEY_R(24) = subR[24] ^ subR[23];
527 } else {
528 tl = subL[26] ^ (subR[26] & ~subR[24]);
Julia Lawall452ec042013-08-14 15:52:58 +0200529 dw = tl & subL[24]; /* FL(kl5) */
530 tr = subR[26] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800531 SUBKEY_L(23) = subL[22] ^ tl; /* round 18 */
532 SUBKEY_R(23) = subR[22] ^ tr;
533 SUBKEY_L(24) = subL[24]; /* FL(kl5) */
534 SUBKEY_R(24) = subR[24];
535 SUBKEY_L(25) = subL[25]; /* FLinv(kl6) */
536 SUBKEY_R(25) = subR[25];
537 tl = subL[23] ^ (subR[23] & ~subR[25]);
Julia Lawall452ec042013-08-14 15:52:58 +0200538 dw = tl & subL[25]; /* FLinv(kl6) */
539 tr = subR[23] ^ rol32(dw, 1);
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800540 SUBKEY_L(26) = tl ^ subL[27]; /* round 19 */
541 SUBKEY_R(26) = tr ^ subR[27];
542 SUBKEY_L(27) = subL[26] ^ subL[28]; /* round 20 */
543 SUBKEY_R(27) = subR[26] ^ subR[28];
544 SUBKEY_L(28) = subL[27] ^ subL[29]; /* round 21 */
545 SUBKEY_R(28) = subR[27] ^ subR[29];
546 SUBKEY_L(29) = subL[28] ^ subL[30]; /* round 22 */
547 SUBKEY_R(29) = subR[28] ^ subR[30];
548 SUBKEY_L(30) = subL[29] ^ subL[31]; /* round 23 */
549 SUBKEY_R(30) = subR[29] ^ subR[31];
550 SUBKEY_L(31) = subL[30]; /* round 24 */
551 SUBKEY_R(31) = subR[30];
552 SUBKEY_L(32) = subL[32] ^ subL[31]; /* kw3 */
553 SUBKEY_R(32) = subR[32] ^ subR[31];
554 }
Denys Vlasenkod3e74802007-11-06 22:15:19 +0800555}
556
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100557static void camellia_setup128(const unsigned char *key, u32 *subkey)
558{
559 u32 kll, klr, krl, krr;
560 u32 il, ir, t0, t1, w0, w1;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100561 u32 subL[26];
562 u32 subR[26];
563
564 /**
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800565 * k == kll || klr || krl || krr (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100566 */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800567 kll = get_unaligned_be32(key);
568 klr = get_unaligned_be32(key + 4);
569 krl = get_unaligned_be32(key + 8);
570 krr = get_unaligned_be32(key + 12);
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800571
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800572 /* generate KL dependent subkeys */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100573 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800574 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100575 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800576 subL[1] = krl; subR[1] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100577 /* rotation left shift 15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800578 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100579 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800580 subL[4] = kll; subR[4] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100581 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800582 subL[5] = krl; subR[5] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100583 /* rotation left shift 15+30bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800584 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100585 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800586 subL[10] = kll; subR[10] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100587 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800588 subL[11] = krl; subR[11] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100589 /* rotation left shift 15+30+15bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800590 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100591 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800592 subL[13] = krl; subR[13] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100593 /* rotation left shift 15+30+15+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800594 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100595 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800596 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100597 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800598 subL[17] = krl; subR[17] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100599 /* rotation left shift 15+30+15+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800600 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100601 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800602 subL[18] = kll; subR[18] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100603 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800604 subL[19] = krl; subR[19] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100605 /* rotation left shift 15+30+15+17+17+17 bit */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800606 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100607 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800608 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100609 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800610 subL[23] = krl; subR[23] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100611
612 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800613 kll = subL[0]; klr = subR[0];
614 krl = subL[1]; krr = subR[1];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100615 CAMELLIA_F(kll, klr,
616 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
617 w0, w1, il, ir, t0, t1);
618 krl ^= w0; krr ^= w1;
619 CAMELLIA_F(krl, krr,
620 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
621 kll, klr, il, ir, t0, t1);
622 /* current status == (kll, klr, w0, w1) */
623 CAMELLIA_F(kll, klr,
624 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
625 krl, krr, il, ir, t0, t1);
626 krl ^= w0; krr ^= w1;
627 CAMELLIA_F(krl, krr,
628 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
629 w0, w1, il, ir, t0, t1);
630 kll ^= w0; klr ^= w1;
631
632 /* generate KA dependent subkeys */
633 /* k1, k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800634 subL[2] = kll; subR[2] = klr;
635 subL[3] = krl; subR[3] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800636 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100637 /* k5,k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800638 subL[6] = kll; subR[6] = klr;
639 subL[7] = krl; subR[7] = 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 /* kl1, kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800642 subL[8] = kll; subR[8] = klr;
643 subL[9] = krl; subR[9] = 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 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800646 subL[12] = kll; subR[12] = klr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800647 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100648 /* k11, k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800649 subL[14] = kll; subR[14] = klr;
650 subL[15] = krl; subR[15] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800651 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100652 /* k15, k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800653 subL[20] = kll; subR[20] = klr;
654 subL[21] = krl; subR[21] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800655 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100656 /* kw3, kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800657 subL[24] = kll; subR[24] = klr;
658 subL[25] = krl; subR[25] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100659
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800660 camellia_setup_tail(subkey, subL, subR, 24);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100661}
662
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100663static void camellia_setup256(const unsigned char *key, u32 *subkey)
664{
Denys Vlasenko1ce73e82007-11-06 22:13:40 +0800665 u32 kll, klr, krl, krr; /* left half of key */
666 u32 krll, krlr, krrl, krrr; /* right half of key */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100667 u32 il, ir, t0, t1, w0, w1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100668 u32 subL[34];
669 u32 subR[34];
670
671 /**
672 * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800673 * (|| is concatenation)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100674 */
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800675 kll = get_unaligned_be32(key);
676 klr = get_unaligned_be32(key + 4);
677 krl = get_unaligned_be32(key + 8);
678 krr = get_unaligned_be32(key + 12);
679 krll = get_unaligned_be32(key + 16);
680 krlr = get_unaligned_be32(key + 20);
681 krrl = get_unaligned_be32(key + 24);
682 krrr = get_unaligned_be32(key + 28);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100683
684 /* generate KL dependent subkeys */
685 /* kw1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800686 subL[0] = kll; subR[0] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100687 /* kw2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800688 subL[1] = krl; subR[1] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800689 ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100690 /* k9 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800691 subL[12] = kll; subR[12] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100692 /* k10 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800693 subL[13] = krl; subR[13] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800694 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100695 /* kl3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800696 subL[16] = kll; subR[16] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100697 /* kl4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800698 subL[17] = krl; subR[17] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800699 ROLDQ(kll, klr, krl, krr, w0, w1, 17);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100700 /* k17 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800701 subL[22] = kll; subR[22] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100702 /* k18 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800703 subL[23] = krl; subR[23] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800704 ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100705 /* k23 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800706 subL[30] = kll; subR[30] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100707 /* k24 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800708 subL[31] = krl; subR[31] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100709
710 /* generate KR dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800711 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100712 /* k3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800713 subL[4] = krll; subR[4] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100714 /* k4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800715 subL[5] = krrl; subR[5] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800716 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100717 /* kl1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800718 subL[8] = krll; subR[8] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100719 /* kl2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800720 subL[9] = krrl; subR[9] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800721 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100722 /* k13 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800723 subL[18] = krll; subR[18] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100724 /* k14 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800725 subL[19] = krrl; subR[19] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800726 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100727 /* k19 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800728 subL[26] = krll; subR[26] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100729 /* k20 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800730 subL[27] = krrl; subR[27] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800731 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100732
733 /* generate KA */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800734 kll = subL[0] ^ krll; klr = subR[0] ^ krlr;
735 krl = subL[1] ^ krrl; krr = subR[1] ^ krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100736 CAMELLIA_F(kll, klr,
737 CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
738 w0, w1, il, ir, t0, t1);
739 krl ^= w0; krr ^= w1;
740 CAMELLIA_F(krl, krr,
741 CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
742 kll, klr, il, ir, t0, t1);
743 kll ^= krll; klr ^= krlr;
744 CAMELLIA_F(kll, klr,
745 CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
746 krl, krr, il, ir, t0, t1);
747 krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
748 CAMELLIA_F(krl, krr,
749 CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
750 w0, w1, il, ir, t0, t1);
751 kll ^= w0; klr ^= w1;
752
753 /* generate KB */
754 krll ^= kll; krlr ^= klr;
755 krrl ^= krl; krrr ^= krr;
756 CAMELLIA_F(krll, krlr,
757 CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
758 w0, w1, il, ir, t0, t1);
759 krrl ^= w0; krrr ^= w1;
760 CAMELLIA_F(krrl, krrr,
761 CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
762 w0, w1, il, ir, t0, t1);
763 krll ^= w0; krlr ^= w1;
764
765 /* generate KA dependent subkeys */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800766 ROLDQ(kll, klr, krl, krr, w0, w1, 15);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100767 /* k5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800768 subL[6] = kll; subR[6] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100769 /* k6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800770 subL[7] = krl; subR[7] = krr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800771 ROLDQ(kll, klr, krl, krr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100772 /* k11 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800773 subL[14] = kll; subR[14] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100774 /* k12 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800775 subL[15] = krl; subR[15] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100776 /* rotation left shift 32bit */
777 /* kl5 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800778 subL[24] = klr; subR[24] = krl;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100779 /* kl6 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800780 subL[25] = krr; subR[25] = kll;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100781 /* rotation left shift 49 from k11,k12 -> k21,k22 */
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800782 ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100783 /* k21 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800784 subL[28] = kll; subR[28] = klr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100785 /* k22 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800786 subL[29] = krl; subR[29] = krr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100787
788 /* generate KB dependent subkeys */
789 /* k1 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800790 subL[2] = krll; subR[2] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100791 /* k2 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800792 subL[3] = krrl; subR[3] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800793 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100794 /* k7 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800795 subL[10] = krll; subR[10] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100796 /* k8 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800797 subL[11] = krrl; subR[11] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800798 ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100799 /* k15 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800800 subL[20] = krll; subR[20] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100801 /* k16 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800802 subL[21] = krrl; subR[21] = krrr;
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +0800803 ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100804 /* kw3 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800805 subL[32] = krll; subR[32] = krlr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100806 /* kw4 */
Denys Vlasenko1721a812007-11-06 22:01:20 +0800807 subL[33] = krrl; subR[33] = krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100808
Denys Vlasenkodedcf8b2007-11-23 21:14:24 +0800809 camellia_setup_tail(subkey, subL, subR, 32);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100810}
811
812static void camellia_setup192(const unsigned char *key, u32 *subkey)
813{
814 unsigned char kk[32];
Richard Hartmann621dd362010-02-16 20:27:57 +0800815 u32 krll, krlr, krrl, krrr;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100816
817 memcpy(kk, key, 24);
Denys Vlasenko1721a812007-11-06 22:01:20 +0800818 memcpy((unsigned char *)&krll, key+16, 4);
819 memcpy((unsigned char *)&krlr, key+20, 4);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100820 krrl = ~krll;
821 krrr = ~krlr;
822 memcpy(kk+24, (unsigned char *)&krrl, 4);
823 memcpy(kk+28, (unsigned char *)&krrr, 4);
824 camellia_setup256(kk, subkey);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100825}
826
827
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800828/*
829 * Encrypt/decrypt
830 */
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200831#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) ({ \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800832 t0 = kll; \
833 t2 = krr; \
834 t0 &= ll; \
835 t2 |= rr; \
836 rl ^= t2; \
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800837 lr ^= rol32(t0, 1); \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800838 t3 = krl; \
839 t1 = klr; \
840 t3 &= rl; \
841 t1 |= lr; \
842 ll ^= t1; \
Harvey Harrison32bd78e2008-10-12 20:40:12 +0800843 rr ^= rol32(t3, 1); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200844})
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800845
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200846#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir) ({ \
Jussi Kivilinnac9b56d32012-03-03 13:59:00 +0200847 yl ^= kl; \
848 yr ^= kr; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800849 ir = camellia_sp1110[(u8)xr]; \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200850 il = camellia_sp1110[(u8)(xl >> 24)]; \
851 ir ^= camellia_sp0222[(u8)(xr >> 24)]; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800852 il ^= camellia_sp0222[(u8)(xl >> 16)]; \
853 ir ^= camellia_sp3033[(u8)(xr >> 16)]; \
854 il ^= camellia_sp3033[(u8)(xl >> 8)]; \
855 ir ^= camellia_sp4404[(u8)(xr >> 8)]; \
856 il ^= camellia_sp4404[(u8)xl]; \
Jussi Kivilinnac9b56d32012-03-03 13:59:00 +0200857 ir ^= il; \
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800858 yl ^= ir; \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200859 yr ^= ror32(il, 8) ^ ir; \
860})
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800861
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800862/* max = 24: 128bit encrypt, max = 32: 256bit encrypt */
863static void camellia_do_encrypt(const u32 *subkey, u32 *io, unsigned max)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100864{
Richard Hartmann621dd362010-02-16 20:27:57 +0800865 u32 il, ir, t0, t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100866
Denys Vlasenko1721a812007-11-06 22:01:20 +0800867 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800868 io[0] ^= SUBKEY_L(0);
869 io[1] ^= SUBKEY_R(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100870
Denys Vlasenko1721a812007-11-06 22:01:20 +0800871 /* main iteration */
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200872#define ROUNDS(i) ({ \
Richard Hartmann621dd362010-02-16 20:27:57 +0800873 CAMELLIA_ROUNDSM(io[0], io[1], \
874 SUBKEY_L(i + 2), SUBKEY_R(i + 2), \
875 io[2], io[3], il, ir); \
876 CAMELLIA_ROUNDSM(io[2], io[3], \
877 SUBKEY_L(i + 3), SUBKEY_R(i + 3), \
878 io[0], io[1], il, ir); \
879 CAMELLIA_ROUNDSM(io[0], io[1], \
880 SUBKEY_L(i + 4), SUBKEY_R(i + 4), \
881 io[2], io[3], il, ir); \
882 CAMELLIA_ROUNDSM(io[2], io[3], \
883 SUBKEY_L(i + 5), SUBKEY_R(i + 5), \
884 io[0], io[1], il, ir); \
885 CAMELLIA_ROUNDSM(io[0], io[1], \
886 SUBKEY_L(i + 6), SUBKEY_R(i + 6), \
887 io[2], io[3], il, ir); \
888 CAMELLIA_ROUNDSM(io[2], io[3], \
889 SUBKEY_L(i + 7), SUBKEY_R(i + 7), \
890 io[0], io[1], il, ir); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200891})
892#define FLS(i) ({ \
Richard Hartmann621dd362010-02-16 20:27:57 +0800893 CAMELLIA_FLS(io[0], io[1], io[2], io[3], \
894 SUBKEY_L(i + 0), SUBKEY_R(i + 0), \
895 SUBKEY_L(i + 1), SUBKEY_R(i + 1), \
896 t0, t1, il, ir); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200897})
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100898
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800899 ROUNDS(0);
900 FLS(8);
901 ROUNDS(8);
902 FLS(16);
903 ROUNDS(16);
904 if (max == 32) {
905 FLS(24);
906 ROUNDS(24);
907 }
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100908
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800909#undef ROUNDS
910#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100911
912 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800913 io[2] ^= SUBKEY_L(max);
914 io[3] ^= SUBKEY_R(max);
915 /* NB: io[0],[1] should be swapped with [2],[3] by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100916}
917
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800918static void camellia_do_decrypt(const u32 *subkey, u32 *io, unsigned i)
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100919{
Richard Hartmann621dd362010-02-16 20:27:57 +0800920 u32 il, ir, t0, t1; /* temporary variables */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100921
Denys Vlasenko1721a812007-11-06 22:01:20 +0800922 /* pre whitening but absorb kw2 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800923 io[0] ^= SUBKEY_L(i);
924 io[1] ^= SUBKEY_R(i);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100925
926 /* main iteration */
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200927#define ROUNDS(i) ({ \
Richard Hartmann621dd362010-02-16 20:27:57 +0800928 CAMELLIA_ROUNDSM(io[0], io[1], \
929 SUBKEY_L(i + 7), SUBKEY_R(i + 7), \
930 io[2], io[3], il, ir); \
931 CAMELLIA_ROUNDSM(io[2], io[3], \
932 SUBKEY_L(i + 6), SUBKEY_R(i + 6), \
933 io[0], io[1], il, ir); \
934 CAMELLIA_ROUNDSM(io[0], io[1], \
935 SUBKEY_L(i + 5), SUBKEY_R(i + 5), \
936 io[2], io[3], il, ir); \
937 CAMELLIA_ROUNDSM(io[2], io[3], \
938 SUBKEY_L(i + 4), SUBKEY_R(i + 4), \
939 io[0], io[1], il, ir); \
940 CAMELLIA_ROUNDSM(io[0], io[1], \
941 SUBKEY_L(i + 3), SUBKEY_R(i + 3), \
942 io[2], io[3], il, ir); \
943 CAMELLIA_ROUNDSM(io[2], io[3], \
944 SUBKEY_L(i + 2), SUBKEY_R(i + 2), \
945 io[0], io[1], il, ir); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200946})
947#define FLS(i) ({ \
Richard Hartmann621dd362010-02-16 20:27:57 +0800948 CAMELLIA_FLS(io[0], io[1], io[2], io[3], \
949 SUBKEY_L(i + 1), SUBKEY_R(i + 1), \
950 SUBKEY_L(i + 0), SUBKEY_R(i + 0), \
951 t0, t1, il, ir); \
Jussi Kivilinnae2861a72012-03-05 20:26:37 +0200952})
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100953
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800954 if (i == 32) {
955 ROUNDS(24);
956 FLS(24);
957 }
958 ROUNDS(16);
959 FLS(16);
960 ROUNDS(8);
961 FLS(8);
962 ROUNDS(0);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100963
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800964#undef ROUNDS
965#undef FLS
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100966
967 /* post whitening but kw4 */
Denys Vlasenkoacca79a2007-11-23 21:10:03 +0800968 io[2] ^= SUBKEY_L(0);
969 io[3] ^= SUBKEY_R(0);
970 /* NB: 0,1 should be swapped with 2,3 by caller! */
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100971}
972
973
Denys Vlasenko1721a812007-11-06 22:01:20 +0800974struct camellia_ctx {
975 int key_length;
Denys Vlasenko2ddae4a2007-11-23 21:05:55 +0800976 u32 key_table[CAMELLIA_TABLE_BYTE_LEN / sizeof(u32)];
Denys Vlasenko1721a812007-11-06 22:01:20 +0800977};
978
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100979static int
980camellia_set_key(struct crypto_tfm *tfm, const u8 *in_key,
981 unsigned int key_len)
982{
983 struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
984 const unsigned char *key = (const unsigned char *)in_key;
985 u32 *flags = &tfm->crt_flags;
986
987 if (key_len != 16 && key_len != 24 && key_len != 32) {
988 *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
989 return -EINVAL;
990 }
991
992 cctx->key_length = key_len;
993
Denys Vlasenko1721a812007-11-06 22:01:20 +0800994 switch (key_len) {
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +1100995 case 16:
996 camellia_setup128(key, cctx->key_table);
997 break;
998 case 24:
999 camellia_setup192(key, cctx->key_table);
1000 break;
1001 case 32:
1002 camellia_setup256(key, cctx->key_table);
1003 break;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001004 }
1005
1006 return 0;
1007}
1008
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001009static void camellia_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1010{
1011 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1012 const __be32 *src = (const __be32 *)in;
1013 __be32 *dst = (__be32 *)out;
Jussi Kivilinnae2861a72012-03-05 20:26:37 +02001014 unsigned int max;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001015
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001016 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001017
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001018 tmp[0] = be32_to_cpu(src[0]);
1019 tmp[1] = be32_to_cpu(src[1]);
1020 tmp[2] = be32_to_cpu(src[2]);
1021 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001022
Jussi Kivilinnae2861a72012-03-05 20:26:37 +02001023 if (cctx->key_length == 16)
1024 max = 24;
1025 else
1026 max = 32; /* for key lengths of 24 and 32 */
1027
1028 camellia_do_encrypt(cctx->key_table, tmp, max);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001029
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001030 /* do_encrypt returns 0,1 swapped with 2,3 */
1031 dst[0] = cpu_to_be32(tmp[2]);
1032 dst[1] = cpu_to_be32(tmp[3]);
1033 dst[2] = cpu_to_be32(tmp[0]);
1034 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001035}
1036
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001037static void camellia_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
1038{
1039 const struct camellia_ctx *cctx = crypto_tfm_ctx(tfm);
1040 const __be32 *src = (const __be32 *)in;
1041 __be32 *dst = (__be32 *)out;
Jussi Kivilinnae2861a72012-03-05 20:26:37 +02001042 unsigned int max;
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001043
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001044 u32 tmp[4];
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001045
Denys Vlasenko3a5e5f812007-11-06 22:05:36 +08001046 tmp[0] = be32_to_cpu(src[0]);
1047 tmp[1] = be32_to_cpu(src[1]);
1048 tmp[2] = be32_to_cpu(src[2]);
1049 tmp[3] = be32_to_cpu(src[3]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001050
Jussi Kivilinnae2861a72012-03-05 20:26:37 +02001051 if (cctx->key_length == 16)
1052 max = 24;
1053 else
1054 max = 32; /* for key lengths of 24 and 32 */
1055
1056 camellia_do_decrypt(cctx->key_table, tmp, max);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001057
Denys Vlasenkoacca79a2007-11-23 21:10:03 +08001058 /* do_decrypt returns 0,1 swapped with 2,3 */
1059 dst[0] = cpu_to_be32(tmp[2]);
1060 dst[1] = cpu_to_be32(tmp[3]);
1061 dst[2] = cpu_to_be32(tmp[0]);
1062 dst[3] = cpu_to_be32(tmp[1]);
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001063}
1064
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001065static struct crypto_alg camellia_alg = {
1066 .cra_name = "camellia",
1067 .cra_driver_name = "camellia-generic",
1068 .cra_priority = 100,
1069 .cra_flags = CRYPTO_ALG_TYPE_CIPHER,
1070 .cra_blocksize = CAMELLIA_BLOCK_SIZE,
1071 .cra_ctxsize = sizeof(struct camellia_ctx),
1072 .cra_alignmask = 3,
1073 .cra_module = THIS_MODULE,
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001074 .cra_u = {
1075 .cipher = {
1076 .cia_min_keysize = CAMELLIA_MIN_KEY_SIZE,
1077 .cia_max_keysize = CAMELLIA_MAX_KEY_SIZE,
1078 .cia_setkey = camellia_set_key,
1079 .cia_encrypt = camellia_encrypt,
1080 .cia_decrypt = camellia_decrypt
1081 }
1082 }
1083};
1084
1085static int __init camellia_init(void)
1086{
1087 return crypto_register_alg(&camellia_alg);
1088}
1089
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001090static void __exit camellia_fini(void)
1091{
1092 crypto_unregister_alg(&camellia_alg);
1093}
1094
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001095module_init(camellia_init);
1096module_exit(camellia_fini);
1097
Noriaki TAKAMIYAd64beac2007-01-24 21:47:48 +11001098MODULE_DESCRIPTION("Camellia Cipher Algorithm");
1099MODULE_LICENSE("GPL");
Kees Cook5d26a102014-11-20 17:05:53 -08001100MODULE_ALIAS_CRYPTO("camellia");
Mathias Krause3e14dcf2015-01-11 18:17:42 +01001101MODULE_ALIAS_CRYPTO("camellia-generic");