X-Git-Url: https://git.distorted.org.uk/~mdw/secnet/blobdiff_plain/b4a26b17a38c3dd1cc6e086a17649b94b0ab8e37..refs/heads/mdw/xdh:/sha512.c diff --git a/sha512.c b/sha512.c index 5c0b2ed..5fa40d2 100644 --- a/sha512.c +++ b/sha512.c @@ -22,6 +22,8 @@ #include +#include "secnet.h" + #include "sha512.h" #include @@ -171,184 +173,6 @@ sha384_finish_ctx (struct sha512_ctx *ctx, void *resbuf) return sha384_read_ctx (ctx, resbuf); } -/* 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) -{ - struct sha512_ctx ctx; - size_t sum; - - char *buffer = malloc (BLOCKSIZE + 72); - if (!buffer) - return 1; - - /* Initialize the computation context. */ - sha512_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); - - /* Construct result in desired memory. */ - sha512_finish_ctx (&ctx, resblock); - free (buffer); - return 0; -} - -/* FIXME: Avoid code duplication */ -int -sha384_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); - - /* Construct result in desired memory. */ - sha384_finish_ctx (&ctx, resblock); - free (buffer); - return 0; -} - -/* Compute SHA512 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. */ -void * -sha512_buffer (const char *buffer, size_t len, void *resblock) -{ - struct sha512_ctx ctx; - - /* Initialize the computation context. */ - sha512_init_ctx (&ctx); - - /* Process whole buffer but last len % 128 bytes. */ - sha512_process_bytes (buffer, len, &ctx); - - /* Put result in desired memory area. */ - return sha512_finish_ctx (&ctx, resblock); -} - -void * -sha384_buffer (const char *buffer, size_t len, void *resblock) -{ - struct sha512_ctx ctx; - - /* Initialize the computation context. */ - sha384_init_ctx (&ctx); - - /* Process whole buffer but last len % 128 bytes. */ - sha512_process_bytes (buffer, len, &ctx); - - /* Put result in desired memory area. */ - return sha384_finish_ctx (&ctx, resblock); -} - void sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx) { @@ -617,3 +441,34 @@ sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx) h = ctx->state[7] = u64plus (ctx->state[7], h); } } + +struct sha512 { + closure_t cl; + struct hash_if ops; +}; + +static void *sha512_init(void) + { struct sha512_ctx *ctx; NEW(ctx); sha512_init_ctx(ctx); return ctx; } + +static void sha512_update(void *st, const void *buf, int32_t len) + { struct sha512_ctx *ctx = st; sha512_process_bytes(buf, len, ctx); } + +static void sha512_final(void *st, uint8_t *digest) + { struct sha512_ctx *ctx = st; sha512_finish_ctx(ctx, digest); free(ctx); } + +void sha512_module(dict_t *dict) +{ + struct sha512 *st; + + NEW(st); + st->cl.description="sha512"; + st->cl.type=CL_HASH; + st->cl.apply=NULL; + st->cl.interface=&st->ops; + st->ops.len=64; + st->ops.init=sha512_init; + st->ops.update=sha512_update; + st->ops.final=sha512_final; + + dict_add(dict,"sha512",new_closure(&st->cl)); +}