Use a better alignment.
authorWerner Koch <wk@gnupg.org>
Mon, 14 Feb 2011 19:31:47 +0000 (20:31 +0100)
committerWerner Koch <wk@gnupg.org>
Mon, 14 Feb 2011 19:31:47 +0000 (20:31 +0100)
benchmark does now support the option
  --alignment 16
to test the non-aligned overhead.

cipher/ChangeLog
cipher/rijndael.c
tests/ChangeLog
tests/benchmark.c

index 9a59bde..787fe20 100644 (file)
@@ -1,5 +1,10 @@
 2011-02-14  Werner Koch  <wk@g10code.com>
 
+       * rijndael.c (ATTR_ALIGNED_16): New
+       (do_aesni): Do not copy if already aligned.
+       (do_encrypt, do_decrypt): Ditto.
+       (rijndael_decrypt, rijndael_encrypt): Increase stack burning amount.
+
        * rijndael.c (RIJNDAEL_context): Reorder fields.  Chnage filedname
        ROUNDS to rounds.  Move padlock_key into u1.
        (keySched, keySched2): Rename macros to keyscherr and keyschdec
index 56b55dc..43d7e67 100644 (file)
 #define BLOCKSIZE               (128/8)
 
 
+/* Helper macro to force alignment to 16 bytes.  */
+#ifdef __GNUC__
+# define ATTR_ALIGNED_16  __attribute__ ((aligned (16)))
+#else
+# define ATTR_ALIGNED_16
+#endif
+
+
 /* USE_PADLOCK indicates whether to compile the padlock specific
    code.  */
 #undef USE_PADLOCK
@@ -510,22 +518,29 @@ static void
 do_encrypt (const RIJNDAEL_context *ctx,
             unsigned char *bx, const unsigned char *ax)
 {
-  /* BX and AX are not necessary correctly aligned.  Thus we need to
-     copy them here. */
-  union
-  {
-    u32  dummy[4];
-    byte a[16];
-  } a;
-  union
-  {
-    u32  dummy[4];
-    byte b[16];
-  } b;
+  /* BX and AX are not necessary correctly aligned.  Thus we might
+     need to copy them here.  We try to align to a 16 bytes.  */
+  if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f))
+    {
+      union
+      {
+        u32  dummy[4];
+        byte a[16] ATTR_ALIGNED_16;
+      } a;
+      union
+      {
+        u32  dummy[4];
+        byte b[16] ATTR_ALIGNED_16;
+      } b;
 
-  memcpy (a.a, ax, 16);
-  do_encrypt_aligned (ctx, b.b, a.a);
-  memcpy (bx, b.b, 16);
+      memcpy (a.a, ax, 16);
+      do_encrypt_aligned (ctx, b.b, a.a);
+      memcpy (bx, b.b, 16);
+    }
+  else
+    {
+      do_encrypt_aligned (ctx, bx, ax);
+    }
 }
 
 
@@ -652,24 +667,33 @@ static void
 do_aesni (RIJNDAEL_context *ctx, int decrypt_flag,
           unsigned char *bx, const unsigned char *ax)
 {
-  /* BX and AX are not necessary correctly aligned.  Thus we need to
-     copy them here. */
-  unsigned char a[16] __attribute__ ((aligned (16)));
-  unsigned char b[16] __attribute__ ((aligned (16)));
+  if (decrypt_flag && !ctx->decryption_prepared )
+    {
+      prepare_decryption ( ctx );
+      ctx->decryption_prepared = 1;
+    }
 
-  memcpy (a, ax, 16);
-  if (decrypt_flag)
+  /* BX and AX are not necessary correctly aligned.  Thus we might
+     need to copy them here.  */
+  if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f))
     {
-      if ( !ctx->decryption_prepared )
-        {
-          prepare_decryption ( ctx );
-          ctx->decryption_prepared = 1;
-        }
-      do_aesni_dec_aligned (ctx, b, a);
+      unsigned char a[16] __attribute__ ((aligned (16)));
+      unsigned char b[16] __attribute__ ((aligned (16)));
+
+      memcpy (a, ax, 16);
+      if (decrypt_flag)
+        do_aesni_dec_aligned (ctx, b, a);
+      else
+        do_aesni_enc_aligned (ctx, b, a);
+      memcpy (bx, b, 16);
     }
   else
-    do_aesni_enc_aligned (ctx, b, a);
-  memcpy (bx, b, 16);
+    {
+      if (decrypt_flag)
+        do_aesni_dec_aligned (ctx, bx, ax);
+      else
+        do_aesni_enc_aligned (ctx, bx, ax);
+    }
 }
 #endif /*USE_AESNI*/
 
