diff options
Diffstat (limited to 'libhashsum_init_sha2_hasher.c')
-rw-r--r-- | libhashsum_init_sha2_hasher.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/libhashsum_init_sha2_hasher.c b/libhashsum_init_sha2_hasher.c new file mode 100644 index 0000000..ab64517 --- /dev/null +++ b/libhashsum_init_sha2_hasher.c @@ -0,0 +1,93 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +LIBHASHSUM_1_NONNULL_ +static size_t +process(struct libhashsum_hasher *this, const void *data, size_t bytes) +{ + const uint8_t *m = data; + int i; + bytes -= bytes & (this->input_block_size - 1U); + if (bytes > SIZE_MAX >> 3) { + for (i = 0; i < 8; i++) { + libsha2_update(&this->state.sha2.s, m, bytes); + m = &m[bytes >> 3]; + } + } else if (bytes) { + libsha2_update(&this->state.sha2.s, m, bytes << 3); + } + return bytes; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise_const(struct libhashsum_hasher *this, const void *data, size_t bytes, unsigned extra_bits) +{ + const uint8_t *m = data; + size_t r; + + if (extra_bits > 7U) { + errno = EINVAL; + return -1; + } + + r = process(this, m, bytes); + m = &m[r]; + bytes -= r; + + libsha2_digest(&this->state.sha2.s, data, (bytes << 3) | extra_bits, this->state.sha2.sum); + memset(&this->state.sha2.s, 0, sizeof(this->state.sha2.s)); + this->hash_output = this->state.sha2.sum; + return 0; +} + + +LIBHASHSUM_1_NONNULL_ +static int +finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size) +{ + (void) size; + return finalise_const(this, data, bytes, extra_bits); +} + + +int +libhashsum_init_sha2_hasher(struct libhashsum_hasher *this, unsigned algobits, size_t hashbits) +{ + enum libsha2_algorithm algo; + + if (algobits == 32U && hashbits == 224U) { + this->algorithm = LIBHASHSUM_SHA_224; + algo = LIBSHA2_224; + } else if (algobits == 32U && hashbits == 256U) { + this->algorithm = LIBHASHSUM_SHA_256; + algo = LIBSHA2_256; + } else if (algobits == 64U && hashbits == 384U) { + this->algorithm = LIBHASHSUM_SHA_384; + algo = LIBSHA2_384; + } else if (algobits == 64U && hashbits == 512U) { + this->algorithm = LIBHASHSUM_SHA_512; + algo = LIBSHA2_512; + } else if (algobits == 64U && hashbits == 224U) { + this->algorithm = LIBHASHSUM_SHA_512_224; + algo = LIBSHA2_512_224; + } else if (algobits == 64U && hashbits == 256U) { + this->algorithm = LIBHASHSUM_SHA_512_256; + algo = LIBSHA2_512_256; + } else { + errno = EINVAL; + return -1; + } + + this->input_block_size = (size_t)algobits << 1; + this->hash_size = hashbits >> 3; + this->hash_output = NULL; + this->supports_non_whole_bytes = 1; + this->process = &process; + this->finalise_const = &finalise_const; + this->finalise = &finalise; + libsha2_init(&this->state.sha2.s, algo); + return 0; +} |