[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