[PATCH 5/7] Optimizations for digest final functions

Jussi Kivilinna jussi.kivilinna at iki.fi
Fri Apr 5 19:26:05 CEST 2019


* cipher/md4.c (md4_final): Avoid byte-by-byte buffer setting when
padding; Merge extra and last block processing.
* cipher/md5.c (md5_final): Ditto.
* cipher/rmd160.c (rmd160_final): Ditto.
* cipher/sha1.c (sha1_final): Ditto.
* cipher/sha256.c (sha256_final): Ditto.
* cipher/sm3.c (sm3_final): Ditto.
* cipher/tiger.c (tiger_final): Ditto.
* cipher/sha512.c (sha512_final): Avoid byte-by-byte buffer setting
when padding.
* cipher/stribog.c (stribog_final): Ditto.
* cipher/whirlpool.c (whirlpool_final): Ditto.
--

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 0 files changed

diff --git a/cipher/md4.c b/cipher/md4.c
index 098380801..997dbe0ce 100644
--- a/cipher/md4.c
+++ b/cipher/md4.c
@@ -234,25 +234,30 @@ md4_final( void *context )
   msb <<= 3;
   msb |= t >> 29;
 
-  if( hd->bctx.count < 56 )  /* enough room */
+  if (hd->bctx.count < 56)  /* enough room */
     {
       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
-      while( hd->bctx.count < 56 )
-        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
+      if (hd->bctx.count < 56)
+	memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+      hd->bctx.count = 56;
+
+      /* append the 64 bit count */
+      buf_put_le32(hd->bctx.buf + 56, lsb);
+      buf_put_le32(hd->bctx.buf + 60, msb);
+      burn = transform (hd, hd->bctx.buf, 1);
     }
   else /* need one extra block */
     {
       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
-      while( hd->bctx.count < 64 )
-        hd->bctx.buf[hd->bctx.count++] = 0;
-      _gcry_md_block_write(hd, NULL, 0);  /* flush */;
-      memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
+      /* fill pad and next block with zeroes */
+      memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+      hd->bctx.count = 64 + 56;
+
+      /* append the 64 bit count */
+      buf_put_le32(hd->bctx.buf + 56, lsb);
+      buf_put_le32(hd->bctx.buf + 60, msb);
+      burn = transform (hd, hd->bctx.buf, 2);
     }
-  /* append the 64 bit count */
-  buf_put_le32(hd->bctx.buf + 56, lsb);
-  buf_put_le32(hd->bctx.buf + 60, msb);
-  burn = transform ( hd, hd->bctx.buf, 1 );
-  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0)
@@ -262,6 +267,7 @@ md4_final( void *context )
   X(D);
 #undef X
 
+  _gcry_burn_stack (burn);
 }
 
 static byte *
diff --git a/cipher/md5.c b/cipher/md5.c
index e35a500c4..c432502ff 100644
--- a/cipher/md5.c
+++ b/cipher/md5.c
@@ -258,25 +258,30 @@ md5_final( void *context)
   msb <<= 3;
   msb |= t >> 29;
 
-  if( hd->bctx.count < 56 )  /* enough room */
+  if (hd->bctx.count < 56)  /* enough room */
     {
       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
-      while( hd->bctx.count < 56 )
-        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
+      if (hd->bctx.count < 56)
+	memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+      hd->bctx.count = 56;
+
+      /* append the 64 bit count */
+      buf_put_le32(hd->bctx.buf + 56, lsb);
+      buf_put_le32(hd->bctx.buf + 60, msb);
+      burn = transform (hd, hd->bctx.buf, 1);
     }
-  else  /* need one extra block */
+  else /* need one extra block */
     {
       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
-      while( hd->bctx.count < 64 )
-        hd->bctx.buf[hd->bctx.count++] = 0;
-      _gcry_md_block_write(hd, NULL, 0);  /* flush */;
-      memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
+      /* fill pad and next block with zeroes */
+      memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+      hd->bctx.count = 64 + 56;
+
+      /* append the 64 bit count */
+      buf_put_le32(hd->bctx.buf + 56, lsb);
+      buf_put_le32(hd->bctx.buf + 60, msb);
+      burn = transform (hd, hd->bctx.buf, 2);
     }
