summaryrefslogtreecommitdiff
path: root/cipher/dsa-common.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2021-07-29 11:50:31 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2021-07-29 11:50:31 +0900
commit4a3e71403225bd60a96d6747a8141a268bedda78 (patch)
treea59c87c25d52a801216722d73e8fe7dc36fb9f50 /cipher/dsa-common.c
parent877be1bf9df0b4e9aed9036db1592a64582a4bac (diff)
downloadlibgcrypt-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.c55
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