aboutsummaryrefslogtreecommitdiffstats
path: root/libhashsum
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2024-08-24 18:02:00 +0200
committerMattias Andrée <maandree@kth.se>2024-08-24 18:02:00 +0200
commit72111e7a53eaad7bea841ab8b09e70642bde00ae (patch)
tree016e0326b794f8a5b9cc03139b8a5ab094ed7411 /libhashsum
parentMake it possible for libhashsum_state to grow in future versions (diff)
downloadlibhashsum-72111e7a53eaad7bea841ab8b09e70642bde00ae.tar.gz
libhashsum-72111e7a53eaad7bea841ab8b09e70642bde00ae.tar.bz2
libhashsum-72111e7a53eaad7bea841ab8b09e70642bde00ae.tar.xz
Add support for Keccak, SHA3, SHAKE, and RawSHAKE via libkeccak>=1.3 (this version introduced zerocopy)
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
-rw-r--r--libhashsum.h485
-rw-r--r--libhashsum_init_hasher.c29
-rw-r--r--libhashsum_init_hasher_from_string.c129
-rw-r--r--libhashsum_init_keccak_224_hasher.c9
-rw-r--r--libhashsum_init_keccak_256_hasher.c9
-rw-r--r--libhashsum_init_keccak_384_hasher.c9
-rw-r--r--libhashsum_init_keccak_512_hasher.c9
-rw-r--r--libhashsum_init_keccak__.c148
-rw-r--r--libhashsum_init_keccak_hasher.c75
-rw-r--r--libhashsum_init_md2_hasher.c1
-rw-r--r--libhashsum_init_md4_hasher.c1
-rw-r--r--libhashsum_init_md5_hasher.c1
-rw-r--r--libhashsum_init_rawshake128_hasher.c9
-rw-r--r--libhashsum_init_rawshake256_hasher.c9
-rw-r--r--libhashsum_init_rawshake512_hasher.c9
-rw-r--r--libhashsum_init_rawshake_hasher.c52
-rw-r--r--libhashsum_init_ripemd_128_hasher.c1
-rw-r--r--libhashsum_init_ripemd_160_hasher.c1
-rw-r--r--libhashsum_init_ripemd_256_hasher.c1
-rw-r--r--libhashsum_init_ripemd_320_hasher.c1
-rw-r--r--libhashsum_init_sha0_hasher.c1
-rw-r--r--libhashsum_init_sha1_hasher.c1
-rw-r--r--libhashsum_init_sha2_hasher.c1
-rw-r--r--libhashsum_init_sha3_224_hasher.c9
-rw-r--r--libhashsum_init_sha3_256_hasher.c9
-rw-r--r--libhashsum_init_sha3_384_hasher.c9
-rw-r--r--libhashsum_init_sha3_512_hasher.c9
-rw-r--r--libhashsum_init_sha3_hasher.c42
-rw-r--r--libhashsum_init_shake128_hasher.c9
-rw-r--r--libhashsum_init_shake256_hasher.c9
-rw-r--r--libhashsum_init_shake512_hasher.c9
-rw-r--r--libhashsum_init_shake_hasher.c52
32 files changed, 1127 insertions, 21 deletions
diff --git a/libhashsum.h b/libhashsum.h
index 67f27b4..e7050c1 100644
--- a/libhashsum.h
+++ b/libhashsum.h
@@ -5,8 +5,15 @@
#include <stddef.h>
#include <stdint.h>
-#include <libsha1.h>
-#include <libsha2.h>
+#ifdef LIBHASHSUM_INCLUDE_LIBSHA1_STATE
+# include <libsha1.h>
+#endif
+#ifdef LIBHASHSUM_INCLUDE_LIBSHA2_STATE
+# include <libsha2.h>
+#endif
+#ifdef LIBHASHSUM_INCLUDE_LIBKECCAK_STATE
+# include <libkeccak.h>
+#endif
#if defined(__GNUC__)
@@ -27,21 +34,36 @@
*/
enum libhashsum_algorithm {
/* since 1.0 */
- LIBHASHSUM_MD2, /**< MD2 */
- LIBHASHSUM_MD4, /**< MD4 */
- LIBHASHSUM_MD5, /**< MD5; this algorithm has been compromised */
- LIBHASHSUM_RIPEMD_128, /**< RIPEMD-128 */
- LIBHASHSUM_RIPEMD_160, /**< RIPEMD-160 */
- LIBHASHSUM_RIPEMD_256, /**< RIPEMD-256 */
- LIBHASHSUM_RIPEMD_320, /**< RIPEMD-320 */
- LIBHASHSUM_SHA0, /**< SHA0; this algorithm has been compromised */
- LIBHASHSUM_SHA1, /**< SHA1; this algorithm has been compromised */
- LIBHASHSUM_SHA_224, /**< SHA-224 (SHA2) */
- LIBHASHSUM_SHA_256, /**< SHA-256 (SHA2) */
- LIBHASHSUM_SHA_384, /**< SHA-384 (SHA2) */
- LIBHASHSUM_SHA_512, /**< SHA-512 (SHA2) */
- LIBHASHSUM_SHA_512_224, /**< SHA-512/224 (SHA2) */
- LIBHASHSUM_SHA_512_256 /**< SHA-512/256 (SHA2) */
+ LIBHASHSUM_MD2, /**< MD2 */
+ LIBHASHSUM_MD4, /**< MD4 */
+ LIBHASHSUM_MD5, /**< MD5; this algorithm has been compromised */
+ LIBHASHSUM_RIPEMD_128, /**< RIPEMD-128 */
+ LIBHASHSUM_RIPEMD_160, /**< RIPEMD-160 */
+ LIBHASHSUM_RIPEMD_256, /**< RIPEMD-256 */
+ LIBHASHSUM_RIPEMD_320, /**< RIPEMD-320 */
+ LIBHASHSUM_SHA0, /**< SHA0; this algorithm has been compromised */
+ LIBHASHSUM_SHA1, /**< SHA1; this algorithm has been compromised */
+ LIBHASHSUM_SHA_224, /**< SHA-224 (SHA2) */
+ LIBHASHSUM_SHA_256, /**< SHA-256 (SHA2) */
+ LIBHASHSUM_SHA_384, /**< SHA-384 (SHA2) */
+ LIBHASHSUM_SHA_512, /**< SHA-512 (SHA2) */
+ LIBHASHSUM_SHA_512_224, /**< SHA-512/224 (SHA2) */
+ LIBHASHSUM_SHA_512_256, /**< SHA-512/256 (SHA2) */
+ LIBHASHSUM_KECCAK, /**< Keccak[] */
+ LIBHASHSUM_KECCAK_224, /**< Keccak-224 */
+ LIBHASHSUM_KECCAK_256, /**< Keccak-256 */
+ LIBHASHSUM_KECCAK_384, /**< Keccak-384 */
+ LIBHASHSUM_KECCAK_512, /**< Keccak-512 */
+ LIBHASHSUM_SHA3_224, /**< SHA3-224 */
+ LIBHASHSUM_SHA3_256, /**< SHA3-256 */
+ LIBHASHSUM_SHA3_384, /**< SHA3-384 */
+ LIBHASHSUM_SHA3_512, /**< SHA3-512 */
+ LIBHASHSUM_SHAKE128 , /**< SHAKE128 */
+ LIBHASHSUM_SHAKE256, /**< SHAKE256 */
+ LIBHASHSUM_SHAKE512, /**< SHAKE512 */
+ LIBHASHSUM_RAWSHAKE128, /**< RawSHAKE128 */
+ LIBHASHSUM_RAWSHAKE256, /**< RawSHAKE256 */
+ LIBHASHSUM_RAWSHAKE512 /**< RawSHAKE512 */
};
@@ -150,6 +172,104 @@ enum libhashsum_algorithm {
*/
#define LIBHASHSUM_SHA_512_256_HASH_SIZE 32
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA3_224`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_KECCAK_224_HASH_SIZE 28
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_KECCAK_256`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_KECCAK_256_HASH_SIZE 32
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_KECCAK_384`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_KECCAK_384_HASH_SIZE 48
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_KECCAK_512`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_KECCAK_512_HASH_SIZE 64
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA3_224`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_SHA3_224_HASH_SIZE 28
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA3_256`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_SHA3_256_HASH_SIZE 32
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA3_384`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_SHA3_384_HASH_SIZE 48
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHA3_512`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_SHA3_512_HASH_SIZE 64
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHAKE_128`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_SHAKE_128_HASH_SIZE 28
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHAKE_256`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_SHAKE_256_HASH_SIZE 32
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHAKE_512`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_SHAKE_512_HASH_SIZE 64
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RAWSHAKE_128`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_RAWSHAKE_128_HASH_SIZE 28
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RAWSHAKE_256`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_RAWSHAKE_256_HASH_SIZE 32
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RAWSHAKE_512`
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_RAWSHAKE_512_HASH_SIZE 64
+
/**
* Hash state
@@ -239,17 +359,32 @@ union libhashsum_state {
uint64_t count;
} ripemd_320; /* size = 152 */
+#ifdef LIBHASHSUM_INCLUDE_LIBSHA1_STATE
struct {
struct libsha1_state s;
uint8_t sum[20];
} sha0, sha1; /* size = [432, 440] */
+#endif
+#ifdef LIBHASHSUM_INCLUDE_LIBSHA2_STATE
struct {
struct libsha2_state s;
uint8_t sum[64];
} sha2; /* size = [1612, 1624] */
+#endif
+
+#ifdef LIBHASHSUM_INCLUDE_LIBKECCAK_STATE
+ struct {
+ struct libkeccak_state s;
+ union {
+ uint8_t buf[512];
+ uint8_t *dyn;
+ } sum;
+ const char *suffix;
+ char algostr[256];
+ } keccak; /* size = [1020, 1065] */
+#endif
- /* libkeccak: size = [248, 288] */
/* libblake: size = 56(s), 112(b), 48(2s), 96(2b), 144(2Xs), 276(2Xb) */
char max_size[1648];
@@ -384,6 +519,18 @@ struct libhashsum_hasher {
int (*finalise)(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size);
/**
+ * Unless this pointer its `NULL`, it points to
+ * function that shall be once the object (`this`)
+ * is not needed anymore
+ *
+ * @param this The object containing this function pointer
+ *
+ * @since 1.0
+ */
+ LIBHASHSUM_1_NONNULL_
+ void (*destroy)(struct libhashsum_hasher *this);
+
+ /**
* The hash state
*
* For internal use
@@ -405,7 +552,7 @@ struct libhashsum_hasher {
* @throws EINVAL `algorithm` is not recognised
* @throws EINVAL `algorithm` requires parameters, and is therefore
* not supported by this function (use dedicated
- * initialiser instead)
+ * initialiser instead). (`algorithm` is `LIBHASHSUM_KECCAK`)
* @throws ENOSYS Support for `algorithm` was excluded at compile time
* @throws ENOSYS The `algorithm` requires a newer version of the library
* that application was compiled for (the application
@@ -413,6 +560,7 @@ struct libhashsum_hasher {
* (specifically this means that the application's version
* of `union libhashsum_state`, and thus also
* `struct libhashsum_hasher`, is too small to store the state)
+ * @throws ENOMEM Not enough memory available
*
* @since 1.0
*/
@@ -435,6 +583,7 @@ int libhashsum_init_hasher(struct libhashsum_hasher *this, enum libhashsum_algor
* (specifically this means that the application's version
* of `union libhashsum_state`, and thus also
* `struct libhashsum_hasher`, is too small to store the state)
+ * @throws ENOMEM Not enough memory available
*
* @since 1.0
*/
@@ -671,5 +820,303 @@ int libhashsum_init_sha_512_256_hasher(struct libhashsum_hasher *this);
LIBHASHSUM_1_NONNULL_
int libhashsum_init_sha2_hasher(struct libhashsum_hasher *this, unsigned algobits, size_t hashbits);
+/**
+ * Create an initialised state for Keccak-224
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @return 0 on success, -1 on failure
+ *
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_keccak_224_hasher(struct libhashsum_hasher *this);
+
+/**
+ * Create an initialised state for Keccak-256
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @return 0 on success, -1 on failure
+ *
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_keccak_256_hasher(struct libhashsum_hasher *this);
+
+/**
+ * Create an initialised state for Keccak-384
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @return 0 on success, -1 on failure
+ *
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_keccak_384_hasher(struct libhashsum_hasher *this);
+
+/**
+ * Create an initialised state for Keccak-512
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @return 0 on success, -1 on failure
+ *
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_keccak_512_hasher(struct libhashsum_hasher *this);
+
+/**
+ * Create an initialised state for Keccak
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @param ratebits Bitrate (in bits), 0 for automatic
+ * @param capbits Capacity in bits, 0 for automatic
+ * @param hashbits Hash output size in bits, 0 for automatic
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL (`ratebits`, `capbits`, `hashbits`) is invalid
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebits, size_t capbits, size_t hashbits);
+
+/**
+ * Create an initialised state for SHA3-224
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @return 0 on success, -1 on failure
+ *
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_sha3_224_hasher(struct libhashsum_hasher *this);
+
+/**
+ * Create an initialised state for SHA3-256
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @return 0 on success, -1 on failure
+ *
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_sha3_256_hasher(struct libhashsum_hasher *this);
+
+/**
+ * Create an initialised state for SHA3-384
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @return 0 on success, -1 on failure
+ *
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_sha3_384_hasher(struct libhashsum_hasher *this);
+
+/**
+ * Create an initialised state for SHA3-512
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @return 0 on success, -1 on failure
+ *
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_sha3_512_hasher(struct libhashsum_hasher *this);
+
+/**
+ * Create an initialised state for SHA3
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @param hashbits Hash output size in bits
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hashbits` is invalid (neither 224, 256, 384, nor 512)
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_sha3_hasher(struct libhashsum_hasher *this, size_t hashbits);
+
+/**
+ * Create an initialised state for SHAKE128
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @param hashbits Hash output size in bits, if 0, 128 is used
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hashbits` is too large
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_shake128_hasher(struct libhashsum_hasher *this, size_t hashbits);
+
+/**
+ * Create an initialised state for SHAKE256
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @param hashbits Hash output size in bits, if 0, 256 is used
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hashbits` is too large
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_shake256_hasher(struct libhashsum_hasher *this, size_t hashbits);
+
+/**
+ * Create an initialised state for SHAKE512
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @param hashbits Hash output size in bits, if 0, 512 is used
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hashbits` is too large
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_shake512_hasher(struct libhashsum_hasher *this, size_t hashbits);
+
+/**
+ * Create an initialised state for SHAKE
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @param hcapbits Half of the capacity, in bits (this is the
+ * value added behind the function name)
+ * @param hashbits Hash output size in bits, if 0, `hcapbits` is used
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hcapbits` is invalid (neither 128, 256, nor 512)
+ * @throws EINVAL `hashbits` is too large
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_shake_hasher(struct libhashsum_hasher *this, size_t hcapbits, size_t hashbits);
+
+/**
+ * Create an initialised state for RawSHAKE128
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @param hashbits Hash output size in bits, if 0, 128 is used
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hashbits` is too large
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_rawshake128_hasher(struct libhashsum_hasher *this, size_t hashbits);
+
+/**
+ * Create an initialised state for RawSHAKE256
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @param hashbits Hash output size in bits, if 0, 256 is used
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hashbits` is too large
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_rawshake256_hasher(struct libhashsum_hasher *this, size_t hashbits);
+
+/**
+ * Create an initialised state for RawSHAKE512
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @param hashbits Hash output size in bits, if 0, 512 is used
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hashbits` is too large
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_rawshake512_hasher(struct libhashsum_hasher *this, size_t hashbits);
+
+/**
+ * Create an initialised state for RawSHAKE
+ * hashing and return hash functions and details
+ *
+ * @param this The output parameter for the functions, details, and state
+ * @param hcapbits Half of the capacity, in bits (this is the
+ * value added behind the function name)
+ * @param hashbits Hash output size in bits, if 0, `hcapbits` is used
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hcapbits` is invalid (neither 128, 256, nor 512)
+ * @throws EINVAL `hashbits` is too large
+ * @throws ENOSYS Support was excluded at compile time
+ * @throws ENOMEM Not enough memory available
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_rawshake_hasher(struct libhashsum_hasher *this, size_t hcapbits, size_t hashbits);
+
#endif
diff --git a/libhashsum_init_hasher.c b/libhashsum_init_hasher.c
index 3f99e6c..3d8a521 100644
--- a/libhashsum_init_hasher.c
+++ b/libhashsum_init_hasher.c
@@ -36,7 +36,36 @@ libhashsum_init_hasher(struct libhashsum_hasher *this, enum libhashsum_algorithm
return libhashsum_init_sha_512_224_hasher(this);
case LIBHASHSUM_SHA_512_256:
return libhashsum_init_sha_512_256_hasher(this);
+ case LIBHASHSUM_KECCAK_224:
+ return libhashsum_init_keccak_224_hasher(this);
+ case LIBHASHSUM_KECCAK_256:
+ return libhashsum_init_keccak_256_hasher(this);
+ case LIBHASHSUM_KECCAK_384:
+ return libhashsum_init_keccak_384_hasher(this);
+ case LIBHASHSUM_KECCAK_512:
+ return libhashsum_init_keccak_512_hasher(this);
+ case LIBHASHSUM_SHA3_224:
+ return libhashsum_init_sha3_224_hasher(this);
+ case LIBHASHSUM_SHA3_256:
+ return libhashsum_init_sha3_256_hasher(this);
+ case LIBHASHSUM_SHA3_384:
+ return libhashsum_init_sha3_384_hasher(this);
+ case LIBHASHSUM_SHA3_512:
+ return libhashsum_init_sha3_512_hasher(this);
+ case LIBHASHSUM_SHAKE128:
+ return libhashsum_init_shake128_hasher(this, 0);
+ case LIBHASHSUM_SHAKE256:
+ return libhashsum_init_shake256_hasher(this, 0);
+ case LIBHASHSUM_SHAKE512:
+ return libhashsum_init_shake512_hasher(this, 0);
+ case LIBHASHSUM_RAWSHAKE128:
+ return libhashsum_init_rawshake128_hasher(this, 0);
+ case LIBHASHSUM_RAWSHAKE256:
+ return libhashsum_init_rawshake256_hasher(this, 0);
+ case LIBHASHSUM_RAWSHAKE512:
+ return libhashsum_init_rawshake512_hasher(this, 0);
default:
+ case LIBHASHSUM_KECCAK:
errno = EINVAL;
return -1;
}
diff --git a/libhashsum_init_hasher_from_string.c b/libhashsum_init_hasher_from_string.c
index e41c8b1..30526da 100644
--- a/libhashsum_init_hasher_from_string.c
+++ b/libhashsum_init_hasher_from_string.c
@@ -8,7 +8,7 @@ __attribute__((__pure__))
static int
equiv(const char *a, const char *b)
{
- while (*a && *b) {
+ while (*a && *b && *b != '[') {
if (tolower(*a) == tolower(*b)) {
a++;
b++;
@@ -18,7 +18,102 @@ equiv(const char *a, const char *b)
return 0;
}
}
- return !*a && !*b;
+ return !*a && (!*b || *b == '[');
+}
+
+
+static int
+with_n(int (*initfunc)(struct libhashsum_hasher *, size_t), struct libhashsum_hasher *this, const char *algorithm)
+{
+ const char *p;
+ size_t n = 0, digit;
+
+ p = strchr(algorithm, '[');
+ if (!p || *++p == ']')
+ return initfunc(this, 0);
+
+ if ((*p++ != 'n' && *p++ != 'N'))
+ goto einval;
+ if (*p++ != '=' || !('1' <= *p && *p <= '9'))
+ goto einval;
+
+ while (isdigit(*p)) {
+ digit = (size_t)(*p++ & 15);
+ if (n > (SIZE_MAX - digit) / 10U)
+ goto einval;
+ n = n * 10U + digit;
+ }
+
+ if (*p++ != ']' || *p)
+ goto einval;
+
+ return initfunc(this, n);
+
+einval:
+ errno = EINVAL;
+ return -1;
+}
+
+
+static int
+parse_value(size_t *valp, const char *p, const char **end_out)
+{
+ size_t digit;
+ if (*valp)
+ return -1;
+ p++;
+ if (*p++ != '=' || !('1' <= *p && *p <= '9'))
+ return -1;
+ while (isdigit(*p)) {
+ digit = (size_t)(*p++ & 15);
+ if (*valp > (SIZE_MAX - digit) / 10U)
+ return -1;
+ *valp = *valp * 10U + digit;
+ }
+ *end_out = p;
+ return 0;
+}
+
+
+static int
+with_rcn(int (*initfunc)(struct libhashsum_hasher *, size_t, size_t, size_t),
+ struct libhashsum_hasher *this, const char *algorithm)
+{
+ const char *p;
+ size_t r = 0, c = 0, n = 0;
+
+ p = strchr(algorithm, '[');
+ if (!p || *++p == ']')
+ return initfunc(this, 0, 0, 0);
+
+ for (;;) {
+ if (*p == 'r' || *p == 'R') {
+ if (parse_value(&r, p, &p))
+ goto einval;
+ } else if (*p == 'c' || *p == 'C') {
+ if (parse_value(&c, p, &p))
+ goto einval;
+ } else if (*p == 'n' || *p == 'N') {
+ if (parse_value(&n, p, &p))
+ goto einval;
+ } else if (*p == ']') {
+ break;
+ } else {
+ goto einval;
+ }
+ if (*p == ']')
+ break;
+ if (*p++ != ',')
+ goto einval;
+ }
+ if (p[1])
+ goto einval;
+
+ return initfunc(this, r, c, n);
+
+einval:
+ errno = EINVAL;
+ return -1;
}
@@ -55,6 +150,36 @@ libhashsum_init_hasher_from_string(struct libhashsum_hasher *this, const char *a
return libhashsum_init_sha_512_224_hasher(this);
if (equiv(algorithm, "SHA-512/256") || !strcasecmp(algorithm, "SHA2-512/256"))
return libhashsum_init_sha_512_256_hasher(this);
+ if (equiv(algorithm, "Keccak-224"))
+ return libhashsum_init_keccak_224_hasher(this);
+ if (equiv(algorithm, "Keccak-256"))
+ return libhashsum_init_keccak_256_hasher(this);
+ if (equiv(algorithm, "Keccak-384"))
+ return libhashsum_init_keccak_384_hasher(this);
+ if (equiv(algorithm, "Keccak-512"))
+ return libhashsum_init_keccak_512_hasher(this);
+ if (!strcasecmp(algorithm, "SHA3-224"))
+ return libhashsum_init_sha3_224_hasher(this);
+ if (!strcasecmp(algorithm, "SHA3-256"))
+ return libhashsum_init_sha3_256_hasher(this);
+ if (!strcasecmp(algorithm, "SHA3-384"))
+ return libhashsum_init_sha3_384_hasher(this);
+ if (!strcasecmp(algorithm, "SHA3-512"))
+ return libhashsum_init_sha3_512_hasher(this);
+ if (equiv(algorithm, "SHAKE-128["))
+ return with_n(&libhashsum_init_shake128_hasher, this, algorithm);
+ if (equiv(algorithm, "SHAKE-256["))
+ return with_n(&libhashsum_init_shake256_hasher, this, algorithm);
+ if (equiv(algorithm, "SHAKE-512["))
+ return with_n(&libhashsum_init_shake512_hasher, this, algorithm);
+ if (equiv(algorithm, "RawSHAKE-128["))
+ return with_n(&libhashsum_init_rawshake128_hasher, this, algorithm);
+ if (equiv(algorithm, "RawSHAKE-256["))
+ return with_n(&libhashsum_init_rawshake256_hasher, this, algorithm);
+ if (equiv(algorithm, "RawSHAKE-512["))
+ return with_n(&libhashsum_init_rawshake512_hasher, this, algorithm);
+ if (equiv(algorithm, "Keccak["))
+ return with_rcn(&libhashsum_init_keccak_hasher, this, algorithm);
errno = EINVAL;
return -1;
diff --git a/libhashsum_init_keccak_224_hasher.c b/libhashsum_init_keccak_224_hasher.c
new file mode 100644
index 0000000..7a2b516
--- /dev/null
+++ b/libhashsum_init_keccak_224_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_keccak_224_hasher(struct libhashsum_hasher *this)
+{
+ return libhashsum_init_keccak_hasher(this, KECCAKN(224));
+}
diff --git a/libhashsum_init_keccak_256_hasher.c b/libhashsum_init_keccak_256_hasher.c
new file mode 100644
index 0000000..2724e3a
--- /dev/null
+++ b/libhashsum_init_keccak_256_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_keccak_256_hasher(struct libhashsum_hasher *this)
+{
+ return libhashsum_init_keccak_hasher(this, KECCAKN(256));
+}
diff --git a/libhashsum_init_keccak_384_hasher.c b/libhashsum_init_keccak_384_hasher.c
new file mode 100644
index 0000000..61e4f64
--- /dev/null
+++ b/libhashsum_init_keccak_384_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_keccak_384_hasher(struct libhashsum_hasher *this)
+{
+ return libhashsum_init_keccak_hasher(this, KECCAKN(384));
+}
diff --git a/libhashsum_init_keccak_512_hasher.c b/libhashsum_init_keccak_512_hasher.c
new file mode 100644
index 0000000..1946aca
--- /dev/null
+++ b/libhashsum_init_keccak_512_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_keccak_512_hasher(struct libhashsum_hasher *this)
+{
+ return libhashsum_init_keccak_hasher(this, KECCAKN(512));
+}
diff --git a/libhashsum_init_keccak__.c b/libhashsum_init_keccak__.c
new file mode 100644
index 0000000..b0023a5
--- /dev/null
+++ b/libhashsum_init_keccak__.c
@@ -0,0 +1,148 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifdef LIBHASHSUM_INCLUDE_LIBKECCAK_STATE
+
+
+LIBHASHSUM_1_NONNULL_
+static size_t
+process(struct libhashsum_hasher *this, const void *data, size_t bytes)
+{
+ bytes -= bytes % this->input_block_size;
+ libkeccak_zerocopy_update(&this->state.keccak.s, data, bytes);
+ 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;
+
+ if (this->hash_size > sizeof(this->state.keccak.sum.buf))
+ this->hash_output = this->state.keccak.sum.dyn;
+ else
+ this->hash_output = this->state.keccak.sum.buf;
+ libkeccak_digest(&this->state.keccak.s, m, bytes, extra_bits, this->state.keccak.suffix, this->hash_output);
+ libkeccak_state_wipe_message(&this->state.keccak.s);
+ libkeccak_state_fast_destroy(&this->state.keccak.s);
+ memset(&this->state.keccak.s, 0, sizeof(this->state.keccak.s));
+ this->state.keccak.s.M = NULL;
+ return 0;
+}
+
+
+LIBHASHSUM_1_NONNULL_
+static int
+finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size)
+{
+ uint8_t *m = data;
+ size_t r;
+ size_t need;
+
+ if (extra_bits > 7U) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ r = process(this, m, bytes);
+ m = &m[r];
+ bytes -= r;
+ size -= r;
+
+ need = strlen(this->state.keccak.suffix) + 2U + extra_bits;
+ need = (need + 7U) >> 3;
+ need += bytes;
+ if (need & (this->input_block_size - 1U)) {
+ need &= ~(this->input_block_size - 1U);
+ need += this->input_block_size;
+ }
+
+ if (this->hash_size > sizeof(this->state.keccak.sum.buf))
+ this->hash_output = this->state.keccak.sum.dyn;
+ else
+ this->hash_output = this->state.keccak.sum.buf;
+ if (size < need)
+ libkeccak_digest(&this->state.keccak.s, m, bytes, extra_bits,
+ this->state.keccak.suffix, this->hash_output);
+ else
+ libkeccak_zerocopy_digest(&this->state.keccak.s, m, bytes, extra_bits,
+ this->state.keccak.suffix, this->hash_output);
+ libkeccak_state_wipe_message(&this->state.keccak.s);
+ libkeccak_state_fast_destroy(&this->state.keccak.s);
+ memset(&this->state.keccak.s, 0, sizeof(this->state.keccak.s));
+ this->state.keccak.s.M = NULL;
+ return 0;
+}
+
+
+LIBHASHSUM_1_NONNULL_
+static void
+destroy(struct libhashsum_hasher *this)
+{
+ libkeccak_state_wipe_message(&this->state.keccak.s);
+ libkeccak_state_fast_destroy(&this->state.keccak.s);
+ memset(&this->state.keccak.s, 0, sizeof(this->state.keccak.s));
+ this->state.keccak.s.M = NULL;
+ if (this->hash_size > sizeof(this->state.keccak.sum.buf)) {
+ free(this->state.keccak.sum.dyn);
+ this->state.keccak.sum.dyn = NULL;
+ }
+}
+
+
+int
+libhashsum_init_keccak__(struct libhashsum_hasher *this, size_t hashbits, void *spec_, const char *suffix)
+{
+ struct libkeccak_spec *spec = spec_;
+
+ this->hash_size = hashbits >> 3;
+ this->hash_size += (size_t)!!(hashbits & 7U);
+ this->hash_output = NULL;
+ this->supports_non_whole_bytes = 1;
+ this->state.keccak.suffix = suffix;
+
+ if (this->hash_size > sizeof(this->state.keccak.sum.buf)) {
+ this->state.keccak.sum.dyn = malloc(this->hash_size);
+ if (!this->state.keccak.sum.dyn)
+ return -1;
+ }
+
+ if (libkeccak_state_initialise(&this->state.keccak.s, spec)) {
+ if (this->hash_size > sizeof(this->state.keccak.sum.buf)) {
+ free(this->state.keccak.sum.dyn);
+ this->state.keccak.sum.dyn = NULL;
+ }
+ return -1;
+ }
+
+ this->input_block_size = libkeccak_zerocopy_chunksize(&this->state.keccak.s);
+ this->process = &process;
+ this->finalise_const = &finalise_const;
+ this->finalise = &finalise;
+ this->destroy = &destroy;
+ return 0;
+}
+
+
+#else
+int
+libhashsum_init_keccak__(struct libhashsum_hasher *this, size_t hashbits, void *spec, const char *suffix);
+{
+ (void) this;
+ (void) spec;
+ (void) suffix;
+ errno = ENOSYS;
+ return -1;
+}
+#endif
diff --git a/libhashsum_init_keccak_hasher.c b/libhashsum_init_keccak_hasher.c
new file mode 100644
index 0000000..93622f6
--- /dev/null
+++ b/libhashsum_init_keccak_hasher.c
@@ -0,0 +1,75 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifdef SUPPORT_KECCAK
+
+
+int
+libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebits, size_t capbits, size_t hashbits)
+{
+ struct libkeccak_generalised_spec gspec;
+ struct libkeccak_spec spec;
+
+ if ((ratebits | capbits | hashbits) > (size_t)LONG_MAX) {
+ errno = EINVAL;
+ return -1;
+ } else if (!ratebits || !capbits || !hashbits) {
+ libkeccak_generalised_spec_initialise(&gspec);
+ if (ratebits)
+ gspec.bitrate = (long int)ratebits;
+ if (capbits)
+ gspec.capacity = (long int)capbits;
+ if (hashbits)
+ gspec.output = (long int)hashbits;
+ if (libkeccak_degeneralise_spec(&gspec, &spec)) {
+ errno = EINVAL;
+ return -1;
+ }
+ ratebits = (size_t)spec.bitrate;
+ capbits = (size_t)spec.capacity;
+ hashbits = (size_t)spec.output;
+ } else {
+ spec.bitrate = (long int)ratebits;
+ spec.capacity = (long int)capbits;
+ spec.output = (long int)hashbits;
+ }
+ if (libkeccak_spec_check(&spec)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ this->algorithm = LIBHASHSUM_KECCAK;
+ if ((capbits >> 1) == hashbits && !(capbits & 1U) &&
+ 1600U >= capbits && ratebits == 1600U - capbits) {
+ if (hashbits == 224U) {
+ this->algorithm = LIBHASHSUM_KECCAK_224;
+ this->algorithm_string = "Keccak-224";
+ } else if (hashbits == 256U) {
+ this->algorithm = LIBHASHSUM_KECCAK_256;
+ this->algorithm_string = "Keccak-256";
+ } else if (hashbits == 384U) {
+ this->algorithm = LIBHASHSUM_KECCAK_384;
+ this->algorithm_string = "Keccak-384";
+ } else if (hashbits == 512U) {
+ this->algorithm = LIBHASHSUM_KECCAK_512;
+ this->algorithm_string = "Keccak-512";
+ }
+ }
+ if (this->algorithm == LIBHASHSUM_KECCAK) {
+ sprintf(this->state.keccak.algostr, "Keccak[r=%zu,c=%zu,n=%zu]", ratebits, capbits, hashbits);
+ this->algorithm_string = this->state.keccak.algostr;
+ }
+
+ return libhashsum_init_keccak__(this, hashbits, &spec, "");
+}
+
+
+#else
+int
+libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t hashbits)
+{
+ (void) this;
+ (void) hashbits;
+ errno = ENOSYS;
+ return -1;
+}
+#endif
diff --git a/libhashsum_init_md2_hasher.c b/libhashsum_init_md2_hasher.c
index 6ea2063..cf0a495 100644
--- a/libhashsum_init_md2_hasher.c
+++ b/libhashsum_init_md2_hasher.c
@@ -142,6 +142,7 @@ libhashsum_init_md2_hasher(struct libhashsum_hasher *this)
this->process = &process;
this->finalise_const = &finalise_const;
this->finalise = &finalise;
+ this->destroy = NULL;
memset(&this->state.md2, 0, sizeof(this->state.md2));
return 0;
}
diff --git a/libhashsum_init_md4_hasher.c b/libhashsum_init_md4_hasher.c
index 22626a9..bc361d8 100644
--- a/libhashsum_init_md4_hasher.c
+++ b/libhashsum_init_md4_hasher.c
@@ -185,6 +185,7 @@ libhashsum_init_md4_hasher(struct libhashsum_hasher *this)
this->process = &process;
this->finalise_const = &finalise_const;
this->finalise = &finalise;
+ this->destroy = NULL;
memset(&this->state.md4, 0, sizeof(this->state.md4));
this->state.md4.h.h32[0] = UINT32_C(0x67452301);
this->state.md4.h.h32[1] = UINT32_C(0xefcdab89);
diff --git a/libhashsum_init_md5_hasher.c b/libhashsum_init_md5_hasher.c
index 6888f6e..8147204 100644
--- a/libhashsum_init_md5_hasher.c
+++ b/libhashsum_init_md5_hasher.c
@@ -200,6 +200,7 @@ libhashsum_init_md5_hasher(struct libhashsum_hasher *this)
this->process = &process;
this->finalise_const = &finalise_const;
this->finalise = &finalise;
+ this->destroy = NULL;
memset(&this->state.md5, 0, sizeof(this->state.md5));
this->state.md5.h.h32[0] = UINT32_C(0x67452301);
this->state.md5.h.h32[1] = UINT32_C(0xefcdab89);
diff --git a/libhashsum_init_rawshake128_hasher.c b/libhashsum_init_rawshake128_hasher.c
new file mode 100644
index 0000000..38a8bd3
--- /dev/null
+++ b/libhashsum_init_rawshake128_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_rawshake128_hasher(struct libhashsum_hasher *this, size_t hashbits)
+{
+ return libhashsum_init_rawshake_hasher(this, 128, hashbits);
+}
diff --git a/libhashsum_init_rawshake256_hasher.c b/libhashsum_init_rawshake256_hasher.c
new file mode 100644
index 0000000..abd7bd7
--- /dev/null
+++ b/libhashsum_init_rawshake256_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_rawshake256_hasher(struct libhashsum_hasher *this, size_t hashbits)
+{
+ return libhashsum_init_rawshake_hasher(this, 256, hashbits);
+}
diff --git a/libhashsum_init_rawshake512_hasher.c b/libhashsum_init_rawshake512_hasher.c
new file mode 100644
index 0000000..34009e1
--- /dev/null
+++ b/libhashsum_init_rawshake512_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_rawshake512_hasher(struct libhashsum_hasher *this, size_t hashbits)
+{
+ return libhashsum_init_rawshake_hasher(this, 512, hashbits);
+}
diff --git a/libhashsum_init_rawshake_hasher.c b/libhashsum_init_rawshake_hasher.c
new file mode 100644
index 0000000..f90e3b7
--- /dev/null
+++ b/libhashsum_init_rawshake_hasher.c
@@ -0,0 +1,52 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifdef SUPPORT_RAWSHAKE
+
+
+int
+libhashsum_init_rawshake_hasher(struct libhashsum_hasher *this, size_t hcapbits, size_t hashbits)
+{
+ struct libkeccak_spec spec;
+
+ if (hcapbits == 128U) {
+ this->algorithm = LIBHASHSUM_RAWSHAKE128;
+ this->algorithm_string = "RawSHAKE128";
+ } else if (hcapbits == 256U) {
+ this->algorithm = LIBHASHSUM_RAWSHAKE256;
+ this->algorithm_string = "RawSHAKE256";
+ } else if (hcapbits == 512U) {
+ this->algorithm = LIBHASHSUM_RAWSHAKE512;
+ this->algorithm_string = "RawSHAKE512";
+ } else {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (hashbits == 0U) {
+ hashbits = hcapbits;
+ } else if (hashbits > (size_t)LONG_MAX) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (hashbits != hcapbits) {
+ sprintf(this->state.keccak.algostr, "%s[n=%zu]", this->algorithm_string, hashbits);
+ this->algorithm_string = this->state.keccak.algostr;
+ }
+
+ libkeccak_spec_rawshake(&spec, (long int)hcapbits, (long int)hashbits);
+ return libhashsum_init_keccak__(this, hashbits, &spec, LIBKECCAK_RAWSHAKE_SUFFIX);
+}
+
+
+#else
+int
+libhashsum_init_rawshake_hasher(struct libhashsum_hasher *this, size_t hcapbits, size_t hashbits)
+{
+ (void) this;
+ (void) hcapbits;
+ (void) hashbits;
+ errno = ENOSYS;
+ return -1;
+}
+#endif
diff --git a/libhashsum_init_ripemd_128_hasher.c b/libhashsum_init_ripemd_128_hasher.c
index 39c5f1c..d958adb 100644
--- a/libhashsum_init_ripemd_128_hasher.c
+++ b/libhashsum_init_ripemd_128_hasher.c
@@ -221,6 +221,7 @@ libhashsum_init_ripemd_128_hasher(struct libhashsum_hasher *this)
this->process = &process;
this->finalise_const = &finalise_const;
this->finalise = &finalise;
+ this->destroy = NULL;
memset(&this->state.ripemd_128, 0, sizeof(this->state.ripemd_128));
this->state.ripemd_128.h.h32[0] = UINT32_C(0x67452301);
this->state.ripemd_128.h.h32[1] = UINT32_C(0xefcdab89);
diff --git a/libhashsum_init_ripemd_160_hasher.c b/libhashsum_init_ripemd_160_hasher.c
index 8b37b0a..edb1c5f 100644
--- a/libhashsum_init_ripemd_160_hasher.c
+++ b/libhashsum_init_ripemd_160_hasher.c
@@ -224,6 +224,7 @@ libhashsum_init_ripemd_160_hasher(struct libhashsum_hasher *this)
this->process = &process;
this->finalise_const = &finalise_const;
this->finalise = &finalise;
+ this->destroy = NULL;
memset(&this->state.ripemd_160, 0, sizeof(this->state.ripemd_160));
this->state.ripemd_160.h.h32[0] = UINT32_C(0x67452301);
this->state.ripemd_160.h.h32[1] = UINT32_C(0xefcdab89);
diff --git a/libhashsum_init_ripemd_256_hasher.c b/libhashsum_init_ripemd_256_hasher.c
index 6ba8aa0..ce3bf14 100644
--- a/libhashsum_init_ripemd_256_hasher.c
+++ b/libhashsum_init_ripemd_256_hasher.c
@@ -232,6 +232,7 @@ libhashsum_init_ripemd_256_hasher(struct libhashsum_hasher *this)
this->process = &process;
this->finalise_const = &finalise_const;
this->finalise = &finalise;
+ this->destroy = NULL;
memset(&this->state.ripemd_256, 0, sizeof(this->state.ripemd_256));
this->state.ripemd_256.h.h32[0] = UINT32_C(0x67452301);
this->state.ripemd_256.h.h32[1] = UINT32_C(0xefcdab89);
diff --git a/libhashsum_init_ripemd_320_hasher.c b/libhashsum_init_ripemd_320_hasher.c
index 2bb2383..d5af69a 100644
--- a/libhashsum_init_ripemd_320_hasher.c
+++ b/libhashsum_init_ripemd_320_hasher.c
@@ -238,6 +238,7 @@ libhashsum_init_ripemd_320_hasher(struct libhashsum_hasher *this)
this->process = &process;
this->finalise_const = &finalise_const;
this->finalise = &finalise;
+ this->destroy = NULL;
memset(&this->state.ripemd_320, 0, sizeof(this->state.ripemd_320));
this->state.ripemd_320.h.h32[0] = UINT32_C(0x67452301);
this->state.ripemd_320.h.h32[1] = UINT32_C(0xefcdab89);
diff --git a/libhashsum_init_sha0_hasher.c b/libhashsum_init_sha0_hasher.c
index eddb750..7f420d8 100644
--- a/libhashsum_init_sha0_hasher.c
+++ b/libhashsum_init_sha0_hasher.c
@@ -66,6 +66,7 @@ libhashsum_init_sha0_hasher(struct libhashsum_hasher *this)
this->process = &process;
this->finalise_const = &finalise_const;
this->finalise = &finalise;
+ this->destroy = NULL;
libsha1_init(&this->state.sha0.s, LIBSHA1_0);
return 0;
}
diff --git a/libhashsum_init_sha1_hasher.c b/libhashsum_init_sha1_hasher.c
index 023e856..91bcc15 100644
--- a/libhashsum_init_sha1_hasher.c
+++ b/libhashsum_init_sha1_hasher.c
@@ -66,6 +66,7 @@ libhashsum_init_sha1_hasher(struct libhashsum_hasher *this)
this->process = &process;
this->finalise_const = &finalise_const;
this->finalise = &finalise;
+ this->destroy = NULL;
libsha1_init(&this->state.sha1.s, LIBSHA1_1);
return 0;
}
diff --git a/libhashsum_init_sha2_hasher.c b/libhashsum_init_sha2_hasher.c
index b76f059..f06c59b 100644
--- a/libhashsum_init_sha2_hasher.c
+++ b/libhashsum_init_sha2_hasher.c
@@ -95,6 +95,7 @@ libhashsum_init_sha2_hasher(struct libhashsum_hasher *this, unsigned algobits, s
this->process = &process;
this->finalise_const = &finalise_const;
this->finalise = &finalise;
+ this->destroy = NULL;
libsha2_init(&this->state.sha2.s, algo);
return 0;
}
diff --git a/libhashsum_init_sha3_224_hasher.c b/libhashsum_init_sha3_224_hasher.c
new file mode 100644
index 0000000..d8ed53e
--- /dev/null
+++ b/libhashsum_init_sha3_224_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_sha3_224_hasher(struct libhashsum_hasher *this)
+{
+ return libhashsum_init_sha3_hasher(this, 224);
+}
diff --git a/libhashsum_init_sha3_256_hasher.c b/libhashsum_init_sha3_256_hasher.c
new file mode 100644
index 0000000..5a89d72
--- /dev/null
+++ b/libhashsum_init_sha3_256_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_sha3_256_hasher(struct libhashsum_hasher *this)
+{
+ return libhashsum_init_sha3_hasher(this, 256);
+}
diff --git a/libhashsum_init_sha3_384_hasher.c b/libhashsum_init_sha3_384_hasher.c
new file mode 100644
index 0000000..fb1f123
--- /dev/null
+++ b/libhashsum_init_sha3_384_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_sha3_384_hasher(struct libhashsum_hasher *this)
+{
+ return libhashsum_init_sha3_hasher(this, 384);
+}
diff --git a/libhashsum_init_sha3_512_hasher.c b/libhashsum_init_sha3_512_hasher.c
new file mode 100644
index 0000000..029968b
--- /dev/null
+++ b/libhashsum_init_sha3_512_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_sha3_512_hasher(struct libhashsum_hasher *this)
+{
+ return libhashsum_init_sha3_hasher(this, 512);
+}
diff --git a/libhashsum_init_sha3_hasher.c b/libhashsum_init_sha3_hasher.c
new file mode 100644
index 0000000..c9d6ac7
--- /dev/null
+++ b/libhashsum_init_sha3_hasher.c
@@ -0,0 +1,42 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifdef SUPPORT_SHA3
+
+
+int
+libhashsum_init_sha3_hasher(struct libhashsum_hasher *this, size_t hashbits)
+{
+ struct libkeccak_spec spec;
+
+ if (hashbits == 224U) {
+ this->algorithm = LIBHASHSUM_SHA3_224;
+ this->algorithm_string = "SHA3-224";
+ } else if (hashbits == 256U) {
+ this->algorithm = LIBHASHSUM_SHA3_256;
+ this->algorithm_string = "SHA3-256";
+ } else if (hashbits == 384U) {
+ this->algorithm = LIBHASHSUM_SHA3_384;
+ this->algorithm_string = "SHA3-384";
+ } else if (hashbits == 512U) {
+ this->algorithm = LIBHASHSUM_SHA3_512;
+ this->algorithm_string = "SHA3-512";
+ } else {
+ errno = EINVAL;
+ return -1;
+ }
+
+ libkeccak_spec_sha3(&spec, (long int)hashbits);
+ return libhashsum_init_keccak__(this, hashbits, &spec, LIBKECCAK_SHA3_SUFFIX);
+}
+
+
+#else
+int
+libhashsum_init_sha3_hasher(struct libhashsum_hasher *this, size_t hashbits)
+{
+ (void) this;
+ (void) hashbits;
+ errno = ENOSYS;
+ return -1;
+}
+#endif
diff --git a/libhashsum_init_shake128_hasher.c b/libhashsum_init_shake128_hasher.c
new file mode 100644
index 0000000..2b7df6a
--- /dev/null
+++ b/libhashsum_init_shake128_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_shake128_hasher(struct libhashsum_hasher *this, size_t hashbits)
+{
+ return libhashsum_init_shake_hasher(this, 128, hashbits);
+}
diff --git a/libhashsum_init_shake256_hasher.c b/libhashsum_init_shake256_hasher.c
new file mode 100644
index 0000000..26c4f09
--- /dev/null
+++ b/libhashsum_init_shake256_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_shake256_hasher(struct libhashsum_hasher *this, size_t hashbits)
+{
+ return libhashsum_init_shake_hasher(this, 256, hashbits);
+}
diff --git a/libhashsum_init_shake512_hasher.c b/libhashsum_init_shake512_hasher.c
new file mode 100644
index 0000000..ddaf2ed
--- /dev/null
+++ b/libhashsum_init_shake512_hasher.c
@@ -0,0 +1,9 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+
+
+int
+libhashsum_init_shake512_hasher(struct libhashsum_hasher *this, size_t hashbits)
+{
+ return libhashsum_init_shake_hasher(this, 512, hashbits);
+}
diff --git a/libhashsum_init_shake_hasher.c b/libhashsum_init_shake_hasher.c
new file mode 100644
index 0000000..a5f5746
--- /dev/null
+++ b/libhashsum_init_shake_hasher.c
@@ -0,0 +1,52 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifdef SUPPORT_SHAKE
+
+
+int
+libhashsum_init_shake_hasher(struct libhashsum_hasher *this, size_t hcapbits, size_t hashbits)
+{
+ struct libkeccak_spec spec;
+
+ if (hcapbits == 128U) {
+ this->algorithm = LIBHASHSUM_SHAKE128;
+ this->algorithm_string = "SHAKE128";
+ } else if (hcapbits == 256U) {
+ this->algorithm = LIBHASHSUM_SHAKE256;
+ this->algorithm_string = "SHAKE256";
+ } else if (hcapbits == 512U) {
+ this->algorithm = LIBHASHSUM_SHAKE512;
+ this->algorithm_string = "SHAKE512";
+ } else {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (hashbits == 0U) {
+ hashbits = hcapbits;
+ } else if (hashbits > (size_t)LONG_MAX) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (hashbits != hcapbits) {
+ sprintf(this->state.keccak.algostr, "%s[n=%zu]", this->algorithm_string, hashbits);
+ this->algorithm_string = this->state.keccak.algostr;
+ }
+
+ libkeccak_spec_shake(&spec, (long int)hcapbits, (long int)hashbits);
+ return libhashsum_init_keccak__(this, hashbits, &spec, LIBKECCAK_SHAKE_SUFFIX);
+}
+
+
+#else
+int
+libhashsum_init_shake_hasher(struct libhashsum_hasher *this, size_t hcapbits, size_t hashbits)
+{
+ (void) this;
+ (void) hcapbits;
+ (void) hashbits;
+ errno = ENOSYS;
+ return -1;
+}
+#endif