diff options
Diffstat (limited to '')
| -rw-r--r-- | libsha2.h | 268 | 
1 files changed, 268 insertions, 0 deletions
| diff --git a/libsha2.h b/libsha2.h new file mode 100644 index 0000000..5b37130 --- /dev/null +++ b/libsha2.h @@ -0,0 +1,268 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef LIBSHA2_H +#define LIBSHA2_H  1 + +#include <stdint.h> +#include <stddef.h> + + +/** + * Algorithms supported by libsha2 + */ +enum libsha2_algorithm { +	/** +	 * SHA-224, outputs 28 bytes +	 */ +	LIBSHA2_224, + +	/** +	 * SHA-256, outputs 32 bytes +	 */ +	LIBSHA2_256, + +	/** +	 * SHA-384, outputs 48 bytes +	 */ +	LIBSHA2_384, + +	/** +	 * SHA-512, outputs 64 bytes +	 */ +	LIBSHA2_512, + +	/** +	 * SHA-512/224, outputs 28 bytes +	 */ +	LIBSHA2_512_224, + +	/** +	 * SHA-512/256, outputs 32 bytes +	 */ +	LIBSHA2_512_256 +}; + +/** + * Data structure that describes the state of a hashing process + *  + * Data that could just as well be allocated (with `auto`) are + * allocated here so that is is easier to wipe the data without + * exposing two versions of each function: one to wipe data, + * and one not to wipe data to gain speed, now you can use use + * `explicit_bzero` (or `memset`) when you are done. + *  + * This data structure is flat (it contains dynamic pointers) + * and can be marshalled and unmarshalled naïvely, and does + * not need destroyed; however, if you when to marshall it + * using as little memory as possible, this are comments + * about data that does not need to be mashalled + */ +struct libsha2_state { +	/** +	 * The size of the message, as far as processed, in bits; +	 */ +	size_t message_size; + +	/** +	 * Round constants +	 */ +	union { +		/** +		 * For 32-bit algorithms +		 */ +		uint32_t b32[64]; +     +		/** +		 * For 64-bit algorithms +		 */ +		uint64_t b64[80]; +	} k; + +	/** +	 * Words +	 *  +	 * Does not need to be marshalled +	 */ +	union { +		/** +		 * For 32-bit algorithms +		 */ +		uint32_t b32[64]; + +		/** +		 * For 64-bit algorithms +		 */ +		uint64_t b64[80]; +	} w; + +	/** +	 * Hashing values +	 */ +	union { +		/** +		 * For 32-bit algorithms +		 */ +		uint32_t b32[8]; + +		/** +		 * For 64-bit algorithms +		 */ +		uint64_t b64[8]; +	} h; + +	/** +	 * Temporary hashing values +	 *  +	 * Does not need to be marshalled +	 */ +	union { +		/** +		 * For 32-bit algorithms +		 */ +		uint32_t b32[8]; + +		/** +		 * For 64-bit algorithms +		 */ +		uint64_t b64[8]; +	} work_h; + +	/** +	 * Space for chunks to process, limited +	 * to 64 bytes on 32-bit algorithms +	 */ +	unsigned char chunk[128]; + +	/** +	 * Space for storing the last bits and +	 * the padding +	 *  +	 * Does not need to be marshalled +	 */ +	char appendix[256]; + +	/** +	 * The size of the chunks, in bytes +	 */ +	size_t chunk_size; + +	/** +	 * The algorithm that is used +	 */ +	enum libsha2_algorithm algorithm; + +	int __padding1; +}; + + +/** + * Initialise a state + *  + * @parma   state      The state that should be initialised + * @parma   algorithm  The hashing algorithm + * @return             Zero on success, -1 on error + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nothrow__, __nonnull__)) +#endif +int libsha2_state_initialise(struct libsha2_state *restrict, enum libsha2_algorithm); + +/** + * Get the output size of the algorithm specified for a state + *  + * @parma   state  The state + * @return         The number of bytes in the output, zero on error + */ +#if defined(__GNUC__) +__attribute__((__nothrow__, __nonnull__, __pure__)) +#endif +size_t libsha2_state_output_size(const struct libsha2_state *restrict); + +/** + * Get the output size of an algorithm + *  + * @parma   algorithm  The hashing algorithm + * @return             The number of bytes in the output, zero on error + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nothrow__, __const__)) +#endif +size_t libsha2_algorithm_output_size(enum libsha2_algorithm); + +/** + * Absorb more of the message + *  + * @param  state    The hashing state + * @param  message  The message, in bits, must be equivalent to 0 modulus 8 + * @param  msglen   The length of the message + */ +#if defined(__GNUC__) +__attribute__((__nonnull__, __nothrow__)) +#endif +void libsha2_update(struct libsha2_state *restrict, const char *restrict, size_t); + +/** + * Absorb the last part of the message and output a hash + *  + * @param  state    The hashing state + * @param  message  The message, in bits + * @param  msglen   The length of the message, zero if there is nothing more to absorb + * @param  output   The output buffer for the hash + */ +#if defined(__GNUC__) +__attribute__((__nonnull__(1, 4), __nothrow__)) +#endif +void libsha2_digest(struct libsha2_state *restrict, const char *restrict, size_t, char *); + +/** + * Calculate the checksum for a file, + * the content of the file is assumed non-sensitive + *  + * @param   fd         The file descriptor of the file + * @param   algorithm  The hashing algorithm + * @param   hashsum    Output buffer for the hash + * @return             Zero on success, -1 on error + */ +#if defined(__GNUC__) +__attribute__((__nonnull__, __leaf__)) +#endif +int libsha2_sum_fd(int, enum libsha2_algorithm, char *restrict); + +/** + * Convert a binary hashsum to lower case hexadecimal representation + *  + * @param  output   Output array, should have an allocation size of at least `2 * n + 1` + * @param  hashsum  The hashsum to convert + * @param  n        The size of `hashsum` + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nonnull__, __nothrow__)) +#endif +void libsha2_behex_lower(char *restrict, const char *restrict, size_t); + +/** + * Convert a binary hashsum to upper case hexadecimal representation + *  + * @param  output   Output array, should have an allocation size of at least `2 * n + 1` + * @param  hashsum  The hashsum to convert + * @param  n        The size of `hashsum` + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nonnull__, __nothrow__)) +#endif +void libsha2_behex_upper(char *restrict, const char *restrict, size_t); + +/** + * Convert a hexadecimal hashsum (both lower case, upper + * case and mixed is supported) to binary representation + *  + * @param  output   Output array, should have an allocation + *                  size of at least `strlen(hashsum) / 2` + * @param  hashsum  The hashsum to convert + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nonnull__, __nothrow__)) +#endif +void libsha2_unhex(char *restrict, const char *restrict); + + +#endif | 
