diff options
author | Werner Koch <wk@gnupg.org> | 2013-07-19 18:14:38 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-07-19 18:14:38 +0200 |
commit | 37d0a1ebdc2dc74df4fb6bf0621045018122a68f (patch) | |
tree | b516be67206ef44bcb92076faa7afcceb12d98b7 /cipher/dsa.c | |
parent | 2d3e8d4d9562d666420aadd9ffa8ac0456a1cd91 (diff) | |
download | libgcrypt-37d0a1ebdc2dc74df4fb6bf0621045018122a68f.tar.gz |
pk: Allow the use of a hash element for DSA sign and verify.
* cipher/pubkey.c (pubkey_sign): Add arg ctx and pass it to the sign
module.
(gcry_pk_sign): Pass CTX to pubkey_sign.
(sexp_data_to_mpi): Add flag rfc6979 and code to alls hash with *DSA
* cipher/rsa.c (rsa_sign, rsa_verify): Return an error if an opaque
MPI is given for DATA/HASH.
* cipher/elgamal.c (elg_sign, elg_verify): Ditto.
* cipher/dsa.c (dsa_sign, dsa_verify): Convert a given opaque MPI.
* cipher/ecc.c (ecc_sign, ecc_verify): Ditto.
* tests/basic.c (check_pubkey_sign_ecdsa): Add a test for using a hash
element with DSA.
--
This patch allows the use of
(data (flags raw)
(hash sha256 #80112233445566778899AABBCCDDEEFF
000102030405060708090A0B0C0D0E0F#))
in addition to the old but more efficient
(data (flags raw)
(value #80112233445566778899AABBCCDDEEFF
000102030405060708090A0B0C0D0E0F#))
for DSA and ECDSA. With the hash element the flag "raw" must be
explicitly given because existing regression test code expects that
conflict error is return if no flags but a hash element is given.
Note that the hash algorithm name is currently not checked. It may
eventually be used to cross-check the length of the provided hash
value. It is suggested that the correct hash name is given - even if
a truncated hash value is used.
Finally this patch adds a way to pass the hash algorithm and flag
values to the signing module. "rfc6979" as been implemented as a new
but not yet used flag.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'cipher/dsa.c')
-rw-r--r-- | cipher/dsa.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/cipher/dsa.c b/cipher/dsa.c index 55805e21..7652c19f 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -1,6 +1,7 @@ /* dsa.c - DSA signature algorithm * Copyright (C) 1998, 2000, 2001, 2002, 2003, * 2006, 2008 Free Software Foundation, Inc. + * Copyright (C) 2013 g10 Code GmbH. * * This file is part of Libgcrypt. * @@ -539,7 +540,7 @@ check_secret_key( DSA_secret_key *sk ) Make a DSA signature from HASH and put it into r and s. */ static void -sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey ) +sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey ) { gcry_mpi_t k; gcry_mpi_t kinv; @@ -929,7 +930,22 @@ dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey, sk.x = skey[4]; resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p)); resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p)); - sign (resarr[0], resarr[1], data, &sk); + if (mpi_is_opaque (data)) + { + const void *abuf; + unsigned int abits; + gcry_mpi_t a; + + abuf = gcry_mpi_get_opaque (data, &abits); + err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, abuf, abits/8, NULL); + if (!err) + { + sign (resarr[0], resarr[1], a, &sk); + gcry_mpi_release (a); + } + } + else + sign (resarr[0], resarr[1], data, &sk); } return err; } @@ -954,8 +970,26 @@ dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey, pk.q = pkey[1]; pk.g = pkey[2]; pk.y = pkey[3]; - if (! verify (data[0], data[1], hash, &pk)) - err = GPG_ERR_BAD_SIGNATURE; + if (mpi_is_opaque (hash)) + { + const void *abuf; + unsigned int abits; + gcry_mpi_t a; + + abuf = gcry_mpi_get_opaque (hash, &abits); + err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, abuf, abits/8, NULL); + if (!err) + { + if (!verify (data[0], data[1], a, &pk)) + err = GPG_ERR_BAD_SIGNATURE; + gcry_mpi_release (a); + } + } + else + { + if (!verify (data[0], data[1], hash, &pk)) + err = GPG_ERR_BAD_SIGNATURE; + } } return err; } |