Description: Fixes twadmin loop eating 100% CPU
Bug-Debian: http://bugs.debian.org/225313
Bug-Debian: http://bugs.debian.org/240982
Bug-Debian: http://bugs.debian.org/244299
X-Comment: Recovered from package tripwire-2.3.1.2.0-13
Author: Nicolas François <nicolas.francois@centraliens.net>
Forwarded: no
Index: tripwire-2.4.2/src/cryptlib/integer.cpp
===================================================================
--- tripwire-2.4.2.orig/src/cryptlib/integer.cpp	2010-06-25 14:02:18.454989316 +0200
+++ tripwire-2.4.2/src/cryptlib/integer.cpp	2010-06-25 14:04:37.285964407 +0200
@@ -15,6 +15,20 @@
 
 #define MAKE_DWORD(lowWord, highWord) ((dword(highWord)<<WORD_BITS) | (lowWord))
 
+union dword_union
+{
+    dword dw;
+    struct {
+#ifdef WORDS_BIGENDIAN
+      word high;
+      word low;
+#else
+      word low;
+      word high;
+#endif
+    };
+};
+
 #if defined(_MSC_VER) && defined(_M_IX86) && (_M_IX86<=500)
 
 // Add() and Subtract() are coded in Pentium assembly for a speed increase
@@ -127,11 +141,12 @@
 	word carry=0;
 	for (unsigned i = 0; i < N; i+=2)
 	{
-		dword u = (dword) carry + A[i] + B[i];
-		C[i] = LOW_WORD(u);
-		u = (dword) HIGH_WORD(u) + A[i+1] + B[i+1];
-		C[i+1] = LOW_WORD(u);
-		carry = HIGH_WORD(u);
+		dword_union u;
+		u.dw = (dword) carry + A[i] + B[i];
+		C[i] = u.low;
+		u.dw = (dword) u.high + A[i+1] + B[i+1];
+		C[i+1] = u.low;
+		carry = u.high;
 	}
 	return carry;
 }
@@ -143,11 +158,12 @@
 	word borrow=0;
 	for (unsigned i = 0; i < N; i+=2)
 	{
-		dword u = (dword) A[i] - B[i] - borrow;
-		C[i] = LOW_WORD(u);
-		u = (dword) A[i+1] - B[i+1] - (word)(0-HIGH_WORD(u));
-		C[i+1] = LOW_WORD(u);
-		borrow = 0-HIGH_WORD(u);
+		dword_union u;
+                u.dw = (dword) A[i] - B[i] - borrow;
+		C[i] = u.low;
+		u.dw = (dword) A[i+1] - B[i+1] - (word)(0-u.high);
+		C[i+1] = u.low;
+		borrow = 0-u.high;
 	}
 	return borrow;
 }
@@ -203,9 +219,10 @@
 	word carry=0;
 	for(unsigned i=0; i<N; i++)
 	{
-		dword p = (dword)A[i] * B + carry;
-		C[i] = LOW_WORD(p);
-		carry = HIGH_WORD(p);
+		dword_union p;
+                p.dw = (dword)A[i] * B + carry;
+		C[i] = p.low;
+		carry = p.high;
 	}
 	return carry;
 }
