Remove unused pkg dependancy
[platform/upstream/iotivity.git] / extlibs / tinydtls / aes / rijndael.c
index c7eaabd..33001a8 100644 (file)
 
 #include "rijndael.h"
 
+#ifdef ARDUINO_AVR_MEGA2560
+       #include <pgmspace.h>
+#else
+       #define PROGMEM
+       #define pgm_read_dword *
+#endif
+
 #undef FULL_UNROLL
 
 /*
@@ -47,7 +54,7 @@ Td3[x] = Si[x].[09, 0d, 0b, 0e];
 Td4[x] = Si[x].[01, 01, 01, 01];
 */
 
-static const aes_u32 Te0[256] = {
+PROGMEM static const aes_u32 Te0[256] = {
     0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
     0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
     0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
@@ -113,7 +120,7 @@ static const aes_u32 Te0[256] = {
     0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
     0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
 };
-static const aes_u32 Te1[256] = {
+PROGMEM static const aes_u32 Te1[256] = {
     0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
     0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
     0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
@@ -179,7 +186,7 @@ static const aes_u32 Te1[256] = {
     0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
     0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
 };
-static const aes_u32 Te2[256] = {
+PROGMEM static const aes_u32 Te2[256] = {
     0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
     0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
     0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
@@ -245,7 +252,7 @@ static const aes_u32 Te2[256] = {
     0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
     0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
 };
-static const aes_u32 Te3[256] = {
+PROGMEM static const aes_u32 Te3[256] = {
     0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
     0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
     0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
@@ -311,7 +318,7 @@ static const aes_u32 Te3[256] = {
     0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
     0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
 };
-static const aes_u32 Te4[256] = {
+PROGMEM static const aes_u32 Te4[256] = {
     0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
     0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
     0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
@@ -380,7 +387,7 @@ static const aes_u32 Te4[256] = {
 
 #ifdef WITH_AES_DECRYPT
 
-static const aes_u32 Td0[256] = {
+PROGMEM static const aes_u32 Td0[256] = {
     0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
     0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
     0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
@@ -446,7 +453,7 @@ static const aes_u32 Td0[256] = {
     0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
     0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
 };
-static const aes_u32 Td1[256] = {
+PROGMEM static const aes_u32 Td1[256] = {
     0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
     0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
     0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
@@ -512,7 +519,7 @@ static const aes_u32 Td1[256] = {
     0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
     0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
 };
-static const aes_u32 Td2[256] = {
+PROGMEM static const aes_u32 Td2[256] = {
     0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
     0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
     0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
@@ -578,7 +585,7 @@ static const aes_u32 Td2[256] = {
     0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
     0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
 };
-static const aes_u32 Td3[256] = {
+PROGMEM static const aes_u32 Td3[256] = {
     0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
     0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
     0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
@@ -644,7 +651,7 @@ static const aes_u32 Td3[256] = {
     0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
     0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
 };
-static const aes_u32 Td4[256] = {
+PROGMEM static const aes_u32 Td4[256] = {
     0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
     0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
     0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
@@ -713,7 +720,7 @@ static const aes_u32 Td4[256] = {
 
 #endif /* WITH_AES_DECRYPT */
 
-static const aes_u32 rcon[] = {
+PROGMEM static const aes_u32 rcon[] = {
        0x01000000, 0x02000000, 0x04000000, 0x08000000,
        0x10000000, 0x20000000, 0x40000000, 0x80000000,
        0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
@@ -741,11 +748,11 @@ rijndaelKeySetupEnc(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int ke
                for (;;) {
                        temp  = rk[3];
                        rk[4] = rk[0] ^
-                               (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
-                               (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
-                               (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
-                               (Te4[(temp >> 24)       ] & 0x000000ff) ^
-                               rcon[i];
+                               (pgm_read_dword(&Te4[(temp >> 16) &0xff ]) & 0xff000000) ^
+                               (pgm_read_dword(&Te4[(temp >>  8) & 0xff]) & 0x00ff0000) ^
+                               (pgm_read_dword(&Te4[(temp      ) & 0xff]) & 0x0000ff00) ^
+                               (pgm_read_dword(&Te4[(temp >> 24)       ]) & 0x000000ff) ^
+                               (pgm_read_dword(&rcon[i]));
                        rk[5] = rk[1] ^ rk[4];
                        rk[6] = rk[2] ^ rk[5];
                        rk[7] = rk[3] ^ rk[6];
@@ -761,11 +768,11 @@ rijndaelKeySetupEnc(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int ke
                for (;;) {
                        temp = rk[ 5];
                        rk[ 6] = rk[ 0] ^
-                               (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
-                               (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
-                               (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
-                               (Te4[(temp >> 24)       ] & 0x000000ff) ^
-                               rcon[i];
+                               (pgm_read_dword(&Te4[(temp >> 16) & 0xff]) & 0xff000000) ^
+                               (pgm_read_dword(&Te4[(temp >>  8) & 0xff]) & 0x00ff0000) ^
+                               (pgm_read_dword(&Te4[(temp      ) & 0xff]) & 0x0000ff00) ^
+                               (pgm_read_dword(&Te4[(temp >> 24)       ]) & 0x000000ff) ^
+                               (pgm_read_dword(&rcon[i]));
                        rk[ 7] = rk[ 1] ^ rk[ 6];
                        rk[ 8] = rk[ 2] ^ rk[ 7];
                        rk[ 9] = rk[ 3] ^ rk[ 8];
@@ -783,11 +790,11 @@ rijndaelKeySetupEnc(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int ke
                for (;;) {
                        temp = rk[ 7];
                        rk[ 8] = rk[ 0] ^
-                               (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
-                               (Te4[(temp >>  8) & 0xff] & 0x00ff0000) ^
-                               (Te4[(temp      ) & 0xff] & 0x0000ff00) ^
-                               (Te4[(temp >> 24)       ] & 0x000000ff) ^
-                               rcon[i];
+                               (pgm_read_dword(&Te4[(temp >> 16) & 0xff]) & 0xff000000) ^
+                               (pgm_read_dword(&Te4[(temp >>  8) & 0xff]) & 0x00ff0000) ^
+                               (pgm_read_dword(&Te4[(temp      ) & 0xff]) & 0x0000ff00) ^
+                               (pgm_read_dword(&Te4[(temp >> 24)       ]) & 0x000000ff) ^
+                               (pgm_read_dword(&rcon[i]));
                        rk[ 9] = rk[ 1] ^ rk[ 8];
                        rk[10] = rk[ 2] ^ rk[ 9];
                        rk[11] = rk[ 3] ^ rk[10];
@@ -796,10 +803,10 @@ rijndaelKeySetupEnc(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int ke
                        }
                        temp = rk[11];
                        rk[12] = rk[ 4] ^
-                               (Te4[(temp >> 24)       ] & 0xff000000) ^
-                               (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
-                               (Te4[(temp >>  8) & 0xff] & 0x0000ff00) ^
-                               (Te4[(temp      ) & 0xff] & 0x000000ff);
+                               (pgm_read_dword(&Te4[(temp >> 24)       ]) & 0xff000000) ^
+                               (pgm_read_dword(&Te4[(temp >> 16) & 0xff]) & 0x00ff0000) ^
+                               (pgm_read_dword(&Te4[(temp >>  8) & 0xff]) & 0x0000ff00) ^
+                               (pgm_read_dword(&Te4[(temp      ) & 0xff]) & 0x000000ff);
                        rk[13] = rk[ 5] ^ rk[12];
                        rk[14] = rk[ 6] ^ rk[13];
                        rk[15] = rk[ 7] ^ rk[14];
@@ -835,25 +842,25 @@ rijndaelKeySetupDec(aes_u32 rk[/*4*(Nr + 1)*/], const aes_u8 cipherKey[], int ke
        for (i = 1; i < Nr; i++) {
                rk += 4;
                rk[0] =
-                       Td0[Te4[(rk[0] >> 24)       ] & 0xff] ^
-                       Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
-                       Td2[Te4[(rk[0] >>  8) & 0xff] & 0xff] ^
-                       Td3[Te4[(rk[0]      ) & 0xff] & 0xff];
+                       pgm_read_dword(&Td0[pgm_read_dword(&Te4[(rk[0] >> 24)       ]) & 0xff]) ^
+                       pgm_read_dword(&Td1[pgm_read_dword(&Te4[(rk[0] >> 16) & 0xff]) & 0xff]) ^
+                       pgm_read_dword(&Td2[pgm_read_dword(&Te4[(rk[0] >>  8) & 0xff]) & 0xff]) ^
+                       pgm_read_dword(&Td3[pgm_read_dword(&Te4[(rk[0]      ) & 0xff]) & 0xff]);
                rk[1] =
-                       Td0[Te4[(rk[1] >> 24)       ] & 0xff] ^
-                       Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
-                       Td2[Te4[(rk[1] >>  8) & 0xff] & 0xff] ^
-                       Td3[Te4[(rk[1]      ) & 0xff] & 0xff];
+                       pgm_read_dword(&Td0[pgm_read_dword(&Te4[(rk[1] >> 24)       ]) & 0xff]) ^
+                       pgm_read_dword(&Td1[pgm_read_dword(&Te4[(rk[1] >> 16) & 0xff]) & 0xff]) ^
+                       pgm_read_dword(&Td2[pgm_read_dword(&Te4[(rk[1] >>  8) & 0xff]) & 0xff]) ^
+                       pgm_read_dword(&Td3[pgm_read_dword(&Te4[(rk[1]      ) & 0xff]) & 0xff]);
                rk[2] =
-                       Td0[Te4[(rk[2] >> 24)       ] & 0xff] ^
-                       Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
-                       Td2[Te4[(rk[2] >>  8) & 0xff] & 0xff] ^
-                       Td3[Te4[(rk[2]      ) & 0xff] & 0xff];
+                       pgm_read_dword(&Td0[pgm_read_dword(&Te4[(rk[2] >> 24)       ]) & 0xff]) ^
+                       pgm_read_dword(&Td1[pgm_read_dword(&Te4[(rk[2] >> 16) & 0xff]) & 0xff]) ^
+                       pgm_read_dword(&Td2[pgm_read_dword(&Te4[(rk[2] >>  8) & 0xff]) & 0xff]) ^
+                       pgm_read_dword(&Td3[pgm_read_dword(&Te4[(rk[2]      ) & 0xff]) & 0xff]);
                rk[3] =
-                       Td0[Te4[(rk[3] >> 24)       ] & 0xff] ^
-                       Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
-                       Td2[Te4[(rk[3] >>  8) & 0xff] & 0xff] ^
-                       Td3[Te4[(rk[3]      ) & 0xff] & 0xff];
+                       pgm_read_dword(&Td0[pgm_read_dword(&Te4[(rk[3] >> 24)       ]) & 0xff]) ^
+                       pgm_read_dword(&Td1[pgm_read_dword(&Te4[(rk[3] >> 16) & 0xff]) & 0xff]) ^
+                       pgm_read_dword(&Td2[pgm_read_dword(&Te4[(rk[3] >>  8) & 0xff]) & 0xff]) ^
+                       pgm_read_dword(&Td3[pgm_read_dword(&Te4[(rk[3]      ) & 0xff]) & 0xff]);
        }
        return Nr;
 }
@@ -878,72 +885,72 @@ rijndaelEncrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 pt[16],
        s3 = GETU32(pt + 12) ^ rk[3];
 #ifdef FULL_UNROLL
     /* round 1: */
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+       t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[ 4];
+       t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[ 5];
+       t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[ 6];
+       t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[ 7];
        /* round 2: */
-       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
-       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
-       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
-       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+       s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[ 8];
+       s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[ 9];
+       s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[10];
+       s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[11];
     /* round 3: */
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+       t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[12];
+       t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[13];
+       t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[14];
+       t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[15];
        /* round 4: */
-       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
-       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
-       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
-       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+       s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[16];
+       s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[17];
+       s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[18];
+       s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[19];
     /* round 5: */
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+       t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[20];
+       t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[21];
+       t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[22];
+       t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[23];
        /* round 6: */
-       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
-       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
-       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
-       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+       s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[24];
+       s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[25];
+       s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[26];
+       s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[27];
     /* round 7: */
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+       t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[28];
+       t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[29];
+       t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[30];
+       t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[31];
        /* round 8: */
-       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
-       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
-       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
-       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+       s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[32];
+       s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[33];
+       s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[34];
+       s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[35];
     /* round 9: */
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+       t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[36];
+       t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[37];
+       t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[38];
+       t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[39];
     if (Nr > 10) {
        /* round 10: */
-       s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
-       s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
-       s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
-       s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+       s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[40];
+       s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[41];
+       s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[42];
+       s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[43];
        /* round 11: */
-       t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
-       t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
-       t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
-       t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+       t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[44];
+       t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[45];
+       t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[46];
+       t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[47];
        if (Nr > 12) {
            /* round 12: */
-           s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >>  8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
-           s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >>  8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
-           s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >>  8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
-           s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >>  8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+           s0 = pgm_read_dword(&Te0[t0 >> 24]) ^ pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t3 & 0xff]) ^ rk[48];
+           s1 = pgm_read_dword(&Te0[t1 >> 24]) ^ pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t0 & 0xff]) ^ rk[49];
+           s2 = pgm_read_dword(&Te0[t2 >> 24]) ^ pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t1 & 0xff]) ^ rk[50];
+           s3 = pgm_read_dword(&Te0[t3 >> 24]) ^ pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[t2 & 0xff]) ^ rk[51];
            /* round 13: */
-           t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >>  8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
-           t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >>  8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
-           t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >>  8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
-           t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >>  8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+           t0 = pgm_read_dword(&Te0[s0 >> 24]) ^ pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s3 & 0xff]) ^ rk[52];
+           t1 = pgm_read_dword(&Te0[s1 >> 24]) ^ pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s0 & 0xff]) ^ rk[53];
+           t2 = pgm_read_dword(&Te0[s2 >> 24]) ^ pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s1 & 0xff]) ^ rk[54];
+           t3 = pgm_read_dword(&Te0[s3 >> 24]) ^ pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Te2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Te3[s2 & 0xff]) ^ rk[55];
        }
     }
     rk += Nr << 2;
@@ -954,28 +961,28 @@ rijndaelEncrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 pt[16],
     r = Nr >> 1;
     for (;;) {
        t0 =
-           Te0[(s0 >> 24)       ] ^
-           Te1[(s1 >> 16) & 0xff] ^
-           Te2[(s2 >>  8) & 0xff] ^
-           Te3[(s3      ) & 0xff] ^
+           pgm_read_dword(&Te0[(s0 >> 24)       ]) ^
+           pgm_read_dword(&Te1[(s1 >> 16) & 0xff]) ^
+           pgm_read_dword(&Te2[(s2 >>  8) & 0xff]) ^
+           pgm_read_dword(&Te3[(s3      ) & 0xff]) ^
            rk[4];
        t1 =
-           Te0[(s1 >> 24)       ] ^
-           Te1[(s2 >> 16) & 0xff] ^
-           Te2[(s3 >>  8) & 0xff] ^
-           Te3[(s0      ) & 0xff] ^
+           pgm_read_dword(&Te0[(s1 >> 24)       ]) ^
+           pgm_read_dword(&Te1[(s2 >> 16) & 0xff]) ^
+           pgm_read_dword(&Te2[(s3 >>  8) & 0xff]) ^
+           pgm_read_dword(&Te3[(s0      ) & 0xff]) ^
            rk[5];
        t2 =
-           Te0[(s2 >> 24)       ] ^
-           Te1[(s3 >> 16) & 0xff] ^
-           Te2[(s0 >>  8) & 0xff] ^
-           Te3[(s1      ) & 0xff] ^
+           pgm_read_dword(&Te0[(s2 >> 24)       ]) ^
+           pgm_read_dword(&Te1[(s3 >> 16) & 0xff]) ^
+           pgm_read_dword(&Te2[(s0 >>  8) & 0xff]) ^
+           pgm_read_dword(&Te3[(s1      ) & 0xff]) ^
            rk[6];
        t3 =
-           Te0[(s3 >> 24)       ] ^
-           Te1[(s0 >> 16) & 0xff] ^
-           Te2[(s1 >>  8) & 0xff] ^
-           Te3[(s2      ) & 0xff] ^
+           pgm_read_dword(&Te0[(s3 >> 24)       ]) ^
+           pgm_read_dword(&Te1[(s0 >> 16) & 0xff]) ^
+           pgm_read_dword(&Te2[(s1 >>  8) & 0xff]) ^
+           pgm_read_dword(&Te3[(s2      ) & 0xff]) ^
            rk[7];
 
        rk += 8;
@@ -984,28 +991,28 @@ rijndaelEncrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 pt[16],
        }
 
        s0 =
-           Te0[(t0 >> 24)       ] ^
-           Te1[(t1 >> 16) & 0xff] ^
-           Te2[(t2 >>  8) & 0xff] ^
-           Te3[(t3      ) & 0xff] ^
+           pgm_read_dword(&Te0[(t0 >> 24)       ]) ^
+           pgm_read_dword(&Te1[(t1 >> 16) & 0xff]) ^
+           pgm_read_dword(&Te2[(t2 >>  8) & 0xff]) ^
+           pgm_read_dword(&Te3[(t3      ) & 0xff]) ^
            rk[0];
        s1 =
-           Te0[(t1 >> 24)       ] ^
-           Te1[(t2 >> 16) & 0xff] ^
-           Te2[(t3 >>  8) & 0xff] ^
-           Te3[(t0      ) & 0xff] ^
+           pgm_read_dword(&Te0[(t1 >> 24)       ]) ^
+           pgm_read_dword(&Te1[(t2 >> 16) & 0xff]) ^
+           pgm_read_dword(&Te2[(t3 >>  8) & 0xff]) ^
+           pgm_read_dword(&Te3[(t0      ) & 0xff]) ^
            rk[1];
        s2 =
-           Te0[(t2 >> 24)       ] ^
-           Te1[(t3 >> 16) & 0xff] ^
-           Te2[(t0 >>  8) & 0xff] ^
-           Te3[(t1      ) & 0xff] ^
+           pgm_read_dword(&Te0[(t2 >> 24)       ]) ^
+           pgm_read_dword(&Te1[(t3 >> 16) & 0xff]) ^
+           pgm_read_dword(&Te2[(t0 >>  8) & 0xff]) ^
+           pgm_read_dword(&Te3[(t1      ) & 0xff]) ^
            rk[2];
        s3 =
-           Te0[(t3 >> 24)       ] ^
-           Te1[(t0 >> 16) & 0xff] ^
-           Te2[(t1 >>  8) & 0xff] ^
-           Te3[(t2      ) & 0xff] ^
+           pgm_read_dword(&Te0[(t3 >> 24)       ]) ^
+           pgm_read_dword(&Te1[(t0 >> 16) & 0xff]) ^
+           pgm_read_dword(&Te2[(t1 >>  8) & 0xff]) ^
+           pgm_read_dword(&Te3[(t2      ) & 0xff]) ^
            rk[3];
     }
 #endif /* ?FULL_UNROLL */
@@ -1014,31 +1021,31 @@ rijndaelEncrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 pt[16],
         * map cipher state to byte array block:
         */
        s0 =
-               (Te4[(t0 >> 24)       ] & 0xff000000) ^
-               (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
-               (Te4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
-               (Te4[(t3      ) & 0xff] & 0x000000ff) ^
+               (pgm_read_dword(&Te4[(t0 >> 24)       ]) & 0xff000000) ^
+               (pgm_read_dword(&Te4[(t1 >> 16) & 0xff]) & 0x00ff0000) ^
+               (pgm_read_dword(&Te4[(t2 >>  8) & 0xff]) & 0x0000ff00) ^
+               (pgm_read_dword(&Te4[(t3      ) & 0xff]) & 0x000000ff) ^
                rk[0];
        PUTU32(ct     , s0);
        s1 =
-               (Te4[(t1 >> 24)       ] & 0xff000000) ^
-               (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
-               (Te4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
-               (Te4[(t0      ) & 0xff] & 0x000000ff) ^
+               (pgm_read_dword(&Te4[(t1 >> 24)       ]) & 0xff000000) ^
+               (pgm_read_dword(&Te4[(t2 >> 16) & 0xff]) & 0x00ff0000) ^
+               (pgm_read_dword(&Te4[(t3 >>  8) & 0xff]) & 0x0000ff00) ^
+               (pgm_read_dword(&Te4[(t0      ) & 0xff]) & 0x000000ff) ^
                rk[1];
        PUTU32(ct +  4, s1);
        s2 =
-               (Te4[(t2 >> 24)       ] & 0xff000000) ^
-               (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
-               (Te4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
-               (Te4[(t1      ) & 0xff] & 0x000000ff) ^
+               (pgm_read_dword(&Te4[(t2 >> 24)       ]) & 0xff000000) ^
+               (pgm_read_dword(&Te4[(t3 >> 16) & 0xff]) & 0x00ff0000) ^
+               (pgm_read_dword(&Te4[(t0 >>  8) & 0xff]) & 0x0000ff00) ^
+               (pgm_read_dword(&Te4[(t1      ) & 0xff]) & 0x000000ff) ^
                rk[2];
        PUTU32(ct +  8, s2);
        s3 =
-               (Te4[(t3 >> 24)       ] & 0xff000000) ^
-               (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
-               (Te4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
-               (Te4[(t2      ) & 0xff] & 0x000000ff) ^
+               (pgm_read_dword(&Te4[(t3 >> 24)       ]) & 0xff000000) ^
+               (pgm_read_dword(&Te4[(t0 >> 16) & 0xff]) & 0x00ff0000) ^
+               (pgm_read_dword(&Te4[(t1 >>  8) & 0xff]) & 0x0000ff00) ^
+               (pgm_read_dword(&Te4[(t2      ) & 0xff]) & 0x000000ff) ^
                rk[3];
        PUTU32(ct + 12, s3);
 }
@@ -1063,72 +1070,72 @@ rijndaelDecrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 ct[16],
     s3 = GETU32(ct + 12) ^ rk[3];
 #ifdef FULL_UNROLL
     /* round 1: */
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
+    t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[ 4];
+    t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[ 5];
+    t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[ 6];
+    t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[ 7];
     /* round 2: */
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
+    s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[ 8];
+    s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[ 9];
+    s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[10];
+    s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[11];
     /* round 3: */
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
+    t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[12];
+    t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[13];
+    t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[14];
+    t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[15];
     /* round 4: */
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
+    s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[16];
+    s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[17];
+    s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[18];
+    s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[19];
     /* round 5: */
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
+    t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[20];
+    t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[21];
+    t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[22];
+    t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[23];
     /* round 6: */
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
+    s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[24];
+    s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[25];
+    s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[26];
+    s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[27];
     /* round 7: */
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
+    t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[28];
+    t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[29];
+    t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[30];
+    t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[31];
     /* round 8: */
-    s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
-    s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
-    s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
-    s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
+    s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[32];
+    s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[33];
+    s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[34];
+    s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[35];
     /* round 9: */
-    t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
-    t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
-    t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
-    t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
+    t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[36];
+    t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[37];
+    t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[38];
+    t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[39];
     if (Nr > 10) {
        /* round 10: */
-       s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
-       s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
-       s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
-       s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+       s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[40];
+       s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[41];
+       s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[42];
+       s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[43];
        /* round 11: */
-       t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
-       t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
-       t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
-       t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+       t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[44];
+       t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[45];
+       t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[46];
+       t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[47];
        if (Nr > 12) {
            /* round 12: */
-           s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >>  8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
-           s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >>  8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
-           s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >>  8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
-           s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >>  8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+           s0 = pgm_read_dword(&Td0[t0 >> 24]) ^ pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t1 & 0xff]) ^ rk[48];
+           s1 = pgm_read_dword(&Td0[t1 >> 24]) ^ pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t2 & 0xff]) ^ rk[49];
+           s2 = pgm_read_dword(&Td0[t2 >> 24]) ^ pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t3 & 0xff]) ^ rk[50];
+           s3 = pgm_read_dword(&Td0[t3 >> 24]) ^ pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(t1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[t0 & 0xff]) ^ rk[51];
            /* round 13: */
-           t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >>  8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
-           t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >>  8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
-           t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >>  8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
-           t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >>  8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
+           t0 = pgm_read_dword(&Td0[s0 >> 24]) ^ pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s2 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s1 & 0xff]) ^ rk[52];
+           t1 = pgm_read_dword(&Td0[s1 >> 24]) ^ pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s3 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s2 & 0xff]) ^ rk[53];
+           t2 = pgm_read_dword(&Td0[s2 >> 24]) ^ pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s0 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s3 & 0xff]) ^ rk[54];
+           t3 = pgm_read_dword(&Td0[s3 >> 24]) ^ pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^ pgm_read_dword(&Td2[(s1 >>  8) & 0xff]) ^ pgm_read_dword(&Td3[s0 & 0xff]) ^ rk[55];
        }
     }
        rk += Nr << 2;
@@ -1139,28 +1146,28 @@ rijndaelDecrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 ct[16],
     r = Nr >> 1;
     for (;;) {
        t0 =
-           Td0[(s0 >> 24)       ] ^
-           Td1[(s3 >> 16) & 0xff] ^
-           Td2[(s2 >>  8) & 0xff] ^
-           Td3[(s1      ) & 0xff] ^
+           pgm_read_dword(&Td0[(s0 >> 24)       ]) ^
+           pgm_read_dword(&Td1[(s3 >> 16) & 0xff]) ^
+           pgm_read_dword(&Td2[(s2 >>  8) & 0xff]) ^
+           pgm_read_dword(&Td3[(s1      ) & 0xff]) ^
            rk[4];
        t1 =
-           Td0[(s1 >> 24)       ] ^
-           Td1[(s0 >> 16) & 0xff] ^
-           Td2[(s3 >>  8) & 0xff] ^
-           Td3[(s2      ) & 0xff] ^
+           pgm_read_dword(&Td0[(s1 >> 24)       ]) ^
+           pgm_read_dword(&Td1[(s0 >> 16) & 0xff]) ^
+           pgm_read_dword(&Td2[(s3 >>  8) & 0xff]) ^
+           pgm_read_dword(&Td3[(s2      ) & 0xff]) ^
            rk[5];
        t2 =
-           Td0[(s2 >> 24)       ] ^
-           Td1[(s1 >> 16) & 0xff] ^
-           Td2[(s0 >>  8) & 0xff] ^
-           Td3[(s3      ) & 0xff] ^
+           pgm_read_dword(&Td0[(s2 >> 24)       ]) ^
+           pgm_read_dword(&Td1[(s1 >> 16) & 0xff]) ^
+           pgm_read_dword(&Td2[(s0 >>  8) & 0xff]) ^
+           pgm_read_dword(&Td3[(s3      ) & 0xff]) ^
            rk[6];
        t3 =
-           Td0[(s3 >> 24)       ] ^
-           Td1[(s2 >> 16) & 0xff] ^
-           Td2[(s1 >>  8) & 0xff] ^
-           Td3[(s0      ) & 0xff] ^
+           pgm_read_dword(&Td0[(s3 >> 24)       ]) ^
+           pgm_read_dword(&Td1[(s2 >> 16) & 0xff]) ^
+           pgm_read_dword(&Td2[(s1 >>  8) & 0xff]) ^
+           pgm_read_dword(&Td3[(s0      ) & 0xff]) ^
            rk[7];
 
        rk += 8;
@@ -1169,28 +1176,28 @@ rijndaelDecrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 ct[16],
        }
 
        s0 =
-           Td0[(t0 >> 24)       ] ^
-           Td1[(t3 >> 16) & 0xff] ^
-           Td2[(t2 >>  8) & 0xff] ^
-           Td3[(t1      ) & 0xff] ^
+           pgm_read_dword(&Td0[(t0 >> 24)       ]) ^
+           pgm_read_dword(&Td1[(t3 >> 16) & 0xff]) ^
+           pgm_read_dword(&Td2[(t2 >>  8) & 0xff]) ^
+           pgm_read_dword(&Td3[(t1      ) & 0xff]) ^
            rk[0];
        s1 =
-           Td0[(t1 >> 24)       ] ^
-           Td1[(t0 >> 16) & 0xff] ^
-           Td2[(t3 >>  8) & 0xff] ^
-           Td3[(t2      ) & 0xff] ^
+           pgm_read_dword(&Td0[(t1 >> 24)       ]) ^
+           pgm_read_dword(&Td1[(t0 >> 16) & 0xff]) ^
+           pgm_read_dword(&Td2[(t3 >>  8) & 0xff]) ^
+           pgm_read_dword(&Td3[(t2      ) & 0xff]) ^
            rk[1];
        s2 =
-           Td0[(t2 >> 24)       ] ^
-           Td1[(t1 >> 16) & 0xff] ^
-           Td2[(t0 >>  8) & 0xff] ^
-           Td3[(t3      ) & 0xff] ^
+           pgm_read_dword(&Td0[(t2 >> 24)       ]) ^
+           pgm_read_dword(&Td1[(t1 >> 16) & 0xff]) ^
+           pgm_read_dword(&Td2[(t0 >>  8) & 0xff]) ^
+           pgm_read_dword(&Td3[(t3      ) & 0xff]) ^
            rk[2];
        s3 =
-           Td0[(t3 >> 24)       ] ^
-           Td1[(t2 >> 16) & 0xff] ^
-           Td2[(t1 >>  8) & 0xff] ^
-           Td3[(t0      ) & 0xff] ^
+           pgm_read_dword(&Td0[(t3 >> 24)       ]) ^
+           pgm_read_dword(&Td1[(t2 >> 16) & 0xff]) ^
+           pgm_read_dword(&Td2[(t1 >>  8) & 0xff]) ^
+           pgm_read_dword(&Td3[(t0      ) & 0xff]) ^
            rk[3];
     }
 #endif /* ?FULL_UNROLL */
@@ -1199,31 +1206,31 @@ rijndaelDecrypt(const aes_u32 rk[/*4*(Nr + 1)*/], int Nr, const aes_u8 ct[16],
         * map cipher state to byte array block:
         */
        s0 =
-               (Td4[(t0 >> 24)       ] & 0xff000000) ^
-               (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
-               (Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
-               (Td4[(t1      ) & 0xff] & 0x000000ff) ^
+               (pgm_read_dword(&Td4[(t0 >> 24)       ]) & 0xff000000) ^
+               (pgm_read_dword(&Td4[(t3 >> 16) & 0xff]) & 0x00ff0000) ^
+               (pgm_read_dword(&Td4[(t2 >>  8) & 0xff]) & 0x0000ff00) ^
+               (pgm_read_dword(&Td4[(t1      ) & 0xff]) & 0x000000ff) ^
                rk[0];
        PUTU32(pt     , s0);
        s1 =
-               (Td4[(t1 >> 24)       ] & 0xff000000) ^
-               (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
-               (Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
-               (Td4[(t2      ) & 0xff] & 0x000000ff) ^
+               (pgm_read_dword(&Td4[(t1 >> 24)       ]) & 0xff000000) ^
+               (pgm_read_dword(&Td4[(t0 >> 16) & 0xff]) & 0x00ff0000) ^
+               (pgm_read_dword(&Td4[(t3 >>  8) & 0xff]) & 0x0000ff00) ^
+               (pgm_read_dword(&Td4[(t2      ) & 0xff]) & 0x000000ff) ^
                rk[1];
        PUTU32(pt +  4, s1);
        s2 =
-               (Td4[(t2 >> 24)       ] & 0xff000000) ^
-               (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
-               (Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
-               (Td4[(t3      ) & 0xff] & 0x000000ff) ^
+               (pgm_read_dword(&Td4[(t2 >> 24)       ]) & 0xff000000) ^
+               (pgm_read_dword(&Td4[(t1 >> 16) & 0xff]) & 0x00ff0000) ^
+               (pgm_read_dword(&Td4[(t0 >>  8) & 0xff]) & 0x0000ff00) ^
+               (pgm_read_dword(&Td4[(t3      ) & 0xff]) & 0x000000ff) ^
                rk[2];
        PUTU32(pt +  8, s2);
        s3 =
-               (Td4[(t3 >> 24)       ] & 0xff000000) ^
-               (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
-               (Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
-               (Td4[(t0      ) & 0xff] & 0x000000ff) ^
+               (pgm_read_dword(&Td4[(t3 >> 24)       ]) & 0xff000000) ^
+               (pgm_read_dword(&Td4[(t2 >> 16) & 0xff]) & 0x00ff0000) ^
+               (pgm_read_dword(&Td4[(t1 >>  8) & 0xff]) & 0x0000ff00) ^
+               (pgm_read_dword(&Td4[(t0      ) & 0xff]) & 0x000000ff) ^
                rk[3];
        PUTU32(pt + 12, s3);
 }