diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2021-03-22 23:12:02 +0200 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2021-04-26 22:41:51 +0300 |
commit | f53d541d0947a894e6f09b4568658a859505a649 (patch) | |
tree | 0510c4a43ec3865bb3215504dc4f9953acf0b991 /cipher/md.c | |
parent | 4770ad72607f73b9d529511c687556a6b4109875 (diff) | |
download | libgcrypt-f53d541d0947a894e6f09b4568658a859505a649.tar.gz |
Add XOF output support for internal _gcry_md_hash_buffers
* cipher/ecc-eddsa.c (_gcry_ecc_eddsa_compute_h_d, _gcry_ecc_eddsa_sign)
(_gcry_ecc_eddsa_verify): Use same _gcry_md_hash_buffers_extract code
path for SHA512 and SHAKE256.
* cipher/md.c (_gcry_md_hash_buffers): Rename to ...
(_gcry_md_hash_buffers_extract): ... this; Add digestlen and handling
for XOF algorithms (SHAKE128, SHAKE256).
(_gcry_md_hash_buffers): New.
* src/gcrypt-int.h (_gcry_md_hash_buffers_extract): New.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher/md.c')
-rw-r--r-- | cipher/md.c | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/cipher/md.c b/cipher/md.c index efb7376a..87979059 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -1251,11 +1251,15 @@ _gcry_md_hash_buffer (int algo, void *digest, used as the key. On success 0 is returned and resulting hash or HMAC is stored at - DIGEST which must have been provided by the caller with an - appropriate length. */ + DIGEST. DIGESTLEN may be given as -1, in which case DIGEST must + have been provided by the caller with an appropriate length. + DIGESTLEN may also be the appropriate length or, in case of XOF + algorithms, DIGESTLEN indicates number bytes to extract from XOF + to DIGEST. */ gpg_err_code_t -_gcry_md_hash_buffers (int algo, unsigned int flags, void *digest, - const gcry_buffer_t *iov, int iovcnt) +_gcry_md_hash_buffers_extract (int algo, unsigned int flags, void *digest, + int digestlen, const gcry_buffer_t *iov, + int iovcnt) { gcry_md_spec_t *spec; int hmac; @@ -1287,6 +1291,11 @@ _gcry_md_hash_buffers (int algo, unsigned int flags, void *digest, } } + if (spec->mdlen > 0 && digestlen != -1 && digestlen != spec->mdlen) + return GPG_ERR_DIGEST_ALGO; + if (spec->mdlen == 0 && digestlen == -1) + return GPG_ERR_DIGEST_ALGO; + if (!hmac && spec->hash_buffers) { spec->hash_buffers (digest, iov, iovcnt); @@ -1297,13 +1306,6 @@ _gcry_md_hash_buffers (int algo, unsigned int flags, void *digest, normal functions. */ gcry_md_hd_t h; gpg_err_code_t rc; - int dlen; - - /* Detect SHAKE128 like algorithms which we can't use because - * our API does not allow for a variable length digest. */ - dlen = md_digest_length (algo); - if (!dlen) - return GPG_ERR_DIGEST_ALGO; rc = md_open (&h, algo, (hmac? GCRY_MD_FLAG_HMAC:0)); if (rc) @@ -1324,7 +1326,10 @@ _gcry_md_hash_buffers (int algo, unsigned int flags, void *digest, for (;iovcnt; iov++, iovcnt--) md_write (h, (const char*)iov[0].data + iov[0].off, iov[0].len); md_final (h); - memcpy (digest, md_read (h, algo), dlen); + if (spec->mdlen > 0) + memcpy (digest, md_read (h, algo), spec->mdlen); + else if (digestlen > 0) + md_extract (h, algo, digest, digestlen); md_close (h); } @@ -1332,6 +1337,28 @@ _gcry_md_hash_buffers (int algo, unsigned int flags, void *digest, } +/* Shortcut function to hash multiple buffers with a given algo. In + contrast to gcry_md_hash_buffer, this function returns an error on + invalid arguments or on other problems; disabled algorithms are + _not_ ignored but flagged as an error. + + The data to sign is taken from the array IOV which has IOVCNT items. + + The only supported flag in FLAGS is GCRY_MD_FLAG_HMAC which turns + this function into a HMAC function; the first item in IOV is then + used as the key. + + On success 0 is returned and resulting hash or HMAC is stored at + DIGEST which must have been provided by the caller with an + appropriate length. */ +gpg_err_code_t +_gcry_md_hash_buffers (int algo, unsigned int flags, void *digest, + const gcry_buffer_t *iov, int iovcnt) +{ + return _gcry_md_hash_buffers_extract(algo, flags, digest, -1, iov, iovcnt); +} + + static int md_get_algo (gcry_md_hd_t a) { |