diff options
author | Mattias Andrée <maandree@kth.se> | 2024-08-24 18:02:00 +0200 |
---|---|---|
committer | Mattias Andrée <maandree@kth.se> | 2024-08-24 18:02:00 +0200 |
commit | 72111e7a53eaad7bea841ab8b09e70642bde00ae (patch) | |
tree | 016e0326b794f8a5b9cc03139b8a5ab094ed7411 /libhashsum | |
parent | Make it possible for libhashsum_state to grow in future versions (diff) | |
download | libhashsum-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 '')
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 |