summaryrefslogtreecommitdiff
path: root/lib/sha512.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sha512.c')
-rw-r--r--lib/sha512.c132
1 files changed, 41 insertions, 91 deletions
diff --git a/lib/sha512.c b/lib/sha512.c
index 8a6dd4e83ac..e854951eb31 100644
--- a/lib/sha512.c
+++ b/lib/sha512.c
@@ -36,18 +36,11 @@
# include "unlocked-io.h"
#endif
+#include <byteswap.h>
#ifdef WORDS_BIGENDIAN
# define SWAP(n) (n)
#else
-# define SWAP(n) \
- u64or (u64or (u64or (u64shl (n, 56), \
- u64shl (u64and (n, u64lo (0x0000ff00)), 40)), \
- u64or (u64shl (u64and (n, u64lo (0x00ff0000)), 24), \
- u64shl (u64and (n, u64lo (0xff000000)), 8))), \
- u64or (u64or (u64and (u64shr (n, 8), u64lo (0xff000000)), \
- u64and (u64shr (n, 24), u64lo (0x00ff0000))), \
- u64or (u64and (u64shr (n, 40), u64lo (0x0000ff00)), \
- u64shr (n, 56))))
+# define SWAP(n) bswap_64 (n)
#endif
#define BLOCKSIZE 32768
@@ -177,21 +170,32 @@ 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. */
-int
-sha512_stream (FILE *stream, void *resblock)
+#ifdef GL_COMPILE_CRYPTO_STREAM
+
+#include "af_alg.h"
+
+/* 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 sha512_ctx *),
+ void *(*finish_ctx) (struct sha512_ctx *, void *))
{
- struct sha512_ctx ctx;
- size_t sum;
+ switch (afalg_stream (stream, alg, resblock, hashlen))
+ {
+ case 0: return 0;
+ case -EIO: return 1;
+ }
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)
@@ -205,6 +209,14 @@ sha512_stream (FILE *stream, void *resblock)
/* Read block. Take care for partial reads. */
while (1)
{
+ /* Either process a partial fread() from this loop,
+ or the fread() in afalg_stream may have gotten EOF.
+ We need to avoid a subsequent fread() as EOF may
+ not be sticky. For details of such systems, see:
+ https://sourceware.org/bugzilla/show_bug.cgi?id=1190 */
+ if (feof (stream))
+ goto process_partial_block;
+
n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
sum += n;
@@ -224,12 +236,6 @@ sha512_stream (FILE *stream, void *resblock)
}
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
@@ -245,81 +251,25 @@ 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 = 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);
}
+#endif
#if ! HAVE_OPENSSL_SHA512
/* Compute SHA512 message digest for LEN bytes beginning at BUFFER. The