LCOV - code coverage report
Current view: top level - cipher - rijndael-ssse3-amd64.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 170 0.0 %
Date: 2017-03-02 16:44:37 Functions: 0 15 0.0 %

          Line data    Source code
       1             : /* SSSE3 vector permutation AES for Libgcrypt
       2             :  * Copyright (C) 2014-2017 Jussi Kivilinna <jussi.kivilinna@iki.fi>
       3             :  *
       4             :  * This file is part of Libgcrypt.
       5             :  *
       6             :  * Libgcrypt is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU Lesser General Public License as
       8             :  * published by the Free Software Foundation; either version 2.1 of
       9             :  * the License, or (at your option) any later version.
      10             :  *
      11             :  * Libgcrypt is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  *
      19             :  *
      20             :  * The code is based on the public domain library libvpaes version 0.5
      21             :  * available at http://crypto.stanford.edu/vpaes/ and which carries
      22             :  * this notice:
      23             :  *
      24             :  *     libvpaes: constant-time SSSE3 AES encryption and decryption.
      25             :  *     version 0.5
      26             :  *
      27             :  *     By Mike Hamburg, Stanford University, 2009.  Public domain.
      28             :  *     I wrote essentially all of this code.  I did not write the test
      29             :  *     vectors; they are the NIST known answer tests.  I hereby release all
      30             :  *     the code and documentation here that I wrote into the public domain.
      31             :  *
      32             :  *     This is an implementation of AES following my paper,
      33             :  *       "Accelerating AES with Vector Permute Instructions"
      34             :  *       CHES 2009; http://shiftleft.org/papers/vector_aes/
      35             :  */
      36             : 
      37             : #include <config.h>
      38             : #include <stdio.h>
      39             : #include <stdlib.h>
      40             : #include <string.h> /* for memcmp() */
      41             : 
      42             : #include "types.h"  /* for byte and u32 typedefs */
      43             : #include "g10lib.h"
      44             : #include "cipher.h"
      45             : #include "bufhelp.h"
      46             : #include "cipher-selftest.h"
      47             : #include "rijndael-internal.h"
      48             : #include "./cipher-internal.h"
      49             : 
      50             : 
      51             : #ifdef USE_SSSE3
      52             : 
      53             : 
      54             : #if _GCRY_GCC_VERSION >= 40400 /* 4.4 */
      55             : /* Prevent compiler from issuing SSE instructions between asm blocks. */
      56             : #  pragma GCC target("no-sse")
      57             : #endif
      58             : 
      59             : 
      60             : /* Assembly functions in rijndael-ssse3-amd64-asm.S. Note that these
      61             :    have custom calling convention and need to be called from assembly
      62             :    blocks, not directly. */
      63             : extern void _gcry_aes_ssse3_enc_preload(void);
      64             : extern void _gcry_aes_ssse3_dec_preload(void);
      65             : extern void _gcry_aes_ssse3_schedule_core(void);
      66             : extern void _gcry_aes_ssse3_encrypt_core(void);
      67             : extern void _gcry_aes_ssse3_decrypt_core(void);
      68             : 
      69             : 
      70             : 
      71             : /* Two macros to be called prior and after the use of SSSE3
      72             :    instructions.  There should be no external function calls between
      73             :    the use of these macros.  There purpose is to make sure that the
      74             :    SSE registers are cleared and won't reveal any information about
      75             :    the key or the data.  */
      76             : #ifdef HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS
      77             : # define SSSE3_STATE_SIZE (16 * 10)
      78             : /* XMM6-XMM15 are callee-saved registers on WIN64. */
      79             : # define vpaes_ssse3_prepare() \
      80             :     asm volatile ("movdqu %%xmm6,  0*16(%0)\n\t" \
      81             :                   "movdqu %%xmm7,  1*16(%0)\n\t" \
      82             :                   "movdqu %%xmm8,  2*16(%0)\n\t" \
      83             :                   "movdqu %%xmm9,  3*16(%0)\n\t" \
      84             :                   "movdqu %%xmm10, 4*16(%0)\n\t" \
      85             :                   "movdqu %%xmm11, 5*16(%0)\n\t" \
      86             :                   "movdqu %%xmm12, 6*16(%0)\n\t" \
      87             :                   "movdqu %%xmm13, 7*16(%0)\n\t" \
      88             :                   "movdqu %%xmm14, 8*16(%0)\n\t" \
      89             :                   "movdqu %%xmm15, 9*16(%0)\n\t" \
      90             :                   : \
      91             :                   : "r" (ssse3_state) \
      92             :                   : "memory" )
      93             : # define vpaes_ssse3_cleanup() \
      94             :     asm volatile ("pxor    %%xmm0,  %%xmm0 \n\t" \
      95             :                   "pxor    %%xmm1,  %%xmm1 \n\t" \
      96             :                   "pxor    %%xmm2,  %%xmm2 \n\t" \
      97             :                   "pxor    %%xmm3,  %%xmm3 \n\t" \
      98             :                   "pxor    %%xmm4,  %%xmm4 \n\t" \
      99             :                   "pxor    %%xmm5,  %%xmm5 \n\t" \
     100             :                   "movdqu 0*16(%0), %%xmm6 \n\t" \
     101             :                   "movdqu 1*16(%0), %%xmm7 \n\t" \
     102             :                   "movdqu 2*16(%0), %%xmm8 \n\t" \
     103             :                   "movdqu 3*16(%0), %%xmm9 \n\t" \
     104             :                   "movdqu 4*16(%0), %%xmm10 \n\t" \
     105             :                   "movdqu 5*16(%0), %%xmm11 \n\t" \
     106             :                   "movdqu 6*16(%0), %%xmm12 \n\t" \
     107             :                   "movdqu 7*16(%0), %%xmm13 \n\t" \
     108             :                   "movdqu 8*16(%0), %%xmm14 \n\t" \
     109             :                   "movdqu 9*16(%0), %%xmm15 \n\t" \
     110             :                   : \
     111             :                   : "r" (ssse3_state) \
     112             :                   : "memory" )
     113             : #else
     114             : # define SSSE3_STATE_SIZE 1
     115             : # define vpaes_ssse3_prepare() (void)ssse3_state
     116             : # define vpaes_ssse3_cleanup() \
     117             :     asm volatile ("pxor    %%xmm0,  %%xmm0 \n\t" \
     118             :                   "pxor    %%xmm1,  %%xmm1 \n\t" \
     119             :                   "pxor    %%xmm2,  %%xmm2 \n\t" \
     120             :                   "pxor    %%xmm3,  %%xmm3 \n\t" \
     121             :                   "pxor    %%xmm4,  %%xmm4 \n\t" \
     122             :                   "pxor    %%xmm5,  %%xmm5 \n\t" \
     123             :                   "pxor    %%xmm6,  %%xmm6 \n\t" \
     124             :                   "pxor    %%xmm7,  %%xmm7 \n\t" \
     125             :                   "pxor    %%xmm8,  %%xmm8 \n\t" \
     126             :                   ::: "memory" )
     127             : #endif
     128             : 
     129             : #define vpaes_ssse3_prepare_enc() \
     130             :     vpaes_ssse3_prepare(); \
     131             :     asm volatile ("callq *%q[core] \n\t" \
     132             :                   : \
     133             :                   : [core] "r" (_gcry_aes_ssse3_enc_preload) \
     134             :                   : "rax", "cc", "memory" )
     135             : 
     136             : #define vpaes_ssse3_prepare_dec() \
     137             :     vpaes_ssse3_prepare(); \
     138             :     asm volatile ("callq *%q[core] \n\t" \
     139             :                   : \
     140             :                   : [core] "r" (_gcry_aes_ssse3_dec_preload) \
     141             :                   : "rax", "cc", "memory" )
     142             : 
     143             : 
     144             : 
     145             : void
     146           0 : _gcry_aes_ssse3_do_setkey (RIJNDAEL_context *ctx, const byte *key)
     147             : {
     148           0 :   unsigned int keybits = (ctx->rounds - 10) * 32 + 128;
     149             :   byte ssse3_state[SSSE3_STATE_SIZE];
     150             : 
     151             :   vpaes_ssse3_prepare();
     152             : 
     153           0 :   asm volatile ("leaq %q[key], %%rdi"                 "\n\t"
     154             :                 "movl %[bits], %%esi"                 "\n\t"
     155             :                 "leaq %[buf], %%rdx"                  "\n\t"
     156             :                 "movl %[dir], %%ecx"                  "\n\t"
     157             :                 "movl %[rotoffs], %%r8d"              "\n\t"
     158             :                 "callq *%q[core]"                     "\n\t"
     159             :                 :
     160             :                 : [core] "r" (&_gcry_aes_ssse3_schedule_core),
     161             :                   [key] "m" (*key),
     162             :                   [bits] "g" (keybits),
     163             :                   [buf] "m" (ctx->keyschenc32[0][0]),
     164             :                   [dir] "g" (0),
     165             :                   [rotoffs] "g" (48)
     166             :                 : "r8", "r9", "r10", "r11", "rax", "rcx", "rdx", "rdi", "rsi",
     167             :                   "cc", "memory");
     168             : 
     169             :   /* Save key for setting up decryption. */
     170           0 :   if (keybits > 192)
     171           0 :     asm volatile ("movdqu   (%[src]), %%xmm0\n\t"
     172             :                   "movdqu 16(%[src]), %%xmm1\n\t"
     173             :                   "movdqu %%xmm0,   (%[dst])\n\t"
     174             :                   "movdqu %%xmm1, 16(%[dst])\n\t"
     175             :                   : /* No output */
     176           0 :                   : [dst] "r" (&ctx->keyschdec32[0][0]), [src] "r" (key)
     177             :                   : "memory" );
     178           0 :   else if (keybits == 192)
     179           0 :     asm volatile ("movdqu   (%[src]), %%xmm0\n\t"
     180             :                   "movq   16(%[src]), %%xmm1\n\t"
     181             :                   "movdqu %%xmm0,   (%[dst])\n\t"
     182             :                   "movq   %%xmm1, 16(%[dst])\n\t"
     183             :                   : /* No output */
     184           0 :                   : [dst] "r" (&ctx->keyschdec32[0][0]), [src] "r" (key)
     185             :                   : "memory" );
     186             :   else
     187           0 :     asm volatile ("movdqu (%[src]), %%xmm0\n\t"
     188             :                   "movdqu %%xmm0, (%[dst])\n\t"
     189             :                   : /* No output */
     190           0 :                   : [dst] "r" (&ctx->keyschdec32[0][0]), [src] "r" (key)
     191             :                   : "memory" );
     192             : 
     193           0 :   vpaes_ssse3_cleanup();
     194           0 : }
     195             : 
     196             : 
     197             : /* Make a decryption key from an encryption key. */
     198             : void
     199           0 : _gcry_aes_ssse3_prepare_decryption (RIJNDAEL_context *ctx)
     200             : {
     201           0 :   unsigned int keybits = (ctx->rounds - 10) * 32 + 128;
     202             :   byte ssse3_state[SSSE3_STATE_SIZE];
     203             : 
     204             :   vpaes_ssse3_prepare();
     205             : 
     206           0 :   asm volatile ("leaq %q[key], %%rdi"                 "\n\t"
     207             :                 "movl %[bits], %%esi"                 "\n\t"
     208             :                 "leaq %[buf], %%rdx"                  "\n\t"
     209             :                 "movl %[dir], %%ecx"                  "\n\t"
     210             :                 "movl %[rotoffs], %%r8d"              "\n\t"
     211             :                 "callq *%q[core]"                     "\n\t"
     212             :                 :
     213             :                 : [core] "r" (_gcry_aes_ssse3_schedule_core),
     214             :                   [key] "m" (ctx->keyschdec32[0][0]),
     215             :                   [bits] "g" (keybits),
     216           0 :                   [buf] "m" (ctx->keyschdec32[ctx->rounds][0]),
     217             :                   [dir] "g" (1),
     218           0 :                   [rotoffs] "g" ((keybits == 192) ? 0 : 32)
     219             :                 : "r8", "r9", "r10", "r11", "rax", "rcx", "rdx", "rdi", "rsi",
     220             :                   "cc", "memory");
     221             : 
     222           0 :   vpaes_ssse3_cleanup();
     223           0 : }
     224             : 
     225             : 
     226             : /* Encrypt one block using the Intel SSSE3 instructions.  Block is input
     227             : * and output through SSE register xmm0. */
     228             : static inline void
     229           0 : do_vpaes_ssse3_enc (const RIJNDAEL_context *ctx, unsigned int nrounds)
     230             : {
     231           0 :   unsigned int middle_rounds = nrounds - 1;
     232           0 :   const void *keysched = ctx->keyschenc32;
     233             : 
     234           0 :   asm volatile ("callq *%q[core]"                     "\n\t"
     235             :                 : "+a" (middle_rounds), "+d" (keysched)
     236             :                 : [core] "r" (_gcry_aes_ssse3_encrypt_core)
     237             :                 : "rcx", "rsi", "rdi", "cc", "memory");
     238           0 : }
     239             : 
     240             : 
     241             : /* Decrypt one block using the Intel SSSE3 instructions.  Block is input
     242             : * and output through SSE register xmm0. */
     243             : static inline void
     244           0 : do_vpaes_ssse3_dec (const RIJNDAEL_context *ctx, unsigned int nrounds)
     245             : {
     246           0 :   unsigned int middle_rounds = nrounds - 1;
     247           0 :   const void *keysched = ctx->keyschdec32;
     248             : 
     249           0 :   asm volatile ("callq *%q[core]"                     "\n\t"
     250             :                 : "+a" (middle_rounds), "+d" (keysched)
     251             :                 : [core] "r" (_gcry_aes_ssse3_decrypt_core)
     252             :                 : "rcx", "rsi", "cc", "memory");
     253           0 : }
     254             : 
     255             : 
     256             : unsigned int
     257           0 : _gcry_aes_ssse3_encrypt (const RIJNDAEL_context *ctx, unsigned char *dst,
     258             :                         const unsigned char *src)
     259             : {
     260           0 :   unsigned int nrounds = ctx->rounds;
     261             :   byte ssse3_state[SSSE3_STATE_SIZE];
     262             : 
     263           0 :   vpaes_ssse3_prepare_enc ();
     264           0 :   asm volatile ("movdqu %[src], %%xmm0\n\t"
     265             :                 :
     266             :                 : [src] "m" (*src)
     267             :                 : "memory" );
     268           0 :   do_vpaes_ssse3_enc (ctx, nrounds);
     269           0 :   asm volatile ("movdqu %%xmm0, %[dst]\n\t"
     270             :                 : [dst] "=m" (*dst)
     271             :                 :
     272             :                 : "memory" );
     273           0 :   vpaes_ssse3_cleanup ();
     274           0 :   return 0;
     275             : }
     276             : 
     277             : 
     278             : void
     279           0 : _gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
     280             :                         const unsigned char *inbuf, unsigned char *iv,
     281             :                         size_t nblocks)
     282             : {
     283           0 :   unsigned int nrounds = ctx->rounds;
     284             :   byte ssse3_state[SSSE3_STATE_SIZE];
     285             : 
     286           0 :   vpaes_ssse3_prepare_enc ();
     287             : 
     288           0 :   asm volatile ("movdqu %[iv], %%xmm0\n\t"
     289             :                 : /* No output */
     290             :                 : [iv] "m" (*iv)
     291             :                 : "memory" );
     292             : 
     293           0 :   for ( ;nblocks; nblocks-- )
     294             :     {
     295           0 :       do_vpaes_ssse3_enc (ctx, nrounds);
     296             : 
     297           0 :       asm volatile ("movdqu %[inbuf], %%xmm1\n\t"
     298             :                     "pxor %%xmm1, %%xmm0\n\t"
     299             :                     "movdqu %%xmm0, %[outbuf]\n\t"
     300             :                     : [outbuf] "=m" (*outbuf)
     301             :                     : [inbuf] "m" (*inbuf)
     302             :                     : "memory" );
     303             : 
     304           0 :       outbuf += BLOCKSIZE;
     305           0 :       inbuf  += BLOCKSIZE;
     306             :     }
     307             : 
     308           0 :   asm volatile ("movdqu %%xmm0, %[iv]\n\t"
     309             :                 : [iv] "=m" (*iv)
     310             :                 :
     311             :                 : "memory" );
     312             : 
     313           0 :   vpaes_ssse3_cleanup ();
     314           0 : }
     315             : 
     316             : 
     317             : void
     318           0 : _gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
     319             :                         const unsigned char *inbuf, unsigned char *iv,
     320             :                         size_t nblocks, int cbc_mac)
     321             : {
     322           0 :   unsigned int nrounds = ctx->rounds;
     323             :   byte ssse3_state[SSSE3_STATE_SIZE];
     324             : 
     325           0 :   vpaes_ssse3_prepare_enc ();
     326             : 
     327           0 :   asm volatile ("movdqu %[iv], %%xmm7\n\t"
     328             :                 : /* No output */
     329             :                 : [iv] "m" (*iv)
     330             :                 : "memory" );
     331             : 
     332           0 :   for ( ;nblocks; nblocks-- )
     333             :     {
     334           0 :       asm volatile ("movdqu %[inbuf], %%xmm0\n\t"
     335             :                     "pxor %%xmm7, %%xmm0\n\t"
     336             :                     : /* No output */
     337             :                     : [inbuf] "m" (*inbuf)
     338             :                     : "memory" );
     339             : 
     340           0 :       do_vpaes_ssse3_enc (ctx, nrounds);
     341             : 
     342           0 :       asm volatile ("movdqa %%xmm0, %%xmm7\n\t"
     343             :                     "movdqu %%xmm0, %[outbuf]\n\t"
     344             :                     : [outbuf] "=m" (*outbuf)
     345             :                     :
     346             :                     : "memory" );
     347             : 
     348           0 :       inbuf += BLOCKSIZE;
     349           0 :       if (!cbc_mac)
     350           0 :         outbuf += BLOCKSIZE;
     351             :     }
     352             : 
     353           0 :   asm volatile ("movdqu %%xmm7, %[iv]\n\t"
     354             :                 : [iv] "=m" (*iv)
     355             :                 :
     356             :                 : "memory" );
     357             : 
     358           0 :   vpaes_ssse3_cleanup ();
     359           0 : }
     360             : 
     361             : 
     362             : void
     363           0 : _gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf,
     364             :                         const unsigned char *inbuf, unsigned char *ctr,
     365             :                         size_t nblocks)
     366             : {
     367             :   static const unsigned char be_mask[16] __attribute__ ((aligned (16))) =
     368             :     { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
     369           0 :   unsigned int nrounds = ctx->rounds;
     370             :   byte ssse3_state[SSSE3_STATE_SIZE];
     371             :   u64 ctrlow;
     372             : 
     373           0 :   vpaes_ssse3_prepare_enc ();
     374             : 
     375           0 :   asm volatile ("movdqa %[mask], %%xmm6\n\t" /* Preload mask */
     376             :                 "movdqa (%[ctr]), %%xmm7\n\t"  /* Preload CTR */
     377             :                 "movq 8(%[ctr]), %q[ctrlow]\n\t"
     378             :                 "bswapq %q[ctrlow]\n\t"
     379             :                 : [ctrlow] "=r" (ctrlow)
     380             :                 : [mask] "m" (*be_mask),
     381             :                   [ctr] "r" (ctr)
     382             :                 : "memory", "cc");
     383             : 
     384           0 :   for ( ;nblocks; nblocks-- )
     385             :     {
     386           0 :       asm volatile ("movdqa %%xmm7, %%xmm0\n\t"     /* xmm0 := CTR (xmm7)  */
     387             :                     "pcmpeqd %%xmm1, %%xmm1\n\t"
     388             :                     "psrldq $8, %%xmm1\n\t"         /* xmm1 = -1 */
     389             : 
     390             :                     "pshufb %%xmm6, %%xmm7\n\t"
     391             :                     "psubq  %%xmm1, %%xmm7\n\t"     /* xmm7++ (big endian) */
     392             : 
     393             :                     /* detect if 64-bit carry handling is needed */
     394             :                     "incq   %q[ctrlow]\n\t"
     395             :                     "jnz    .Lno_carry%=\n\t"
     396             : 
     397             :                     "pslldq $8, %%xmm1\n\t"         /* move lower 64-bit to high */
     398             :                     "psubq   %%xmm1, %%xmm7\n\t"    /* add carry to upper 64bits */
     399             : 
     400             :                     ".Lno_carry%=:\n\t"
     401             : 
     402             :                     "pshufb %%xmm6, %%xmm7\n\t"
     403             :                     : [ctrlow] "+r" (ctrlow)
     404             :                     :
     405             :                     : "cc", "memory");
     406             : 
     407           0 :       do_vpaes_ssse3_enc (ctx, nrounds);
     408             : 
     409           0 :       asm volatile ("movdqu %[src], %%xmm1\n\t"      /* xmm1 := input   */
     410             :                     "pxor %%xmm1, %%xmm0\n\t"        /* EncCTR ^= input  */
     411             :                     "movdqu %%xmm0, %[dst]"          /* Store EncCTR.    */
     412             :                     : [dst] "=m" (*outbuf)
     413             :                     : [src] "m" (*inbuf)
     414             :                     : "memory");
     415             : 
     416           0 :       outbuf += BLOCKSIZE;
     417           0 :       inbuf  += BLOCKSIZE;
     418             :     }
     419             : 
     420           0 :   asm volatile ("movdqu %%xmm7, %[ctr]\n\t"   /* Update CTR (mem).       */
     421             :                 : [ctr] "=m" (*ctr)
     422             :                 :
     423             :                 : "memory" );
     424             : 
     425           0 :   vpaes_ssse3_cleanup ();
     426           0 : }
     427             : 
     428             : 
     429             : unsigned int
     430           0 : _gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst,
     431             :                         const unsigned char *src)
     432             : {
     433           0 :   unsigned int nrounds = ctx->rounds;
     434             :   byte ssse3_state[SSSE3_STATE_SIZE];
     435             : 
     436           0 :   vpaes_ssse3_prepare_dec ();
     437           0 :   asm volatile ("movdqu %[src], %%xmm0\n\t"
     438             :                 :
     439             :                 : [src] "m" (*src)
     440             :                 : "memory" );
     441           0 :   do_vpaes_ssse3_dec (ctx, nrounds);
     442           0 :   asm volatile ("movdqu %%xmm0, %[dst]\n\t"
     443             :                 : [dst] "=m" (*dst)
     444             :                 :
     445             :                 : "memory" );
     446           0 :   vpaes_ssse3_cleanup ();
     447           0 :   return 0;
     448             : }
     449             : 
     450             : 
     451             : void
     452           0 : _gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf,
     453             :                         const unsigned char *inbuf, unsigned char *iv,
     454             :                         size_t nblocks)
     455             : {
     456           0 :   unsigned int nrounds = ctx->rounds;
     457             :   byte ssse3_state[SSSE3_STATE_SIZE];
     458             : 
     459           0 :   vpaes_ssse3_prepare_enc ();
     460             : 
     461           0 :   asm volatile ("movdqu %[iv], %%xmm0\n\t"
     462             :                 : /* No output */
     463             :                 : [iv] "m" (*iv)
     464             :                 : "memory" );
     465             : 
     466           0 :   for ( ;nblocks; nblocks-- )
     467             :     {
     468           0 :       do_vpaes_ssse3_enc (ctx, nrounds);
     469             : 
     470           0 :       asm volatile ("movdqa %%xmm0, %%xmm6\n\t"
     471             :                     "movdqu %[inbuf], %%xmm0\n\t"
     472             :                     "pxor %%xmm0, %%xmm6\n\t"
     473             :                     "movdqu %%xmm6, %[outbuf]\n\t"
     474             :                     : [outbuf] "=m" (*outbuf)
     475             :                     : [inbuf] "m" (*inbuf)
     476             :                     : "memory" );
     477             : 
     478           0 :       outbuf += BLOCKSIZE;
     479           0 :       inbuf  += BLOCKSIZE;
     480             :     }
     481             : 
     482           0 :   asm volatile ("movdqu %%xmm0, %[iv]\n\t"
     483             :                 : [iv] "=m" (*iv)
     484             :                 :
     485             :                 : "memory" );
     486             : 
     487           0 :   vpaes_ssse3_cleanup ();
     488           0 : }
     489             : 
     490             : 
     491             : void
     492           0 : _gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf,
     493             :                         const unsigned char *inbuf, unsigned char *iv,
     494             :                         size_t nblocks)
     495             : {
     496           0 :   unsigned int nrounds = ctx->rounds;
     497             :   byte ssse3_state[SSSE3_STATE_SIZE];
     498             : 
     499           0 :   vpaes_ssse3_prepare_dec ();
     500             : 
     501           0 :   asm volatile ("movdqu %[iv], %%xmm7\n\t"    /* use xmm7 as fast IV storage */
     502             :                 : /* No output */
     503             :                 : [iv] "m" (*iv)
     504             :                 : "memory");
     505             : 
     506           0 :   for ( ;nblocks; nblocks-- )
     507             :     {
     508           0 :       asm volatile ("movdqu %[inbuf], %%xmm0\n\t"
     509             :                     "movdqa %%xmm0, %%xmm6\n\t"    /* use xmm6 as savebuf */
     510             :                     : /* No output */
     511             :                     : [inbuf] "m" (*inbuf)
     512             :                     : "memory");
     513             : 
     514           0 :       do_vpaes_ssse3_dec (ctx, nrounds);
     515             : 
     516           0 :       asm volatile ("pxor %%xmm7, %%xmm0\n\t" /* xor IV with output */
     517             :                     "movdqu %%xmm0, %[outbuf]\n\t"
     518             :                     "movdqu %%xmm6, %%xmm7\n\t"       /* store savebuf as new IV */
     519             :                     : [outbuf] "=m" (*outbuf)
     520             :                     :
     521             :                     : "memory");
     522             : 
     523           0 :       outbuf += BLOCKSIZE;
     524           0 :       inbuf  += BLOCKSIZE;
     525             :     }
     526             : 
     527           0 :   asm volatile ("movdqu %%xmm7, %[iv]\n\t"    /* store IV */
     528             :                 : /* No output */
     529             :                 : [iv] "m" (*iv)
     530             :                 : "memory");
     531             : 
     532           0 :   vpaes_ssse3_cleanup ();
     533           0 : }
     534             : 
     535             : 
     536             : static void
     537           0 : ssse3_ocb_enc (gcry_cipher_hd_t c, void *outbuf_arg,
     538             :                const void *inbuf_arg, size_t nblocks)
     539             : {
     540           0 :   RIJNDAEL_context *ctx = (void *)&c->context.c;
     541           0 :   unsigned char *outbuf = outbuf_arg;
     542           0 :   const unsigned char *inbuf = inbuf_arg;
     543           0 :   u64 n = c->u_mode.ocb.data_nblocks;
     544           0 :   unsigned int nrounds = ctx->rounds;
     545             :   byte ssse3_state[SSSE3_STATE_SIZE];
     546             : 
     547           0 :   vpaes_ssse3_prepare_enc ();
     548             : 
     549             :   /* Preload Offset and Checksum */
     550           0 :   asm volatile ("movdqu %[iv], %%xmm7\n\t"
     551             :                 "movdqu %[ctr], %%xmm6\n\t"
     552             :                 : /* No output */
     553             :                 : [iv] "m" (*c->u_iv.iv),
     554             :                   [ctr] "m" (*c->u_ctr.ctr)
     555             :                 : "memory" );
     556             : 
     557           0 :   for ( ;nblocks; nblocks-- )
     558             :     {
     559             :       const unsigned char *l;
     560             : 
     561           0 :       l = ocb_get_l(c, ++n);
     562             : 
     563             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
     564             :       /* Checksum_i = Checksum_{i-1} xor P_i  */
     565             :       /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
     566           0 :       asm volatile ("movdqu %[l],     %%xmm1\n\t"
     567             :                     "movdqu %[inbuf], %%xmm0\n\t"
     568             :                     "pxor   %%xmm1,   %%xmm7\n\t"
     569             :                     "pxor   %%xmm0,   %%xmm6\n\t"
     570             :                     "pxor   %%xmm7,   %%xmm0\n\t"
     571             :                     :
     572             :                     : [l] "m" (*l),
     573             :                       [inbuf] "m" (*inbuf)
     574             :                     : "memory" );
     575             : 
     576           0 :       do_vpaes_ssse3_enc (ctx, nrounds);
     577             : 
     578           0 :       asm volatile ("pxor   %%xmm7, %%xmm0\n\t"
     579             :                     "movdqu %%xmm0, %[outbuf]\n\t"
     580             :                     : [outbuf] "=m" (*outbuf)
     581             :                     :
     582             :                     : "memory" );
     583             : 
     584           0 :       inbuf += BLOCKSIZE;
     585           0 :       outbuf += BLOCKSIZE;
     586             :     }
     587             : 
     588           0 :   c->u_mode.ocb.data_nblocks = n;
     589           0 :   asm volatile ("movdqu %%xmm7, %[iv]\n\t"
     590             :                 "movdqu %%xmm6, %[ctr]\n\t"
     591             :                 : [iv] "=m" (*c->u_iv.iv),
     592             :                   [ctr] "=m" (*c->u_ctr.ctr)
     593             :                 :
     594             :                 : "memory" );
     595             : 
     596           0 :   vpaes_ssse3_cleanup ();
     597           0 : }
     598             : 
     599             : static void
     600           0 : ssse3_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg,
     601             :                const void *inbuf_arg, size_t nblocks)
     602             : {
     603           0 :   RIJNDAEL_context *ctx = (void *)&c->context.c;
     604           0 :   unsigned char *outbuf = outbuf_arg;
     605           0 :   const unsigned char *inbuf = inbuf_arg;
     606           0 :   u64 n = c->u_mode.ocb.data_nblocks;
     607           0 :   unsigned int nrounds = ctx->rounds;
     608             :   byte ssse3_state[SSSE3_STATE_SIZE];
     609             : 
     610           0 :   vpaes_ssse3_prepare_dec ();
     611             : 
     612             :   /* Preload Offset and Checksum */
     613           0 :   asm volatile ("movdqu %[iv], %%xmm7\n\t"
     614             :                 "movdqu %[ctr], %%xmm6\n\t"
     615             :                 : /* No output */
     616             :                 : [iv] "m" (*c->u_iv.iv),
     617             :                   [ctr] "m" (*c->u_ctr.ctr)
     618             :                 : "memory" );
     619             : 
     620           0 :   for ( ;nblocks; nblocks-- )
     621             :     {
     622             :       const unsigned char *l;
     623             : 
     624           0 :       l = ocb_get_l(c, ++n);
     625             : 
     626             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
     627             :       /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
     628             :       /* Checksum_i = Checksum_{i-1} xor P_i  */
     629           0 :       asm volatile ("movdqu %[l],     %%xmm1\n\t"
     630             :                     "movdqu %[inbuf], %%xmm0\n\t"
     631             :                     "pxor   %%xmm1,   %%xmm7\n\t"
     632             :                     "pxor   %%xmm7,   %%xmm0\n\t"
     633             :                     :
     634             :                     : [l] "m" (*l),
     635             :                       [inbuf] "m" (*inbuf)
     636             :                     : "memory" );
     637             : 
     638           0 :       do_vpaes_ssse3_dec (ctx, nrounds);
     639             : 
     640           0 :       asm volatile ("pxor   %%xmm7, %%xmm0\n\t"
     641             :                     "pxor   %%xmm0, %%xmm6\n\t"
     642             :                     "movdqu %%xmm0, %[outbuf]\n\t"
     643             :                     : [outbuf] "=m" (*outbuf)
     644             :                     :
     645             :                     : "memory" );
     646             : 
     647           0 :       inbuf += BLOCKSIZE;
     648           0 :       outbuf += BLOCKSIZE;
     649             :     }
     650             : 
     651           0 :   c->u_mode.ocb.data_nblocks = n;
     652           0 :   asm volatile ("movdqu %%xmm7, %[iv]\n\t"
     653             :                 "movdqu %%xmm6, %[ctr]\n\t"
     654             :                 : [iv] "=m" (*c->u_iv.iv),
     655             :                   [ctr] "=m" (*c->u_ctr.ctr)
     656             :                 :
     657             :                 : "memory" );
     658             : 
     659           0 :   vpaes_ssse3_cleanup ();
     660           0 : }
     661             : 
     662             : 
     663             : void
     664           0 : _gcry_aes_ssse3_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg,
     665             :                           const void *inbuf_arg, size_t nblocks, int encrypt)
     666             : {
     667           0 :   if (encrypt)
     668           0 :     ssse3_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks);
     669             :   else
     670           0 :     ssse3_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks);
     671           0 : }
     672             : 
     673             : 
     674             : void
     675           0 : _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg,
     676             :                           size_t nblocks)
     677             : {
     678           0 :   RIJNDAEL_context *ctx = (void *)&c->context.c;
     679           0 :   const unsigned char *abuf = abuf_arg;
     680           0 :   u64 n = c->u_mode.ocb.aad_nblocks;
     681           0 :   unsigned int nrounds = ctx->rounds;
     682             :   byte ssse3_state[SSSE3_STATE_SIZE];
     683             : 
     684           0 :   vpaes_ssse3_prepare_enc ();
     685             : 
     686             :   /* Preload Offset and Sum */
     687           0 :   asm volatile ("movdqu %[iv], %%xmm7\n\t"
     688             :                 "movdqu %[ctr], %%xmm6\n\t"
     689             :                 : /* No output */
     690             :                 : [iv] "m" (*c->u_mode.ocb.aad_offset),
     691             :                   [ctr] "m" (*c->u_mode.ocb.aad_sum)
     692             :                 : "memory" );
     693             : 
     694           0 :   for ( ;nblocks; nblocks-- )
     695             :     {
     696             :       const unsigned char *l;
     697             : 
     698           0 :       l = ocb_get_l(c, ++n);
     699             : 
     700             :       /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
     701             :       /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
     702           0 :       asm volatile ("movdqu %[l],     %%xmm1\n\t"
     703             :                     "movdqu %[abuf],  %%xmm0\n\t"
     704             :                     "pxor   %%xmm1,   %%xmm7\n\t"
     705             :                     "pxor   %%xmm7,   %%xmm0\n\t"
     706             :                     :
     707             :                     : [l] "m" (*l),
     708             :                       [abuf] "m" (*abuf)
     709             :                     : "memory" );
     710             : 
     711           0 :       do_vpaes_ssse3_enc (ctx, nrounds);
     712             : 
     713           0 :       asm volatile ("pxor   %%xmm0,   %%xmm6\n\t"
     714             :                     :
     715             :                     :
     716             :                     : "memory" );
     717             : 
     718           0 :       abuf += BLOCKSIZE;
     719             :     }
     720             : 
     721           0 :   c->u_mode.ocb.aad_nblocks = n;
     722           0 :   asm volatile ("movdqu %%xmm7, %[iv]\n\t"
     723             :                 "movdqu %%xmm6, %[ctr]\n\t"
     724             :                 : [iv] "=m" (*c->u_mode.ocb.aad_offset),
     725             :                   [ctr] "=m" (*c->u_mode.ocb.aad_sum)
     726             :                 :
     727             :                 : "memory" );
     728             : 
     729           0 :   vpaes_ssse3_cleanup ();
     730           0 : }
     731             : 
     732             : #endif /* USE_SSSE3 */

Generated by: LCOV version 1.13