@@ -213,85 +230,91 @@
 static void AtomicMultiply(word *C, word A0, word A1, word B0, word B1)
 {
 	word s;
-	dword d;
+	dword_union d;
 
 	if (A1 >= A0)
 		if (B0 >= B1)
 		{
 			s = 0;
-			d = (dword)(A1-A0)*(B0-B1);
+			d.dw = (dword)(A1-A0)*(B0-B1);
 		}
 		else
 		{
 			s = (A1-A0);
-			d = (dword)s*(word)(B0-B1);
+			d.dw = (dword)s*(word)(B0-B1);
 		}
 	else
 		if (B0 > B1)
 		{
 			s = (B0-B1);
-			d = (word)(A1-A0)*(dword)s;
+			d.dw = (word)(A1-A0)*(dword)s;
 		}
 		else
 		{
 			s = 0;
-			d = (dword)(A0-A1)*(B1-B0);
+			d.dw = (dword)(A0-A1)*(B1-B0);
 		}
 
-	dword A0B0 = (dword)A0*B0;
-	C[0] = LOW_WORD(A0B0);
-
-	dword A1B1 = (dword)A1*B1;
-	dword t = (dword) HIGH_WORD(A0B0) + LOW_WORD(A0B0) + LOW_WORD(d) + LOW_WORD(A1B1);
-	C[1] = LOW_WORD(t);
-
-	t = A1B1 + HIGH_WORD(t) + HIGH_WORD(A0B0) + HIGH_WORD(d) + HIGH_WORD(A1B1) - s;
-	C[2] = LOW_WORD(t);
-	C[3] = HIGH_WORD(t);
+	dword_union A0B0;
+	A0B0.dw = (dword)A0*B0;
+	C[0] = A0B0.low;
+
+	dword_union A1B1;
+	A1B1.dw = (dword)A1*B1;
+	dword_union t;
+	t.dw = (dword)A0B0.high + A0B0.low + d.low + A1B1.low;
+	C[1] = t.low;
+
+	t.dw = A1B1.dw + t.high + A0B0.high + d.high + A1B1.high - s;
+	C[2] = t.low;
+	C[3] = t.high;
 }
 
 static word AtomicMultiplyAdd(word *C, word A0, word A1, word B0, word B1)
 {
 	word s;
-	dword d;
+	dword_union d;
 
 	if (A1 >= A0)
 		if (B0 >= B1)
 		{
 			s = 0;
-			d = (dword)(A1-A0)*(B0-B1);
+			d.dw = (dword)(A1-A0)*(B0-B1);
 		}
 		else
 		{
 			s = (A1-A0);
-			d = (dword)s*(word)(B0-B1);
+			d.dw = (dword)s*(word)(B0-B1);
 		}
 	else
 		if (B0 > B1)
 		{
 			s = (B0-B1);
-			d = (word)(A1-A0)*(dword)s;
+			d.dw = (word)(A1-A0)*(dword)s;
 		}
 		else
 		{
 			s = 0;
-			d = (dword)(A0-A1)*(B1-B0);
+			d.dw = (dword)(A0-A1)*(B1-B0);
 		}
 
-	dword A0B0 = (dword)A0*B0;
-	dword t = A0B0 + C[0];
-	C[0] = LOW_WORD(t);
-
-	dword A1B1 = (dword)A1*B1;
-	t = (dword) HIGH_WORD(t) + LOW_WORD(A0B0) + LOW_WORD(d) + LOW_WORD(A1B1) + C[1];
-	C[1] = LOW_WORD(t);
-
-	t = (dword) HIGH_WORD(t) + LOW_WORD(A1B1) + HIGH_WORD(A0B0) + HIGH_WORD(d) + HIGH_WORD(A1B1) - s + C[2];
-	C[2] = LOW_WORD(t);
-
-	t = (dword) HIGH_WORD(t) + HIGH_WORD(A1B1) + C[3];
-	C[3] = LOW_WORD(t);
-	return HIGH_WORD(t);
+	dword_union A0B0;
+	A0B0.dw = (dword)A0*B0;
+	dword_union t;
+	t.dw = A0B0.dw + C[0];
+	C[0] = t.low;
+
+	dword_union A1B1;
+        A1B1.dw = (dword)A1*B1;
+	t.dw = (dword) t.high + A0B0.low + d.low + A1B1.low + C[1];
+	C[1] = t.low;
+
+	t.dw = (dword) t.high + A1B1.low + A0B0.high + d.high + A1B1.high - s + C[2];
+	C[2] = t.low;
+
+	t.dw = (dword) t.high + A1B1.high + C[3];
+	C[3] = t.low;
+	return t.high;
 }
 
 static inline void AtomicSquare(word *C, word A, word B)
@@ -300,56 +323,60 @@
 	// VC50 workaround
 	AtomicMultiply(C, A, B, A, B);
 #else
