2 * Camellia Cipher Algorithm (x86_64)
4 * Copyright (C) 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 #include <linux/linkage.h>
25 .file "camellia-x86_64-asm_64.S"
28 .extern camellia_sp10011110;
29 .extern camellia_sp22000222;
30 .extern camellia_sp03303033;
31 .extern camellia_sp00444404;
32 .extern camellia_sp02220222;
33 .extern camellia_sp30333033;
34 .extern camellia_sp44044404;
35 .extern camellia_sp11101110;
37 #define sp10011110 camellia_sp10011110
38 #define sp22000222 camellia_sp22000222
39 #define sp03303033 camellia_sp03303033
40 #define sp00444404 camellia_sp00444404
41 #define sp02220222 camellia_sp02220222
42 #define sp30333033 camellia_sp30333033
43 #define sp44044404 camellia_sp44044404
44 #define sp11101110 camellia_sp11101110
46 #define CAMELLIA_TABLE_BYTE_LEN 272
48 /* struct camellia_ctx: */
50 #define key_length CAMELLIA_TABLE_BYTE_LEN
94 #define xor2ror16(T0, T1, tmp1, tmp2, ab, dst) \
95 movzbl ab ## bl, tmp2 ## d; \
96 movzbl ab ## bh, tmp1 ## d; \
98 xorq T0(, tmp2, 8), dst; \
99 xorq T1(, tmp1, 8), dst;
101 /**********************************************************************
103 **********************************************************************/
104 #define roundsm(ab, subkey, cd) \
105 movq (key_table + ((subkey) * 2) * 4)(CTX), RT2; \
107 xor2ror16(sp00444404, sp03303033, RT0, RT1, ab ## 0, cd ## 0); \
108 xor2ror16(sp22000222, sp10011110, RT0, RT1, ab ## 0, RT2); \
109 xor2ror16(sp11101110, sp44044404, RT0, RT1, ab ## 0, cd ## 0); \
110 xor2ror16(sp30333033, sp02220222, RT0, RT1, ab ## 0, RT2); \
114 #define fls(l, r, kl, kr) \
115 movl (key_table + ((kl) * 2) * 4)(CTX), RT0d; \
116 andl l ## 0d, RT0d; \
120 movq (key_table + ((kr) * 2) * 4)(CTX), RT1; \
125 movq (key_table + ((kl) * 2) * 4)(CTX), RT2; \
129 movl (key_table + ((kr) * 2) * 4)(CTX), RT0d; \
130 andl r ## 0d, RT0d; \
135 #define enc_rounds(i) \
136 roundsm(RAB, i + 2, RCD); \
137 roundsm(RCD, i + 3, RAB); \
138 roundsm(RAB, i + 4, RCD); \
139 roundsm(RCD, i + 5, RAB); \
140 roundsm(RAB, i + 6, RCD); \
141 roundsm(RCD, i + 7, RAB);
144 fls(RAB, RCD, i + 0, i + 1);
146 #define enc_inpack() \
150 movq 4*2(RIO), RCD0; \
153 xorq key_table(CTX), RAB0;
155 #define enc_outunpack(op, max) \
156 xorq key_table(CTX, max, 8), RCD0; \
159 op ## q RCD0, (RIO); \
162 op ## q RAB0, 4*2(RIO);
164 #define dec_rounds(i) \
165 roundsm(RAB, i + 7, RCD); \
166 roundsm(RCD, i + 6, RAB); \
167 roundsm(RAB, i + 5, RCD); \
168 roundsm(RCD, i + 4, RAB); \
169 roundsm(RAB, i + 3, RCD); \
170 roundsm(RCD, i + 2, RAB);
173 fls(RAB, RCD, i + 1, i + 0);
175 #define dec_inpack(max) \
179 movq 4*2(RIO), RCD0; \
182 xorq key_table(CTX, max, 8), RAB0;
184 #define dec_outunpack() \
185 xorq key_table(CTX), RCD0; \
193 ENTRY(__camellia_enc_blk)
213 movl $24, RT1d; /* max */
215 cmpb $16, key_length(CTX);
220 movl $32, RT1d; /* max */
223 testb RXORbl, RXORbl;
228 enc_outunpack(mov, RT1);
234 enc_outunpack(xor, RT1);
238 ENDPROC(__camellia_enc_blk)
240 ENTRY(camellia_dec_blk)
246 cmpl $16, key_length(CTX);
249 cmovel RXORd, RT2d; /* max */
276 ENDPROC(camellia_dec_blk)
278 /**********************************************************************
280 **********************************************************************/
281 #define roundsm2(ab, subkey, cd) \
282 movq (key_table + ((subkey) * 2) * 4)(CTX), RT2; \
285 xor2ror16(sp00444404, sp03303033, RT0, RT1, ab ## 0, cd ## 0); \
286 xor2ror16(sp22000222, sp10011110, RT0, RT1, ab ## 0, RT2); \
287 xor2ror16(sp11101110, sp44044404, RT0, RT1, ab ## 0, cd ## 0); \
288 xor2ror16(sp30333033, sp02220222, RT0, RT1, ab ## 0, RT2); \
290 xor2ror16(sp00444404, sp03303033, RT0, RT1, ab ## 1, cd ## 1); \
292 xor2ror16(sp22000222, sp10011110, RT0, RT1, ab ## 1, cd ## 1); \
293 xor2ror16(sp11101110, sp44044404, RT0, RT1, ab ## 1, cd ## 1); \
294 xor2ror16(sp30333033, sp02220222, RT0, RT1, ab ## 1, cd ## 1);
296 #define fls2(l, r, kl, kr) \
297 movl (key_table + ((kl) * 2) * 4)(CTX), RT0d; \
298 andl l ## 0d, RT0d; \
302 movq (key_table + ((kr) * 2) * 4)(CTX), RT1; \
307 movl (key_table + ((kl) * 2) * 4)(CTX), RT2d; \
308 andl l ## 1d, RT2d; \
312 movq (key_table + ((kr) * 2) * 4)(CTX), RT0; \
317 movq (key_table + ((kl) * 2) * 4)(CTX), RT1; \
321 movl (key_table + ((kr) * 2) * 4)(CTX), RT2d; \
322 andl r ## 0d, RT2d; \
327 movq (key_table + ((kl) * 2) * 4)(CTX), RT0; \
331 movl (key_table + ((kr) * 2) * 4)(CTX), RT1d; \
332 andl r ## 1d, RT1d; \
337 #define enc_rounds2(i) \
338 roundsm2(RAB, i + 2, RCD); \
339 roundsm2(RCD, i + 3, RAB); \
340 roundsm2(RAB, i + 4, RCD); \
341 roundsm2(RCD, i + 5, RAB); \
342 roundsm2(RAB, i + 6, RCD); \
343 roundsm2(RCD, i + 7, RAB);
345 #define enc_fls2(i) \
346 fls2(RAB, RCD, i + 0, i + 1);
348 #define enc_inpack2() \
352 movq 4*2(RIO), RCD0; \
355 xorq key_table(CTX), RAB0; \
357 movq 8*2(RIO), RAB1; \
360 movq 12*2(RIO), RCD1; \
363 xorq key_table(CTX), RAB1;
365 #define enc_outunpack2(op, max) \
366 xorq key_table(CTX, max, 8), RCD0; \
369 op ## q RCD0, (RIO); \
372 op ## q RAB0, 4*2(RIO); \
374 xorq key_table(CTX, max, 8), RCD1; \
377 op ## q RCD1, 8*2(RIO); \
380 op ## q RAB1, 12*2(RIO);
382 #define dec_rounds2(i) \
383 roundsm2(RAB, i + 7, RCD); \
384 roundsm2(RCD, i + 6, RAB); \
385 roundsm2(RAB, i + 5, RCD); \
386 roundsm2(RCD, i + 4, RAB); \
387 roundsm2(RAB, i + 3, RCD); \
388 roundsm2(RCD, i + 2, RAB);
390 #define dec_fls2(i) \
391 fls2(RAB, RCD, i + 1, i + 0);
393 #define dec_inpack2(max) \
397 movq 4*2(RIO), RCD0; \
400 xorq key_table(CTX, max, 8), RAB0; \
402 movq 8*2(RIO), RAB1; \
405 movq 12*2(RIO), RCD1; \
408 xorq key_table(CTX, max, 8), RAB1;
410 #define dec_outunpack2() \
411 xorq key_table(CTX), RCD0; \
417 movq RAB0, 4*2(RIO); \
419 xorq key_table(CTX), RCD1; \
422 movq RCD1, 8*2(RIO); \
425 movq RAB1, 12*2(RIO);
427 ENTRY(__camellia_enc_blk_2way)
448 movl $24, RT2d; /* max */
450 cmpb $16, key_length(CTX);
455 movl $32, RT2d; /* max */
462 enc_outunpack2(mov, RT2);
469 enc_outunpack2(xor, RT2);
474 ENDPROC(__camellia_enc_blk_2way)
476 ENTRY(camellia_dec_blk_2way)
482 cmpl $16, key_length(CTX);
485 cmovel RXORd, RT2d; /* max */
495 je .L__dec2_rounds16;
514 ENDPROC(camellia_dec_blk_2way)