summaryrefslogtreecommitdiff
path: root/cipher/ecc-ecdsa.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/ecc-ecdsa.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/ecc-ecdsa.c')
-rw-r--r--cipher/ecc-ecdsa.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/cipher/ecc-ecdsa.c b/cipher/ecc-ecdsa.c
index 30103f14..c7f4c8d5 100644
--- a/cipher/ecc-ecdsa.c
+++ b/cipher/ecc-ecdsa.c
@@ -51,16 +51,29 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, mpi_ec_t ec,
unsigned int abits, qbits;
gcry_mpi_t b; /* Random number needed for blinding. */
gcry_mpi_t bi; /* multiplicative inverse of B. */
+ gcry_mpi_t hash_computed_internally = NULL;
if (DBG_CIPHER)
log_mpidump ("ecdsa sign hash ", input );
qbits = mpi_get_nbits (ec->n);
+ if ((flags & PUBKEY_FLAG_PREHASH))
+ {
+ rc = _gcry_dsa_compute_hash (&hash_computed_internally, input, hashalgo);
+ if (rc)
+ return rc;
+ input = hash_computed_internally;
+ }
+
/* Convert the INPUT into an MPI if needed. */
rc = _gcry_dsa_normalize_hash (input, &hash, qbits);
+
if (rc)
- return rc;
+ {
+ mpi_free (hash_computed_internally);
+ return rc;
+ }
b = mpi_snew (qbits);
bi = mpi_snew (qbits);
@@ -155,6 +168,7 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, mpi_ec_t ec,
if (hash != input)
mpi_free (hash);
+ mpi_free (hash_computed_internally);
return rc;
}
@@ -165,12 +179,14 @@ _gcry_ecc_ecdsa_sign (gcry_mpi_t input, mpi_ec_t ec,
*/
gpg_err_code_t
_gcry_ecc_ecdsa_verify (gcry_mpi_t input, mpi_ec_t ec,
- gcry_mpi_t r, gcry_mpi_t s)
+ gcry_mpi_t r, gcry_mpi_t s,
+ int flags, int hashalgo)
{
gpg_err_code_t err = 0;
gcry_mpi_t hash, h, h1, h2, x;
mpi_point_struct Q, Q1, Q2;
unsigned int nbits;
+ gcry_mpi_t hash_computed_internally = NULL;
if (!_gcry_mpi_ec_curve_point (ec->Q, ec))
return GPG_ERR_BROKEN_PUBKEY;
@@ -181,9 +197,21 @@ _gcry_ecc_ecdsa_verify (gcry_mpi_t input, mpi_ec_t ec,
return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n failed. */
nbits = mpi_get_nbits (ec->n);
+ if ((flags & PUBKEY_FLAG_PREHASH))
+ {
+ err = _gcry_dsa_compute_hash (&hash_computed_internally, input,
+ hashalgo);
+ if (err)
+ return err;
+ input = hash_computed_internally;
+ }
+
err = _gcry_dsa_normalize_hash (input, &hash, nbits);
if (err)
- return err;
+ {
+ mpi_free (hash_computed_internally);
+ return err;
+ }
h = mpi_alloc (0);
h1 = mpi_alloc (0);
@@ -243,6 +271,7 @@ _gcry_ecc_ecdsa_verify (gcry_mpi_t input, mpi_ec_t ec,
mpi_free (h);
if (hash != input)
mpi_free (hash);
+ mpi_free (hash_computed_internally);
return err;
}