-  /* append the 64 bit count */
-  buf_put_le32(hd->bctx.buf + 56, lsb);
-  buf_put_le32(hd->bctx.buf + 60, msb);
-  burn = transform ( hd, hd->bctx.buf, 1 );
-  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #define X(a) do { buf_put_le32(p, hd->a); p += 4; } while(0)
@@ -286,6 +291,7 @@ md5_final( void *context)
   X(D);
 #undef X
 
+  _gcry_burn_stack (burn);
 }
 
 static byte *
diff --git a/cipher/rmd160.c b/cipher/rmd160.c
index 2d2fae916..231640d27 100644
--- a/cipher/rmd160.c
+++ b/cipher/rmd160.c
@@ -431,25 +431,30 @@ rmd160_final( void *context )
   msb <<= 3;
   msb |= t >> 29;
 
-  if( hd->bctx.count < 56 )  /* enough room */
+  if (hd->bctx.count < 56)  /* enough room */
     {
       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
-      while( hd->bctx.count < 56 )
-        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
+      if (hd->bctx.count < 56)
+	memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+      hd->bctx.count = 56;
+
+      /* append the 64 bit count */
+      buf_put_le32(hd->bctx.buf + 56, lsb);
+      buf_put_le32(hd->bctx.buf + 60, msb);
+      burn = transform (hd, hd->bctx.buf, 1);
     }
-  else  /* need one extra block */
+  else /* need one extra block */
     {
       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
-      while( hd->bctx.count < 64 )
-        hd->bctx.buf[hd->bctx.count++] = 0;
-      _gcry_md_block_write(hd, NULL, 0);  /* flush */;
-      memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
+      /* fill pad and next block with zeroes */
+      memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+      hd->bctx.count = 64 + 56;
+
+      /* append the 64 bit count */
+      buf_put_le32(hd->bctx.buf + 56, lsb);
+      buf_put_le32(hd->bctx.buf + 60, msb);
+      burn = transform (hd, hd->bctx.buf, 2);
     }
-  /* append the 64 bit count */
-  buf_put_le32(hd->bctx.buf + 56, lsb);
-  buf_put_le32(hd->bctx.buf + 60, msb);
-  burn = transform ( hd, hd->bctx.buf, 1 );
-  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #define X(a) do { buf_put_le32(p, hd->h##a); p += 4; } while(0)
@@ -459,6 +464,8 @@ rmd160_final( void *context )
   X(3);
   X(4);
 #undef X
+
+  _gcry_burn_stack (burn);
 }
 
 static byte *
diff --git a/cipher/sha256.c b/cipher/sha256.c
index e82a9d902..327e1029f 100644
--- a/cipher/sha256.c
+++ b/cipher/sha256.c
@@ -498,25 +498,30 @@ sha256_final(void *context)
   msb <<= 3;
   msb |= t >> 29;
 
-  if (hd->bctx.count < 56)
-    { /* enough room */
+  if (hd->bctx.count < 56)  /* enough room */
+    {
       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
-      while (hd->bctx.count < 56)
-        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
+      if (hd->bctx.count < 56)
+	memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+      hd->bctx.count = 56;
+
+      /* append the 64 bit count */
+      buf_put_be32(hd->bctx.buf + 56, msb);
+      buf_put_be32(hd->bctx.buf + 60, lsb);
+      burn = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 1);
     }
