Discussion:
[PATCH] crypto/{md5,sha1,sha256,sha512}: simplify
Paul Eggert
2018-05-06 02:40:42 UTC
Permalink
* 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 <***@cs.ucla.edu>

+ 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
Loading...