linux/arch/x86/crypto/cast6-avx-x86_64-asm_64.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * Cast6 Cipher 8-way parallel algorithm (AVX/x86_64)
   4 *
   5 * Copyright (C) 2012 Johannes Goetzfried
   6 *     <Johannes.Goetzfried@informatik.stud.uni-erlangen.de>
   7 *
   8 * Copyright © 2012-2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
   9 */
  10
  11#include <linux/linkage.h>
  12#include <asm/frame.h>
  13#include "glue_helper-asm-avx.S"
  14
  15.file "cast6-avx-x86_64-asm_64.S"
  16
  17.extern cast_s1
  18.extern cast_s2
  19.extern cast_s3
  20.extern cast_s4
  21
  22/* structure of crypto context */
  23#define km      0
  24#define kr      (12*4*4)
  25
  26/* s-boxes */
  27#define s1      cast_s1
  28#define s2      cast_s2
  29#define s3      cast_s3
  30#define s4      cast_s4
  31
  32/**********************************************************************
  33  8-way AVX cast6
  34 **********************************************************************/
  35#define CTX %r15
  36
  37#define RA1 %xmm0
  38#define RB1 %xmm1
  39#define RC1 %xmm2
  40#define RD1 %xmm3
  41
  42#define RA2 %xmm4
  43#define RB2 %xmm5
  44#define RC2 %xmm6
  45#define RD2 %xmm7
  46
  47#define RX  %xmm8
  48
  49#define RKM  %xmm9
  50#define RKR  %xmm10
  51#define RKRF %xmm11
  52#define RKRR %xmm12
  53#define R32  %xmm13
  54#define R1ST %xmm14
  55
  56#define RTMP %xmm15
  57
  58#define RID1  %rdi
  59#define RID1d %edi
  60#define RID2  %rsi
  61#define RID2d %esi
  62
  63#define RGI1   %rdx
  64#define RGI1bl %dl
  65#define RGI1bh %dh
  66#define RGI2   %rcx
  67#define RGI2bl %cl
  68#define RGI2bh %ch
  69
  70#define RGI3   %rax
  71#define RGI3bl %al
  72#define RGI3bh %ah
  73#define RGI4   %rbx
  74#define RGI4bl %bl
  75#define RGI4bh %bh
  76
  77#define RFS1  %r8
  78#define RFS1d %r8d
  79#define RFS2  %r9
  80#define RFS2d %r9d
  81#define RFS3  %r10
  82#define RFS3d %r10d
  83
  84
  85#define lookup_32bit(src, dst, op1, op2, op3, interleave_op, il_reg) \
  86        movzbl          src ## bh,     RID1d;    \
  87        movzbl          src ## bl,     RID2d;    \
  88        shrq $16,       src;                     \
  89        movl            s1(, RID1, 4), dst ## d; \
  90        op1             s2(, RID2, 4), dst ## d; \
  91        movzbl          src ## bh,     RID1d;    \
  92        movzbl          src ## bl,     RID2d;    \
  93        interleave_op(il_reg);                   \
  94        op2             s3(, RID1, 4), dst ## d; \
  95        op3             s4(, RID2, 4), dst ## d;
  96
  97#define dummy(d) /* do nothing */
  98
  99#define shr_next(reg) \
 100        shrq $16,       reg;
 101
 102#define F_head(a, x, gi1, gi2, op0) \
 103        op0     a,      RKM,  x;                 \
 104        vpslld  RKRF,   x,    RTMP;              \
 105        vpsrld  RKRR,   x,    x;                 \
 106        vpor    RTMP,   x,    x;                 \
 107        \
 108        vmovq           x,    gi1;               \
 109        vpextrq $1,     x,    gi2;
 110
 111#define F_tail(a, x, gi1, gi2, op1, op2, op3) \
 112        lookup_32bit(##gi1, RFS1, op1, op2, op3, shr_next, ##gi1); \
 113        lookup_32bit(##gi2, RFS3, op1, op2, op3, shr_next, ##gi2); \
 114        \
 115        lookup_32bit(##gi1, RFS2, op1, op2, op3, dummy, none);     \
 116        shlq $32,       RFS2;                                      \
 117        orq             RFS1, RFS2;                                \
 118        lookup_32bit(##gi2, RFS1, op1, op2, op3, dummy, none);     \
 119        shlq $32,       RFS1;                                      \
 120        orq             RFS1, RFS3;                                \
 121        \
 122        vmovq           RFS2, x;                                   \
 123        vpinsrq $1,     RFS3, x, x;
 124
 125#define F_2(a1, b1, a2, b2, op0, op1, op2, op3) \
 126        F_head(b1, RX, RGI1, RGI2, op0);              \
 127        F_head(b2, RX, RGI3, RGI4, op0);              \
 128        \
 129        F_tail(b1, RX, RGI1, RGI2, op1, op2, op3);    \
 130        F_tail(b2, RTMP, RGI3, RGI4, op1, op2, op3);  \
 131        \
 132        vpxor           a1, RX,   a1;                 \
 133        vpxor           a2, RTMP, a2;
 134
 135#define F1_2(a1, b1, a2, b2) \
 136        F_2(a1, b1, a2, b2, vpaddd, xorl, subl, addl)
 137#define F2_2(a1, b1, a2, b2) \
 138        F_2(a1, b1, a2, b2, vpxor, subl, addl, xorl)
 139#define F3_2(a1, b1, a2, b2) \
 140        F_2(a1, b1, a2, b2, vpsubd, addl, xorl, subl)
 141
 142#define qop(in, out, f) \
 143        F ## f ## _2(out ## 1, in ## 1, out ## 2, in ## 2);
 144
 145#define get_round_keys(nn) \
 146        vbroadcastss    (km+(4*(nn)))(CTX), RKM;        \
 147        vpand           R1ST,               RKR,  RKRF; \
 148        vpsubq          RKRF,               R32,  RKRR; \
 149        vpsrldq $1,     RKR,                RKR;
 150
 151#define Q(n) \
 152        get_round_keys(4*n+0); \
 153        qop(RD, RC, 1);        \
 154        \
 155        get_round_keys(4*n+1); \
 156        qop(RC, RB, 2);        \
 157        \
 158        get_round_keys(4*n+2); \
 159        qop(RB, RA, 3);        \
 160        \
 161        get_round_keys(4*n+3); \
 162        qop(RA, RD, 1);
 163
 164#define QBAR(n) \
 165        get_round_keys(4*n+3); \
 166        qop(RA, RD, 1);        \
 167        \
 168        get_round_keys(4*n+2); \
 169        qop(RB, RA, 3);        \
 170        \
 171        get_round_keys(4*n+1); \
 172        qop(RC, RB, 2);        \
 173        \
 174        get_round_keys(4*n+0); \
 175        qop(RD, RC, 1);
 176
 177#define shuffle(mask) \
 178        vpshufb         mask,            RKR, RKR;
 179
 180#define preload_rkr(n, do_mask, mask) \
 181        vbroadcastss    .L16_mask,                RKR;      \
 182        /* add 16-bit rotation to key rotations (mod 32) */ \
 183        vpxor           (kr+n*16)(CTX),           RKR, RKR; \
 184        do_mask(mask);
 185
 186#define transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
 187        vpunpckldq              x1, x0, t0; \
 188        vpunpckhdq              x1, x0, t2; \
 189        vpunpckldq              x3, x2, t1; \
 190        vpunpckhdq              x3, x2, x3; \
 191        \
 192        vpunpcklqdq             t1, t0, x0; \
 193        vpunpckhqdq             t1, t0, x1; \
 194        vpunpcklqdq             x3, t2, x2; \
 195        vpunpckhqdq             x3, t2, x3;
 196
 197#define inpack_blocks(x0, x1, x2, x3, t0, t1, t2, rmask) \
 198        vpshufb rmask, x0,      x0; \
 199        vpshufb rmask, x1,      x1; \
 200        vpshufb rmask, x2,      x2; \
 201        vpshufb rmask, x3,      x3; \
 202        \
 203        transpose_4x4(x0, x1, x2, x3, t0, t1, t2)
 204
 205#define outunpack_blocks(x0, x1, x2, x3, t0, t1, t2, rmask) \
 206        transpose_4x4(x0, x1, x2, x3, t0, t1, t2) \
 207        \
 208        vpshufb rmask,          x0, x0;       \
 209        vpshufb rmask,          x1, x1;       \
 210        vpshufb rmask,          x2, x2;       \
 211        vpshufb rmask,          x3, x3;
 212
 213.section        .rodata.cst16, "aM", @progbits, 16
 214.align 16
 215.Lxts_gf128mul_and_shl1_mask:
 216        .byte 0x87, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0
 217.Lbswap_mask:
 218        .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
 219.Lbswap128_mask:
 220        .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
 221.Lrkr_enc_Q_Q_QBAR_QBAR:
 222        .byte 0, 1, 2, 3, 4, 5, 6, 7, 11, 10, 9, 8, 15, 14, 13, 12
 223.Lrkr_enc_QBAR_QBAR_QBAR_QBAR:
 224        .byte 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12
 225.Lrkr_dec_Q_Q_Q_Q:
 226        .byte 12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3
 227.Lrkr_dec_Q_Q_QBAR_QBAR:
 228        .byte 12, 13, 14, 15, 8, 9, 10, 11, 7, 6, 5, 4, 3, 2, 1, 0
 229.Lrkr_dec_QBAR_QBAR_QBAR_QBAR:
 230        .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
 231
 232.section        .rodata.cst4.L16_mask, "aM", @progbits, 4
 233.align 4
 234.L16_mask:
 235        .byte 16, 16, 16, 16
 236
 237.section        .rodata.cst4.L32_mask, "aM", @progbits, 4
 238.align 4
 239.L32_mask:
 240        .byte 32, 0, 0, 0
 241
 242.section        .rodata.cst4.first_mask, "aM", @progbits, 4
 243.align 4
 244.Lfirst_mask:
 245        .byte 0x1f, 0, 0, 0
 246
 247.text
 248
 249.align 8
 250SYM_FUNC_START_LOCAL(__cast6_enc_blk8)
 251        /* input:
 252         *      %rdi: ctx
 253         *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: blocks
 254         * output:
 255         *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks
 256         */
 257
 258        pushq %r15;
 259        pushq %rbx;
 260
 261        movq %rdi, CTX;
 262
 263        vmovdqa .Lbswap_mask, RKM;
 264        vmovd .Lfirst_mask, R1ST;
 265        vmovd .L32_mask, R32;
 266
 267        inpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
 268        inpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
 269
 270        preload_rkr(0, dummy, none);
 271        Q(0);
 272        Q(1);
 273        Q(2);
 274        Q(3);
 275        preload_rkr(1, shuffle, .Lrkr_enc_Q_Q_QBAR_QBAR);
 276        Q(4);
 277        Q(5);
 278        QBAR(6);
 279        QBAR(7);
 280        preload_rkr(2, shuffle, .Lrkr_enc_QBAR_QBAR_QBAR_QBAR);
 281        QBAR(8);
 282        QBAR(9);
 283        QBAR(10);
 284        QBAR(11);
 285
 286        popq %rbx;
 287        popq %r15;
 288
 289        vmovdqa .Lbswap_mask, RKM;
 290
 291        outunpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
 292        outunpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
 293
 294        ret;
 295SYM_FUNC_END(__cast6_enc_blk8)
 296
 297.align 8
 298SYM_FUNC_START_LOCAL(__cast6_dec_blk8)
 299        /* input:
 300         *      %rdi: ctx
 301         *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: encrypted blocks
 302         * output:
 303         *      RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2: decrypted blocks
 304         */
 305
 306        pushq %r15;
 307        pushq %rbx;
 308
 309        movq %rdi, CTX;
 310
 311        vmovdqa .Lbswap_mask, RKM;
 312        vmovd .Lfirst_mask, R1ST;
 313        vmovd .L32_mask, R32;
 314
 315        inpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
 316        inpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
 317
 318        preload_rkr(2, shuffle, .Lrkr_dec_Q_Q_Q_Q);
 319        Q(11);
 320        Q(10);
 321        Q(9);
 322        Q(8);
 323        preload_rkr(1, shuffle, .Lrkr_dec_Q_Q_QBAR_QBAR);
 324        Q(7);
 325        Q(6);
 326        QBAR(5);
 327        QBAR(4);
 328        preload_rkr(0, shuffle, .Lrkr_dec_QBAR_QBAR_QBAR_QBAR);
 329        QBAR(3);
 330        QBAR(2);
 331        QBAR(1);
 332        QBAR(0);
 333
 334        popq %rbx;
 335        popq %r15;
 336
 337        vmovdqa .Lbswap_mask, RKM;
 338        outunpack_blocks(RA1, RB1, RC1, RD1, RTMP, RX, RKRF, RKM);
 339        outunpack_blocks(RA2, RB2, RC2, RD2, RTMP, RX, RKRF, RKM);
 340
 341        ret;
 342SYM_FUNC_END(__cast6_dec_blk8)
 343
 344SYM_FUNC_START(cast6_ecb_enc_8way)
 345        /* input:
 346         *      %rdi: ctx
 347         *      %rsi: dst
 348         *      %rdx: src
 349         */
 350        FRAME_BEGIN
 351        pushq %r15;
 352
 353        movq %rdi, CTX;
 354        movq %rsi, %r11;
 355
 356        load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 357
 358        call __cast6_enc_blk8;
 359
 360        store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 361
 362        popq %r15;
 363        FRAME_END
 364        ret;
 365SYM_FUNC_END(cast6_ecb_enc_8way)
 366
 367SYM_FUNC_START(cast6_ecb_dec_8way)
 368        /* input:
 369         *      %rdi: ctx
 370         *      %rsi: dst
 371         *      %rdx: src
 372         */
 373        FRAME_BEGIN
 374        pushq %r15;
 375
 376        movq %rdi, CTX;
 377        movq %rsi, %r11;
 378
 379        load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 380
 381        call __cast6_dec_blk8;
 382
 383        store_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 384
 385        popq %r15;
 386        FRAME_END
 387        ret;
 388SYM_FUNC_END(cast6_ecb_dec_8way)
 389
 390SYM_FUNC_START(cast6_cbc_dec_8way)
 391        /* input:
 392         *      %rdi: ctx
 393         *      %rsi: dst
 394         *      %rdx: src
 395         */
 396        FRAME_BEGIN
 397        pushq %r12;
 398        pushq %r15;
 399
 400        movq %rdi, CTX;
 401        movq %rsi, %r11;
 402        movq %rdx, %r12;
 403
 404        load_8way(%rdx, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 405
 406        call __cast6_dec_blk8;
 407
 408        store_cbc_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 409
 410        popq %r15;
 411        popq %r12;
 412        FRAME_END
 413        ret;
 414SYM_FUNC_END(cast6_cbc_dec_8way)
 415
 416SYM_FUNC_START(cast6_ctr_8way)
 417        /* input:
 418         *      %rdi: ctx, CTX
 419         *      %rsi: dst
 420         *      %rdx: src
 421         *      %rcx: iv (little endian, 128bit)
 422         */
 423        FRAME_BEGIN
 424        pushq %r12;
 425        pushq %r15
 426
 427        movq %rdi, CTX;
 428        movq %rsi, %r11;
 429        movq %rdx, %r12;
 430
 431        load_ctr_8way(%rcx, .Lbswap128_mask, RA1, RB1, RC1, RD1, RA2, RB2, RC2,
 432                      RD2, RX, RKR, RKM);
 433
 434        call __cast6_enc_blk8;
 435
 436        store_ctr_8way(%r12, %r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 437
 438        popq %r15;
 439        popq %r12;
 440        FRAME_END
 441        ret;
 442SYM_FUNC_END(cast6_ctr_8way)
 443
 444SYM_FUNC_START(cast6_xts_enc_8way)
 445        /* input:
 446         *      %rdi: ctx, CTX
 447         *      %rsi: dst
 448         *      %rdx: src
 449         *      %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸))
 450         */
 451        FRAME_BEGIN
 452        pushq %r15;
 453
 454        movq %rdi, CTX
 455        movq %rsi, %r11;
 456
 457        /* regs <= src, dst <= IVs, regs <= regs xor IVs */
 458        load_xts_8way(%rcx, %rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2,
 459                      RX, RKR, RKM, .Lxts_gf128mul_and_shl1_mask);
 460
 461        call __cast6_enc_blk8;
 462
 463        /* dst <= regs xor IVs(in dst) */
 464        store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 465
 466        popq %r15;
 467        FRAME_END
 468        ret;
 469SYM_FUNC_END(cast6_xts_enc_8way)
 470
 471SYM_FUNC_START(cast6_xts_dec_8way)
 472        /* input:
 473         *      %rdi: ctx, CTX
 474         *      %rsi: dst
 475         *      %rdx: src
 476         *      %rcx: iv (t ⊕ αⁿ ∈ GF(2¹²⁸))
 477         */
 478        FRAME_BEGIN
 479        pushq %r15;
 480
 481        movq %rdi, CTX
 482        movq %rsi, %r11;
 483
 484        /* regs <= src, dst <= IVs, regs <= regs xor IVs */
 485        load_xts_8way(%rcx, %rdx, %rsi, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2,
 486                      RX, RKR, RKM, .Lxts_gf128mul_and_shl1_mask);
 487
 488        call __cast6_dec_blk8;
 489
 490        /* dst <= regs xor IVs(in dst) */
 491        store_xts_8way(%r11, RA1, RB1, RC1, RD1, RA2, RB2, RC2, RD2);
 492
 493        popq %r15;
 494        FRAME_END
 495        ret;
 496SYM_FUNC_END(cast6_xts_dec_8way)
 497