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