-  else
-    { /* need one extra block */
+  else  /* need one extra block */
+    {
       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
-      while (hd->bctx.count < 64)
-        hd->bctx.buf[hd->bctx.count++] = 0;
-      _gcry_md_block_write (hd, NULL, 0);  /* flush */;
-      memset (hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
+      /* fill pad and next block with zeroes */
+      memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+      hd->bctx.count = 64 + 56;
+
+      /* append the 64 bit count */
+      buf_put_be32(hd->bctx.buf + 64 + 56, msb);
+      buf_put_be32(hd->bctx.buf + 64 + 60, lsb);
+      burn = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 2);
     }
-  /* append the 64 bit count */
-  buf_put_be32(hd->bctx.buf + 56, msb);
-  buf_put_be32(hd->bctx.buf + 60, lsb);
-  burn = (*hd->bctx.bwrite) (hd, hd->bctx.buf, 1);
-  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0)
@@ -529,6 +534,8 @@ sha256_final(void *context)
   X(6);
   X(7);
 #undef X
+
+  _gcry_burn_stack (burn);
 }
 
 static byte *
diff --git a/cipher/sha512.c b/cipher/sha512.c
index 721f34054..615b55357 100644
--- a/cipher/sha512.c
+++ b/cipher/sha512.c
@@ -659,14 +659,16 @@ sha512_final (void *context)
   if (hd->bctx.count < 112)
     {				/* enough room */
       hd->bctx.buf[hd->bctx.count++] = 0x80;	/* pad */
-      while (hd->bctx.count < 112)
-        hd->bctx.buf[hd->bctx.count++] = 0;	/* pad */
+      if (hd->bctx.count < 112)
+	memset (&hd->bctx.buf[hd->bctx.count], 0, 112 - hd->bctx.count);
+      hd->bctx.count = 112;
     }
   else
     {				/* need one extra block */
       hd->bctx.buf[hd->bctx.count++] = 0x80;	/* pad character */
-      while (hd->bctx.count < 128)
-        hd->bctx.buf[hd->bctx.count++] = 0;
+      if (hd->bctx.count < 128)
+	memset (&hd->bctx.buf[hd->bctx.count], 0, 128 - hd->bctx.count);
+      hd->bctx.count = 128;
       _gcry_md_block_write (context, NULL, 0); /* flush */ ;
       memset (hd->bctx.buf, 0, 112);	/* fill next block with zeroes */
     }
diff --git a/cipher/sm3.c b/cipher/sm3.c
index c6f1a091d..7bfb37b95 100644
--- a/cipher/sm3.c
+++ b/cipher/sm3.c
@@ -291,25 +291,30 @@ sm3_final(void *context)
   msb <<= 3;
   msb |= t >> 29;
 
