[PATCH] AES & GCM: copy look-up tables from .rodata section to .data

Jussi Kivilinna jussi.kivilinna at iki.fi
Thu May 30 19:17:37 CEST 2019


* cipher/cipher-gcm.c (gcmR): Rename to ...
(gcmR_const): ... this.
(gcmR): New.
(do_prefetch_tables): Copy gcmR_const to gcmR.
* cipher/rijndael-tables.h (encT): Rename to ...
(encT_const): ... this.
(encT): New.
(dec_tables): Rename to ...
(dec_tables_const): ... this.
(dec_tables): New.
* cipher/rijndael.c (prepare_enc_tables, prepare_dec_tables): New.
(do_setkey): Prepare encryption tables instead of prefetching.
(prepare_decryption): Prepare decryption tables instead of prefetching.
--

GnuPG-bug-id: 4541
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 cipher/cipher-gcm.c      |   21 +++++++++++++++++----
 cipher/rijndael-tables.h |   17 +++++++++++++----
 cipher/rijndael.c        |   33 +++++++++++++++++++++++++++++++--
 3 files changed, 61 insertions(+), 10 deletions(-)

diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c
index 11f119aa7..f237906bb 100644
--- a/cipher/cipher-gcm.c
+++ b/cipher/cipher-gcm.c
@@ -83,7 +83,10 @@ ghash_armv7_neon (gcry_cipher_hd_t c, byte *result, const byte *buf,
 
 
 #ifdef GCM_USE_TABLES
-static const u16 gcmR[256] = {
+
+static u16 gcmR[256];
+
+static const u16 gcmR_const[256] = {
   0x0000, 0x01c2, 0x0384, 0x0246, 0x0708, 0x06ca, 0x048c, 0x054e,
   0x0e10, 0x0fd2, 0x0d94, 0x0c56, 0x0918, 0x08da, 0x0a9c, 0x0b5e,
   0x1c20, 0x1de2, 0x1fa4, 0x1e66, 0x1b28, 0x1aea, 0x18ac, 0x196e,
@@ -119,7 +122,7 @@ static const u16 gcmR[256] = {
 };
 
 static inline
-void prefetch_table(const void *tab, size_t len)
+void prefetch_table (const void *tab, size_t len)
 {
   const volatile byte *vtab = tab;
   size_t i;
@@ -142,8 +145,18 @@ void prefetch_table(const void *tab, size_t len)
 static inline void
 do_prefetch_tables (const void *gcmM, size_t gcmM_size)
 {
-  prefetch_table(gcmM, gcmM_size);
-  prefetch_table(gcmR, sizeof(gcmR));
+  prefetch_table (gcmM, gcmM_size);
+
+  if (gcmR[1] != gcmR_const[1] || gcmR[255] != gcmR_const[255])
+    {
+      /* Copy look-up tables from .rodata section to .data to avoid
+       * sharing physical memory between processes. */
+      buf_cpy (gcmR, gcmR_const, sizeof(gcmR_const));
+    }
+  else
+    {
+      prefetch_table (gcmR, sizeof(gcmR));
+    }
 }
 
 #ifdef GCM_TABLES_USE_U64
diff --git a/cipher/rijndael-tables.h b/cipher/rijndael-tables.h
index 835947001..0940006cc 100644
--- a/cipher/rijndael-tables.h
+++ b/cipher/rijndael-tables.h
@@ -21,7 +21,16 @@
 /* To keep the actual implementation at a readable size we use this
    include file to define the tables.  */
 
-static const u32 encT[256] =
+
+static u32 encT[256];
+
+static struct
+{
+  u32 T[256];
+  byte inv_sbox[256];
+} dec_tables;
+
+static const u32 encT_const[256] =
   {
     0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6,
     0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
@@ -91,9 +100,9 @@ static const u32 encT[256] =
 
 static const struct
 {
-  u32 T[256];
-  byte inv_sbox[256];
-} dec_tables =
+  u32 T_const[256];
+  byte inv_sbox_const[256];
+} dec_tables_const =
   {
     {
       0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a,
diff --git a/cipher/rijndael.c b/cipher/rijndael.c
index 1001b1d52..4843e9770 100644
--- a/cipher/rijndael.c
+++ b/cipher/rijndael.c
@@ -247,6 +247,35 @@ static void prefetch_dec(void)
   prefetch_table((const void *)&dec_tables, sizeof(dec_tables));
 }
 
+static void prepare_enc_tables(void)
+{
+  if (encT[0] != encT_const[0] || encT[255] != encT_const[255])
+    {
+      /* Copy look-up tables from .rodata section to .data to avoid
+       * sharing physical memory between processes. */
+      buf_cpy(encT, encT_const, sizeof(encT_const));
+    }
+  else
+    {
+      prefetch_enc();
+    }
+}
+
+static void prepare_dec_tables(void)
+{
+  if (decT[0] != dec_tables_const.T_const[0] ||
+      inv_sbox[255] != dec_tables_const.inv_sbox_const[255])
+    {
+      /* Copy look-up tables from .rodata section to .data to avoid
+       * sharing physical memory between processes. */
+      buf_cpy(&dec_tables, &dec_tables_const, sizeof(dec_tables_const));
+    }
+  else
+    {
+      prefetch_dec();
+    }
+}
+
 
 

 /* Perform the key setup.  */
@@ -443,7 +472,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen,
 #define W      (ctx->keyschenc)
 #define W_u32  (ctx->keyschenc32)
 
-      prefetch_enc();
+      prepare_enc_tables();
 
       for (i = 0; i < keylen; i++)
         {
@@ -575,8 +604,8 @@ prepare_decryption( RIJNDAEL_context *ctx )
     {
       const byte *sbox = ((const byte *)encT) + 1;
 
+      prepare_dec_tables();
       prefetch_enc();
-      prefetch_dec();
 
       ctx->keyschdec32[0][0] = ctx->keyschenc32[0][0];
       ctx->keyschdec32[0][1] = ctx->keyschenc32[0][1];




More information about the Gcrypt-devel mailing list