[FFmpeg-devel] [PATCH 1/3] Allow pre-generation of AES tables.

Diego Elio 'Flameeyes' Pettenò flameeyes
Sat Jun 26 01:48:43 CEST 2010


This adds tablegen support to libavutil Makefile, and includes header
and sources to produce an hardcoded copy of the tables rather than
calculate them at runtime.
---
 libavutil/Makefile       |   16 ++++++++
 libavutil/aes.c          |   48 ++------------------------
 libavutil/aes_tablegen.c |   53 ++++++++++++++++++++++++++++
 libavutil/aes_tablegen.h |   86 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 158 insertions(+), 45 deletions(-)
 create mode 100644 libavutil/aes_tablegen.c
 create mode 100644 libavutil/aes_tablegen.h

diff --git a/libavutil/Makefile b/libavutil/Makefile
index f6961ac..361fe5a 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -61,3 +61,19 @@ ARCH_HEADERS = bswap.h intmath.h intreadwrite.h timer.h
 include $(SUBDIR)../subdir.mak
 
 $(SUBDIR)lzo-test$(EXESUF): ELIBS = -llzo2
+
+ifdef CONFIG_SMALL
+$(SUBDIR)%_tablegen$(HOSTEXESUF): HOSTCFLAGS += -DCONFIG_SMALL=1
+else
+$(SUBDIR)%_tablegen$(HOSTEXESUF): HOSTCFLAGS += -DCONFIG_SMALL=0
+endif
+
+$(SUBDIR)%_tablegen$(HOSTEXESUF): $(SUBDIR)%_tablegen.c $(SUBDIR)../libavcodec/tableprint.c
+	$(HOSTCC) $(HOSTCFLAGS) -I$(SRC_PATH)/libavcodec $(HOSTLDFLAGS) -o $@ $^ $(HOSTLIBS)
+
+$(SUBDIR)%_tables.h: $(SUBDIR)%_tablegen$(HOSTEXESUF)
+	$(M)./$< > $@
+
+ifdef CONFIG_HARDCODED_TABLES
+$(SUBDIR)/aes.o: $(SUBDIR)aes_tables.h
+endif
diff --git a/libavutil/aes.c b/libavutil/aes.c
index d3a271c..c9a87a8 100644
--- a/libavutil/aes.c
+++ b/libavutil/aes.c
@@ -22,6 +22,7 @@
 
 #include "common.h"
 #include "aes.h"
+#include "aes_tablegen.h"
 
 typedef struct AVAES{
     // Note: round_key[16] is accessed in the init code, but this only
@@ -37,16 +38,6 @@ static const uint8_t rcon[10] = {
   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
 };
 
-static uint8_t     sbox[256];
-static uint8_t inv_sbox[256];
-#if CONFIG_SMALL
-static uint32_t enc_multbl[1][256];
-static uint32_t dec_multbl[1][256];
-#else
-static uint32_t enc_multbl[4][256];
-static uint32_t dec_multbl[4][256];
-#endif
-
 static inline void addkey(uint64_t dst[2], const uint64_t src[2], const uint64_t round_key[2]){
     dst[0] = src[0] ^ round_key[0];
     dst[1] = src[1] ^ round_key[1];
@@ -108,47 +99,14 @@ void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t
     }
 }
 
