1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-02-07 17:33:02 +01:00

Fix aliasing problem.

This commit is contained in:
Werner Koch 2011-08-09 10:54:02 +02:00
parent cc6ddd1dac
commit 0ad1458f82

View File

@ -45,6 +45,13 @@
#define MAXKC (256/32)
#define MAXROUNDS 14
/* Define an u32 variant for the sake of gcc 4.4's strict aliasing rules. */
#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )
typedef u32 __attribute__ ((__may_alias__)) u32_a_t;
#else
typedef u32 u32_a_t;
#endif
static const char *selftest(void);
@ -1877,61 +1884,61 @@ do_encrypt_aligned (const RIJNDAEL_context *ctx,
int r;
union
{
u32 tempu32[4]; /* Force correct alignment. */
u32_a_t tempu32[4]; /* Force correct alignment. */
byte temp[4][4];
} u;
*((u32*)u.temp[0]) = *((u32*)(a )) ^ *((u32*)rk[0][0]);
*((u32*)u.temp[1]) = *((u32*)(a+ 4)) ^ *((u32*)rk[0][1]);
*((u32*)u.temp[2]) = *((u32*)(a+ 8)) ^ *((u32*)rk[0][2]);
*((u32*)u.temp[3]) = *((u32*)(a+12)) ^ *((u32*)rk[0][3]);
*((u32*)(b )) = (*((u32*)T1[u.temp[0][0]])
^ *((u32*)T2[u.temp[1][1]])
^ *((u32*)T3[u.temp[2][2]])
^ *((u32*)T4[u.temp[3][3]]));
*((u32*)(b + 4)) = (*((u32*)T1[u.temp[1][0]])
^ *((u32*)T2[u.temp[2][1]])
^ *((u32*)T3[u.temp[3][2]])
^ *((u32*)T4[u.temp[0][3]]));
*((u32*)(b + 8)) = (*((u32*)T1[u.temp[2][0]])
^ *((u32*)T2[u.temp[3][1]])
^ *((u32*)T3[u.temp[0][2]])
^ *((u32*)T4[u.temp[1][3]]));
*((u32*)(b +12)) = (*((u32*)T1[u.temp[3][0]])
^ *((u32*)T2[u.temp[0][1]])
^ *((u32*)T3[u.temp[1][2]])
^ *((u32*)T4[u.temp[2][3]]));
*((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[0][0]);
*((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[0][1]);
*((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[0][2]);
*((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[0][3]);
*((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]])
^ *((u32_a_t*)T2[u.temp[1][1]])
^ *((u32_a_t*)T3[u.temp[2][2]])
^ *((u32_a_t*)T4[u.temp[3][3]]));
*((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]])
^ *((u32_a_t*)T2[u.temp[2][1]])
^ *((u32_a_t*)T3[u.temp[3][2]])
^ *((u32_a_t*)T4[u.temp[0][3]]));
*((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]])
^ *((u32_a_t*)T2[u.temp[3][1]])
^ *((u32_a_t*)T3[u.temp[0][2]])
^ *((u32_a_t*)T4[u.temp[1][3]]));
*((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]])
^ *((u32_a_t*)T2[u.temp[0][1]])
^ *((u32_a_t*)T3[u.temp[1][2]])
^ *((u32_a_t*)T4[u.temp[2][3]]));
for (r = 1; r < ROUNDS-1; r++)
{
*((u32*)u.temp[0]) = *((u32*)(b )) ^ *((u32*)rk[r][0]);
*((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[r][1]);
*((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[r][2]);
*((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[r][3]);
*((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]);
*((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]);
*((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]);
*((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]);
*((u32*)(b )) = (*((u32*)T1[u.temp[0][0]])
^ *((u32*)T2[u.temp[1][1]])
^ *((u32*)T3[u.temp[2][2]])
^ *((u32*)T4[u.temp[3][3]]));
*((u32*)(b + 4)) = (*((u32*)T1[u.temp[1][0]])
^ *((u32*)T2[u.temp[2][1]])
^ *((u32*)T3[u.temp[3][2]])
^ *((u32*)T4[u.temp[0][3]]));
*((u32*)(b + 8)) = (*((u32*)T1[u.temp[2][0]])
^ *((u32*)T2[u.temp[3][1]])
^ *((u32*)T3[u.temp[0][2]])
^ *((u32*)T4[u.temp[1][3]]));
*((u32*)(b +12)) = (*((u32*)T1[u.temp[3][0]])
^ *((u32*)T2[u.temp[0][1]])
^ *((u32*)T3[u.temp[1][2]])
^ *((u32*)T4[u.temp[2][3]]));
*((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]])
^ *((u32_a_t*)T2[u.temp[1][1]])
^ *((u32_a_t*)T3[u.temp[2][2]])
^ *((u32_a_t*)T4[u.temp[3][3]]));
*((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]])
^ *((u32_a_t*)T2[u.temp[2][1]])
^ *((u32_a_t*)T3[u.temp[3][2]])
^ *((u32_a_t*)T4[u.temp[0][3]]));
*((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]])
^ *((u32_a_t*)T2[u.temp[3][1]])
^ *((u32_a_t*)T3[u.temp[0][2]])
^ *((u32_a_t*)T4[u.temp[1][3]]));
*((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]])
^ *((u32_a_t*)T2[u.temp[0][1]])
^ *((u32_a_t*)T3[u.temp[1][2]])
^ *((u32_a_t*)T4[u.temp[2][3]]));
}
/* Last round is special. */
*((u32*)u.temp[0]) = *((u32*)(b )) ^ *((u32*)rk[ROUNDS-1][0]);
*((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[ROUNDS-1][1]);
*((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[ROUNDS-1][2]);
*((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[ROUNDS-1][3]);
*((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[ROUNDS-1][0]);
*((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[ROUNDS-1][1]);
*((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[ROUNDS-1][2]);
*((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[ROUNDS-1][3]);
b[ 0] = T1[u.temp[0][0]][1];
b[ 1] = T1[u.temp[1][1]][1];
b[ 2] = T1[u.temp[2][2]][1];
@ -1948,10 +1955,10 @@ do_encrypt_aligned (const RIJNDAEL_context *ctx,
b[13] = T1[u.temp[0][1]][1];
b[14] = T1[u.temp[1][2]][1];
b[15] = T1[u.temp[2][3]][1];
*((u32*)(b )) ^= *((u32*)rk[ROUNDS][0]);
*((u32*)(b+ 4)) ^= *((u32*)rk[ROUNDS][1]);
*((u32*)(b+ 8)) ^= *((u32*)rk[ROUNDS][2]);
*((u32*)(b+12)) ^= *((u32*)rk[ROUNDS][3]);
*((u32_a_t*)(b )) ^= *((u32_a_t*)rk[ROUNDS][0]);
*((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[ROUNDS][1]);
*((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[ROUNDS][2]);
*((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[ROUNDS][3]);
#undef rk
}
@ -2003,54 +2010,55 @@ do_decrypt (RIJNDAEL_context *ctx, byte *b, const byte *a)
ctx->decryption_prepared = 1;
}
*((u32*)temp[0]) = *((u32*)(a )) ^ *((u32*)rk[ROUNDS][0]);
*((u32*)temp[1]) = *((u32*)(a+ 4)) ^ *((u32*)rk[ROUNDS][1]);
*((u32*)temp[2]) = *((u32*)(a+ 8)) ^ *((u32*)rk[ROUNDS][2]);
*((u32*)temp[3]) = *((u32*)(a+12)) ^ *((u32*)rk[ROUNDS][3]);
*((u32_a_t*)temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[ROUNDS][0]);
*((u32_a_t*)temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[ROUNDS][1]);
*((u32_a_t*)temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[ROUNDS][2]);
*((u32_a_t*)temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[ROUNDS][3]);
*((u32*)(b )) = *((u32*)T5[temp[0][0]])
^ *((u32*)T6[temp[3][1]])
^ *((u32*)T7[temp[2][2]])
^ *((u32*)T8[temp[1][3]]);
*((u32*)(b+ 4)) = *((u32*)T5[temp[1][0]])
^ *((u32*)T6[temp[0][1]])
^ *((u32*)T7[temp[3][2]])
^ *((u32*)T8[temp[2][3]]);
*((u32*)(b+ 8)) = *((u32*)T5[temp[2][0]])
^ *((u32*)T6[temp[1][1]])
^ *((u32*)T7[temp[0][2]])
^ *((u32*)T8[temp[3][3]]);
*((u32*)(b+12)) = *((u32*)T5[temp[3][0]])
^ *((u32*)T6[temp[2][1]])
^ *((u32*)T7[temp[1][2]])
^ *((u32*)T8[temp[0][3]]);
*((u32_a_t*)(b )) = *((u32_a_t*)T5[temp[0][0]])
^ *((u32_a_t*)T6[temp[3][1]])
^ *((u32_a_t*)T7[temp[2][2]])
^ *((u32_a_t*)T8[temp[1][3]]);
*((u32_a_t*)(b+ 4)) = *((u32_a_t*)T5[temp[1][0]])
^ *((u32_a_t*)T6[temp[0][1]])
^ *((u32_a_t*)T7[temp[3][2]])
^ *((u32_a_t*)T8[temp[2][3]]);
*((u32_a_t*)(b+ 8)) = *((u32_a_t*)T5[temp[2][0]])
^ *((u32_a_t*)T6[temp[1][1]])
^ *((u32_a_t*)T7[temp[0][2]])
^ *((u32_a_t*)T8[temp[3][3]]);
*((u32_a_t*)(b+12)) = *((u32_a_t*)T5[temp[3][0]])
^ *((u32_a_t*)T6[temp[2][1]])
^ *((u32_a_t*)T7[temp[1][2]])
^ *((u32_a_t*)T8[temp[0][3]]);
for (r = ROUNDS-1; r > 1; r--) {
*((u32*)temp[0]) = *((u32*)(b )) ^ *((u32*)rk[r][0]);
*((u32*)temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[r][1]);
*((u32*)temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[r][2]);
*((u32*)temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[r][3]);
*((u32*)(b )) = *((u32*)T5[temp[0][0]])
^ *((u32*)T6[temp[3][1]])
^ *((u32*)T7[temp[2][2]])
^ *((u32*)T8[temp[1][3]]);
*((u32*)(b+ 4)) = *((u32*)T5[temp[1][0]])
^ *((u32*)T6[temp[0][1]])
^ *((u32*)T7[temp[3][2]])
^ *((u32*)T8[temp[2][3]]);
*((u32*)(b+ 8)) = *((u32*)T5[temp[2][0]])
^ *((u32*)T6[temp[1][1]])
^ *((u32*)T7[temp[0][2]])
^ *((u32*)T8[temp[3][3]]);
*((u32*)(b+12)) = *((u32*)T5[temp[3][0]])
^ *((u32*)T6[temp[2][1]])
^ *((u32*)T7[temp[1][2]])
^ *((u32*)T8[temp[0][3]]);
*((u32_a_t*)temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]);
*((u32_a_t*)temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]);
*((u32_a_t*)temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]);
*((u32_a_t*)temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]);
*((u32_a_t*)(b )) = *((u32_a_t*)T5[temp[0][0]])
^ *((u32_a_t*)T6[temp[3][1]])
^ *((u32_a_t*)T7[temp[2][2]])
^ *((u32_a_t*)T8[temp[1][3]]);
*((u32_a_t*)(b+ 4)) = *((u32_a_t*)T5[temp[1][0]])
^ *((u32_a_t*)T6[temp[0][1]])
^ *((u32_a_t*)T7[temp[3][2]])
^ *((u32_a_t*)T8[temp[2][3]]);
*((u32_a_t*)(b+ 8)) = *((u32_a_t*)T5[temp[2][0]])
^ *((u32_a_t*)T6[temp[1][1]])
^ *((u32_a_t*)T7[temp[0][2]])
^ *((u32_a_t*)T8[temp[3][3]]);
*((u32_a_t*)(b+12)) = *((u32_a_t*)T5[temp[3][0]])
^ *((u32_a_t*)T6[temp[2][1]])
^ *((u32_a_t*)T7[temp[1][2]])
^ *((u32_a_t*)T8[temp[0][3]]);
}
/* last round is special */
*((u32*)temp[0]) = *((u32*)(b )) ^ *((u32*)rk[1][0]);
*((u32*)temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[1][1]);
*((u32*)temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[1][2]);
*((u32*)temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[1][3]);
/* Last round is special. */
*((u32_a_t*)temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[1][0]);
*((u32_a_t*)temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[1][1]);
*((u32_a_t*)temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[1][2]);
*((u32_a_t*)temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[1][3]);
b[ 0] = S5[temp[0][0]];
b[ 1] = S5[temp[3][1]];
b[ 2] = S5[temp[2][2]];
@ -2067,10 +2075,10 @@ do_decrypt (RIJNDAEL_context *ctx, byte *b, const byte *a)
b[13] = S5[temp[2][1]];
b[14] = S5[temp[1][2]];
b[15] = S5[temp[0][3]];
*((u32*)(b )) ^= *((u32*)rk[0][0]);
*((u32*)(b+ 4)) ^= *((u32*)rk[0][1]);
*((u32*)(b+ 8)) ^= *((u32*)rk[0][2]);
*((u32*)(b+12)) ^= *((u32*)rk[0][3]);
*((u32_a_t*)(b )) ^= *((u32_a_t*)rk[0][0]);
*((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[0][1]);
*((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[0][2]);
*((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[0][3]);
#undef rk
}