-  if (hd->bctx.count < 56)
-    { /* enough room */
+  if (hd->bctx.count < 56)  /* enough room */
+    {
       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
-      while (hd->bctx.count < 56)
-        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
+      if (hd->bctx.count < 56)
+	memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+      hd->bctx.count = 56;
+
+      /* append the 64 bit count */
+      buf_put_be32(hd->bctx.buf + 56, msb);
+      buf_put_be32(hd->bctx.buf + 60, lsb);
+      burn = (*hd->bctx.bwrite) ( hd, hd->bctx.buf, 1 );
     }
-  else
-    { /* need one extra block */
+  else  /* need one extra block */
+    {
       hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
-      while (hd->bctx.count < 64)
-        hd->bctx.buf[hd->bctx.count++] = 0;
-      _gcry_md_block_write (hd, NULL, 0);  /* flush */;
-      memset (hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
+      /* fill pad and next block with zeroes */
+      memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+      hd->bctx.count = 64 + 56;
+
+      /* append the 64 bit count */
+      buf_put_be32(hd->bctx.buf + 64 + 56, msb);
+      buf_put_be32(hd->bctx.buf + 64 + 60, lsb);
+      burn = (*hd->bctx.bwrite) ( hd, hd->bctx.buf, 2 );
     }
-  /* append the 64 bit count */
-  buf_put_be32(hd->bctx.buf + 56, msb);
-  buf_put_be32(hd->bctx.buf + 60, lsb);
-  burn = transform (hd, hd->bctx.buf, 1);
-  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #define X(a) do { buf_put_be32(p, hd->h##a); p += 4; } while(0)
@@ -322,6 +327,8 @@ sm3_final(void *context)
   X(6);
   X(7);
 #undef X
+
+  _gcry_burn_stack (burn);
 }
 
 static byte *
diff --git a/cipher/stribog.c b/cipher/stribog.c
index 459e4db99..d31dddd37 100644
--- a/cipher/stribog.c
+++ b/cipher/stribog.c
@@ -1292,8 +1292,9 @@ stribog_final (void *context)
   i = hd->bctx.count;
   /* After flush we have at least one byte free) */
   hd->bctx.buf[i++] = 1;
-  while (i < 64)
-    hd->bctx.buf[i++] = 0;
+  if (i < 64)
+    memset (&hd->bctx.buf[i], 0, 64 - i);
+  i = 64;
   transform_bits (hd, hd->bctx.buf, hd->bctx.count * 8);
 
   g (hd->h, hd->N, Z);
diff --git a/cipher/tiger.c b/cipher/tiger.c
index d24d1603b..0319b7115 100644
--- a/cipher/tiger.c
+++ b/cipher/tiger.c
@@ -760,22 +760,26 @@ tiger_final( void *context )
   if( hd->bctx.count < 56 )  /* enough room */
     {
       hd->bctx.buf[hd->bctx.count++] = pad;
-      while( hd->bctx.count < 56 )
-        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
+      if (hd->bctx.count < 56)
+	memset (&hd->bctx.buf[hd->bctx.count], 0, 56 - hd->bctx.count);
+      hd->bctx.count = 56;
+      /* append the 64 bit count */
+      buf_put_le32(hd->bctx.buf + 56, lsb);
+      buf_put_le32(hd->bctx.buf + 60, msb);
+      burn = transform( hd, hd->bctx.buf, 1 );
     }
   else  /* need one extra block */
     {
       hd->bctx.buf[hd->bctx.count++] = pad; /* pad character */
-      while( hd->bctx.count < 64 )
-        hd->bctx.buf[hd->bctx.count++] = 0;
-      _gcry_md_block_write(hd, NULL, 0);  /* flush */;
-      memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
+      /* fill pad and next block with zeroes */
+      memset (&hd->bctx.buf[hd->bctx.count], 0, 64 - hd->bctx.count + 56);
+      hd->bctx.count = 64 + 56;
+
+      /* append the 64 bit count */
+      buf_put_le32(hd->bctx.buf + 64 + 56, lsb);
+      buf_put_le32(hd->bctx.buf + 64 + 60, msb);
+      burn = transform( hd, hd->bctx.buf, 2 );
     }
-  /* append the 64 bit count */
-  buf_put_le32(hd->bctx.buf + 56, lsb);
-  buf_put_le32(hd->bctx.buf + 60, msb);
-  burn = transform( hd, hd->bctx.buf, 1 );
-  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #define X(a) do { buf_put_be64(p, hd->a); p += 8; } while(0)
@@ -794,6 +798,8 @@ tiger_final( void *context )
     }
 #undef X
 #undef Y
+
+  _gcry_burn_stack (burn);
 }
 
 static byte *
diff --git a/cipher/whirlpool.c b/cipher/whirlpool.c
index d52375ada..d9b79cf1a 100644
--- a/cipher/whirlpool.c
+++ b/cipher/whirlpool.c
@@ -1494,12 +1494,16 @@ whirlpool_final (void *ctx)
   if (context->bctx.count > 32)
     {
       /* An extra block is necessary.  */
-      while (context->bctx.count < 64)
-	context->bctx.buf[context->bctx.count++] = 0;
+      if (context->bctx.count < 64)
+	memset (&context->bctx.buf[context->bctx.count], 0,
+	        64 - context->bctx.count);
+      context->bctx.count = 64;
       whirlpool_write (context, NULL, 0);
     }
-  while (context->bctx.count < 32)
-    context->bctx.buf[context->bctx.count++] = 0;
+  if (context->bctx.count < 32)
+    memset (&context->bctx.buf[context->bctx.count], 0,
+	    32 - context->bctx.count);
+  context->bctx.count = 32;
 
   /* Add length of message.  */
   length = context->bctx.buf + context->bctx.count;




More information about the Gcrypt-devel mailing list