[PATCH 1/4] cipher: add explicit blocksize checks to allow better optimization

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 1/4] cipher: add explicit blocksize checks to allow better optimization

Jussi Kivilinna-2
* cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt)
(_gcry_cipher_cbc_decrypt): Add explicit check for cipher blocksize of
64-bit or 128-bit.
* cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt)
(_gcry_cipher_cfb_decrypt): Ditto.
* cipher/cipher-cmac.c (cmac_write, cmac_generate_subkeys)
(cmac_final): Ditto.
* cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Ditto.
* cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt): Ditto.
--

Signed-off-by: Jussi Kivilinna <[hidden email]>
---
 0 files changed

diff --git a/cipher/cipher-cbc.c b/cipher/cipher-cbc.c
index 67814b7..95c49b2 100644
--- a/cipher/cipher-cbc.c
+++ b/cipher/cipher-cbc.c
@@ -44,6 +44,11 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd_t c,
   size_t nblocks = inbuflen / blocksize;
   unsigned int burn, nburn;
 
+  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+   * length, to allow better optimization of this function.  */
+  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+    return GPG_ERR_INV_LENGTH;
+
   if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen))
     return GPG_ERR_BUFFER_TOO_SHORT;
 
@@ -133,6 +138,11 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c,
   size_t nblocks = inbuflen / blocksize;
   unsigned int burn, nburn;
 
+  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+   * length, to allow better optimization of this function.  */
+  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+    return GPG_ERR_INV_LENGTH;
+
   if (outbuflen < inbuflen)
     return GPG_ERR_BUFFER_TOO_SHORT;
 
diff --git a/cipher/cipher-cfb.c b/cipher/cipher-cfb.c
index f289ed3..21c81ca 100644
--- a/cipher/cipher-cfb.c
+++ b/cipher/cipher-cfb.c
@@ -41,6 +41,11 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c,
   size_t blocksize_x_2 = blocksize + blocksize;
   unsigned int burn, nburn;
 
+  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+   * length, to allow better optimization of this function.  */
+  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+    return GPG_ERR_INV_LENGTH;
+
   if (outbuflen < inbuflen)
     return GPG_ERR_BUFFER_TOO_SHORT;
 
@@ -138,6 +143,11 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c,
   size_t blocksize_x_2 = blocksize + blocksize;
   unsigned int burn, nburn;
 
+  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+   * length, to allow better optimization of this function.  */
+  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+    return GPG_ERR_INV_LENGTH;
+
   if (outbuflen < inbuflen)
     return GPG_ERR_BUFFER_TOO_SHORT;
 
diff --git a/cipher/cipher-cmac.c b/cipher/cipher-cmac.c
index eca1c1a..da3ef75 100644
--- a/cipher/cipher-cmac.c
+++ b/cipher/cipher-cmac.c
@@ -42,6 +42,11 @@ cmac_write (gcry_cipher_hd_t c, const byte * inbuf, size_t inlen)
   unsigned int burn = 0;
   unsigned int nblocks;
 
+  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+   * length, to allow better optimization of this function.  */
+  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+    return;
+
   if (!inlen || !inbuf)
     return;
 
@@ -109,6 +114,11 @@ cmac_generate_subkeys (gcry_cipher_hd_t c)
     byte buf[MAX_BLOCKSIZE];
   } u;
 
+  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+   * length, to allow better optimization of this function.  */
+  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+    return;
+
   if (MAX_BLOCKSIZE < blocksize)
     BUG ();
 
@@ -149,6 +159,11 @@ cmac_final (gcry_cipher_hd_t c)
   unsigned int burn;
   byte *subkey;
 
+  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+   * length, to allow better optimization of this function.  */
+  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+    return;
+
   if (count == blocksize)
     subkey = c->u_mode.cmac.subkeys[0];        /* K1 */
   else
diff --git a/cipher/cipher-ctr.c b/cipher/cipher-ctr.c
index 4bbfaae..f9cb6b5 100644
--- a/cipher/cipher-ctr.c
+++ b/cipher/cipher-ctr.c
@@ -42,6 +42,11 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c,
   size_t nblocks;
   unsigned int burn, nburn;
 
+  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+   * length, to allow better optimization of this function.  */
+  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+    return GPG_ERR_INV_LENGTH;
+
   if (outbuflen < inbuflen)
     return GPG_ERR_BUFFER_TOO_SHORT;
 
diff --git a/cipher/cipher-ofb.c b/cipher/cipher-ofb.c
index 7db7658..f821d1b 100644
--- a/cipher/cipher-ofb.c
+++ b/cipher/cipher-ofb.c
@@ -40,6 +40,11 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c,
   size_t blocksize = c->spec->blocksize;
   unsigned int burn, nburn;
 
+  /* Tell compiler that we require a cipher with a 64bit or 128 bit block
+   * length, to allow better optimization of this function.  */
+  if (blocksize > 16 || blocksize < 8 || blocksize & (8 - 1))
+    return GPG_ERR_INV_LENGTH;
+
   if (outbuflen < inbuflen)
     return GPG_ERR_BUFFER_TOO_SHORT;
 


