LCOV - code coverage report
Current view: top level - cipher - rijndael-aesni.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 273 273 100.0 %
Date: 2017-03-02 16:44:37 Functions: 19 19 100.0 %

          Line data    Source code
       1             : /* AES-NI accelerated AES for Libgcrypt
       2             :  * Copyright (C) 2000, 2001, 2002, 2003, 2007,
       3             :  *               2008, 2011, 2012 Free Software Foundation, Inc.
       4             :  *
       5             :  * This file is part of Libgcrypt.
       6             :  *
       7             :  * Libgcrypt is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU Lesser General Public License as
       9             :  * published by the Free Software Foundation; either version 2.1 of
      10             :  * the License, or (at your option) any later version.
      11             :  *
      12             :  * Libgcrypt is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include <config.h>
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <string.h> /* for memcmp() */
      25             : 
      26             : #include "types.h"  /* for byte and u32 typedefs */
      27             : #include "g10lib.h"
      28             : #include "cipher.h"
      29             : #include "bufhelp.h"
      30             : #include "cipher-selftest.h"
      31             : #include "rijndael-internal.h"
      32             : #include "./cipher-internal.h"
      33             : 
      34             : 
      35             : #ifdef USE_AESNI
      36             : 
      37             : 
      38             : #if _GCRY_GCC_VERSION >= 40400 /* 4.4 */
      39             : /* Prevent compiler from issuing SSE instructions between asm blocks. */
      40             : #  pragma GCC target("no-sse")
      41             : #endif
      42             : 
      43             : 
      44             : typedef struct u128_s
      45             : {
      46             :   u32 a, b, c, d;
      47             : } __attribute__((packed, aligned(1), may_alias)) u128_t;
      48             : 
      49             : 
      50             : /* Two macros to be called prior and after the use of AESNI
      51             :    instructions.  There should be no external function calls between
      52             :    the use of these macros.  There purpose is to make sure that the
      53             :    SSE regsiters are cleared and won't reveal any information about
      54             :    the key or the data.  */
      55             : #ifdef __WIN64__
      56             : /* XMM6-XMM15 are callee-saved registers on WIN64. */
      57             : # define aesni_prepare_2_6_variable char win64tmp[16]
      58             : # define aesni_prepare() do { } while (0)
      59             : # define aesni_prepare_2_6()                                            \
      60             :    do { asm volatile ("movdqu %%xmm6, %0\n\t"                           \
      61             :                       : "=m" (*win64tmp)                                \
      62             :                       :                                                 \
      63             :                       : "memory");                                      \
      64             :    } while (0)
      65             : # define aesni_cleanup()                                                \
      66             :    do { asm volatile ("pxor %%xmm0, %%xmm0\n\t"                         \
      67             :                       "pxor %%xmm1, %%xmm1\n" :: );                     \
      68             :    } while (0)
      69             : # define aesni_cleanup_2_6()                                            \
      70             :    do { asm volatile ("movdqu %0,   %%xmm6\n\t"                         \
      71             :                       "pxor %%xmm2, %%xmm2\n"                           \
      72             :                       "pxor %%xmm3, %%xmm3\n"                           \
      73             :                       "pxor %%xmm4, %%xmm4\n"                           \
      74             :                       "pxor %%xmm5, %%xmm5\n"                           \
      75             :                       :                                                 \
      76             :                       : "m" (*win64tmp)                                 \
      77             :                       : "memory");                                      \
      78             :    } while (0)
      79             : #else
      80             : # define aesni_prepare_2_6_variable
      81             : # define aesni_prepare() do { } while (0)
      82             : # define aesni_prepare_2_6() do { } while (0)
      83             : # define aesni_cleanup()                                                \
      84             :    do { asm volatile ("pxor %%xmm0, %%xmm0\n\t"                         \
      85             :                       "pxor %%xmm1, %%xmm1\n" :: );                     \
      86             :    } while (0)
      87             : # define aesni_cleanup_2_6()                                            \
      88             :    do { asm volatile ("pxor %%xmm2, %%xmm2\n\t"                         \
      89             :                       "pxor %%xmm3, %%xmm3\n"                           \
      90             :                       "pxor %%xmm4, %%xmm4\n"                           \
      91             :                       "pxor %%xmm5, %%xmm5\n"                           \
      92             :                       "pxor %%xmm6, %%xmm6\n":: );                      \
      93             :    } while (0)
      94             : #endif
      95             : 
      96             : void
      97        1558 : _gcry_aes_aesni_do_setkey (RIJNDAEL_context *ctx, const byte *key)
      98             : {
      99             :   aesni_prepare_2_6_variable;
     100             : 
     101             :   aesni_prepare();
     102             :   aesni_prepare_2_6();
     103             : 
     104        1558 :   if (ctx->rounds < 12)
     105             :     {
     106             :       /* 128-bit key */
     107             : #define AESKEYGENASSIST_xmm1_xmm2(imm8) \
     108             :         ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t"
     109             : #define AESKEY_EXPAND128 \
     110             :         "pshufd $0xff, %%xmm2, %%xmm2\n\t" \
     111             :         "movdqa %%xmm1, %%xmm3\n\t" \
     112             :         "pslldq $4, %%xmm3\n\t" \
     113             :         "pxor   %%xmm3, %%xmm1\n\t" \
     114             :         "pslldq $4, %%xmm3\n\t" \
     115             :         "pxor   %%xmm3, %%xmm1\n\t" \
     116             :         "pslldq $4, %%xmm3\n\t" \
     117             :         "pxor   %%xmm3, %%xmm2\n\t" \
     118             :         "pxor   %%xmm2, %%xmm1\n\t"
     119             : 
     120         931 :       asm volatile ("movdqu (%[key]), %%xmm1\n\t"     /* xmm1 := key   */
     121             :                     "movdqa %%xmm1, (%[ksch])\n\t"     /* ksch[0] := xmm1  */
     122             :                     AESKEYGENASSIST_xmm1_xmm2(0x01)
     123             :                     AESKEY_EXPAND128
     124             :                     "movdqa %%xmm1, 0x10(%[ksch])\n\t" /* ksch[1] := xmm1  */
     125             :                     AESKEYGENASSIST_xmm1_xmm2(0x02)
     126             :                     AESKEY_EXPAND128
     127             :                     "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1  */
     128             :                     AESKEYGENASSIST_xmm1_xmm2(0x04)
     129             :                     AESKEY_EXPAND128
     130             :                     "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1  */
     131             :                     AESKEYGENASSIST_xmm1_xmm2(0x08)
     132             :                     AESKEY_EXPAND128
     133             :                     "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1  */
     134             :                     AESKEYGENASSIST_xmm1_xmm2(0x10)
     135             :                     AESKEY_EXPAND128
     136             :                     "movdqa %%xmm1, 0x50(%[ksch])\n\t" /* ksch[5] := xmm1  */
     137             :                     AESKEYGENASSIST_xmm1_xmm2(0x20)
     138             :                     AESKEY_EXPAND128
     139             :                     "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1  */
     140             :                     AESKEYGENASSIST_xmm1_xmm2(0x40)
     141             :                     AESKEY_EXPAND128
     142             :                     "movdqa %%xmm1, 0x70(%[ksch])\n\t" /* ksch[7] := xmm1  */
     143             :                     AESKEYGENASSIST_xmm1_xmm2(0x80)
     144             :                     AESKEY_EXPAND128
     145             :                     "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1  */
     146             :                     AESKEYGENASSIST_xmm1_xmm2(0x1b)
     147             :                     AESKEY_EXPAND128
     148             :                     "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1  */
     149             :                     AESKEYGENASSIST_xmm1_xmm2(0x36)
     150             :                     AESKEY_EXPAND128
     151             :                     "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1  */
     152             :                     :
     153             :                     : [key] "r" (key), [ksch] "r" (ctx->keyschenc)
     154             :                     : "cc", "memory" );
     155             : #undef AESKEYGENASSIST_xmm1_xmm2
     156             : #undef AESKEY_EXPAND128
     157             :     }
     158         627 :   else if (ctx->rounds == 12)
     159             :     {
     160             :       /* 192-bit key */
     161             : #define AESKEYGENASSIST_xmm3_xmm2(imm8) \
     162             :         ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t"
     163             : #define AESKEY_EXPAND192 \
     164             :         "pshufd $0x55, %%xmm2, %%xmm2\n\t" \
     165             :         "movdqu %%xmm1, %%xmm4\n\t" \
     166             :         "pslldq $4, %%xmm4\n\t" \
     167             :         "pxor %%xmm4, %%xmm1\n\t" \
     168             :         "pslldq $4, %%xmm4\n\t" \
     169             :         "pxor %%xmm4, %%xmm1\n\t" \
     170             :         "pslldq $4, %%xmm4\n\t" \
     171             :         "pxor %%xmm4, %%xmm1\n\t" \
     172             :         "pxor %%xmm2, %%xmm1\n\t" \
     173             :         "pshufd $0xff, %%xmm1, %%xmm2\n\t" \
     174             :         "movdqu %%xmm3, %%xmm4\n\t" \
     175             :         "pslldq $4, %%xmm4\n\t" \
     176             :         "pxor %%xmm4, %%xmm3\n\t" \
     177             :         "pxor %%xmm2, %%xmm3\n\t"
     178             : 
     179         280 :       asm volatile ("movdqu (%[key]), %%xmm1\n\t"     /* xmm1 := key[0..15]   */
     180             :                     "movq 16(%[key]), %%xmm3\n\t"     /* xmm3 := key[16..23]  */
     181             :                     "movdqa %%xmm1, (%[ksch])\n\t"    /* ksch[0] := xmm1  */
     182             :                     "movdqa %%xmm3, %%xmm5\n\t"
     183             : 
     184             :                     AESKEYGENASSIST_xmm3_xmm2(0x01)
     185             :                     AESKEY_EXPAND192
     186             :                     "shufpd $0, %%xmm1, %%xmm5\n\t"
     187             :                     "movdqa %%xmm5, 0x10(%[ksch])\n\t" /* ksch[1] := xmm5  */
     188             :                     "movdqa %%xmm1, %%xmm6\n\t"
     189             :                     "shufpd $1, %%xmm3, %%xmm6\n\t"
     190             :                     "movdqa %%xmm6, 0x20(%[ksch])\n\t" /* ksch[2] := xmm6  */
     191             :                     AESKEYGENASSIST_xmm3_xmm2(0x02)
     192             :                     AESKEY_EXPAND192
     193             :                     "movdqa %%xmm1, 0x30(%[ksch])\n\t" /* ksch[3] := xmm1  */
     194             :                     "movdqa %%xmm3, %%xmm5\n\t"
     195             : 
     196             :                     AESKEYGENASSIST_xmm3_xmm2(0x04)
     197             :                     AESKEY_EXPAND192
     198             :                     "shufpd $0, %%xmm1, %%xmm5\n\t"
     199             :                     "movdqa %%xmm5, 0x40(%[ksch])\n\t" /* ksch[4] := xmm5  */
     200             :                     "movdqa %%xmm1, %%xmm6\n\t"
     201             :                     "shufpd $1, %%xmm3, %%xmm6\n\t"
     202             :                     "movdqa %%xmm6, 0x50(%[ksch])\n\t" /* ksch[5] := xmm6  */
     203             :                     AESKEYGENASSIST_xmm3_xmm2(0x08)
     204             :                     AESKEY_EXPAND192
     205             :                     "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1  */
     206             :                     "movdqa %%xmm3, %%xmm5\n\t"
     207             : 
     208             :                     AESKEYGENASSIST_xmm3_xmm2(0x10)
     209             :                     AESKEY_EXPAND192
     210             :                     "shufpd $0, %%xmm1, %%xmm5\n\t"
     211             :                     "movdqa %%xmm5, 0x70(%[ksch])\n\t" /* ksch[7] := xmm5  */
     212             :                     "movdqa %%xmm1, %%xmm6\n\t"
     213             :                     "shufpd $1, %%xmm3, %%xmm6\n\t"
     214             :                     "movdqa %%xmm6, 0x80(%[ksch])\n\t" /* ksch[8] := xmm6  */
     215             :                     AESKEYGENASSIST_xmm3_xmm2(0x20)
     216             :                     AESKEY_EXPAND192
     217             :                     "movdqa %%xmm1, 0x90(%[ksch])\n\t" /* ksch[9] := xmm1  */
     218             :                     "movdqa %%xmm3, %%xmm5\n\t"
     219             : 
     220             :                     AESKEYGENASSIST_xmm3_xmm2(0x40)
     221             :                     AESKEY_EXPAND192
     222             :                     "shufpd $0, %%xmm1, %%xmm5\n\t"
     223             :                     "movdqa %%xmm5, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm5  */
     224             :                     "movdqa %%xmm1, %%xmm6\n\t"
     225             :                     "shufpd $1, %%xmm3, %%xmm6\n\t"
     226             :                     "movdqa %%xmm6, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm6  */
     227             :                     AESKEYGENASSIST_xmm3_xmm2(0x80)
     228             :                     AESKEY_EXPAND192
     229             :                     "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1  */
     230             :                     :
     231             :                     : [key] "r" (key), [ksch] "r" (ctx->keyschenc)
     232             :                     : "cc", "memory" );
     233             : #undef AESKEYGENASSIST_xmm3_xmm2
     234             : #undef AESKEY_EXPAND192
     235             :     }
     236         347 :   else if (ctx->rounds > 12)
     237             :     {
     238             :       /* 256-bit key */
     239             : #define AESKEYGENASSIST_xmm1_xmm2(imm8) \
     240             :         ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd1, " #imm8 " \n\t"
     241             : #define AESKEYGENASSIST_xmm3_xmm2(imm8) \
     242             :         ".byte 0x66, 0x0f, 0x3a, 0xdf, 0xd3, " #imm8 " \n\t"
     243             : #define AESKEY_EXPAND256_A \
     244             :         "pshufd $0xff, %%xmm2, %%xmm2\n\t" \
     245             :         "movdqa %%xmm1, %%xmm4\n\t" \
     246             :         "pslldq $4, %%xmm4\n\t" \
     247             :         "pxor %%xmm4, %%xmm1\n\t" \
     248             :         "pslldq $4, %%xmm4\n\t" \
     249             :         "pxor %%xmm4, %%xmm1\n\t" \
     250             :         "pslldq $4, %%xmm4\n\t" \
     251             :         "pxor %%xmm4, %%xmm1\n\t" \
     252             :         "pxor %%xmm2, %%xmm1\n\t"
     253             : #define AESKEY_EXPAND256_B \
     254             :         "pshufd $0xaa, %%xmm2, %%xmm2\n\t" \
     255             :         "movdqa %%xmm3, %%xmm4\n\t" \
     256             :         "pslldq $4, %%xmm4\n\t" \
     257             :         "pxor %%xmm4, %%xmm3\n\t" \
     258             :         "pslldq $4, %%xmm4\n\t" \
     259             :         "pxor %%xmm4, %%xmm3\n\t" \
     260             :         "pslldq $4, %%xmm4\n\t" \
     261             :         "pxor %%xmm4, %%xmm3\n\t" \
     262             :         "pxor %%xmm2, %%xmm3\n\t"
     263             : 
     264         347 :       asm volatile ("movdqu (%[key]), %%xmm1\n\t"     /* xmm1 := key[0..15]   */
     265             :                     "movdqu 16(%[key]), %%xmm3\n\t"   /* xmm3 := key[16..31]  */
     266             :                     "movdqa %%xmm1, (%[ksch])\n\t"     /* ksch[0] := xmm1  */
     267             :                     "movdqa %%xmm3, 0x10(%[ksch])\n\t" /* ksch[1] := xmm3  */
     268             : 
     269             :                     AESKEYGENASSIST_xmm3_xmm2(0x01)
     270             :                     AESKEY_EXPAND256_A
     271             :                     "movdqa %%xmm1, 0x20(%[ksch])\n\t" /* ksch[2] := xmm1  */
     272             :                     AESKEYGENASSIST_xmm1_xmm2(0x00)
     273             :                     AESKEY_EXPAND256_B
     274             :                     "movdqa %%xmm3, 0x30(%[ksch])\n\t" /* ksch[3] := xmm3  */
     275             : 
     276             :                     AESKEYGENASSIST_xmm3_xmm2(0x02)
     277             :                     AESKEY_EXPAND256_A
     278             :                     "movdqa %%xmm1, 0x40(%[ksch])\n\t" /* ksch[4] := xmm1  */
     279             :                     AESKEYGENASSIST_xmm1_xmm2(0x00)
     280             :                     AESKEY_EXPAND256_B
     281             :                     "movdqa %%xmm3, 0x50(%[ksch])\n\t" /* ksch[5] := xmm3  */
     282             : 
     283             :                     AESKEYGENASSIST_xmm3_xmm2(0x04)
     284             :                     AESKEY_EXPAND256_A
     285             :                     "movdqa %%xmm1, 0x60(%[ksch])\n\t" /* ksch[6] := xmm1  */
     286             :                     AESKEYGENASSIST_xmm1_xmm2(0x00)
     287             :                     AESKEY_EXPAND256_B
     288             :                     "movdqa %%xmm3, 0x70(%[ksch])\n\t" /* ksch[7] := xmm3  */
     289             : 
     290             :                     AESKEYGENASSIST_xmm3_xmm2(0x08)
     291             :                     AESKEY_EXPAND256_A
     292             :                     "movdqa %%xmm1, 0x80(%[ksch])\n\t" /* ksch[8] := xmm1  */
     293             :                     AESKEYGENASSIST_xmm1_xmm2(0x00)
     294             :                     AESKEY_EXPAND256_B
     295             :                     "movdqa %%xmm3, 0x90(%[ksch])\n\t" /* ksch[9] := xmm3  */
     296             : 
     297             :                     AESKEYGENASSIST_xmm3_xmm2(0x10)
     298             :                     AESKEY_EXPAND256_A
     299             :                     "movdqa %%xmm1, 0xa0(%[ksch])\n\t" /* ksch[10] := xmm1  */
     300             :                     AESKEYGENASSIST_xmm1_xmm2(0x00)
     301             :                     AESKEY_EXPAND256_B
     302             :                     "movdqa %%xmm3, 0xb0(%[ksch])\n\t" /* ksch[11] := xmm3  */
     303             : 
     304             :                     AESKEYGENASSIST_xmm3_xmm2(0x20)
     305             :                     AESKEY_EXPAND256_A
     306             :                     "movdqa %%xmm1, 0xc0(%[ksch])\n\t" /* ksch[12] := xmm1  */
     307             :                     AESKEYGENASSIST_xmm1_xmm2(0x00)
     308             :                     AESKEY_EXPAND256_B
     309             :                     "movdqa %%xmm3, 0xd0(%[ksch])\n\t" /* ksch[13] := xmm3  */
     310             : 
     311             :                     AESKEYGENASSIST_xmm3_xmm2(0x40)
     312             :                     AESKEY_EXPAND256_A
     313             :                     "movdqa %%xmm1, 0xe0(%[ksch])\n\t" /* ksch[14] := xmm1  */
     314             : 
     315             :                     :
     316             :                     : [key] "r" (key), [ksch] "r" (ctx->keyschenc)
     317             :                     : "cc", "memory" );
     318             : #undef AESKEYGENASSIST_xmm1_xmm2
     319             : #undef AESKEYGENASSIST_xmm3_xmm2
     320             : #undef AESKEY_EXPAND256_A
     321             : #undef AESKEY_EXPAND256_B
     322             :     }
     323             : 
     324        1558 :   aesni_cleanup();
     325        1558 :   aesni_cleanup_2_6();
     326        1558 : }
     327             : 
     328             : 
     329             : /* Make a decryption key from an encryption key. */
     330             : void
     331        1082 : _gcry_aes_aesni_prepare_decryption (RIJNDAEL_context *ctx)
     332             : {
     333             :   /* The AES-NI decrypt instructions use the Equivalent Inverse
     334             :      Cipher, thus we can't use the the standard decrypt key
     335             :      preparation.  */
     336        1082 :   u128_t *ekey = (u128_t *)ctx->keyschenc;
     337        1082 :   u128_t *dkey = (u128_t *)ctx->keyschdec;
     338             :   int rr;
     339             :   int r;
     340             : 
     341             :   aesni_prepare();
     342             : 
     343             : #define DO_AESNI_AESIMC() \
     344             :   asm volatile ("movdqa %[ekey], %%xmm1\n\t" \
     345             :                 /*"aesimc %%xmm1, %%xmm1\n\t"*/ \
     346             :                 ".byte 0x66, 0x0f, 0x38, 0xdb, 0xc9\n\t" \
     347             :                 "movdqa %%xmm1, %[dkey]" \
     348             :                 : [dkey] "=m" (dkey[r]) \
     349             :                 : [ekey] "m" (ekey[rr]) \
     350             :                 : "memory")
     351             : 
     352        1082 :   dkey[0] = ekey[ctx->rounds];
     353        1082 :   r=1;
     354        1082 :   rr=ctx->rounds-1;
     355        1082 :   DO_AESNI_AESIMC(); r++; rr--; /* round 1 */
     356        1082 :   DO_AESNI_AESIMC(); r++; rr--; /* round 2 */
     357        1082 :   DO_AESNI_AESIMC(); r++; rr--; /* round 3 */
     358        1082 :   DO_AESNI_AESIMC(); r++; rr--; /* round 4 */
     359        1082 :   DO_AESNI_AESIMC(); r++; rr--; /* round 5 */
     360        1082 :   DO_AESNI_AESIMC(); r++; rr--; /* round 6 */
     361        1082 :   DO_AESNI_AESIMC(); r++; rr--; /* round 7 */
     362        1082 :   DO_AESNI_AESIMC(); r++; rr--; /* round 8 */
     363        1082 :   DO_AESNI_AESIMC(); r++; rr--; /* round 9 */
     364        1082 :   if (ctx->rounds > 10)
     365             :     {
     366         699 :       DO_AESNI_AESIMC(); r++; rr--; /* round 10 */
     367         699 :       DO_AESNI_AESIMC(); r++; rr--; /* round 11 */
     368         699 :       if (ctx->rounds > 12)
     369             :         {
     370         360 :           DO_AESNI_AESIMC(); r++; rr--; /* round 12 */
     371         360 :           DO_AESNI_AESIMC(); r++; rr--; /* round 13 */
     372             :         }
     373             :     }
     374             : 
     375        1082 :   dkey[r] = ekey[0];
     376             : 
     377             : #undef DO_AESNI_AESIMC
     378             : 
     379        1082 :   aesni_cleanup();
     380        1082 : }
     381             : 
     382             : 
     383             : /* Encrypt one block using the Intel AES-NI instructions.  Block is input
     384             :  * and output through SSE register xmm0. */
     385             : static inline void
     386    11490668 : do_aesni_enc (const RIJNDAEL_context *ctx)
     387             : {
     388             : #define aesenc_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
     389             : #define aesenclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
     390    22981336 :   asm volatile ("movdqa (%[key]), %%xmm1\n\t"    /* xmm1 := key[0] */
     391             :                 "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0] */
     392             :                 "movdqa 0x10(%[key]), %%xmm1\n\t"
     393             :                 aesenc_xmm1_xmm0
     394             :                 "movdqa 0x20(%[key]), %%xmm1\n\t"
     395             :                 aesenc_xmm1_xmm0
     396             :                 "movdqa 0x30(%[key]), %%xmm1\n\t"
     397             :                 aesenc_xmm1_xmm0
     398             :                 "movdqa 0x40(%[key]), %%xmm1\n\t"
     399             :                 aesenc_xmm1_xmm0
     400             :                 "movdqa 0x50(%[key]), %%xmm1\n\t"
     401             :                 aesenc_xmm1_xmm0
     402             :                 "movdqa 0x60(%[key]), %%xmm1\n\t"
     403             :                 aesenc_xmm1_xmm0
     404             :                 "movdqa 0x70(%[key]), %%xmm1\n\t"
     405             :                 aesenc_xmm1_xmm0
     406             :                 "movdqa 0x80(%[key]), %%xmm1\n\t"
     407             :                 aesenc_xmm1_xmm0
     408             :                 "movdqa 0x90(%[key]), %%xmm1\n\t"
     409             :                 aesenc_xmm1_xmm0
     410             :                 "movdqa 0xa0(%[key]), %%xmm1\n\t"
     411             :                 "cmpl $10, %[rounds]\n\t"
     412             :                 "jz .Lenclast%=\n\t"
     413             :                 aesenc_xmm1_xmm0
     414             :                 "movdqa 0xb0(%[key]), %%xmm1\n\t"
     415             :                 aesenc_xmm1_xmm0
     416             :                 "movdqa 0xc0(%[key]), %%xmm1\n\t"
     417             :                 "cmpl $12, %[rounds]\n\t"
     418             :                 "jz .Lenclast%=\n\t"
     419             :                 aesenc_xmm1_xmm0
     420             :                 "movdqa 0xd0(%[key]), %%xmm1\n\t"
     421             :                 aesenc_xmm1_xmm0
     422             :                 "movdqa 0xe0(%[key]), %%xmm1\n"
     423             : 
     424             :                 ".Lenclast%=:\n\t"
     425             :                 aesenclast_xmm1_xmm0
     426             :                 "\n"
     427             :                 :
     428             :                 : [key] "r" (ctx->keyschenc),
     429    11490668 :                   [rounds] "r" (ctx->rounds)
     430             :                 : "cc", "memory");
     431             : #undef aesenc_xmm1_xmm0
     432             : #undef aesenclast_xmm1_xmm0
     433    11490668 : }
     434             : 
     435             : 
     436             : /* Decrypt one block using the Intel AES-NI instructions.  Block is input
     437             :  * and output through SSE register xmm0. */
     438             : static inline void
     439     1943721 : do_aesni_dec (const RIJNDAEL_context *ctx)
     440             : {
     441             : #define aesdec_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xde, 0xc1\n\t"
     442             : #define aesdeclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc1\n\t"
     443     3887442 :   asm volatile ("movdqa (%[key]), %%xmm1\n\t"
     444             :                 "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0] */
     445             :                 "movdqa 0x10(%[key]), %%xmm1\n\t"
     446             :                 aesdec_xmm1_xmm0
     447             :                 "movdqa 0x20(%[key]), %%xmm1\n\t"
     448             :                 aesdec_xmm1_xmm0
     449             :                 "movdqa 0x30(%[key]), %%xmm1\n\t"
     450             :                 aesdec_xmm1_xmm0
     451             :                 "movdqa 0x40(%[key]), %%xmm1\n\t"
     452             :                 aesdec_xmm1_xmm0
     453             :                 "movdqa 0x50(%[key]), %%xmm1\n\t"
     454             :                 aesdec_xmm1_xmm0
     455             :                 "movdqa 0x60(%[key]), %%xmm1\n\t"
     456             :                 aesdec_xmm1_xmm0
     457             :                 "movdqa 0x70(%[key]), %%xmm1\n\t"
     458             :                 aesdec_xmm1_xmm0
     459             :                 "movdqa 0x80(%[key]), %%xmm1\n\t"
     460             :                 aesdec_xmm1_xmm0
     461             :                 "movdqa 0x90(%[key]), %%xmm1\n\t"
     462             :                 aesdec_xmm1_xmm0
     463             :                 "movdqa 0xa0(%[key]), %%xmm1\n\t"
     464             :                 "cmpl $10, %[rounds]\n\t"
     465             :                 "jz .Ldeclast%=\n\t"
     466             :                 aesdec_xmm1_xmm0
     467             :                 "movdqa 0xb0(%[key]), %%xmm1\n\t"
     468             :                 aesdec_xmm1_xmm0
     469             :                 "movdqa 0xc0(%[key]), %%xmm1\n\t"
     470             :                 "cmpl $12, %[rounds]\n\t"
     471             :                 "jz .Ldeclast%=\n\t"
     472             :                 aesdec_xmm1_xmm0
     473             :                 "movdqa 0xd0(%[key]), %%xmm1\n\t"
     474             :                 aesdec_xmm1_xmm0
     475             :                 "movdqa 0xe0(%[key]), %%xmm1\n"
     476             : 
     477             :                 ".Ldeclast%=:\n\t"
     478             :                 aesdeclast_xmm1_xmm0
     479             :                 "\n"
     480             :                 :
     481             :                 : [key] "r" (ctx->keyschdec),
     482     1943721 :                   [rounds] "r" (ctx->rounds)
     483             :                 : "cc", "memory");
     484             : #undef aesdec_xmm1_xmm0
     485             : #undef aesdeclast_xmm1_xmm0
     486     1943721 : }
     487             : 
     488             : 
     489             : /* Encrypt four blocks using the Intel AES-NI instructions.  Blocks are input
     490             :  * and output through SSE registers xmm1 to xmm4.  */
     491             : static inline void
     492     1763767 : do_aesni_enc_vec4 (const RIJNDAEL_context *ctx)
     493             : {
     494             : #define aesenc_xmm0_xmm1      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc8\n\t"
     495             : #define aesenc_xmm0_xmm2      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd0\n\t"
     496             : #define aesenc_xmm0_xmm3      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd8\n\t"
     497             : #define aesenc_xmm0_xmm4      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe0\n\t"
     498             : #define aesenclast_xmm0_xmm1  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc8\n\t"
     499             : #define aesenclast_xmm0_xmm2  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd0\n\t"
     500             : #define aesenclast_xmm0_xmm3  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd8\n\t"
     501             : #define aesenclast_xmm0_xmm4  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe0\n\t"
     502     3527534 :   asm volatile ("movdqa (%[key]), %%xmm0\n\t"
     503             :                 "pxor   %%xmm0, %%xmm1\n\t"     /* xmm1 ^= key[0] */
     504             :                 "pxor   %%xmm0, %%xmm2\n\t"     /* xmm2 ^= key[0] */
     505             :                 "pxor   %%xmm0, %%xmm3\n\t"     /* xmm3 ^= key[0] */
     506             :                 "pxor   %%xmm0, %%xmm4\n\t"     /* xmm4 ^= key[0] */
     507             :                 "movdqa 0x10(%[key]), %%xmm0\n\t"
     508             :                 aesenc_xmm0_xmm1
     509             :                 aesenc_xmm0_xmm2
     510             :                 aesenc_xmm0_xmm3
     511             :                 aesenc_xmm0_xmm4
     512             :                 "movdqa 0x20(%[key]), %%xmm0\n\t"
     513             :                 aesenc_xmm0_xmm1
     514             :                 aesenc_xmm0_xmm2
     515             :                 aesenc_xmm0_xmm3
     516             :                 aesenc_xmm0_xmm4
     517             :                 "movdqa 0x30(%[key]), %%xmm0\n\t"
     518             :                 aesenc_xmm0_xmm1
     519             :                 aesenc_xmm0_xmm2
     520             :                 aesenc_xmm0_xmm3
     521             :                 aesenc_xmm0_xmm4
     522             :                 "movdqa 0x40(%[key]), %%xmm0\n\t"
     523             :                 aesenc_xmm0_xmm1
     524             :                 aesenc_xmm0_xmm2
     525             :                 aesenc_xmm0_xmm3
     526             :                 aesenc_xmm0_xmm4
     527             :                 "movdqa 0x50(%[key]), %%xmm0\n\t"
     528             :                 aesenc_xmm0_xmm1
     529             :                 aesenc_xmm0_xmm2
     530             :                 aesenc_xmm0_xmm3
     531             :                 aesenc_xmm0_xmm4
     532             :                 "movdqa 0x60(%[key]), %%xmm0\n\t"
     533             :                 aesenc_xmm0_xmm1
     534             :                 aesenc_xmm0_xmm2
     535             :                 aesenc_xmm0_xmm3
     536             :                 aesenc_xmm0_xmm4
     537             :                 "movdqa 0x70(%[key]), %%xmm0\n\t"
     538             :                 aesenc_xmm0_xmm1
     539             :                 aesenc_xmm0_xmm2
     540             :                 aesenc_xmm0_xmm3
     541             :                 aesenc_xmm0_xmm4
     542             :                 "movdqa 0x80(%[key]), %%xmm0\n\t"
     543             :                 aesenc_xmm0_xmm1
     544             :                 aesenc_xmm0_xmm2
     545             :                 aesenc_xmm0_xmm3
     546             :                 aesenc_xmm0_xmm4
     547             :                 "movdqa 0x90(%[key]), %%xmm0\n\t"
     548             :                 aesenc_xmm0_xmm1
     549             :                 aesenc_xmm0_xmm2
     550             :                 aesenc_xmm0_xmm3
     551             :                 aesenc_xmm0_xmm4
     552             :                 "movdqa 0xa0(%[key]), %%xmm0\n\t"
     553             :                 "cmpl $10, %[rounds]\n\t"
     554             :                 "jz .Ldeclast%=\n\t"
     555             :                 aesenc_xmm0_xmm1
     556             :                 aesenc_xmm0_xmm2
     557             :                 aesenc_xmm0_xmm3
     558             :                 aesenc_xmm0_xmm4
     559             :                 "movdqa 0xb0(%[key]), %%xmm0\n\t"
     560             :                 aesenc_xmm0_xmm1
     561             :                 aesenc_xmm0_xmm2
     562             :                 aesenc_xmm0_xmm3
     563             :                 aesenc_xmm0_xmm4
     564             :                 "movdqa 0xc0(%[key]), %%xmm0\n\t"
     565             :                 "cmpl $12, %[rounds]\n\t"
     566             :                 "jz .Ldeclast%=\n\t"
     567             :                 aesenc_xmm0_xmm1
     568             :                 aesenc_xmm0_xmm2
     569             :                 aesenc_xmm0_xmm3
     570             :                 aesenc_xmm0_xmm4
     571             :                 "movdqa 0xd0(%[key]), %%xmm0\n\t"
     572             :                 aesenc_xmm0_xmm1
     573             :                 aesenc_xmm0_xmm2
     574             :                 aesenc_xmm0_xmm3
     575             :                 aesenc_xmm0_xmm4
     576             :                 "movdqa 0xe0(%[key]), %%xmm0\n"
     577             : 
     578             :                 ".Ldeclast%=:\n\t"
     579             :                 aesenclast_xmm0_xmm1
     580             :                 aesenclast_xmm0_xmm2
     581             :                 aesenclast_xmm0_xmm3
     582             :                 aesenclast_xmm0_xmm4
     583             :                 : /* no output */
     584             :                 : [key] "r" (ctx->keyschenc),
     585     1763767 :                   [rounds] "r" (ctx->rounds)
     586             :                 : "cc", "memory");
     587             : #undef aesenc_xmm0_xmm1
     588             : #undef aesenc_xmm0_xmm2
     589             : #undef aesenc_xmm0_xmm3
     590             : #undef aesenc_xmm0_xmm4
     591             : #undef aesenclast_xmm0_xmm1
     592             : #undef aesenclast_xmm0_xmm2
     593             : #undef aesenclast_xmm0_xmm3
     594             : #undef aesenclast_xmm0_xmm4
     595     1763767 : }
     596             : 
     597             : 
     598             : /* Decrypt four blocks using the Intel AES-NI instructions.  Blocks are input
     599             :  * and output through SSE registers xmm1 to xmm4.  */
     600             : static inline void
     601     1017713 : do_aesni_dec_vec4 (const RIJNDAEL_context *ctx)
     602             : {
     603             : #define aesdec_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc8\n\t"
     604             : #define aesdec_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd0\n\t"
     605             : #define aesdec_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xde, 0xd8\n\t"
     606             : #define aesdec_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xde, 0xe0\n\t"
     607             : #define aesdeclast_xmm0_xmm1 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc8\n\t"
     608             : #define aesdeclast_xmm0_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd0\n\t"
     609             : #define aesdeclast_xmm0_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xd8\n\t"
     610             : #define aesdeclast_xmm0_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xe0\n\t"
     611     2035426 :   asm volatile ("movdqa (%[key]), %%xmm0\n\t"
     612             :                 "pxor   %%xmm0, %%xmm1\n\t"     /* xmm1 ^= key[0] */
     613             :                 "pxor   %%xmm0, %%xmm2\n\t"     /* xmm2 ^= key[0] */
     614             :                 "pxor   %%xmm0, %%xmm3\n\t"     /* xmm3 ^= key[0] */
     615             :                 "pxor   %%xmm0, %%xmm4\n\t"     /* xmm4 ^= key[0] */
     616             :                 "movdqa 0x10(%[key]), %%xmm0\n\t"
     617             :                 aesdec_xmm0_xmm1
     618             :                 aesdec_xmm0_xmm2
     619             :                 aesdec_xmm0_xmm3
     620             :                 aesdec_xmm0_xmm4
     621             :                 "movdqa 0x20(%[key]), %%xmm0\n\t"
     622             :                 aesdec_xmm0_xmm1
     623             :                 aesdec_xmm0_xmm2
     624             :                 aesdec_xmm0_xmm3
     625             :                 aesdec_xmm0_xmm4
     626             :                 "movdqa 0x30(%[key]), %%xmm0\n\t"
     627             :                 aesdec_xmm0_xmm1
     628             :                 aesdec_xmm0_xmm2
     629             :                 aesdec_xmm0_xmm3
     630             :                 aesdec_xmm0_xmm4
     631             :                 "movdqa 0x40(%[key]), %%xmm0\n\t"
     632             :                 aesdec_xmm0_xmm1
     633             :                 aesdec_xmm0_xmm2
     634             :                 aesdec_xmm0_xmm3
     635             :                 aesdec_xmm0_xmm4
     636             :                 "movdqa 0x50(%[key]), %%xmm0\n\t"
     637             :                 aesdec_xmm0_xmm1
     638             :                 aesdec_xmm0_xmm2
     639             :                 aesdec_xmm0_xmm3
     640             :                 aesdec_xmm0_xmm4
     641             :                 "movdqa 0x60(%[key]), %%xmm0\n\t"
     642             :                 aesdec_xmm0_xmm1
     643             :                 aesdec_xmm0_xmm2
     644             :                 aesdec_xmm0_xmm3
     645             :                 aesdec_xmm0_xmm4
     646             :                 "movdqa 0x70(%[key]), %%xmm0\n\t"
     647             :                 aesdec_xmm0_xmm1
     648             :                 aesdec_xmm0_xmm2
     649             :                 aesdec_xmm0_xmm3
     650             :                 aesdec_xmm0_xmm4
     651             :                 "movdqa 0x80(%[key]), %%xmm0\n\t"
     652             :                 aesdec_xmm0_xmm1
     653             :                 aesdec_xmm0_xmm2
     654             :                 aesdec_xmm0_xmm3
     655             :                 aesdec_xmm0_xmm4
     656             :                 "movdqa 0x90(%[key]), %%xmm0\n\t"
     657             :                 aesdec_xmm0_xmm1
     658             :                 aesdec_xmm0_xmm2
     659             :                 aesdec_xmm0_xmm3
     660             :                 aesdec_xmm0_xmm4
     661             :                 "movdqa 0xa0(%[key]), %%xmm0\n\t"
     662             :                 "cmpl $10, %[rounds]\n\t"
     663             :                 "jz .Ldeclast%=\n\t"
     664             :                 aesdec_xmm0_xmm1
     665             :                 aesdec_xmm0_xmm2
     666             :                 aesdec_xmm0_xmm3
     667             :                 aesdec_xmm0_xmm4
     668             :                 "movdqa 0xb0(%[key]), %%xmm0\n\t"
     669             :                 aesdec_xmm0_xmm1
     670             :                 aesdec_xmm0_xmm2
     671             :                 aesdec_xmm0_xmm3
     672             :                 aesdec_xmm0_xmm4
     673             :                 "movdqa 0xc0(%[key]), %%xmm0\n\t"
     674             :                 "cmpl $12, %[rounds]\n\t"
     675             :                 "jz .Ldeclast%=\n\t"
     676             :                 aesdec_xmm0_xmm1
     677             :                 aesdec_xmm0_xmm2
     678             :                 aesdec_xmm0_xmm3
     679             :                 aesdec_xmm0_xmm4
     680             :                 "movdqa 0xd0(%[key]), %%xmm0\n\t"
     681             :                 aesdec_xmm0_xmm1
     682             :                 aesdec_xmm0_xmm2
     683             :                 aesdec_xmm0_xmm3
     684             :                 aesdec_xmm0_xmm4
     685             :                 "movdqa 0xe0(%[key]), %%xmm0\n"
     686             : 
     687             :                 ".Ldeclast%=:\n\t"
     688             :                 aesdeclast_xmm0_xmm1
     689             :                 aesdeclast_xmm0_xmm2
     690             :                 aesdeclast_xmm0_xmm3
     691             :                 aesdeclast_xmm0_xmm4
     692             :                 : /* no output */
     693             :                 : [key] "r" (ctx->keyschdec),
     694     1017713 :                   [rounds] "r" (ctx->rounds)
     695             :                 : "cc", "memory");
     696             : #undef aesdec_xmm0_xmm1
     697             : #undef aesdec_xmm0_xmm2
     698             : #undef aesdec_xmm0_xmm3
     699             : #undef aesdec_xmm0_xmm4
     700             : #undef aesdeclast_xmm0_xmm1
     701             : #undef aesdeclast_xmm0_xmm2
     702             : #undef aesdeclast_xmm0_xmm3
     703             : #undef aesdeclast_xmm0_xmm4
     704     1017713 : }
     705             : 
     706             : 
     707             : /* Perform a CTR encryption round using the counter CTR and the input
     708             :    block A.  Write the result to the output block B and update CTR.
     709             :    CTR needs to be a 16 byte aligned little-endian value.  */
     710             : static void
     711       57810 : do_aesni_ctr (const RIJNDAEL_context *ctx,
     712             :               unsigned char *ctr, unsigned char *b, const unsigned char *a)
     713             : {
     714             : #define aesenc_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
     715             : #define aesenclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
     716             : 
     717      115620 :   asm volatile ("movdqa %%xmm5, %%xmm0\n\t"     /* xmm0 := CTR (xmm5)  */
     718             :                 "pcmpeqd %%xmm1, %%xmm1\n\t"
     719             :                 "psrldq $8, %%xmm1\n\t"         /* xmm1 = -1 */
     720             : 
     721             :                 "pshufb %%xmm6, %%xmm5\n\t"
     722             :                 "psubq  %%xmm1, %%xmm5\n\t"     /* xmm5++ (big endian) */
     723             : 
     724             :                 /* detect if 64-bit carry handling is needed */
     725             :                 "cmpl   $0xffffffff, 8(%[ctr])\n\t"
     726             :                 "jne    .Lno_carry%=\n\t"
     727             :                 "cmpl   $0xffffffff, 12(%[ctr])\n\t"
     728             :                 "jne    .Lno_carry%=\n\t"
     729             : 
     730             :                 "pslldq $8, %%xmm1\n\t"         /* move lower 64-bit to high */
     731             :                 "psubq   %%xmm1, %%xmm5\n\t"    /* add carry to upper 64bits */
     732             : 
     733             :                 ".Lno_carry%=:\n\t"
     734             : 
     735             :                 "pshufb %%xmm6, %%xmm5\n\t"
     736             :                 "movdqa %%xmm5, (%[ctr])\n\t"   /* Update CTR (mem).       */
     737             : 
     738             :                 "pxor (%[key]), %%xmm0\n\t"     /* xmm1 ^= key[0]    */
     739             :                 "movdqa 0x10(%[key]), %%xmm1\n\t"
     740             :                 aesenc_xmm1_xmm0
     741             :                 "movdqa 0x20(%[key]), %%xmm1\n\t"
     742             :                 aesenc_xmm1_xmm0
     743             :                 "movdqa 0x30(%[key]), %%xmm1\n\t"
     744             :                 aesenc_xmm1_xmm0
     745             :                 "movdqa 0x40(%[key]), %%xmm1\n\t"
     746             :                 aesenc_xmm1_xmm0
     747             :                 "movdqa 0x50(%[key]), %%xmm1\n\t"
     748             :                 aesenc_xmm1_xmm0
     749             :                 "movdqa 0x60(%[key]), %%xmm1\n\t"
     750             :                 aesenc_xmm1_xmm0
     751             :                 "movdqa 0x70(%[key]), %%xmm1\n\t"
     752             :                 aesenc_xmm1_xmm0
     753             :                 "movdqa 0x80(%[key]), %%xmm1\n\t"
     754             :                 aesenc_xmm1_xmm0
     755             :                 "movdqa 0x90(%[key]), %%xmm1\n\t"
     756             :                 aesenc_xmm1_xmm0
     757             :                 "movdqa 0xa0(%[key]), %%xmm1\n\t"
     758             :                 "cmpl $10, %[rounds]\n\t"
     759             :                 "jz .Lenclast%=\n\t"
     760             :                 aesenc_xmm1_xmm0
     761             :                 "movdqa 0xb0(%[key]), %%xmm1\n\t"
     762             :                 aesenc_xmm1_xmm0
     763             :                 "movdqa 0xc0(%[key]), %%xmm1\n\t"
     764             :                 "cmpl $12, %[rounds]\n\t"
     765             :                 "jz .Lenclast%=\n\t"
     766             :                 aesenc_xmm1_xmm0
     767             :                 "movdqa 0xd0(%[key]), %%xmm1\n\t"
     768             :                 aesenc_xmm1_xmm0
     769             :                 "movdqa 0xe0(%[key]), %%xmm1\n"
     770             : 
     771             :                 ".Lenclast%=:\n\t"
     772             :                 aesenclast_xmm1_xmm0
     773             :                 "movdqu %[src], %%xmm1\n\t"      /* xmm1 := input   */
     774             :                 "pxor %%xmm1, %%xmm0\n\t"        /* EncCTR ^= input  */
     775             :                 "movdqu %%xmm0, %[dst]"          /* Store EncCTR.    */
     776             : 
     777             :                 : [dst] "=m" (*b)
     778             :                 : [src] "m" (*a),
     779             :                   [ctr] "r" (ctr),
     780             :                   [key] "r" (ctx->keyschenc),
     781       57810 :                   [rounds] "g" (ctx->rounds)
     782             :                 : "cc", "memory");
     783             : #undef aesenc_xmm1_xmm0
     784             : #undef aesenclast_xmm1_xmm0
     785       57810 : }
     786             : 
     787             : 
     788             : /* Four blocks at a time variant of do_aesni_ctr.  */
     789             : static void
     790     1649512 : do_aesni_ctr_4 (const RIJNDAEL_context *ctx,
     791             :                 unsigned char *ctr, unsigned char *b, const unsigned char *a)
     792             : {
     793             :   static const byte bige_addb_const[4][16] __attribute__ ((aligned (16))) =
     794             :     {
     795             :       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
     796             :       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2 },
     797             :       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3 },
     798             :       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4 }
     799             :     };
     800     1649512 :   const void *bige_addb = bige_addb_const;
     801             : #define aesenc_xmm1_xmm0      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
     802             : #define aesenc_xmm1_xmm2      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd1\n\t"
     803             : #define aesenc_xmm1_xmm3      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd9\n\t"
     804             : #define aesenc_xmm1_xmm4      ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe1\n\t"
     805             : #define aesenclast_xmm1_xmm0  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
     806             : #define aesenclast_xmm1_xmm2  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd1\n\t"
     807             : #define aesenclast_xmm1_xmm3  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd9\n\t"
     808             : #define aesenclast_xmm1_xmm4  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe1\n\t"
     809             : 
     810             :   /* Register usage:
     811             :       esi   keyschedule
     812             :       xmm0  CTR-0
     813             :       xmm1  temp / round key
     814             :       xmm2  CTR-1
     815             :       xmm3  CTR-2
     816             :       xmm4  CTR-3
     817             :       xmm5  copy of *ctr
     818             :       xmm6  endian swapping mask
     819             :    */
     820             : 
     821     1649512 :   asm volatile (/* detect if 8-bit carry handling is needed */
     822             :                 "cmpb   $0xfb, 15(%[ctr])\n\t"
     823             :                 "ja     .Ladd32bit%=\n\t"
     824             : 
     825             :                 "movdqa %%xmm5, %%xmm0\n\t"     /* xmm0 := CTR (xmm5) */
     826             :                 "movdqa 0*16(%[addb]), %%xmm2\n\t"  /* xmm2 := be(1) */
     827             :                 "movdqa 1*16(%[addb]), %%xmm3\n\t"  /* xmm3 := be(2) */
     828             :                 "movdqa 2*16(%[addb]), %%xmm4\n\t"  /* xmm4 := be(3) */
     829             :                 "movdqa 3*16(%[addb]), %%xmm5\n\t"  /* xmm5 := be(4) */
     830             :                 "paddb  %%xmm0, %%xmm2\n\t"     /* xmm2 := be(1) + CTR (xmm0) */
     831             :                 "paddb  %%xmm0, %%xmm3\n\t"     /* xmm3 := be(2) + CTR (xmm0) */
     832             :                 "paddb  %%xmm0, %%xmm4\n\t"     /* xmm4 := be(3) + CTR (xmm0) */
     833             :                 "paddb  %%xmm0, %%xmm5\n\t"     /* xmm5 := be(4) + CTR (xmm0) */
     834             :                 "movdqa (%[key]), %%xmm1\n\t"   /* xmm1 := key[0] */
     835             :                 "jmp    .Lstore_ctr%=\n\t"
     836             : 
     837             :                 ".Ladd32bit%=:\n\t"
     838             :                 "movdqa %%xmm5, %%xmm0\n\t"     /* xmm0, xmm2 := CTR (xmm5) */
     839             :                 "movdqa %%xmm0, %%xmm2\n\t"
     840             :                 "pcmpeqd %%xmm1, %%xmm1\n\t"
     841             :                 "psrldq $8, %%xmm1\n\t"         /* xmm1 = -1 */
     842             : 
     843             :                 "pshufb %%xmm6, %%xmm2\n\t"     /* xmm2 := le(xmm2) */
     844             :                 "psubq  %%xmm1, %%xmm2\n\t"     /* xmm2++           */
     845             :                 "movdqa %%xmm2, %%xmm3\n\t"     /* xmm3 := xmm2     */
     846             :                 "psubq  %%xmm1, %%xmm3\n\t"     /* xmm3++           */
     847             :                 "movdqa %%xmm3, %%xmm4\n\t"     /* xmm4 := xmm3     */
     848             :                 "psubq  %%xmm1, %%xmm4\n\t"     /* xmm4++           */
     849             :                 "movdqa %%xmm4, %%xmm5\n\t"     /* xmm5 := xmm4     */
     850             :                 "psubq  %%xmm1, %%xmm5\n\t"     /* xmm5++           */
     851             : 
     852             :                 /* detect if 64-bit carry handling is needed */
     853             :                 "cmpl   $0xffffffff, 8(%[ctr])\n\t"
     854             :                 "jne    .Lno_carry%=\n\t"
     855             :                 "movl   12(%[ctr]), %%esi\n\t"
     856             :                 "bswapl %%esi\n\t"
     857             :                 "cmpl   $0xfffffffc, %%esi\n\t"
     858             :                 "jb     .Lno_carry%=\n\t"       /* no carry */
     859             : 
     860             :                 "pslldq $8, %%xmm1\n\t"         /* move lower 64-bit to high */
     861             :                 "je     .Lcarry_xmm5%=\n\t"     /* esi == 0xfffffffc */
     862             :                 "cmpl   $0xfffffffe, %%esi\n\t"
     863             :                 "jb     .Lcarry_xmm4%=\n\t"     /* esi == 0xfffffffd */
     864             :                 "je     .Lcarry_xmm3%=\n\t"     /* esi == 0xfffffffe */
     865             :                 /* esi == 0xffffffff */
     866             : 
     867             :                 "psubq   %%xmm1, %%xmm2\n\t"
     868             :                 ".Lcarry_xmm3%=:\n\t"
     869             :                 "psubq   %%xmm1, %%xmm3\n\t"
     870             :                 ".Lcarry_xmm4%=:\n\t"
     871             :                 "psubq   %%xmm1, %%xmm4\n\t"
     872             :                 ".Lcarry_xmm5%=:\n\t"
     873             :                 "psubq   %%xmm1, %%xmm5\n\t"
     874             : 
     875             :                 ".Lno_carry%=:\n\t"
     876             :                 "movdqa (%[key]), %%xmm1\n\t"   /* xmm1 := key[0]    */
     877             : 
     878             :                 "pshufb %%xmm6, %%xmm2\n\t"     /* xmm2 := be(xmm2) */
     879             :                 "pshufb %%xmm6, %%xmm3\n\t"     /* xmm3 := be(xmm3) */
     880             :                 "pshufb %%xmm6, %%xmm4\n\t"     /* xmm4 := be(xmm4) */
     881             :                 "pshufb %%xmm6, %%xmm5\n\t"     /* xmm5 := be(xmm5) */
     882             : 
     883             :                 ".Lstore_ctr%=:\n\t"
     884             :                 "movdqa %%xmm5, (%[ctr])\n\t"   /* Update CTR (mem).  */
     885             :                 :
     886             :                 : [ctr] "r" (ctr),
     887             :                   [key] "r" (ctx->keyschenc),
     888             :                   [addb] "r" (bige_addb)
     889             :                 : "%esi", "cc", "memory");
     890             : 
     891     3299024 :   asm volatile ("pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0]    */
     892             :                 "pxor   %%xmm1, %%xmm2\n\t"     /* xmm2 ^= key[0]    */
     893             :                 "pxor   %%xmm1, %%xmm3\n\t"     /* xmm3 ^= key[0]    */
     894             :                 "pxor   %%xmm1, %%xmm4\n\t"     /* xmm4 ^= key[0]    */
     895             :                 "movdqa 0x10(%[key]), %%xmm1\n\t"
     896             :                 aesenc_xmm1_xmm0
     897             :                 aesenc_xmm1_xmm2
     898             :                 aesenc_xmm1_xmm3
     899             :                 aesenc_xmm1_xmm4
     900             :                 "movdqa 0x20(%[key]), %%xmm1\n\t"
     901             :                 aesenc_xmm1_xmm0
     902             :                 aesenc_xmm1_xmm2
     903             :                 aesenc_xmm1_xmm3
     904             :                 aesenc_xmm1_xmm4
     905             :                 "movdqa 0x30(%[key]), %%xmm1\n\t"
     906             :                 aesenc_xmm1_xmm0
     907             :                 aesenc_xmm1_xmm2
     908             :                 aesenc_xmm1_xmm3
     909             :                 aesenc_xmm1_xmm4
     910             :                 "movdqa 0x40(%[key]), %%xmm1\n\t"
     911             :                 aesenc_xmm1_xmm0
     912             :                 aesenc_xmm1_xmm2
     913             :                 aesenc_xmm1_xmm3
     914             :                 aesenc_xmm1_xmm4
     915             :                 "movdqa 0x50(%[key]), %%xmm1\n\t"
     916             :                 aesenc_xmm1_xmm0
     917             :                 aesenc_xmm1_xmm2
     918             :                 aesenc_xmm1_xmm3
     919             :                 aesenc_xmm1_xmm4
     920             :                 "movdqa 0x60(%[key]), %%xmm1\n\t"
     921             :                 aesenc_xmm1_xmm0
     922             :                 aesenc_xmm1_xmm2
     923             :                 aesenc_xmm1_xmm3
     924             :                 aesenc_xmm1_xmm4
     925             :                 "movdqa 0x70(%[key]), %%xmm1\n\t"
     926             :                 aesenc_xmm1_xmm0
     927             :                 aesenc_xmm1_xmm2
     928             :                 aesenc_xmm1_xmm3
     929             :                 aesenc_xmm1_xmm4
     930             :                 "movdqa 0x80(%[key]), %%xmm1\n\t"
     931             :                 aesenc_xmm1_xmm0
     932             :                 aesenc_xmm1_xmm2
     933             :                 aesenc_xmm1_xmm3
     934             :                 aesenc_xmm1_xmm4
     935             :                 "movdqa 0x90(%[key]), %%xmm1\n\t"
     936             :                 aesenc_xmm1_xmm0
     937             :                 aesenc_xmm1_xmm2
     938             :                 aesenc_xmm1_xmm3
     939             :                 aesenc_xmm1_xmm4
     940             :                 "movdqa 0xa0(%[key]), %%xmm1\n\t"
     941             :                 "cmpl $10, %[rounds]\n\t"
     942             :                 "jz .Lenclast%=\n\t"
     943             :                 aesenc_xmm1_xmm0
     944             :                 aesenc_xmm1_xmm2
     945             :                 aesenc_xmm1_xmm3
     946             :                 aesenc_xmm1_xmm4
     947             :                 "movdqa 0xb0(%[key]), %%xmm1\n\t"
     948             :                 aesenc_xmm1_xmm0
     949             :                 aesenc_xmm1_xmm2
     950             :                 aesenc_xmm1_xmm3
     951             :                 aesenc_xmm1_xmm4
     952             :                 "movdqa 0xc0(%[key]), %%xmm1\n\t"
     953             :                 "cmpl $12, %[rounds]\n\t"
     954             :                 "jz .Lenclast%=\n\t"
     955             :                 aesenc_xmm1_xmm0
     956             :                 aesenc_xmm1_xmm2
     957             :                 aesenc_xmm1_xmm3
     958             :                 aesenc_xmm1_xmm4
     959             :                 "movdqa 0xd0(%[key]), %%xmm1\n\t"
     960             :                 aesenc_xmm1_xmm0
     961             :                 aesenc_xmm1_xmm2
     962             :                 aesenc_xmm1_xmm3
     963             :                 aesenc_xmm1_xmm4
     964             :                 "movdqa 0xe0(%[key]), %%xmm1\n"
     965             : 
     966             :                 ".Lenclast%=:\n\t"
     967             :                 aesenclast_xmm1_xmm0
     968             :                 aesenclast_xmm1_xmm2
     969             :                 aesenclast_xmm1_xmm3
     970             :                 aesenclast_xmm1_xmm4
     971             :                 :
     972             :                 : [key] "r" (ctx->keyschenc),
     973     1649512 :                   [rounds] "r" (ctx->rounds)
     974             :                 : "cc", "memory");
     975             : 
     976     1649512 :   asm volatile ("movdqu (%[src]), %%xmm1\n\t"    /* Get block 1.      */
     977             :                 "pxor %%xmm1, %%xmm0\n\t"        /* EncCTR-1 ^= input */
     978             :                 "movdqu %%xmm0, (%[dst])\n\t"    /* Store block 1     */
     979             : 
     980             :                 "movdqu 16(%[src]), %%xmm1\n\t"  /* Get block 2.      */
     981             :                 "pxor %%xmm1, %%xmm2\n\t"        /* EncCTR-2 ^= input */
     982             :                 "movdqu %%xmm2, 16(%[dst])\n\t"  /* Store block 2.    */
     983             : 
     984             :                 "movdqu 32(%[src]), %%xmm1\n\t"  /* Get block 3.      */
     985             :                 "pxor %%xmm1, %%xmm3\n\t"        /* EncCTR-3 ^= input */
     986             :                 "movdqu %%xmm3, 32(%[dst])\n\t"  /* Store block 3.    */
     987             : 
     988             :                 "movdqu 48(%[src]), %%xmm1\n\t"  /* Get block 4.      */
     989             :                 "pxor %%xmm1, %%xmm4\n\t"        /* EncCTR-4 ^= input */
     990             :                 "movdqu %%xmm4, 48(%[dst])"      /* Store block 4.   */
     991             :                 :
     992             :                 : [src] "r" (a),
     993             :                   [dst] "r" (b)
     994             :                 : "memory");
     995             : #undef aesenc_xmm1_xmm0
     996             : #undef aesenc_xmm1_xmm2
     997             : #undef aesenc_xmm1_xmm3
     998             : #undef aesenc_xmm1_xmm4
     999             : #undef aesenclast_xmm1_xmm0
    1000             : #undef aesenclast_xmm1_xmm2
    1001             : #undef aesenclast_xmm1_xmm3
    1002             : #undef aesenclast_xmm1_xmm4
    1003     1649512 : }
    1004             : 
    1005             : 
    1006             : unsigned int
    1007     4571555 : _gcry_aes_aesni_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst,
    1008             :                          const unsigned char *src)
    1009             : {
    1010             :   aesni_prepare ();
    1011     4571555 :   asm volatile ("movdqu %[src], %%xmm0\n\t"
    1012             :                 :
    1013             :                 : [src] "m" (*src)
    1014             :                 : "memory" );
    1015     4571555 :   do_aesni_enc (ctx);
    1016     4571555 :   asm volatile ("movdqu %%xmm0, %[dst]\n\t"
    1017             :                 : [dst] "=m" (*dst)
    1018             :                 :
    1019             :                 : "memory" );
    1020     4571555 :   aesni_cleanup ();
    1021     4571555 :   return 0;
    1022             : }
    1023             : 
    1024             : 
    1025             : void
    1026       12635 : _gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
    1027             :                          const unsigned char *inbuf, unsigned char *iv,
    1028             :                          size_t nblocks)
    1029             : {
    1030             :   aesni_prepare ();
    1031             : 
    1032       12635 :   asm volatile ("movdqu %[iv], %%xmm0\n\t"
    1033             :                 : /* No output */
    1034             :                 : [iv] "m" (*iv)
    1035             :                 : "memory" );
    1036             : 
    1037     1391079 :   for ( ;nblocks; nblocks-- )
    1038             :     {
    1039     1378444 :       do_aesni_enc (ctx);
    1040             : 
    1041     1378444 :       asm volatile ("movdqu %[inbuf], %%xmm1\n\t"
    1042             :                     "pxor %%xmm1, %%xmm0\n\t"
    1043             :                     "movdqu %%xmm0, %[outbuf]\n\t"
    1044             :                     : [outbuf] "=m" (*outbuf)
    1045             :                     : [inbuf] "m" (*inbuf)
    1046             :                     : "memory" );
    1047             : 
    1048     1378444 :       outbuf += BLOCKSIZE;
    1049     1378444 :       inbuf  += BLOCKSIZE;
    1050             :     }
    1051             : 
    1052       12635 :   asm volatile ("movdqu %%xmm0, %[iv]\n\t"
    1053             :                 : [iv] "=m" (*iv)
    1054             :                 :
    1055             :                 : "memory" );
    1056             : 
    1057       12635 :   aesni_cleanup ();
    1058       12635 : }
    1059             : 
    1060             : 
    1061             : void
    1062      121504 : _gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
    1063             :                          const unsigned char *inbuf, unsigned char *iv,
    1064             :                          size_t nblocks, int cbc_mac)
    1065             : {
    1066             :   aesni_prepare_2_6_variable;
    1067             : 
    1068             :   aesni_prepare ();
    1069             :   aesni_prepare_2_6();
    1070             : 
    1071      121504 :   asm volatile ("movdqu %[iv], %%xmm5\n\t"
    1072             :                 : /* No output */
    1073             :                 : [iv] "m" (*iv)
    1074             :                 : "memory" );
    1075             : 
    1076     5643648 :   for ( ;nblocks; nblocks-- )
    1077             :     {
    1078     5522144 :       asm volatile ("movdqu %[inbuf], %%xmm0\n\t"
    1079             :                     "pxor %%xmm5, %%xmm0\n\t"
    1080             :                     : /* No output */
    1081             :                     : [inbuf] "m" (*inbuf)
    1082             :                     : "memory" );
    1083             : 
    1084     5522144 :       do_aesni_enc (ctx);
    1085             : 
    1086     5522144 :       asm volatile ("movdqa %%xmm0, %%xmm5\n\t"
    1087             :                     "movdqu %%xmm0, %[outbuf]\n\t"
    1088             :                     : [outbuf] "=m" (*outbuf)
    1089             :                     :
    1090             :                     : "memory" );
    1091             : 
    1092     5522144 :       inbuf += BLOCKSIZE;
    1093     5522144 :       if (!cbc_mac)
    1094     1964932 :         outbuf += BLOCKSIZE;
    1095             :     }
    1096             : 
    1097      121504 :   asm volatile ("movdqu %%xmm5, %[iv]\n\t"
    1098             :                 : [iv] "=m" (*iv)
    1099             :                 :
    1100             :                 : "memory" );
    1101             : 
    1102      121504 :   aesni_cleanup ();
    1103      121504 :   aesni_cleanup_2_6 ();
    1104      121504 : }
    1105             : 
    1106             : 
    1107             : void
    1108       71318 : _gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
    1109             :                          const unsigned char *inbuf, unsigned char *ctr,
    1110             :                          size_t nblocks)
    1111             : {
    1112             :   static const unsigned char be_mask[16] __attribute__ ((aligned (16))) =
    1113             :     { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
    1114             :   aesni_prepare_2_6_variable;
    1115             : 
    1116             :   aesni_prepare ();
    1117             :   aesni_prepare_2_6();
    1118             : 
    1119       71318 :   asm volatile ("movdqa %[mask], %%xmm6\n\t" /* Preload mask */
    1120             :                 "movdqa %[ctr], %%xmm5\n\t"  /* Preload CTR */
    1121             :                 : /* No output */
    1122             :                 : [mask] "m" (*be_mask),
    1123             :                   [ctr] "m" (*ctr)
    1124             :                 : "memory");
    1125             : 
    1126     1720830 :   for ( ;nblocks > 3 ; nblocks -= 4 )
    1127             :     {
    1128     1649512 :       do_aesni_ctr_4 (ctx, ctr, outbuf, inbuf);
    1129     1649512 :       outbuf += 4*BLOCKSIZE;
    1130     1649512 :       inbuf  += 4*BLOCKSIZE;
    1131             :     }
    1132      129128 :   for ( ;nblocks; nblocks-- )
    1133             :     {
    1134       57810 :       do_aesni_ctr (ctx, ctr, outbuf, inbuf);
    1135       57810 :       outbuf += BLOCKSIZE;
    1136       57810 :       inbuf  += BLOCKSIZE;
    1137             :     }
    1138       71318 :   aesni_cleanup ();
    1139       71318 :   aesni_cleanup_2_6 ();
    1140       71318 : }
    1141             : 
    1142             : 
    1143             : unsigned int
    1144     1920069 : _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst,
    1145             :                          const unsigned char *src)
    1146             : {
    1147             :   aesni_prepare ();
    1148     1920069 :   asm volatile ("movdqu %[src], %%xmm0\n\t"
    1149             :                 :
    1150             :                 : [src] "m" (*src)
    1151             :                 : "memory" );
    1152     1920069 :   do_aesni_dec (ctx);
    1153     1920069 :   asm volatile ("movdqu %%xmm0, %[dst]\n\t"
    1154             :                 : [dst] "=m" (*dst)
    1155             :                 :
    1156             :                 : "memory" );
    1157     1920069 :   aesni_cleanup ();
    1158     1920069 :   return 0;
    1159             : }
    1160             : 
    1161             : 
    1162             : void
    1163       12259 : _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf,
    1164             :                          const unsigned char *inbuf, unsigned char *iv,
    1165             :                          size_t nblocks)
    1166             : {
    1167             :   aesni_prepare_2_6_variable;
    1168             : 
    1169             :   aesni_prepare ();
    1170             :   aesni_prepare_2_6();
    1171             : 
    1172       12259 :   asm volatile ("movdqu %[iv], %%xmm6\n\t"
    1173             :                 : /* No output */
    1174             :                 : [iv] "m" (*iv)
    1175             :                 : "memory" );
    1176             : 
    1177             :   /* CFB decryption can be parallelized */
    1178      341942 :   for ( ;nblocks >= 4; nblocks -= 4)
    1179             :     {
    1180      329683 :       asm volatile
    1181             :         ("movdqu %%xmm6,         %%xmm1\n\t" /* load input blocks */
    1182             :          "movdqu 0*16(%[inbuf]), %%xmm2\n\t"
    1183             :          "movdqu 1*16(%[inbuf]), %%xmm3\n\t"
    1184             :          "movdqu 2*16(%[inbuf]), %%xmm4\n\t"
    1185             : 
    1186             :          "movdqu 3*16(%[inbuf]), %%xmm6\n\t" /* update IV */
    1187             :          : /* No output */
    1188             :          : [inbuf] "r" (inbuf)
    1189             :          : "memory");
    1190             : 
    1191      329683 :       do_aesni_enc_vec4 (ctx);
    1192             : 
    1193      329683 :       asm volatile
    1194             :         ("movdqu 0*16(%[inbuf]), %%xmm5\n\t"
    1195             :          "pxor %%xmm5, %%xmm1\n\t"
    1196             :          "movdqu %%xmm1, 0*16(%[outbuf])\n\t"
    1197             : 
    1198             :          "movdqu 1*16(%[inbuf]), %%xmm5\n\t"
    1199             :          "pxor %%xmm5, %%xmm2\n\t"
    1200             :          "movdqu %%xmm2, 1*16(%[outbuf])\n\t"
    1201             : 
    1202             :          "movdqu 2*16(%[inbuf]), %%xmm5\n\t"
    1203             :          "pxor %%xmm5, %%xmm3\n\t"
    1204             :          "movdqu %%xmm3, 2*16(%[outbuf])\n\t"
    1205             : 
    1206             :          "movdqu 3*16(%[inbuf]), %%xmm5\n\t"
    1207             :          "pxor %%xmm5, %%xmm4\n\t"
    1208             :          "movdqu %%xmm4, 3*16(%[outbuf])\n\t"
    1209             : 
    1210             :          : /* No output */
    1211             :          : [inbuf] "r" (inbuf),
    1212             :            [outbuf] "r" (outbuf)
    1213             :          : "memory");
    1214             : 
    1215      329683 :       outbuf += 4*BLOCKSIZE;
    1216      329683 :       inbuf  += 4*BLOCKSIZE;
    1217             :     }
    1218             : 
    1219       12259 :   asm volatile ("movdqu %%xmm6, %%xmm0\n\t" ::: "cc");
    1220             : 
    1221       21711 :   for ( ;nblocks; nblocks-- )
    1222             :     {
    1223        9452 :       do_aesni_enc (ctx);
    1224             : 
    1225        9452 :       asm volatile ("movdqa %%xmm0, %%xmm6\n\t"
    1226             :                     "movdqu %[inbuf], %%xmm0\n\t"
    1227             :                     "pxor %%xmm0, %%xmm6\n\t"
    1228             :                     "movdqu %%xmm6, %[outbuf]\n\t"
    1229             :                     : [outbuf] "=m" (*outbuf)
    1230             :                     : [inbuf] "m" (*inbuf)
    1231             :                     : "memory" );
    1232             : 
    1233        9452 :       outbuf += BLOCKSIZE;
    1234        9452 :       inbuf  += BLOCKSIZE;
    1235             :     }
    1236             : 
    1237       12259 :   asm volatile ("movdqu %%xmm0, %[iv]\n\t"
    1238             :                 : [iv] "=m" (*iv)
    1239             :                 :
    1240             :                 : "memory" );
    1241             : 
    1242       12259 :   aesni_cleanup ();
    1243       12259 :   aesni_cleanup_2_6 ();
    1244       12259 : }
    1245             : 
    1246             : 
    1247             : void
    1248       21431 : _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf,
    1249             :                          const unsigned char *inbuf, unsigned char *iv,
    1250             :                          size_t nblocks)
    1251             : {
    1252             :   aesni_prepare_2_6_variable;
    1253             : 
    1254             :   aesni_prepare ();
    1255             :   aesni_prepare_2_6();
    1256             : 
    1257       21431 :   asm volatile
    1258             :     ("movdqu %[iv], %%xmm5\n\t"       /* use xmm5 as fast IV storage */
    1259             :      : /* No output */
    1260             :      : [iv] "m" (*iv)
    1261             :      : "memory");
    1262             : 
    1263      512074 :   for ( ;nblocks > 3 ; nblocks -= 4 )
    1264             :     {
    1265      490643 :       asm volatile
    1266             :         ("movdqu 0*16(%[inbuf]), %%xmm1\n\t"  /* load input blocks */
    1267             :          "movdqu 1*16(%[inbuf]), %%xmm2\n\t"
    1268             :          "movdqu 2*16(%[inbuf]), %%xmm3\n\t"
    1269             :          "movdqu 3*16(%[inbuf]), %%xmm4\n\t"
    1270             :          : /* No output */
    1271             :          : [inbuf] "r" (inbuf)
    1272             :          : "memory");
    1273             : 
    1274      490643 :       do_aesni_dec_vec4 (ctx);
    1275             : 
    1276      490643 :       asm volatile
    1277             :         ("pxor %%xmm5, %%xmm1\n\t"            /* xor IV with output */
    1278             :          "movdqu 0*16(%[inbuf]), %%xmm5\n\t"  /* load new IV */
    1279             :          "movdqu %%xmm1, 0*16(%[outbuf])\n\t"
    1280             : 
    1281             :          "pxor %%xmm5, %%xmm2\n\t"            /* xor IV with output */
    1282             :          "movdqu 1*16(%[inbuf]), %%xmm5\n\t"  /* load new IV */
    1283             :          "movdqu %%xmm2, 1*16(%[outbuf])\n\t"
    1284             : 
    1285             :          "pxor %%xmm5, %%xmm3\n\t"            /* xor IV with output */
    1286             :          "movdqu 2*16(%[inbuf]), %%xmm5\n\t"  /* load new IV */
    1287             :          "movdqu %%xmm3, 2*16(%[outbuf])\n\t"
    1288             : 
    1289             :          "pxor %%xmm5, %%xmm4\n\t"            /* xor IV with output */
    1290             :          "movdqu 3*16(%[inbuf]), %%xmm5\n\t"  /* load new IV */
    1291             :          "movdqu %%xmm4, 3*16(%[outbuf])\n\t"
    1292             : 
    1293             :          : /* No output */
    1294             :          : [inbuf] "r" (inbuf),
    1295             :            [outbuf] "r" (outbuf)
    1296             :          : "memory");
    1297             : 
    1298      490643 :       outbuf += 4*BLOCKSIZE;
    1299      490643 :       inbuf  += 4*BLOCKSIZE;
    1300             :     }
    1301             : 
    1302       40437 :   for ( ;nblocks; nblocks-- )
    1303             :     {
    1304       19006 :       asm volatile
    1305             :         ("movdqu %[inbuf], %%xmm0\n\t"
    1306             :          "movdqa %%xmm0, %%xmm2\n\t"    /* use xmm2 as savebuf */
    1307             :          : /* No output */
    1308             :          : [inbuf] "m" (*inbuf)
    1309             :          : "memory");
    1310             : 
    1311             :       /* uses only xmm0 and xmm1 */
    1312       19006 :       do_aesni_dec (ctx);
    1313             : 
    1314       19006 :       asm volatile
    1315             :         ("pxor %%xmm5, %%xmm0\n\t"    /* xor IV with output */
    1316             :          "movdqu %%xmm0, %[outbuf]\n\t"
    1317             :          "movdqu %%xmm2, %%xmm5\n\t"  /* store savebuf as new IV */
    1318             :          : [outbuf] "=m" (*outbuf)
    1319             :          :
    1320             :          : "memory");
    1321             : 
    1322       19006 :       outbuf += BLOCKSIZE;
    1323       19006 :       inbuf  += BLOCKSIZE;
    1324             :     }
    1325             : 
    1326       21431 :   asm volatile
    1327             :     ("movdqu %%xmm5, %[iv]\n\t"       /* store IV */
    1328             :      : /* No output */
    1329             :      : [iv] "m" (*iv)
    1330             :      : "memory");
    1331             : 
    1332       21431 :   aesni_cleanup ();
    1333       21431 :   aesni_cleanup_2_6 ();
    1334       21431 : }
    1335             : 
    1336             : 
    1337             : static void
    1338        8078 : aesni_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg,
    1339             :                const void *inbuf_arg, size_t nblocks)
    1340             : {
    1341        8078 :   RIJNDAEL_context *ctx = (void *)&c->context.c;
    1342        8078 :   unsigned char *outbuf = outbuf_arg;
    1343        8078 :   const unsigned char *inbuf = inbuf_arg;
    1344        8078 :   u64 n = c->u_mode.ocb.data_nblocks;
    1345             :   const unsigned char *l;
    1346             :   aesni_prepare_2_6_variable;
    1347             : 
    1348             :   aesni_prepare ();
    1349             :   aesni_prepare_2_6 ();
    1350             : 
    1351             :   /* Preload Offset and Checksum */
    1352        8078 :   asm volatile ("movdqu %[iv], %%xmm5\n\t"
    1353             :                 "movdqu %[ctr], %%xmm6\n\t"
    1354             :                 : /* No output */
    1355             :                 : [iv] "m" (*c->u_iv.iv),
    1356             :                   [ctr] "m" (*c->u_ctr.ctr)
    1357             :                 : "memory" );
    1358             : 
    1359             : 
    1360        8956 :   for ( ;nblocks && n % 4; nblocks-- )
    1361             :     {
    1362         878 :       l = ocb_get_l(c, ++n);
    1363             : 
    1364             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
    1365             :       /* Checksum_i = Checksum_{i-1} xor P_i  */
    1366             :       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
    1367         878 :       asm volatile ("movdqu %[l],     %%xmm1\n\t"
    1368             :                     "movdqu %[inbuf], %%xmm0\n\t"
    1369             :                     "pxor   %%xmm1,   %%xmm5\n\t"
    1370             :                     "pxor   %%xmm0,   %%xmm6\n\t"
    1371             :                     "pxor   %%xmm5,   %%xmm0\n\t"
    1372             :                     :
    1373             :                     : [l] "m" (*l),
    1374             :                       [inbuf] "m" (*inbuf)
    1375             :                     : "memory" );
    1376             : 
    1377         878 :       do_aesni_enc (ctx);
    1378             : 
    1379         878 :       asm volatile ("pxor   %%xmm5, %%xmm0\n\t"
    1380             :                     "movdqu %%xmm0, %[outbuf]\n\t"
    1381             :                     : [outbuf] "=m" (*outbuf)
    1382             :                     :
    1383             :                     : "memory" );
    1384             : 
    1385         878 :       inbuf += BLOCKSIZE;
    1386         878 :       outbuf += BLOCKSIZE;
    1387             :     }
    1388             : 
    1389      576748 :   for ( ;nblocks > 3 ; nblocks -= 4 )
    1390             :     {
    1391      568670 :       n += 4;
    1392      568670 :       l = ocb_get_l(c, n);
    1393             : 
    1394             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
    1395             :       /* Checksum_i = Checksum_{i-1} xor P_i  */
    1396             :       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
    1397      568670 :       asm volatile ("movdqu %[l0],     %%xmm0\n\t"
    1398             :                     "movdqu %[inbuf0], %%xmm1\n\t"
    1399             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1400             :                     "pxor   %%xmm1,    %%xmm6\n\t"
    1401             :                     "pxor   %%xmm5,    %%xmm1\n\t"
    1402             :                     "movdqu %%xmm5,    %[outbuf0]\n\t"
    1403             :                     : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE))
    1404             :                     : [l0] "m" (*c->u_mode.ocb.L[0]),
    1405             :                       [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE))
    1406             :                     : "memory" );
    1407      568670 :       asm volatile ("movdqu %[l1],     %%xmm0\n\t"
    1408             :                     "movdqu %[inbuf1], %%xmm2\n\t"
    1409             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1410             :                     "pxor   %%xmm2,    %%xmm6\n\t"
    1411             :                     "pxor   %%xmm5,    %%xmm2\n\t"
    1412             :                     "movdqu %%xmm5,    %[outbuf1]\n\t"
    1413      568670 :                     : [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE))
    1414             :                     : [l1] "m" (*c->u_mode.ocb.L[1]),
    1415      568670 :                       [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE))
    1416             :                     : "memory" );
    1417      568670 :       asm volatile ("movdqu %[l2],     %%xmm0\n\t"
    1418             :                     "movdqu %[inbuf2], %%xmm3\n\t"
    1419             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1420             :                     "pxor   %%xmm3,    %%xmm6\n\t"
    1421             :                     "pxor   %%xmm5,    %%xmm3\n\t"
    1422             :                     "movdqu %%xmm5,    %[outbuf2]\n\t"
    1423      568670 :                     : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE))
    1424             :                     : [l2] "m" (*c->u_mode.ocb.L[0]),
    1425      568670 :                       [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE))
    1426             :                     : "memory" );
    1427      568670 :       asm volatile ("movdqu %[l3],     %%xmm0\n\t"
    1428             :                     "movdqu %[inbuf3], %%xmm4\n\t"
    1429             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1430             :                     "pxor   %%xmm4,    %%xmm6\n\t"
    1431             :                     "pxor   %%xmm5,    %%xmm4\n\t"
    1432             :                     :
    1433             :                     : [l3] "m" (*l),
    1434      568670 :                       [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE))
    1435             :                     : "memory" );
    1436             : 
    1437      568670 :       do_aesni_enc_vec4 (ctx);
    1438             : 
    1439      568670 :       asm volatile ("movdqu %[outbuf0],%%xmm0\n\t"
    1440             :                     "pxor   %%xmm0,    %%xmm1\n\t"
    1441             :                     "movdqu %%xmm1,    %[outbuf0]\n\t"
    1442             :                     "movdqu %[outbuf1],%%xmm0\n\t"
    1443             :                     "pxor   %%xmm0,    %%xmm2\n\t"
    1444             :                     "movdqu %%xmm2,    %[outbuf1]\n\t"
    1445             :                     "movdqu %[outbuf2],%%xmm0\n\t"
    1446             :                     "pxor   %%xmm0,    %%xmm3\n\t"
    1447             :                     "movdqu %%xmm3,    %[outbuf2]\n\t"
    1448             :                     "pxor   %%xmm5,    %%xmm4\n\t"
    1449             :                     "movdqu %%xmm4,    %[outbuf3]\n\t"
    1450             :                     : [outbuf0] "+m" (*(outbuf + 0 * BLOCKSIZE)),
    1451      568670 :                       [outbuf1] "+m" (*(outbuf + 1 * BLOCKSIZE)),
    1452      568670 :                       [outbuf2] "+m" (*(outbuf + 2 * BLOCKSIZE)),
    1453      568670 :                       [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE))
    1454             :                     :
    1455             :                     : "memory" );
    1456             : 
    1457      568670 :       outbuf += 4*BLOCKSIZE;
    1458      568670 :       inbuf  += 4*BLOCKSIZE;
    1459             :     }
    1460             : 
    1461       13354 :   for ( ;nblocks; nblocks-- )
    1462             :     {
    1463        5276 :       l = ocb_get_l(c, ++n);
    1464             : 
    1465             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
    1466             :       /* Checksum_i = Checksum_{i-1} xor P_i  */
    1467             :       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
    1468        5276 :       asm volatile ("movdqu %[l],     %%xmm1\n\t"
    1469             :                     "movdqu %[inbuf], %%xmm0\n\t"
    1470             :                     "pxor   %%xmm1,   %%xmm5\n\t"
    1471             :                     "pxor   %%xmm0,   %%xmm6\n\t"
    1472             :                     "pxor   %%xmm5,   %%xmm0\n\t"
    1473             :                     :
    1474             :                     : [l] "m" (*l),
    1475             :                       [inbuf] "m" (*inbuf)
    1476             :                     : "memory" );
    1477             : 
    1478        5276 :       do_aesni_enc (ctx);
    1479             : 
    1480        5276 :       asm volatile ("pxor   %%xmm5, %%xmm0\n\t"
    1481             :                     "movdqu %%xmm0, %[outbuf]\n\t"
    1482             :                     : [outbuf] "=m" (*outbuf)
    1483             :                     :
    1484             :                     : "memory" );
    1485             : 
    1486        5276 :       inbuf += BLOCKSIZE;
    1487        5276 :       outbuf += BLOCKSIZE;
    1488             :     }
    1489             : 
    1490        8078 :   c->u_mode.ocb.data_nblocks = n;
    1491        8078 :   asm volatile ("movdqu %%xmm5, %[iv]\n\t"
    1492             :                 "movdqu %%xmm6, %[ctr]\n\t"
    1493             :                 : [iv] "=m" (*c->u_iv.iv),
    1494             :                   [ctr] "=m" (*c->u_ctr.ctr)
    1495             :                 :
    1496             :                 : "memory" );
    1497             : 
    1498        8078 :   aesni_cleanup ();
    1499        8078 :   aesni_cleanup_2_6 ();
    1500        8078 : }
    1501             : 
    1502             : 
    1503             : static void
    1504        6586 : aesni_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg,
    1505             :                const void *inbuf_arg, size_t nblocks)
    1506             : {
    1507        6586 :   RIJNDAEL_context *ctx = (void *)&c->context.c;
    1508        6586 :   unsigned char *outbuf = outbuf_arg;
    1509        6586 :   const unsigned char *inbuf = inbuf_arg;
    1510        6586 :   u64 n = c->u_mode.ocb.data_nblocks;
    1511             :   const unsigned char *l;
    1512             :   aesni_prepare_2_6_variable;
    1513             : 
    1514             :   aesni_prepare ();
    1515             :   aesni_prepare_2_6 ();
    1516             : 
    1517             :   /* Preload Offset and Checksum */
    1518        6586 :   asm volatile ("movdqu %[iv], %%xmm5\n\t"
    1519             :                 "movdqu %[ctr], %%xmm6\n\t"
    1520             :                 : /* No output */
    1521             :                 : [iv] "m" (*c->u_iv.iv),
    1522             :                   [ctr] "m" (*c->u_ctr.ctr)
    1523             :                 : "memory" );
    1524             : 
    1525        7464 :   for ( ;nblocks && n % 4; nblocks-- )
    1526             :     {
    1527         878 :       l = ocb_get_l(c, ++n);
    1528             : 
    1529             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
    1530             :       /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
    1531             :       /* Checksum_i = Checksum_{i-1} xor P_i  */
    1532         878 :       asm volatile ("movdqu %[l],     %%xmm1\n\t"
    1533             :                     "movdqu %[inbuf], %%xmm0\n\t"
    1534             :                     "pxor   %%xmm1,   %%xmm5\n\t"
    1535             :                     "pxor   %%xmm5,   %%xmm0\n\t"
    1536             :                     :
    1537             :                     : [l] "m" (*l),
    1538             :                       [inbuf] "m" (*inbuf)
    1539             :                     : "memory" );
    1540             : 
    1541         878 :       do_aesni_dec (ctx);
    1542             : 
    1543         878 :       asm volatile ("pxor   %%xmm5, %%xmm0\n\t"
    1544             :                     "pxor   %%xmm0, %%xmm6\n\t"
    1545             :                     "movdqu %%xmm0, %[outbuf]\n\t"
    1546             :                     : [outbuf] "=m" (*outbuf)
    1547             :                     :
    1548             :                     : "memory" );
    1549             : 
    1550         878 :       inbuf += BLOCKSIZE;
    1551         878 :       outbuf += BLOCKSIZE;
    1552             :     }
    1553             : 
    1554      533656 :   for ( ;nblocks > 3 ; nblocks -= 4 )
    1555             :     {
    1556      527070 :       n += 4;
    1557      527070 :       l = ocb_get_l(c, n);
    1558             : 
    1559             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
    1560             :       /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
    1561             :       /* Checksum_i = Checksum_{i-1} xor P_i  */
    1562      527070 :       asm volatile ("movdqu %[l0],     %%xmm0\n\t"
    1563             :                     "movdqu %[inbuf0], %%xmm1\n\t"
    1564             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1565             :                     "pxor   %%xmm5,    %%xmm1\n\t"
    1566             :                     "movdqu %%xmm5,    %[outbuf0]\n\t"
    1567             :                     : [outbuf0] "=m" (*(outbuf + 0 * BLOCKSIZE))
    1568             :                     : [l0] "m" (*c->u_mode.ocb.L[0]),
    1569             :                       [inbuf0] "m" (*(inbuf + 0 * BLOCKSIZE))
    1570             :                     : "memory" );
    1571      527070 :       asm volatile ("movdqu %[l1],     %%xmm0\n\t"
    1572             :                     "movdqu %[inbuf1], %%xmm2\n\t"
    1573             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1574             :                     "pxor   %%xmm5,    %%xmm2\n\t"
    1575             :                     "movdqu %%xmm5,    %[outbuf1]\n\t"
    1576      527070 :                     : [outbuf1] "=m" (*(outbuf + 1 * BLOCKSIZE))
    1577             :                     : [l1] "m" (*c->u_mode.ocb.L[1]),
    1578      527070 :                       [inbuf1] "m" (*(inbuf + 1 * BLOCKSIZE))
    1579             :                     : "memory" );
    1580      527070 :       asm volatile ("movdqu %[l2],     %%xmm0\n\t"
    1581             :                     "movdqu %[inbuf2], %%xmm3\n\t"
    1582             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1583             :                     "pxor   %%xmm5,    %%xmm3\n\t"
    1584             :                     "movdqu %%xmm5,    %[outbuf2]\n\t"
    1585      527070 :                     : [outbuf2] "=m" (*(outbuf + 2 * BLOCKSIZE))
    1586             :                     : [l2] "m" (*c->u_mode.ocb.L[0]),
    1587      527070 :                       [inbuf2] "m" (*(inbuf + 2 * BLOCKSIZE))
    1588             :                     : "memory" );
    1589      527070 :       asm volatile ("movdqu %[l3],     %%xmm0\n\t"
    1590             :                     "movdqu %[inbuf3], %%xmm4\n\t"
    1591             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1592             :                     "pxor   %%xmm5,    %%xmm4\n\t"
    1593             :                     :
    1594             :                     : [l3] "m" (*l),
    1595      527070 :                       [inbuf3] "m" (*(inbuf + 3 * BLOCKSIZE))
    1596             :                     : "memory" );
    1597             : 
    1598      527070 :       do_aesni_dec_vec4 (ctx);
    1599             : 
    1600      527070 :       asm volatile ("movdqu %[outbuf0],%%xmm0\n\t"
    1601             :                     "pxor   %%xmm0,    %%xmm1\n\t"
    1602             :                     "movdqu %%xmm1,    %[outbuf0]\n\t"
    1603             :                     "movdqu %[outbuf1],%%xmm0\n\t"
    1604             :                     "pxor   %%xmm0,    %%xmm2\n\t"
    1605             :                     "movdqu %%xmm2,    %[outbuf1]\n\t"
    1606             :                     "movdqu %[outbuf2],%%xmm0\n\t"
    1607             :                     "pxor   %%xmm0,    %%xmm3\n\t"
    1608             :                     "movdqu %%xmm3,    %[outbuf2]\n\t"
    1609             :                     "pxor   %%xmm5,    %%xmm4\n\t"
    1610             :                     "movdqu %%xmm4,    %[outbuf3]\n\t"
    1611             :                     "pxor   %%xmm1,    %%xmm6\n\t"
    1612             :                     "pxor   %%xmm2,    %%xmm6\n\t"
    1613             :                     "pxor   %%xmm3,    %%xmm6\n\t"
    1614             :                     "pxor   %%xmm4,    %%xmm6\n\t"
    1615             :                     : [outbuf0] "+m" (*(outbuf + 0 * BLOCKSIZE)),
    1616      527070 :                       [outbuf1] "+m" (*(outbuf + 1 * BLOCKSIZE)),
    1617      527070 :                       [outbuf2] "+m" (*(outbuf + 2 * BLOCKSIZE)),
    1618      527070 :                       [outbuf3] "=m" (*(outbuf + 3 * BLOCKSIZE))
    1619             :                     :
    1620             :                     : "memory" );
    1621             : 
    1622      527070 :       outbuf += 4*BLOCKSIZE;
    1623      527070 :       inbuf  += 4*BLOCKSIZE;
    1624             :     }
    1625             : 
    1626       10354 :   for ( ;nblocks; nblocks-- )
    1627             :     {
    1628        3768 :       l = ocb_get_l(c, ++n);
    1629             : 
    1630             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
    1631             :       /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
    1632             :       /* Checksum_i = Checksum_{i-1} xor P_i  */
    1633        3768 :       asm volatile ("movdqu %[l],     %%xmm1\n\t"
    1634             :                     "movdqu %[inbuf], %%xmm0\n\t"
    1635             :                     "pxor   %%xmm1,   %%xmm5\n\t"
    1636             :                     "pxor   %%xmm5,   %%xmm0\n\t"
    1637             :                     :
    1638             :                     : [l] "m" (*l),
    1639             :                       [inbuf] "m" (*inbuf)
    1640             :                     : "memory" );
    1641             : 
    1642        3768 :       do_aesni_dec (ctx);
    1643             : 
    1644        3768 :       asm volatile ("pxor   %%xmm5, %%xmm0\n\t"
    1645             :                     "pxor   %%xmm0, %%xmm6\n\t"
    1646             :                     "movdqu %%xmm0, %[outbuf]\n\t"
    1647             :                     : [outbuf] "=m" (*outbuf)
    1648             :                     :
    1649             :                     : "memory" );
    1650             : 
    1651        3768 :       inbuf += BLOCKSIZE;
    1652        3768 :       outbuf += BLOCKSIZE;
    1653             :     }
    1654             : 
    1655        6586 :   c->u_mode.ocb.data_nblocks = n;
    1656        6586 :   asm volatile ("movdqu %%xmm5, %[iv]\n\t"
    1657             :                 "movdqu %%xmm6, %[ctr]\n\t"
    1658             :                 : [iv] "=m" (*c->u_iv.iv),
    1659             :                   [ctr] "=m" (*c->u_ctr.ctr)
    1660             :                 :
    1661             :                 : "memory" );
    1662             : 
    1663        6586 :   aesni_cleanup ();
    1664        6586 :   aesni_cleanup_2_6 ();
    1665        6586 : }
    1666             : 
    1667             : 
    1668             : void
    1669       14664 : _gcry_aes_aesni_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg,
    1670             :                           const void *inbuf_arg, size_t nblocks, int encrypt)
    1671             : {
    1672       14664 :   if (encrypt)
    1673        8078 :     aesni_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks);
    1674             :   else
    1675        6586 :     aesni_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks);
    1676       14664 : }
    1677             : 
    1678             : 
    1679             : void
    1680        2748 : _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
    1681             :                           size_t nblocks)
    1682             : {
    1683        2748 :   RIJNDAEL_context *ctx = (void *)&c->context.c;
    1684        2748 :   const unsigned char *abuf = abuf_arg;
    1685        2748 :   u64 n = c->u_mode.ocb.aad_nblocks;
    1686             :   const unsigned char *l;
    1687             :   aesni_prepare_2_6_variable;
    1688             : 
    1689             :   aesni_prepare ();
    1690             :   aesni_prepare_2_6 ();
    1691             : 
    1692             :   /* Preload Offset and Sum */
    1693        2748 :   asm volatile ("movdqu %[iv], %%xmm5\n\t"
    1694             :                 "movdqu %[ctr], %%xmm6\n\t"
    1695             :                 : /* No output */
    1696             :                 : [iv] "m" (*c->u_mode.ocb.aad_offset),
    1697             :                   [ctr] "m" (*c->u_mode.ocb.aad_sum)
    1698             :                 : "memory" );
    1699             : 
    1700        2771 :   for ( ;nblocks && n % 4; nblocks-- )
    1701             :     {
    1702          23 :       l = ocb_get_l(c, ++n);
    1703             : 
    1704             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
    1705             :       /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
    1706          23 :       asm volatile ("movdqu %[l],     %%xmm1\n\t"
    1707             :                     "movdqu %[abuf],  %%xmm0\n\t"
    1708             :                     "pxor   %%xmm1,   %%xmm5\n\t"
    1709             :                     "pxor   %%xmm5,   %%xmm0\n\t"
    1710             :                     :
    1711             :                     : [l] "m" (*l),
    1712             :                       [abuf] "m" (*abuf)
    1713             :                     : "memory" );
    1714             : 
    1715          23 :       do_aesni_enc (ctx);
    1716             : 
    1717          23 :       asm volatile ("pxor   %%xmm0,   %%xmm6\n\t"
    1718             :                     :
    1719             :                     :
    1720             :                     : "memory" );
    1721             : 
    1722          23 :       abuf += BLOCKSIZE;
    1723             :     }
    1724             : 
    1725      868162 :   for ( ;nblocks > 3 ; nblocks -= 4 )
    1726             :     {
    1727      865414 :       n += 4;
    1728      865414 :       l = ocb_get_l(c, n);
    1729             : 
    1730             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
    1731             :       /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
    1732      865414 :       asm volatile ("movdqu %[l0],     %%xmm0\n\t"
    1733             :                     "movdqu %[abuf0],  %%xmm1\n\t"
    1734             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1735             :                     "pxor   %%xmm5,    %%xmm1\n\t"
    1736             :                     :
    1737             :                     : [l0] "m" (*c->u_mode.ocb.L[0]),
    1738             :                       [abuf0] "m" (*(abuf + 0 * BLOCKSIZE))
    1739             :                     : "memory" );
    1740      865414 :       asm volatile ("movdqu %[l1],     %%xmm0\n\t"
    1741             :                     "movdqu %[abuf1],  %%xmm2\n\t"
    1742             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1743             :                     "pxor   %%xmm5,    %%xmm2\n\t"
    1744             :                     :
    1745             :                     : [l1] "m" (*c->u_mode.ocb.L[1]),
    1746      865414 :                       [abuf1] "m" (*(abuf + 1 * BLOCKSIZE))
    1747             :                     : "memory" );
    1748      865414 :       asm volatile ("movdqu %[l2],     %%xmm0\n\t"
    1749             :                     "movdqu %[abuf2],  %%xmm3\n\t"
    1750             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1751             :                     "pxor   %%xmm5,    %%xmm3\n\t"
    1752             :                     :
    1753             :                     : [l2] "m" (*c->u_mode.ocb.L[0]),
    1754      865414 :                       [abuf2] "m" (*(abuf + 2 * BLOCKSIZE))
    1755             :                     : "memory" );
    1756      865414 :       asm volatile ("movdqu %[l3],     %%xmm0\n\t"
    1757             :                     "movdqu %[abuf3],  %%xmm4\n\t"
    1758             :                     "pxor   %%xmm0,    %%xmm5\n\t"
    1759             :                     "pxor   %%xmm5,    %%xmm4\n\t"
    1760             :                     :
    1761             :                     : [l3] "m" (*l),
    1762      865414 :                       [abuf3] "m" (*(abuf + 3 * BLOCKSIZE))
    1763             :                     : "memory" );
    1764             : 
    1765      865414 :       do_aesni_enc_vec4 (ctx);
    1766             : 
    1767      865414 :       asm volatile ("pxor   %%xmm1,   %%xmm6\n\t"
    1768             :                     "pxor   %%xmm2,   %%xmm6\n\t"
    1769             :                     "pxor   %%xmm3,   %%xmm6\n\t"
    1770             :                     "pxor   %%xmm4,   %%xmm6\n\t"
    1771             :                     :
    1772             :                     :
    1773             :                     : "memory" );
    1774             : 
    1775      865414 :       abuf += 4*BLOCKSIZE;
    1776             :     }
    1777             : 
    1778        5644 :   for ( ;nblocks; nblocks-- )
    1779             :     {
    1780        2896 :       l = ocb_get_l(c, ++n);
    1781             : 
    1782             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
    1783             :       /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
    1784        2896 :       asm volatile ("movdqu %[l],     %%xmm1\n\t"
    1785             :                     "movdqu %[abuf],  %%xmm0\n\t"
    1786             :                     "pxor   %%xmm1,   %%xmm5\n\t"
    1787             :                     "pxor   %%xmm5,   %%xmm0\n\t"
    1788             :                     :
    1789             :                     : [l] "m" (*l),
    1790             :                       [abuf] "m" (*abuf)
    1791             :                     : "memory" );
    1792             : 
    1793        2896 :       do_aesni_enc (ctx);
    1794             : 
    1795        2896 :       asm volatile ("pxor   %%xmm0,   %%xmm6\n\t"
    1796             :                     :
    1797             :                     :
    1798             :                     : "memory" );
    1799             : 
    1800        2896 :       abuf += BLOCKSIZE;
    1801             :     }
    1802             : 
    1803        2748 :   c->u_mode.ocb.aad_nblocks = n;
    1804        2748 :   asm volatile ("movdqu %%xmm5, %[iv]\n\t"
    1805             :                 "movdqu %%xmm6, %[ctr]\n\t"
    1806             :                 : [iv] "=m" (*c->u_mode.ocb.aad_offset),
    1807             :                   [ctr] "=m" (*c->u_mode.ocb.aad_sum)
    1808             :                 :
    1809             :                 : "memory" );
    1810             : 
    1811        2748 :   aesni_cleanup ();
    1812        2748 :   aesni_cleanup_2_6 ();
    1813        2748 : }
    1814             : 
    1815             : 
    1816             : #endif /* USE_AESNI */

Generated by: LCOV version 1.13