diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2021-07-29 11:50:31 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2021-07-29 11:50:31 +0900 |
commit | 4a3e71403225bd60a96d6747a8141a268bedda78 (patch) | |
tree | a59c87c25d52a801216722d73e8fe7dc36fb9f50 /cipher/dsa-common.c | |
parent | 877be1bf9df0b4e9aed9036db1592a64582a4bac (diff) | |
download | libgcrypt-4a3e71403225bd60a96d6747a8141a268bedda78.tar.gz |
cipher: Support internal hashing for DSA and ECDSA signing.
* cipher/dsa-common.c (_gcry_dsa_compute_hash): New.
* cipher/pubkey-internal.h (_gcry_dsa_compute_hash): New.
* cipher/dsa.c (verify): Add FLAGS and HASHALGO.
(test_keys): Follow the change of verify API.
(sign, verify): Support PUBKEY_FLAG_PREHASH flag to hash internally.
(selftest_sign): Test with "prehash" flag.
* cipher/ecc-common.h (_gcry_ecc_ecdsa_verify): Add FLAGS and
HASHALGO.
* cipher/ecc-ecdsa.c (_gcry_ecc_ecdsa_sign): Support
PUBKEY_FLAG_PREHASH flag to hash internally.
(_gcry_ecc_ecdsa_verify): Likewise.
* cipher/ecc.c (test_keys): Follow the change of
_gcry_ecc_ecdsa_verify API.
(selftest_sign): Test with "prehash" flag.
* cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi): Support handling
of "hash-algo" and "value" with "prehash" flag.
--
GnuPG-bug-id: 5530
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'cipher/dsa-common.c')
-rw-r--r-- | cipher/dsa-common.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/cipher/dsa-common.c b/cipher/dsa-common.c index fe49248d..7000903a 100644 --- a/cipher/dsa-common.c +++ b/cipher/dsa-common.c @@ -384,6 +384,61 @@ _gcry_dsa_gen_rfc6979_k (gcry_mpi_t *r_k, return rc; } + + +/* + * For DSA/ECDSA, as prehash function, compute hash with HASHALGO for + * INPUT. Result hash value is returned in R_HASH as an opaque MPI. + * Returns error code. + */ +gpg_err_code_t +_gcry_dsa_compute_hash (gcry_mpi_t *r_hash, gcry_mpi_t input, int hashalgo) +{ + gpg_err_code_t rc = 0; + size_t hlen; + void *hashbuf; + void *abuf; + unsigned int abits; + unsigned int n; + + hlen = _gcry_md_get_algo_dlen (hashalgo); + hashbuf = xtrymalloc (hlen); + if (!hashbuf) + { + rc = gpg_err_code_from_syserror (); + return rc; + } + + if (mpi_is_opaque (input)) + { + abuf = mpi_get_opaque (input, &abits); + n = (abits+7)/8; + _gcry_md_hash_buffer (hashalgo, hashbuf, abuf, n); + } + else + { + abits = mpi_get_nbits (input); + n = (abits+7)/8; + abuf = xtrymalloc (n); + if (!abuf) + { + rc = gpg_err_code_from_syserror (); + xfree (hashbuf); + return rc; + } + _gcry_mpi_to_octet_string (NULL, abuf, input, n); + _gcry_md_hash_buffer (hashalgo, hashbuf, abuf, n); + xfree (abuf); + } + + *r_hash = mpi_set_opaque (NULL, hashbuf, hlen*8); + if (!*r_hash) + rc = GPG_ERR_INV_OBJ; + + return rc; +} + + /* * Truncate opaque hash value to qbits for DSA. * Non-opaque input is not truncated, in hope that user |