aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2024-09-01 16:34:46 +0200
committerMattias Andrée <maandree@kth.se>2024-09-01 16:34:46 +0200
commitd737d34b436f673173695c4c772f0ddef9fe7837 (patch)
treef6bf400809124d411eaff38fe2c9d24842c8d23a
parentm fix (diff)
downloadlibhashsum-d737d34b436f673173695c4c772f0ddef9fe7837.tar.gz
libhashsum-d737d34b436f673173695c4c772f0ddef9fe7837.tar.bz2
libhashsum-d737d34b436f673173695c4c772f0ddef9fe7837.tar.xz
Add support for BLAKE2 (but not tree-hashing)
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile4
-rw-r--r--README3
-rw-r--r--common.h5
-rw-r--r--config.mk6
-rw-r--r--libhashsum.75
-rw-r--r--libhashsum.h77
-rw-r--r--libhashsum/internal.h16
-rw-r--r--libhashsum_get_algorithm_from_string.318
-rw-r--r--libhashsum_get_algorithm_from_string.c4
-rw-r--r--libhashsum_init_blake2b_hasher.c202
-rw-r--r--libhashsum_init_blake2s_hasher.c201
-rw-r--r--libhashsum_init_hasher.312
-rw-r--r--libhashsum_init_hasher.c4
-rw-r--r--libhashsum_init_hasher_from_string.32
-rw-r--r--libhashsum_init_hasher_from_string.c172
-rw-r--r--misc-tests.c115
-rw-r--r--mk/after-config.mk6
-rw-r--r--mk/before-config.mk2
l---------mk/blake2b=no.mk1
-rw-r--r--mk/blake2b=yes.mk4
l---------mk/blake2s=no.mk1
-rw-r--r--mk/blake2s=yes.mk4
22 files changed, 822 insertions, 42 deletions
diff --git a/Makefile b/Makefile
index 6a4b01c..a05adac 100644
--- a/Makefile
+++ b/Makefile
@@ -68,7 +68,9 @@ OBJ_PUBLIC =\
libhashsum_init_blake384_hasher.o\
libhashsum_init_blake512_hasher.o\
libhashsum_init_blakeb_hasher.o\
- libhashsum_init_blake_hasher.o
+ libhashsum_init_blake_hasher.o\
+ libhashsum_init_blake2s_hasher.o\
+ libhashsum_init_blake2b_hasher.o
OBJ_HIDDEN =\
libhashsum_reverse_byte__.o\
diff --git a/README b/README
index 1ee0242..f34b8f7 100644
--- a/README
+++ b/README
@@ -26,6 +26,9 @@ DESCRIPTION
Via libblake>=1.1
BLAKE224, BLAKE256, BLAKE384, BLAKE512
+ Via libblake>=3.0
+ BLAKE2s, BLAKE2b
+
libhashsum makes it easy to select at compile-time which
functions to compile support for.
diff --git a/common.h b/common.h
index 01d3231..18d817c 100644
--- a/common.h
+++ b/common.h
@@ -24,7 +24,10 @@
#if defined(SUPPORT_BLAKES) || defined(SUPPORT_BLAKEB)
# define SUPPORT_BLAKE
#endif
-#if defined(SUPPORT_BLAKE)
+#if defined(SUPPORT_BLAKE2S) || defined(SUPPORT_BLAKE2B)
+# define SUPPORT_BLAKE2
+#endif
+#if defined(SUPPORT_BLAKE) || defined(SUPPORT_BLAKE2)
# define LIBHASHSUM_INCLUDE_LIBBLAKE_STATE
#endif
diff --git a/config.mk b/config.mk
index b415389..357a9b0 100644
--- a/config.mk
+++ b/config.mk
@@ -72,3 +72,9 @@ SUPPORT_BLAKE384 = $(DEFAULT_SUPPORT)
SUPPORT_BLAKE512 = $(DEFAULT_SUPPORT)
# Requires libblake>=1.1
+
+SUPPORT_BLAKE2S = $(DEFAULT_SUPPORT)
+# Requires libblake>=3.0
+
+SUPPORT_BLAKE2B = $(DEFAULT_SUPPORT)
+# Requires libblake>=3.0
diff --git a/libhashsum.7 b/libhashsum.7
index 1945b99..ec8dcb1 100644
--- a/libhashsum.7
+++ b/libhashsum.7
@@ -20,7 +20,7 @@ Link with
(unless support for Keccak, SHA-3, SHAKE, and RawSHAKE was excluded)
.br
.I -lblake
-(unless support for BLAKE was excluded).
+(unless support for BLAKE and BLAKE2 was excluded).
.SH DESCRIPTION
The
@@ -46,6 +46,9 @@ RawSHAKE128, RawSHAKE256, RawSHAKE512
.TP
Via libblake>=1.1
BLAKE224, BLAKE256, BLAKE384, BLAKE512
+.TP
+Via libblake>=3.0
+BLAKE2s, BLAKE2b
.PP
For each hash function,
.B libhashsum
diff --git a/libhashsum.h b/libhashsum.h
index 780b567..777176b 100644
--- a/libhashsum.h
+++ b/libhashsum.h
@@ -186,6 +186,7 @@
/**
* The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHAKE256`
+ * (using default hash size)
*
* @since 1.0
*/
@@ -193,6 +194,7 @@
/**
* The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_SHAKE512`
+ * (using default hash size)
*
* @since 1.0
*/
@@ -200,6 +202,7 @@
/**
* The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RAWSHAKE128`
+ * (using default hash size)
*
* @since 1.0
*/
@@ -207,6 +210,7 @@
/**
* The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RAWSHAKE256`
+ * (using default hash size)
*
* @since 1.0
*/
@@ -214,6 +218,7 @@
/**
* The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_RAWSHAKE512`
+ * (using default hash size)
*
* @since 1.0
*/
@@ -247,6 +252,22 @@
*/
#define LIBHASHSUM_BLAKE512_HASH_SIZE 64
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_BLAKE2S`
+ * (using default/maximium hash size)
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_BLAKE2S_HASH_SIZE 32
+
+/**
+ * The value of `struct libhashsum_hasher.hash_size` for `LIBHASHSUM_BLAKE2B`
+ * (using default/maximium hash size)
+ *
+ * @since 1.0
+ */
+#define LIBHASHSUM_BLAKE2B_HASH_SIZE 64
+
#if defined(__GNUC__)
# pragma GCC diagnostic push
@@ -297,7 +318,9 @@ enum libhashsum_algorithm {
LIBHASHSUM_BLAKE224, /**< BLAKE224 (BLAKE, BLAKEs) */
LIBHASHSUM_BLAKE256, /**< BLAKE256 (BLAKE, BLAKEs) */
LIBHASHSUM_BLAKE384, /**< BLAKE384 (BLAKE, BLAKEb) */
- LIBHASHSUM_BLAKE512 /**< BLAKE512 (BLAKE, BLAKEb) */
+ LIBHASHSUM_BLAKE512, /**< BLAKE512 (BLAKE, BLAKEb) */
+ LIBHASHSUM_BLAKE2S, /**< BLAKE2s (BLAKE2) */
+ LIBHASHSUM_BLAKE2B /**< BLAKE2b (BLAKE2) */
};
@@ -1214,5 +1237,57 @@ int libhashsum_init_blakeb_hasher(struct libhashsum_hasher *this, size_t hashbit
LIBHASHSUM_1_NONNULL_
int libhashsum_init_blake_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt, size_t saltbytes);
+/**
+ * Create an initialised state for BLAKE2s (BLAKE2)
+ * 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, must be an multiple of 8 between
+ * 8 and 256 (inclusively), or 0 for the maximum size
+ * @param salt `NULL` (for all zeroes) or a 8-byte salt
+ * @param pepper `NULL` (for all zeroes) or a 8-byte pepper
+ * @param key Key or `NULL` for unkeyed mode,
+ * @param keybits The number of byts in `key` (0 if `key` is `NULL`),
+ * which must be a multiple of 8 no greater than 256
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hashbits` is greater than 256
+ * @throws EINVAL `hashbits` is not a multiple of 8
+ * @throws EINVAL `keybits` is greater than 256
+ * @throws EINVAL `keybits` is not a multiple of 8
+ * @throws ENOSYS Support was excluded at compile time
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_blake2s_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt, /* TODO man, test */
+ const void *pepper, const void *key, size_t keybits);
+
+/**
+ * Create an initialised state for BLAKE2b (BLAKE2)
+ * 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, must be an multiple of 8 between
+ * 8 and 512 (inclusively), or 0 for the maximum size
+ * @param salt `NULL` (for all zeroes) or a 16-byte salt
+ * @param pepper `NULL` (for all zeroes) or a 16-byte pepper
+ * @param key Key or `NULL` for unkeyed mode,
+ * @param keybits The number of byts in `key` (0 if `key` is `NULL`),
+ * which must be a multiple of 8 no greater than 512
+ * @return 0 on success, -1 on failure
+ *
+ * @throws EINVAL `hashbits` is greater than 512
+ * @throws EINVAL `hashbits` is not a multiple of 8
+ * @throws EINVAL `keybits` is greater than 512
+ * @throws EINVAL `keybits` is not a multiple of 8
+ * @throws ENOSYS Support was excluded at compile time
+ *
+ * @since 1.0
+ */
+LIBHASHSUM_1_NONNULL_
+int libhashsum_init_blake2b_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt, /* TODO man, test */
+ const void *pepper, const void *key, size_t keybits);
+
#endif
diff --git a/libhashsum/internal.h b/libhashsum/internal.h
index b75cdd9..e02a417 100644
--- a/libhashsum/internal.h
+++ b/libhashsum/internal.h
@@ -155,9 +155,23 @@ union libhashsum_state {
uint8_t buf[256];
char algostr[81];
} blake512; /* size = 449 */
+
+ struct {
+ struct libblake_blake2s_state s;
+ char algostr[130];
+ unsigned char buf[64];
+ unsigned char keybytes;
+ } blake2s; /* size = 243 */
+
+ struct {
+ struct libblake_blake2b_state s;
+ char algostr[226];
+ unsigned char buf[128];
+ unsigned char keybytes;
+ } blake2b; /* size = 451 */
#endif
- /* libblake: 48(2s), 96(2b), 144(2Xs), 276(2Xb) */
+ /* libblake: 144(2Xs), 276(2Xb) */
char max_size[1648];
#define libhashsum_init_hasher libhashsum_init_hasher__1648
diff --git a/libhashsum_get_algorithm_from_string.3 b/libhashsum_get_algorithm_from_string.3
index c039da6..b01d1c7 100644
--- a/libhashsum_get_algorithm_from_string.3
+++ b/libhashsum_get_algorithm_from_string.3
@@ -301,6 +301,23 @@ is
.RB \(dq BLAKE-512 \(dq
or
.RB \(dq B512 \(dq.
+.TP
+.B LIBHASHSUM_BLAKE2S
+BLAKE2s (BLAKE2)
+
+.I algorithm
+is
+.RB \(dq BLAKE2s \(dq
+or
+.RB \(dq B2s \(dq.
+.TP
+BLAKE2b (BLAKE2)
+
+.I algorithm
+is
+.RB \(dq BLAKE2b \(dq
+or
+.RB \(dq B2b \(dq.
.PP
The function is case-insensitive, and tolerates
skipping dashes
@@ -309,6 +326,7 @@ that are not immediately after a digit. Additionally,
it will ignore the substring
.RB \(dq sum \(dq
if it is added to the end of the function name.
+
.PP
The function
.I does not
diff --git a/libhashsum_get_algorithm_from_string.c b/libhashsum_get_algorithm_from_string.c
index 9740510..07d97e5 100644
--- a/libhashsum_get_algorithm_from_string.c
+++ b/libhashsum_get_algorithm_from_string.c
@@ -97,6 +97,10 @@ libhashsum_get_algorithm_from_string(enum libhashsum_algorithm *algorithm_out, c
*algorithm_out = LIBHASHSUM_BLAKE384;
else if (equiv(algorithm, "BLAKE-512[]") || equiv(algorithm, "B512[]"))
*algorithm_out = LIBHASHSUM_BLAKE512;
+ else if (equiv(algorithm, "BLAKE-2s[]") || equiv(algorithm, "B2s[]"))
+ *algorithm_out = LIBHASHSUM_BLAKE2S;
+ else if (equiv(algorithm, "BLAKE-2b[]") || equiv(algorithm, "B2b[]"))
+ *algorithm_out = LIBHASHSUM_BLAKE2B;
else
return 0;
return 1;
diff --git a/libhashsum_init_blake2b_hasher.c b/libhashsum_init_blake2b_hasher.c
new file mode 100644
index 0000000..57be6fe
--- /dev/null
+++ b/libhashsum_init_blake2b_hasher.c
@@ -0,0 +1,202 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifdef SUPPORT_BLAKE2B
+
+
+#define BLAKE2B_BLOCK_SIZE 128U
+
+
+LIBHASHSUM_1_NONNULL_
+static size_t
+process(struct libhashsum_hasher *this, const void *data, size_t bytes)
+{
+ if (this->state.blake2b.keybytes && bytes) {
+ libblake_blake2b_force_update(&this->state.blake2b.s, this->state.blake2b.buf, BLAKE2B_BLOCK_SIZE);
+ this->state.blake2b.keybytes = 0;
+ memset(this->state.blake2b.buf, 0, (size_t)this->state.blake2b.keybytes);
+ }
+ return libblake_blake2b_update(&this->state.blake2b.s, data, bytes);
+}
+
+
+LIBHASHSUM_1_NONNULL_
+static int
+finalise_const(struct libhashsum_hasher *this, const void *data, size_t bytes, unsigned extra_bits)
+{
+ const unsigned char *m = data;
+ size_t r;
+
+ if (extra_bits) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ r = process(this, data, bytes);
+ m = &m[r];
+ bytes -= r;
+
+ if (!this->hash_output)
+ this->hash_output = this->state.blake2b.buf;
+
+ if (this->state.blake2b.keybytes)
+ bytes = BLAKE2B_BLOCK_SIZE;
+ else
+ memcpy(this->state.blake2b.buf, m, bytes);
+ libblake_blake2b_digest(&this->state.blake2b.s, this->state.blake2b.buf,
+ bytes, 0, this->hash_size, this->hash_output);
+
+ memset(&this->state.blake2b.s, 0, sizeof(this->state.blake2b.s));
+ this->state.blake2b.keybytes = 0;
+ return 0;
+}
+
+
+LIBHASHSUM_1_NONNULL_
+static int
+finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size)
+{
+ unsigned char *m = data;
+ size_t r;
+
+ if (extra_bits) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ r = process(this, data, bytes);
+ m = &m[r];
+ bytes -= r;
+ size -= r;
+
+ if (!this->hash_output)
+ this->hash_output = this->state.blake224.buf;
+
+ if (this->state.blake2b.keybytes) {
+ bytes = BLAKE2B_BLOCK_SIZE;
+ m = this->state.blake2b.buf;
+ } else if (size < libblake_blake2b_digest_get_required_input_size(bytes)) {
+ memcpy(this->state.blake2b.buf, m, bytes);
+ m = this->state.blake2b.buf;
+ }
+ libblake_blake2b_digest(&this->state.blake2b.s, m, bytes, 0, this->hash_size, this->hash_output);
+
+ memset(&this->state.blake2b.s, 0, sizeof(this->state.blake2b.s));
+ this->state.blake2b.keybytes = 0;
+ return 0;
+}
+
+
+#if defined(__GNUC__)
+__attribute__((__pure__))
+#endif
+static int
+allzeroes(const uint8_t *data, size_t n)
+{
+ if (data)
+ while (n--)
+ if (data[n])
+ return 0;
+ return 1;
+}
+
+
+static char *
+hex(char *buf, const uint8_t *data, size_t n)
+{
+ size_t i;
+ for (i = 0; i < n; i++) {
+ *buf++ = "0123456789abcdef"[(data[i] >> 4) & 15];
+ *buf++ = "0123456789abcdef"[(data[i] >> 0) & 15];
+ }
+ return buf;
+}
+
+
+static const char *
+mkalgostr(char *buf, const char *name, size_t hashbits, const uint8_t *salt,
+ const uint8_t *pepper, size_t salt_pepper_bytes, const uint8_t *key, size_t keybytes)
+{
+ char *p, *b;
+ int with_salt = (salt && !allzeroes(salt, salt_pepper_bytes));
+ int with_pepper = (pepper && !allzeroes(pepper, salt_pepper_bytes));
+ if (!hashbits && !with_salt && !with_pepper && !keybytes)
+ return name;
+ b = p = stpcpy(buf, name);
+ if (hashbits)
+ p = &p[sprintf(p, ",n=%zu", hashbits)];
+ if (with_salt)
+ p = hex(stpcpy(p, ",salt="), salt, salt_pepper_bytes);
+ if (with_pepper)
+ p = hex(stpcpy(p, ",pepper="), pepper, salt_pepper_bytes);
+ if (keybytes)
+ p = hex(stpcpy(p, ",key="), key, keybytes);
+ *b = '[';
+ *p++ = ']';
+ *p++ = '\0';
+ return buf;
+}
+
+
+int
+libhashsum_init_blake2b_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt,
+ const void *pepper, const void *key, size_t keybits)
+{
+ struct libblake_blake2b_params params = {
+ .digest_len = (unsigned char)(hashbits / 8U),
+ .key_len = (unsigned char)(keybits / 8U),
+ .fanout = 1U,
+ .depth = 1U,
+ .leaf_len = 0U,
+ .node_offset = 0U,
+ .node_depth = 0U,
+ .inner_len = 0U
+ };
+ if (((hashbits | keybits) & 7U) || ((hashbits | keybits) > 256U)) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (!hashbits)
+ hashbits = 512U;
+ libblake_init();
+ this->algorithm = LIBHASHSUM_BLAKE2B;
+ this->algorithm_string = mkalgostr(this->state.blake2b.algostr, "BLAKE2b",
+ hashbits == 512U ? 0U : hashbits,
+ salt, pepper, 16U, key, keybits / 8U);
+ this->input_block_size = BLAKE2B_BLOCK_SIZE;
+ this->hash_size = hashbits / 8U;
+ this->hash_output = NULL;
+ this->supports_non_whole_bytes = 0;
+ this->process = &process;
+ this->finalise_const = &finalise_const;
+ this->finalise = &finalise;
+ this->stretch = NULL;
+ this->destroy = NULL;
+ if (salt)
+ memcpy(params.salt, salt, sizeof(params.salt));
+ if (pepper)
+ memcpy(params.pepper, pepper, sizeof(params.pepper));
+ this->state.blake2b.keybytes = (unsigned char)(keybits / 8U);
+ if (this->state.blake2b.keybytes) {
+ memcpy(this->state.blake2b.buf, key, keybits / 8U);
+ memset(&this->state.blake2b.buf[keybits / 8U], 0, sizeof(this->state.blake2b.buf) - keybits / 8U);
+ }
+ libblake_blake2b_init(&this->state.blake2b.s, &params);
+ return 0;
+}
+
+
+#else
+int
+libhashsum_init_blake2b_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt,
+ const void *pepper, const void *key, size_t keybits)
+{
+ (void) this;
+ (void) hashbits;
+ (void) salt;
+ (void) pepper;
+ (void) key;
+ (void) keybits;
+ errno = ENOSYS;
+ return -1;
+}
+#endif
diff --git a/libhashsum_init_blake2s_hasher.c b/libhashsum_init_blake2s_hasher.c
new file mode 100644
index 0000000..0957b22
--- /dev/null
+++ b/libhashsum_init_blake2s_hasher.c
@@ -0,0 +1,201 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+#ifdef SUPPORT_BLAKE2S
+
+
+#define BLAKE2S_BLOCK_SIZE 64U
+
+
+LIBHASHSUM_1_NONNULL_
+static size_t
+process(struct libhashsum_hasher *this, const void *data, size_t bytes)
+{
+ if (this->state.blake2s.keybytes && bytes) {
+ libblake_blake2s_force_update(&this->state.blake2s.s, this->state.blake2s.buf, BLAKE2S_BLOCK_SIZE);
+ this->state.blake2s.keybytes = 0;
+ memset(this->state.blake2s.buf, 0, (size_t)this->state.blake2s.keybytes);
+ }
+ return libblake_blake2s_update(&this->state.blake2s.s, data, bytes);
+}
+
+
+LIBHASHSUM_1_NONNULL_
+static int
+finalise_const(struct libhashsum_hasher *this, const void *data, size_t bytes, unsigned extra_bits)
+{
+ const unsigned char *m = data;
+ size_t r;
+
+ if (extra_bits) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ r = process(this, data, bytes);
+ m = &m[r];
+ bytes -= r;
+
+ if (!this->hash_output)
+ this->hash_output = this->state.blake2s.buf;
+
+ if (this->state.blake2s.keybytes)
+ bytes = BLAKE2S_BLOCK_SIZE;
+ else
+ memcpy(this->state.blake2s.buf, m, bytes);
+ libblake_blake2s_digest(&this->state.blake2s.s, this->state.blake2s.buf,
+ bytes, 0, this->hash_size, this->hash_output);
+
+ memset(&this->state.blake2s.s, 0, sizeof(this->state.blake2s.s));
+ this->state.blake2s.keybytes = 0;
+ return 0;
+}
+
+
+LIBHASHSUM_1_NONNULL_
+static int
+finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extra_bits, size_t size)
+{
+ unsigned char *m = data;
+ size_t r;
+
+ if (extra_bits) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ r = process(this, data, bytes);
+ m = &m[r];
+ bytes -= r;
+ size -= r;
+
+ if (!this->hash_output)
+ this->hash_output = this->state.blake224.buf;
+
+ if (this->state.blake2s.keybytes) {
+ bytes = BLAKE2S_BLOCK_SIZE;
+ m = this->state.blake2s.buf;
+ } else if (size < libblake_blake2s_digest_get_required_input_size(bytes)) {
+ memcpy(this->state.blake2s.buf, m, bytes);
+ m = this->state.blake2s.buf;
+ }
+ libblake_blake2s_digest(&this->state.blake2s.s, m, bytes, 0, this->hash_size, this->hash_output);
+
+ memset(&this->state.blake2s.s, 0, sizeof(this->state.blake2s.s));
+ this->state.blake2s.keybytes = 0;
+ return 0;
+}
+
+
+#if defined(__GNUC__)
+__attribute__((__pure__))
+#endif
+static int
+allzeroes(const uint8_t *data, size_t n)
+{
+ while (n--)
+ if (data[n])
+ return 0;
+ return 1;
+}
+
+
+static char *
+hex(char *buf, const uint8_t *data, size_t n)
+{
+ size_t i;
+ for (i = 0; i < n; i++) {
+ *buf++ = "0123456789abcdef"[(data[i] >> 4) & 15];
+ *buf++ = "0123456789abcdef"[(data[i] >> 0) & 15];
+ }
+ return buf;
+}
+
+
+static const char *
+mkalgostr(char *buf, const char *name, size_t hashbits, const uint8_t *salt,
+ const uint8_t *pepper, size_t salt_pepper_bytes, const uint8_t *key, size_t keybytes)
+{
+ char *p, *b;
+ int with_salt = (salt && !allzeroes(salt, salt_pepper_bytes));
+ int with_pepper = (pepper && !allzeroes(pepper, salt_pepper_bytes));
+ if (!hashbits && !with_salt && !with_pepper && !keybytes)
+ return name;
+ b = p = stpcpy(buf, name);
+ if (hashbits)
+ p = &p[sprintf(p, ",n=%zu", hashbits)];
+ if (with_salt)
+ p = hex(stpcpy(p, ",salt="), salt, salt_pepper_bytes);
+ if (with_pepper)
+ p = hex(stpcpy(p, ",pepper="), pepper, salt_pepper_bytes);
+ if (keybytes)
+ p = hex(stpcpy(p, ",key="), key, keybytes);
+ *b = '[';
+ *p++ = ']';
+ *p++ = '\0';
+ return buf;
+}
+
+
+int
+libhashsum_init_blake2s_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt,
+ const void *pepper, const void *key, size_t keybits)
+{
+ struct libblake_blake2s_params params = {
+ .digest_len = (unsigned char)(hashbits / 8U),
+ .key_len = (unsigned char)(keybits / 8U),
+ .fanout = 1U,
+ .depth = 1U,
+ .leaf_len = 0U,
+ .node_offset = 0U,
+ .node_depth = 0U,
+ .inner_len = 0U
+ };
+ if (((hashbits | keybits) & 7U) || ((hashbits | keybits) > 256U)) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (!hashbits)
+ hashbits = 256U;
+ libblake_init();
+ this->algorithm = LIBHASHSUM_BLAKE2S;
+ this->algorithm_string = mkalgostr(this->state.blake2s.algostr, "BLAKE2s",
+ hashbits == 256U ? 0U : hashbits,
+ salt, pepper, 8U, key, keybits / 8U);
+ this->input_block_size = BLAKE2S_BLOCK_SIZE;
+ this->hash_size = hashbits / 8U;
+ this->hash_output = NULL;
+ this->supports_non_whole_bytes = 0;
+ this->process = &process;
+ this->finalise_const = &finalise_const;
+ this->finalise = &finalise;
+ this->stretch = NULL;
+ this->destroy = NULL;
+ if (salt)
+ memcpy(params.salt, salt, sizeof(params.salt));
+ if (pepper)
+ memcpy(params.pepper, pepper, sizeof(params.pepper));
+ this->state.blake2s.keybytes = (unsigned char)(keybits / 8U);
+ if (this->state.blake2s.keybytes) {
+ memcpy(this->state.blake2s.buf, key, keybits / 8U);
+ memset(&this->state.blake2s.buf[keybits / 8U], 0, sizeof(this->state.blake2s.buf) - keybits / 8U);
+ }
+ libblake_blake2s_init(&this->state.blake2s.s, &params);
+ return 0;
+}
+
+
+#else
+int
+libhashsum_init_blake2s_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt,
+ const void *pepper, const void *key, size_t keybits)
+{
+ (void) this;
+ (void) hashbits;
+ (void) salt;
+ (void) pepper;
+ (void) key;
+ (void) keybits;
+ errno = ENOSYS;
+ return -1;
+}
+#endif
diff --git a/libhashsum_init_hasher.3 b/libhashsum_init_hasher.3
index 0f3f978..a61b00e 100644
--- a/libhashsum_init_hasher.3
+++ b/libhashsum_init_hasher.3
@@ -39,7 +39,7 @@ Link with
(unless support for Keccak, SHA-3, SHAKE, and RawSHAKE was excluded)
.br
.I -lblake
-(unless support for BLAKE was excluded).
+(unless support for BLAKE and BLAKE2 was excluded).
.SH DESCRIPTION
The
@@ -232,6 +232,16 @@ for more information.
Selects BLAKE512 (BLAKE, BLAKEb). See
.BR libhashsum_init_blake512_hasher (3)
for more information.
+.TP
+.B LIBHASHSUM_BLAKE2S
+Selects BLAKE2s (BLAKE2). See
+.BR libhashsum_init_blake2s_hasher (3)
+for more information.
+.TP
+.B LIBHASHSUM_BLAKE2B
+Selects BLAKE2b (BLAKE). See
+.BR libhashsum_init_blake2b_hasher (3)
+for more information.
.PP
.I hasher->algorithm
will be set to
diff --git a/libhashsum_init_hasher.c b/libhashsum_init_hasher.c
index 6f09629..02c1e92 100644
--- a/libhashsum_init_hasher.c
+++ b/libhashsum_init_hasher.c
@@ -72,6 +72,10 @@ libhashsum_init_hasher(struct libhashsum_hasher *this, enum libhashsum_algorithm
return libhashsum_init_blake384_hasher(this, NULL);
case LIBHASHSUM_BLAKE512:
return libhashsum_init_blake512_hasher(this, NULL);
+ case LIBHASHSUM_BLAKE2S:
+ return libhashsum_init_blake2s_hasher(this, 0, NULL, NULL, NULL, 0);
+ case LIBHASHSUM_BLAKE2B:
+ return libhashsum_init_blake2b_hasher(this, 0, NULL, NULL, NULL, 0);
default:
case LIBHASHSUM_KECCAK:
errno = EINVAL;
diff --git a/libhashsum_init_hasher_from_string.3 b/libhashsum_init_hasher_from_string.3
index db88547..901d3f5 100644
--- a/libhashsum_init_hasher_from_string.3
+++ b/libhashsum_init_hasher_from_string.3
@@ -37,7 +37,7 @@ Link with
(unless support for Keccak, SHA-3, SHAKE, and RawSHAKE was excluded)
.br
.I -lblake
-(unless support for BLAKE was excluded).
+(unless support for BLAKE and BLAKE2 was excluded).
.SH DESCRIPTION
The
diff --git a/libhashsum_init_hasher_from_string.c b/libhashsum_init_hasher_from_string.c
index a1ee827..ffd23eb 100644
--- a/libhashsum_init_hasher_from_string.c
+++ b/libhashsum_init_hasher_from_string.c
@@ -3,28 +3,42 @@
static int
+parse_value(size_t *valp, const char *p, const char **end_out)
+{
+ size_t digit;
+ if (*valp)
+ return -1;
+ 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_n(int (*initfunc)(struct libhashsum_hasher *, size_t), struct libhashsum_hasher *this, const char *algorithm)
{
const char *p;
- size_t n = 0, digit;
+ size_t n = 0;
p = strchr(algorithm, '[');
- if (!p || *++p == ']')
+ if (!p || *++p == ']') {
+ if (p && *++p)
+ goto einval;
return initfunc(this, 0);
+ }
if (*p != 'n' && *p != 'N')
goto einval;
- p++;
- if (*p++ != '=' || !('1' <= *p && *p <= '9'))
+ if (parse_value(&n, &p[1], &p))
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;
@@ -37,25 +51,6 @@ einval:
static int
-parse_value(size_t *valp, const char *p, const char **end_out)
-{
- size_t digit;
- if (*valp)
- return -1;
- 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_rcnz(int (*initfunc)(struct libhashsum_hasher *, size_t, size_t, size_t, size_t),
struct libhashsum_hasher *this, const char *algorithm)
{
@@ -64,7 +59,7 @@ with_rcnz(int (*initfunc)(struct libhashsum_hasher *, size_t, size_t, size_t, si
p = strchr(algorithm, '[');
if (!p || *++p == ']') {
- if (p && *p)
+ if (p && *++p)
goto einval;
return initfunc(this, 0, 0, 0, 0);
}
@@ -112,8 +107,11 @@ with_salt(int (*initfunc)(struct libhashsum_hasher *, const void *),
size_t salti = 0;
p = strchr(algorithm, '[');
- if (!p || *++p == ']')
+ if (!p || *++p == ']') {
+ if (p && *++p)
+ goto einval;
return initfunc(this, NULL);
+ }
if (*p != 's' && *p != 'S')
goto einval;
@@ -156,10 +154,116 @@ with_salt(int (*initfunc)(struct libhashsum_hasher *, const void *),
if (*p++ != ']' || *p)
goto einval;
- return initfunc(this, salt);
+ return initfunc(this, salti ? salt : NULL);
+
+einval:
+ errno = EINVAL;
+ return -1;
+}
+
+
+static int
+blake2(int (*initfunc)(struct libhashsum_hasher *, size_t, const void *, const void *, const void *, size_t),
+ struct libhashsum_hasher *this, const char *algorithm, size_t saltbytes, size_t pepperbytes)
+{
+ const char *p;
+ uint8_t a, b, salt[16], pepper[16], *key = NULL;
+ size_t n = 0, salti = 0, pepperi = 0, keyi = 0, i;
+ int r;
+
+ p = strchr(algorithm, '[');
+ if (!p || *++p == ']') {
+ if (p && *++p)
+ goto einval;
+ return initfunc(this, 0, NULL, NULL, NULL, 0);
+ }
+
+next:
+ if (!salti && !strncasecmp(p, "salt=", 5U)) {
+ p = &p[5];
+ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
+ p = &p[2];
+ for (;;) {
+ if (isxdigit(p[0]) && isxdigit(p[1])) {
+ if (!saltbytes)
+ goto einval;
+ saltbytes--;
+ } else if (isxdigit(p[0])) {
+ goto einval;
+ } else if (saltbytes) {
+ goto einval;
+ } else {
+ break;
+ }
+ a = (uint8_t)(((p[0] & 15) + (p[0] > '9' ? 9 : 0)) << 4);
+ b = (uint8_t)(((p[1] & 15) + (p[1] > '9' ? 9 : 0)) << 0);
+ salt[salti++] = (uint8_t)(a | b);
+ p = &p[2];
+ }
+ } else if (!pepperi && !strncasecmp(p, "pepper=", 7U)) {
+ p = &p[7];
+ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
+ p = &p[2];
+ for (;;) {
+ if (isxdigit(p[0]) && isxdigit(p[1])) {
+ if (!pepperbytes)
+ goto einval;
+ pepperbytes--;
+ } else if (isxdigit(p[0])) {
+ goto einval;
+ } else if (pepperbytes) {
+ goto einval;
+ } else {
+ break;
+ }
+ a = (uint8_t)(((p[0] & 15) + (p[0] > '9' ? 9 : 0)) << 4);
+ b = (uint8_t)(((p[1] & 15) + (p[1] > '9' ? 9 : 0)) << 0);
+ pepper[pepperi++] = (uint8_t)(a | b);
+ p = &p[2];
+ }
+ } else if (!keyi && !strncasecmp(p, "key=", 4U)) {
+ p = &p[4];
+ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
+ p = &p[2];
+ while (isxdigit(p[keyi | 0]) && isxdigit(p[keyi | 1]))
+ keyi += 2U;
+ if (isxdigit(p[keyi]))
+ goto einval;
+ keyi /= 2U;
+ if (keyi) {
+ key = malloc(keyi);
+ if (!key)
+ goto fail;
+ }
+ for (i = 0; i < keyi; i++) {
+ a = (uint8_t)(((p[0] & 15) + (p[0] > '9' ? 9 : 0)) << 4);
+ b = (uint8_t)(((p[1] & 15) + (p[1] > '9' ? 9 : 0)) << 0);
+ key[i] = (uint8_t)(a | b);
+ p = &p[2];
+ }
+ } else if (*p == 'n' || *p == 'N') {
+ if (parse_value(&n, &p[1], &p))
+ goto einval;
+ } else {
+ goto einval;
+ }
+
+ if (*p == ',') {
+ p++;
+ goto next;
+ }
+
+ if (*p++ != ']' || *p)
+ goto einval;
+
+ r = initfunc(this, n, salti ? salt : NULL, pepperi ? pepper : NULL, key, keyi);
+ free(key);
+ return r;
einval:
errno = EINVAL;
+fail:
+ free(key);
return -1;
}
@@ -207,6 +311,8 @@ libhashsum_init_hasher_from_string(struct libhashsum_hasher *this, const char *a
case LIBHASHSUM_BLAKE256: return with_salt(&libhashsum_init_blake256_hasher, this, algorithm, 16U);
case LIBHASHSUM_BLAKE384: return with_salt(&libhashsum_init_blake384_hasher, this, algorithm, 32U);
case LIBHASHSUM_BLAKE512: return with_salt(&libhashsum_init_blake512_hasher, this, algorithm, 32U);
+ case LIBHASHSUM_BLAKE2S: return blake2(&libhashsum_init_blake2s_hasher, this, algorithm, 8U, 8U);
+ case LIBHASHSUM_BLAKE2B: return blake2(&libhashsum_init_blake2b_hasher, this, algorithm, 16U, 16U);
default:
abort();
}
diff --git a/misc-tests.c b/misc-tests.c
index 4eca0a6..7a5c546 100644
--- a/misc-tests.c
+++ b/misc-tests.c
@@ -53,6 +53,26 @@ eq(struct libhashsum_hasher *a, struct libhashsum_hasher *b)
if (memcmp(&a->state, &b->state, sizeof(a->state)))
return 0;
break;
+ case LIBHASHSUM_BLAKE2S:
+#ifdef LIBHASHSUM_INCLUDE_LIBBLAKE_STATE
+ if (memcmp(&a->state.blake2s.s, &b->state.blake2s.s, sizeof(a->state.blake2s.s)))
+ return 0;
+ if (a->state.blake2s.keybytes != b->state.blake2s.keybytes)
+ return 0;
+ if (a->state.blake2s.keybytes && memcmp(a->state.blake2s.buf, b->state.blake2s.buf, sizeof(a->state.blake2s.buf)))
+ return 0;
+#endif
+ break;
+ case LIBHASHSUM_BLAKE2B:
+#ifdef LIBHASHSUM_INCLUDE_LIBBLAKE_STATE
+ if (memcmp(&a->state.blake2b.s, &b->state.blake2b.s, sizeof(a->state.blake2b.s)))
+ return 0;
+ if (a->state.blake2b.keybytes != b->state.blake2b.keybytes)
+ return 0;
+ if (a->state.blake2b.keybytes && memcmp(a->state.blake2b.buf, b->state.blake2b.buf, sizeof(a->state.blake2b.buf)))
+ return 0;
+#endif
+ break;
case LIBHASHSUM_KECCAK:
case LIBHASHSUM_KECCAK_224:
case LIBHASHSUM_KECCAK_256:
@@ -86,8 +106,8 @@ eq(struct libhashsum_hasher *a, struct libhashsum_hasher *b)
if (r)
return 0;
}
- break;
#endif
+ break;
default:
abort();
}
@@ -421,6 +441,10 @@ main(void)
ASSERT(libhashsum_get_algorithm_from_string(&algo, "B-256") == 0);
ASSERT(libhashsum_get_algorithm_from_string(&algo, "B-384") == 0);
ASSERT(libhashsum_get_algorithm_from_string(&algo, "B-512") == 0);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE-2s") == 1 && algo == LIBHASHSUM_BLAKE2S);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE-2b") == 1 && algo == LIBHASHSUM_BLAKE2B);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "B-2s") == 0);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "B-2b") == 0);
ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD128") == 1 && algo == LIBHASHSUM_RIPEMD_128);
ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD160") == 1 && algo == LIBHASHSUM_RIPEMD_160);
@@ -474,6 +498,10 @@ main(void)
ASSERT(libhashsum_get_algorithm_from_string(&algo, "B256") == 1 && algo == LIBHASHSUM_BLAKE256);
ASSERT(libhashsum_get_algorithm_from_string(&algo, "B384") == 1 && algo == LIBHASHSUM_BLAKE384);
ASSERT(libhashsum_get_algorithm_from_string(&algo, "B512") == 1 && algo == LIBHASHSUM_BLAKE512);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE2s") == 1 && algo == LIBHASHSUM_BLAKE2S);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE2b") == 1 && algo == LIBHASHSUM_BLAKE2B);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "B2s") == 1 && algo == LIBHASHSUM_BLAKE2S);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "B2b") == 1 && algo == LIBHASHSUM_BLAKE2B);
ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD-128[]") == 0);
ASSERT(libhashsum_get_algorithm_from_string(&algo, "RIPEMD-160[]") == 0);
@@ -527,6 +555,10 @@ main(void)
ASSERT(libhashsum_get_algorithm_from_string(&algo, "B256[]") == 1 && algo == LIBHASHSUM_BLAKE256);
ASSERT(libhashsum_get_algorithm_from_string(&algo, "B384[]") == 1 && algo == LIBHASHSUM_BLAKE384);
ASSERT(libhashsum_get_algorithm_from_string(&algo, "B512[]") == 1 && algo == LIBHASHSUM_BLAKE512);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE2s[]") == 1 && algo == LIBHASHSUM_BLAKE2S);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "BLAKE2b[]") == 1 && algo == LIBHASHSUM_BLAKE2B);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "B2s[]") == 1 && algo == LIBHASHSUM_BLAKE2S);
+ ASSERT(libhashsum_get_algorithm_from_string(&algo, "B2b[]") == 1 && algo == LIBHASHSUM_BLAKE2B);
#define CHECK(ALGO, CALL)\
do {\
@@ -634,6 +666,7 @@ main(void)
CHECK("BLAKE512[SaLt=0X0123456789abcDef0123456789abcdef0123456789abcdef0123456789abcdef]",
libhashsum_init_blake512_hasher(&hasher, SALT SALT));
CHECK("Keccak", libhashsum_init_keccak_hasher(&hasher, 0, 0, 0, 0));
+ CHECK("Keccak[]", libhashsum_init_keccak_hasher(&hasher, 0, 0, 0, 0));
CHECK("Keccak[r=256]", libhashsum_init_keccak_hasher(&hasher, 256, 0, 0, 0));
CHECK("Keccak[R=256]", libhashsum_init_keccak_hasher(&hasher, 256, 0, 0, 0));
CHECK("Keccak[c=256]", libhashsum_init_keccak_hasher(&hasher, 0, 256, 0, 0));
@@ -644,11 +677,50 @@ main(void)
CHECK("Keccak[Z=256]", libhashsum_init_keccak_hasher(&hasher, 0, 0, 0, 256));
CHECK("Keccak[r=1200,c=400,n=100,z=60]", libhashsum_init_keccak_hasher(&hasher, 1200, 400, 100, 60));
CHECK("Keccak[z=60,r=1200,c=400,n=100]", libhashsum_init_keccak_hasher(&hasher, 1200, 400, 100, 60));
+ CHECK("BLAKE2s", libhashsum_init_blake2s_hasher(&hasher, 0, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2s[]", libhashsum_init_blake2s_hasher(&hasher, 0, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2s[n=128]", libhashsum_init_blake2s_hasher(&hasher, 128, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2s[Salt=0000000000000000]", libhashsum_init_blake2s_hasher(&hasher, 0, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2s[pePPer=0000000000000000]", libhashsum_init_blake2s_hasher(&hasher, 0, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2s[key=]", libhashsum_init_blake2s_hasher(&hasher, 0, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2s[salt=0123456789abcDEF]", libhashsum_init_blake2s_hasher(&hasher, 0, SALT, NULL, NULL, 0));
+ CHECK("BLAKE2s[pepper=0123456789abcDEF]", libhashsum_init_blake2s_hasher(&hasher, 0, NULL, SALT, NULL, 0));
+ CHECK("BLAKE2s[key=0123456789abcDEF]", libhashsum_init_blake2s_hasher(&hasher, 0, NULL, NULL, SALT, 8));
+ CHECK("BLAKE2s[KEY=0123456789abcdef0123456789ABCDEF]", libhashsum_init_blake2s_hasher(&hasher, 0, NULL, NULL, SALT, 16));
+ CHECK("BLAKE2s[key=0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF]",
+ libhashsum_init_blake2s_hasher(&hasher, 0, NULL, NULL, SALT SALT, 32));
+ CHECK("BLAKE2b", libhashsum_init_blake2b_hasher(&hasher, 0, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2b[]", libhashsum_init_blake2b_hasher(&hasher, 0, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2b[n=64]", libhashsum_init_blake2b_hasher(&hasher, 64, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2b[N=128]", libhashsum_init_blake2b_hasher(&hasher, 128, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2b[salt=0123456789abcDEF0123456789abcDEF]",
+ libhashsum_init_blake2b_hasher(&hasher, 0, SALT, NULL, NULL, 0));
+ CHECK("BLAKE2b[pepper=0123456789abcDEF0123456789abcDEF]",
+ libhashsum_init_blake2b_hasher(&hasher, 0, NULL, SALT, NULL, 0));
+ CHECK("BLAKE2b[key=0123456789abcDEF]", libhashsum_init_blake2b_hasher(&hasher, 0, NULL, NULL, SALT, 8));
+ CHECK("BLAKE2b[salt=00000000000000000000000000000000]",
+ libhashsum_init_blake2b_hasher(&hasher, 0, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2b[pepper=00000000000000000000000000000000]",
+ libhashsum_init_blake2b_hasher(&hasher, 0, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2b[key=]", libhashsum_init_blake2b_hasher(&hasher, 0, NULL, NULL, NULL, 0));
+ CHECK("BLAKE2b[key=0123456789abcdef0123456789ABCDEF]", libhashsum_init_blake2b_hasher(&hasher, 0, NULL, NULL, SALT, 16));
+ CHECK("BLAKE2b[key=0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF]",
+ libhashsum_init_blake2b_hasher(&hasher, 0, NULL, NULL, SALT SALT, 32));
+ CHECK("BLAKE2b[key=0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF"
+ "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF]",
+ libhashsum_init_blake2b_hasher(&hasher, 0, NULL, NULL, SALT SALT, 64));
#undef CHECK
#undef SALT
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[]sum") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[]sum") == -1 && errno == EINVAL);
ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[salt=]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[salt=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz") == -1);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[salt=00zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz") == -1);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[salt=000zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz") == -1);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[salt=00z0zzzzzzzzzzzzzzzzzzzzzzzzzzzzz") == -1);
+ ASSERT(errno == EINVAL);
ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[salt=00000000]") == -1 && errno == EINVAL);
ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE256[salt=1234567890abcdef1234567890abcdef"
"1234567890abcdef1234567890abcdef]"));
@@ -658,6 +730,7 @@ main(void)
ASSERT(libhashsum_init_hasher_from_string(&hasher, "SHAKE128[n=0]") == -1 && errno == EINVAL);
ASSERT(libhashsum_init_hasher_from_string(&hasher, "SHAKE128[n=1000,]") == -1 && errno == EINVAL);
ASSERT(libhashsum_init_hasher_from_string(&hasher, "SHAKE128[,n=1000]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "shake128[]sum") == -1 && errno == EINVAL);
ASSERT(libhashsum_init_hasher_from_string(&hasher, "") == -1 && errno == EINVAL);
ASSERT(libhashsum_init_hasher_from_string(&hasher, "X") == -1 && errno == EINVAL);
ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[") == -1 && errno == EINVAL);
@@ -667,6 +740,46 @@ main(void)
ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[c=0]") == -1 && errno == EINVAL);
ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[n=0]") == -1 && errno == EINVAL);
ASSERT(libhashsum_init_hasher_from_string(&hasher, "Keccak[z=0]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2s[n=0]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[n=0]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2s[salt=00000000000000]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[salt=000000000000000000000000000000]") == -1);
+ ASSERT(errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2s[salt=000000000000000000]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[salt=0000000000000000000000000000000000]") == -1);
+ ASSERT(errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2s[pepper=00000000000000]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[pepper=000000000000000000000000000000]") == -1);
+ ASSERT(errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2s[pepper=000000000000000000]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[pepper=0000000000000000000000000000000000]") == -1);
+ ASSERT(errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2s[salt=zzzzzzzzzzzzzzzz]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[salt=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz]") == -1);
+ ASSERT(errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2s[salt=00zzzzzzzzzzzzzz]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[salt=00zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz]") == -1);
+ ASSERT(errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2s[salt=000zzzzzzzzzzzzz]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[salt=000zzzzzzzzzzzzzzzzzzzzzzzzzzzzz]") == -1);
+ ASSERT(errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2s[salt=00z0zzzzzzzzzzzz]") == -1 && errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[salt=00z0zzzzzzzzzzzzzzzzzzzzzzzzzzzz]") == -1);
+ ASSERT(errno == EINVAL);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2s[key=00000000000000000000000000000000"
+ "0000000000000000000000000000000000"
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000]") == -1);
+ ASSERT(errno == EINVAL || errno == ENOSYS);
+ ASSERT(libhashsum_init_hasher_from_string(&hasher, "BLAKE2b[key=00000000000000000000000000000000"
+ "0000000000000000000000000000000000"
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000"
+ "00000000000000000000000000000000]") == -1);
+ ASSERT(errno == EINVAL || errno == ENOSYS);
return 0;
}
diff --git a/mk/after-config.mk b/mk/after-config.mk
index 7afa950..209a6b2 100644
--- a/mk/after-config.mk
+++ b/mk/after-config.mk
@@ -21,6 +21,8 @@ include mk/blake224=$(SUPPORT_BLAKE224).mk
include mk/blake256=$(SUPPORT_BLAKE256).mk
include mk/blake384=$(SUPPORT_BLAKE384).mk
include mk/blake512=$(SUPPORT_BLAKE512).mk
+include mk/blake2s=$(SUPPORT_BLAKE2S).mk
+include mk/blake2b=$(SUPPORT_BLAKE2B).mk
CPPFLAGS_FULL =\
@@ -43,7 +45,9 @@ CPPFLAGS_FULL =\
$(CPPFLAGS_BLAKE224)\
$(CPPFLAGS_BLAKE256)\
$(CPPFLAGS_BLAKE384)\
- $(CPPFLAGS_BLAKE512)
+ $(CPPFLAGS_BLAKE512)\
+ $(CPPFLAGS_BLAKE2S)\
+ $(CPPFLAGS_BLAKE2B)
LDFLAGS_FULL =\
$(LDFLAGS)\
diff --git a/mk/before-config.mk b/mk/before-config.mk
index c77dd47..0e16b94 100644
--- a/mk/before-config.mk
+++ b/mk/before-config.mk
@@ -19,3 +19,5 @@ SUPPORT_BLAKE224 = $(DEFAULT_SUPPORT)
SUPPORT_BLAKE256 = $(DEFAULT_SUPPORT)
SUPPORT_BLAKE384 = $(DEFAULT_SUPPORT)
SUPPORT_BLAKE512 = $(DEFAULT_SUPPORT)
+SUPPORT_BLAKE2S = $(DEFAULT_SUPPORT)
+SUPPORT_BLAKE2B = $(DEFAULT_SUPPORT)
diff --git a/mk/blake2b=no.mk b/mk/blake2b=no.mk
new file mode 120000
index 0000000..54299a4
--- /dev/null
+++ b/mk/blake2b=no.mk
@@ -0,0 +1 @@
+no \ No newline at end of file
diff --git a/mk/blake2b=yes.mk b/mk/blake2b=yes.mk
new file mode 100644
index 0000000..0790c78
--- /dev/null
+++ b/mk/blake2b=yes.mk
@@ -0,0 +1,4 @@
+CPPFLAGS_BLAKE2B = -DSUPPORT_BLAKE2B
+
+CPPFLAGS_LIBBLAKE_IF_SUPPORTED = $(CPPFLAGS_LIBBLAKE)
+LDFLAGS_LIBBLAKE_IF_SUPPORTED = $(LDFLAGS_LIBBLAKE)
diff --git a/mk/blake2s=no.mk b/mk/blake2s=no.mk
new file mode 120000
index 0000000..54299a4
--- /dev/null
+++ b/mk/blake2s=no.mk
@@ -0,0 +1 @@
+no \ No newline at end of file
diff --git a/mk/blake2s=yes.mk b/mk/blake2s=yes.mk
new file mode 100644
index 0000000..caeed5f
--- /dev/null
+++ b/mk/blake2s=yes.mk
@@ -0,0 +1,4 @@
+CPPFLAGS_BLAKE2S = -DSUPPORT_BLAKE2S
+
+CPPFLAGS_LIBBLAKE_IF_SUPPORTED = $(CPPFLAGS_LIBBLAKE)
+LDFLAGS_LIBBLAKE_IF_SUPPORTED = $(LDFLAGS_LIBBLAKE)