[ibr@ata.cs.hun.edu.tr: Bug#191247: libgcrypt1: mutt dies with
bus error while accessing imap over tls]
Werner Koch
wk@gnupg.org
Tue, 06 May 2003 10:30:23 +0200
On Mon, 5 May 2003 20:11:59 +0300, Nikos Mavroyanopoulos said:
> It seems like an alignment problem. A fix might be replacing
> the byte temp[4][4], with u32 temp[4] and casting the other
> way round.
Can someone please check this patch:
Index: rijndael.c
===================================================================
RCS file: /cvs/gnupg/libgcrypt/cipher/rijndael.c,v
retrieving revision 1.10
diff -u -r1.10 rijndael.c
--- rijndael.c 16 Apr 2003 16:21:34 -0000 1.10
+++ rijndael.c 5 May 2003 18:10:15 -0000
@@ -1860,75 +1860,81 @@
static void
do_encrypt (const RIJNDAEL_context *ctx, byte *b, const byte *a)
{
+ /* FIXME: Ugly code, replace by straighter implementaion and use
+ optimized assembler for common CPUs. */
+
int r;
- byte temp[4][4];
+ union {
+ u32 tempu32[4]; /* Force correct alignment. */
+ byte temp[4][4];
+ } u;
int ROUNDS = ctx->ROUNDS;
#define rk (ctx->keySched)
- *((u32*)temp[0]) = *((u32*)(a )) ^ *((u32*)rk[0][0]);
- *((u32*)temp[1]) = *((u32*)(a+ 4)) ^ *((u32*)rk[0][1]);
- *((u32*)temp[2]) = *((u32*)(a+ 8)) ^ *((u32*)rk[0][2]);
- *((u32*)temp[3]) = *((u32*)(a+12)) ^ *((u32*)rk[0][3]);
- *((u32*)(b )) = *((u32*)T1[temp[0][0]])
- ^ *((u32*)T2[temp[1][1]])
- ^ *((u32*)T3[temp[2][2]])
- ^ *((u32*)T4[temp[3][3]]);
- *((u32*)(b + 4)) = *((u32*)T1[temp[1][0]])
- ^ *((u32*)T2[temp[2][1]])
- ^ *((u32*)T3[temp[3][2]])
- ^ *((u32*)T4[temp[0][3]]);
- *((u32*)(b + 8)) = *((u32*)T1[temp[2][0]])
- ^ *((u32*)T2[temp[3][1]])
- ^ *((u32*)T3[temp[0][2]])
- ^ *((u32*)T4[temp[1][3]]);
- *((u32*)(b +12)) = *((u32*)T1[temp[3][0]])
- ^ *((u32*)T2[temp[0][1]])
- ^ *((u32*)T3[temp[1][2]])
- ^ *((u32*)T4[temp[2][3]]);
+ *((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]]);
for (r = 1; r < ROUNDS-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*)T1[temp[0][0]])
- ^ *((u32*)T2[temp[1][1]])
- ^ *((u32*)T3[temp[2][2]])
- ^ *((u32*)T4[temp[3][3]]);
- *((u32*)(b + 4)) = *((u32*)T1[temp[1][0]])
- ^ *((u32*)T2[temp[2][1]])
- ^ *((u32*)T3[temp[3][2]])
- ^ *((u32*)T4[temp[0][3]]);
- *((u32*)(b + 8)) = *((u32*)T1[temp[2][0]])
- ^ *((u32*)T2[temp[3][1]])
- ^ *((u32*)T3[temp[0][2]])
- ^ *((u32*)T4[temp[1][3]]);
- *((u32*)(b +12)) = *((u32*)T1[temp[3][0]])
- ^ *((u32*)T2[temp[0][1]])
- ^ *((u32*)T3[temp[1][2]])
- ^ *((u32*)T4[temp[2][3]]);
+ *((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*)(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]]);
}
/* last round is special */
- *((u32*)temp[0]) = *((u32*)(b )) ^ *((u32*)rk[ROUNDS-1][0]);
- *((u32*)temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[ROUNDS-1][1]);
- *((u32*)temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[ROUNDS-1][2]);
- *((u32*)temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[ROUNDS-1][3]);
- b[ 0] = T1[temp[0][0]][1];
- b[ 1] = T1[temp[1][1]][1];
- b[ 2] = T1[temp[2][2]][1];
- b[ 3] = T1[temp[3][3]][1];
- b[ 4] = T1[temp[1][0]][1];
- b[ 5] = T1[temp[2][1]][1];
- b[ 6] = T1[temp[3][2]][1];
- b[ 7] = T1[temp[0][3]][1];
- b[ 8] = T1[temp[2][0]][1];
- b[ 9] = T1[temp[3][1]][1];
- b[10] = T1[temp[0][2]][1];
- b[11] = T1[temp[1][3]][1];
- b[12] = T1[temp[3][0]][1];
- b[13] = T1[temp[0][1]][1];
- b[14] = T1[temp[1][2]][1];
- b[15] = T1[temp[2][3]][1];
+ *((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]);
+ b[ 0] = T1[u.temp[0][0]][1];
+ b[ 1] = T1[u.temp[1][1]][1];
+ b[ 2] = T1[u.temp[2][2]][1];
+ b[ 3] = T1[u.temp[3][3]][1];
+ b[ 4] = T1[u.temp[1][0]][1];
+ b[ 5] = T1[u.temp[2][1]][1];
+ b[ 6] = T1[u.temp[3][2]][1];
+ b[ 7] = T1[u.temp[0][3]][1];
+ b[ 8] = T1[u.temp[2][0]][1];
+ b[ 9] = T1[u.temp[3][1]][1];
+ b[10] = T1[u.temp[0][2]][1];
+ b[11] = T1[u.temp[1][3]][1];
+ b[12] = T1[u.temp[3][0]][1];
+ 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]);
@@ -1953,7 +1959,10 @@
#define rk (ctx->keySched2)
int ROUNDS = ctx->ROUNDS;
int r;
- byte temp[4][4];
+ union {
+ u32 tempu32[4]; /* Force correct alignment. */
+ byte temp[4][4];
+ } u;
if ( !ctx->decryption_prepared ) {
prepare_decryption ( ctx );
@@ -1961,70 +1970,70 @@
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*)u.temp[0]) = *((u32*)(a )) ^ *((u32*)rk[ROUNDS][0]);
+ *((u32*)u.temp[1]) = *((u32*)(a+ 4)) ^ *((u32*)rk[ROUNDS][1]);
+ *((u32*)u.temp[2]) = *((u32*)(a+ 8)) ^ *((u32*)rk[ROUNDS][2]);
+ *((u32*)u.temp[3]) = *((u32*)(a+12)) ^ *((u32*)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*)(b )) = *((u32*)T5[u.temp[0][0]])
+ ^ *((u32*)T6[u.temp[3][1]])
+ ^ *((u32*)T7[u.temp[2][2]])
+ ^ *((u32*)T8[u.temp[1][3]]);
+ *((u32*)(b+ 4)) = *((u32*)T5[u.temp[1][0]])
+ ^ *((u32*)T6[u.temp[0][1]])
+ ^ *((u32*)T7[u.temp[3][2]])
+ ^ *((u32*)T8[u.temp[2][3]]);
+ *((u32*)(b+ 8)) = *((u32*)T5[u.temp[2][0]])
+ ^ *((u32*)T6[u.temp[1][1]])
+ ^ *((u32*)T7[u.temp[0][2]])
+ ^ *((u32*)T8[u.temp[3][3]]);
+ *((u32*)(b+12)) = *((u32*)T5[u.temp[3][0]])
+ ^ *((u32*)T6[u.temp[2][1]])
+ ^ *((u32*)T7[u.temp[1][2]])
+ ^ *((u32*)T8[u.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*)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*)(b )) = *((u32*)T5[u.temp[0][0]])
+ ^ *((u32*)T6[u.temp[3][1]])
+ ^ *((u32*)T7[u.temp[2][2]])
+ ^ *((u32*)T8[u.temp[1][3]]);
+ *((u32*)(b+ 4)) = *((u32*)T5[u.temp[1][0]])
+ ^ *((u32*)T6[u.temp[0][1]])
+ ^ *((u32*)T7[u.temp[3][2]])
+ ^ *((u32*)T8[u.temp[2][3]]);
+ *((u32*)(b+ 8)) = *((u32*)T5[u.temp[2][0]])
+ ^ *((u32*)T6[u.temp[1][1]])
+ ^ *((u32*)T7[u.temp[0][2]])
+ ^ *((u32*)T8[u.temp[3][3]]);
+ *((u32*)(b+12)) = *((u32*)T5[u.temp[3][0]])
+ ^ *((u32*)T6[u.temp[2][1]])
+ ^ *((u32*)T7[u.temp[1][2]])
+ ^ *((u32*)T8[u.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]);
- b[ 0] = S5[temp[0][0]];
- b[ 1] = S5[temp[3][1]];
- b[ 2] = S5[temp[2][2]];
- b[ 3] = S5[temp[1][3]];
- b[ 4] = S5[temp[1][0]];
- b[ 5] = S5[temp[0][1]];
- b[ 6] = S5[temp[3][2]];
- b[ 7] = S5[temp[2][3]];
- b[ 8] = S5[temp[2][0]];
- b[ 9] = S5[temp[1][1]];
- b[10] = S5[temp[0][2]];
- b[11] = S5[temp[3][3]];
- b[12] = S5[temp[3][0]];
- b[13] = S5[temp[2][1]];
- b[14] = S5[temp[1][2]];
- b[15] = S5[temp[0][3]];
+ *((u32*)u.temp[0]) = *((u32*)(b )) ^ *((u32*)rk[1][0]);
+ *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[1][1]);
+ *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[1][2]);
+ *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[1][3]);
+ b[ 0] = S5[u.temp[0][0]];
+ b[ 1] = S5[u.temp[3][1]];
+ b[ 2] = S5[u.temp[2][2]];
+ b[ 3] = S5[u.temp[1][3]];
+ b[ 4] = S5[u.temp[1][0]];
+ b[ 5] = S5[u.temp[0][1]];
+ b[ 6] = S5[u.temp[3][2]];
+ b[ 7] = S5[u.temp[2][3]];
+ b[ 8] = S5[u.temp[2][0]];
+ b[ 9] = S5[u.temp[1][1]];
+ b[10] = S5[u.temp[0][2]];
+ b[11] = S5[u.temp[3][3]];
+ b[12] = S5[u.temp[3][0]];
+ b[13] = S5[u.temp[2][1]];
+ b[14] = S5[u.temp[1][2]];
+ b[15] = S5[u.temp[0][3]];
*((u32*)(b )) ^= *((u32*)rk[0][0]);
*((u32*)(b+ 4)) ^= *((u32*)rk[0][1]);
*((u32*)(b+ 8)) ^= *((u32*)rk[0][2]);
--
Nonviolence is the greatest force at the disposal of
mankind. It is mightier than the mightiest weapon of
destruction devised by the ingenuity of man. -Gandhi