diff options
-rw-r--r-- | libhashsum.h | 44 | ||||
-rw-r--r-- | libhashsum_init_blake224_hasher.c | 32 | ||||
-rw-r--r-- | libhashsum_init_blake256_hasher.c | 32 | ||||
-rw-r--r-- | libhashsum_init_blake384_hasher.c | 32 | ||||
-rw-r--r-- | libhashsum_init_blake512_hasher.c | 32 | ||||
-rw-r--r-- | libhashsum_init_blake_hasher.c | 25 | ||||
-rw-r--r-- | libhashsum_init_blakeb_hasher.c | 9 | ||||
-rw-r--r-- | libhashsum_init_blakes_hasher.c | 9 | ||||
-rw-r--r-- | libhashsum_init_hasher.c | 8 | ||||
-rw-r--r-- | libhashsum_init_hasher_from_string.c | 73 |
10 files changed, 239 insertions, 57 deletions
diff --git a/libhashsum.h b/libhashsum.h index d85dadd..00fbb17 100644 --- a/libhashsum.h +++ b/libhashsum.h @@ -424,22 +424,26 @@ union libhashsum_state { struct { struct libblake_blake224_state s; uint8_t buf[128]; - } blake224; /* size = 184 */ + char algostr[49]; + } blake224; /* size = 233 */ struct { struct libblake_blake256_state s; uint8_t buf[128]; - } blake256; /* size = 184 */ + char algostr[49]; + } blake256; /* size = 233 */ struct { struct libblake_blake384_state s; uint8_t buf[256]; - } blake384; /* size = 368 */ + char algostr[81]; + } blake384; /* size = 449 */ struct { struct libblake_blake512_state s; uint8_t buf[256]; - } blake512; /* size = 368 */ + char algostr[81]; + } blake512; /* size = 449 */ #endif /* libblake: 48(2s), 96(2b), 144(2Xs), 276(2Xb) */ @@ -1180,6 +1184,7 @@ int libhashsum_init_rawshake_hasher(struct libhashsum_hasher *this, size_t hcapb * hashing and return hash functions and details * * @param this The output parameter for the functions, details, and state + * @param salt `NULL` (for all zeroes) or a 16-byte salt * @return 0 on success, -1 on failure * * @throws ENOSYS Support was excluded at compile time @@ -1187,13 +1192,14 @@ int libhashsum_init_rawshake_hasher(struct libhashsum_hasher *this, size_t hcapb * @since 1.0 */ LIBHASHSUM_1_NONNULL_ -int libhashsum_init_blake224_hasher(struct libhashsum_hasher *this); +int libhashsum_init_blake224_hasher(struct libhashsum_hasher *this, const void *salt); /** * Create an initialised state for BLAKE256 (BLAKE, BLAKEs) * hashing and return hash functions and details * * @param this The output parameter for the functions, details, and state + * @param salt `NULL` (for all zeroes) or a 16-byte salt * @return 0 on success, -1 on failure * * @throws ENOSYS Support was excluded at compile time @@ -1201,7 +1207,7 @@ int libhashsum_init_blake224_hasher(struct libhashsum_hasher *this); * @since 1.0 */ LIBHASHSUM_1_NONNULL_ -int libhashsum_init_blake256_hasher(struct libhashsum_hasher *this); +int libhashsum_init_blake256_hasher(struct libhashsum_hasher *this, const void *salt); /** * Create an initialised state for BLAKEs (BLAKE) @@ -1209,6 +1215,7 @@ int libhashsum_init_blake256_hasher(struct libhashsum_hasher *this); * * @param this The output parameter for the functions, details, and state * @param hashbits Hash output size in bits + * @param salt `NULL` (for all zeroes) or a 16-byte salt * @return 0 on success, -1 on failure * * @throws EINVAL `hashbits` is invalid (neither 224 nor 256) @@ -1217,13 +1224,14 @@ int libhashsum_init_blake256_hasher(struct libhashsum_hasher *this); * @since 1.0 */ LIBHASHSUM_1_NONNULL_ -int libhashsum_init_blakes_hasher(struct libhashsum_hasher *this, size_t hashbits); +int libhashsum_init_blakes_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt); /** * Create an initialised state for BLAKE384 (BLAKE, BLAKEb) * hashing and return hash functions and details * * @param this The output parameter for the functions, details, and state + * @param salt `NULL` (for all zeroes) or a 32-byte salt * @return 0 on success, -1 on failure * * @throws ENOSYS Support was excluded at compile time @@ -1231,13 +1239,14 @@ int libhashsum_init_blakes_hasher(struct libhashsum_hasher *this, size_t hashbit * @since 1.0 */ LIBHASHSUM_1_NONNULL_ -int libhashsum_init_blake384_hasher(struct libhashsum_hasher *this); +int libhashsum_init_blake384_hasher(struct libhashsum_hasher *this, const void *salt); /** * Create an initialised state for BLAKE512 (BLAKE, BLAKEb) * hashing and return hash functions and details * * @param this The output parameter for the functions, details, and state + * @param salt `NULL` (for all zeroes) or a 32-byte salt * @return 0 on success, -1 on failure * * @throws ENOSYS Support was excluded at compile time @@ -1245,7 +1254,7 @@ int libhashsum_init_blake384_hasher(struct libhashsum_hasher *this); * @since 1.0 */ LIBHASHSUM_1_NONNULL_ -int libhashsum_init_blake512_hasher(struct libhashsum_hasher *this); +int libhashsum_init_blake512_hasher(struct libhashsum_hasher *this, const void *salt); /** * Create an initialised state for BLAKEb (BLAKE) @@ -1253,6 +1262,7 @@ int libhashsum_init_blake512_hasher(struct libhashsum_hasher *this); * * @param this The output parameter for the functions, details, and state * @param hashbits Hash output size in bits + * @param salt `NULL` (for all zeroes) or a 32-byte salt * @return 0 on success, -1 on failure * * @throws EINVAL `hashbits` is invalid (neither 384 nor 512) @@ -1261,23 +1271,29 @@ int libhashsum_init_blake512_hasher(struct libhashsum_hasher *this); * @since 1.0 */ LIBHASHSUM_1_NONNULL_ -int libhashsum_init_blakeb_hasher(struct libhashsum_hasher *this, size_t hashbits); +int libhashsum_init_blakeb_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt); /** * Create an initialised state for BLAKE * 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 + * @param this The output parameter for the functions, details, and state + * @param hashbits Hash output size in bits + * @param salt `NULL` (for all zeroes) or a salt + * @parma saltbytes The number of bytes in `salt` (ignored if `salt` is `NULL`), + * shall be 16 for if `hashbits` is 224 or 256, and 32 if + * `hashbits` is 384 or 512 + * @return 0 on success, -1 on failure * * @throws EINVAL `hashbits` is invalid (neither 224, 256, 384, nor 512) + * @throws EINVAL `salt` is not `NULL` but `saltbytes` does not match + * the expected value for the input `hashbits` * @throws ENOSYS Support was excluded at compile time * * @since 1.0 */ LIBHASHSUM_1_NONNULL_ -int libhashsum_init_blake_hasher(struct libhashsum_hasher *this, size_t hashbits); +int libhashsum_init_blake_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt, size_t saltbytes); #endif diff --git a/libhashsum_init_blake224_hasher.c b/libhashsum_init_blake224_hasher.c index 65d0ee1..642af8d 100644 --- a/libhashsum_init_blake224_hasher.c +++ b/libhashsum_init_blake224_hasher.c @@ -68,12 +68,35 @@ finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extr } +static const char * +mkalgostr(char *buf, const char *name, const uint8_t *salt) +{ + char *p; + size_t i; + if (!salt) + return name; + for (i = 0; i < 16U; i++) + if (salt[i]) + goto nonzero; + return name; +nonzero: + p = stpcpy(stpcpy(buf, name), "[salt="); + for (i = 0; i < 16U; i++) { + *p++ = "0123456789abcdef"[(salt[i] >> 4) & 15]; + *p++ = "0123456789abcdef"[(salt[i] >> 0) & 15]; + } + *p++ = ']'; + *p++ = '\0'; + return buf; +} + + int -libhashsum_init_blake224_hasher(struct libhashsum_hasher *this) +libhashsum_init_blake224_hasher(struct libhashsum_hasher *this, const void *salt) { libblake_init(); this->algorithm = LIBHASHSUM_BLAKE224; - this->algorithm_string = "BLAKE224"; + this->algorithm_string = mkalgostr(this->state.blake224.algostr, "BLAKE224", salt); this->input_block_size = 64U; this->hash_size = LIBHASHSUM_BLAKE224_HASH_SIZE; this->hash_output = NULL; @@ -82,16 +105,17 @@ libhashsum_init_blake224_hasher(struct libhashsum_hasher *this) this->finalise_const = &finalise_const; this->finalise = &finalise; this->destroy = NULL; - libblake_blake224_init2(&this->state.blake224.s, NULL); + libblake_blake224_init2(&this->state.blake224.s, salt); return 0; } #else int -libhashsum_init_blake224_hasher(struct libhashsum_hasher *this) +libhashsum_init_blake224_hasher(struct libhashsum_hasher *this, const void *salt) { (void) this; + (void) salt; errno = ENOSYS; return -1; } diff --git a/libhashsum_init_blake256_hasher.c b/libhashsum_init_blake256_hasher.c index 202dc37..fd77878 100644 --- a/libhashsum_init_blake256_hasher.c +++ b/libhashsum_init_blake256_hasher.c @@ -68,12 +68,35 @@ finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extr } +static const char * +mkalgostr(char *buf, const char *name, const uint8_t *salt) +{ + char *p; + size_t i; + if (!salt) + return name; + for (i = 0; i < 16U; i++) + if (salt[i]) + goto nonzero; + return name; +nonzero: + p = stpcpy(stpcpy(buf, name), "[salt="); + for (i = 0; i < 16U; i++) { + *p++ = "0123456789abcdef"[(salt[i] >> 4) & 15]; + *p++ = "0123456789abcdef"[(salt[i] >> 0) & 15]; + } + *p++ = ']'; + *p++ = '\0'; + return buf; +} + + int -libhashsum_init_blake256_hasher(struct libhashsum_hasher *this) +libhashsum_init_blake256_hasher(struct libhashsum_hasher *this, const void *salt) { libblake_init(); this->algorithm = LIBHASHSUM_BLAKE256; - this->algorithm_string = "BLAKE256"; + this->algorithm_string = mkalgostr(this->state.blake224.algostr, "BLAKE256", salt); this->input_block_size = 64U; this->hash_size = LIBHASHSUM_BLAKE256_HASH_SIZE; this->hash_output = NULL; @@ -82,16 +105,17 @@ libhashsum_init_blake256_hasher(struct libhashsum_hasher *this) this->finalise_const = &finalise_const; this->finalise = &finalise; this->destroy = NULL; - libblake_blake256_init2(&this->state.blake256.s, NULL); + libblake_blake256_init2(&this->state.blake256.s, salt); return 0; } #else int -libhashsum_init_blake256_hasher(struct libhashsum_hasher *this) +libhashsum_init_blake256_hasher(struct libhashsum_hasher *this, const void *salt) { (void) this; + (void) salt; errno = ENOSYS; return -1; } diff --git a/libhashsum_init_blake384_hasher.c b/libhashsum_init_blake384_hasher.c index 6f92c6c..cd6457f 100644 --- a/libhashsum_init_blake384_hasher.c +++ b/libhashsum_init_blake384_hasher.c @@ -68,12 +68,35 @@ finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extr } +static const char * +mkalgostr(char *buf, const char *name, const uint8_t *salt) +{ + char *p; + size_t i; + if (!salt) + return name; + for (i = 0; i < 32U; i++) + if (salt[i]) + goto nonzero; + return name; +nonzero: + p = stpcpy(stpcpy(buf, name), "[salt="); + for (i = 0; i < 32U; i++) { + *p++ = "0123456789abcdef"[(salt[i] >> 4) & 15]; + *p++ = "0123456789abcdef"[(salt[i] >> 0) & 15]; + } + *p++ = ']'; + *p++ = '\0'; + return buf; +} + + int -libhashsum_init_blake384_hasher(struct libhashsum_hasher *this) +libhashsum_init_blake384_hasher(struct libhashsum_hasher *this, const void *salt) { libblake_init(); this->algorithm = LIBHASHSUM_BLAKE384; - this->algorithm_string = "BLAKE384"; + this->algorithm_string = mkalgostr(this->state.blake224.algostr, "BLAKE384", salt); this->input_block_size = 128U; this->hash_size = LIBHASHSUM_BLAKE384_HASH_SIZE; this->hash_output = NULL; @@ -82,16 +105,17 @@ libhashsum_init_blake384_hasher(struct libhashsum_hasher *this) this->finalise_const = &finalise_const; this->finalise = &finalise; this->destroy = NULL; - libblake_blake384_init2(&this->state.blake384.s, NULL); + libblake_blake384_init2(&this->state.blake384.s, salt); return 0; } #else int -libhashsum_init_blake384_hasher(struct libhashsum_hasher *this) +libhashsum_init_blake384_hasher(struct libhashsum_hasher *this, const void *salt) { (void) this; + (void) salt; errno = ENOSYS; return -1; } diff --git a/libhashsum_init_blake512_hasher.c b/libhashsum_init_blake512_hasher.c index b1d2c13..d174fdd 100644 --- a/libhashsum_init_blake512_hasher.c +++ b/libhashsum_init_blake512_hasher.c @@ -68,12 +68,35 @@ finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extr } +static const char * +mkalgostr(char *buf, const char *name, const uint8_t *salt) +{ + char *p; + size_t i; + if (!salt) + return name; + for (i = 0; i < 32U; i++) + if (salt[i]) + goto nonzero; + return name; +nonzero: + p = stpcpy(stpcpy(buf, name), "[salt="); + for (i = 0; i < 32U; i++) { + *p++ = "0123456789abcdef"[(salt[i] >> 4) & 15]; + *p++ = "0123456789abcdef"[(salt[i] >> 0) & 15]; + } + *p++ = ']'; + *p++ = '\0'; + return buf; +} + + int -libhashsum_init_blake512_hasher(struct libhashsum_hasher *this) +libhashsum_init_blake512_hasher(struct libhashsum_hasher *this, const void *salt) { libblake_init(); this->algorithm = LIBHASHSUM_BLAKE512; - this->algorithm_string = "BLAKE512"; + this->algorithm_string = mkalgostr(this->state.blake224.algostr, "BLAKE512", salt); this->input_block_size = 128U; this->hash_size = LIBHASHSUM_BLAKE512_HASH_SIZE; this->hash_output = NULL; @@ -82,16 +105,17 @@ libhashsum_init_blake512_hasher(struct libhashsum_hasher *this) this->finalise_const = &finalise_const; this->finalise = &finalise; this->destroy = NULL; - libblake_blake512_init2(&this->state.blake512.s, NULL); + libblake_blake512_init2(&this->state.blake512.s, salt); return 0; } #else int -libhashsum_init_blake512_hasher(struct libhashsum_hasher *this) +libhashsum_init_blake512_hasher(struct libhashsum_hasher *this, const void *salt) { (void) this; + (void) salt; errno = ENOSYS; return -1; } diff --git a/libhashsum_init_blake_hasher.c b/libhashsum_init_blake_hasher.c index 645ab95..7b6d78e 100644 --- a/libhashsum_init_blake_hasher.c +++ b/libhashsum_init_blake_hasher.c @@ -4,17 +4,28 @@ int -libhashsum_init_blake_hasher(struct libhashsum_hasher *this, size_t hashbits) +libhashsum_init_blake_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt, size_t salybytes) { + if (salt) { + if (hashbits == 224U || hashbits == 256U) { + if (salybytes != 16U) + goto einval; + } else if (hashbits == 384U || hashbits == 512U) { + if (salybytes != 32U) + goto einval; + } + } + if (hashbits == 224U) - return libhashsum_init_blake224_hasher(this); + return libhashsum_init_blake224_hasher(this, salt); if (hashbits == 256U) - return libhashsum_init_blake256_hasher(this); + return libhashsum_init_blake256_hasher(this, salt); if (hashbits == 384U) - return libhashsum_init_blake384_hasher(this); + return libhashsum_init_blake384_hasher(this, salt); if (hashbits == 512U) - return libhashsum_init_blake512_hasher(this); + return libhashsum_init_blake512_hasher(this, salt); +einval: errno = EINVAL; return -1; } @@ -22,10 +33,12 @@ libhashsum_init_blake_hasher(struct libhashsum_hasher *this, size_t hashbits) #else int -libhashsum_init_blake_hasher(struct libhashsum_hasher *this, size_t hashbits) +libhashsum_init_blake_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt, size_t salybytes) { (void) this; (void) hashbits; + (void) salt; + (void) saltbytes; errno = ENOSYS; return -1; } diff --git a/libhashsum_init_blakeb_hasher.c b/libhashsum_init_blakeb_hasher.c index 417553b..42cdb16 100644 --- a/libhashsum_init_blakeb_hasher.c +++ b/libhashsum_init_blakeb_hasher.c @@ -4,12 +4,12 @@ int -libhashsum_init_blakeb_hasher(struct libhashsum_hasher *this, size_t hashbits) +libhashsum_init_blakeb_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt) { if (hashbits == 384U) - return libhashsum_init_blake384_hasher(this); + return libhashsum_init_blake384_hasher(this, salt); if (hashbits == 512U) - return libhashsum_init_blake512_hasher(this); + return libhashsum_init_blake512_hasher(this, salt); errno = EINVAL; return -1; @@ -18,10 +18,11 @@ libhashsum_init_blakeb_hasher(struct libhashsum_hasher *this, size_t hashbits) #else int -libhashsum_init_blakeb_hasher(struct libhashsum_hasher *this, size_t hashbits) +libhashsum_init_blakeb_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt) { (void) this; (void) hashbits; + (void) salt; errno = ENOSYS; return -1; } diff --git a/libhashsum_init_blakes_hasher.c b/libhashsum_init_blakes_hasher.c index f5e7c20..32bf9a3 100644 --- a/libhashsum_init_blakes_hasher.c +++ b/libhashsum_init_blakes_hasher.c @@ -4,12 +4,12 @@ int -libhashsum_init_blakes_hasher(struct libhashsum_hasher *this, size_t hashbits) +libhashsum_init_blakes_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt) { if (hashbits == 224U) - return libhashsum_init_blake224_hasher(this); + return libhashsum_init_blake224_hasher(this, salt); if (hashbits == 256U) - return libhashsum_init_blake256_hasher(this); + return libhashsum_init_blake256_hasher(this, salt); errno = EINVAL; return -1; @@ -18,10 +18,11 @@ libhashsum_init_blakes_hasher(struct libhashsum_hasher *this, size_t hashbits) #else int -libhashsum_init_blakes_hasher(struct libhashsum_hasher *this, size_t hashbits) +libhashsum_init_blakes_hasher(struct libhashsum_hasher *this, size_t hashbits, const void *salt) { (void) this; (void) hashbits; + (void) salt; errno = ENOSYS; return -1; } diff --git a/libhashsum_init_hasher.c b/libhashsum_init_hasher.c index ab44ac1..6f09629 100644 --- a/libhashsum_init_hasher.c +++ b/libhashsum_init_hasher.c @@ -65,13 +65,13 @@ libhashsum_init_hasher(struct libhashsum_hasher *this, enum libhashsum_algorithm case LIBHASHSUM_RAWSHAKE512: return libhashsum_init_rawshake512_hasher(this, 0); case LIBHASHSUM_BLAKE224: - return libhashsum_init_blake224_hasher(this); + return libhashsum_init_blake224_hasher(this, NULL); case LIBHASHSUM_BLAKE256: - return libhashsum_init_blake256_hasher(this); + return libhashsum_init_blake256_hasher(this, NULL); case LIBHASHSUM_BLAKE384: - return libhashsum_init_blake384_hasher(this); + return libhashsum_init_blake384_hasher(this, NULL); case LIBHASHSUM_BLAKE512: - return libhashsum_init_blake512_hasher(this); + return libhashsum_init_blake512_hasher(this, NULL); default: case LIBHASHSUM_KECCAK: errno = EINVAL; diff --git a/libhashsum_init_hasher_from_string.c b/libhashsum_init_hasher_from_string.c index 9a53864..1bdc70d 100644 --- a/libhashsum_init_hasher_from_string.c +++ b/libhashsum_init_hasher_from_string.c @@ -32,7 +32,7 @@ with_n(int (*initfunc)(struct libhashsum_hasher *, size_t), struct libhashsum_ha if (!p || *++p == ']') return initfunc(this, 0); - if ((*p++ != 'n' && *p++ != 'N')) + if (*p++ != 'n' && *p++ != 'N') goto einval; if (*p++ != '=' || !('1' <= *p && *p <= '9')) goto einval; @@ -117,6 +117,61 @@ einval: } +static int +with_salt(int (*initfunc)(struct libhashsum_hasher *, const void *), + struct libhashsum_hasher *this, const char *algorithm, size_t saltbytes) +{ + const char *p; + uint8_t a, b, salt[32]; + size_t salti = 0; + + p = strchr(algorithm, '['); + if (!p || *++p == ']') + return initfunc(this, NULL); + + if (*p++ != 's' && *p++ != 'S') + goto einval; + if (*p++ != 'a' && *p++ != 'A') + goto einval; + if (*p++ != 'l' && *p++ != 'L') + goto einval; + if (*p++ != 't' && *p++ != 'T') + goto einval; + if (*p++ != '=') + goto einval; + + 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 & 15) + (*p > '9' ? 9 : 0)) << 4); + b = (uint8_t)(((*p & 15) + (*p > '9' ? 9 : 0)) << 0); + salt[salti++] = (uint8_t)(a | b); + } + + if (*p++ != ']' || *p) + goto einval; + + return initfunc(this, salt); + +einval: + errno = EINVAL; + return -1; +} + + int libhashsum_init_hasher_from_string(struct libhashsum_hasher *this, const char *algorithm) { @@ -180,14 +235,14 @@ libhashsum_init_hasher_from_string(struct libhashsum_hasher *this, const char *a return with_n(&libhashsum_init_rawshake512_hasher, this, algorithm); if (equiv(algorithm, "Keccak[")) return with_rcn(&libhashsum_init_keccak_hasher, this, algorithm); - if (equiv(algorithm, "BLAKE-224")) - return libhashsum_init_blake224_hasher(this); - if (equiv(algorithm, "BLAKE-256")) - return libhashsum_init_blake256_hasher(this); - if (equiv(algorithm, "BLAKE-384")) - return libhashsum_init_blake384_hasher(this); - if (equiv(algorithm, "BLAKE-512")) - return libhashsum_init_blake512_hasher(this); + if (equiv(algorithm, "BLAKE-224[")) + return with_salt(&libhashsum_init_blake224_hasher, this, algorithm, 16U); + if (equiv(algorithm, "BLAKE-256[")) + return with_salt(&libhashsum_init_blake256_hasher, this, algorithm, 16U); + if (equiv(algorithm, "BLAKE-384[")) + return with_salt(&libhashsum_init_blake384_hasher, this, algorithm, 32U); + if (equiv(algorithm, "BLAKE-512[")) + return with_salt(&libhashsum_init_blake512_hasher, this, algorithm, 32U); errno = EINVAL; return -1; |