bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] crypto/{md5,sha1,sha256,sha512}: simplify


From: Paul Eggert
Subject: [PATCH] crypto/{md5,sha1,sha256,sha512}: simplify
Date: Sat, 5 May 2018 19:40:42 -0700

* lib/md5.c (md5_stream):
* lib/sha1.c (sha1_stream):
* lib/sha256.c (shaxxx_stream):
Simplify, partly by assuming C99.
* lib/sha256.c (shaxxx_stream):
New function, which implements both sha256 and sha224.
Simplify, partly by assuming C99.
(sha256_stream, sha224_stream):
Use it to avoid code duplication, removing a FIXME.
* lib/sha512.c (shaxxx_stream, sha512_stream, sha384_stream):
Likewise.
---
 ChangeLog    |  13 +++++
 lib/md5.c    |  22 +++------
 lib/sha1.c   |  22 +++------
 lib/sha256.c | 136 +++++++++++++--------------------------------------
 lib/sha512.c | 122 ++++++++++-----------------------------------
 5 files changed, 88 insertions(+), 227 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7f1f5b032..6c0af783d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2018-05-05  Paul Eggert  <address@hidden>
 
+       crypto/{md5,sha1,sha256,sha512}: simplify
+       * lib/md5.c (md5_stream):
+       * lib/sha1.c (sha1_stream):
+       * lib/sha256.c (shaxxx_stream):
+       Simplify, partly by assuming C99.
+       * lib/sha256.c (shaxxx_stream):
+       New function, which implements both sha256 and sha224.
+       Simplify, partly by assuming C99.
+       (sha256_stream, sha224_stream):
+       Use it to avoid code duplication, removing a FIXME.
+       * lib/sha512.c (shaxxx_stream, sha512_stream, sha384_stream):
+       Likewise.
+
        af_alg: Improve comments.
        * lib/af_alg.h: Use imperatives and tighten up wording.
 
diff --git a/lib/md5.c b/lib/md5.c
index 2bf2f0c75..9b414aaf8 100644
--- a/lib/md5.c
+++ b/lib/md5.c
@@ -142,25 +142,19 @@ md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
 int
 md5_stream (FILE *stream, void *resblock)
 {
-  struct md5_ctx ctx;
-  size_t sum;
-  char *buffer;
-
-  {
-    int ret = afalg_stream (stream, "md5", resblock, MD5_DIGEST_SIZE);
-    if (!ret)
-      return 0;
-
-    if (ret == -EIO)
-      return 1;
-  }
+  switch (afalg_stream (stream, "md5", resblock, MD5_DIGEST_SIZE))
+    {
+    case 0: return 0;
+    case -EIO: return 1;
+    }
 
-  buffer = malloc (BLOCKSIZE + 72);
+  char *buffer = malloc (BLOCKSIZE + 72);
   if (!buffer)
     return 1;
 
-  /* Initialize the computation context.  */
+  struct md5_ctx ctx;
   md5_init_ctx (&ctx);
+  size_t sum;
 
   /* Iterate over full file contents.  */
   while (1)
diff --git a/lib/sha1.c b/lib/sha1.c
index e7cd2a305..847e452b7 100644
--- a/lib/sha1.c
+++ b/lib/sha1.c
@@ -130,25 +130,19 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
 int
 sha1_stream (FILE *stream, void *resblock)
 {
-  struct sha1_ctx ctx;
-  size_t sum;
-  char *buffer;
-
-  {
-    int ret = afalg_stream (stream, "sha1", resblock, SHA1_DIGEST_SIZE);
-    if (!ret)
-      return 0;
-
-    if (ret == -EIO)
-      return 1;
-  }
+  switch (afalg_stream (stream, "sha1", resblock, SHA1_DIGEST_SIZE))
+    {
+    case 0: return 0;
+    case -EIO: return 1;
+    }
 
-  buffer = malloc (BLOCKSIZE + 72);
+  char *buffer = malloc (BLOCKSIZE + 72);
   if (!buffer)
     return 1;
 
-  /* Initialize the computation context.  */
+  struct sha1_ctx ctx;
   sha1_init_ctx (&ctx);
+  size_t sum;
 
   /* Iterate over full file contents.  */
   while (1)
diff --git a/lib/sha256.c b/lib/sha256.c
index 410bd98c2..5503c209f 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -93,17 +93,17 @@ sha224_init_ctx (struct sha256_ctx *ctx)
   ctx->buflen = 0;
 }
 
-/* Copy the value from v into the memory location pointed to by *cp,
-   If your architecture allows unaligned access this is equivalent to
-   * (uint32_t *) cp = v  */
+/* Copy the value from v into the memory location pointed to by *CP,
+   If your architecture allows unaligned access, this is equivalent to
+   * (__typeof__ (v) *) cp = v  */
 static void
 set_uint32 (char *cp, uint32_t v)
 {
   memcpy (cp, &v, sizeof v);
 }
 
-/* Put result from CTX in first 32 bytes following RESBUF.  The result
-   must be in little endian byte order.  */
+/* Put result from CTX in first 32 bytes following RESBUF.
+   The result must be in little endian byte order.  */
 void *
 sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf)
 {
@@ -171,31 +171,28 @@ sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
 }
 #endif
 
