[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