Commit ade5dd2b authored by Niels Möller's avatar Niels Möller

dsa: Allow arbitrary digest sizes. Support 224-bit q.

parent 28213082
2013-11-24 Niels Möller <nisse@lysator.liu.se>
* testsuite/dsa-keygen-test.c (test_main): Test generating a
key with 224-bit q.
* dsa-verify.c (_dsa_verify): Use _dsa_hash.
* dsa-sign.c (_dsa_sign): Use _dsa_hash. Fix memory leak in
error case, spotted by Nikos.
* dsa-keygen.c (dsa_generate_keypair): Allow q_bits == 224.
* dsa-hash.c (_dsa_hash): New file and function. Allows digest
sizes not matching the bitsize of q.
* dsa.h (_dsa_hash): Declare it.
* Makefile.in (hogweed_SOURCES): Added dsa-hash.c.
2013-11-23 Niels Möller <nisse@lysator.liu.se>
* configure.ac: Check also for openssl/ecdsa.h.
......
......@@ -129,7 +129,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \
rsa-encrypt.c rsa-decrypt.c rsa-decrypt-tr.c \
rsa-keygen.c rsa-compat.c rsa-blind.c \
rsa2sexp.c sexp2rsa.c \
dsa.c dsa-sign.c dsa-verify.c dsa-keygen.c \
dsa.c dsa-sign.c dsa-verify.c dsa-keygen.c dsa-hash.c \
dsa-sha1-sign.c dsa-sha1-verify.c \
dsa-sha256-sign.c dsa-sha256-verify.c \
dsa2sexp.c sexp2dsa.c \
......
/* dsa-hash.c */
/* nettle, low-level cryptographics library
*
* Copyright (C) 2013 Niels Möller
*
* The nettle library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* The nettle library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the nettle library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02111-1301, USA.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include "dsa.h"
#include "bignum.h"
/* Convert hash value to an integer. The general description of DSA in
FIPS186-3 allows both larger and smaller q; in the the latter case,
the hash must be truncated to the right number of bits. */
void
_dsa_hash (mpz_t h, unsigned bit_size,
size_t length, const uint8_t *digest)
{
if (length > (bit_size + 7) / 8)
length = (bit_size + 7) / 8;
nettle_mpz_set_str_256_u(h, length, digest);
if (8 * length > bit_size)
/* We got a few extra bits, at the low end. Discard them. */
mpz_tdiv_q_2exp (h, h, 8*length - bit_size);
}
......@@ -36,7 +36,7 @@
#include "nettle-internal.h"
/* Valid sizes, according to FIPS 186-3 are (1024, 160), (2048. 224),
/* Valid sizes, according to FIPS 186-3 are (1024, 160), (2048, 224),
(2048, 256), (3072, 256). Currenty, we use only q_bits of 160 or
256. */
int
......@@ -56,6 +56,7 @@ dsa_generate_keypair(struct dsa_public_key *pub,
if (p_bits < DSA_SHA1_MIN_P_BITS)
return 0;
break;
case 224:
case 256:
if (p_bits < DSA_SHA256_MIN_P_BITS)
return 0;
......
......@@ -46,14 +46,8 @@ _dsa_sign(const struct dsa_public_key *pub,
mpz_t k;
mpz_t h;
mpz_t tmp;
/* Require precise match of bitsize of q and hash size. The general
description of DSA in FIPS186-3 allows both larger and smaller q;
in the the latter case, the hash must be truncated to the right
number of bits. */
if (mpz_sizeinbase(pub->q, 2) != 8 * digest_size)
return 0;
int res;
/* Select k, 0<k<q, randomly */
mpz_init_set(tmp, pub->q);
mpz_sub_ui(tmp, tmp, 1);
......@@ -68,23 +62,26 @@ _dsa_sign(const struct dsa_public_key *pub,
/* Compute hash */
mpz_init(h);
nettle_mpz_set_str_256_u(h, digest_size, digest);
_dsa_hash (h, mpz_sizeinbase(pub->q, 2), digest_size, digest);
/* Compute k^-1 (mod q) */
if (!mpz_invert(k, k, pub->q))
if (mpz_invert(k, k, pub->q))
{
/* Compute signature s = k^-1 (h + xr) (mod q) */
mpz_mul(tmp, signature->r, key->x);
mpz_fdiv_r(tmp, tmp, pub->q);
mpz_add(tmp, tmp, h);
mpz_mul(tmp, tmp, k);
mpz_fdiv_r(signature->s, tmp, pub->q);
res = 1;
}
else
/* What do we do now? The key is invalid. */
return 0;
/* Compute signature s = k^-1 (h + xr) (mod q) */
mpz_mul(tmp, signature->r, key->x);
mpz_fdiv_r(tmp, tmp, pub->q);
mpz_add(tmp, tmp, h);
mpz_mul(tmp, tmp, k);
mpz_fdiv_r(signature->s, tmp, pub->q);
res = 0;
mpz_clear(k);
mpz_clear(h);
mpz_clear(tmp);
return 1;
return res;
}
......@@ -45,9 +45,6 @@ _dsa_verify(const struct dsa_public_key *key,
int res;
if (mpz_sizeinbase(key->q, 2) != 8 * digest_size)
return 0;
/* Check that r and s are in the proper range */
if (mpz_sgn(signature->r) <= 0 || mpz_cmp(signature->r, key->q) >= 0)
return 0;
......@@ -71,7 +68,7 @@ _dsa_verify(const struct dsa_public_key *key,
mpz_init(v);
/* The message digest */
nettle_mpz_set_str_256_u(tmp, digest_size, digest);
_dsa_hash (tmp, mpz_sizeinbase (key->q, 2), digest_size, digest);
/* v = g^{w * h (mod q)} (mod p) */
mpz_mul(tmp, tmp, w);
......
......@@ -62,6 +62,7 @@ extern "C" {
#define dsa_public_key_from_der_iterator nettle_dsa_public_key_from_der_iterator
#define dsa_openssl_private_key_from_der_iterator nettle_dsa_openssl_private_key_from_der_iterator
#define dsa_openssl_private_key_from_der nettle_openssl_provate_key_from_der
#define _dsa_hash _nettle_dsa_hash
#define _dsa_sign _nettle_dsa_sign
#define _dsa_verify _nettle_dsa_verify
......@@ -272,6 +273,10 @@ dsa_openssl_private_key_from_der(struct dsa_public_key *pub,
/* Internal functions. */
void
_dsa_hash (mpz_t h, unsigned bit_size,
size_t length, const uint8_t *digest);
int
_dsa_sign(const struct dsa_public_key *pub,
const struct dsa_private_key *key,
......
......@@ -39,6 +39,15 @@ test_main(void)
test_dsa_key(&pub, &key, 256);
test_dsa256(&pub, &key, NULL);
ASSERT (dsa_generate_keypair(&pub, &key,
&lfib,
(nettle_random_func *) knuth_lfib_random,
NULL, verbose ? progress : NULL,
2048, 224));
test_dsa_key(&pub, &key, 224);
test_dsa256(&pub, &key, NULL);
dsa_public_key_clear(&pub);
dsa_private_key_clear(&key);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment