aboutsummaryrefslogtreecommitdiffstats
path: root/libsha1.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libsha1.h328
-rw-r--r--libsha1.h.0134
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)