On 16.06.2017 03:08, Bruce Momjian wrote:

Yeah, I guess we will just have to wait to see it since other people are
excited about it.  My concern is code complexity and usability
challenges, vs punting the problem to the operating system, though
admittedly there are some cases where that is not possible.


Let me also share my opinion about encryption and compression support at database level. PostgresPro Enterprise does support both. I have made presentation about it at PgConn 2016 in Tallinn. I was a little bit surprised that there were more questions about encryption than about compression. But right now we have several customers which are using compression and none of them use encryption (just because them do not need to protect their databases). But I absolutely sure that there are many Postgres users which first of all need to protect their data.

Encryption is much easier to implement than compression, because it is not changing page size. So I do not see any "complexity and flexibility challenges" here. Just for reference I attached to this mail our own encryption patch. I do not want to propose it as alternative to Aasmas patch: it is less flexible and doesn't support encryption of WAL, just encryption of relation data. Also it doesn't allow custom encryption libraries: AES implementation is embedded. Encryption cipher is taken from environment variable. At Tallin's conferences I was informed about possible security issue with passing key through environment variable: it is possible to inspect server's environment variables using plpython/plperl stored procedure. This is why we unset this environment variable after reading. I am not expect in security, but I do not know other issues with such solution.

Concerning the question whether to implement compression/encryption on database level or rely on OS, my opinion is that there are many scenarios where it is not possible or is not desirable to use OS level encryption/protection. It first of all includes cloud installations and embedded applications. I do not want to repeat arguments already mentioned in this thread. But the fact is that there are many people which really need compression/encryption support and them can not or do not want to redirect this aspects to OS. Almost all DBMSes are supporting compression encryption, so lack of this features in Postgres definitely can not be considered as Postgres advantage.

Postgres buffer manager interface significantly simplifies integration of encryption and compression. There is actually single path through which data is fetched/stored to the disk. It is most obvious and natural solution to decompress/decrypt data when it is read from the disk to page pool and compress/encrypt it when it is written back. Taken in account that memory is cheap now and many databases can completely fit in memory, storing pages in the buffer cache in plain (decompressed/decrypted) format allows to minimize overhead of compression/encryption and its influence on performance. For read only queries working with cached data performance will be exactly the same as without encryption/compression. Write speed for encrypted pages will be certainly slightly worse, but still encryption speed is much higher than disk IO speed.

So I do not think that it is really necessary to support encryption of some particular tables, storing "non-secrete" data in plain format without encryption. It should not cause noticeable improve of performance, but may complicate implementation and increase possibility of leaking secure data.

I do not think that pluggable storage API is right approach to integrate compression and especially encryption. It is better to plugin encryption between buffer manager and storage device, allowing to use it with any storage implementation. Also it is not clear to me whether encryption of WAL can be provided using pluggable storage API.

The last discussed question is whether it is necessary to encrypt temporary data (BufFile). In our solution we encrypt only main fork of non-system relations and do no encrypt temporary relations. It may cause that some secrete data will be stored at this disk in non-encrypted format. But accessing this data is not trivial. You can not just copy/stole disk, open database and do "select * from SecreteTable": you will have to extract data from raw file yourself. So looks like it is better to allow user to make choice whether to encrypt temporary data or not.

--
Konstantin Knizhnik
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company

diff --git a/src/backend/storage/file/Makefile b/src/backend/storage/file/Makefile
index d2198f2..9492662 100644
--- a/src/backend/storage/file/Makefile
+++ b/src/backend/storage/file/Makefile
@@ -12,6 +12,6 @@ subdir = src/backend/storage/file
 top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
-OBJS = fd.o buffile.o copydir.o reinit.o
+OBJS = fd.o buffile.o copydir.o reinit.o rijndael.o
 
 include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/storage/file/rijndael.c b/src/backend/storage/file/rijndael.c
