diff --git a/ChangeLog b/ChangeLog index 926cefb2896a5324a0f02210c2cc8963dab59dea..42a9f8ec184007ae91711dc2999cce9180aca419 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2010-03-30 Niels M�ller <nisse@lysator.liu.se> + + * Makefile.in (hogweed_SOURCES): Added dsa-sha1-sign.c, + dsa-sha1-verify.c, dsa-sha256-sign.c, and dsa-sha256-verify.c. + + * dsa.h: Updated and added dsa declarations. + + * dsa-sha256-verify.c (dsa_sha256_verify_digest): New file, new + function. + (dsa_sha256_verify): New function. + * dsa-sha256-sign.c (dsa_sha256_sign_digest): New file, new + function. + (dsa_sha256_sign): New function. + + * dsa-sha1-verify.c (dsa_sha1_verify_digest): New file. Moved and + renamed function, from dsa_verify_digest, rewrote to use + _dsa_verify. + (dsa_sha1_verify): Analogous change, renamed from dsa_verify. + * dsa-sha1-sign.c (dsa_sha1_sign_digest): New file. Moved and + renamed function, from dsa_sign_digest, rewrote to use _dsa_sign, + and added return value. + (dsa_sha1_sign): Analogous change, renamed from dsa_sign. + + * dsa-verify.c (_dsa_verify): New general verification function, + for any hash. + * dsa-sign.c (_dsa_sign): New general signing function, for any + hash. Returns success code, like the rsa signture functions. + 2010-03-29 Niels M�ller <nisse@lysator.liu.se> * configure.ac (ABI): Attempt to use a better, ABI-dependant, diff --git a/Makefile.in b/Makefile.in index 7315b2b301fa65787d07dd93bf83420933d2629c..d4c8f1b63da5658d929964ba9310bea739bc9936 100644 --- a/Makefile.in +++ b/Makefile.in @@ -88,6 +88,8 @@ hogweed_SOURCES = sexp.c sexp-format.c \ rsa-keygen.c rsa-compat.c \ rsa2sexp.c sexp2rsa.c \ dsa.c dsa-sign.c dsa-verify.c dsa-keygen.c \ + dsa-sha1-sign.c dsa-sha1-verify.c \ + dsa-sha256-sign.c dsa-sha256-verify.c \ dsa2sexp.c sexp2dsa.c \ pgp-encode.c rsa2openpgp.c \ der-iterator.c der2rsa.c der2dsa.c diff --git a/dsa-sha1-sign.c b/dsa-sha1-sign.c new file mode 100644 index 0000000000000000000000000000000000000000..5654c493b18a50f84528ba72bb9272615b5f4bec --- /dev/null +++ b/dsa-sha1-sign.c @@ -0,0 +1,56 @@ +/* dsa-sha1-sign.c + * + * The original DSA publickey algorithm, using SHA-1. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 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., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa.h" + +int +dsa_sha1_sign_digest(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + const uint8_t *digest, + struct dsa_signature *signature) +{ + return _dsa_sign(pub, key, random_ctx, random, + SHA1_DIGEST_SIZE, digest, signature); +} + + +int +dsa_sha1_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + struct sha1_ctx *hash, + struct dsa_signature *signature) +{ + uint8_t digest[SHA1_DIGEST_SIZE]; + sha1_digest(hash, sizeof(digest), digest); + + return _dsa_sign(pub, key, random_ctx, random, + sizeof(digest), digest, signature); +} diff --git a/dsa-sha1-verify.c b/dsa-sha1-verify.c new file mode 100644 index 0000000000000000000000000000000000000000..73e948c11104cf6df5d965b977f3a2860db77c55 --- /dev/null +++ b/dsa-sha1-verify.c @@ -0,0 +1,51 @@ +/* dsa-sha1-verify.c + * + * The original DSA publickey algorithm, using SHA-1. + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2003, 2010 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., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> + +#include "dsa.h" + +int +dsa_sha1_verify_digest(const struct dsa_public_key *key, + const uint8_t *digest, + const struct dsa_signature *signature) +{ + return _dsa_verify(key, SHA1_DIGEST_SIZE, digest, signature); +} + +int +dsa_sha1_verify(const struct dsa_public_key *key, + struct sha1_ctx *hash, + const struct dsa_signature *signature) +{ + uint8_t digest[SHA1_DIGEST_SIZE]; + sha1_digest(hash, sizeof(digest), digest); + + return _dsa_verify(key, sizeof(digest), digest, signature); +} diff --git a/dsa-sha256-sign.c b/dsa-sha256-sign.c new file mode 100644 index 0000000000000000000000000000000000000000..ea82022e0f1ad714fe206dfc3615ca70775ff8c5 --- /dev/null +++ b/dsa-sha256-sign.c @@ -0,0 +1,55 @@ +/* dsa-sha256-sign.c + * + * The DSA publickey algorithm, using SHA-256 (FIPS186-3). + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 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., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "dsa.h" + +int +dsa_sha256_sign_digest(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + const uint8_t *digest, + struct dsa_signature *signature) +{ + return _dsa_sign(pub, key, random_ctx, random, + SHA256_DIGEST_SIZE, digest, signature); +} + +int +dsa_sha256_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + struct sha256_ctx *hash, + struct dsa_signature *signature) +{ + uint8_t digest[SHA256_DIGEST_SIZE]; + sha256_digest(hash, sizeof(digest), digest); + + return _dsa_sign(pub, key, random_ctx, random, + sizeof(digest), digest, signature); +} diff --git a/dsa-sha256-verify.c b/dsa-sha256-verify.c new file mode 100644 index 0000000000000000000000000000000000000000..ed79a86e27ab58b3451b171432f02b729a240adf --- /dev/null +++ b/dsa-sha256-verify.c @@ -0,0 +1,51 @@ +/* dsa-sha256-verify.c + * + * The DSA publickey algorithm, using SHA-256 (FIPS186-3). + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2010 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., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdlib.h> + +#include "dsa.h" + +int +dsa_sha256_verify_digest(const struct dsa_public_key *key, + const uint8_t *digest, + const struct dsa_signature *signature) +{ + return _dsa_verify(key, SHA256_DIGEST_SIZE, digest, signature); +} + +int +dsa_sha256_verify(const struct dsa_public_key *key, + struct sha256_ctx *hash, + const struct dsa_signature *signature) +{ + uint8_t digest[SHA256_DIGEST_SIZE]; + sha256_digest(hash, sizeof(digest), digest); + + return _dsa_verify(key, sizeof(digest), digest, signature); +} diff --git a/dsa-sign.c b/dsa-sign.c index a44c2ea048abae58c90ccf361f749648ab469af3..9c5a29c95858fc8aa4d980ee615003c4725c29c0 100644 --- a/dsa-sign.c +++ b/dsa-sign.c @@ -5,7 +5,7 @@ /* nettle, low-level cryptographics library * - * Copyright (C) 2002 Niels M�ller + * Copyright (C) 2002, 2010 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 @@ -27,6 +27,7 @@ # include "config.h" #endif +#include <assert.h> #include <stdlib.h> #include "dsa.h" @@ -34,17 +35,25 @@ #include "bignum.h" -void -dsa_sign_digest(const struct dsa_public_key *pub, - const struct dsa_private_key *key, - void *random_ctx, nettle_random_func random, - const uint8_t *digest, - struct dsa_signature *signature) +int +_dsa_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + unsigned digest_size, + const uint8_t *digest, + struct dsa_signature *signature) { 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; + /* Select k, 0<k<q, randomly */ mpz_init_set(tmp, pub->q); mpz_sub_ui(tmp, tmp, 1); @@ -59,12 +68,12 @@ dsa_sign_digest(const struct dsa_public_key *pub, /* Compute hash */ mpz_init(h); - nettle_mpz_set_str_256_u(h, SHA1_DIGEST_SIZE, digest); + nettle_mpz_set_str_256_u(h, digest_size, digest); /* Compute k^-1 (mod q) */ if (!mpz_invert(k, k, pub->q)) /* What do we do now? The key is invalid. */ - abort(); + return 0; /* Compute signature s = k^-1 (h + xr) (mod q) */ mpz_mul(tmp, signature->r, key->x); @@ -76,18 +85,6 @@ dsa_sign_digest(const struct dsa_public_key *pub, mpz_clear(k); mpz_clear(h); mpz_clear(tmp); -} - -void -dsa_sign(const struct dsa_public_key *pub, - const struct dsa_private_key *key, - void *random_ctx, nettle_random_func random, - struct sha1_ctx *hash, - struct dsa_signature *signature) -{ - uint8_t digest[SHA1_DIGEST_SIZE]; - sha1_digest(hash, sizeof(digest), digest); - dsa_sign_digest(pub, key, random_ctx, random, - digest, signature); + return 1; } diff --git a/dsa-verify.c b/dsa-verify.c index 519c4207a62dbc2686220c1058ddc8418ae4819e..faea0a000b4f1405c57d12b1e1c492d6ad98af15 100644 --- a/dsa-verify.c +++ b/dsa-verify.c @@ -34,16 +34,20 @@ #include "bignum.h" int -dsa_verify_digest(const struct dsa_public_key *key, - const uint8_t *digest, - const struct dsa_signature *signature) +_dsa_verify(const struct dsa_public_key *key, + unsigned digest_size, + const uint8_t *digest, + const struct dsa_signature *signature) { mpz_t w; mpz_t tmp; mpz_t v; 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; @@ -67,7 +71,7 @@ dsa_verify_digest(const struct dsa_public_key *key, mpz_init(v); /* The message digest */ - nettle_mpz_set_str_256_u(tmp, SHA1_DIGEST_SIZE, digest); + nettle_mpz_set_str_256_u(tmp, digest_size, digest); /* v = g^{w * h (mod q)} (mod p) */ mpz_mul(tmp, tmp, w); @@ -95,14 +99,3 @@ dsa_verify_digest(const struct dsa_public_key *key, return res; } - -int -dsa_verify(const struct dsa_public_key *key, - struct sha1_ctx *hash, - const struct dsa_signature *signature) -{ - uint8_t digest[SHA1_DIGEST_SIZE]; - sha1_digest(hash, sizeof(digest), digest); - - return dsa_verify_digest(key, digest, signature); -} diff --git a/dsa.h b/dsa.h index 32f691deb3f00b2810953d7aed6206cdb0c45df7..c98fb12b51c48796b18df96583b0c0f7124cd9a6 100644 --- a/dsa.h +++ b/dsa.h @@ -46,10 +46,14 @@ extern "C" { #define dsa_private_key_clear nettle_dsa_private_key_clear #define dsa_signature_init nettle_dsa_signature_init #define dsa_signature_clear nettle_dsa_signature_clear -#define dsa_sign nettle_dsa_sign -#define dsa_verify nettle_dsa_verify -#define dsa_sign_digest nettle_dsa_sign_digest -#define dsa_verify_digest nettle_dsa_verify_digest +#define dsa_sha1_sign nettle_dsa_sha1_sign +#define dsa_sha1_verify nettle_dsa_sha1_verify +#define dsa_sha256_sign nettle_dsa_sha256_sign +#define dsa_sha256_verify nettle_dsa_sha256_verify +#define dsa_sha1_sign_digest nettle_dsa_sha1_sign_digest +#define dsa_sha1_verify_digest nettle_dsa_sha1_verify_digest +#define dsa_sha256_sign_digest nettle_dsa_sha256_sign_digest +#define dsa_sha256_verify_digest nettle_dsa_sha256_verify_digest #define dsa_generate_keypair nettle_dsa_generate_keypair #define dsa_signature_from_sexp nettle_dsa_signature_from_sexp #define dsa_keypair_to_sexp nettle_dsa_keypair_to_sexp @@ -59,6 +63,8 @@ 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_sign _nettle_dsa_sign +#define _dsa_verify _nettle_dsa_verify #define DSA_MIN_P_BITS 512 #define DSA_Q_OCTETS 20 @@ -138,31 +144,53 @@ void dsa_signature_clear(struct dsa_signature *signature); -void -dsa_sign(const struct dsa_public_key *pub, - const struct dsa_private_key *key, - void *random_ctx, nettle_random_func random, - struct sha1_ctx *hash, - struct dsa_signature *signature); - - int -dsa_verify(const struct dsa_public_key *key, - struct sha1_ctx *hash, - const struct dsa_signature *signature); +dsa_sha1_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + struct sha1_ctx *hash, + struct dsa_signature *signature); -void -dsa_sign_digest(const struct dsa_public_key *pub, +int +dsa_sha256_sign(const struct dsa_public_key *pub, const struct dsa_private_key *key, void *random_ctx, nettle_random_func random, - const uint8_t *digest, + struct sha256_ctx *hash, struct dsa_signature *signature); int -dsa_verify_digest(const struct dsa_public_key *key, - const uint8_t *digest, +dsa_sha1_verify(const struct dsa_public_key *key, + struct sha1_ctx *hash, + const struct dsa_signature *signature); + +int +dsa_sha256_verify(const struct dsa_public_key *key, + struct sha256_ctx *hash, const struct dsa_signature *signature); +int +dsa_sha1_sign_digest(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + const uint8_t *digest, + struct dsa_signature *signature); +int +dsa_sha256_sign_digest(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + const uint8_t *digest, + struct dsa_signature *signature); + +int +dsa_sha1_verify_digest(const struct dsa_public_key *key, + const uint8_t *digest, + const struct dsa_signature *signature); + +int +dsa_sha256_verify_digest(const struct dsa_public_key *key, + const uint8_t *digest, + const struct dsa_signature *signature); + /* Key generation */ int @@ -235,6 +263,21 @@ dsa_openssl_private_key_from_der(struct dsa_public_key *pub, unsigned length, const uint8_t *data); +/* Internal functions. */ +int +_dsa_sign(const struct dsa_public_key *pub, + const struct dsa_private_key *key, + void *random_ctx, nettle_random_func random, + unsigned digest_size, + const uint8_t *digest, + struct dsa_signature *signature); + +int +_dsa_verify(const struct dsa_public_key *key, + unsigned digest_size, + const uint8_t *digest, + const struct dsa_signature *signature); + #ifdef __cplusplus } #endif