-static void init_multbl2(uint8_t tbl[1024], const int c[4], const uint8_t *log8, const uint8_t *alog8, const uint8_t *sbox){
-    int i, j;
-    for(i=0; i<1024; i++){
-        int x= sbox[i>>2];
-        if(x) tbl[i]= alog8[ log8[x] + log8[c[i&3]] ];
-    }
-#if !CONFIG_SMALL
-    for(j=256; j<1024; j++)
-        for(i=0; i<4; i++)
-            tbl[4*j+i]= tbl[4*j + ((i-1)&3) - 1024];
-#endif
-}
-
 // this is based on the reference AES code by Paulo Barreto and Vincent Rijmen
 int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) {
     int i, j, t, rconpointer = 0;
     uint8_t tk[8][4];
     int KC= key_bits>>5;
     int rounds= KC + 6;
-    uint8_t  log8[256];
-    uint8_t alog8[512];
-
-    if(!enc_multbl[0][sizeof(enc_multbl)/sizeof(enc_multbl[0][0])-1]){
-        j=1;
-        for(i=0; i<255; i++){
-            alog8[i]=
-            alog8[i+255]= j;
-            log8[j]= i;
-            j^= j+j;
-            if(j>255) j^= 0x11B;
-        }
-        for(i=0; i<256; i++){
-            j= i ? alog8[255-log8[i]] : 0;
-            j ^= (j<<1) ^ (j<<2) ^ (j<<3) ^ (j<<4);
-            j = (j ^ (j>>8) ^ 99) & 255;
-            inv_sbox[j]= i;
-            sbox    [i]= j;
-        }
-        init_multbl2(dec_multbl[0], (const int[4]){0xe, 0x9, 0xd, 0xb}, log8, alog8, inv_sbox);
-        init_multbl2(enc_multbl[0], (const int[4]){0x2, 0x1, 0x1, 0x3}, log8, alog8, sbox);
-    }
+
+    ff_aes_init_tables();
 
     if(key_bits!=128 && key_bits!=192 && key_bits!=256)
         return -1;
diff --git a/libavutil/aes_tablegen.c b/libavutil/aes_tablegen.c
new file mode 100644
index 0000000..4a24c2f
--- /dev/null
+++ b/libavutil/aes_tablegen.c
@@ -0,0 +1,53 @@
+/*
+ * Generate a source file for hardcoded AES tables
+ *
+ * copyright (c) 2007 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdlib.h>
+#define CONFIG_HARDCODED_TABLES 0
+#include "aes_tablegen.h"
+#include "tableprint.h"
+
+int main(void)
+{
+    ff_aes_init_tables();
+
+    write_fileheader();
+
+    printf("static const uint8_t sbox[256] = {\n");
+    write_uint8_array(sbox, 256);
+    printf("};\n");
+
+    printf("static const uint8_t inv_sbox[256] = {\n");
+    write_uint8_array(inv_sbox, 256);
+    printf("};\n");
+
+    printf("static const uint32_t enc_multbl[%d][256] = {\n",
+	   AES_TABLE_COUNT);
+    write_uint8_2d_array(enc_multbl, AES_TABLE_COUNT, 256);
+    printf("};\n");
+
+    printf("static const uint32_t dec_multbl[%d][256] = {\n",
+	   AES_TABLE_COUNT);
+    write_uint8_2d_array(dec_multbl, AES_TABLE_COUNT, 256);
+    printf("};\n");
+
+    return 0;
+}
diff --git a/libavutil/aes_tablegen.h b/libavutil/aes_tablegen.h
new file mode 100644
index 0000000..d3bb567
--- /dev/null
+++ b/libavutil/aes_tablegen.h
@@ -0,0 +1,86 @@
+/*
+ * Generate a header file for hardcoded AES tables
+ *
+ * copyright (c) 2007 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AES_TABLEGEN_H
+#define AES_TABLEGEN_H
+
+#include <stdint.h>
+#include <math.h>
+
+#if CONFIG_SMALL
+#define AES_TABLE_COUNT 1
+#else
+#define AES_TABLE_COUNT 4
+#endif
+
+#if CONFIG_HARDCODED_TABLES
+#define ff_aes_init_tables()
+#include "libavutil/aes_tables.h"
+#else
+
+static uint8_t     sbox[256];
+static uint8_t inv_sbox[256];
+static uint32_t enc_multbl[AES_TABLE_COUNT][256];
+static uint32_t dec_multbl[AES_TABLE_COUNT][256];
+
+static void init_multbl2(uint8_t tbl[1024], const int c[4], const uint8_t *log8, const uint8_t *alog8, const uint8_t *sbox){
+    int i, j;
+    for(i=0; i<1024; i++){
+        int x= sbox[i>>2];
+        if(x) tbl[i]= alog8[ log8[x] + log8[c[i&3]] ];
+    }
+#if !CONFIG_SMALL
+    for(j=256; j<1024; j++)
+        for(i=0; i<4; i++)
+            tbl[4*j+i]= tbl[4*j + ((i-1)&3) - 1024];
+#endif
+}
+
+static void ff_aes_init_tables() {
+    int i, j;
+    uint8_t  log8[256];
+    uint8_t alog8[512];
+
+    if(!enc_multbl[0][sizeof(enc_multbl)/sizeof(enc_multbl[0][0])-1]){
+        j=1;
+        for(i=0; i<255; i++){
+            alog8[i]=
+            alog8[i+255]= j;
+            log8[j]= i;
+            j^= j+j;
+            if(j>255) j^= 0x11B;
+        }
+        for(i=0; i<256; i++){
+            j= i ? alog8[255-log8[i]] : 0;
+            j ^= (j<<1) ^ (j<<2) ^ (j<<3) ^ (j<<4);
+            j = (j ^ (j>>8) ^ 99) & 255;
+            inv_sbox[j]= i;
+            sbox    [i]= j;
+        }
+        init_multbl2(dec_multbl[0], (const int[4]){0xe, 0x9, 0xd, 0xb}, log8, alog8, inv_sbox);
+        init_multbl2(enc_multbl[0], (const int[4]){0x2, 0x1, 0x1, 0x3}, log8, alog8, sbox);
+    }
+}
+
+#endif /* CONFIG_HARDCODED_TABLES */
+
+#endif /* AES_TABLEGEN_H */
-- 
1.7.1




More information about the ffmpeg-devel mailing list