diff options
Diffstat (limited to '')
| -rw-r--r-- | common.h | 4 | ||||
| -rw-r--r-- | libhashsum.h | 11 | ||||
| -rw-r--r-- | libhashsum_init_hasher_from_string.c | 20 | ||||
| -rw-r--r-- | libhashsum_init_keccak__.c | 25 | ||||
| -rw-r--r-- | libhashsum_init_keccak_hasher.c | 20 | ||||
| -rw-r--r-- | libhashsum_init_rawshake_hasher.c | 2 | ||||
| -rw-r--r-- | libhashsum_init_sha3_hasher.c | 2 | ||||
| -rw-r--r-- | libhashsum_init_shake_hasher.c | 2 | 
8 files changed, 57 insertions, 29 deletions
| @@ -44,10 +44,10 @@ __attribute__((__const__))  uint8_t libhashsum_reverse_byte__(uint8_t);  #ifdef LIBHASHSUM_INCLUDE_LIBKECCAK_STATE -int libhashsum_init_keccak__(struct libhashsum_hasher *this, size_t hashbits, void *spec, const char *suffix); +int libhashsum_init_keccak__(struct libhashsum_hasher *this, size_t hashbits, void *spec, size_t squeezes, const char *suffix);  #endif -#define KECCAKN(N) 1600 - 2 * (N), 2 * (N), (N) +#define KECCAKN(N) 1600 - 2 * (N), 2 * (N), (N), 1  #ifdef TEST diff --git a/libhashsum.h b/libhashsum.h index 29a8f6f..65c3a66 100644 --- a/libhashsum.h +++ b/libhashsum.h @@ -37,8 +37,8 @@   */  enum libhashsum_algorithm {  	/* since 1.0 */ -	LIBHASHSUM_MD2,          /**< MD2 */ -	LIBHASHSUM_MD4,          /**< MD4 */ +	LIBHASHSUM_MD2,          /**< MD2; this algorithm has been theoretically compromised */ +	LIBHASHSUM_MD4,          /**< MD4; this algorithm has been compromised */  	LIBHASHSUM_MD5,          /**< MD5; this algorithm has been compromised */  	LIBHASHSUM_RIPEMD_128,   /**< RIPEMD-128 */  	LIBHASHSUM_RIPEMD_160,   /**< RIPEMD-160 */ @@ -422,8 +422,9 @@ union libhashsum_state {  			uint8_t *dyn;  		} sum;  		const char *suffix; +		size_t squeezes;  		char algostr[256]; -	} keccak; /* size = [1020, 1065] */ +	} keccak; /* size = [1024, 1072] */  #endif  #ifdef LIBHASHSUM_INCLUDE_LIBBLAKE_STATE @@ -974,6 +975,7 @@ int libhashsum_init_keccak_512_hasher(struct libhashsum_hasher *this);   * @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 + * @param   squeezes  The number of squeezes to performed, 0 for automatic (which is 1)   * @return            0 on success, -1 on failure   *    * @throws  EINVAL  (`ratebits`, `capbits`, `hashbits`) is invalid @@ -983,7 +985,8 @@ int libhashsum_init_keccak_512_hasher(struct libhashsum_hasher *this);   * @since  1.0   */  LIBHASHSUM_1_NONNULL_ -int libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebits, size_t capbits, size_t hashbits); +int libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebits, +                                  size_t capbits, size_t hashbits, size_t squeezes);  /**   * Create an initialised state for SHA3-224 diff --git a/libhashsum_init_hasher_from_string.c b/libhashsum_init_hasher_from_string.c index 55fe882..0eaa12e 100644 --- a/libhashsum_init_hasher_from_string.c +++ b/libhashsum_init_hasher_from_string.c @@ -41,7 +41,6 @@ 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)) { @@ -56,25 +55,28 @@ parse_value(size_t *valp, const char *p, const char **end_out)  static int -with_rcn(int (*initfunc)(struct libhashsum_hasher *, size_t, size_t, size_t), +with_rcnz(int (*initfunc)(struct libhashsum_hasher *, size_t, size_t, size_t, size_t),           struct libhashsum_hasher *this, const char *algorithm)  {  	const char *p; -	size_t r = 0, c = 0, n = 0; +	size_t r = 0, c = 0, n = 0, z = 0;  	p = strchr(algorithm, '[');  	if (!p || *++p == ']') -		return initfunc(this, 0, 0, 0); +		return initfunc(this, 0, 0, 0, 0);  	for (;;) {  		if (*p == 'r' || *p == 'R') { -			if (parse_value(&r, p, &p)) +			if (parse_value(&r, &p[1], &p))  				goto einval;  		} else if (*p == 'c' || *p == 'C') { -			if (parse_value(&c, p, &p)) +			if (parse_value(&c, &p[1], &p))  				goto einval;  		} else if (*p == 'n' || *p == 'N') { -			if (parse_value(&n, p, &p)) +			if (parse_value(&n, &p[1], &p)) +				goto einval; +		} else if (*p == 'z' || *p == 'Z') { +			if (parse_value(&z, &p[1], &p))  				goto einval;  		} else if (*p == ']') {  			break; @@ -89,7 +91,7 @@ with_rcn(int (*initfunc)(struct libhashsum_hasher *, size_t, size_t, size_t),  	if (p[1])  		goto einval; -	return initfunc(this, r, c, n); +	return initfunc(this, r, c, n, z);  einval:  	errno = EINVAL; @@ -190,7 +192,7 @@ libhashsum_init_hasher_from_string(struct libhashsum_hasher *this, const char *a  	case LIBHASHSUM_RAWSHAKE128:  return with_n(&libhashsum_init_rawshake128_hasher, this, algorithm);  	case LIBHASHSUM_RAWSHAKE256:  return with_n(&libhashsum_init_rawshake256_hasher, this, algorithm);  	case LIBHASHSUM_RAWSHAKE512:  return with_n(&libhashsum_init_rawshake512_hasher, this, algorithm); -	case LIBHASHSUM_KECCAK:       return with_rcn(&libhashsum_init_keccak_hasher, this, algorithm); +	case LIBHASHSUM_KECCAK:       return with_rcnz(&libhashsum_init_keccak_hasher, this, algorithm);  	case LIBHASHSUM_BLAKE224:     return with_salt(&libhashsum_init_blake224_hasher, this, algorithm, 16U);  	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); diff --git a/libhashsum_init_keccak__.c b/libhashsum_init_keccak__.c index b0023a5..03dd466 100644 --- a/libhashsum_init_keccak__.c +++ b/libhashsum_init_keccak__.c @@ -73,11 +73,22 @@ finalise(struct libhashsum_hasher *this, void *data, size_t bytes, unsigned extr  	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); +		libkeccak_digest(&this->state.keccak.s, m, bytes, extra_bits, this->state.keccak.suffix, +		                 this->state.keccak.squeezes > 1U ? NULL : this->hash_output);  	else -		libkeccak_zerocopy_digest(&this->state.keccak.s, m, bytes, extra_bits, -		                          this->state.keccak.suffix, this->hash_output); +		libkeccak_zerocopy_digest(&this->state.keccak.s, m, bytes, extra_bits, this->state.keccak.suffix, +		                          this->state.keccak.squeezes > 1U ? NULL : this->hash_output); +	if (this->state.keccak.squeezes > 2U) { +		size_t squeezes = this->state.keccak.squeezes - 2U; +		while (squeezes > (size_t)LONG_MAX) { +			libkeccak_fast_squeeze(&this->state.keccak.s, LONG_MAX); +			squeezes -= (size_t)LONG_MAX; +		} +		libkeccak_fast_squeeze(&this->state.keccak.s, (long int)squeezes); +	} +	if (this->state.keccak.squeezes > 1U) +		libkeccak_squeeze(&this->state.keccak.s, 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)); @@ -102,7 +113,7 @@ destroy(struct libhashsum_hasher *this)  int -libhashsum_init_keccak__(struct libhashsum_hasher *this, size_t hashbits, void *spec_, const char *suffix) +libhashsum_init_keccak__(struct libhashsum_hasher *this, size_t hashbits, void *spec_, size_t squeezes, const char *suffix)  {  	struct libkeccak_spec *spec = spec_; @@ -110,6 +121,7 @@ libhashsum_init_keccak__(struct libhashsum_hasher *this, size_t hashbits, void *  	this->hash_size += (size_t)!!(hashbits & 7U);  	this->hash_output = NULL;  	this->supports_non_whole_bytes = 1; +	this->state.keccak.squeezes = squeezes;  	this->state.keccak.suffix = suffix;  	if (this->hash_size > sizeof(this->state.keccak.sum.buf)) { @@ -137,10 +149,11 @@ libhashsum_init_keccak__(struct libhashsum_hasher *this, size_t hashbits, void *  #else  int -libhashsum_init_keccak__(struct libhashsum_hasher *this, size_t hashbits, void *spec, const char *suffix); +libhashsum_init_keccak__(struct libhashsum_hasher *this, size_t hashbits, void *spec, size_t squeezes, const char *suffix);  {  	(void) this;  	(void) spec; +	(void) squeezes;  	(void) suffix;  	errno = ENOSYS;  	return -1; diff --git a/libhashsum_init_keccak_hasher.c b/libhashsum_init_keccak_hasher.c index 93622f6..45e8627 100644 --- a/libhashsum_init_keccak_hasher.c +++ b/libhashsum_init_keccak_hasher.c @@ -4,11 +4,14 @@  int -libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebits, size_t capbits, size_t hashbits) +libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebits, size_t capbits, size_t hashbits, size_t squeezes)  {  	struct libkeccak_generalised_spec gspec;  	struct libkeccak_spec spec; +	if (!squeezes) +		squeezes = 1U; +  	if ((ratebits | capbits | hashbits) > (size_t)LONG_MAX) {  		errno = EINVAL;  		return -1; @@ -38,7 +41,7 @@ libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebits, s  	}  	this->algorithm = LIBHASHSUM_KECCAK; -	if ((capbits >> 1) == hashbits && !(capbits & 1U) && +	if ((capbits >> 1) == hashbits && !(capbits & 1U) && squeezes == 1U &&  	    1600U >= capbits && ratebits == 1600U - capbits) {  		if (hashbits == 224U) {  			this->algorithm = LIBHASHSUM_KECCAK_224; @@ -55,19 +58,26 @@ libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebits, s  		}  	}  	if (this->algorithm == LIBHASHSUM_KECCAK) { -		sprintf(this->state.keccak.algostr, "Keccak[r=%zu,c=%zu,n=%zu]", ratebits, capbits, hashbits); +		if (squeezes > 1U) { +			sprintf(this->state.keccak.algostr, "Keccak[r=%zu,c=%zu,n=%zu,z=%zu]", +			        ratebits, capbits, hashbits, squeezes); +		} else { +			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, ""); +	return libhashsum_init_keccak__(this, hashbits, &spec, squeezes, "");  }  #else  int -libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t hashbits) +libhashsum_init_keccak_hasher(struct libhashsum_hasher *this, size_t ratebits, size_t capbits, size_t hashbits, size_t squeezes)  {  	(void) this; +	(void) ratebits; +	(void) capbits;  	(void) hashbits;  	errno = ENOSYS;  	return -1; diff --git a/libhashsum_init_rawshake_hasher.c b/libhashsum_init_rawshake_hasher.c index f90e3b7..f6cba3b 100644 --- a/libhashsum_init_rawshake_hasher.c +++ b/libhashsum_init_rawshake_hasher.c @@ -35,7 +35,7 @@ libhashsum_init_rawshake_hasher(struct libhashsum_hasher *this, size_t hcapbits,  	}  	libkeccak_spec_rawshake(&spec, (long int)hcapbits, (long int)hashbits); -	return libhashsum_init_keccak__(this, hashbits, &spec, LIBKECCAK_RAWSHAKE_SUFFIX); +	return libhashsum_init_keccak__(this, hashbits, &spec, 1U, LIBKECCAK_RAWSHAKE_SUFFIX);  } diff --git a/libhashsum_init_sha3_hasher.c b/libhashsum_init_sha3_hasher.c index c9d6ac7..fc03114 100644 --- a/libhashsum_init_sha3_hasher.c +++ b/libhashsum_init_sha3_hasher.c @@ -26,7 +26,7 @@ libhashsum_init_sha3_hasher(struct libhashsum_hasher *this, size_t hashbits)  	}  	libkeccak_spec_sha3(&spec, (long int)hashbits); -	return libhashsum_init_keccak__(this, hashbits, &spec, LIBKECCAK_SHA3_SUFFIX); +	return libhashsum_init_keccak__(this, hashbits, &spec, 1U, LIBKECCAK_SHA3_SUFFIX);  } diff --git a/libhashsum_init_shake_hasher.c b/libhashsum_init_shake_hasher.c index a5f5746..460e4c0 100644 --- a/libhashsum_init_shake_hasher.c +++ b/libhashsum_init_shake_hasher.c @@ -35,7 +35,7 @@ libhashsum_init_shake_hasher(struct libhashsum_hasher *this, size_t hcapbits, si  	}  	libkeccak_spec_shake(&spec, (long int)hcapbits, (long int)hashbits); -	return libhashsum_init_keccak__(this, hashbits, &spec, LIBKECCAK_SHAKE_SUFFIX); +	return libhashsum_init_keccak__(this, hashbits, &spec, 1U, LIBKECCAK_SHAKE_SUFFIX);  } | 