-/* Compute SHA256 message digest for bytes read from STREAM.  The
-   resulting message digest number will be written into the 32 bytes
-   beginning at RESBLOCK.  */
-int
-sha256_stream (FILE *stream, void *resblock)
+/* Compute message digest for bytes read from STREAM using algorithm ALG.
+   Write the message digest into RESBLOCK, which contains HASHLEN bytes.
+   The initial and finishing operations are INIT_CTX and FINISH_CTX.
+   Return zero if and only if successful.  */
+static int
+shaxxx_stream (FILE *stream, char const *alg, void *resblock,
+               ssize_t hashlen, void (*init_ctx) (struct sha256_ctx *),
+               void *(*finish_ctx) (struct sha256_ctx *, void *))
 {
-  struct sha256_ctx ctx;
-  size_t sum;
-  char *buffer;
-
-  {
-    int ret = afalg_stream (stream, "sha256", resblock, SHA256_DIGEST_SIZE);
-    if (!ret)
-      return 0;
-
-    if (ret == -EIO)
-      return 1;
-  }
+  switch (afalg_stream (stream, alg, resblock, hashlen))
+    {
+    case 0: return 0;
+    case -EIO: return 1;
+    }
 
-  buffer = malloc (BLOCKSIZE + 72);
+  char *buffer = malloc (BLOCKSIZE + 72);
   if (!buffer)
     return 1;
 
-  /* Initialize the computation context.  */
-  sha256_init_ctx (&ctx);
+  struct sha256_ctx ctx;
+  init_ctx (&ctx);
+  size_t sum;
 
   /* Iterate over full file contents.  */
   while (1)
@@ -249,94 +246,27 @@ sha256_stream (FILE *stream, void *resblock)
     sha256_process_bytes (buffer, sum, &ctx);
 
   /* Construct result in desired memory.  */
-  sha256_finish_ctx (&ctx, resblock);
+  finish_ctx (&ctx, resblock);
   free (buffer);
   return 0;
 }
 
-/* FIXME: Avoid code duplication */
 int
-sha224_stream (FILE *stream, void *resblock)
+sha256_stream (FILE *stream, void *resblock)
 {
-  struct sha256_ctx ctx;
-  size_t sum;
-  char *buffer;
-
-  {
-    int ret = afalg_stream(stream, "sha224", resblock, SHA224_DIGEST_SIZE);
-    if (!ret)
-      return 0;
-
-    if (ret == -EIO)
-      return 1;
-  }
-
-  buffer = malloc (BLOCKSIZE + 72);
-  if (!buffer)
-    return 1;
-
-  /* Initialize the computation context.  */
-  sha224_init_ctx (&ctx);
-
-  /* Iterate over full file contents.  */
-  while (1)
-    {
-      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
-         computation function processes the whole buffer so that with the
-         next round of the loop another block can be read.  */
-      size_t n;
-      sum = 0;
-
-      /* Read block.  Take care for partial reads.  */
-      while (1)
-        {
-          n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
-
-          sum += n;
-
-          if (sum == BLOCKSIZE)
-            break;
-
-          if (n == 0)
-            {
-              /* Check for the error flag IFF N == 0, so that we don't
-                 exit the loop after a partial read due to e.g., EAGAIN
-                 or EWOULDBLOCK.  */
-              if (ferror (stream))
-                {
-                  free (buffer);
-                  return 1;
-                }
-              goto process_partial_block;
-            }
-
-          /* We've read at least one byte, so ignore errors.  But always
-             check for EOF, since feof may be true even though N > 0.
-             Otherwise, we could end up calling fread after EOF.  */
-          if (feof (stream))
-            goto process_partial_block;
-        }
-
-      /* Process buffer with BLOCKSIZE bytes.  Note that
-                        BLOCKSIZE % 64 == 0
-       */
-      sha256_process_block (buffer, BLOCKSIZE, &ctx);
-    }
-
- process_partial_block:;
-
-  /* Process any remaining bytes.  */
-  if (sum > 0)
-    sha256_process_bytes (buffer, sum, &ctx);
+  return shaxxx_stream (stream, "sha256", resblock, SHA256_DIGEST_SIZE,
+                        sha256_init_ctx, sha256_finish_ctx);
+}
 
-  /* Construct result in desired memory.  */
-  sha224_finish_ctx (&ctx, resblock);
-  free (buffer);
-  return 0;
+int
+sha224_stream (FILE *stream, void *resblock)
+{
+  return shaxxx_stream (stream, "sha224", resblock, SHA224_DIGEST_SIZE,
+                        sha224_init_ctx, sha224_finish_ctx);
 }
 
 #if ! HAVE_OPENSSL_SHA256
-/* Compute SHA512 message digest for LEN bytes beginning at BUFFER.  The
+/* Compute SHA256 message digest for LEN bytes beginning at BUFFER.  The
    result is always in little endian byte order, so that a byte-wise
    output yields to the wanted ASCII representation of the message
    digest.  */
