diff options
Diffstat (limited to '')
-rw-r--r-- | libsha1.h | 328 | ||||
-rw-r--r-- | libsha1.h.0 | 134 |
2 files changed, 462 insertions, 0 deletions
diff --git a/libsha1.h b/libsha1.h new file mode 100644 index 0000000..a263ea3 --- /dev/null +++ b/libsha1.h @@ -0,0 +1,328 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef LIBSHA1_H +#define LIBSHA1_H 1 + +#include <stdint.h> +#include <stddef.h> + + +/** + * Algorithms supported by libsha1 + */ +enum libsha1_algorithm { + /** + * SHA-0, outputs 20 bytes + */ + LIBSHA1_0, + + /** + * SHA-1, outputs 20 bytes + */ + LIBSHA1_1 +}; + +/** + * 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. + */ +struct libsha1_state { + /** + * The size of the message, as far as processed, in bits; + */ + size_t message_size; + + /** + * Words + * + * Does not need to be marshalled + */ + uint32_t w[80]; + + /** + * Hashing values + */ + uint32_t h[5]; + + /** + * Space for chunks to process + */ + unsigned char chunk[64]; + + /** + * The size of the chunks, in bytes + */ + size_t chunk_size; + + /** + * The algorithm that is used + */ + enum libsha1_algorithm algorithm; + + int __padding1; +}; + + +/** + * Data structure that describes the state of a HMAC 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. + */ +struct libsha1_hmac_state { + /** + * State of the underlaying hash function + */ + struct libsha1_state sha1_state; + + /** + * The output size of the underlaying + * hash algorithm, in bits + */ + size_t outsize; + + /** + * Whether `.sha1_state` has been initialised + * and whether the `ipad` has been feed into + * the algorithm + */ + unsigned char inited; + + /** + * Inner pad XOR processed key + */ + unsigned char ipad[128]; + + /** + * Outer pad XOR processed key + */ + unsigned char opad[128]; +}; + + +/** + * Initialise a state + * + * @param state The state that should be initialised + * @param algorithm The hashing algorithm + * @return Zero on success, -1 on error + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nothrow__, __nonnull__)) +#endif +int libsha1_init(struct libsha1_state *restrict, enum libsha1_algorithm); + +/** + * Get the output size of the algorithm specified for a state + * + * @param state The state + * @return The number of bytes in the output, zero on error + */ +#if defined(__GNUC__) +__attribute__((__nothrow__, __nonnull__, __pure__)) +#endif +size_t libsha1_state_output_size(const struct libsha1_state *restrict); + +/** + * Get the output size of an algorithm + * + * @param 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 libsha1_algorithm_output_size(enum libsha1_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 libsha1_update(struct libsha1_state *restrict, const void *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 libsha1_digest(struct libsha1_state *restrict, const void *, size_t, void *); + +/** + * 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 libsha1_sum_fd(int, enum libsha1_algorithm, void *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 libsha1_behex_lower(char *restrict, const void *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 libsha1_behex_upper(char *restrict, const void *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 libsha1_unhex(void *restrict, const char *restrict); + +/** + * Marshal a state into a buffer + * + * @param state The state to marshal + * @param buf Output buffer, `NULL` to only return the required size + * @return The number of bytes marshalled to `buf` + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nonnull__(1), __nothrow__)) +#endif +size_t libsha1_marshal(const struct libsha1_state *restrict, void *restrict); + +/** + * Unmarshal a state from a buffer + * + * @param state Output parameter for the unmarshalled state + * @param buf The buffer from which the state shall be unmarshalled + * @param bufsize The maximum number of bytes that can be unmarshalled + * @return The number of read bytes, 0 on failure + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nonnull__, __nothrow__)) +#endif +size_t libsha1_unmarshal(struct libsha1_state *restrict, const void *restrict, size_t); + +/** + * Initialise an HMAC state + * + * @param state The state that should be initialised + * @param algorithm The hashing algorithm + * @param key The key + * @param key_length The length of key, in bits + * @return Zero on success, -1 on error + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nonnull__, __nothrow__)) +#endif +int libsha1_hmac_init(struct libsha1_hmac_state *restrict, enum libsha1_algorithm, const void *restrict, size_t); + +/** + * Get the output size of the algorithm specified for an HMAC state + * + * @param state The state + * @return The number of bytes in the output, zero on error + */ +#if defined(__GNUC__) +__attribute__((__nothrow__, __nonnull__, __pure__)) +#endif +size_t libsha1_hmac_state_output_size(const struct libsha1_hmac_state *restrict); + +/** + * Feed data into the HMAC algorithm + * + * @param state The state of the algorithm + * @param data Data to feed into the algorithm + * @param n The number of bytes to feed into the + * algorithm, this must be a multiple of 8 + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nonnull__, __nothrow__)) +#endif +void libsha1_hmac_update(struct libsha1_hmac_state *restrict, const void *restrict, size_t); + +/** + * Feed data into the HMAC algorithm and + * get the result + * + * The state of the algorithm will be reset and + * `libsha1_hmac_update` and `libsha1_hmac_update` + * can be called again + * + * @param state The state of the algorithm + * @param data Data to feed into the algorithm + * @param n The number of bytes to feed into the algorithm + * @param output The output buffer for the hash, it will be as + * large as for the underlaying hash algorithm + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nonnull__, __nothrow__)) +#endif +void libsha1_hmac_digest(struct libsha1_hmac_state *restrict, const void *, size_t, void *); + +/** + * Marshal an HMAC state into a buffer + * + * @param state The state to marshal + * @param buf Output buffer, `NULL` to only return the required size + * @return The number of bytes marshalled to `buf` + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nonnull__(1), __nothrow__)) +#endif +size_t libsha1_hmac_marshal(const struct libsha1_hmac_state *restrict, void *restrict); + +/** + * Unmarshal an HMAC state from a buffer + * + * @param state Output parameter for the unmarshalled state + * @param buf The buffer from which the state shall be unmarshalled + * @param bufsize The maximum number of bytes that can be unmarshalled + * @return The number of read bytes, 0 on failure + */ +#if defined(__GNUC__) +__attribute__((__leaf__, __nonnull__, __nothrow__)) +#endif +size_t libsha1_hmac_unmarshal(struct libsha1_hmac_state *restrict, const void *restrict, size_t); + + +#endif diff --git a/libsha1.h.0 b/libsha1.h.0 new file mode 100644 index 0000000..30d624b --- /dev/null +++ b/libsha1.h.0 @@ -0,0 +1,134 @@ +.TH LIBSHA1.H 0 2019-02-10 libsha1 +.SH NAME +libsha1.h \- SHA 1 and SHA 0 library header +.SH SYNOPSIS +.nf +#include <libsha1.h> + +enum libsha1_algorithm { + LIBSHA1_0, /* SHA-0 */ + LIBSHA1_1 /* SHA-1 */ +}; + +struct libsha1_state { + /* members omitted */ +}; + +int libsha1_init(struct libsha1_state *restrict \fIstate\fP, enum libsha1_algorithm \fIalgorithm\fP); +size_t libsha1_state_output_size(const struct libsha1_state *restrict \fIstate\fP); +size_t libsha1_algorithm_output_size(enum libsha1_algorithm \fIalgorithm\fP); +void libsha1_update(struct libsha1_state *restrict \fIstate\fP, const void *restrict \fImessage\fP, size_t \fImsglen\fP); +void libsha1_digest(struct libsha1_state *restrict \fIstate\fP, const void *restrict \fImessage\fP, size_t \fImsglen\fP, void *\fIoutput\fP); +int libsha1_sum_fd(int \fIfd\fP, enum libsha1_algorithm \fIalgorithm\fP, void *restrict \fIhashsum\fP); +void libsha1_behex_lower(char *restrict \fIoutput\fP, const void *restrict \fIhashsum\fP, size_t \fIn\fP); +void libsha1_behex_upper(char *restrict \fIoutput\fP, const void *restrict \fIhashsum\fP, size_t \fIn\fP); +void libsha1_unhex(void *restrict \fIoutput\fP, const char *restrict \fIhashsum\fP); +size_t libsha1_marshal(const struct libsha1_state *restrict \fIstate\fP, void *restrict \fIbuf\fP); +size_t libsha1_unmarshal(struct libsha1_state *restrict \fIstate\fP, const void *restrict \fIbuf\fP, size_t \fIbufsize\fP); +int libsha1_hmac_init(struct libsha1_hmac_state *restrict \fIstate\fP, enum libsha1_algorithm \fIalgorithm\fP, + const void *restrict \fIkey\fP, size_t \fIkeylen\fP); +size_t libsha1_hmac_state_output_size(const struct libsha1_hmac_state *restrict \fIstate\fP); +void libsha1_hmac_update(struct libsha1_hmac_state *restrict \fIstate\fP, const void *restrict \fIdata\fP, size_t \fIn\fP); +void libsha1_hmac_digest(struct libsha1_hmac_state *restrict \fIstate\fP, const void *\fIdata\fP, size_t \fIn\fP, void *\fIoutput\fP); +size_t libsha1_hmac_marshal(const struct libsha1_hmac_state *restrict \fIstate\fP, void *restrict \fIbuf\fP); +size_t libsha1_hmac_unmarshal(struct libsha1_hmac_state *restrict \fIstate\fP, const void *restrict \fIbuf\fP, size_t \fIbufsize\fP); +.fi +.PP +Link with +.IR \-lsha1 . +.SH DESCRIPTION +The +.B libsha1.h +header, the header for the libsha1 C library defines +.B enum libsha1_algorithm +which has one value per supported algorithm: +.TP +.B LIBSHA1_0 +SHA-0 +.TP +.B LIBSHA1_1 +SHA-1 +.PP +Further, the +.B libsha1.h +header defines the opaque, but complete, +.B struct libsha1_state +which stores the selected algorithm and +the state of the hashing. A state can be +securely erased by overriding all bytes +in the structure with zeroes (or any other +byte sequence). The header also +defines the functions: +.TP +.BR libsha1_init (3) +Initialise hashing state. +.TP +.BR libsha1_state_output_size "(3), " libsha1_algorithm_output_size (3) +Get the output size for an algorithm. +.TP +.BR libsha1_update (3) +Feed data into the hashing state. +.TP +.BR libsha1_digest (3) +Get the result of a hashing. +.TP +.BR libsha1_sum_fd (3) +Hash an entire file. +.TP +.BR libsha1_behex_lower "(3), " libsha1_behex_upper (3) +Convert binary output from +.BR libsha1_digest (3) +to hexadecimal. +.TP +.BR libsha1_unhex (3) +Convert a hexadecimal hash to binary. +.TP +.BR libsha1_marshal (3) +Marshal a hashing state. +.TP +.BR libsha1_unmarshal (3) +Unmarshal a hashing state. +.TP +.BR libsha1_hmac_init (3) +Initialise HMAC hashing state. +.TP +.BR libsha1_hmac_update (3) +Feed data into the HMAC hashing state. +.TP +.BR libsha1_hmac_digest (3) +Get the result of an HMAC hashing. +.TP +.BR libsha1_hmac_marshal (3) +Marshal an HMAC hashing state. +.TP +.BR libsha1_hmac_unmarshal (3) +Unmarshal an HMAC hashing state. +.SH EXAMPLES +None. +.SH APPLICATION USAGE +None. +.SH RATIONALE +None. +.SH FUTURE DIRECTIONS +None. +.SH NOTES +None. +.SH BUGS +None. +.SH SEE ALSO +.BR libsha1_algorithm_output_size (3), +.BR libsha1_behex_lower (3), +.BR libsha1_behex_upper (3), +.BR libsha1_digest (3), +.BR libsha1_hmac_digest (3), +.BR libsha1_hmac_init (3), +.BR libsha1_hmac_marshal (3), +.BR libsha1_hmac_unmarshal (3), +.BR libsha1_hmac_update (3), +.BR libsha1_init (3), +.BR libsha1_marshal (3), +.BR libsha1_state_output_size (3), +.BR libsha1_sum_fd (3), +.BR libsha1_unhex (3), +.BR libsha1_unmarshal (3), +.BR libsha1_update (3) |