new file mode 100644
index 0000000..31b2a60
--- /dev/null
+++ b/src/backend/storage/file/rijndael.c
@@ -0,0 +1,677 @@
+/*	$OpenBSD: rijndael.c,v 1.6 2000/12/09 18:51:34 markus Exp $ */
+
+/* contrib/pgcrypto/rijndael.c */
+
+/* This is an independent implementation of the encryption algorithm:	*/
+/*																		*/
+/*		   RIJNDAEL by Joan Daemen and Vincent Rijmen					*/
+/*																		*/
+/* which is a candidate algorithm in the Advanced Encryption Standard	*/
+/* programme of the US National Institute of Standards and Technology.  */
+/*																		*/
+/* Copyright in this implementation is held by Dr B R Gladman but I		*/
+/* hereby give permission for its free direct or derivative use subject */
+/* to acknowledgment of its origin and compliance with any conditions	*/
+/* that the originators of the algorithm place on its exploitation.     */
+/*																		*/
+/* Dr Brian Gladman (glad...@seven77.demon.co.uk) 14th January 1999		*/
+
+/* Timing data for Rijndael (rijndael.c)
+
+Algorithm: rijndael (rijndael.c)
+
+128 bit key:
+Key Setup:	  305/1389 cycles (encrypt/decrypt)
+Encrypt:	   374 cycles =    68.4 mbits/sec
+Decrypt:	   352 cycles =    72.7 mbits/sec
+Mean:		   363 cycles =    70.5 mbits/sec
+
+192 bit key:
+Key Setup:	  277/1595 cycles (encrypt/decrypt)
+Encrypt:	   439 cycles =    58.3 mbits/sec
+Decrypt:	   425 cycles =    60.2 mbits/sec
+Mean:		   432 cycles =    59.3 mbits/sec
+
+256 bit key:
+Key Setup:	  374/1960 cycles (encrypt/decrypt)
+Encrypt:	   502 cycles =    51.0 mbits/sec
+Decrypt:	   498 cycles =    51.4 mbits/sec
+Mean:		   500 cycles =    51.2 mbits/sec
+
+*/
+
+#include "postgres.h"
+
+#include <sys/param.h>
+#include <string.h>
+
+#include "storage/rijndael.h"
+
+#define PRE_CALC_TABLES
+#define LARGE_TABLES
+
+static void gen_tabs(void);
+
+/* 3. Basic macros for speeding up generic operations				*/
+
+/* Circular rotate of 32 bit values									*/
+
+#define rotr(x,n)	(((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))
+#define rotl(x,n)	(((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))
+
+/* Invert byte order in a 32 bit variable							*/
+
+#define bswap(x)	((rotl((x), 8) & 0x00ff00ff) | (rotr((x), 8) & 0xff00ff00))
+
+/* Extract byte from a 32 bit quantity (little endian notation)		*/
+
+#define byte(x,n)	((u1byte)((x) >> (8 * (n))))
+
+#ifdef WORDS_BIGENDIAN
+#define io_swap(x)	bswap(x)
+#else
+#define io_swap(x)	(x)
+#endif
+
+#ifdef PRINT_TABS
+#undef PRE_CALC_TABLES
+#endif
+
+#ifdef PRE_CALC_TABLES
+
+#include "rijndael.tbl"
+#define tab_gen		1
+#else							/* !PRE_CALC_TABLES */
+
+static u1byte pow_tab[256];
+static u1byte log_tab[256];
+static u1byte sbx_tab[256];
+static u1byte isb_tab[256];
+static u4byte rco_tab[10];
+static u4byte ft_tab[4][256];
+static u4byte it_tab[4][256];
+
+#ifdef	LARGE_TABLES
+static u4byte fl_tab[4][256];
+static u4byte il_tab[4][256];
+#endif
+
+static u4byte tab_gen = 0;
+#endif   /* !PRE_CALC_TABLES */
+
+#define ff_mult(a,b)	((a) && (b) ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)
+
+#define f_rn(bo, bi, n, k)								\
+	(bo)[n] =  ft_tab[0][byte((bi)[n],0)] ^				\
+			 ft_tab[1][byte((bi)[((n) + 1) & 3],1)] ^	\
+			 ft_tab[2][byte((bi)[((n) + 2) & 3],2)] ^	\
+			 ft_tab[3][byte((bi)[((n) + 3) & 3],3)] ^ *((k) + (n))
+
+#define i_rn(bo, bi, n, k)							\
+	(bo)[n] =  it_tab[0][byte((bi)[n],0)] ^				\
+			 it_tab[1][byte((bi)[((n) + 3) & 3],1)] ^	\
+			 it_tab[2][byte((bi)[((n) + 2) & 3],2)] ^	\
+			 it_tab[3][byte((bi)[((n) + 1) & 3],3)] ^ *((k) + (n))
+
+#ifdef LARGE_TABLES
+
+#define ls_box(x)				 \
+	( fl_tab[0][byte(x, 0)] ^	 \
+	  fl_tab[1][byte(x, 1)] ^	 \
+	  fl_tab[2][byte(x, 2)] ^	 \
+	  fl_tab[3][byte(x, 3)] )
+
+#define f_rl(bo, bi, n, k)								\
+	(bo)[n] =  fl_tab[0][byte((bi)[n],0)] ^				\
+			 fl_tab[1][byte((bi)[((n) + 1) & 3],1)] ^	\
+			 fl_tab[2][byte((bi)[((n) + 2) & 3],2)] ^	\
+			 fl_tab[3][byte((bi)[((n) + 3) & 3],3)] ^ *((k) + (n))
+
+#define i_rl(bo, bi, n, k)								\
+	(bo)[n] =  il_tab[0][byte((bi)[n],0)] ^				\
+			 il_tab[1][byte((bi)[((n) + 3) & 3],1)] ^	\
+			 il_tab[2][byte((bi)[((n) + 2) & 3],2)] ^	\
+			 il_tab[3][byte((bi)[((n) + 1) & 3],3)] ^ *((k) + (n))
+#else
+
+#define ls_box(x)							 \
+	((u4byte)sbx_tab[byte(x, 0)] <<  0) ^	 \
+	((u4byte)sbx_tab[byte(x, 1)] <<  8) ^	 \
+	((u4byte)sbx_tab[byte(x, 2)] << 16) ^	 \
+	((u4byte)sbx_tab[byte(x, 3)] << 24)
+
+#define f_rl(bo, bi, n, k)											\
+	(bo)[n] = (u4byte)sbx_tab[byte((bi)[n],0)] ^					\
+		rotl(((u4byte)sbx_tab[byte((bi)[((n) + 1) & 3],1)]),  8) ^	\
+		rotl(((u4byte)sbx_tab[byte((bi)[((n) + 2) & 3],2)]), 16) ^	\
+		rotl(((u4byte)sbx_tab[byte((bi)[((n) + 3) & 3],3)]), 24) ^ *((k) + (n))
+
+#define i_rl(bo, bi, n, k)											\
+	(bo)[n] = (u4byte)isb_tab[byte((bi)[n],0)] ^					\
+		rotl(((u4byte)isb_tab[byte((bi)[((n) + 3) & 3],1)]),  8) ^	\
+		rotl(((u4byte)isb_tab[byte((bi)[((n) + 2) & 3],2)]), 16) ^	\
+		rotl(((u4byte)isb_tab[byte((bi)[((n) + 1) & 3],3)]), 24) ^ *((k) + (n))
+#endif
+
+static void
+gen_tabs(void)
+{
+#ifndef PRE_CALC_TABLES
+	u4byte		i,
+				t;
+	u1byte		p,
+				q;
+
+	/* log and power tables for GF(2**8) finite field with	*/
+	/* 0x11b as modular polynomial - the simplest prmitive	*/
+	/* root is 0x11, used here to generate the tables		*/
+
+	for (i = 0, p = 1; i < 256; ++i)
+	{
+		pow_tab[i] = (u1byte) p;
+		log_tab[p] = (u1byte) i;
+
+		p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0);
+	}
+
+	log_tab[1] = 0;
+	p = 1;
+
+	for (i = 0; i < 10; ++i)
+	{
+		rco_tab[i] = p;
+
+		p = (p << 1) ^ (p & 0x80 ? 0x1b : 0);
+	}
+
+	/* note that the affine byte transformation matrix in	*/
+	/* rijndael specification is in big endian format with	*/
+	/* bit 0 as the most significant bit. In the remainder	*/
+	/* of the specification the bits are numbered from the	*/
+	/* least significant end of a byte.                     */
+
+	for (i = 0; i < 256; ++i)
+	{
+		p = (i ? pow_tab[255 - log_tab[i]] : 0);
+		q = p;
+		q = (q >> 7) | (q << 1);
+		p ^= q;
+		q = (q >> 7) | (q << 1);
+		p ^= q;
+		q = (q >> 7) | (q << 1);
+		p ^= q;
+		q = (q >> 7) | (q << 1);
+		p ^= q ^ 0x63;
+		sbx_tab[i] = (u1byte) p;
+		isb_tab[p] = (u1byte) i;
+	}
+
+	for (i = 0; i < 256; ++i)
+	{
+		p = sbx_tab[i];
+
+#ifdef	LARGE_TABLES
+
+		t = p;
+		fl_tab[0][i] = t;
+		fl_tab[1][i] = rotl(t, 8);
+		fl_tab[2][i] = rotl(t, 16);
+		fl_tab[3][i] = rotl(t, 24);
+#endif
+		t = ((u4byte) ff_mult(2, p)) |
+			((u4byte) p << 8) |
+			((u4byte) p << 16) |
+			((u4byte) ff_mult(3, p) << 24);
+
+		ft_tab[0][i] = t;
+		ft_tab[1][i] = rotl(t, 8);
+		ft_tab[2][i] = rotl(t, 16);
+		ft_tab[3][i] = rotl(t, 24);
+
+		p = isb_tab[i];
+
+#ifdef	LARGE_TABLES
+
+		t = p;
+		il_tab[0][i] = t;
+		il_tab[1][i] = rotl(t, 8);
+		il_tab[2][i] = rotl(t, 16);
+		il_tab[3][i] = rotl(t, 24);
+#endif
+		t = ((u4byte) ff_mult(14, p)) |
+			((u4byte) ff_mult(9, p) << 8) |
+			((u4byte) ff_mult(13, p) << 16) |
+			((u4byte) ff_mult(11, p) << 24);
+
+		it_tab[0][i] = t;
+		it_tab[1][i] = rotl(t, 8);
+		it_tab[2][i] = rotl(t, 16);
+		it_tab[3][i] = rotl(t, 24);
+	}
+
+	tab_gen = 1;
+#endif   /* !PRE_CALC_TABLES */
+}
+
+
+#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
+
+#define imix_col(y,x)		\
+do { \
+	u	= star_x(x);		\
+	v	= star_x(u);		\
+	w	= star_x(v);		\
+	t	= w ^ (x);			\
+   (y)	= u ^ v ^ w;		\
+   (y) ^= rotr(u ^ t,  8) ^ \
+		  rotr(v ^ t, 16) ^ \
+		  rotr(t,24);		\
+} while (0)
+
+/* initialise the key schedule from the user supplied key	*/
+
+#define loop4(i)									\
+do {   t = ls_box(rotr(t,  8)) ^ rco_tab[i];		   \
+	t ^= e_key[4 * i];	   e_key[4 * i + 4] = t;	\
+	t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t;	\
+	t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t;	\
+	t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t;	\
+} while (0)
+
+#define loop6(i)									\
+do {   t = ls_box(rotr(t,  8)) ^ rco_tab[i];		   \
+	t ^= e_key[6 * (i)];	   e_key[6 * (i) + 6] = t;	\
+	t ^= e_key[6 * (i) + 1]; e_key[6 * (i) + 7] = t;	\
+	t ^= e_key[6 * (i) + 2]; e_key[6 * (i) + 8] = t;	\
+	t ^= e_key[6 * (i) + 3]; e_key[6 * (i) + 9] = t;	\
+	t ^= e_key[6 * (i) + 4]; e_key[6 * (i) + 10] = t;	\
+	t ^= e_key[6 * (i) + 5]; e_key[6 * (i) + 11] = t;	\
+} while (0)
+
+#define loop8(i)									\
+do {   t = ls_box(rotr(t,  8)) ^ rco_tab[i];		   \
+	t ^= e_key[8 * (i)];	 e_key[8 * (i) + 8] = t;	\
+	t ^= e_key[8 * (i) + 1]; e_key[8 * (i) + 9] = t;	\
+	t ^= e_key[8 * (i) + 2]; e_key[8 * (i) + 10] = t;	\
+	t ^= e_key[8 * (i) + 3]; e_key[8 * (i) + 11] = t;	\
+	t  = e_key[8 * (i) + 4] ^ ls_box(t);				\
+	e_key[8 * (i) + 12] = t;							\
+	t ^= e_key[8 * (i) + 5]; e_key[8 * (i) + 13] = t;	\
+	t ^= e_key[8 * (i) + 6]; e_key[8 * (i) + 14] = t;	\
+	t ^= e_key[8 * (i) + 7]; e_key[8 * (i) + 15] = t;	\
+} while (0)
+
+rijndael_ctx *
+rijndael_set_key(rijndael_ctx *ctx, const u4byte *in_key, const u4byte key_len,
+				 int encrypt)
+{
+	u4byte		i,
+				t,
+				u,
+				v,
+				w;
+	u4byte	   *e_key = ctx->e_key;
+	u4byte	   *d_key = ctx->d_key;
+
+	ctx->decrypt = !encrypt;
+
+	if (!tab_gen)
+		gen_tabs();
+
+	ctx->k_len = (key_len + 31) / 32;
+
+	e_key[0] = io_swap(in_key[0]);
+	e_key[1] = io_swap(in_key[1]);
+	e_key[2] = io_swap(in_key[2]);
+	e_key[3] = io_swap(in_key[3]);
+
+	switch (ctx->k_len)
+	{
+		case 4:
+			t = e_key[3];
+			for (i = 0; i < 10; ++i)
+				loop4(i);
+			break;
+
+		case 6:
+			e_key[4] = io_swap(in_key[4]);
+			t = e_key[5] = io_swap(in_key[5]);
+			for (i = 0; i < 8; ++i)
+				loop6(i);
+			break;
+
+		case 8:
+			e_key[4] = io_swap(in_key[4]);
+			e_key[5] = io_swap(in_key[5]);
+			e_key[6] = io_swap(in_key[6]);
+			t = e_key[7] = io_swap(in_key[7]);
+			for (i = 0; i < 7; ++i)
+				loop8(i);
+			break;
+	}
+
+	if (!encrypt)
+	{
+		d_key[0] = e_key[0];
+		d_key[1] = e_key[1];
+		d_key[2] = e_key[2];
+		d_key[3] = e_key[3];
+
+		for (i = 4; i < 4 * ctx->k_len + 24; ++i)
+			imix_col(d_key[i], e_key[i]);
+	}
+
+	return ctx;
+}
+
+/* encrypt a block of text	*/
+
+#define f_nround(bo, bi, k) \
+do { \
+	f_rn(bo, bi, 0, k);		\
+	f_rn(bo, bi, 1, k);		\
+	f_rn(bo, bi, 2, k);		\
+	f_rn(bo, bi, 3, k);		\
+	k += 4;					\
+} while (0)
+
+#define f_lround(bo, bi, k) \
+do { \
+	f_rl(bo, bi, 0, k);		\
+	f_rl(bo, bi, 1, k);		\
+	f_rl(bo, bi, 2, k);		\
+	f_rl(bo, bi, 3, k);		\
+} while (0)
+
+void
+rijndael_encrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
+{
+	u4byte		k_len = ctx->k_len;
+	u4byte	   *e_key = ctx->e_key;
+	u4byte		b0[4],
+				b1[4],
+			   *kp;
+
+	b0[0] = io_swap(in_blk[0]) ^ e_key[0];
+	b0[1] = io_swap(in_blk[1]) ^ e_key[1];
+	b0[2] = io_swap(in_blk[2]) ^ e_key[2];
+	b0[3] = io_swap(in_blk[3]) ^ e_key[3];
+
+	kp = e_key + 4;
+
+	if (k_len > 6)
+	{
+		f_nround(b1, b0, kp);
+		f_nround(b0, b1, kp);
+	}
+
+	if (k_len > 4)
+	{
+		f_nround(b1, b0, kp);
+		f_nround(b0, b1, kp);
+	}
+
+	f_nround(b1, b0, kp);
+	f_nround(b0, b1, kp);
+	f_nround(b1, b0, kp);
+	f_nround(b0, b1, kp);
+	f_nround(b1, b0, kp);
+	f_nround(b0, b1, kp);
+	f_nround(b1, b0, kp);
+	f_nround(b0, b1, kp);
+	f_nround(b1, b0, kp);
+	f_lround(b0, b1, kp);
+
+	out_blk[0] = io_swap(b0[0]);
+	out_blk[1] = io_swap(b0[1]);
+	out_blk[2] = io_swap(b0[2]);
+	out_blk[3] = io_swap(b0[3]);
+}
+
+/* decrypt a block of text	*/
+
+#define i_nround(bo, bi, k) \
+do { \
+	i_rn(bo, bi, 0, k);		\
+	i_rn(bo, bi, 1, k);		\
+	i_rn(bo, bi, 2, k);		\
+	i_rn(bo, bi, 3, k);		\
+	k -= 4;					\
+} while (0)
+
+#define i_lround(bo, bi, k) \
+do { \
+	i_rl(bo, bi, 0, k);		\
+	i_rl(bo, bi, 1, k);		\
+	i_rl(bo, bi, 2, k);		\
+	i_rl(bo, bi, 3, k);		\
+} while (0)
+
+void
+rijndael_decrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
+{
+	u4byte		b0[4],
+				b1[4],
+			   *kp;
+	u4byte		k_len = ctx->k_len;
+	u4byte	   *e_key = ctx->e_key;
+	u4byte	   *d_key = ctx->d_key;
+
+	b0[0] = io_swap(in_blk[0]) ^ e_key[4 * k_len + 24];
+	b0[1] = io_swap(in_blk[1]) ^ e_key[4 * k_len + 25];
+	b0[2] = io_swap(in_blk[2]) ^ e_key[4 * k_len + 26];
+	b0[3] = io_swap(in_blk[3]) ^ e_key[4 * k_len + 27];
+
+	kp = d_key + 4 * (k_len + 5);
+
+	if (k_len > 6)
+	{
+		i_nround(b1, b0, kp);
+		i_nround(b0, b1, kp);
+	}
+
+	if (k_len > 4)
+	{
+		i_nround(b1, b0, kp);
+		i_nround(b0, b1, kp);
+	}
+
+	i_nround(b1, b0, kp);
+	i_nround(b0, b1, kp);
+	i_nround(b1, b0, kp);
+	i_nround(b0, b1, kp);
+	i_nround(b1, b0, kp);
+	i_nround(b0, b1, kp);
+	i_nround(b1, b0, kp);
+	i_nround(b0, b1, kp);
+	i_nround(b1, b0, kp);
+	i_lround(b0, b1, kp);
+
+	out_blk[0] = io_swap(b0[0]);
+	out_blk[1] = io_swap(b0[1]);
+	out_blk[2] = io_swap(b0[2]);
+	out_blk[3] = io_swap(b0[3]);
+}
+
+/*
+ * conventional interface
+ *
+ * ATM it hopes all data is 4-byte aligned - which
+ * should be true for PX.  -marko
+ */
+
+void
+aes_set_key(rijndael_ctx *ctx, const uint8 *key, unsigned keybits, int enc)
+{
+	uint32	   *k;
+
+	k = (uint32 *) key;
+	rijndael_set_key(ctx, k, keybits, enc);
+}
+
+void
+aes_ecb_encrypt(rijndael_ctx *ctx, uint8 *data, unsigned len)
+{
+	unsigned	bs = 16;
+	uint32	   *d;
+
+	while (len >= bs)
+	{
+		d = (uint32 *) data;
+		rijndael_encrypt(ctx, d, d);
+
+		len -= bs;
+		data += bs;
+	}
+}
+
+void
+aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len)
+{
+	unsigned	bs = 16;
+	uint32	   *d;
+
+	while (len >= bs)
+	{
+		d = (uint32 *) data;
+		rijndael_decrypt(ctx, d, d);
+
+		len -= bs;
+		data += bs;
+	}
+}
+
+void
+aes_cbc_encrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len)
+{
+	uint32	   *iv = (uint32 *) iva;
+	uint32	   *d = (uint32 *) data;
+	unsigned	bs = 16;
+
+	while (len >= bs)
+	{
+		d[0] ^= iv[0];
+		d[1] ^= iv[1];
+		d[2] ^= iv[2];
+		d[3] ^= iv[3];
+
+		rijndael_encrypt(ctx, d, d);
+
+		iv = d;
+		d += bs / 4;
+		len -= bs;
+	}
+}
+
+void
+aes_cbc_decrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len)
+{
+	uint32	   *d = (uint32 *) data;
+	unsigned	bs = 16;
+	uint32		buf[4],
+				iv[4];
+
+	memcpy(iv, iva, bs);
+	while (len >= bs)
+	{
+		buf[0] = d[0];
+		buf[1] = d[1];
+		buf[2] = d[2];
+		buf[3] = d[3];
+
+		rijndael_decrypt(ctx, buf, d);
+
+		d[0] ^= iv[0];
+		d[1] ^= iv[1];
+		d[2] ^= iv[2];
+		d[3] ^= iv[3];
+
+		iv[0] = buf[0];
+		iv[1] = buf[1];
+		iv[2] = buf[2];
+		iv[3] = buf[3];
+		d += 4;
+		len -= bs;
+	}
+}
+
+/*
+ * pre-calculate tables.
+ *
+ * On i386 lifts 17k from .bss to .rodata
+ * and avoids 1k code and setup time.
+ *	  -marko
+ */
+#ifdef PRINT_TABS
+
+static void
+show256u8(char *name, uint8 *data)
+{
+	int			i;
+
+	printf("static const u1byte  %s[256] = {\n  ", name);
+	for (i = 0; i < 256;)
+	{
+		printf("%u", pow_tab[i++]);
+		if (i < 256)
+			printf(i % 16 ? ", " : ",\n  ");
+	}
+	printf("\n};\n\n");
+}
+
+
+static void
+show4x256u32(char *name, uint32 data[4][256])
+{
+	int			i,
+				j;
+
+	printf("static const u4byte  %s[4][256] = {\n{\n  ", name);
+	for (i = 0; i < 4; i++)
+	{
+		for (j = 0; j < 256;)
+		{
+			printf("0x%08x", data[i][j]);
+			j++;
+			if (j < 256)
+				printf(j % 4 ? ", " : ",\n  ");
+		}
+		printf(i < 3 ? "\n}, {\n  " : "\n}\n");
+	}
+	printf("};\n\n");
+}
+
+int
+main()
+{
+	int			i;
+	char	   *hdr = "/* Generated by rijndael.c */\n\n";
+
+	gen_tabs();
+
+	printf(hdr);
+	show256u8("pow_tab", pow_tab);
+	show256u8("log_tab", log_tab);
+	show256u8("sbx_tab", sbx_tab);
+	show256u8("isb_tab", isb_tab);
+
+	show4x256u32("ft_tab", ft_tab);
+	show4x256u32("it_tab", it_tab);
+#ifdef LARGE_TABLES
+	show4x256u32("fl_tab", fl_tab);
+	show4x256u32("il_tab", il_tab);
+#endif
+	printf("static const u4byte rco_tab[10] = {\n  ");
+	for (i = 0; i < 10; i++)
+	{
+		printf("0x%08x", rco_tab[i]);
+		if (i < 9)
+			printf(", ");
+		if (i == 4)
+			printf("\n  ");
+	}
+	printf("\n};\n\n");
+	return 0;
+}
+
+#endif
diff --git a/src/backend/storage/file/rijndael.tbl b/src/backend/storage/file/rijndael.tbl
new file mode 100644
index 0000000..c7610c0
--- /dev/null
+++ b/src/backend/storage/file/rijndael.tbl
@@ -0,0 +1,1138 @@
+/* Generated by rijndael.c */
+
+static const u1byte  pow_tab[256] = {
+  1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
+  95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
+  229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
+  83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
+  76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
+  131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
+  181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
+  254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
+  251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
+  195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
+  159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
+  155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
+  252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
+  69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
+  18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
+  57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
+};
+
+static const u1byte  log_tab[256] = {
+  1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
+  95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
+  229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
+  83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
+  76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
+  131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
+  181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
+  254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
+  251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
+  195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
+  159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
+  155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
+  252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
+  69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
+  18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
+  57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
+};
+
+static const u1byte  sbx_tab[256] = {
+  1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
+  95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
+  229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
+  83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
+  76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
+  131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
+  181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
+  254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
+  251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
+  195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
+  159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
+  155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
+  252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
+  69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
+  18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
+  57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
+};
+
+static const u1byte  isb_tab[256] = {
+  1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
+  95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
+  229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
+  83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
+  76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
+  131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
+  181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
+  254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
+  251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
+  195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
+  159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
+  155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
+  252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
+  69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
+  18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
+  57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
+};
+
+static const u4byte  ft_tab[4][256] = {
+{
+  0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6,
+  0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
+  0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
+  0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
+  0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
+  0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
+  0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45,
+  0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
+  0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c,
+  0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
+  0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9,
+  0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
+  0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d,
+  0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
+  0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
+  0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
+  0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34,
+  0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
+  0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d,
+  0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
+  0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1,
+  0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
+  0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972,
+  0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
+  0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
+  0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
+  0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,
+  0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
+  0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05,
+  0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
+  0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142,
+  0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
+  0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
+  0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
+  0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
+  0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
+  0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3,
+  0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
+  0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428,
+  0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
+  0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14,
+  0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
+  0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4,
+  0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
+  0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
+  0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
+  0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf,
+  0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
+  0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c,
+  0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
+  0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
+  0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
+  0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc,
+  0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
+  0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
+  0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
+  0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,
+  0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
+  0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9,
+  0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
+  0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a,
+  0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
+  0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
+  0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
+}, {
+  0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d,
+  0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154,
+  0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d,
+  0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a,
+  0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87,
+  0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b,
+  0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea,
+  0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b,
+  0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a,
+  0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f,
+  0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908,
+  0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f,
+  0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e,
+  0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5,
+  0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d,
+  0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f,
+  0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e,
+  0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb,
+  0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce,
+  0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397,
+  0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c,
+  0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed,
+  0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b,
+  0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a,
+  0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16,
+  0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194,
+  0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81,
+  0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3,
+  0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a,
+  0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104,
+  0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263,
+  0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d,
+  0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f,
+  0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39,
+  0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47,
+  0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695,
+  0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f,
+  0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83,
+  0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c,
+  0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76,
+  0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e,
+  0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4,
+  0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6,
+  0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b,
+  0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7,
+  0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0,
+  0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25,
+  0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018,
+  0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72,
+  0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751,
+  0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21,
+  0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85,
+  0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa,
+  0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12,
+  0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0,
+  0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9,
+  0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233,
+  0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7,
+  0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920,
+  0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a,
+  0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17,
+  0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8,
+  0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11,
+  0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a
+}, {
+  0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b,
+  0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5,
+  0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b,
+  0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76,
+  0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d,
+  0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0,
+  0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf,
+  0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0,
+  0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26,
+  0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc,
+  0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1,
+  0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15,
+  0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3,
+  0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a,
+  0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2,
+  0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75,
+  0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a,
+  0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0,
+  0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3,
+  0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784,
+  0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced,
+  0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b,
+  0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39,
+  0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf,
+  0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb,
+  0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485,
+  0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f,
+  0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8,
+  0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f,
+  0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5,
+  0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321,
+  0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2,
+  0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec,
+  0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917,
+  0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d,
+  0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573,
+  0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc,
+  0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388,
+  0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14,
+  0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db,
+  0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a,
+  0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c,
+  0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662,
+  0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79,
+  0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d,
+  0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9,
+  0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea,
+  0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808,
+  0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e,
+  0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6,
+  0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f,
+  0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a,
+  0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66,
+  0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e,
+  0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9,
+  0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e,
+  0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311,
+  0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794,
+  0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9,
+  0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf,
+  0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d,
+  0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868,
+  0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f,
+  0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16
+}, {
+  0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b,
+  0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5,
+  0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b,
+  0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676,
+  0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d,
+  0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0,
+  0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf,
+  0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0,
+  0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626,
+  0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc,
+  0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1,
+  0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515,
+  0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3,
+  0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a,
+  0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2,
+  0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575,
+  0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a,
+  0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0,
+  0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3,
+  0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484,
+  0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded,
+  0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b,
+  0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939,
+  0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf,
+  0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb,
+  0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585,
+  0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f,
+  0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8,
+  0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f,
+  0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5,
+  0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121,
+  0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2,
+  0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec,
+  0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717,
+  0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d,
+  0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373,
+  0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc,
+  0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888,
+  0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414,
+  0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb,
+  0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a,
+  0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c,
+  0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262,
+  0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979,
+  0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d,
+  0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9,
+  0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea,
+  0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808,
+  0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e,
+  0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6,
+  0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f,
+  0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a,
+  0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666,
+  0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e,
+  0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9,
+  0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e,
+  0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111,
+  0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494,
+  0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9,
+  0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf,
+  0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d,
+  0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868,
+  0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f,
+  0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616
+}
+};
+
+static const u4byte  it_tab[4][256] = {
+{
+  0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a,
+  0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b,
+  0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5,
+  0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5,
+  0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d,
+  0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b,
+  0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295,
+  0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e,
+  0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927,
+  0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
+  0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362,
+  0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9,
+  0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52,
+  0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566,
+  0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3,
+  0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed,
+  0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e,
+  0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4,
+  0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4,
+  0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
+  0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d,
+  0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060,
+  0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967,
+  0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879,
+  0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000,
+  0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c,
+  0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36,
+  0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624,
+  0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b,
+  0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
+  0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12,
+  0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14,
+  0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3,
+  0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b,
+  0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8,
+  0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684,
+  0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7,
+  0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177,
+  0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947,
+  0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
+  0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498,
+  0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f,
+  0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54,
+  0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382,
+  0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf,
+  0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb,
+  0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83,
+  0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef,
+  0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029,
+  0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
+  0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733,
+  0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117,
+  0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4,
+  0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546,
+  0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb,
+  0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d,
+  0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb,
+  0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a,
+  0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773,
+  0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
+  0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2,
+  0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff,
+  0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664,
+  0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0
+}, {
+  0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96,
+  0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x03e34b93,
+  0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525,
+  0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f,
+  0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1,
+  0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6,
+  0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da,
+  0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44,
+  0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd,
+  0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4,
+  0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245,
+  0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994,
+  0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7,
+  0xd373ab23, 0x024b72e2, 0x8f1fe357, 0xab55662a,
+  0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5,
+  0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c,
+  0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1,
+  0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a,
+  0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475,
+  0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51,
+  0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46,
+  0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff,
+  0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777,
+  0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db,
+  0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000,
+  0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e,
+  0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627,
+  0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a,
+  0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e,
+  0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16,
+  0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d,
+  0x0d090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8,
+  0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd,
+  0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34,
+  0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863,
+  0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420,
+  0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d,
+  0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0,
+  0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722,
+  0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef,
+  0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836,
+  0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4,
+  0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462,
+  0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5,
+  0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3,
+  0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b,
+  0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8,
+  0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6,
+  0x9be7bad9, 0x366f4ace, 0x099fead4, 0x7cb029d6,
+  0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0,
+  0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315,
+  0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f,
+  0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x0496e4df,
+  0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f,
+  0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e,
+  0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13,
+  0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89,
+  0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c,
+  0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf,
+  0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886,
+  0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f,
+  0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41,
+  0x01a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490,
+  0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042
+}, {
+  0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e,
+  0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303,
+  0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c,
+  0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3,
+  0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0,
+  0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9,
+  0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59,
+  0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8,
+  0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71,
+  0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a,
+  0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f,
+  0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b,
+  0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8,
+  0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab,
+  0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508,
+  0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82,
+  0xcf8a2b1c, 0x79a792b4, 0x07f3f0f2, 0x694ea1e2,
+  0xda65cdf4, 0x0506d5be, 0x34d11f62, 0xa6c48afe,
+  0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb,
+  0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110,
+  0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd,
+  0x5491b58d, 0xc471055d, 0x06046fd4, 0x5060ff15,
+  0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e,
+  0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee,
+  0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000,
+  0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72,
+  0x0efdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739,
+  0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e,
+  0x0a0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91,
+  0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a,
+  0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17,
+  0x090e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9,
+  0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60,
+  0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e,
+  0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1,
+  0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011,
+  0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1,
+  0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3,
+  0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264,
+  0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90,
+  0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b,
+  0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf,
+  0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246,
+  0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af,
+  0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312,
+  0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb,
+  0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a,
+  0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8,
+  0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c,
+  0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066,
+  0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8,
+  0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6,
+  0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04,
+  0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51,
+  0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41,
+  0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347,
+  0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c,
+  0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1,
+  0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37,
+  0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db,
+  0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40,
+  0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0x0dff4195,
+  0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1,
+  0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257
+}, {
+  0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27,
+  0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3,
+  0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02,
+  0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362,
+  0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe,
+  0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3,
+  0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952,
+  0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9,
+  0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9,
+  0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace,
+  0x63184adf, 0xe582311a, 0x97603351, 0x62457f53,
+  0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08,
+  0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b,
+  0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55,
+  0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837,
+  0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216,
+  0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269,
+  0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6,
+  0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6,
+  0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e,
+  0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6,
+  0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550,
+  0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9,
+  0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8,
+  0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000,
+  0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a,
+  0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d,
+  0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36,
+  0x0cb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b,
+  0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12,
+  0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b,
+  0x0e0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e,
+  0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f,
+  0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb,
+  0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4,
+  0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6,
+  0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129,
+  0x1d4b2f9e, 0xdcf330b2, 0x0dec5286, 0x77d0e3c1,
+  0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9,
+  0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033,
+  0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4,
+  0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad,
+  0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e,
+  0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3,
+  0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225,
+  0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b,
+  0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f,
+  0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815,
+  0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0,
+  0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2,
+  0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7,
+  0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691,
+  0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496,
+  0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165,
+  0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b,
+  0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6,
+  0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13,
+  0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147,
+  0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7,
+  0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44,
+  0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3,
+  0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d,
+  0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156,
+  0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8
+}
+};
+
+static const u4byte  fl_tab[4][256] = {
+{
+  0x00000063, 0x0000007c, 0x00000077, 0x0000007b,
+  0x000000f2, 0x0000006b, 0x0000006f, 0x000000c5,
+  0x00000030, 0x00000001, 0x00000067, 0x0000002b,
+  0x000000fe, 0x000000d7, 0x000000ab, 0x00000076,
+  0x000000ca, 0x00000082, 0x000000c9, 0x0000007d,
+  0x000000fa, 0x00000059, 0x00000047, 0x000000f0,
+  0x000000ad, 0x000000d4, 0x000000a2, 0x000000af,
+  0x0000009c, 0x000000a4, 0x00000072, 0x000000c0,
+  0x000000b7, 0x000000fd, 0x00000093, 0x00000026,
+  0x00000036, 0x0000003f, 0x000000f7, 0x000000cc,
+  0x00000034, 0x000000a5, 0x000000e5, 0x000000f1,
+  0x00000071, 0x000000d8, 0x00000031, 0x00000015,
+  0x00000004, 0x000000c7, 0x00000023, 0x000000c3,
+  0x00000018, 0x00000096, 0x00000005, 0x0000009a,
+  0x00000007, 0x00000012, 0x00000080, 0x000000e2,
+  0x000000eb, 0x00000027, 0x000000b2, 0x00000075,
+  0x00000009, 0x00000083, 0x0000002c, 0x0000001a,
+  0x0000001b, 0x0000006e, 0x0000005a, 0x000000a0,
+  0x00000052, 0x0000003b, 0x000000d6, 0x000000b3,
+  0x00000029, 0x000000e3, 0x0000002f, 0x00000084,
+  0x00000053, 0x000000d1, 0x00000000, 0x000000ed,
+  0x00000020, 0x000000fc, 0x000000b1, 0x0000005b,
+  0x0000006a, 0x000000cb, 0x000000be, 0x00000039,
+  0x0000004a, 0x0000004c, 0x00000058, 0x000000cf,
+  0x000000d0, 0x000000ef, 0x000000aa, 0x000000fb,
+  0x00000043, 0x0000004d, 0x00000033, 0x00000085,
+  0x00000045, 0x000000f9, 0x00000002, 0x0000007f,
+  0x00000050, 0x0000003c, 0x0000009f, 0x000000a8,
+  0x00000051, 0x000000a3, 0x00000040, 0x0000008f,
+  0x00000092, 0x0000009d, 0x00000038, 0x000000f5,
+  0x000000bc, 0x000000b6, 0x000000da, 0x00000021,
+  0x00000010, 0x000000ff, 0x000000f3, 0x000000d2,
+  0x000000cd, 0x0000000c, 0x00000013, 0x000000ec,
+  0x0000005f, 0x00000097, 0x00000044, 0x00000017,
+  0x000000c4, 0x000000a7, 0x0000007e, 0x0000003d,
+  0x00000064, 0x0000005d, 0x00000019, 0x00000073,
+  0x00000060, 0x00000081, 0x0000004f, 0x000000dc,
+  0x00000022, 0x0000002a, 0x00000090, 0x00000088,
+  0x00000046, 0x000000ee, 0x000000b8, 0x00000014,
+  0x000000de, 0x0000005e, 0x0000000b, 0x000000db,
+  0x000000e0, 0x00000032, 0x0000003a, 0x0000000a,
+  0x00000049, 0x00000006, 0x00000024, 0x0000005c,
+  0x000000c2, 0x000000d3, 0x000000ac, 0x00000062,
+  0x00000091, 0x00000095, 0x000000e4, 0x00000079,
+  0x000000e7, 0x000000c8, 0x00000037, 0x0000006d,
+  0x0000008d, 0x000000d5, 0x0000004e, 0x000000a9,
+  0x0000006c, 0x00000056, 0x000000f4, 0x000000ea,
+  0x00000065, 0x0000007a, 0x000000ae, 0x00000008,
+  0x000000ba, 0x00000078, 0x00000025, 0x0000002e,
+  0x0000001c, 0x000000a6, 0x000000b4, 0x000000c6,
+  0x000000e8, 0x000000dd, 0x00000074, 0x0000001f,
+  0x0000004b, 0x000000bd, 0x0000008b, 0x0000008a,
+  0x00000070, 0x0000003e, 0x000000b5, 0x00000066,
+  0x00000048, 0x00000003, 0x000000f6, 0x0000000e,
+  0x00000061, 0x00000035, 0x00000057, 0x000000b9,
+  0x00000086, 0x000000c1, 0x0000001d, 0x0000009e,
+  0x000000e1, 0x000000f8, 0x00000098, 0x00000011,
+  0x00000069, 0x000000d9, 0x0000008e, 0x00000094,
+  0x0000009b, 0x0000001e, 0x00000087, 0x000000e9,
+  0x000000ce, 0x00000055, 0x00000028, 0x000000df,
+  0x0000008c, 0x000000a1, 0x00000089, 0x0000000d,
+  0x000000bf, 0x000000e6, 0x00000042, 0x00000068,
+  0x00000041, 0x00000099, 0x0000002d, 0x0000000f,
+  0x000000b0, 0x00000054, 0x000000bb, 0x00000016
+}, {
+  0x00006300, 0x00007c00, 0x00007700, 0x00007b00,
+  0x0000f200, 0x00006b00, 0x00006f00, 0x0000c500,
+  0x00003000, 0x00000100, 0x00006700, 0x00002b00,
+  0x0000fe00, 0x0000d700, 0x0000ab00, 0x00007600,
+  0x0000ca00, 0x00008200, 0x0000c900, 0x00007d00,
+  0x0000fa00, 0x00005900, 0x00004700, 0x0000f000,
+  0x0000ad00, 0x0000d400, 0x0000a200, 0x0000af00,
+  0x00009c00, 0x0000a400, 0x00007200, 0x0000c000,
+  0x0000b700, 0x0000fd00, 0x00009300, 0x00002600,
+  0x00003600, 0x00003f00, 0x0000f700, 0x0000cc00,
+  0x00003400, 0x0000a500, 0x0000e500, 0x0000f100,
+  0x00007100, 0x0000d800, 0x00003100, 0x00001500,
+  0x00000400, 0x0000c700, 0x00002300, 0x0000c300,
+  0x00001800, 0x00009600, 0x00000500, 0x00009a00,
+  0x00000700, 0x00001200, 0x00008000, 0x0000e200,
+  0x0000eb00, 0x00002700, 0x0000b200, 0x00007500,
+  0x00000900, 0x00008300, 0x00002c00, 0x00001a00,
+  0x00001b00, 0x00006e00, 0x00005a00, 0x0000a000,
+  0x00005200, 0x00003b00, 0x0000d600, 0x0000b300,
+  0x00002900, 0x0000e300, 0x00002f00, 0x00008400,
+  0x00005300, 0x0000d100, 0x00000000, 0x0000ed00,
+  0x00002000, 0x0000fc00, 0x0000b100, 0x00005b00,
+  0x00006a00, 0x0000cb00, 0x0000be00, 0x00003900,
+  0x00004a00, 0x00004c00, 0x00005800, 0x0000cf00,
+  0x0000d000, 0x0000ef00, 0x0000aa00, 0x0000fb00,
+  0x00004300, 0x00004d00, 0x00003300, 0x00008500,
+  0x00004500, 0x0000f900, 0x00000200, 0x00007f00,
+  0x00005000, 0x00003c00, 0x00009f00, 0x0000a800,
+  0x00005100, 0x0000a300, 0x00004000, 0x00008f00,
+  0x00009200, 0x00009d00, 0x00003800, 0x0000f500,
+  0x0000bc00, 0x0000b600, 0x0000da00, 0x00002100,
+  0x00001000, 0x0000ff00, 0x0000f300, 0x0000d200,
+  0x0000cd00, 0x00000c00, 0x00001300, 0x0000ec00,
+  0x00005f00, 0x00009700, 0x00004400, 0x00001700,
+  0x0000c400, 0x0000a700, 0x00007e00, 0x00003d00,
+  0x00006400, 0x00005d00, 0x00001900, 0x00007300,
+  0x00006000, 0x00008100, 0x00004f00, 0x0000dc00,
+  0x00002200, 0x00002a00, 0x00009000, 0x00008800,
+  0x00004600, 0x0000ee00, 0x0000b800, 0x00001400,
+  0x0000de00, 0x00005e00, 0x00000b00, 0x0000db00,
+  0x0000e000, 0x00003200, 0x00003a00, 0x00000a00,
+  0x00004900, 0x00000600, 0x00002400, 0x00005c00,
+  0x0000c200, 0x0000d300, 0x0000ac00, 0x00006200,
+  0x00009100, 0x00009500, 0x0000e400, 0x00007900,
+  0x0000e700, 0x0000c800, 0x00003700, 0x00006d00,
+  0x00008d00, 0x0000d500, 0x00004e00, 0x0000a900,
+  0x00006c00, 0x00005600, 0x0000f400, 0x0000ea00,
+  0x00006500, 0x00007a00, 0x0000ae00, 0x00000800,
+  0x0000ba00, 0x00007800, 0x00002500, 0x00002e00,
+  0x00001c00, 0x0000a600, 0x0000b400, 0x0000c600,
+  0x0000e800, 0x0000dd00, 0x00007400, 0x00001f00,
+  0x00004b00, 0x0000bd00, 0x00008b00, 0x00008a00,
+  0x00007000, 0x00003e00, 0x0000b500, 0x00006600,
+  0x00004800, 0x00000300, 0x0000f600, 0x00000e00,
+  0x00006100, 0x00003500, 0x00005700, 0x0000b900,
+  0x00008600, 0x0000c100, 0x00001d00, 0x00009e00,
+  0x0000e100, 0x0000f800, 0x00009800, 0x00001100,
+  0x00006900, 0x0000d900, 0x00008e00, 0x00009400,
+  0x00009b00, 0x00001e00, 0x00008700, 0x0000e900,
+  0x0000ce00, 0x00005500, 0x00002800, 0x0000df00,
+  0x00008c00, 0x0000a100, 0x00008900, 0x00000d00,
+  0x0000bf00, 0x0000e600, 0x00004200, 0x00006800,
+  0x00004100, 0x00009900, 0x00002d00, 0x00000f00,
+  0x0000b000, 0x00005400, 0x0000bb00, 0x00001600
+}, {
+  0x00630000, 0x007c0000, 0x00770000, 0x007b0000,
+  0x00f20000, 0x006b0000, 0x006f0000, 0x00c50000,
+  0x00300000, 0x00010000, 0x00670000, 0x002b0000,
+  0x00fe0000, 0x00d70000, 0x00ab0000, 0x00760000,
+  0x00ca0000, 0x00820000, 0x00c90000, 0x007d0000,
+  0x00fa0000, 0x00590000, 0x00470000, 0x00f00000,
+  0x00ad0000, 0x00d40000, 0x00a20000, 0x00af0000,
+  0x009c0000, 0x00a40000, 0x00720000, 0x00c00000,
+  0x00b70000, 0x00fd0000, 0x00930000, 0x00260000,
+  0x00360000, 0x003f0000, 0x00f70000, 0x00cc0000,
+  0x00340000, 0x00a50000, 0x00e50000, 0x00f10000,
+  0x00710000, 0x00d80000, 0x00310000, 0x00150000,
+  0x00040000, 0x00c70000, 0x00230000, 0x00c30000,
+  0x00180000, 0x00960000, 0x00050000, 0x009a0000,
+  0x00070000, 0x00120000, 0x00800000, 0x00e20000,
+  0x00eb0000, 0x00270000, 0x00b20000, 0x00750000,
+  0x00090000, 0x00830000, 0x002c0000, 0x001a0000,
+  0x001b0000, 0x006e0000, 0x005a0000, 0x00a00000,
+  0x00520000, 0x003b0000, 0x00d60000, 0x00b30000,
+  0x00290000, 0x00e30000, 0x002f0000, 0x00840000,
+  0x00530000, 0x00d10000, 0x00000000, 0x00ed0000,
+  0x00200000, 0x00fc0000, 0x00b10000, 0x005b0000,
+  0x006a0000, 0x00cb0000, 0x00be0000, 0x00390000,
+  0x004a0000, 0x004c0000, 0x00580000, 0x00cf0000,
+  0x00d00000, 0x00ef0000, 0x00aa0000, 0x00fb0000,
+  0x00430000, 0x004d0000, 0x00330000, 0x00850000,
+  0x00450000, 0x00f90000, 0x00020000, 0x007f0000,
+  0x00500000, 0x003c0000, 0x009f0000, 0x00a80000,
+  0x00510000, 0x00a30000, 0x00400000, 0x008f0000,
+  0x00920000, 0x009d0000, 0x00380000, 0x00f50000,
+  0x00bc0000, 0x00b60000, 0x00da0000, 0x00210000,
+  0x00100000, 0x00ff0000, 0x00f30000, 0x00d20000,
+  0x00cd0000, 0x000c0000, 0x00130000, 0x00ec0000,
+  0x005f0000, 0x00970000, 0x00440000, 0x00170000,
+  0x00c40000, 0x00a70000, 0x007e0000, 0x003d0000,
+  0x00640000, 0x005d0000, 0x00190000, 0x00730000,
+  0x00600000, 0x00810000, 0x004f0000, 0x00dc0000,
+  0x00220000, 0x002a0000, 0x00900000, 0x00880000,
+  0x00460000, 0x00ee0000, 0x00b80000, 0x00140000,
+  0x00de0000, 0x005e0000, 0x000b0000, 0x00db0000,
+  0x00e00000, 0x00320000, 0x003a0000, 0x000a0000,
+  0x00490000, 0x00060000, 0x00240000, 0x005c0000,
+  0x00c20000, 0x00d30000, 0x00ac0000, 0x00620000,
+  0x00910000, 0x00950000, 0x00e40000, 0x00790000,
+  0x00e70000, 0x00c80000, 0x00370000, 0x006d0000,
+  0x008d0000, 0x00d50000, 0x004e0000, 0x00a90000,
+  0x006c0000, 0x00560000, 0x00f40000, 0x00ea0000,
+  0x00650000, 0x007a0000, 0x00ae0000, 0x00080000,
+  0x00ba0000, 0x00780000, 0x00250000, 0x002e0000,
+  0x001c0000, 0x00a60000, 0x00b40000, 0x00c60000,
+  0x00e80000, 0x00dd0000, 0x00740000, 0x001f0000,
+  0x004b0000, 0x00bd0000, 0x008b0000, 0x008a0000,
+  0x00700000, 0x003e0000, 0x00b50000, 0x00660000,
+  0x00480000, 0x00030000, 0x00f60000, 0x000e0000,
+  0x00610000, 0x00350000, 0x00570000, 0x00b90000,
+  0x00860000, 0x00c10000, 0x001d0000, 0x009e0000,
+  0x00e10000, 0x00f80000, 0x00980000, 0x00110000,
+  0x00690000, 0x00d90000, 0x008e0000, 0x00940000,
+  0x009b0000, 0x001e0000, 0x00870000, 0x00e90000,
+  0x00ce0000, 0x00550000, 0x00280000, 0x00df0000,
+  0x008c0000, 0x00a10000, 0x00890000, 0x000d0000,
+  0x00bf0000, 0x00e60000, 0x00420000, 0x00680000,
+  0x00410000, 0x00990000, 0x002d0000, 0x000f0000,
+  0x00b00000, 0x00540000, 0x00bb0000, 0x00160000
+}, {
+  0x63000000, 0x7c000000, 0x77000000, 0x7b000000,
+  0xf2000000, 0x6b000000, 0x6f000000, 0xc5000000,
+  0x30000000, 0x01000000, 0x67000000, 0x2b000000,
+  0xfe000000, 0xd7000000, 0xab000000, 0x76000000,
+  0xca000000, 0x82000000, 0xc9000000, 0x7d000000,
+  0xfa000000, 0x59000000, 0x47000000, 0xf0000000,
+  0xad000000, 0xd4000000, 0xa2000000, 0xaf000000,
+  0x9c000000, 0xa4000000, 0x72000000, 0xc0000000,
+  0xb7000000, 0xfd000000, 0x93000000, 0x26000000,
+  0x36000000, 0x3f000000, 0xf7000000, 0xcc000000,
+  0x34000000, 0xa5000000, 0xe5000000, 0xf1000000,
+  0x71000000, 0xd8000000, 0x31000000, 0x15000000,
+  0x04000000, 0xc7000000, 0x23000000, 0xc3000000,
+  0x18000000, 0x96000000, 0x05000000, 0x9a000000,
+  0x07000000, 0x12000000, 0x80000000, 0xe2000000,
+  0xeb000000, 0x27000000, 0xb2000000, 0x75000000,
+  0x09000000, 0x83000000, 0x2c000000, 0x1a000000,
+  0x1b000000, 0x6e000000, 0x5a000000, 0xa0000000,
+  0x52000000, 0x3b000000, 0xd6000000, 0xb3000000,
+  0x29000000, 0xe3000000, 0x2f000000, 0x84000000,
+  0x53000000, 0xd1000000, 0x00000000, 0xed000000,
+  0x20000000, 0xfc000000, 0xb1000000, 0x5b000000,
+  0x6a000000, 0xcb000000, 0xbe000000, 0x39000000,
+  0x4a000000, 0x4c000000, 0x58000000, 0xcf000000,
+  0xd0000000, 0xef000000, 0xaa000000, 0xfb000000,
+  0x43000000, 0x4d000000, 0x33000000, 0x85000000,
+  0x45000000, 0xf9000000, 0x02000000, 0x7f000000,
+  0x50000000, 0x3c000000, 0x9f000000, 0xa8000000,
+  0x51000000, 0xa3000000, 0x40000000, 0x8f000000,
+  0x92000000, 0x9d000000, 0x38000000, 0xf5000000,
+  0xbc000000, 0xb6000000, 0xda000000, 0x21000000,
+  0x10000000, 0xff000000, 0xf3000000, 0xd2000000,
+  0xcd000000, 0x0c000000, 0x13000000, 0xec000000,
+  0x5f000000, 0x97000000, 0x44000000, 0x17000000,
+  0xc4000000, 0xa7000000, 0x7e000000, 0x3d000000,
+  0x64000000, 0x5d000000, 0x19000000, 0x73000000,
+  0x60000000, 0x81000000, 0x4f000000, 0xdc000000,
+  0x22000000, 0x2a000000, 0x90000000, 0x88000000,
+  0x46000000, 0xee000000, 0xb8000000, 0x14000000,
+  0xde000000, 0x5e000000, 0x0b000000, 0xdb000000,
+  0xe0000000, 0x32000000, 0x3a000000, 0x0a000000,
+  0x49000000, 0x06000000, 0x24000000, 0x5c000000,
+  0xc2000000, 0xd3000000, 0xac000000, 0x62000000,
+  0x91000000, 0x95000000, 0xe4000000, 0x79000000,
+  0xe7000000, 0xc8000000, 0x37000000, 0x6d000000,
+  0x8d000000, 0xd5000000, 0x4e000000, 0xa9000000,
+  0x6c000000, 0x56000000, 0xf4000000, 0xea000000,
+  0x65000000, 0x7a000000, 0xae000000, 0x08000000,
+  0xba000000, 0x78000000, 0x25000000, 0x2e000000,
+  0x1c000000, 0xa6000000, 0xb4000000, 0xc6000000,
+  0xe8000000, 0xdd000000, 0x74000000, 0x1f000000,
+  0x4b000000, 0xbd000000, 0x8b000000, 0x8a000000,
+  0x70000000, 0x3e000000, 0xb5000000, 0x66000000,
+  0x48000000, 0x03000000, 0xf6000000, 0x0e000000,
+  0x61000000, 0x35000000, 0x57000000, 0xb9000000,
+  0x86000000, 0xc1000000, 0x1d000000, 0x9e000000,
+  0xe1000000, 0xf8000000, 0x98000000, 0x11000000,
+  0x69000000, 0xd9000000, 0x8e000000, 0x94000000,
+  0x9b000000, 0x1e000000, 0x87000000, 0xe9000000,
+  0xce000000, 0x55000000, 0x28000000, 0xdf000000,
+  0x8c000000, 0xa1000000, 0x89000000, 0x0d000000,
+  0xbf000000, 0xe6000000, 0x42000000, 0x68000000,
+  0x41000000, 0x99000000, 0x2d000000, 0x0f000000,
+  0xb0000000, 0x54000000, 0xbb000000, 0x16000000
+}
+};
+
+static const u4byte  il_tab[4][256] = {
+{
+  0x00000052, 0x00000009, 0x0000006a, 0x000000d5,
+  0x00000030, 0x00000036, 0x000000a5, 0x00000038,
+  0x000000bf, 0x00000040, 0x000000a3, 0x0000009e,
+  0x00000081, 0x000000f3, 0x000000d7, 0x000000fb,
+  0x0000007c, 0x000000e3, 0x00000039, 0x00000082,
+  0x0000009b, 0x0000002f, 0x000000ff, 0x00000087,
+  0x00000034, 0x0000008e, 0x00000043, 0x00000044,
+  0x000000c4, 0x000000de, 0x000000e9, 0x000000cb,
+  0x00000054, 0x0000007b, 0x00000094, 0x00000032,
+  0x000000a6, 0x000000c2, 0x00000023, 0x0000003d,
+  0x000000ee, 0x0000004c, 0x00000095, 0x0000000b,
+  0x00000042, 0x000000fa, 0x000000c3, 0x0000004e,
+  0x00000008, 0x0000002e, 0x000000a1, 0x00000066,
+  0x00000028, 0x000000d9, 0x00000024, 0x000000b2,
+  0x00000076, 0x0000005b, 0x000000a2, 0x00000049,
+  0x0000006d, 0x0000008b, 0x000000d1, 0x00000025,
+  0x00000072, 0x000000f8, 0x000000f6, 0x00000064,
+  0x00000086, 0x00000068, 0x00000098, 0x00000016,
+  0x000000d4, 0x000000a4, 0x0000005c, 0x000000cc,
+  0x0000005d, 0x00000065, 0x000000b6, 0x00000092,
+  0x0000006c, 0x00000070, 0x00000048, 0x00000050,
+  0x000000fd, 0x000000ed, 0x000000b9, 0x000000da,
+  0x0000005e, 0x00000015, 0x00000046, 0x00000057,
+  0x000000a7, 0x0000008d, 0x0000009d, 0x00000084,
+  0x00000090, 0x000000d8, 0x000000ab, 0x00000000,
+  0x0000008c, 0x000000bc, 0x000000d3, 0x0000000a,
+  0x000000f7, 0x000000e4, 0x00000058, 0x00000005,
+  0x000000b8, 0x000000b3, 0x00000045, 0x00000006,
+  0x000000d0, 0x0000002c, 0x0000001e, 0x0000008f,
+  0x000000ca, 0x0000003f, 0x0000000f, 0x00000002,
+  0x000000c1, 0x000000af, 0x000000bd, 0x00000003,
+  0x00000001, 0x00000013, 0x0000008a, 0x0000006b,
+  0x0000003a, 0x00000091, 0x00000011, 0x00000041,
+  0x0000004f, 0x00000067, 0x000000dc, 0x000000ea,
+  0x00000097, 0x000000f2, 0x000000cf, 0x000000ce,
+  0x000000f0, 0x000000b4, 0x000000e6, 0x00000073,
+  0x00000096, 0x000000ac, 0x00000074, 0x00000022,
+  0x000000e7, 0x000000ad, 0x00000035, 0x00000085,
+  0x000000e2, 0x000000f9, 0x00000037, 0x000000e8,
+  0x0000001c, 0x00000075, 0x000000df, 0x0000006e,
+  0x00000047, 0x000000f1, 0x0000001a, 0x00000071,
+  0x0000001d, 0x00000029, 0x000000c5, 0x00000089,
+  0x0000006f, 0x000000b7, 0x00000062, 0x0000000e,
+  0x000000aa, 0x00000018, 0x000000be, 0x0000001b,
+  0x000000fc, 0x00000056, 0x0000003e, 0x0000004b,
+  0x000000c6, 0x000000d2, 0x00000079, 0x00000020,
+  0x0000009a, 0x000000db, 0x000000c0, 0x000000fe,
+  0x00000078, 0x000000cd, 0x0000005a, 0x000000f4,
+  0x0000001f, 0x000000dd, 0x000000a8, 0x00000033,
+  0x00000088, 0x00000007, 0x000000c7, 0x00000031,
+  0x000000b1, 0x00000012, 0x00000010, 0x00000059,
+  0x00000027, 0x00000080, 0x000000ec, 0x0000005f,
+  0x00000060, 0x00000051, 0x0000007f, 0x000000a9,
+  0x00000019, 0x000000b5, 0x0000004a, 0x0000000d,
+  0x0000002d, 0x000000e5, 0x0000007a, 0x0000009f,
+  0x00000093, 0x000000c9, 0x0000009c, 0x000000ef,
+  0x000000a0, 0x000000e0, 0x0000003b, 0x0000004d,
+  0x000000ae, 0x0000002a, 0x000000f5, 0x000000b0,
+  0x000000c8, 0x000000eb, 0x000000bb, 0x0000003c,
+  0x00000083, 0x00000053, 0x00000099, 0x00000061,
+  0x00000017, 0x0000002b, 0x00000004, 0x0000007e,
+  0x000000ba, 0x00000077, 0x000000d6, 0x00000026,
+  0x000000e1, 0x00000069, 0x00000014, 0x00000063,
+  0x00000055, 0x00000021, 0x0000000c, 0x0000007d
+}, {
+  0x00005200, 0x00000900, 0x00006a00, 0x0000d500,
+  0x00003000, 0x00003600, 0x0000a500, 0x00003800,
+  0x0000bf00, 0x00004000, 0x0000a300, 0x00009e00,
+  0x00008100, 0x0000f300, 0x0000d700, 0x0000fb00,
+  0x00007c00, 0x0000e300, 0x00003900, 0x00008200,
+  0x00009b00, 0x00002f00, 0x0000ff00, 0x00008700,
+  0x00003400, 0x00008e00, 0x00004300, 0x00004400,
+  0x0000c400, 0x0000de00, 0x0000e900, 0x0000cb00,
+  0x00005400, 0x00007b00, 0x00009400, 0x00003200,
+  0x0000a600, 0x0000c200, 0x00002300, 0x00003d00,
+  0x0000ee00, 0x00004c00, 0x00009500, 0x00000b00,
+  0x00004200, 0x0000fa00, 0x0000c300, 0x00004e00,
+  0x00000800, 0x00002e00, 0x0000a100, 0x00006600,
+  0x00002800, 0x0000d900, 0x00002400, 0x0000b200,
+  0x00007600, 0x00005b00, 0x0000a200, 0x00004900,
+  0x00006d00, 0x00008b00, 0x0000d100, 0x00002500,
+  0x00007200, 0x0000f800, 0x0000f600, 0x00006400,
+  0x00008600, 0x00006800, 0x00009800, 0x00001600,
+  0x0000d400, 0x0000a400, 0x00005c00, 0x0000cc00,
+  0x00005d00, 0x00006500, 0x0000b600, 0x00009200,
+  0x00006c00, 0x00007000, 0x00004800, 0x00005000,
+  0x0000fd00, 0x0000ed00, 0x0000b900, 0x0000da00,
+  0x00005e00, 0x00001500, 0x00004600, 0x00005700,
+  0x0000a700, 0x00008d00, 0x00009d00, 0x00008400,
+  0x00009000, 0x0000d800, 0x0000ab00, 0x00000000,
+  0x00008c00, 0x0000bc00, 0x0000d300, 0x00000a00,
+  0x0000f700, 0x0000e400, 0x00005800, 0x00000500,
+  0x0000b800, 0x0000b300, 0x00004500, 0x00000600,
+  0x0000d000, 0x00002c00, 0x00001e00, 0x00008f00,
+  0x0000ca00, 0x00003f00, 0x00000f00, 0x00000200,
+  0x0000c100, 0x0000af00, 0x0000bd00, 0x00000300,
+  0x00000100, 0x00001300, 0x00008a00, 0x00006b00,
+  0x00003a00, 0x00009100, 0x00001100, 0x00004100,
+  0x00004f00, 0x00006700, 0x0000dc00, 0x0000ea00,
+  0x00009700, 0x0000f200, 0x0000cf00, 0x0000ce00,
+  0x0000f000, 0x0000b400, 0x0000e600, 0x00007300,
+  0x00009600, 0x0000ac00, 0x00007400, 0x00002200,
+  0x0000e700, 0x0000ad00, 0x00003500, 0x00008500,
+  0x0000e200, 0x0000f900, 0x00003700, 0x0000e800,
+  0x00001c00, 0x00007500, 0x0000df00, 0x00006e00,
+  0x00004700, 0x0000f100, 0x00001a00, 0x00007100,
+  0x00001d00, 0x00002900, 0x0000c500, 0x00008900,
+  0x00006f00, 0x0000b700, 0x00006200, 0x00000e00,
+  0x0000aa00, 0x00001800, 0x0000be00, 0x00001b00,
+  0x0000fc00, 0x00005600, 0x00003e00, 0x00004b00,
+  0x0000c600, 0x0000d200, 0x00007900, 0x00002000,
+  0x00009a00, 0x0000db00, 0x0000c000, 0x0000fe00,
+  0x00007800, 0x0000cd00, 0x00005a00, 0x0000f400,
+  0x00001f00, 0x0000dd00, 0x0000a800, 0x00003300,
+  0x00008800, 0x00000700, 0x0000c700, 0x00003100,
+  0x0000b100, 0x00001200, 0x00001000, 0x00005900,
+  0x00002700, 0x00008000, 0x0000ec00, 0x00005f00,
+  0x00006000, 0x00005100, 0x00007f00, 0x0000a900,
+  0x00001900, 0x0000b500, 0x00004a00, 0x00000d00,
+  0x00002d00, 0x0000e500, 0x00007a00, 0x00009f00,
+  0x00009300, 0x0000c900, 0x00009c00, 0x0000ef00,
+  0x0000a000, 0x0000e000, 0x00003b00, 0x00004d00,
+  0x0000ae00, 0x00002a00, 0x0000f500, 0x0000b000,
+  0x0000c800, 0x0000eb00, 0x0000bb00, 0x00003c00,
+  0x00008300, 0x00005300, 0x00009900, 0x00006100,
+  0x00001700, 0x00002b00, 0x00000400, 0x00007e00,
+  0x0000ba00, 0x00007700, 0x0000d600, 0x00002600,
+  0x0000e100, 0x00006900, 0x00001400, 0x00006300,
+  0x00005500, 0x00002100, 0x00000c00, 0x00007d00
+}, {
+  0x00520000, 0x00090000, 0x006a0000, 0x00d50000,
+  0x00300000, 0x00360000, 0x00a50000, 0x00380000,
+  0x00bf0000, 0x00400000, 0x00a30000, 0x009e0000,
+  0x00810000, 0x00f30000, 0x00d70000, 0x00fb0000,
+  0x007c0000, 0x00e30000, 0x00390000, 0x00820000,
+  0x009b0000, 0x002f0000, 0x00ff0000, 0x00870000,
+  0x00340000, 0x008e0000, 0x00430000, 0x00440000,
+  0x00c40000, 0x00de0000, 0x00e90000, 0x00cb0000,
+  0x00540000, 0x007b0000, 0x00940000, 0x00320000,
+  0x00a60000, 0x00c20000, 0x00230000, 0x003d0000,
+  0x00ee0000, 0x004c0000, 0x00950000, 0x000b0000,
+  0x00420000, 0x00fa0000, 0x00c30000, 0x004e0000,
+  0x00080000, 0x002e0000, 0x00a10000, 0x00660000,
+  0x00280000, 0x00d90000, 0x00240000, 0x00b20000,
+  0x00760000, 0x005b0000, 0x00a20000, 0x00490000,
+  0x006d0000, 0x008b0000, 0x00d10000, 0x00250000,
+  0x00720000, 0x00f80000, 0x00f60000, 0x00640000,
+  0x00860000, 0x00680000, 0x00980000, 0x00160000,
+  0x00d40000, 0x00a40000, 0x005c0000, 0x00cc0000,
+  0x005d0000, 0x00650000, 0x00b60000, 0x00920000,
+  0x006c0000, 0x00700000, 0x00480000, 0x00500000,
+  0x00fd0000, 0x00ed0000, 0x00b90000, 0x00da0000,
+  0x005e0000, 0x00150000, 0x00460000, 0x00570000,
+  0x00a70000, 0x008d0000, 0x009d0000, 0x00840000,
+  0x00900000, 0x00d80000, 0x00ab0000, 0x00000000,
+  0x008c0000, 0x00bc0000, 0x00d30000, 0x000a0000,
+  0x00f70000, 0x00e40000, 0x00580000, 0x00050000,
+  0x00b80000, 0x00b30000, 0x00450000, 0x00060000,
+  0x00d00000, 0x002c0000, 0x001e0000, 0x008f0000,
+  0x00ca0000, 0x003f0000, 0x000f0000, 0x00020000,
+  0x00c10000, 0x00af0000, 0x00bd0000, 0x00030000,
+  0x00010000, 0x00130000, 0x008a0000, 0x006b0000,
+  0x003a0000, 0x00910000, 0x00110000, 0x00410000,
+  0x004f0000, 0x00670000, 0x00dc0000, 0x00ea0000,
+  0x00970000, 0x00f20000, 0x00cf0000, 0x00ce0000,
+  0x00f00000, 0x00b40000, 0x00e60000, 0x00730000,
+  0x00960000, 0x00ac0000, 0x00740000, 0x00220000,
+  0x00e70000, 0x00ad0000, 0x00350000, 0x00850000,
+  0x00e20000, 0x00f90000, 0x00370000, 0x00e80000,
+  0x001c0000, 0x00750000, 0x00df0000, 0x006e0000,
+  0x00470000, 0x00f10000, 0x001a0000, 0x00710000,
+  0x001d0000, 0x00290000, 0x00c50000, 0x00890000,
+  0x006f0000, 0x00b70000, 0x00620000, 0x000e0000,
+  0x00aa0000, 0x00180000, 0x00be0000, 0x001b0000,
+  0x00fc0000, 0x00560000, 0x003e0000, 0x004b0000,
+  0x00c60000, 0x00d20000, 0x00790000, 0x00200000,
+  0x009a0000, 0x00db0000, 0x00c00000, 0x00fe0000,
+  0x00780000, 0x00cd0000, 0x005a0000, 0x00f40000,
+  0x001f0000, 0x00dd0000, 0x00a80000, 0x00330000,
+  0x00880000, 0x00070000, 0x00c70000, 0x00310000,
+  0x00b10000, 0x00120000, 0x00100000, 0x00590000,
+  0x00270000, 0x00800000, 0x00ec0000, 0x005f0000,
+  0x00600000, 0x00510000, 0x007f0000, 0x00a90000,
+  0x00190000, 0x00b50000, 0x004a0000, 0x000d0000,
+  0x002d0000, 0x00e50000, 0x007a0000, 0x009f0000,
+  0x00930000, 0x00c90000, 0x009c0000, 0x00ef0000,
+  0x00a00000, 0x00e00000, 0x003b0000, 0x004d0000,
+  0x00ae0000, 0x002a0000, 0x00f50000, 0x00b00000,
+  0x00c80000, 0x00eb0000, 0x00bb0000, 0x003c0000,
+  0x00830000, 0x00530000, 0x00990000, 0x00610000,
+  0x00170000, 0x002b0000, 0x00040000, 0x007e0000,
+  0x00ba0000, 0x00770000, 0x00d60000, 0x00260000,
+  0x00e10000, 0x00690000, 0x00140000, 0x00630000,
+  0x00550000, 0x00210000, 0x000c0000, 0x007d0000
+}, {
+  0x52000000, 0x09000000, 0x6a000000, 0xd5000000,
+  0x30000000, 0x36000000, 0xa5000000, 0x38000000,
+  0xbf000000, 0x40000000, 0xa3000000, 0x9e000000,
+  0x81000000, 0xf3000000, 0xd7000000, 0xfb000000,
+  0x7c000000, 0xe3000000, 0x39000000, 0x82000000,
+  0x9b000000, 0x2f000000, 0xff000000, 0x87000000,
+  0x34000000, 0x8e000000, 0x43000000, 0x44000000,
+  0xc4000000, 0xde000000, 0xe9000000, 0xcb000000,
+  0x54000000, 0x7b000000, 0x94000000, 0x32000000,
+  0xa6000000, 0xc2000000, 0x23000000, 0x3d000000,
+  0xee000000, 0x4c000000, 0x95000000, 0x0b000000,
+  0x42000000, 0xfa000000, 0xc3000000, 0x4e000000,
+  0x08000000, 0x2e000000, 0xa1000000, 0x66000000,
+  0x28000000, 0xd9000000, 0x24000000, 0xb2000000,
+  0x76000000, 0x5b000000, 0xa2000000, 0x49000000,
+  0x6d000000, 0x8b000000, 0xd1000000, 0x25000000,
+  0x72000000, 0xf8000000, 0xf6000000, 0x64000000,
+  0x86000000, 0x68000000, 0x98000000, 0x16000000,
+  0xd4000000, 0xa4000000, 0x5c000000, 0xcc000000,
+  0x5d000000, 0x65000000, 0xb6000000, 0x92000000,
+  0x6c000000, 0x70000000, 0x48000000, 0x50000000,
+  0xfd000000, 0xed000000, 0xb9000000, 0xda000000,
+  0x5e000000, 0x15000000, 0x46000000, 0x57000000,
+  0xa7000000, 0x8d000000, 0x9d000000, 0x84000000,
+  0x90000000, 0xd8000000, 0xab000000, 0x00000000,
+  0x8c000000, 0xbc000000, 0xd3000000, 0x0a000000,
+  0xf7000000, 0xe4000000, 0x58000000, 0x05000000,
+  0xb8000000, 0xb3000000, 0x45000000, 0x06000000,
+  0xd0000000, 0x2c000000, 0x1e000000, 0x8f000000,
+  0xca000000, 0x3f000000, 0x0f000000, 0x02000000,
+  0xc1000000, 0xaf000000, 0xbd000000, 0x03000000,
+  0x01000000, 0x13000000, 0x8a000000, 0x6b000000,
+  0x3a000000, 0x91000000, 0x11000000, 0x41000000,
+  0x4f000000, 0x67000000, 0xdc000000, 0xea000000,
+  0x97000000, 0xf2000000, 0xcf000000, 0xce000000,
+  0xf0000000, 0xb4000000, 0xe6000000, 0x73000000,
+  0x96000000, 0xac000000, 0x74000000, 0x22000000,
+  0xe7000000, 0xad000000, 0x35000000, 0x85000000,
+  0xe2000000, 0xf9000000, 0x37000000, 0xe8000000,
+  0x1c000000, 0x75000000, 0xdf000000, 0x6e000000,
+  0x47000000, 0xf1000000, 0x1a000000, 0x71000000,
+  0x1d000000, 0x29000000, 0xc5000000, 0x89000000,
+  0x6f000000, 0xb7000000, 0x62000000, 0x0e000000,
+  0xaa000000, 0x18000000, 0xbe000000, 0x1b000000,
+  0xfc000000, 0x56000000, 0x3e000000, 0x4b000000,
+  0xc6000000, 0xd2000000, 0x79000000, 0x20000000,
+  0x9a000000, 0xdb000000, 0xc0000000, 0xfe000000,
+  0x78000000, 0xcd000000, 0x5a000000, 0xf4000000,
+  0x1f000000, 0xdd000000, 0xa8000000, 0x33000000,
+  0x88000000, 0x07000000, 0xc7000000, 0x31000000,
+  0xb1000000, 0x12000000, 0x10000000, 0x59000000,
+  0x27000000, 0x80000000, 0xec000000, 0x5f000000,
+  0x60000000, 0x51000000, 0x7f000000, 0xa9000000,
+  0x19000000, 0xb5000000, 0x4a000000, 0x0d000000,
+  0x2d000000, 0xe5000000, 0x7a000000, 0x9f000000,
+  0x93000000, 0xc9000000, 0x9c000000, 0xef000000,
+  0xa0000000, 0xe0000000, 0x3b000000, 0x4d000000,
+  0xae000000, 0x2a000000, 0xf5000000, 0xb0000000,
+  0xc8000000, 0xeb000000, 0xbb000000, 0x3c000000,
+  0x83000000, 0x53000000, 0x99000000, 0x61000000,
+  0x17000000, 0x2b000000, 0x04000000, 0x7e000000,
+  0xba000000, 0x77000000, 0xd6000000, 0x26000000,
+  0xe1000000, 0x69000000, 0x14000000, 0x63000000,
+  0x55000000, 0x21000000, 0x0c000000, 0x7d000000
+}
+};
+
+static const u4byte rco_tab[10] = {
+  0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
+  0x00000020, 0x00000040, 0x00000080, 0x0000001b, 0x00000036
+};
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 2d1ed14..96a87f8 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -149,6 +149,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
 		size = add_size(size, BTreeShmemSize());
 		size = add_size(size, SyncScanShmemSize());
 		size = add_size(size, AsyncShmemSize());