diff --git a/lib/sha512.c b/lib/sha512.c
index 7a0234828..af0776c72 100644
--- a/lib/sha512.c
+++ b/lib/sha512.c
@@ -179,31 +179,28 @@ sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
 }
 #endif
 
-/* Compute SHA512 message digest for bytes read from STREAM.  The
-   resulting message digest number will be written into the 64 bytes
-   beginning at RESBLOCK.  */
+/* Compute message digest for bytes read from STREAM using algorithm ALG.
+   Write the message digest into RESBLOCK, which contains HASHLEN bytes.
+   The initial and finishing operations are INIT_CTX and FINISH_CTX.
+   Return zero if and only if successful.  */
 int
-sha512_stream (FILE *stream, void *resblock)
+shaxxx_stream (FILE *stream, char const *alg, void *resblock,
+               ssize_t hashlen, void (*init_ctx) (struct sha512_ctx *),
+               void *(*finish_ctx) (struct sha512_ctx *, void *))
 {
-  struct sha512_ctx ctx;
-  size_t sum;
-  char *buffer;
-
-  {
-    int ret = afalg_stream (stream, "sha512", resblock, SHA512_DIGEST_SIZE);
-    if (!ret)
-      return 0;
-
-    if (ret == -EIO)
-      return 1;
-  }
+  switch (afalg_stream (stream, alg, resblock, hashlen))
+    {
+    case 0: return 0;
+    case -EIO: return 1;
+    }
 
-  buffer = malloc (BLOCKSIZE + 72);
+  char *buffer = malloc (BLOCKSIZE + 72);
   if (!buffer)
     return 1;
 
-  /* Initialize the computation context.  */
-  sha512_init_ctx (&ctx);
+  struct sha512_ctx ctx;
+  init_ctx (&ctx);
+  size_t sum;
 
   /* Iterate over full file contents.  */
   while (1)
@@ -257,90 +254,23 @@ sha512_stream (FILE *stream, void *resblock)
     sha512_process_bytes (buffer, sum, &ctx);
 
   /* Construct result in desired memory.  */
-  sha512_finish_ctx (&ctx, resblock);
+  finish_ctx (&ctx, resblock);
   free (buffer);
   return 0;
 }
 
-/* FIXME: Avoid code duplication */
 int
-sha384_stream (FILE *stream, void *resblock)
+sha512_stream (FILE *stream, void *resblock)
 {
-  struct sha512_ctx ctx;
-  size_t sum;
-  char *buffer;
-
-  {
-    int ret = afalg_stream(stream, "sha384", resblock, SHA384_DIGEST_SIZE);
-    if (!ret)
-      return 0;
-
-    if (ret == -EIO)
-      return 1;
-  }
-
-  buffer = malloc (BLOCKSIZE + 72);
-  if (!buffer)
-    return 1;
-
-  /* Initialize the computation context.  */
-  sha384_init_ctx (&ctx);
-
-  /* Iterate over full file contents.  */
-  while (1)
-    {
-      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
-         computation function processes the whole buffer so that with the
-         next round of the loop another block can be read.  */
-      size_t n;
-      sum = 0;
-
-      /* Read block.  Take care for partial reads.  */
-      while (1)
-        {
-          n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
-
-          sum += n;
-
-          if (sum == BLOCKSIZE)
-            break;
-
-          if (n == 0)
-            {
-              /* Check for the error flag IFF N == 0, so that we don't
-                 exit the loop after a partial read due to e.g., EAGAIN
-                 or EWOULDBLOCK.  */
-              if (ferror (stream))
-                {
-                  free (buffer);
-                  return 1;
-                }
-              goto process_partial_block;
-            }
-
-          /* We've read at least one byte, so ignore errors.  But always
-             check for EOF, since feof may be true even though N > 0.
-             Otherwise, we could end up calling fread after EOF.  */
-          if (feof (stream))
-            goto process_partial_block;
-        }
-
-      /* Process buffer with BLOCKSIZE bytes.  Note that
-                        BLOCKSIZE % 128 == 0
-       */
-      sha512_process_block (buffer, BLOCKSIZE, &ctx);
-    }
-
- process_partial_block:;
-
-  /* Process any remaining bytes.  */
-  if (sum > 0)
-    sha512_process_bytes (buffer, sum, &ctx);
+  return shaxxx_stream (stream, "sha512", resblock, SHA512_DIGEST_SIZE,
+                        sha512_init_ctx, sha512_finish_ctx);
+}
 
-  /* Construct result in desired memory.  */
-  sha384_finish_ctx (&ctx, resblock);
-  free (buffer);
-  return 0;
+int
+sha384_stream (FILE *stream, void *resblock)
+{
+  return shaxxx_stream (stream, "sha384", resblock, SHA384_DIGEST_SIZE,
+                        sha384_init_ctx, sha384_finish_ctx);
 }
 
 #if ! HAVE_OPENSSL_SHA512
-- 
2.17.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]