diff options
Diffstat (limited to 'libhashsum.h')
-rw-r--r-- | libhashsum.h | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/libhashsum.h b/libhashsum.h new file mode 100644 index 0000000..460b86b --- /dev/null +++ b/libhashsum.h @@ -0,0 +1,344 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef LIBHASHSUM_H +#define LIBHASHSUM_H + +#include <stddef.h> +#include <stdint.h> + + +#if defined(__GNUC__) +# define LIBHASHSUM_USERET_ __attribute__((__warn_unused_result__)) +# define LIBHASHSUM_1_NONNULL_ __attribute__((__nonnull__(1))) +#else +# define LIBHASHSUM_USERET_ +# define LIBHASHSUM_1_NONNULL_ +#endif + + +/** + * Hashing algorithm + */ +enum libhashsum_algorithm { + LIBHASHSUM_MD2, /**< MD2 */ + LIBHASHSUM_MD4, /**< MD4 */ + LIBHASHSUM_MD5, /**< MD5 */ + LIBHASHSUM_RIPEMD_128, /**< RIPEMD-128 */ + LIBHASHSUM_RIPEMD_160, /**< RIPEMD-160 */ + LIBHASHSUM_RIPEMD_256, /**< RIPEMD-256 */ + LIBHASHSUM_RIPEMD_320 /**< RIPEMD-320 */ +}; + + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD2` + */ +#define LIBHASHSUM_MD2_HASH_SIZE 16 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD4` + */ +#define LIBHASHSUM_MD4_HASH_SIZE 16 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_MD5` + */ +#define LIBHASHSUM_MD5_HASH_SIZE 16 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_128` + */ +#define LIBHASHSUM_RIPEMD_128_HASH_SIZE 16 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_160` + */ +#define LIBHASHSUM_RIPEMD_160_HASH_SIZE 20 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_256` + */ +#define LIBHASHSUM_RIPEMD_256_HASH_SIZE 32 + +/** + * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RIPEMD_320` + */ +#define LIBHASHSUM_RIPEMD_320_HASH_SIZE 40 + + +/** + * Hash state + * + * For internal use + */ +union libhashsum_state { + struct { + unsigned char x[32]; + unsigned char mp[16]; + unsigned char mz[16]; + unsigned char sum[16]; + unsigned t; + } md2; + + struct { + union { + uint32_t h32[4]; + uint8_t sum[16]; + } h; + union { + uint32_t m32[16]; + uint8_t m8[64]; + } m; + uint64_t count; + } md4; + + struct { + union { + uint32_t h32[4]; + uint8_t sum[16]; + } h; + uint8_t m[64]; + uint32_t w[16]; + uint64_t count; + } md5; + + struct { + union { + uint32_t h32[4]; + uint8_t sum[16]; + } h; + union { + uint32_t m32[16]; + uint8_t m8[64]; + } m; + uint64_t count; + } ripemd_128; + + struct { + union { + uint32_t h32[5]; + uint8_t sum[20]; + } h; + union { + uint32_t m32[16]; + uint8_t m8[64]; + } m; + uint32_t w1[5]; + uint32_t w2[5]; + uint64_t count; + } ripemd_160; + + struct { + union { + uint32_t h32[8]; + uint8_t sum[32]; + } h; + union { + uint32_t m32[16]; + uint8_t m8[64]; + } m; + uint64_t count; + } ripemd_256; + + struct { + union { + uint32_t h32[10]; + uint8_t sum[40]; + } h; + union { + uint32_t m32[16]; + uint8_t m8[64]; + } m; + uint32_t w1[5]; + uint32_t w2[5]; + uint64_t count; + } ripemd_320; +}; + + +/** + * Message hash functions and state + */ +struct libhashsum_hasher { + /** + * The used hash algorithm + */ + enum libhashsum_algorithm algorithm; + + /** + * The number of bytes required for each + * call to `.process_block` + */ + size_t input_block_size; + + /** + * The number of bytes in the resulting hash + */ + size_t hash_size; + + /** + * The hash + * + * This will be set to `NULL` when the structure + * is initialised, but will be set to a pointer + * to a buffer inside `.state` once `.finalise_const` + * or `.finalise` has been called + */ + unsigned char *hash_output; + + /** + * Whether the algorithm supports non-whole octet input + */ + unsigned char supports_non_whole_bytes; + + /** + * Update the hash state given additional + * input data + * + * @param this The object containing this function pointer + * @param data The new input data + * @param bytes The number of bytes available in `data` + * @return The number of bytes processed from `data` + */ + LIBHASHSUM_USERET_ LIBHASHSUM_1_NONNULL_ + size_t (*process)(struct libhashsum_hasher *this, const void *data, size_t bytes); + + /** + * Update the hash state given it's final + * input data + * + * @param this The object containing this function pointer + * @param data The new input data + * @param bytes The number of bytes available in `data` + * @return 0 on success, -1 on failure + * + * @throws EINVAL `extra_bits` is greater than 7 + * @throws EINVAL `extra_bits` is non-zero but `.supports_non_whole_bytes` is 0 + */ + LIBHASHSUM_1_NONNULL_ + int (*finalise_const)(struct libhashsum_hasher *this, const void *data, unsigned extra_bits, size_t bytes); + + /** + * Update the hash state given it's final + * input data + * + * @param this The object containing this function pointer + * @param data The new input data, the function may rewrite it's content + * @param bytes The number of bytes available in `data` for reading + * @param size `bytes` plus any number of additional bytes available + * for the function to write additional data block padding + * @return 0 on success, -1 on failure + * + * @throws EINVAL `extra_bits` is greater than 7 + * @throws EINVAL `extra_bits` is non-zero but `.supports_non_whole_bytes` is 0 + */ + LIBHASHSUM_1_NONNULL_ + int (*finalise)(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size); + + /** + * The hash state + * + * For internal use + */ + union libhashsum_state state; +}; + + +/** + * Create an initialised state for a hash algorithm + * and return hash functions and details + * + * @param this The output parameter for the functions, details, and state + * @param algorithm The hashing algorithm + * @return 0 on success, -1 on failure + * + * @throws EINVAL `algorithm` is unsupported + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_hasher(struct libhashsum_hasher *this, enum libhashsum_algorithm algorithm); + +/** + * Create an initialised state for a MD2 + * and return hash functions and details + * + * @param this The output parameter for the functions, details, and state + * @return 0 on success, -1 on failure + * + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_md2_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a MD4 + * and return hash functions and details + * + * @param this The output parameter for the functions, details, and state + * @return 0 on success, -1 on failure + * + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_md4_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a MD5 + * and return hash functions and details + * + * @param this The output parameter for the functions, details, and state + * @return 0 on success, -1 on failure + * + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_md5_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a RIPEMD-128 + * and return hash functions and details + * + * @param this The output parameter for the functions, details, and state + * @return 0 on success, -1 on failure + * + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_ripemd_128_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a RIPEMD-160 + * and return hash functions and details + * + * @param this The output parameter for the functions, details, and state + * @return 0 on success, -1 on failure + * + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_ripemd_160_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a RIPEMD-256 + * and return hash functions and details + * + * @param this The output parameter for the functions, details, and state + * @return 0 on success, -1 on failure + * + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_ripemd_256_hasher(struct libhashsum_hasher *this); + +/** + * Create an initialised state for a RIPEMD-320 + * and return hash functions and details + * + * @param this The output parameter for the functions, details, and state + * @return 0 on success, -1 on failure + * + * Failure isn't actually possible, so this function always return 0 + */ +LIBHASHSUM_1_NONNULL_ +int libhashsum_init_ripemd_320_hasher(struct libhashsum_hasher *this); + + +#endif |