_______________________________________________
Gcrypt-devel mailing list
[hidden email]
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 4/4] Add UNLIKELY and LIKELY macros

Jussi Kivilinna-2
* src/g10lib.h (LIKELY, UNLIKELY): New.
(gcry_assert): Use LIKELY for assert check.
(fast_wipememory2_unaligned_head): Use UNLIKELY for unaligned
branching.
* cipher/bufhelp.h (buf_cpy, buf_xor, buf_xor_1, buf_xor_2dst)
(buf_xor_n_copy_2): Ditto.
--

Signed-off-by: Jussi Kivilinna <[hidden email]>
---
 0 files changed

diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h
index 3110a1d..b854bc0 100644
--- a/cipher/bufhelp.h
+++ b/cipher/bufhelp.h
@@ -1,5 +1,5 @@
 /* bufhelp.h  -  Some buffer manipulation helpers
- * Copyright (C) 2012 Jussi Kivilinna <[hidden email]>
+ * Copyright (C) 2012-2017 Jussi Kivilinna <[hidden email]>
  *
  * This file is part of Libgcrypt.
  *
@@ -20,6 +20,7 @@
 #define GCRYPT_BUFHELP_H
 
 
+#include "g10lib.h"
 #include "bithelp.h"
 
 
@@ -88,7 +89,7 @@ buf_cpy(void *_dst, const void *_src, size_t len)
   const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 
   /* Skip fast processing if buffers are unaligned.  */
-  if (((uintptr_t)dst | (uintptr_t)src) & longmask)
+  if (UNLIKELY(((uintptr_t)dst | (uintptr_t)src) & longmask))
     goto do_bytes;
 #endif
 
@@ -124,7 +125,7 @@ buf_xor(void *_dst, const void *_src1, const void *_src2, size_t len)
   const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 
   /* Skip fast processing if buffers are unaligned.  */
-  if (((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask)
+  if (UNLIKELY(((uintptr_t)dst | (uintptr_t)src1 | (uintptr_t)src2) & longmask))
     goto do_bytes;
 #endif
 
@@ -160,7 +161,7 @@ buf_xor_1(void *_dst, const void *_src, size_t len)
   const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 
   /* Skip fast processing if buffers are unaligned.  */
-  if (((uintptr_t)dst | (uintptr_t)src) & longmask)
+  if (UNLIKELY(((uintptr_t)dst | (uintptr_t)src) & longmask))
     goto do_bytes;
 #endif
 
@@ -196,7 +197,7 @@ buf_xor_2dst(void *_dst1, void *_dst2, const void *_src, size_t len)
   const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 
   /* Skip fast processing if buffers are unaligned.  */
-  if (((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask)
+  if (UNLIKELY(((uintptr_t)src | (uintptr_t)dst1 | (uintptr_t)dst2) & longmask))
     goto do_bytes;
 #endif
 
@@ -238,8 +239,8 @@ buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy,
   const unsigned int longmask = sizeof(bufhelp_int_t) - 1;
 
   /* Skip fast processing if buffers are unaligned.  */
-  if (((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor |
-       (uintptr_t)srcdst_cpy) & longmask)
+  if (UNLIKELY(((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor |
+       (uintptr_t)srcdst_cpy) & longmask))
     goto do_bytes;
 #endif
 
diff --git a/src/g10lib.h b/src/g10lib.h
index 8ce84b8..0309a83 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -75,6 +75,14 @@
 #define GCC_ATTR_UNUSED
 #endif
 
+#if __GNUC__ >= 3
+#define LIKELY( expr )    __builtin_expect( !!(expr), 1 )
+#define UNLIKELY( expr )  __builtin_expect( !!(expr), 0 )
+#else
+#define LIKELY( expr )    (!!(expr))
+#define UNLIKELY( expr )  (!!(expr))
+#endif
+
 /* Gettext macros.  */
 
 #define _(a)  _gcry_gettext(a)
@@ -165,15 +173,15 @@ int _gcry_log_verbosity( int level );
 
 #ifdef JNLIB_GCC_M_FUNCTION
 #define BUG() _gcry_bug( __FILE__ , __LINE__, __FUNCTION__ )
-#define gcry_assert(expr) ((expr)? (void)0 \
+#define gcry_assert(expr) (LIKELY(expr)? (void)0 \
          : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __FUNCTION__))
 #elif __STDC_VERSION__ >= 199901L
 #define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ )
-#define gcry_assert(expr) ((expr)? (void)0 \
+#define gcry_assert(expr) (LIKELY(expr)? (void)0 \
          : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__))
 #else
 #define BUG() _gcry_bug( __FILE__ , __LINE__ )
-#define gcry_assert(expr) ((expr)? (void)0 \
+#define gcry_assert(expr) (LIKELY(expr)? (void)0 \
          : _gcry_assert_failed (STR(expr), __FILE__, __LINE__))
 #endif
 
@@ -346,7 +354,7 @@ typedef struct fast_wipememory_s
 } __attribute__((packed, aligned(1), may_alias)) fast_wipememory_t;
 #else
 #define fast_wipememory2_unaligned_head(_vptr,_vset,_vlen) do { \
