12874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */ 2f3f935a7SJussi Kivilinna/* 3f3f935a7SJussi Kivilinna * x86_64/AVX2/AES-NI assembler implementation of Camellia 4f3f935a7SJussi Kivilinna * 5f3f935a7SJussi Kivilinna * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi> 6f3f935a7SJussi Kivilinna */ 7f3f935a7SJussi Kivilinna 8f3f935a7SJussi Kivilinna#include <linux/linkage.h> 98691ccd7SJosh Poimboeuf#include <asm/frame.h> 10f3f935a7SJussi Kivilinna 11f3f935a7SJussi Kivilinna#define CAMELLIA_TABLE_BYTE_LEN 272 12f3f935a7SJussi Kivilinna 13f3f935a7SJussi Kivilinna/* struct camellia_ctx: */ 14f3f935a7SJussi Kivilinna#define key_table 0 15f3f935a7SJussi Kivilinna#define key_length CAMELLIA_TABLE_BYTE_LEN 16f3f935a7SJussi Kivilinna 17f3f935a7SJussi Kivilinna/* register macros */ 18f3f935a7SJussi Kivilinna#define CTX %rdi 19f3f935a7SJussi Kivilinna#define RIO %r8 20f3f935a7SJussi Kivilinna 21f3f935a7SJussi Kivilinna/********************************************************************** 22f3f935a7SJussi Kivilinna helper macros 23f3f935a7SJussi Kivilinna **********************************************************************/ 24f3f935a7SJussi Kivilinna#define filter_8bit(x, lo_t, hi_t, mask4bit, tmp0) \ 25f3f935a7SJussi Kivilinna vpand x, mask4bit, tmp0; \ 26f3f935a7SJussi Kivilinna vpandn x, mask4bit, x; \ 27f3f935a7SJussi Kivilinna vpsrld $4, x, x; \ 28f3f935a7SJussi Kivilinna \ 29f3f935a7SJussi Kivilinna vpshufb tmp0, lo_t, tmp0; \ 30f3f935a7SJussi Kivilinna vpshufb x, hi_t, x; \ 31f3f935a7SJussi Kivilinna vpxor tmp0, x, x; 32f3f935a7SJussi Kivilinna 33f3f935a7SJussi Kivilinna#define ymm0_x xmm0 34f3f935a7SJussi Kivilinna#define ymm1_x xmm1 35f3f935a7SJussi Kivilinna#define ymm2_x xmm2 36f3f935a7SJussi Kivilinna#define ymm3_x xmm3 37f3f935a7SJussi Kivilinna#define ymm4_x xmm4 38f3f935a7SJussi Kivilinna#define ymm5_x xmm5 39f3f935a7SJussi Kivilinna#define ymm6_x xmm6 40f3f935a7SJussi Kivilinna#define ymm7_x xmm7 41f3f935a7SJussi Kivilinna#define ymm8_x xmm8 42f3f935a7SJussi Kivilinna#define ymm9_x xmm9 43f3f935a7SJussi Kivilinna#define ymm10_x xmm10 44f3f935a7SJussi Kivilinna#define ymm11_x xmm11 45f3f935a7SJussi Kivilinna#define ymm12_x xmm12 46f3f935a7SJussi Kivilinna#define ymm13_x xmm13 47f3f935a7SJussi Kivilinna#define ymm14_x xmm14 48f3f935a7SJussi Kivilinna#define ymm15_x xmm15 49f3f935a7SJussi Kivilinna 50f3f935a7SJussi Kivilinna/********************************************************************** 51f3f935a7SJussi Kivilinna 32-way camellia 52f3f935a7SJussi Kivilinna **********************************************************************/ 53f3f935a7SJussi Kivilinna 54f3f935a7SJussi Kivilinna/* 55f3f935a7SJussi Kivilinna * IN: 56f3f935a7SJussi Kivilinna * x0..x7: byte-sliced AB state 57f3f935a7SJussi Kivilinna * mem_cd: register pointer storing CD state 58f3f935a7SJussi Kivilinna * key: index for key material 59f3f935a7SJussi Kivilinna * OUT: 60f3f935a7SJussi Kivilinna * x0..x7: new byte-sliced CD state 61f3f935a7SJussi Kivilinna */ 62f3f935a7SJussi Kivilinna#define roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, t0, t1, t2, t3, t4, t5, t6, \ 63f3f935a7SJussi Kivilinna t7, mem_cd, key) \ 64f3f935a7SJussi Kivilinna /* \ 65f3f935a7SJussi Kivilinna * S-function with AES subbytes \ 66f3f935a7SJussi Kivilinna */ \ 67*24ff1e9dSArd Biesheuvel vbroadcasti128 .Linv_shift_row(%rip), t4; \ 68*24ff1e9dSArd Biesheuvel vpbroadcastd .L0f0f0f0f(%rip), t7; \ 69*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lpre_tf_lo_s1(%rip), t5; \ 70*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lpre_tf_hi_s1(%rip), t6; \ 71*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lpre_tf_lo_s4(%rip), t2; \ 72*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lpre_tf_hi_s4(%rip), t3; \ 73f3f935a7SJussi Kivilinna \ 74f3f935a7SJussi Kivilinna /* AES inverse shift rows */ \ 75f3f935a7SJussi Kivilinna vpshufb t4, x0, x0; \ 76f3f935a7SJussi Kivilinna vpshufb t4, x7, x7; \ 77f3f935a7SJussi Kivilinna vpshufb t4, x3, x3; \ 78f3f935a7SJussi Kivilinna vpshufb t4, x6, x6; \ 79acfffdb8SJussi Kivilinna vpshufb t4, x2, x2; \ 80acfffdb8SJussi Kivilinna vpshufb t4, x5, x5; \ 81acfffdb8SJussi Kivilinna vpshufb t4, x1, x1; \ 82acfffdb8SJussi Kivilinna vpshufb t4, x4, x4; \ 83f3f935a7SJussi Kivilinna \ 84f3f935a7SJussi Kivilinna /* prefilter sboxes 1, 2 and 3 */ \ 85f3f935a7SJussi Kivilinna /* prefilter sbox 4 */ \ 86acfffdb8SJussi Kivilinna filter_8bit(x0, t5, t6, t7, t4); \ 87acfffdb8SJussi Kivilinna filter_8bit(x7, t5, t6, t7, t4); \ 88acfffdb8SJussi Kivilinna vextracti128 $1, x0, t0##_x; \ 89acfffdb8SJussi Kivilinna vextracti128 $1, x7, t1##_x; \ 90acfffdb8SJussi Kivilinna filter_8bit(x3, t2, t3, t7, t4); \ 91acfffdb8SJussi Kivilinna filter_8bit(x6, t2, t3, t7, t4); \ 92acfffdb8SJussi Kivilinna vextracti128 $1, x3, t3##_x; \ 93acfffdb8SJussi Kivilinna vextracti128 $1, x6, t2##_x; \ 94acfffdb8SJussi Kivilinna filter_8bit(x2, t5, t6, t7, t4); \ 95acfffdb8SJussi Kivilinna filter_8bit(x5, t5, t6, t7, t4); \ 96acfffdb8SJussi Kivilinna filter_8bit(x1, t5, t6, t7, t4); \ 97acfffdb8SJussi Kivilinna filter_8bit(x4, t5, t6, t7, t4); \ 98acfffdb8SJussi Kivilinna \ 99f3f935a7SJussi Kivilinna vpxor t4##_x, t4##_x, t4##_x; \ 100f3f935a7SJussi Kivilinna \ 101f3f935a7SJussi Kivilinna /* AES subbytes + AES shift rows */ \ 102acfffdb8SJussi Kivilinna vextracti128 $1, x2, t6##_x; \ 103acfffdb8SJussi Kivilinna vextracti128 $1, x5, t5##_x; \ 104acfffdb8SJussi Kivilinna vaesenclast t4##_x, x0##_x, x0##_x; \ 105acfffdb8SJussi Kivilinna vaesenclast t4##_x, t0##_x, t0##_x; \ 106acfffdb8SJussi Kivilinna vinserti128 $1, t0##_x, x0, x0; \ 107acfffdb8SJussi Kivilinna vaesenclast t4##_x, x7##_x, x7##_x; \ 108acfffdb8SJussi Kivilinna vaesenclast t4##_x, t1##_x, t1##_x; \ 109acfffdb8SJussi Kivilinna vinserti128 $1, t1##_x, x7, x7; \ 110acfffdb8SJussi Kivilinna vaesenclast t4##_x, x3##_x, x3##_x; \ 111acfffdb8SJussi Kivilinna vaesenclast t4##_x, t3##_x, t3##_x; \ 112acfffdb8SJussi Kivilinna vinserti128 $1, t3##_x, x3, x3; \ 113acfffdb8SJussi Kivilinna vaesenclast t4##_x, x6##_x, x6##_x; \ 114acfffdb8SJussi Kivilinna vaesenclast t4##_x, t2##_x, t2##_x; \ 115acfffdb8SJussi Kivilinna vinserti128 $1, t2##_x, x6, x6; \ 116acfffdb8SJussi Kivilinna vextracti128 $1, x1, t3##_x; \ 117acfffdb8SJussi Kivilinna vextracti128 $1, x4, t2##_x; \ 118*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lpost_tf_lo_s1(%rip), t0; \ 119*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lpost_tf_hi_s1(%rip), t1; \ 120acfffdb8SJussi Kivilinna vaesenclast t4##_x, x2##_x, x2##_x; \ 121acfffdb8SJussi Kivilinna vaesenclast t4##_x, t6##_x, t6##_x; \ 122acfffdb8SJussi Kivilinna vinserti128 $1, t6##_x, x2, x2; \ 123acfffdb8SJussi Kivilinna vaesenclast t4##_x, x5##_x, x5##_x; \ 124acfffdb8SJussi Kivilinna vaesenclast t4##_x, t5##_x, t5##_x; \ 125acfffdb8SJussi Kivilinna vinserti128 $1, t5##_x, x5, x5; \ 126acfffdb8SJussi Kivilinna vaesenclast t4##_x, x1##_x, x1##_x; \ 127acfffdb8SJussi Kivilinna vaesenclast t4##_x, t3##_x, t3##_x; \ 128acfffdb8SJussi Kivilinna vinserti128 $1, t3##_x, x1, x1; \ 129acfffdb8SJussi Kivilinna vaesenclast t4##_x, x4##_x, x4##_x; \ 130acfffdb8SJussi Kivilinna vaesenclast t4##_x, t2##_x, t2##_x; \ 131acfffdb8SJussi Kivilinna vinserti128 $1, t2##_x, x4, x4; \ 132f3f935a7SJussi Kivilinna \ 133f3f935a7SJussi Kivilinna /* postfilter sboxes 1 and 4 */ \ 134*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lpost_tf_lo_s3(%rip), t2; \ 135*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lpost_tf_hi_s3(%rip), t3; \ 136f3f935a7SJussi Kivilinna filter_8bit(x0, t0, t1, t7, t6); \ 137f3f935a7SJussi Kivilinna filter_8bit(x7, t0, t1, t7, t6); \ 138f3f935a7SJussi Kivilinna filter_8bit(x3, t0, t1, t7, t6); \ 139f3f935a7SJussi Kivilinna filter_8bit(x6, t0, t1, t7, t6); \ 140f3f935a7SJussi Kivilinna \ 141f3f935a7SJussi Kivilinna /* postfilter sbox 3 */ \ 142*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lpost_tf_lo_s2(%rip), t4; \ 143*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lpost_tf_hi_s2(%rip), t5; \ 144f3f935a7SJussi Kivilinna filter_8bit(x2, t2, t3, t7, t6); \ 145f3f935a7SJussi Kivilinna filter_8bit(x5, t2, t3, t7, t6); \ 146f3f935a7SJussi Kivilinna \ 147f3f935a7SJussi Kivilinna vpbroadcastq key, t0; /* higher 64-bit duplicate ignored */ \ 148f3f935a7SJussi Kivilinna \ 149f3f935a7SJussi Kivilinna /* postfilter sbox 2 */ \ 150f3f935a7SJussi Kivilinna filter_8bit(x1, t4, t5, t7, t2); \ 151f3f935a7SJussi Kivilinna filter_8bit(x4, t4, t5, t7, t2); \ 152acfffdb8SJussi Kivilinna vpxor t7, t7, t7; \ 153f3f935a7SJussi Kivilinna \ 154f3f935a7SJussi Kivilinna vpsrldq $1, t0, t1; \ 155f3f935a7SJussi Kivilinna vpsrldq $2, t0, t2; \ 156acfffdb8SJussi Kivilinna vpshufb t7, t1, t1; \ 157f3f935a7SJussi Kivilinna vpsrldq $3, t0, t3; \ 158f3f935a7SJussi Kivilinna \ 159f3f935a7SJussi Kivilinna /* P-function */ \ 160f3f935a7SJussi Kivilinna vpxor x5, x0, x0; \ 161f3f935a7SJussi Kivilinna vpxor x6, x1, x1; \ 162f3f935a7SJussi Kivilinna vpxor x7, x2, x2; \ 163f3f935a7SJussi Kivilinna vpxor x4, x3, x3; \ 164f3f935a7SJussi Kivilinna \ 165acfffdb8SJussi Kivilinna vpshufb t7, t2, t2; \ 166acfffdb8SJussi Kivilinna vpsrldq $4, t0, t4; \ 167acfffdb8SJussi Kivilinna vpshufb t7, t3, t3; \ 168acfffdb8SJussi Kivilinna vpsrldq $5, t0, t5; \ 169acfffdb8SJussi Kivilinna vpshufb t7, t4, t4; \ 170acfffdb8SJussi Kivilinna \ 171f3f935a7SJussi Kivilinna vpxor x2, x4, x4; \ 172f3f935a7SJussi Kivilinna vpxor x3, x5, x5; \ 173f3f935a7SJussi Kivilinna vpxor x0, x6, x6; \ 174f3f935a7SJussi Kivilinna vpxor x1, x7, x7; \ 175f3f935a7SJussi Kivilinna \ 176acfffdb8SJussi Kivilinna vpsrldq $6, t0, t6; \ 177acfffdb8SJussi Kivilinna vpshufb t7, t5, t5; \ 178acfffdb8SJussi Kivilinna vpshufb t7, t6, t6; \ 179acfffdb8SJussi Kivilinna \ 180f3f935a7SJussi Kivilinna vpxor x7, x0, x0; \ 181f3f935a7SJussi Kivilinna vpxor x4, x1, x1; \ 182f3f935a7SJussi Kivilinna vpxor x5, x2, x2; \ 183f3f935a7SJussi Kivilinna vpxor x6, x3, x3; \ 184f3f935a7SJussi Kivilinna \ 185f3f935a7SJussi Kivilinna vpxor x3, x4, x4; \ 186f3f935a7SJussi Kivilinna vpxor x0, x5, x5; \ 187f3f935a7SJussi Kivilinna vpxor x1, x6, x6; \ 188f3f935a7SJussi Kivilinna vpxor x2, x7, x7; /* note: high and low parts swapped */ \ 189f3f935a7SJussi Kivilinna \ 190f3f935a7SJussi Kivilinna /* Add key material and result to CD (x becomes new CD) */ \ 191f3f935a7SJussi Kivilinna \ 192f3f935a7SJussi Kivilinna vpxor t6, x1, x1; \ 193f3f935a7SJussi Kivilinna vpxor 5 * 32(mem_cd), x1, x1; \ 194f3f935a7SJussi Kivilinna \ 195acfffdb8SJussi Kivilinna vpsrldq $7, t0, t6; \ 196acfffdb8SJussi Kivilinna vpshufb t7, t0, t0; \ 197acfffdb8SJussi Kivilinna vpshufb t7, t6, t7; \ 198acfffdb8SJussi Kivilinna \ 199acfffdb8SJussi Kivilinna vpxor t7, x0, x0; \ 200acfffdb8SJussi Kivilinna vpxor 4 * 32(mem_cd), x0, x0; \ 201acfffdb8SJussi Kivilinna \ 202f3f935a7SJussi Kivilinna vpxor t5, x2, x2; \ 203f3f935a7SJussi Kivilinna vpxor 6 * 32(mem_cd), x2, x2; \ 204f3f935a7SJussi Kivilinna \ 205f3f935a7SJussi Kivilinna vpxor t4, x3, x3; \ 206f3f935a7SJussi Kivilinna vpxor 7 * 32(mem_cd), x3, x3; \ 207f3f935a7SJussi Kivilinna \ 208f3f935a7SJussi Kivilinna vpxor t3, x4, x4; \ 209f3f935a7SJussi Kivilinna vpxor 0 * 32(mem_cd), x4, x4; \ 210f3f935a7SJussi Kivilinna \ 211f3f935a7SJussi Kivilinna vpxor t2, x5, x5; \ 212f3f935a7SJussi Kivilinna vpxor 1 * 32(mem_cd), x5, x5; \ 213f3f935a7SJussi Kivilinna \ 214f3f935a7SJussi Kivilinna vpxor t1, x6, x6; \ 215f3f935a7SJussi Kivilinna vpxor 2 * 32(mem_cd), x6, x6; \ 216f3f935a7SJussi Kivilinna \ 217f3f935a7SJussi Kivilinna vpxor t0, x7, x7; \ 218f3f935a7SJussi Kivilinna vpxor 3 * 32(mem_cd), x7, x7; 219f3f935a7SJussi Kivilinna 220f3f935a7SJussi Kivilinna/* 221acfffdb8SJussi Kivilinna * Size optimization... with inlined roundsm32 binary would be over 5 times 222f3f935a7SJussi Kivilinna * larger and would only marginally faster. 223f3f935a7SJussi Kivilinna */ 22474d8b90aSJiri SlabySYM_FUNC_START_LOCAL(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd) 225f3f935a7SJussi Kivilinna roundsm32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 226f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, %ymm15, 227f3f935a7SJussi Kivilinna %rcx, (%r9)); 228f94909ceSPeter Zijlstra RET; 22974d8b90aSJiri SlabySYM_FUNC_END(roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd) 230f3f935a7SJussi Kivilinna 23174d8b90aSJiri SlabySYM_FUNC_START_LOCAL(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab) 232f3f935a7SJussi Kivilinna roundsm32(%ymm4, %ymm5, %ymm6, %ymm7, %ymm0, %ymm1, %ymm2, %ymm3, 233f3f935a7SJussi Kivilinna %ymm12, %ymm13, %ymm14, %ymm15, %ymm8, %ymm9, %ymm10, %ymm11, 234f3f935a7SJussi Kivilinna %rax, (%r9)); 235f94909ceSPeter Zijlstra RET; 23674d8b90aSJiri SlabySYM_FUNC_END(roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab) 237f3f935a7SJussi Kivilinna 238f3f935a7SJussi Kivilinna/* 239f3f935a7SJussi Kivilinna * IN/OUT: 240f3f935a7SJussi Kivilinna * x0..x7: byte-sliced AB state preloaded 241f3f935a7SJussi Kivilinna * mem_ab: byte-sliced AB state in memory 242f3f935a7SJussi Kivilinna * mem_cb: byte-sliced CD state in memory 243f3f935a7SJussi Kivilinna */ 244f3f935a7SJussi Kivilinna#define two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 245f3f935a7SJussi Kivilinna y6, y7, mem_ab, mem_cd, i, dir, store_ab) \ 246f3f935a7SJussi Kivilinna leaq (key_table + (i) * 8)(CTX), %r9; \ 247f3f935a7SJussi Kivilinna call roundsm32_x0_x1_x2_x3_x4_x5_x6_x7_y0_y1_y2_y3_y4_y5_y6_y7_cd; \ 248f3f935a7SJussi Kivilinna \ 249f3f935a7SJussi Kivilinna vmovdqu x0, 4 * 32(mem_cd); \ 250f3f935a7SJussi Kivilinna vmovdqu x1, 5 * 32(mem_cd); \ 251f3f935a7SJussi Kivilinna vmovdqu x2, 6 * 32(mem_cd); \ 252f3f935a7SJussi Kivilinna vmovdqu x3, 7 * 32(mem_cd); \ 253f3f935a7SJussi Kivilinna vmovdqu x4, 0 * 32(mem_cd); \ 254f3f935a7SJussi Kivilinna vmovdqu x5, 1 * 32(mem_cd); \ 255f3f935a7SJussi Kivilinna vmovdqu x6, 2 * 32(mem_cd); \ 256f3f935a7SJussi Kivilinna vmovdqu x7, 3 * 32(mem_cd); \ 257f3f935a7SJussi Kivilinna \ 258f3f935a7SJussi Kivilinna leaq (key_table + ((i) + (dir)) * 8)(CTX), %r9; \ 259f3f935a7SJussi Kivilinna call roundsm32_x4_x5_x6_x7_x0_x1_x2_x3_y4_y5_y6_y7_y0_y1_y2_y3_ab; \ 260f3f935a7SJussi Kivilinna \ 261f3f935a7SJussi Kivilinna store_ab(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab); 262f3f935a7SJussi Kivilinna 263f3f935a7SJussi Kivilinna#define dummy_store(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) /* do nothing */ 264f3f935a7SJussi Kivilinna 265f3f935a7SJussi Kivilinna#define store_ab_state(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) \ 266f3f935a7SJussi Kivilinna /* Store new AB state */ \ 267f3f935a7SJussi Kivilinna vmovdqu x4, 4 * 32(mem_ab); \ 268f3f935a7SJussi Kivilinna vmovdqu x5, 5 * 32(mem_ab); \ 269f3f935a7SJussi Kivilinna vmovdqu x6, 6 * 32(mem_ab); \ 270f3f935a7SJussi Kivilinna vmovdqu x7, 7 * 32(mem_ab); \ 271f3f935a7SJussi Kivilinna vmovdqu x0, 0 * 32(mem_ab); \ 272f3f935a7SJussi Kivilinna vmovdqu x1, 1 * 32(mem_ab); \ 273f3f935a7SJussi Kivilinna vmovdqu x2, 2 * 32(mem_ab); \ 274f3f935a7SJussi Kivilinna vmovdqu x3, 3 * 32(mem_ab); 275f3f935a7SJussi Kivilinna 276f3f935a7SJussi Kivilinna#define enc_rounds32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 277f3f935a7SJussi Kivilinna y6, y7, mem_ab, mem_cd, i) \ 278f3f935a7SJussi Kivilinna two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 279f3f935a7SJussi Kivilinna y6, y7, mem_ab, mem_cd, (i) + 2, 1, store_ab_state); \ 280f3f935a7SJussi Kivilinna two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 281f3f935a7SJussi Kivilinna y6, y7, mem_ab, mem_cd, (i) + 4, 1, store_ab_state); \ 282f3f935a7SJussi Kivilinna two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 283f3f935a7SJussi Kivilinna y6, y7, mem_ab, mem_cd, (i) + 6, 1, dummy_store); 284f3f935a7SJussi Kivilinna 285f3f935a7SJussi Kivilinna#define dec_rounds32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 286f3f935a7SJussi Kivilinna y6, y7, mem_ab, mem_cd, i) \ 287f3f935a7SJussi Kivilinna two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 288f3f935a7SJussi Kivilinna y6, y7, mem_ab, mem_cd, (i) + 7, -1, store_ab_state); \ 289f3f935a7SJussi Kivilinna two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 290f3f935a7SJussi Kivilinna y6, y7, mem_ab, mem_cd, (i) + 5, -1, store_ab_state); \ 291f3f935a7SJussi Kivilinna two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 292f3f935a7SJussi Kivilinna y6, y7, mem_ab, mem_cd, (i) + 3, -1, dummy_store); 293f3f935a7SJussi Kivilinna 294f3f935a7SJussi Kivilinna/* 295f3f935a7SJussi Kivilinna * IN: 296f3f935a7SJussi Kivilinna * v0..3: byte-sliced 32-bit integers 297f3f935a7SJussi Kivilinna * OUT: 298f3f935a7SJussi Kivilinna * v0..3: (IN <<< 1) 299f3f935a7SJussi Kivilinna */ 300f3f935a7SJussi Kivilinna#define rol32_1_32(v0, v1, v2, v3, t0, t1, t2, zero) \ 301f3f935a7SJussi Kivilinna vpcmpgtb v0, zero, t0; \ 302f3f935a7SJussi Kivilinna vpaddb v0, v0, v0; \ 303f3f935a7SJussi Kivilinna vpabsb t0, t0; \ 304f3f935a7SJussi Kivilinna \ 305f3f935a7SJussi Kivilinna vpcmpgtb v1, zero, t1; \ 306f3f935a7SJussi Kivilinna vpaddb v1, v1, v1; \ 307f3f935a7SJussi Kivilinna vpabsb t1, t1; \ 308f3f935a7SJussi Kivilinna \ 309f3f935a7SJussi Kivilinna vpcmpgtb v2, zero, t2; \ 310f3f935a7SJussi Kivilinna vpaddb v2, v2, v2; \ 311f3f935a7SJussi Kivilinna vpabsb t2, t2; \ 312f3f935a7SJussi Kivilinna \ 313f3f935a7SJussi Kivilinna vpor t0, v1, v1; \ 314f3f935a7SJussi Kivilinna \ 315f3f935a7SJussi Kivilinna vpcmpgtb v3, zero, t0; \ 316f3f935a7SJussi Kivilinna vpaddb v3, v3, v3; \ 317f3f935a7SJussi Kivilinna vpabsb t0, t0; \ 318f3f935a7SJussi Kivilinna \ 319f3f935a7SJussi Kivilinna vpor t1, v2, v2; \ 320f3f935a7SJussi Kivilinna vpor t2, v3, v3; \ 321f3f935a7SJussi Kivilinna vpor t0, v0, v0; 322f3f935a7SJussi Kivilinna 323f3f935a7SJussi Kivilinna/* 324f3f935a7SJussi Kivilinna * IN: 325f3f935a7SJussi Kivilinna * r: byte-sliced AB state in memory 326f3f935a7SJussi Kivilinna * l: byte-sliced CD state in memory 327f3f935a7SJussi Kivilinna * OUT: 328f3f935a7SJussi Kivilinna * x0..x7: new byte-sliced CD state 329f3f935a7SJussi Kivilinna */ 330f3f935a7SJussi Kivilinna#define fls32(l, l0, l1, l2, l3, l4, l5, l6, l7, r, t0, t1, t2, t3, tt0, \ 331f3f935a7SJussi Kivilinna tt1, tt2, tt3, kll, klr, krl, krr) \ 332f3f935a7SJussi Kivilinna /* \ 333f3f935a7SJussi Kivilinna * t0 = kll; \ 334f3f935a7SJussi Kivilinna * t0 &= ll; \ 335f3f935a7SJussi Kivilinna * lr ^= rol32(t0, 1); \ 336f3f935a7SJussi Kivilinna */ \ 337f3f935a7SJussi Kivilinna vpbroadcastd kll, t0; /* only lowest 32-bit used */ \ 338f3f935a7SJussi Kivilinna vpxor tt0, tt0, tt0; \ 339acfffdb8SJussi Kivilinna vpshufb tt0, t0, t3; \ 340f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 341acfffdb8SJussi Kivilinna vpshufb tt0, t0, t2; \ 342f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 343acfffdb8SJussi Kivilinna vpshufb tt0, t0, t1; \ 344f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 345acfffdb8SJussi Kivilinna vpshufb tt0, t0, t0; \ 346f3f935a7SJussi Kivilinna \ 347f3f935a7SJussi Kivilinna vpand l0, t0, t0; \ 348f3f935a7SJussi Kivilinna vpand l1, t1, t1; \ 349f3f935a7SJussi Kivilinna vpand l2, t2, t2; \ 350f3f935a7SJussi Kivilinna vpand l3, t3, t3; \ 351f3f935a7SJussi Kivilinna \ 352f3f935a7SJussi Kivilinna rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \ 353f3f935a7SJussi Kivilinna \ 354f3f935a7SJussi Kivilinna vpxor l4, t0, l4; \ 355acfffdb8SJussi Kivilinna vpbroadcastd krr, t0; /* only lowest 32-bit used */ \ 356f3f935a7SJussi Kivilinna vmovdqu l4, 4 * 32(l); \ 357f3f935a7SJussi Kivilinna vpxor l5, t1, l5; \ 358f3f935a7SJussi Kivilinna vmovdqu l5, 5 * 32(l); \ 359f3f935a7SJussi Kivilinna vpxor l6, t2, l6; \ 360f3f935a7SJussi Kivilinna vmovdqu l6, 6 * 32(l); \ 361f3f935a7SJussi Kivilinna vpxor l7, t3, l7; \ 362f3f935a7SJussi Kivilinna vmovdqu l7, 7 * 32(l); \ 363f3f935a7SJussi Kivilinna \ 364f3f935a7SJussi Kivilinna /* \ 365f3f935a7SJussi Kivilinna * t2 = krr; \ 366f3f935a7SJussi Kivilinna * t2 |= rr; \ 367f3f935a7SJussi Kivilinna * rl ^= t2; \ 368f3f935a7SJussi Kivilinna */ \ 369f3f935a7SJussi Kivilinna \ 370acfffdb8SJussi Kivilinna vpshufb tt0, t0, t3; \ 371f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 372acfffdb8SJussi Kivilinna vpshufb tt0, t0, t2; \ 373f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 374acfffdb8SJussi Kivilinna vpshufb tt0, t0, t1; \ 375f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 376acfffdb8SJussi Kivilinna vpshufb tt0, t0, t0; \ 377f3f935a7SJussi Kivilinna \ 378f3f935a7SJussi Kivilinna vpor 4 * 32(r), t0, t0; \ 379f3f935a7SJussi Kivilinna vpor 5 * 32(r), t1, t1; \ 380f3f935a7SJussi Kivilinna vpor 6 * 32(r), t2, t2; \ 381f3f935a7SJussi Kivilinna vpor 7 * 32(r), t3, t3; \ 382f3f935a7SJussi Kivilinna \ 383f3f935a7SJussi Kivilinna vpxor 0 * 32(r), t0, t0; \ 384f3f935a7SJussi Kivilinna vpxor 1 * 32(r), t1, t1; \ 385f3f935a7SJussi Kivilinna vpxor 2 * 32(r), t2, t2; \ 386f3f935a7SJussi Kivilinna vpxor 3 * 32(r), t3, t3; \ 387f3f935a7SJussi Kivilinna vmovdqu t0, 0 * 32(r); \ 388acfffdb8SJussi Kivilinna vpbroadcastd krl, t0; /* only lowest 32-bit used */ \ 389f3f935a7SJussi Kivilinna vmovdqu t1, 1 * 32(r); \ 390f3f935a7SJussi Kivilinna vmovdqu t2, 2 * 32(r); \ 391f3f935a7SJussi Kivilinna vmovdqu t3, 3 * 32(r); \ 392f3f935a7SJussi Kivilinna \ 393f3f935a7SJussi Kivilinna /* \ 394f3f935a7SJussi Kivilinna * t2 = krl; \ 395f3f935a7SJussi Kivilinna * t2 &= rl; \ 396f3f935a7SJussi Kivilinna * rr ^= rol32(t2, 1); \ 397f3f935a7SJussi Kivilinna */ \ 398acfffdb8SJussi Kivilinna vpshufb tt0, t0, t3; \ 399f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 400acfffdb8SJussi Kivilinna vpshufb tt0, t0, t2; \ 401f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 402acfffdb8SJussi Kivilinna vpshufb tt0, t0, t1; \ 403f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 404acfffdb8SJussi Kivilinna vpshufb tt0, t0, t0; \ 405f3f935a7SJussi Kivilinna \ 406f3f935a7SJussi Kivilinna vpand 0 * 32(r), t0, t0; \ 407f3f935a7SJussi Kivilinna vpand 1 * 32(r), t1, t1; \ 408f3f935a7SJussi Kivilinna vpand 2 * 32(r), t2, t2; \ 409f3f935a7SJussi Kivilinna vpand 3 * 32(r), t3, t3; \ 410f3f935a7SJussi Kivilinna \ 411f3f935a7SJussi Kivilinna rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \ 412f3f935a7SJussi Kivilinna \ 413f3f935a7SJussi Kivilinna vpxor 4 * 32(r), t0, t0; \ 414f3f935a7SJussi Kivilinna vpxor 5 * 32(r), t1, t1; \ 415f3f935a7SJussi Kivilinna vpxor 6 * 32(r), t2, t2; \ 416f3f935a7SJussi Kivilinna vpxor 7 * 32(r), t3, t3; \ 417f3f935a7SJussi Kivilinna vmovdqu t0, 4 * 32(r); \ 418acfffdb8SJussi Kivilinna vpbroadcastd klr, t0; /* only lowest 32-bit used */ \ 419f3f935a7SJussi Kivilinna vmovdqu t1, 5 * 32(r); \ 420f3f935a7SJussi Kivilinna vmovdqu t2, 6 * 32(r); \ 421f3f935a7SJussi Kivilinna vmovdqu t3, 7 * 32(r); \ 422f3f935a7SJussi Kivilinna \ 423f3f935a7SJussi Kivilinna /* \ 424f3f935a7SJussi Kivilinna * t0 = klr; \ 425f3f935a7SJussi Kivilinna * t0 |= lr; \ 426f3f935a7SJussi Kivilinna * ll ^= t0; \ 427f3f935a7SJussi Kivilinna */ \ 428f3f935a7SJussi Kivilinna \ 429acfffdb8SJussi Kivilinna vpshufb tt0, t0, t3; \ 430f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 431acfffdb8SJussi Kivilinna vpshufb tt0, t0, t2; \ 432f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 433acfffdb8SJussi Kivilinna vpshufb tt0, t0, t1; \ 434f3f935a7SJussi Kivilinna vpsrldq $1, t0, t0; \ 435acfffdb8SJussi Kivilinna vpshufb tt0, t0, t0; \ 436f3f935a7SJussi Kivilinna \ 437f3f935a7SJussi Kivilinna vpor l4, t0, t0; \ 438f3f935a7SJussi Kivilinna vpor l5, t1, t1; \ 439f3f935a7SJussi Kivilinna vpor l6, t2, t2; \ 440f3f935a7SJussi Kivilinna vpor l7, t3, t3; \ 441f3f935a7SJussi Kivilinna \ 442f3f935a7SJussi Kivilinna vpxor l0, t0, l0; \ 443f3f935a7SJussi Kivilinna vmovdqu l0, 0 * 32(l); \ 444f3f935a7SJussi Kivilinna vpxor l1, t1, l1; \ 445f3f935a7SJussi Kivilinna vmovdqu l1, 1 * 32(l); \ 446f3f935a7SJussi Kivilinna vpxor l2, t2, l2; \ 447f3f935a7SJussi Kivilinna vmovdqu l2, 2 * 32(l); \ 448f3f935a7SJussi Kivilinna vpxor l3, t3, l3; \ 449f3f935a7SJussi Kivilinna vmovdqu l3, 3 * 32(l); 450f3f935a7SJussi Kivilinna 451f3f935a7SJussi Kivilinna#define transpose_4x4(x0, x1, x2, x3, t1, t2) \ 452f3f935a7SJussi Kivilinna vpunpckhdq x1, x0, t2; \ 453f3f935a7SJussi Kivilinna vpunpckldq x1, x0, x0; \ 454f3f935a7SJussi Kivilinna \ 455f3f935a7SJussi Kivilinna vpunpckldq x3, x2, t1; \ 456f3f935a7SJussi Kivilinna vpunpckhdq x3, x2, x2; \ 457f3f935a7SJussi Kivilinna \ 458f3f935a7SJussi Kivilinna vpunpckhqdq t1, x0, x1; \ 459f3f935a7SJussi Kivilinna vpunpcklqdq t1, x0, x0; \ 460f3f935a7SJussi Kivilinna \ 461f3f935a7SJussi Kivilinna vpunpckhqdq x2, t2, x3; \ 462f3f935a7SJussi Kivilinna vpunpcklqdq x2, t2, x2; 463f3f935a7SJussi Kivilinna 464f3f935a7SJussi Kivilinna#define byteslice_16x16b_fast(a0, b0, c0, d0, a1, b1, c1, d1, a2, b2, c2, d2, \ 465f3f935a7SJussi Kivilinna a3, b3, c3, d3, st0, st1) \ 466f3f935a7SJussi Kivilinna vmovdqu d2, st0; \ 467f3f935a7SJussi Kivilinna vmovdqu d3, st1; \ 468f3f935a7SJussi Kivilinna transpose_4x4(a0, a1, a2, a3, d2, d3); \ 469f3f935a7SJussi Kivilinna transpose_4x4(b0, b1, b2, b3, d2, d3); \ 470f3f935a7SJussi Kivilinna vmovdqu st0, d2; \ 471f3f935a7SJussi Kivilinna vmovdqu st1, d3; \ 472f3f935a7SJussi Kivilinna \ 473f3f935a7SJussi Kivilinna vmovdqu a0, st0; \ 474f3f935a7SJussi Kivilinna vmovdqu a1, st1; \ 475f3f935a7SJussi Kivilinna transpose_4x4(c0, c1, c2, c3, a0, a1); \ 476f3f935a7SJussi Kivilinna transpose_4x4(d0, d1, d2, d3, a0, a1); \ 477f3f935a7SJussi Kivilinna \ 478*24ff1e9dSArd Biesheuvel vbroadcasti128 .Lshufb_16x16b(%rip), a0; \ 479f3f935a7SJussi Kivilinna vmovdqu st1, a1; \ 480f3f935a7SJussi Kivilinna vpshufb a0, a2, a2; \ 481f3f935a7SJussi Kivilinna vpshufb a0, a3, a3; \ 482f3f935a7SJussi Kivilinna vpshufb a0, b0, b0; \ 483f3f935a7SJussi Kivilinna vpshufb a0, b1, b1; \ 484f3f935a7SJussi Kivilinna vpshufb a0, b2, b2; \ 485f3f935a7SJussi Kivilinna vpshufb a0, b3, b3; \ 486f3f935a7SJussi Kivilinna vpshufb a0, a1, a1; \ 487f3f935a7SJussi Kivilinna vpshufb a0, c0, c0; \ 488f3f935a7SJussi Kivilinna vpshufb a0, c1, c1; \ 489f3f935a7SJussi Kivilinna vpshufb a0, c2, c2; \ 490f3f935a7SJussi Kivilinna vpshufb a0, c3, c3; \ 491f3f935a7SJussi Kivilinna vpshufb a0, d0, d0; \ 492f3f935a7SJussi Kivilinna vpshufb a0, d1, d1; \ 493f3f935a7SJussi Kivilinna vpshufb a0, d2, d2; \ 494f3f935a7SJussi Kivilinna vpshufb a0, d3, d3; \ 495f3f935a7SJussi Kivilinna vmovdqu d3, st1; \ 496f3f935a7SJussi Kivilinna vmovdqu st0, d3; \ 497f3f935a7SJussi Kivilinna vpshufb a0, d3, a0; \ 498f3f935a7SJussi Kivilinna vmovdqu d2, st0; \ 499f3f935a7SJussi Kivilinna \ 500f3f935a7SJussi Kivilinna transpose_4x4(a0, b0, c0, d0, d2, d3); \ 501f3f935a7SJussi Kivilinna transpose_4x4(a1, b1, c1, d1, d2, d3); \ 502f3f935a7SJussi Kivilinna vmovdqu st0, d2; \ 503f3f935a7SJussi Kivilinna vmovdqu st1, d3; \ 504f3f935a7SJussi Kivilinna \ 505f3f935a7SJussi Kivilinna vmovdqu b0, st0; \ 506f3f935a7SJussi Kivilinna vmovdqu b1, st1; \ 507f3f935a7SJussi Kivilinna transpose_4x4(a2, b2, c2, d2, b0, b1); \ 508f3f935a7SJussi Kivilinna transpose_4x4(a3, b3, c3, d3, b0, b1); \ 509f3f935a7SJussi Kivilinna vmovdqu st0, b0; \ 510f3f935a7SJussi Kivilinna vmovdqu st1, b1; \ 511f3f935a7SJussi Kivilinna /* does not adjust output bytes inside vectors */ 512f3f935a7SJussi Kivilinna 513f3f935a7SJussi Kivilinna/* load blocks to registers and apply pre-whitening */ 514f3f935a7SJussi Kivilinna#define inpack32_pre(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 515f3f935a7SJussi Kivilinna y6, y7, rio, key) \ 516f3f935a7SJussi Kivilinna vpbroadcastq key, x0; \ 517*24ff1e9dSArd Biesheuvel vpshufb .Lpack_bswap(%rip), x0, x0; \ 518f3f935a7SJussi Kivilinna \ 519f3f935a7SJussi Kivilinna vpxor 0 * 32(rio), x0, y7; \ 520f3f935a7SJussi Kivilinna vpxor 1 * 32(rio), x0, y6; \ 521f3f935a7SJussi Kivilinna vpxor 2 * 32(rio), x0, y5; \ 522f3f935a7SJussi Kivilinna vpxor 3 * 32(rio), x0, y4; \ 523f3f935a7SJussi Kivilinna vpxor 4 * 32(rio), x0, y3; \ 524f3f935a7SJussi Kivilinna vpxor 5 * 32(rio), x0, y2; \ 525f3f935a7SJussi Kivilinna vpxor 6 * 32(rio), x0, y1; \ 526f3f935a7SJussi Kivilinna vpxor 7 * 32(rio), x0, y0; \ 527f3f935a7SJussi Kivilinna vpxor 8 * 32(rio), x0, x7; \ 528f3f935a7SJussi Kivilinna vpxor 9 * 32(rio), x0, x6; \ 529f3f935a7SJussi Kivilinna vpxor 10 * 32(rio), x0, x5; \ 530f3f935a7SJussi Kivilinna vpxor 11 * 32(rio), x0, x4; \ 531f3f935a7SJussi Kivilinna vpxor 12 * 32(rio), x0, x3; \ 532f3f935a7SJussi Kivilinna vpxor 13 * 32(rio), x0, x2; \ 533f3f935a7SJussi Kivilinna vpxor 14 * 32(rio), x0, x1; \ 534f3f935a7SJussi Kivilinna vpxor 15 * 32(rio), x0, x0; 535f3f935a7SJussi Kivilinna 536f3f935a7SJussi Kivilinna/* byteslice pre-whitened blocks and store to temporary memory */ 537f3f935a7SJussi Kivilinna#define inpack32_post(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 538f3f935a7SJussi Kivilinna y6, y7, mem_ab, mem_cd) \ 539f3f935a7SJussi Kivilinna byteslice_16x16b_fast(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, \ 540f3f935a7SJussi Kivilinna y4, y5, y6, y7, (mem_ab), (mem_cd)); \ 541f3f935a7SJussi Kivilinna \ 542f3f935a7SJussi Kivilinna vmovdqu x0, 0 * 32(mem_ab); \ 543f3f935a7SJussi Kivilinna vmovdqu x1, 1 * 32(mem_ab); \ 544f3f935a7SJussi Kivilinna vmovdqu x2, 2 * 32(mem_ab); \ 545f3f935a7SJussi Kivilinna vmovdqu x3, 3 * 32(mem_ab); \ 546f3f935a7SJussi Kivilinna vmovdqu x4, 4 * 32(mem_ab); \ 547f3f935a7SJussi Kivilinna vmovdqu x5, 5 * 32(mem_ab); \ 548f3f935a7SJussi Kivilinna vmovdqu x6, 6 * 32(mem_ab); \ 549f3f935a7SJussi Kivilinna vmovdqu x7, 7 * 32(mem_ab); \ 550f3f935a7SJussi Kivilinna vmovdqu y0, 0 * 32(mem_cd); \ 551f3f935a7SJussi Kivilinna vmovdqu y1, 1 * 32(mem_cd); \ 552f3f935a7SJussi Kivilinna vmovdqu y2, 2 * 32(mem_cd); \ 553f3f935a7SJussi Kivilinna vmovdqu y3, 3 * 32(mem_cd); \ 554f3f935a7SJussi Kivilinna vmovdqu y4, 4 * 32(mem_cd); \ 555f3f935a7SJussi Kivilinna vmovdqu y5, 5 * 32(mem_cd); \ 556f3f935a7SJussi Kivilinna vmovdqu y6, 6 * 32(mem_cd); \ 557f3f935a7SJussi Kivilinna vmovdqu y7, 7 * 32(mem_cd); 558f3f935a7SJussi Kivilinna 559f3f935a7SJussi Kivilinna/* de-byteslice, apply post-whitening and store blocks */ 560f3f935a7SJussi Kivilinna#define outunpack32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, \ 561f3f935a7SJussi Kivilinna y5, y6, y7, key, stack_tmp0, stack_tmp1) \ 562f3f935a7SJussi Kivilinna byteslice_16x16b_fast(y0, y4, x0, x4, y1, y5, x1, x5, y2, y6, x2, x6, \ 563f3f935a7SJussi Kivilinna y3, y7, x3, x7, stack_tmp0, stack_tmp1); \ 564f3f935a7SJussi Kivilinna \ 565f3f935a7SJussi Kivilinna vmovdqu x0, stack_tmp0; \ 566f3f935a7SJussi Kivilinna \ 567f3f935a7SJussi Kivilinna vpbroadcastq key, x0; \ 568*24ff1e9dSArd Biesheuvel vpshufb .Lpack_bswap(%rip), x0, x0; \ 569f3f935a7SJussi Kivilinna \ 570f3f935a7SJussi Kivilinna vpxor x0, y7, y7; \ 571f3f935a7SJussi Kivilinna vpxor x0, y6, y6; \ 572f3f935a7SJussi Kivilinna vpxor x0, y5, y5; \ 573f3f935a7SJussi Kivilinna vpxor x0, y4, y4; \ 574f3f935a7SJussi Kivilinna vpxor x0, y3, y3; \ 575f3f935a7SJussi Kivilinna vpxor x0, y2, y2; \ 576f3f935a7SJussi Kivilinna vpxor x0, y1, y1; \ 577f3f935a7SJussi Kivilinna vpxor x0, y0, y0; \ 578f3f935a7SJussi Kivilinna vpxor x0, x7, x7; \ 579f3f935a7SJussi Kivilinna vpxor x0, x6, x6; \ 580f3f935a7SJussi Kivilinna vpxor x0, x5, x5; \ 581f3f935a7SJussi Kivilinna vpxor x0, x4, x4; \ 582f3f935a7SJussi Kivilinna vpxor x0, x3, x3; \ 583f3f935a7SJussi Kivilinna vpxor x0, x2, x2; \ 584f3f935a7SJussi Kivilinna vpxor x0, x1, x1; \ 585f3f935a7SJussi Kivilinna vpxor stack_tmp0, x0, x0; 586f3f935a7SJussi Kivilinna 587f3f935a7SJussi Kivilinna#define write_output(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \ 588f3f935a7SJussi Kivilinna y6, y7, rio) \ 589f3f935a7SJussi Kivilinna vmovdqu x0, 0 * 32(rio); \ 590f3f935a7SJussi Kivilinna vmovdqu x1, 1 * 32(rio); \ 591f3f935a7SJussi Kivilinna vmovdqu x2, 2 * 32(rio); \ 592f3f935a7SJussi Kivilinna vmovdqu x3, 3 * 32(rio); \ 593f3f935a7SJussi Kivilinna vmovdqu x4, 4 * 32(rio); \ 594f3f935a7SJussi Kivilinna vmovdqu x5, 5 * 32(rio); \ 595f3f935a7SJussi Kivilinna vmovdqu x6, 6 * 32(rio); \ 596f3f935a7SJussi Kivilinna vmovdqu x7, 7 * 32(rio); \ 597f3f935a7SJussi Kivilinna vmovdqu y0, 8 * 32(rio); \ 598f3f935a7SJussi Kivilinna vmovdqu y1, 9 * 32(rio); \ 599f3f935a7SJussi Kivilinna vmovdqu y2, 10 * 32(rio); \ 600f3f935a7SJussi Kivilinna vmovdqu y3, 11 * 32(rio); \ 601f3f935a7SJussi Kivilinna vmovdqu y4, 12 * 32(rio); \ 602f3f935a7SJussi Kivilinna vmovdqu y5, 13 * 32(rio); \ 603f3f935a7SJussi Kivilinna vmovdqu y6, 14 * 32(rio); \ 604f3f935a7SJussi Kivilinna vmovdqu y7, 15 * 32(rio); 605f3f935a7SJussi Kivilinna 606f3f935a7SJussi Kivilinna 607e183914aSDenys Vlasenko.section .rodata.cst32.shufb_16x16b, "aM", @progbits, 32 608e183914aSDenys Vlasenko.align 32 609f3f935a7SJussi Kivilinna#define SHUFB_BYTES(idx) \ 610f3f935a7SJussi Kivilinna 0 + (idx), 4 + (idx), 8 + (idx), 12 + (idx) 611f3f935a7SJussi Kivilinna.Lshufb_16x16b: 612f3f935a7SJussi Kivilinna .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3) 613f3f935a7SJussi Kivilinna .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3) 614f3f935a7SJussi Kivilinna 615e183914aSDenys Vlasenko.section .rodata.cst32.pack_bswap, "aM", @progbits, 32 616e183914aSDenys Vlasenko.align 32 617f3f935a7SJussi Kivilinna.Lpack_bswap: 618f3f935a7SJussi Kivilinna .long 0x00010203, 0x04050607, 0x80808080, 0x80808080 619f3f935a7SJussi Kivilinna .long 0x00010203, 0x04050607, 0x80808080, 0x80808080 620f3f935a7SJussi Kivilinna 621e183914aSDenys Vlasenko/* NB: section is mergeable, all elements must be aligned 16-byte blocks */ 622e183914aSDenys Vlasenko.section .rodata.cst16, "aM", @progbits, 16 623e183914aSDenys Vlasenko.align 16 624e183914aSDenys Vlasenko 625f3f935a7SJussi Kivilinna/* 626f3f935a7SJussi Kivilinna * pre-SubByte transform 627f3f935a7SJussi Kivilinna * 628f3f935a7SJussi Kivilinna * pre-lookup for sbox1, sbox2, sbox3: 629f3f935a7SJussi Kivilinna * swap_bitendianness( 630f3f935a7SJussi Kivilinna * isom_map_camellia_to_aes( 631f3f935a7SJussi Kivilinna * camellia_f( 632f3f935a7SJussi Kivilinna * swap_bitendianess(in) 633f3f935a7SJussi Kivilinna * ) 634f3f935a7SJussi Kivilinna * ) 635f3f935a7SJussi Kivilinna * ) 636f3f935a7SJussi Kivilinna * 637f3f935a7SJussi Kivilinna * (note: '⊕ 0xc5' inside camellia_f()) 638f3f935a7SJussi Kivilinna */ 639f3f935a7SJussi Kivilinna.Lpre_tf_lo_s1: 640f3f935a7SJussi Kivilinna .byte 0x45, 0xe8, 0x40, 0xed, 0x2e, 0x83, 0x2b, 0x86 641f3f935a7SJussi Kivilinna .byte 0x4b, 0xe6, 0x4e, 0xe3, 0x20, 0x8d, 0x25, 0x88 642f3f935a7SJussi Kivilinna.Lpre_tf_hi_s1: 643f3f935a7SJussi Kivilinna .byte 0x00, 0x51, 0xf1, 0xa0, 0x8a, 0xdb, 0x7b, 0x2a 644f3f935a7SJussi Kivilinna .byte 0x09, 0x58, 0xf8, 0xa9, 0x83, 0xd2, 0x72, 0x23 645f3f935a7SJussi Kivilinna 646f3f935a7SJussi Kivilinna/* 647f3f935a7SJussi Kivilinna * pre-SubByte transform 648f3f935a7SJussi Kivilinna * 649f3f935a7SJussi Kivilinna * pre-lookup for sbox4: 650f3f935a7SJussi Kivilinna * swap_bitendianness( 651f3f935a7SJussi Kivilinna * isom_map_camellia_to_aes( 652f3f935a7SJussi Kivilinna * camellia_f( 653f3f935a7SJussi Kivilinna * swap_bitendianess(in <<< 1) 654f3f935a7SJussi Kivilinna * ) 655f3f935a7SJussi Kivilinna * ) 656f3f935a7SJussi Kivilinna * ) 657f3f935a7SJussi Kivilinna * 658f3f935a7SJussi Kivilinna * (note: '⊕ 0xc5' inside camellia_f()) 659f3f935a7SJussi Kivilinna */ 660f3f935a7SJussi Kivilinna.Lpre_tf_lo_s4: 661f3f935a7SJussi Kivilinna .byte 0x45, 0x40, 0x2e, 0x2b, 0x4b, 0x4e, 0x20, 0x25 662f3f935a7SJussi Kivilinna .byte 0x14, 0x11, 0x7f, 0x7a, 0x1a, 0x1f, 0x71, 0x74 663f3f935a7SJussi Kivilinna.Lpre_tf_hi_s4: 664f3f935a7SJussi Kivilinna .byte 0x00, 0xf1, 0x8a, 0x7b, 0x09, 0xf8, 0x83, 0x72 665f3f935a7SJussi Kivilinna .byte 0xad, 0x5c, 0x27, 0xd6, 0xa4, 0x55, 0x2e, 0xdf 666f3f935a7SJussi Kivilinna 667f3f935a7SJussi Kivilinna/* 668f3f935a7SJussi Kivilinna * post-SubByte transform 669f3f935a7SJussi Kivilinna * 670f3f935a7SJussi Kivilinna * post-lookup for sbox1, sbox4: 671f3f935a7SJussi Kivilinna * swap_bitendianness( 672f3f935a7SJussi Kivilinna * camellia_h( 673f3f935a7SJussi Kivilinna * isom_map_aes_to_camellia( 674f3f935a7SJussi Kivilinna * swap_bitendianness( 675f3f935a7SJussi Kivilinna * aes_inverse_affine_transform(in) 676f3f935a7SJussi Kivilinna * ) 677f3f935a7SJussi Kivilinna * ) 678f3f935a7SJussi Kivilinna * ) 679f3f935a7SJussi Kivilinna * ) 680f3f935a7SJussi Kivilinna * 681f3f935a7SJussi Kivilinna * (note: '⊕ 0x6e' inside camellia_h()) 682f3f935a7SJussi Kivilinna */ 683f3f935a7SJussi Kivilinna.Lpost_tf_lo_s1: 684f3f935a7SJussi Kivilinna .byte 0x3c, 0xcc, 0xcf, 0x3f, 0x32, 0xc2, 0xc1, 0x31 685f3f935a7SJussi Kivilinna .byte 0xdc, 0x2c, 0x2f, 0xdf, 0xd2, 0x22, 0x21, 0xd1 686f3f935a7SJussi Kivilinna.Lpost_tf_hi_s1: 687f3f935a7SJussi Kivilinna .byte 0x00, 0xf9, 0x86, 0x7f, 0xd7, 0x2e, 0x51, 0xa8 688f3f935a7SJussi Kivilinna .byte 0xa4, 0x5d, 0x22, 0xdb, 0x73, 0x8a, 0xf5, 0x0c 689f3f935a7SJussi Kivilinna 690f3f935a7SJussi Kivilinna/* 691f3f935a7SJussi Kivilinna * post-SubByte transform 692f3f935a7SJussi Kivilinna * 693f3f935a7SJussi Kivilinna * post-lookup for sbox2: 694f3f935a7SJussi Kivilinna * swap_bitendianness( 695f3f935a7SJussi Kivilinna * camellia_h( 696f3f935a7SJussi Kivilinna * isom_map_aes_to_camellia( 697f3f935a7SJussi Kivilinna * swap_bitendianness( 698f3f935a7SJussi Kivilinna * aes_inverse_affine_transform(in) 699f3f935a7SJussi Kivilinna * ) 700f3f935a7SJussi Kivilinna * ) 701f3f935a7SJussi Kivilinna * ) 702f3f935a7SJussi Kivilinna * ) <<< 1 703f3f935a7SJussi Kivilinna * 704f3f935a7SJussi Kivilinna * (note: '⊕ 0x6e' inside camellia_h()) 705f3f935a7SJussi Kivilinna */ 706f3f935a7SJussi Kivilinna.Lpost_tf_lo_s2: 707f3f935a7SJussi Kivilinna .byte 0x78, 0x99, 0x9f, 0x7e, 0x64, 0x85, 0x83, 0x62 708f3f935a7SJussi Kivilinna .byte 0xb9, 0x58, 0x5e, 0xbf, 0xa5, 0x44, 0x42, 0xa3 709f3f935a7SJussi Kivilinna.Lpost_tf_hi_s2: 710f3f935a7SJussi Kivilinna .byte 0x00, 0xf3, 0x0d, 0xfe, 0xaf, 0x5c, 0xa2, 0x51 711f3f935a7SJussi Kivilinna .byte 0x49, 0xba, 0x44, 0xb7, 0xe6, 0x15, 0xeb, 0x18 712f3f935a7SJussi Kivilinna 713f3f935a7SJussi Kivilinna/* 714f3f935a7SJussi Kivilinna * post-SubByte transform 715f3f935a7SJussi Kivilinna * 716f3f935a7SJussi Kivilinna * post-lookup for sbox3: 717f3f935a7SJussi Kivilinna * swap_bitendianness( 718f3f935a7SJussi Kivilinna * camellia_h( 719f3f935a7SJussi Kivilinna * isom_map_aes_to_camellia( 720f3f935a7SJussi Kivilinna * swap_bitendianness( 721f3f935a7SJussi Kivilinna * aes_inverse_affine_transform(in) 722f3f935a7SJussi Kivilinna * ) 723f3f935a7SJussi Kivilinna * ) 724f3f935a7SJussi Kivilinna * ) 725f3f935a7SJussi Kivilinna * ) >>> 1 726f3f935a7SJussi Kivilinna * 727f3f935a7SJussi Kivilinna * (note: '⊕ 0x6e' inside camellia_h()) 728f3f935a7SJussi Kivilinna */ 729f3f935a7SJussi Kivilinna.Lpost_tf_lo_s3: 730f3f935a7SJussi Kivilinna .byte 0x1e, 0x66, 0xe7, 0x9f, 0x19, 0x61, 0xe0, 0x98 731f3f935a7SJussi Kivilinna .byte 0x6e, 0x16, 0x97, 0xef, 0x69, 0x11, 0x90, 0xe8 732f3f935a7SJussi Kivilinna.Lpost_tf_hi_s3: 733f3f935a7SJussi Kivilinna .byte 0x00, 0xfc, 0x43, 0xbf, 0xeb, 0x17, 0xa8, 0x54 734f3f935a7SJussi Kivilinna .byte 0x52, 0xae, 0x11, 0xed, 0xb9, 0x45, 0xfa, 0x06 735f3f935a7SJussi Kivilinna 736f3f935a7SJussi Kivilinna/* For isolating SubBytes from AESENCLAST, inverse shift row */ 737f3f935a7SJussi Kivilinna.Linv_shift_row: 738f3f935a7SJussi Kivilinna .byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b 739f3f935a7SJussi Kivilinna .byte 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03 740f3f935a7SJussi Kivilinna 741e183914aSDenys Vlasenko.section .rodata.cst4.L0f0f0f0f, "aM", @progbits, 4 742f3f935a7SJussi Kivilinna.align 4 743f3f935a7SJussi Kivilinna/* 4-bit mask */ 744f3f935a7SJussi Kivilinna.L0f0f0f0f: 745f3f935a7SJussi Kivilinna .long 0x0f0f0f0f 746f3f935a7SJussi Kivilinna 747f3f935a7SJussi Kivilinna.text 748f3f935a7SJussi Kivilinna 74974d8b90aSJiri SlabySYM_FUNC_START_LOCAL(__camellia_enc_blk32) 750f3f935a7SJussi Kivilinna /* input: 751f3f935a7SJussi Kivilinna * %rdi: ctx, CTX 752f3f935a7SJussi Kivilinna * %rax: temporary storage, 512 bytes 753f3f935a7SJussi Kivilinna * %ymm0..%ymm15: 32 plaintext blocks 754f3f935a7SJussi Kivilinna * output: 755f3f935a7SJussi Kivilinna * %ymm0..%ymm15: 32 encrypted blocks, order swapped: 756f3f935a7SJussi Kivilinna * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 757f3f935a7SJussi Kivilinna */ 7588691ccd7SJosh Poimboeuf FRAME_BEGIN 759f3f935a7SJussi Kivilinna 760f3f935a7SJussi Kivilinna leaq 8 * 32(%rax), %rcx; 761f3f935a7SJussi Kivilinna 762f3f935a7SJussi Kivilinna inpack32_post(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 763f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 764f3f935a7SJussi Kivilinna %ymm15, %rax, %rcx); 765f3f935a7SJussi Kivilinna 766f3f935a7SJussi Kivilinna enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 767f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 768f3f935a7SJussi Kivilinna %ymm15, %rax, %rcx, 0); 769f3f935a7SJussi Kivilinna 770f3f935a7SJussi Kivilinna fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 771f3f935a7SJussi Kivilinna %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 772f3f935a7SJussi Kivilinna %ymm15, 773f3f935a7SJussi Kivilinna ((key_table + (8) * 8) + 0)(CTX), 774f3f935a7SJussi Kivilinna ((key_table + (8) * 8) + 4)(CTX), 775f3f935a7SJussi Kivilinna ((key_table + (8) * 8) + 8)(CTX), 776f3f935a7SJussi Kivilinna ((key_table + (8) * 8) + 12)(CTX)); 777f3f935a7SJussi Kivilinna 778f3f935a7SJussi Kivilinna enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 779f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 780f3f935a7SJussi Kivilinna %ymm15, %rax, %rcx, 8); 781f3f935a7SJussi Kivilinna 782f3f935a7SJussi Kivilinna fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 783f3f935a7SJussi Kivilinna %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 784f3f935a7SJussi Kivilinna %ymm15, 785f3f935a7SJussi Kivilinna ((key_table + (16) * 8) + 0)(CTX), 786f3f935a7SJussi Kivilinna ((key_table + (16) * 8) + 4)(CTX), 787f3f935a7SJussi Kivilinna ((key_table + (16) * 8) + 8)(CTX), 788f3f935a7SJussi Kivilinna ((key_table + (16) * 8) + 12)(CTX)); 789f3f935a7SJussi Kivilinna 790f3f935a7SJussi Kivilinna enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 791f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 792f3f935a7SJussi Kivilinna %ymm15, %rax, %rcx, 16); 793f3f935a7SJussi Kivilinna 794f3f935a7SJussi Kivilinna movl $24, %r8d; 795f3f935a7SJussi Kivilinna cmpl $16, key_length(CTX); 796f3f935a7SJussi Kivilinna jne .Lenc_max32; 797f3f935a7SJussi Kivilinna 798f3f935a7SJussi Kivilinna.Lenc_done: 799f3f935a7SJussi Kivilinna /* load CD for output */ 800f3f935a7SJussi Kivilinna vmovdqu 0 * 32(%rcx), %ymm8; 801f3f935a7SJussi Kivilinna vmovdqu 1 * 32(%rcx), %ymm9; 802f3f935a7SJussi Kivilinna vmovdqu 2 * 32(%rcx), %ymm10; 803f3f935a7SJussi Kivilinna vmovdqu 3 * 32(%rcx), %ymm11; 804f3f935a7SJussi Kivilinna vmovdqu 4 * 32(%rcx), %ymm12; 805f3f935a7SJussi Kivilinna vmovdqu 5 * 32(%rcx), %ymm13; 806f3f935a7SJussi Kivilinna vmovdqu 6 * 32(%rcx), %ymm14; 807f3f935a7SJussi Kivilinna vmovdqu 7 * 32(%rcx), %ymm15; 808f3f935a7SJussi Kivilinna 809f3f935a7SJussi Kivilinna outunpack32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 810f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 811f3f935a7SJussi Kivilinna %ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax)); 812f3f935a7SJussi Kivilinna 8138691ccd7SJosh Poimboeuf FRAME_END 814f94909ceSPeter Zijlstra RET; 815f3f935a7SJussi Kivilinna 816f3f935a7SJussi Kivilinna.align 8 817f3f935a7SJussi Kivilinna.Lenc_max32: 818f3f935a7SJussi Kivilinna movl $32, %r8d; 819f3f935a7SJussi Kivilinna 820f3f935a7SJussi Kivilinna fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 821f3f935a7SJussi Kivilinna %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 822f3f935a7SJussi Kivilinna %ymm15, 823f3f935a7SJussi Kivilinna ((key_table + (24) * 8) + 0)(CTX), 824f3f935a7SJussi Kivilinna ((key_table + (24) * 8) + 4)(CTX), 825f3f935a7SJussi Kivilinna ((key_table + (24) * 8) + 8)(CTX), 826f3f935a7SJussi Kivilinna ((key_table + (24) * 8) + 12)(CTX)); 827f3f935a7SJussi Kivilinna 828f3f935a7SJussi Kivilinna enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 829f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 830f3f935a7SJussi Kivilinna %ymm15, %rax, %rcx, 24); 831f3f935a7SJussi Kivilinna 832f3f935a7SJussi Kivilinna jmp .Lenc_done; 83374d8b90aSJiri SlabySYM_FUNC_END(__camellia_enc_blk32) 834f3f935a7SJussi Kivilinna 83574d8b90aSJiri SlabySYM_FUNC_START_LOCAL(__camellia_dec_blk32) 836f3f935a7SJussi Kivilinna /* input: 837f3f935a7SJussi Kivilinna * %rdi: ctx, CTX 838f3f935a7SJussi Kivilinna * %rax: temporary storage, 512 bytes 839f3f935a7SJussi Kivilinna * %r8d: 24 for 16 byte key, 32 for larger 840f3f935a7SJussi Kivilinna * %ymm0..%ymm15: 16 encrypted blocks 841f3f935a7SJussi Kivilinna * output: 842f3f935a7SJussi Kivilinna * %ymm0..%ymm15: 16 plaintext blocks, order swapped: 843f3f935a7SJussi Kivilinna * 7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8 844f3f935a7SJussi Kivilinna */ 8458691ccd7SJosh Poimboeuf FRAME_BEGIN 846f3f935a7SJussi Kivilinna 847f3f935a7SJussi Kivilinna leaq 8 * 32(%rax), %rcx; 848f3f935a7SJussi Kivilinna 849f3f935a7SJussi Kivilinna inpack32_post(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 850f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 851f3f935a7SJussi Kivilinna %ymm15, %rax, %rcx); 852f3f935a7SJussi Kivilinna 853f3f935a7SJussi Kivilinna cmpl $32, %r8d; 854f3f935a7SJussi Kivilinna je .Ldec_max32; 855f3f935a7SJussi Kivilinna 856f3f935a7SJussi Kivilinna.Ldec_max24: 857f3f935a7SJussi Kivilinna dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 858f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 859f3f935a7SJussi Kivilinna %ymm15, %rax, %rcx, 16); 860f3f935a7SJussi Kivilinna 861f3f935a7SJussi Kivilinna fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 862f3f935a7SJussi Kivilinna %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 863f3f935a7SJussi Kivilinna %ymm15, 864f3f935a7SJussi Kivilinna ((key_table + (16) * 8) + 8)(CTX), 865f3f935a7SJussi Kivilinna ((key_table + (16) * 8) + 12)(CTX), 866f3f935a7SJussi Kivilinna ((key_table + (16) * 8) + 0)(CTX), 867f3f935a7SJussi Kivilinna ((key_table + (16) * 8) + 4)(CTX)); 868f3f935a7SJussi Kivilinna 869f3f935a7SJussi Kivilinna dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 870f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 871f3f935a7SJussi Kivilinna %ymm15, %rax, %rcx, 8); 872f3f935a7SJussi Kivilinna 873f3f935a7SJussi Kivilinna fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 874f3f935a7SJussi Kivilinna %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 875f3f935a7SJussi Kivilinna %ymm15, 876f3f935a7SJussi Kivilinna ((key_table + (8) * 8) + 8)(CTX), 877f3f935a7SJussi Kivilinna ((key_table + (8) * 8) + 12)(CTX), 878f3f935a7SJussi Kivilinna ((key_table + (8) * 8) + 0)(CTX), 879f3f935a7SJussi Kivilinna ((key_table + (8) * 8) + 4)(CTX)); 880f3f935a7SJussi Kivilinna 881f3f935a7SJussi Kivilinna dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 882f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 883f3f935a7SJussi Kivilinna %ymm15, %rax, %rcx, 0); 884f3f935a7SJussi Kivilinna 885f3f935a7SJussi Kivilinna /* load CD for output */ 886f3f935a7SJussi Kivilinna vmovdqu 0 * 32(%rcx), %ymm8; 887f3f935a7SJussi Kivilinna vmovdqu 1 * 32(%rcx), %ymm9; 888f3f935a7SJussi Kivilinna vmovdqu 2 * 32(%rcx), %ymm10; 889f3f935a7SJussi Kivilinna vmovdqu 3 * 32(%rcx), %ymm11; 890f3f935a7SJussi Kivilinna vmovdqu 4 * 32(%rcx), %ymm12; 891f3f935a7SJussi Kivilinna vmovdqu 5 * 32(%rcx), %ymm13; 892f3f935a7SJussi Kivilinna vmovdqu 6 * 32(%rcx), %ymm14; 893f3f935a7SJussi Kivilinna vmovdqu 7 * 32(%rcx), %ymm15; 894f3f935a7SJussi Kivilinna 895f3f935a7SJussi Kivilinna outunpack32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 896f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 897f3f935a7SJussi Kivilinna %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax)); 898f3f935a7SJussi Kivilinna 8998691ccd7SJosh Poimboeuf FRAME_END 900f94909ceSPeter Zijlstra RET; 901f3f935a7SJussi Kivilinna 902f3f935a7SJussi Kivilinna.align 8 903f3f935a7SJussi Kivilinna.Ldec_max32: 904f3f935a7SJussi Kivilinna dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 905f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 906f3f935a7SJussi Kivilinna %ymm15, %rax, %rcx, 24); 907f3f935a7SJussi Kivilinna 908f3f935a7SJussi Kivilinna fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 909f3f935a7SJussi Kivilinna %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 910f3f935a7SJussi Kivilinna %ymm15, 911f3f935a7SJussi Kivilinna ((key_table + (24) * 8) + 8)(CTX), 912f3f935a7SJussi Kivilinna ((key_table + (24) * 8) + 12)(CTX), 913f3f935a7SJussi Kivilinna ((key_table + (24) * 8) + 0)(CTX), 914f3f935a7SJussi Kivilinna ((key_table + (24) * 8) + 4)(CTX)); 915f3f935a7SJussi Kivilinna 916f3f935a7SJussi Kivilinna jmp .Ldec_max24; 91774d8b90aSJiri SlabySYM_FUNC_END(__camellia_dec_blk32) 918f3f935a7SJussi Kivilinna 9196dcc5627SJiri SlabySYM_FUNC_START(camellia_ecb_enc_32way) 920f3f935a7SJussi Kivilinna /* input: 921f3f935a7SJussi Kivilinna * %rdi: ctx, CTX 922f3f935a7SJussi Kivilinna * %rsi: dst (32 blocks) 923f3f935a7SJussi Kivilinna * %rdx: src (32 blocks) 924f3f935a7SJussi Kivilinna */ 9258691ccd7SJosh Poimboeuf FRAME_BEGIN 926f3f935a7SJussi Kivilinna 927f3f935a7SJussi Kivilinna vzeroupper; 928f3f935a7SJussi Kivilinna 929f3f935a7SJussi Kivilinna inpack32_pre(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 930f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 931f3f935a7SJussi Kivilinna %ymm15, %rdx, (key_table)(CTX)); 932f3f935a7SJussi Kivilinna 933f3f935a7SJussi Kivilinna /* now dst can be used as temporary buffer (even in src == dst case) */ 934f3f935a7SJussi Kivilinna movq %rsi, %rax; 935f3f935a7SJussi Kivilinna 936f3f935a7SJussi Kivilinna call __camellia_enc_blk32; 937f3f935a7SJussi Kivilinna 938f3f935a7SJussi Kivilinna write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0, 939f3f935a7SJussi Kivilinna %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9, 940f3f935a7SJussi Kivilinna %ymm8, %rsi); 941f3f935a7SJussi Kivilinna 942f3f935a7SJussi Kivilinna vzeroupper; 943f3f935a7SJussi Kivilinna 9448691ccd7SJosh Poimboeuf FRAME_END 945f94909ceSPeter Zijlstra RET; 9466dcc5627SJiri SlabySYM_FUNC_END(camellia_ecb_enc_32way) 947f3f935a7SJussi Kivilinna 9486dcc5627SJiri SlabySYM_FUNC_START(camellia_ecb_dec_32way) 949f3f935a7SJussi Kivilinna /* input: 950f3f935a7SJussi Kivilinna * %rdi: ctx, CTX 951f3f935a7SJussi Kivilinna * %rsi: dst (32 blocks) 952f3f935a7SJussi Kivilinna * %rdx: src (32 blocks) 953f3f935a7SJussi Kivilinna */ 9548691ccd7SJosh Poimboeuf FRAME_BEGIN 955f3f935a7SJussi Kivilinna 956f3f935a7SJussi Kivilinna vzeroupper; 957f3f935a7SJussi Kivilinna 958f3f935a7SJussi Kivilinna cmpl $16, key_length(CTX); 959f3f935a7SJussi Kivilinna movl $32, %r8d; 960f3f935a7SJussi Kivilinna movl $24, %eax; 961f3f935a7SJussi Kivilinna cmovel %eax, %r8d; /* max */ 962f3f935a7SJussi Kivilinna 963f3f935a7SJussi Kivilinna inpack32_pre(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 964f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 965f3f935a7SJussi Kivilinna %ymm15, %rdx, (key_table)(CTX, %r8, 8)); 966f3f935a7SJussi Kivilinna 967f3f935a7SJussi Kivilinna /* now dst can be used as temporary buffer (even in src == dst case) */ 968f3f935a7SJussi Kivilinna movq %rsi, %rax; 969f3f935a7SJussi Kivilinna 970f3f935a7SJussi Kivilinna call __camellia_dec_blk32; 971f3f935a7SJussi Kivilinna 972f3f935a7SJussi Kivilinna write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0, 973f3f935a7SJussi Kivilinna %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9, 974f3f935a7SJussi Kivilinna %ymm8, %rsi); 975f3f935a7SJussi Kivilinna 976f3f935a7SJussi Kivilinna vzeroupper; 977f3f935a7SJussi Kivilinna 9788691ccd7SJosh Poimboeuf FRAME_END 979f94909ceSPeter Zijlstra RET; 9806dcc5627SJiri SlabySYM_FUNC_END(camellia_ecb_dec_32way) 981f3f935a7SJussi Kivilinna 9826dcc5627SJiri SlabySYM_FUNC_START(camellia_cbc_dec_32way) 983f3f935a7SJussi Kivilinna /* input: 984f3f935a7SJussi Kivilinna * %rdi: ctx, CTX 985f3f935a7SJussi Kivilinna * %rsi: dst (32 blocks) 986f3f935a7SJussi Kivilinna * %rdx: src (32 blocks) 987f3f935a7SJussi Kivilinna */ 9888691ccd7SJosh Poimboeuf FRAME_BEGIN 989dabe5167SJosh Poimboeuf subq $(16 * 32), %rsp; 990f3f935a7SJussi Kivilinna 991f3f935a7SJussi Kivilinna vzeroupper; 992f3f935a7SJussi Kivilinna 993f3f935a7SJussi Kivilinna cmpl $16, key_length(CTX); 994f3f935a7SJussi Kivilinna movl $32, %r8d; 995f3f935a7SJussi Kivilinna movl $24, %eax; 996f3f935a7SJussi Kivilinna cmovel %eax, %r8d; /* max */ 997f3f935a7SJussi Kivilinna 998f3f935a7SJussi Kivilinna inpack32_pre(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7, 999f3f935a7SJussi Kivilinna %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14, 1000f3f935a7SJussi Kivilinna %ymm15, %rdx, (key_table)(CTX, %r8, 8)); 1001f3f935a7SJussi Kivilinna 1002f3f935a7SJussi Kivilinna cmpq %rsi, %rdx; 1003f3f935a7SJussi Kivilinna je .Lcbc_dec_use_stack; 1004f3f935a7SJussi Kivilinna 1005f3f935a7SJussi Kivilinna /* dst can be used as temporary storage, src is not overwritten. */ 1006f3f935a7SJussi Kivilinna movq %rsi, %rax; 1007f3f935a7SJussi Kivilinna jmp .Lcbc_dec_continue; 1008f3f935a7SJussi Kivilinna 1009f3f935a7SJussi Kivilinna.Lcbc_dec_use_stack: 1010f3f935a7SJussi Kivilinna /* 1011f3f935a7SJussi Kivilinna * dst still in-use (because dst == src), so use stack for temporary 1012f3f935a7SJussi Kivilinna * storage. 1013f3f935a7SJussi Kivilinna */ 1014f3f935a7SJussi Kivilinna movq %rsp, %rax; 1015f3f935a7SJussi Kivilinna 1016f3f935a7SJussi Kivilinna.Lcbc_dec_continue: 1017f3f935a7SJussi Kivilinna call __camellia_dec_blk32; 1018f3f935a7SJussi Kivilinna 1019f3f935a7SJussi Kivilinna vmovdqu %ymm7, (%rax); 1020f3f935a7SJussi Kivilinna vpxor %ymm7, %ymm7, %ymm7; 1021f3f935a7SJussi Kivilinna vinserti128 $1, (%rdx), %ymm7, %ymm7; 1022f3f935a7SJussi Kivilinna vpxor (%rax), %ymm7, %ymm7; 1023f3f935a7SJussi Kivilinna vpxor (0 * 32 + 16)(%rdx), %ymm6, %ymm6; 1024f3f935a7SJussi Kivilinna vpxor (1 * 32 + 16)(%rdx), %ymm5, %ymm5; 1025f3f935a7SJussi Kivilinna vpxor (2 * 32 + 16)(%rdx), %ymm4, %ymm4; 1026f3f935a7SJussi Kivilinna vpxor (3 * 32 + 16)(%rdx), %ymm3, %ymm3; 1027f3f935a7SJussi Kivilinna vpxor (4 * 32 + 16)(%rdx), %ymm2, %ymm2; 1028f3f935a7SJussi Kivilinna vpxor (5 * 32 + 16)(%rdx), %ymm1, %ymm1; 1029f3f935a7SJussi Kivilinna vpxor (6 * 32 + 16)(%rdx), %ymm0, %ymm0; 1030f3f935a7SJussi Kivilinna vpxor (7 * 32 + 16)(%rdx), %ymm15, %ymm15; 1031f3f935a7SJussi Kivilinna vpxor (8 * 32 + 16)(%rdx), %ymm14, %ymm14; 1032f3f935a7SJussi Kivilinna vpxor (9 * 32 + 16)(%rdx), %ymm13, %ymm13; 1033f3f935a7SJussi Kivilinna vpxor (10 * 32 + 16)(%rdx), %ymm12, %ymm12; 1034f3f935a7SJussi Kivilinna vpxor (11 * 32 + 16)(%rdx), %ymm11, %ymm11; 1035f3f935a7SJussi Kivilinna vpxor (12 * 32 + 16)(%rdx), %ymm10, %ymm10; 1036f3f935a7SJussi Kivilinna vpxor (13 * 32 + 16)(%rdx), %ymm9, %ymm9; 1037f3f935a7SJussi Kivilinna vpxor (14 * 32 + 16)(%rdx), %ymm8, %ymm8; 1038f3f935a7SJussi Kivilinna write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0, 1039f3f935a7SJussi Kivilinna %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9, 1040f3f935a7SJussi Kivilinna %ymm8, %rsi); 1041f3f935a7SJussi Kivilinna 1042f3f935a7SJussi Kivilinna vzeroupper; 1043f3f935a7SJussi Kivilinna 1044dabe5167SJosh Poimboeuf addq $(16 * 32), %rsp; 10458691ccd7SJosh Poimboeuf FRAME_END 1046f94909ceSPeter Zijlstra RET; 10476dcc5627SJiri SlabySYM_FUNC_END(camellia_cbc_dec_32way) 1048