* 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 <egg...@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