+		size = add_size(size, CryptShmemSize());
 		size = add_size(size, BackendRandomShmemSize());
 #ifdef EXEC_BACKEND
 		size = add_size(size, ShmemBackendArraySize());
@@ -269,6 +270,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
 	BTreeShmemInit();
 	SyncScanShmemInit();
 	AsyncShmemInit();
+	CryptShmemInit();
 	BackendRandomShmemInit();
 
 #ifdef EXEC_BACKEND
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index 9bc00b6..fa57d24 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -35,6 +35,7 @@
 #include "storage/bufmgr.h"
 #include "storage/relfilenode.h"
 #include "storage/smgr.h"
+#include "storage/rijndael.h"
 #include "utils/hsearch.h"
 #include "utils/memutils.h"
 #include "pg_trace.h"
@@ -198,6 +199,83 @@ static MdfdVec *_mdfd_getseg(SMgrRelation reln, ForkNumber forkno,
 static BlockNumber _mdnblocks(SMgrRelation reln, ForkNumber forknum,
 		   MdfdVec *seg);
 
+static rijndael_ctx* aes_context;
+
+int CryptShmemSize(void)
+{
+	return sizeof(rijndael_ctx);
+}
+
+void CryptShmemInit(void)
+{
+	char* cipher_key = getenv("PG_CIPHER_KEY");
+	if (cipher_key != NULL)
+	{
+		bool found;
+		aes_context = (rijndael_ctx*)ShmemInitStruct("AES encryption context", sizeof(rijndael_ctx), &found);
+		if (!found)
+		{
+			int key_length;
+			uint8 aes_key[32] = {0}; /* at most 256 bits */
+
+			key_length = strlen(cipher_key);
+
+			memcpy(&aes_key, cipher_key, key_length > sizeof(aes_key) ? sizeof(aes_key) : key_length);
+			rijndael_set_key(
+				aes_context, /* context */
+				(u4byte*)&aes_key,       /* key */
+				sizeof(aes_key) * 8      /* key size in bits */,
+				1                        /* for CTR mode we need only encryption */
+				);
+		}
+		unsetenv("PG_CIPHER_KEY"); /* disable inspection of this environment variable */
+	}
+}
+
+/* Encryption and decryption using AES in CTR mode */
+static void aes_crypt_block(SMgrRelation reln, void* block, BlockNumber blocknum)
+{
+/*
+#define AES_DEBUG 1
+*/
+	uint32 aes_in[4]; /* 16 bytes, 128 bits */
+	uint32 aes_out[4];
+	uint8* plaintext = (uint8*)block;
+	uint8* gamma = (uint8*)&aes_out;
+	uint32 offs = 0;
+	uint32 i;
+
+	aes_in[0] = reln->smgr_rnode.node.spcNode;
+	aes_in[1] = reln->smgr_rnode.node.relNode;
+	aes_in[2] = blocknum;
+	aes_in[3] = 0;
+	rijndael_encrypt(aes_context, (u4byte*)&aes_in, (u4byte*)&aes_out);
+
+#ifdef AES_DEBUG
+	elog(LOG, "aes_crypt_block, in = %08X %08X %08X %08X, out = %08X %08X %08X %08X",
+		aes_in[0], aes_in[1], aes_in[2], aes_in[3],
+		aes_out[0], aes_out[1], aes_out[2], aes_out[3]);
+#endif
+
+	for(i = 0; i < BLCKSZ; i++)
+	{
+		plaintext[i] ^= gamma[offs & 0xF];
+		offs++;
+		if((offs & 0xF) == 0)
+		{
+			/* Prepare next gamma part */
+			aes_in[3] = offs;
+			rijndael_encrypt(aes_context, (u4byte*)&aes_in, (u4byte*)&aes_out);
+
+#ifdef AES_DEBUG
+			elog(LOG, "aes_crypt_block, in = %08X %08X %08X %08X, out = %08X %08X %08X %08X",
+				aes_in[0], aes_in[1], aes_in[2], aes_in[3],
+				aes_out[0], aes_out[1], aes_out[2], aes_out[3]);
+#endif
+		}
+	}
+}
+
 
 /*
  *	mdinit() -- Initialize private state for magnetic disk storage manager.
@@ -498,6 +576,7 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
 	off_t		seekpos;
 	int			nbytes;
 	MdfdVec    *v;
+	char        cryptbuf[BLCKSZ];
 
 	/* This assert is too expensive to have on normally ... */
 #ifdef CHECK_WRITE_VS_EXTEND
@@ -537,6 +616,13 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
 				 errmsg("could not seek to block %u in file \"%s\": %m",
 						blocknum, FilePathName(v->mdfd_vfd))));
 