@@ -698,7 +722,7 @@ rijndael_encrypt (void *context, byte *b, const byte *a)
   else
     {
       do_encrypt (ctx, b, a);
-      _gcry_burn_stack (48 + 2*sizeof(int));
+      _gcry_burn_stack (56 + 2*sizeof(int));
     }
 }
 
@@ -903,19 +927,6 @@ do_decrypt_aligned (RIJNDAEL_context *ctx,
 static void
 do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax)
 {
-  /* BX and AX are not necessary correctly aligned.  Thus we need to
-     copy them here. */
-  union
-  {
-    u32  dummy[4];
-    byte a[16];
-  } a;
-  union
-  {
-    u32  dummy[4];
-    byte b[16];
-  } b;
-
   if ( !ctx->decryption_prepared )
     {
       prepare_decryption ( ctx );
@@ -923,10 +934,29 @@ do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax)
       ctx->decryption_prepared = 1;
     }
 
-  memcpy (a.a, ax, 16);
-  do_decrypt_aligned (ctx, b.b, a.a);
-  memcpy (bx, b.b, 16);
-#undef rk
+  /* BX and AX are not necessary correctly aligned.  Thus we might
+     need to copy them here.  We try to align to a 16 bytes. */
+  if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f))
+    {
+      union
+      {
+        u32  dummy[4];
+        byte a[16] ATTR_ALIGNED_16;
+      } a;
+      union
+      {
+        u32  dummy[4];
+        byte b[16] ATTR_ALIGNED_16;
+      } b;
+
+      memcpy (a.a, ax, 16);
+      do_decrypt_aligned (ctx, b.b, a.a);
+      memcpy (bx, b.b, 16);
+    }
+  else
+    {
+      do_decrypt_aligned (ctx, bx, ax);
+    }
 }
 
 
@@ -956,7 +986,7 @@ rijndael_decrypt (void *context, byte *b, const byte *a)
   else
     {
       do_decrypt (ctx, b, a);
-      _gcry_burn_stack (48+2*sizeof(int));
+      _gcry_burn_stack (56+2*sizeof(int));
     }
 }
 
index ac79a28..9334521 100644 (file)
@@ -1,3 +1,7 @@
+2011-02-14  Werner Koch  <wk@g10code.com>
+
+       * benchmark.c: Add option --alignment.
+
 2011-02-01  Werner Koch  <wk@g10code.com>
 
        * curves.c: New.
index 76dcd48..465f1b5 100644 (file)
@@ -51,6 +51,9 @@ static int cipher_repetitions;
 /* Number of hash repetitions.  */
 static int hash_repetitions;
 
+/* Alignment of the buffers.  */
+static int buffer_alignment;
+
 /* Whether fips mode was active at startup.  */
 static int in_fips_mode;
 
@@ -502,6 +505,7 @@ cipher_bench ( const char *algoname )
   int keylen, blklen;
   char key[128];
   char *outbuf, *buf;
+  char *raw_outbuf, *raw_buf;
   size_t allocated_buflen, buflen;
   int repetitions;
   static struct { int mode; const char *name; int blocked; } modes[] = {
@@ -537,8 +541,16 @@ cipher_bench ( const char *algoname )
     }
   repetitions *= cipher_repetitions;
 
-  buf = gcry_xmalloc (allocated_buflen);
-  outbuf = gcry_xmalloc (allocated_buflen);
+  buf = raw_buf = gcry_xmalloc (allocated_buflen+15);
+  if (buffer_alignment)
+    while (((size_t)buf & 0x0f))
+      buf++;
+
+  outbuf = raw_outbuf = gcry_xmalloc (allocated_buflen+15);
+  if (buffer_alignment)
+    while (((size_t)outbuf & 0x0f))
+      outbuf++;
+
 
   if (!header_printed)
     {
@@ -667,8 +679,8 @@ cipher_bench ( const char *algoname )
     }
 
   putchar ('\n');
-  gcry_free (buf);
-  gcry_free (outbuf);
+  gcry_free (raw_buf);
+  gcry_free (raw_outbuf);
 }
 
 
@@ -1116,6 +1128,15 @@ main( int argc, char **argv )
               argc--; argv++;
             }
         }
+      else if (!strcmp (*argv, "--alignment"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              buffer_alignment = atoi(*argv);
+              argc--; argv++;
+            }
+        }
       else if (!strcmp (*argv, "--fips"))
         {
           argc--; argv++;
@@ -1129,6 +1150,15 @@ main( int argc, char **argv )
         }
     }
 
+  switch (buffer_alignment)
+    {
+    case 0:
+    case 16:
+      break;
+    default:
+      die ("option --alignment not used with a value of 0 or 16\n");
+    }
+
   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
 
   if (!gcry_check_version (GCRYPT_VERSION))