1/* 2 * Camellia Cipher Algorithm (x86_64) 3 * 4 * Copyright (C) 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> 5 * 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. 10 * 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. 15 * 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 19 * USA 20 * 21 */ 22 23#include <linux/linkage.h> 24 25.file "camellia-x86_64-asm_64.S" 26.text 27 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; 36 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 45 46#define CAMELLIA_TABLE_BYTE_LEN 272 47 48/* struct camellia_ctx: */ 49#define key_table 0 50#define key_length CAMELLIA_TABLE_BYTE_LEN 51 52/* register macros */ 53#define CTX %rdi 54#define RIO %rsi 55#define RIOd %esi 56 57#define RAB0 %rax 58#define RCD0 %rcx 59#define RAB1 %rbx 60#define RCD1 %rdx 61 62#define RAB0d %eax 63#define RCD0d %ecx 64#define RAB1d %ebx 65#define RCD1d %edx 66 67#define RAB0bl %al 68#define RCD0bl %cl 69#define RAB1bl %bl 70#define RCD1bl %dl 71 72#define RAB0bh %ah 73#define RCD0bh %ch 74#define RAB1bh %bh 75#define RCD1bh %dh 76 77#define RT0 %rsi 78#define RT1 %r12 79#define RT2 %r8 80 81#define RT0d %esi 82#define RT1d %r12d 83#define RT2d %r8d 84 85#define RT2bl %r8b 86 87#define RXOR %r9 88#define RR12 %r10 89#define RDST %r11 90 91#define RXORd %r9d 92#define RXORbl %r9b 93 94#define xor2ror16(T0, T1, tmp1, tmp2, ab, dst) \ 95 movzbl ab ## bl, tmp2 ## d; \ 96 movzbl ab ## bh, tmp1 ## d; \ 97 rorq $16, ab; \ 98 xorq T0(, tmp2, 8), dst; \ 99 xorq T1(, tmp1, 8), dst; 100 101/********************************************************************** 102 1-way camellia 103 **********************************************************************/ 104#define roundsm(ab, subkey, cd) \ 105 movq (key_table + ((subkey) * 2) * 4)(CTX), RT2; \ 106 \ 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); \ 111 \ 112 xorq RT2, cd ## 0; 113 114#define fls(l, r, kl, kr) \ 115 movl (key_table + ((kl) * 2) * 4)(CTX), RT0d; \ 116 andl l ## 0d, RT0d; \ 117 roll $1, RT0d; \ 118 shlq $32, RT0; \ 119 xorq RT0, l ## 0; \ 120 movq (key_table + ((kr) * 2) * 4)(CTX), RT1; \ 121 orq r ## 0, RT1; \ 122 shrq $32, RT1; \ 123 xorq RT1, r ## 0; \ 124 \ 125 movq (key_table + ((kl) * 2) * 4)(CTX), RT2; \ 126 orq l ## 0, RT2; \ 127 shrq $32, RT2; \ 128 xorq RT2, l ## 0; \ 129 movl (key_table + ((kr) * 2) * 4)(CTX), RT0d; \ 130 andl r ## 0d, RT0d; \ 131 roll $1, RT0d; \ 132 shlq $32, RT0; \ 133 xorq RT0, r ## 0; 134 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); 142 143#define enc_fls(i) \ 144 fls(RAB, RCD, i + 0, i + 1); 145 146#define enc_inpack() \ 147 movq (RIO), RAB0; \ 148 bswapq RAB0; \ 149 rolq $32, RAB0; \ 150 movq 4*2(RIO), RCD0; \ 151 bswapq RCD0; \ 152 rorq $32, RCD0; \ 153 xorq key_table(CTX), RAB0; 154 155#define enc_outunpack(op, max) \ 156 xorq key_table(CTX, max, 8), RCD0; \ 157 rorq $32, RCD0; \ 158 bswapq RCD0; \ 159 op ## q RCD0, (RIO); \ 160 rolq $32, RAB0; \ 161 bswapq RAB0; \ 162 op ## q RAB0, 4*2(RIO); 163 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); 171 172#define dec_fls(i) \ 173 fls(RAB, RCD, i + 1, i + 0); 174 175#define dec_inpack(max) \ 176 movq (RIO), RAB0; \ 177 bswapq RAB0; \ 178 rolq $32, RAB0; \ 179 movq 4*2(RIO), RCD0; \ 180 bswapq RCD0; \ 181 rorq $32, RCD0; \ 182 xorq key_table(CTX, max, 8), RAB0; 183 184#define dec_outunpack() \ 185 xorq key_table(CTX), RCD0; \ 186 rorq $32, RCD0; \ 187 bswapq RCD0; \ 188 movq RCD0, (RIO); \ 189 rolq $32, RAB0; \ 190 bswapq RAB0; \ 191 movq RAB0, 4*2(RIO); 192 193ENTRY(__camellia_enc_blk) 194 /* input: 195 * %rdi: ctx, CTX 196 * %rsi: dst 197 * %rdx: src 198 * %rcx: bool xor 199 */ 200 movq %r12, RR12; 201 202 movq %rcx, RXOR; 203 movq %rsi, RDST; 204 movq %rdx, RIO; 205 206 enc_inpack(); 207 208 enc_rounds(0); 209 enc_fls(8); 210 enc_rounds(8); 211 enc_fls(16); 212 enc_rounds(16); 213 movl $24, RT1d; /* max */ 214 215 cmpb $16, key_length(CTX); 216 je .L__enc_done; 217 218 enc_fls(24); 219 enc_rounds(24); 220 movl $32, RT1d; /* max */ 221 222.L__enc_done: 223 testb RXORbl, RXORbl; 224 movq RDST, RIO; 225 226 jnz .L__enc_xor; 227 228 enc_outunpack(mov, RT1); 229 230 movq RR12, %r12; 231 ret; 232 233.L__enc_xor: 234 enc_outunpack(xor, RT1); 235 236 movq RR12, %r12; 237 ret; 238ENDPROC(__camellia_enc_blk) 239 240ENTRY(camellia_dec_blk) 241 /* input: 242 * %rdi: ctx, CTX 243 * %rsi: dst 244 * %rdx: src 245 */ 246 cmpl $16, key_length(CTX); 247 movl $32, RT2d; 248 movl $24, RXORd; 249 cmovel RXORd, RT2d; /* max */ 250 251 movq %r12, RR12; 252 movq %rsi, RDST; 253 movq %rdx, RIO; 254 255 dec_inpack(RT2); 256 257 cmpb $24, RT2bl; 258 je .L__dec_rounds16; 259 260 dec_rounds(24); 261 dec_fls(24); 262 263.L__dec_rounds16: 264 dec_rounds(16); 265 dec_fls(16); 266 dec_rounds(8); 267 dec_fls(8); 268 dec_rounds(0); 269 270 movq RDST, RIO; 271 272 dec_outunpack(); 273 274 movq RR12, %r12; 275 ret; 276ENDPROC(camellia_dec_blk) 277 278/********************************************************************** 279 2-way camellia 280 **********************************************************************/ 281#define roundsm2(ab, subkey, cd) \ 282 movq (key_table + ((subkey) * 2) * 4)(CTX), RT2; \ 283 xorq RT2, cd ## 1; \ 284 \ 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); \ 289 \ 290 xor2ror16(sp00444404, sp03303033, RT0, RT1, ab ## 1, cd ## 1); \ 291 xorq RT2, cd ## 0; \ 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); 295 296#define fls2(l, r, kl, kr) \ 297 movl (key_table + ((kl) * 2) * 4)(CTX), RT0d; \ 298 andl l ## 0d, RT0d; \ 299 roll $1, RT0d; \ 300 shlq $32, RT0; \ 301 xorq RT0, l ## 0; \ 302 movq (key_table + ((kr) * 2) * 4)(CTX), RT1; \ 303 orq r ## 0, RT1; \ 304 shrq $32, RT1; \ 305 xorq RT1, r ## 0; \ 306 \ 307 movl (key_table + ((kl) * 2) * 4)(CTX), RT2d; \ 308 andl l ## 1d, RT2d; \ 309 roll $1, RT2d; \ 310 shlq $32, RT2; \ 311 xorq RT2, l ## 1; \ 312 movq (key_table + ((kr) * 2) * 4)(CTX), RT0; \ 313 orq r ## 1, RT0; \ 314 shrq $32, RT0; \ 315 xorq RT0, r ## 1; \ 316 \ 317 movq (key_table + ((kl) * 2) * 4)(CTX), RT1; \ 318 orq l ## 0, RT1; \ 319 shrq $32, RT1; \ 320 xorq RT1, l ## 0; \ 321 movl (key_table + ((kr) * 2) * 4)(CTX), RT2d; \ 322 andl r ## 0d, RT2d; \ 323 roll $1, RT2d; \ 324 shlq $32, RT2; \ 325 xorq RT2, r ## 0; \ 326 \ 327 movq (key_table + ((kl) * 2) * 4)(CTX), RT0; \ 328 orq l ## 1, RT0; \ 329 shrq $32, RT0; \ 330 xorq RT0, l ## 1; \ 331 movl (key_table + ((kr) * 2) * 4)(CTX), RT1d; \ 332 andl r ## 1d, RT1d; \ 333 roll $1, RT1d; \ 334 shlq $32, RT1; \ 335 xorq RT1, r ## 1; 336 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); 344 345#define enc_fls2(i) \ 346 fls2(RAB, RCD, i + 0, i + 1); 347 348#define enc_inpack2() \ 349 movq (RIO), RAB0; \ 350 bswapq RAB0; \ 351 rorq $32, RAB0; \ 352 movq 4*2(RIO), RCD0; \ 353 bswapq RCD0; \ 354 rolq $32, RCD0; \ 355 xorq key_table(CTX), RAB0; \ 356 \ 357 movq 8*2(RIO), RAB1; \ 358 bswapq RAB1; \ 359 rorq $32, RAB1; \ 360 movq 12*2(RIO), RCD1; \ 361 bswapq RCD1; \ 362 rolq $32, RCD1; \ 363 xorq key_table(CTX), RAB1; 364 365#define enc_outunpack2(op, max) \ 366 xorq key_table(CTX, max, 8), RCD0; \ 367 rolq $32, RCD0; \ 368 bswapq RCD0; \ 369 op ## q RCD0, (RIO); \ 370 rorq $32, RAB0; \ 371 bswapq RAB0; \ 372 op ## q RAB0, 4*2(RIO); \ 373 \ 374 xorq key_table(CTX, max, 8), RCD1; \ 375 rolq $32, RCD1; \ 376 bswapq RCD1; \ 377 op ## q RCD1, 8*2(RIO); \ 378 rorq $32, RAB1; \ 379 bswapq RAB1; \ 380 op ## q RAB1, 12*2(RIO); 381 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); 389 390#define dec_fls2(i) \ 391 fls2(RAB, RCD, i + 1, i + 0); 392 393#define dec_inpack2(max) \ 394 movq (RIO), RAB0; \ 395 bswapq RAB0; \ 396 rorq $32, RAB0; \ 397 movq 4*2(RIO), RCD0; \ 398 bswapq RCD0; \ 399 rolq $32, RCD0; \ 400 xorq key_table(CTX, max, 8), RAB0; \ 401 \ 402 movq 8*2(RIO), RAB1; \ 403 bswapq RAB1; \ 404 rorq $32, RAB1; \ 405 movq 12*2(RIO), RCD1; \ 406 bswapq RCD1; \ 407 rolq $32, RCD1; \ 408 xorq key_table(CTX, max, 8), RAB1; 409 410#define dec_outunpack2() \ 411 xorq key_table(CTX), RCD0; \ 412 rolq $32, RCD0; \ 413 bswapq RCD0; \ 414 movq RCD0, (RIO); \ 415 rorq $32, RAB0; \ 416 bswapq RAB0; \ 417 movq RAB0, 4*2(RIO); \ 418 \ 419 xorq key_table(CTX), RCD1; \ 420 rolq $32, RCD1; \ 421 bswapq RCD1; \ 422 movq RCD1, 8*2(RIO); \ 423 rorq $32, RAB1; \ 424 bswapq RAB1; \ 425 movq RAB1, 12*2(RIO); 426 427ENTRY(__camellia_enc_blk_2way) 428 /* input: 429 * %rdi: ctx, CTX 430 * %rsi: dst 431 * %rdx: src 432 * %rcx: bool xor 433 */ 434 pushq %rbx; 435 436 movq %r12, RR12; 437 movq %rcx, RXOR; 438 movq %rsi, RDST; 439 movq %rdx, RIO; 440 441 enc_inpack2(); 442 443 enc_rounds2(0); 444 enc_fls2(8); 445 enc_rounds2(8); 446 enc_fls2(16); 447 enc_rounds2(16); 448 movl $24, RT2d; /* max */ 449 450 cmpb $16, key_length(CTX); 451 je .L__enc2_done; 452 453 enc_fls2(24); 454 enc_rounds2(24); 455 movl $32, RT2d; /* max */ 456 457.L__enc2_done: 458 test RXORbl, RXORbl; 459 movq RDST, RIO; 460 jnz .L__enc2_xor; 461 462 enc_outunpack2(mov, RT2); 463 464 movq RR12, %r12; 465 popq %rbx; 466 ret; 467 468.L__enc2_xor: 469 enc_outunpack2(xor, RT2); 470 471 movq RR12, %r12; 472 popq %rbx; 473 ret; 474ENDPROC(__camellia_enc_blk_2way) 475 476ENTRY(camellia_dec_blk_2way) 477 /* input: 478 * %rdi: ctx, CTX 479 * %rsi: dst 480 * %rdx: src 481 */ 482 cmpl $16, key_length(CTX); 483 movl $32, RT2d; 484 movl $24, RXORd; 485 cmovel RXORd, RT2d; /* max */ 486 487 movq %rbx, RXOR; 488 movq %r12, RR12; 489 movq %rsi, RDST; 490 movq %rdx, RIO; 491 492 dec_inpack2(RT2); 493 494 cmpb $24, RT2bl; 495 je .L__dec2_rounds16; 496 497 dec_rounds2(24); 498 dec_fls2(24); 499 500.L__dec2_rounds16: 501 dec_rounds2(16); 502 dec_fls2(16); 503 dec_rounds2(8); 504 dec_fls2(8); 505 dec_rounds2(0); 506 507 movq RDST, RIO; 508 509 dec_outunpack2(); 510 511 movq RR12, %r12; 512 movq RXOR, %rbx; 513 ret; 514ENDPROC(camellia_dec_blk_2way) 515