* ttyio.c (tty_enable_completion, tty_disable_completion): Add checks
[gnupg.git] / cipher / rmd160.c
index 4d64475..7a7230f 100644 (file)
@@ -1,5 +1,5 @@
 /* rmd160.c  - RIPE-MD160
- *     Copyright (C) 1998 Free Software Foundation, Inc.
+ *     Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -15,7 +15,8 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  */
 
 #include <config.h>
 #include "util.h"
 #include "memory.h"
 #include "rmd.h"
-#include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */
+#include "cipher.h" /* for rmd160_hash_buffer */
+#include "algorithms.h"
+
+#include "bithelp.h"
 
 /*********************************
  * RIPEMD-160 is not patented, see (as of 25.10.97)
  * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
  */
 
+static void
+burn_stack (int bytes)
+{
+    char buf[150];
+    
+    wipememory(buf,sizeof buf);
+    bytes -= sizeof buf;
+    if (bytes > 0)
+        burn_stack (bytes);
+}
+
+
 
 void
 rmd160_init( RMD160_CONTEXT *hd )
@@ -152,19 +168,6 @@ rmd160_init( RMD160_CONTEXT *hd )
 }
 
 
-#if defined(__GNUC__) && defined(__i386__)
-static inline u32
-rol(int n, u32 x)
-{
-       __asm__("roll %%cl,%0"
-               :"=r" (x)
-               :"0" (x),"c" (n));
-       return x;
-}
-#else
-  #define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
-#endif
-
 
 /****************
  * Transform the message X which consists of 16 32-bit-words
@@ -172,10 +175,8 @@ rol(int n, u32 x)
 static void
 transform( RMD160_CONTEXT *hd, byte *data )
 {
-
-
     u32 a,b,c,d,e,aa,bb,cc,dd,ee,t;
-  #ifdef BIG_ENDIAN_HOST
+#ifdef BIG_ENDIAN_HOST
     u32 x[16];
     { int i;
       byte *p2, *p1;
@@ -186,10 +187,10 @@ transform( RMD160_CONTEXT *hd, byte *data )
        p2[0] = *p1++;
       }
     }
-  #else
-   #if 0
+#else
+#if 0
     u32 *x =(u32*)data;
-   #else
+#else
     /* this version is better because it is always aligned;
      * The performance penalty on a 586-100 is about 6% which
      * is acceptable - because the data is more local it might
@@ -199,8 +200,8 @@ transform( RMD160_CONTEXT *hd, byte *data )
      * [measured with a 4MB data and "gpgm --print-md rmd160"] */
     u32 x[16];
     memcpy( x, data, 64 );
-   #endif
-  #endif
+#endif
+#endif
 
 
 #define K0  0x00000000
@@ -219,8 +220,8 @@ transform( RMD160_CONTEXT *hd, byte *data )
 #define F3(x,y,z)   ( ((x) & (z)) | ((y) & ~(z)) )
 #define F4(x,y,z)   ( (x) ^ ((y) | ~(z)) )
 #define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
-                                 a = rol(s,t) + e;            \
-                                 c = rol(10,c);               \
+                                 a = rol(t,s) + e;            \
+                                 c = rol(c,10);               \
                                } while(0)
 
     /* left lane */
@@ -417,6 +418,7 @@ rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
 {
     if( hd->count == 64 ) { /* flush the buffer */
        transform( hd, hd->buf );
+        burn_stack (108+5*sizeof(void*));
        hd->count = 0;
        hd->nblocks++;
     }
@@ -437,6 +439,7 @@ rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
        inlen -= 64;
        inbuf += 64;
     }
+    burn_stack (108+5*sizeof(void*));
     for( ; inlen && hd->count < 64; inlen-- )
        hd->buf[hd->count++] = *inbuf++;
 }
@@ -452,13 +455,13 @@ rmd160_mixblock( RMD160_CONTEXT *hd, char *buffer )
 {
     char *p = buffer;
     transform( hd, buffer );
-  #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
+#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
     X(0);
     X(1);
     X(2);
     X(3);
     X(4);
-  #undef X
+#undef X
 }
 
 
@@ -473,18 +476,19 @@ rmd160_final( RMD160_CONTEXT *hd )
 
     rmd160_write(hd, NULL, 0); /* flush */;
 
-    msb = 0;
     t = hd->nblocks;
-    if( (lsb = t << 6) < t ) /* multiply by 64 to make a byte count */
-       msb++;
-    msb += t >> 26;
+    /* multiply by 64 to make a byte count */
+    lsb = t << 6;
+    msb = t >> 26;
+    /* add the count */
     t = lsb;
-    if( (lsb = t + hd->count) < t ) /* add the count */
+    if( (lsb += hd->count) < t )
        msb++;
+    /* multiply by 8 to make a bit count */
     t = lsb;
-    if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
-       msb++;
-    msb += t >> 29;
+    lsb <<= 3;
+    msb <<= 3;
+    msb |= t >> 29;
 
     if( hd->count < 56 ) { /* enough room */
        hd->buf[hd->count++] = 0x80; /* pad */
@@ -508,20 +512,21 @@ rmd160_final( RMD160_CONTEXT *hd )
     hd->buf[62] = msb >> 16;
     hd->buf[63] = msb >> 24;
     transform( hd, hd->buf );
+    burn_stack (108+5*sizeof(void*));
 
     p = hd->buf;
-  #ifdef BIG_ENDIAN_HOST
-    #define X(a) do { *p++ = hd->h##a     ; *p++ = hd->h##a >> 8;      \
+#ifdef BIG_ENDIAN_HOST
+#define X(a) do { *p++ = hd->h##a         ; *p++ = hd->h##a >> 8;      \
                      *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
-  #else /* little endian */
-    #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-  #endif
+#else /* little endian */
+#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
+#endif
     X(0);
     X(1);
     X(2);
     X(3);
     X(4);
-  #undef X
+#undef X
 }
 
 static byte *
@@ -574,11 +579,10 @@ rmd160_get_info( int algo, size_t *contextsize,
     *r_asnoid = asn;
     *r_asnlen = DIM(asn);
     *r_mdlen = 20;
-    *r_init  = (void (*)(void *))rmd160_init;
-    *r_write = (void (*)(void *, byte*, size_t))rmd160_write;
-    *r_final = (void (*)(void *))rmd160_final;
-    *r_read  = (byte *(*)(void *))rmd160_read;
+    *(void  (**)(RMD160_CONTEXT *))r_init                = rmd160_init;
+    *(void  (**)(RMD160_CONTEXT *, byte*, size_t))r_write = rmd160_write;
+    *(void  (**)(RMD160_CONTEXT *))r_final               = rmd160_final;
+    *(byte *(**)(RMD160_CONTEXT *))r_read                = rmd160_read;
 
     return "RIPEMD160";
 }
-