+	if (aes_context && forknum == MAIN_FORKNUM)
+	{
+		memcpy(cryptbuf, buffer, BLCKSZ);
+		aes_crypt_block(reln, cryptbuf, blocknum);
+		buffer = cryptbuf;
+	}
+
 	if ((nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ, WAIT_EVENT_DATA_FILE_EXTEND)) != BLCKSZ)
 	{
 		if (nbytes < 0)
@@ -789,6 +875,11 @@ mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
 							blocknum, FilePathName(v->mdfd_vfd),
 							nbytes, BLCKSZ)));
 	}
+	else if (aes_context && forknum == MAIN_FORKNUM)
+	{
+		if (*(long*)buffer != 0)
+			aes_crypt_block(reln, buffer, blocknum);
+	}
 }
 
 /*
@@ -805,6 +896,7 @@ mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
 	off_t		seekpos;
 	int			nbytes;
 	MdfdVec    *v;
+	char        cryptbuf[BLCKSZ];
 
 	/* This assert is too expensive to have on normally ... */
 #ifdef CHECK_WRITE_VS_EXTEND
@@ -830,6 +922,13 @@ mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
 				 errmsg("could not seek to block %u in file \"%s\": %m",
 						blocknum, FilePathName(v->mdfd_vfd))));
 
+	if (aes_context && forknum == MAIN_FORKNUM)
+	{
+		memcpy(cryptbuf, buffer, BLCKSZ);
+		aes_crypt_block(reln, cryptbuf, blocknum);
+		buffer = cryptbuf;
+	}
+
 	nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ, WAIT_EVENT_DATA_FILE_WRITE);
 
 	TRACE_POSTGRESQL_SMGR_MD_WRITE_DONE(forknum, blocknum,
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 0568049..7b36fb5 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -59,7 +59,6 @@ extern int	max_files_per_process;
  */
 extern int	max_safe_fds;
 
-
 /*
  * prototypes for functions in fd.c
  */
diff --git a/src/include/storage/rijndael.h b/src/include/storage/rijndael.h
new file mode 100644
index 0000000..e536c61
--- /dev/null
+++ b/src/include/storage/rijndael.h
@@ -0,0 +1,60 @@
+/*
+ * contrib/pgcrypto/rijndael.h
+ *
+ *	$OpenBSD: rijndael.h,v 1.3 2001/05/09 23:01:32 markus Exp $ */
+
+/* This is an independent implementation of the encryption algorithm:	*/
+/*																		*/
+/*		   RIJNDAEL by Joan Daemen and Vincent Rijmen					*/
+/*																		*/
+/* which is a candidate algorithm in the Advanced Encryption Standard	*/
+/* programme of the US National Institute of Standards and Technology.  */
+/*																		*/
+/* Copyright in this implementation is held by Dr B R Gladman but I		*/
+/* hereby give permission for its free direct or derivative use subject */
+/* to acknowledgment of its origin and compliance with any conditions	*/
+/* that the originators of the algorithm place on its exploitation.     */
+/*																		*/
+/* Dr Brian Gladman (glad...@seven77.demon.co.uk) 14th January 1999		*/
+
+#ifndef _RIJNDAEL_H_
+#define _RIJNDAEL_H_
+
+/* 1. Standard types for AES cryptography source code				*/
+
+typedef uint8 u1byte;			/* an 8 bit unsigned character type */
+typedef uint16 u2byte;			/* a 16 bit unsigned integer type	*/
+typedef uint32 u4byte;			/* a 32 bit unsigned integer type	*/
+
+typedef int8 s1byte;			/* an 8 bit signed character type	*/
+typedef int16 s2byte;			/* a 16 bit signed integer type		*/
+typedef int32 s4byte;			/* a 32 bit signed integer type		*/
+
+typedef struct _rijndael_ctx
+{
+	u4byte		k_len;
+	int			decrypt;
+	u4byte		e_key[64];
+	u4byte		d_key[64];
+} rijndael_ctx;
+
+
+/* 2. Standard interface for AES cryptographic routines				*/
+
+/* These are all based on 32 bit unsigned values and will therefore */
+/* require endian conversions for big-endian architectures			*/
+
+rijndael_ctx *
+			rijndael_set_key(rijndael_ctx *, const u4byte *, const u4byte, int);
+void		rijndael_encrypt(rijndael_ctx *, const u4byte *, u4byte *);
+void		rijndael_decrypt(rijndael_ctx *, const u4byte *, u4byte *);
+
+/* conventional interface */
+
+void		aes_set_key(rijndael_ctx *ctx, const uint8 *key, unsigned keybits, int enc);
+void		aes_ecb_encrypt(rijndael_ctx *ctx, uint8 *data, unsigned len);
+void		aes_ecb_decrypt(rijndael_ctx *ctx, uint8 *data, unsigned len);
+void		aes_cbc_encrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len);
+void		aes_cbc_decrypt(rijndael_ctx *ctx, uint8 *iva, uint8 *data, unsigned len);
+
+#endif   /* _RIJNDAEL_H_ */
diff --git a/src/include/storage/smgr.h b/src/include/storage/smgr.h
index 9ce6829..9eb0042 100644
--- a/src/include/storage/smgr.h
+++ b/src/include/storage/smgr.h
@@ -144,4 +144,7 @@ extern void RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum,
 extern void ForgetRelationFsyncRequests(RelFileNode rnode, ForkNumber forknum);
 extern void ForgetDatabaseFsyncRequests(Oid dbid);
 
+extern int  CryptShmemSize(void);
+extern void CryptShmemInit(void);
+
 #endif   /* SMGR_H */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to