From 49ec33eb18d7c86e3cf2ce56ffef7aaf60de8c0d Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 24 Mar 2016 00:04:53 +0100 Subject: Disallow XOF algorithms for gcry_md_hash_buffers * cipher/md.c (_gcry_md_hash_buffer): Skip calculation for XOFs. (_gcry_md_hash_buffers): Fail when XOFs are selected. * doc/gcrypt.texi: Explicitly document above behavior for XOFs. * tests/benchmark.c: Skip benchmarking hash functions without a fixed output length. -- Caught by UndefinedBehaviorSanitizer while running tests/benchmarks where gcry_md_hash_buffer(GCRY_MD_SHAKE128) would result in memcpy(digest, NULL, 0). Signed-off-by: Peter Wu --- cipher/md.c | 5 +++++ doc/gcrypt.texi | 4 +++- tests/benchmark.c | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cipher/md.c b/cipher/md.c index 0414dcb0..d1d08123 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -948,6 +948,8 @@ _gcry_md_hash_buffer (int algo, void *digest, _gcry_sha1_hash_buffer (digest, buffer, length); else if (algo == GCRY_MD_RMD160 && !fips_mode () ) _gcry_rmd160_hash_buffer (digest, buffer, length); + else if (md_digest_length (algo) == 0) + ; /* Nothing to do for hashes without a fixed output length. */ else { /* For the others we do not have a fast function, so we use the @@ -1007,6 +1009,9 @@ _gcry_md_hash_buffers (int algo, unsigned int flags, void *digest, if (hmac && iovcnt < 1) return GPG_ERR_INV_ARG; + if (md_digest_length (algo) == 0) + return GPG_ERR_INV_ARG; + if (algo == GCRY_MD_SHA1 && !hmac) _gcry_sha1_hash_buffers (digest, iov, iovcnt); else diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 3265a706..9481be9e 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -3378,6 +3378,7 @@ described by @var{iov} and @var{iovcnt}. @var{digest} must be allocated by the caller, large enough to hold the message digest yielded by the the specified algorithm @var{algo}. This required size may be obtained by using the function @code{gcry_md_get_algo_dlen}. +This function cannot be used for extendable-output functions. @var{iov} is an array of buffer descriptions with @var{iovcnt} items. The caller should zero out the structures in this array and for each @@ -3402,7 +3403,8 @@ immediately returns the message digest of the @var{length} bytes at @var{buffer}. @var{digest} must be allocated by the caller, large enough to hold the message digest yielded by the the specified algorithm @var{algo}. This required size may be obtained by using the function -@code{gcry_md_get_algo_dlen}. +@code{gcry_md_get_algo_dlen}. This function has no effect for +extendable-output functions. Note that in contrast to @code{gcry_md_hash_buffers} this function will abort the process if an unavailable algorithm is used. diff --git a/tests/benchmark.c b/tests/benchmark.c index 53b83b1b..5f94cc89 100644 --- a/tests/benchmark.c +++ b/tests/benchmark.c @@ -499,6 +499,8 @@ md_bench ( const char *algoname ) for (i=1; i < 400; i++) if (in_fips_mode && i == GCRY_MD_MD5) ; /* Don't use MD5 in fips mode. */ + else if (gcry_md_get_algo_dlen (i) == 0) + ; /* Skip hash functions without a fixed output length. */ else if ( !gcry_md_test_algo (i) ) md_bench (gcry_md_algo_name (i)); return; -- cgit v1.2.1