-              while((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1) && _vlen) \
+              while(UNLIKELY((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1)) && _vlen) \
                 { *_vptr=(_vset); _vptr++; _vlen--; } \
                   } while(0)
 typedef struct fast_wipememory_s


_______________________________________________
Gcrypt-devel mailing list
[hidden email]
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 3/4] rndhw: avoid type-punching

Jussi Kivilinna-2
In reply to this post by Jussi Kivilinna-2
* random/rndhw.c (rdrand_long, rdrand_nlong): Add 'volatile' for
pointer.
(poll_drng): Convert buffer to 'unsigned long[]' and make use of DIM
macro.
--

Signed-off-by: Jussi Kivilinna <[hidden email]>
---
 0 files changed

diff --git a/random/rndhw.c b/random/rndhw.c
index 8e50751..7c75955 100644
--- a/random/rndhw.c
+++ b/random/rndhw.c
@@ -129,7 +129,7 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins),
 #  define RDRAND_LONG RDRAND_INT
 # endif
 static inline int
-rdrand_long (unsigned long *v)
+rdrand_long (volatile unsigned long *v)
 {
   int ok;
   asm volatile ("1: " RDRAND_LONG "\n\t"
@@ -145,7 +145,7 @@ rdrand_long (unsigned long *v)
 
 
 static inline int
-rdrand_nlong (unsigned long *v, int count)
+rdrand_nlong (volatile unsigned long *v, int count)
 {
   while (count--)
     if (!rdrand_long(v++))
@@ -157,12 +157,12 @@ rdrand_nlong (unsigned long *v, int count)
 static size_t
 poll_drng (add_fn_t add, enum random_origins origin, int fast)
 {
-  volatile char buffer[64] __attribute__ ((aligned (8)));
+  volatile unsigned long buffer[8];
   unsigned int nbytes = sizeof (buffer);
 
   (void)fast;
 
-  if (!rdrand_nlong ((unsigned long *)buffer, sizeof(buffer)/sizeof(long)))
+  if (!rdrand_nlong (buffer, DIM(buffer)))
     return 0;
   (*add)((void *)buffer, nbytes, origin);
   return nbytes;


_______________________________________________
Gcrypt-devel mailing list
[hidden email]
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 2/4] hwf-x86: avoid type-punching

Jussi Kivilinna-2
In reply to this post by Jussi Kivilinna-2
* src/hwf-x86.c (detect_x86_gnuc): Use union for vendor_id.
--

Signed-off-by: Jussi Kivilinna <[hidden email]>
---
 0 files changed

diff --git a/src/hwf-x86.c b/src/hwf-x86.c
index a746ab2..53e00d9 100644
--- a/src/hwf-x86.c
+++ b/src/hwf-x86.c
@@ -170,7 +170,11 @@ get_xgetbv(void)
 static unsigned int
 detect_x86_gnuc (void)
 {
-  char vendor_id[12+1];
+  union
+  {
+    char c[12+1];
+    unsigned int ui[3];
+  } vendor_id;
   unsigned int features;
   unsigned int os_supports_avx_avx2_registers = 0;
   unsigned int max_cpuid_level;
@@ -183,16 +187,14 @@ detect_x86_gnuc (void)
   if (!is_cpuid_available())
     return 0;
 
-  get_cpuid(0, &max_cpuid_level,
-            (unsigned int *)&vendor_id[0],
-            (unsigned int *)&vendor_id[8],
-            (unsigned int *)&vendor_id[4]);
-  vendor_id[12] = 0;
+  get_cpuid(0, &max_cpuid_level, &vendor_id.ui[0], &vendor_id.ui[2],
+            &vendor_id.ui[1]);
+  vendor_id.c[12] = 0;
 
   if (0)
     ; /* Just to make "else if" and ifdef macros look pretty.  */
 #ifdef ENABLE_PADLOCK_SUPPORT
-  else if (!strcmp (vendor_id, "CentaurHauls"))
+  else if (!strcmp (vendor_id.c, "CentaurHauls"))
     {
       /* This is a VIA CPU.  Check what PadLock features we have.  */
 
@@ -225,12 +227,12 @@ detect_x86_gnuc (void)
         }
     }
 #endif /*ENABLE_PADLOCK_SUPPORT*/
-  else if (!strcmp (vendor_id, "GenuineIntel"))
+  else if (!strcmp (vendor_id.c, "GenuineIntel"))
     {
       /* This is an Intel CPU.  */
       result |= HWF_INTEL_CPU;
     }
-  else if (!strcmp (vendor_id, "AuthenticAMD"))
+  else if (!strcmp (vendor_id.c, "AuthenticAMD"))
     {
       /* This is an AMD CPU.  */
     }


_______________________________________________
Gcrypt-devel mailing list
[hidden email]
http://lists.gnupg.org/mailman/listinfo/gcrypt-devel
Loading...