1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

Switch to deterministic DSA.

* agent/pksign.c (rfc6979_hash_algo_string): New.
(do_encode_dsa) [Libgcrypt >= 1.6]: Make use of RFC-6979.
--

Now that we have a good (and not NSA/NIST demanded ;-) specification
on how to use DSA without a random nonce, we take advantage of it and
thus avoid pitfalls related to a misbehaving RNG during signature
creation.

Note that OpenPGP has the option of using a longer hash algorithm but
truncated to what is suitable for the used DSA key size.  The hash
used as input to RFC-6979 will also be one with an appropriate digest
length but not a truncated one.  This is allowed by RFC-6979.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2013-09-07 10:06:46 +02:00
parent 244587ea41
commit 6466db10fb

View File

@ -1,5 +1,6 @@
/* pksign.c - public key signing (well, actually using a secret key)
* Copyright (C) 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
* Copyright (C) 2013 Werner Koch
*
* This file is part of GnuPG.
*
@ -111,6 +112,25 @@ get_dsa_qbits (gcry_sexp_t key)
}
/* Return an appropriate hash algorithm to be used with RFC-6979 for a
message digest of length MDLEN. Although a fallback of SHA-256 is
used the current implementation in Libgcrypt will reject a hash
algorithm which does not match the length of the message. */
static const char *
rfc6979_hash_algo_string (size_t mdlen)
{
switch (mdlen)
{
case 20: return "sha1";
case 28: return "sha224";
case 32: return "sha256";
case 48: return "sha384";
case 64: return "sha512";
default: return "sha256";
}
}
/* Encode a message digest for use with an DSA algorithm. */
static gpg_error_t
do_encode_dsa (const byte *md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey,
@ -177,11 +197,20 @@ do_encode_dsa (const byte *md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey,
if (mdlen > qbits/8)
mdlen = qbits/8;
/* Create the S-expression. We need to convert to an MPI first
because we want an unsigned integer. Using %b directly is not
possible because libgcrypt assumes an mpi and uses
GCRYMPI_FMT_STD for parsing and thus possible yielding a negative
value. */
/* Create the S-expression. If we are using Libgcrypt 1.6 we make
use of Deterministic DSA. Libgcrypt < 1.6 does not implement
RFC-6979 and also requires us to convert to an MPI because it
expects an unsigned integer. Using %b directly is not possible
because Libgcrypt assumes an MPI and uses GCRYMPI_FMT_STD for
parsing and thus possible yielding a negative value. */
#if GCRYPT_VERSION_NUMBER >= 0x010600 /* Libgcrypt >= 1.6 */
{
err = gcry_sexp_build (&hash, NULL,
"(data (flags rfc6979) (hash %s %b))",
rfc6979_hash_algo_string (mdlen),
(int)mdlen, md);
}
#else /* Libgcrypt < 1.6 */
{
gcry_mpi_t mpi;
@ -193,6 +222,7 @@ do_encode_dsa (const byte *md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey,
gcry_mpi_release (mpi);
}
}
#endif /* Libgcrypt < 1.6 */
if (!err)
*r_hash = hash;
return err;