mirror of
git://git.gnupg.org/gnupg.git
synced 2025-05-24 16:43:28 +02: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:
parent
244587ea41
commit
6466db10fb
@ -1,5 +1,6 @@
|
|||||||
/* pksign.c - public key signing (well, actually using a secret key)
|
/* pksign.c - public key signing (well, actually using a secret key)
|
||||||
* Copyright (C) 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
|
||||||
|
* Copyright (C) 2013 Werner Koch
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* 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. */
|
/* Encode a message digest for use with an DSA algorithm. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
do_encode_dsa (const byte *md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey,
|
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)
|
if (mdlen > qbits/8)
|
||||||
mdlen = qbits/8;
|
mdlen = qbits/8;
|
||||||
|
|
||||||
/* Create the S-expression. We need to convert to an MPI first
|
/* Create the S-expression. If we are using Libgcrypt 1.6 we make
|
||||||
because we want an unsigned integer. Using %b directly is not
|
use of Deterministic DSA. Libgcrypt < 1.6 does not implement
|
||||||
possible because libgcrypt assumes an mpi and uses
|
RFC-6979 and also requires us to convert to an MPI because it
|
||||||
GCRYMPI_FMT_STD for parsing and thus possible yielding a negative
|
expects an unsigned integer. Using %b directly is not possible
|
||||||
value. */
|
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;
|
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);
|
gcry_mpi_release (mpi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* Libgcrypt < 1.6 */
|
||||||
if (!err)
|
if (!err)
|
||||||
*r_hash = hash;
|
*r_hash = hash;
|
||||||
return err;
|
return err;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user