-	dword t1 = (dword) A*A;
-	C[0] = LOW_WORD(t1);
-
-	dword t2 = (dword) A*B;
-	t1 = (dword) HIGH_WORD(t1) + LOW_WORD(t2) + LOW_WORD(t2);
-	C[1] = LOW_WORD(t1);
-
-	t1 = (dword) B*B + HIGH_WORD(t1) + HIGH_WORD(t2) + HIGH_WORD(t2);
-	C[2] = LOW_WORD(t1);
-	C[3] = HIGH_WORD(t1);
+	dword_union t1;
+	t1.dw = (dword) A*A;
+	C[0] = t1.low;
+
+	dword_union t2;
+        t2.dw = (dword) A*B;
+	t1.dw = (dword) t1.high + t2.low + t2.low;
+	C[1] = t1.low;
+
+	t1.dw = (dword) B*B + t1.high + t2.high + t2.high;
+	C[2] = t1.low;
+	C[3] = t1.high;
 #endif
 }
 
 static inline void AtomicMultiplyBottom(word *C, word A0, word A1, word B0, word B1)
 {
-	dword t = (dword)A0*B0;
-	C[0] = LOW_WORD(t);
-	C[1] = HIGH_WORD(t) + A0*B1 + A1*B0;
+	dword_union t;
+	t.dw = (dword)A0*B0;
+	C[0] = t.low;
+	C[1] = t.high + A0*B1 + A1*B0;
 }
 
 static inline void AtomicMultiplyBottomAdd(word *C, word A0, word A1, word B0, word B1)
 {
-	dword t = (dword)A0*B0 + C[0];
-	C[0] = LOW_WORD(t);
-	C[1] += HIGH_WORD(t) + A0*B1 + A1*B0;
+	dword_union t;
+	t.dw = (dword)A0*B0 + C[0];
+	C[0] = t.low;
+	C[1] += t.high + A0*B1 + A1*B0;
 }
 
 static void CombaMultiply(word *R, const word *A, const word *B)
 {
-	dword p;
+	dword_union p;
 	word c=0, d=0, e=0;
 
 #define MulAcc(x, y)								\
-	p = (dword)A[x] * B[y] + c;						\
-	c = LOW_WORD(p);								\
-	p = (dword)d + HIGH_WORD(p);					\
-	d = LOW_WORD(p);								\
-	e += HIGH_WORD(p);
+	p.dw = (dword)A[x] * B[y] + c;						\
+	c = p.low;								\
+	p.dw = (dword)d + p.high;					\
+	d = p.low;								\
+	e += p.high;
 
 #define SaveMulAcc(s, x, y)							\
 	R[s] = c;										\
-	p = (dword)A[x] * B[y] + d;						\
-	c = LOW_WORD(p);								\
-	p = (dword)e + HIGH_WORD(p);					\
-	d = LOW_WORD(p);								\
-	e = HIGH_WORD(p);
-
-	p = (dword)A[0] * B[0];
-	R[0] = LOW_WORD(p);
-	c = HIGH_WORD(p);
+	p.dw = (dword)A[x] * B[y] + d;						\
+	c = p.low;								\
+	p.dw = (dword)e + p.high;					\
+	d = p.low;								\
+	e = p.high;
+
+	p.dw = (dword)A[0] * B[0];
+	R[0] = p.low;
+	c = p.high;
 	d = e = 0;
 
 	MulAcc(0, 1);
@@ -372,9 +399,9 @@
 	MulAcc(3, 2);
 
 	R[5] = c;
-	p = (dword)A[3] * B[3] + d;
-	R[6] = LOW_WORD(p);
-	R[7] = e + HIGH_WORD(p);
+	p.dw = (dword)A[3] * B[3] + d;
+	R[6] = p.low;
+	R[7] = e + p.high;
 
 #undef MulAcc
 #undef SaveMulAcc
@@ -384,15 +411,17 @@
 {
 	assert(A0%2==1);
 
-	dword A=MAKE_DWORD(A0, A1), R=A0%8;
+	const dword A = MAKE_DWORD(A0, A1);
+	dword_union R;
+	R.dw = A0%8;
 
 	for (unsigned i=3; i<2*WORD_BITS; i*=2)
-		R = R*(2-R*A);
+		R.dw = R.dw*(2-R.dw*A);
 
-	assert(R*A==1);
+	assert(R.dw*A==1);
 
-	C[0] = LOW_WORD(R);
-	C[1] = HIGH_WORD(R);
+	C[0] = R.low;
+	C[1] = R.high;
 }
 
 // ********************************************************
@@ -792,7 +821,7 @@
 	// assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a word
 	assert(A[2] < B1 || (A[2]==B1 && A[1] < B0));
 
-	dword p, u;
+	dword_union p, u;
 	word Q;
 
 	// estimate the quotient: do a 2 word by 1 word divide
@@ -802,21 +831,21 @@
 		Q = word(MAKE_DWORD(A[1], A[2]) / (B1+1));
 
 	// now subtract Q*B from A
-	p = (dword) B0*Q;
-	u = (dword) A[0] - LOW_WORD(p);
-	A[0] = LOW_WORD(u);
-	u = (dword) A[1] - HIGH_WORD(p) - (word)(0-HIGH_WORD(u)) - (dword)B1*Q;
-	A[1] = LOW_WORD(u);
-	A[2] += HIGH_WORD(u);
+	p.dw = (dword) B0*Q;
+	u.dw = (dword) A[0] - p.low;
+	A[0] = u.low;
+	u.dw = (dword) A[1] - p.high - (word)(0-u.high) - (dword)B1*Q;
+	A[1] = u.low;
+	A[2] += u.high;
 
 	// Q <= actual quotient, so fix it
 	while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0))
 	{
-		u = (dword) A[0] - B0;
-		A[0] = LOW_WORD(u);
-		u = (dword) A[1] - B1 - (word)(0-HIGH_WORD(u));
-		A[1] = LOW_WORD(u);
-		A[2] += HIGH_WORD(u);
+		u.dw = (dword) A[0] - B0;
+		A[0] = u.low;
+		u.dw = (dword) A[1] - B1 - (word)(0-u.high);
+		A[1] = u.low;
+		A[2] += u.high;
 		Q++;
 		assert(Q);  // shouldn't overflow
 	}
