From ffc437e018fdf7cdec54dbbd83c0ace503c33071 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Niels=20M=C3=B6ller?= Date: Sat, 4 Jan 2014 16:48:36 +0100 Subject: [PATCH] Use a separate struct dsa_params with the dsa functions. --- ChangeLog | 29 +++++++++ dsa-sha1-sign.c | 12 ++-- dsa-sha1-verify.c | 6 +- dsa-sha256-sign.c | 10 ++-- dsa-sha256-verify.c | 6 +- dsa-sign.c | 40 ++++++++----- dsa-verify.c | 34 +++++++---- dsa.c | 37 ++++++++++-- dsa.h | 134 +++++++++++++++++++++++++++++++----------- testsuite/testutils.c | 17 ++++-- 10 files changed, 242 insertions(+), 83 deletions(-) diff --git a/ChangeLog b/ChangeLog index f50ef031..916ce5d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2014-01-04 Niels Möller + + * testsuite/testutils.c (test_dsa_sign): #if:ed out, unused. + (test_dsa_verify): Use _dsa_verify. + + * dsa-verify.c (_dsa_verify): New function, with a struct + dsa_params * as a separate argument. + (dsa_verify): Use _dsa_verify. + * dsa-sha1-verify.c (dsa_sha1_verify_digest, dsa_sha1_verify): Use + _dsa_verify. + * dsa-sha256-verify.c (dsa_sha256_verify_digest) + (dsa_sha256_verify): Likewise. + + * dsa-sign.c (_dsa_sign): New function, with struct dsa_params * + as a separate argument. + (dsa_sign): Use _dsa_sign. + * dsa-sha1-sign.c (dsa_sha1_sign_digest, dsa_sha1_sign): Use + _dsa_sign, cast the struct dsa_public_key * input to a struct + dsa_params *. + * dsa-sha256-sign.c (dsa_sha256_sign_digest, dsa_sha256_sign): + Likewise. + + * dsa.c (dsa_params_init, dsa_params_clear): New functions. + (dsa_value_init, dsa_value_clear): New functions. + (dsa_public_key_init): Use dsa_params_init. + (dsa_public_key_clear): Use dsa_params_clear. + + * dsa.h (dsa_params, dsa_value): New structs. + 2014-01-03 Niels Möller * shadata.c (main): Zero-pad output values to 8 hex digits. diff --git a/dsa-sha1-sign.c b/dsa-sha1-sign.c index db820576..28843889 100644 --- a/dsa-sha1-sign.c +++ b/dsa-sha1-sign.c @@ -36,8 +36,9 @@ dsa_sha1_sign_digest(const struct dsa_public_key *pub, const uint8_t *digest, struct dsa_signature *signature) { - return dsa_sign(pub, key, random_ctx, random, - SHA1_DIGEST_SIZE, digest, signature); + return _dsa_sign((const struct dsa_params *) pub, key->x, + random_ctx, random, + SHA1_DIGEST_SIZE, digest, signature); } @@ -50,7 +51,8 @@ dsa_sha1_sign(const struct dsa_public_key *pub, { uint8_t digest[SHA1_DIGEST_SIZE]; sha1_digest(hash, sizeof(digest), digest); - - return dsa_sign(pub, key, random_ctx, random, - sizeof(digest), digest, signature); + + return _dsa_sign((const struct dsa_params *) pub, key->x, + random_ctx, random, + sizeof(digest), digest, signature); } diff --git a/dsa-sha1-verify.c b/dsa-sha1-verify.c index 76de5820..f6767a85 100644 --- a/dsa-sha1-verify.c +++ b/dsa-sha1-verify.c @@ -36,7 +36,8 @@ 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); + return _dsa_verify((const struct dsa_params *) key, key->y, + SHA1_DIGEST_SIZE, digest, signature); } int @@ -47,5 +48,6 @@ dsa_sha1_verify(const struct dsa_public_key *key, uint8_t digest[SHA1_DIGEST_SIZE]; sha1_digest(hash, sizeof(digest), digest); - return dsa_verify(key, sizeof(digest), digest, signature); + return _dsa_verify((const struct dsa_params *) key, key->y, + sizeof(digest), digest, signature); } diff --git a/dsa-sha256-sign.c b/dsa-sha256-sign.c index 68f66d01..56f5d2f7 100644 --- a/dsa-sha256-sign.c +++ b/dsa-sha256-sign.c @@ -36,8 +36,9 @@ dsa_sha256_sign_digest(const struct dsa_public_key *pub, const uint8_t *digest, struct dsa_signature *signature) { - return dsa_sign(pub, key, random_ctx, random, - SHA256_DIGEST_SIZE, digest, signature); + return _dsa_sign((const struct dsa_params *) pub, key->x, + random_ctx, random, + SHA256_DIGEST_SIZE, digest, signature); } int @@ -50,6 +51,7 @@ dsa_sha256_sign(const struct dsa_public_key *pub, uint8_t digest[SHA256_DIGEST_SIZE]; sha256_digest(hash, sizeof(digest), digest); - return dsa_sign(pub, key, random_ctx, random, - sizeof(digest), digest, signature); + return _dsa_sign((const struct dsa_params *) pub, key->x, + random_ctx, random, + sizeof(digest), digest, signature); } diff --git a/dsa-sha256-verify.c b/dsa-sha256-verify.c index d7d7aff6..231e5ae5 100644 --- a/dsa-sha256-verify.c +++ b/dsa-sha256-verify.c @@ -36,7 +36,8 @@ 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); + return _dsa_verify((const struct dsa_params *) key, key->y, + SHA256_DIGEST_SIZE, digest, signature); } int @@ -47,5 +48,6 @@ dsa_sha256_verify(const struct dsa_public_key *key, uint8_t digest[SHA256_DIGEST_SIZE]; sha256_digest(hash, sizeof(digest), digest); - return dsa_verify(key, sizeof(digest), digest, signature); + return _dsa_verify((const struct dsa_params *) key, key->y, + sizeof(digest), digest, signature); } diff --git a/dsa-sign.c b/dsa-sign.c index 4902baba..ba54ea0a 100644 --- a/dsa-sign.c +++ b/dsa-sign.c @@ -36,12 +36,12 @@ int -dsa_sign(const struct dsa_public_key *pub, - const struct dsa_private_key *key, - void *random_ctx, nettle_random_func *random, - size_t digest_size, - const uint8_t *digest, - struct dsa_signature *signature) +_dsa_sign(const struct dsa_params *params, + const mpz_t key, + void *random_ctx, nettle_random_func *random, + size_t digest_size, + const uint8_t *digest, + struct dsa_signature *signature) { mpz_t k; mpz_t h; @@ -49,7 +49,7 @@ dsa_sign(const struct dsa_public_key *pub, int res; /* Select k, 0q); + mpz_init_set(tmp, params->q); mpz_sub_ui(tmp, tmp, 1); mpz_init(k); @@ -57,22 +57,22 @@ dsa_sign(const struct dsa_public_key *pub, mpz_add_ui(k, k, 1); /* Compute r = (g^k (mod p)) (mod q) */ - mpz_powm(tmp, pub->g, k, pub->p); - mpz_fdiv_r(signature->r, tmp, pub->q); + mpz_powm(tmp, params->g, k, params->p); + mpz_fdiv_r(signature->r, tmp, params->q); /* Compute hash */ mpz_init(h); - _dsa_hash (h, mpz_sizeinbase(pub->q, 2), digest_size, digest); + _dsa_hash (h, mpz_sizeinbase(params->q, 2), digest_size, digest); /* Compute k^-1 (mod q) */ - if (mpz_invert(k, k, pub->q)) + if (mpz_invert(k, k, params->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_mul(tmp, signature->r, key); + mpz_fdiv_r(tmp, tmp, params->q); mpz_add(tmp, tmp, h); mpz_mul(tmp, tmp, k); - mpz_fdiv_r(signature->s, tmp, pub->q); + mpz_fdiv_r(signature->s, tmp, params->q); res = 1; } else @@ -85,3 +85,15 @@ dsa_sign(const struct dsa_public_key *pub, return res; } + +int +dsa_sign(const struct dsa_value *key, + void *random_ctx, nettle_random_func *random, + size_t digest_size, + const uint8_t *digest, + struct dsa_signature *signature) +{ + return _dsa_sign (key->params, key->x, + random_ctx, random, + digest_size, digest, signature); +} diff --git a/dsa-verify.c b/dsa-verify.c index b6d5a7ae..e56ed661 100644 --- a/dsa-verify.c +++ b/dsa-verify.c @@ -34,7 +34,8 @@ #include "bignum.h" int -dsa_verify(const struct dsa_public_key *key, +_dsa_verify(const struct dsa_params *params, + const mpz_t key, size_t digest_size, const uint8_t *digest, const struct dsa_signature *signature) @@ -46,10 +47,10 @@ dsa_verify(const struct dsa_public_key *key, int res; /* Check that r and s are in the proper range */ - if (mpz_sgn(signature->r) <= 0 || mpz_cmp(signature->r, key->q) >= 0) + if (mpz_sgn(signature->r) <= 0 || mpz_cmp(signature->r, params->q) >= 0) return 0; - if (mpz_sgn(signature->s) <= 0 || mpz_cmp(signature->s, key->q) >= 0) + if (mpz_sgn(signature->s) <= 0 || mpz_cmp(signature->s, params->q) >= 0) return 0; mpz_init(w); @@ -58,7 +59,7 @@ dsa_verify(const struct dsa_public_key *key, /* NOTE: In gmp-2, mpz_invert sometimes generates negative inverses, * so we need gmp-3 or better. */ - if (!mpz_invert(w, signature->s, key->q)) + if (!mpz_invert(w, signature->s, params->q)) { mpz_clear(w); return 0; @@ -68,25 +69,25 @@ dsa_verify(const struct dsa_public_key *key, mpz_init(v); /* The message digest */ - _dsa_hash (tmp, mpz_sizeinbase (key->q, 2), digest_size, digest); + _dsa_hash (tmp, mpz_sizeinbase (params->q, 2), digest_size, digest); /* v = g^{w * h (mod q)} (mod p) */ mpz_mul(tmp, tmp, w); - mpz_fdiv_r(tmp, tmp, key->q); + mpz_fdiv_r(tmp, tmp, params->q); - mpz_powm(v, key->g, tmp, key->p); + mpz_powm(v, params->g, tmp, params->p); /* y^{w * r (mod q) } (mod p) */ mpz_mul(tmp, signature->r, w); - mpz_fdiv_r(tmp, tmp, key->q); + mpz_fdiv_r(tmp, tmp, params->q); - mpz_powm(tmp, key->y, tmp, key->p); + mpz_powm(tmp, key, tmp, params->p); /* v = (g^{w * h} * y^{w * r} (mod p) ) (mod q) */ mpz_mul(v, v, tmp); - mpz_fdiv_r(v, v, key->p); + mpz_fdiv_r(v, v, params->p); - mpz_fdiv_r(v, v, key->q); + mpz_fdiv_r(v, v, params->q); res = !mpz_cmp(v, signature->r); @@ -96,3 +97,14 @@ dsa_verify(const struct dsa_public_key *key, return res; } + +int +dsa_verify(const struct dsa_value *pub, + size_t digest_size, + const uint8_t *digest, + const struct dsa_signature *signature) +{ + return _dsa_verify (pub->params, pub->x, + digest_size, digest, + signature); +} diff --git a/dsa.c b/dsa.c index 0d241b79..fc574ff9 100644 --- a/dsa.c +++ b/dsa.c @@ -31,21 +31,46 @@ #include "bignum.h" +void +dsa_params_init (struct dsa_params *params) +{ + mpz_init(params->p); + mpz_init(params->q); + mpz_init(params->g); +} + +void +dsa_params_clear (struct dsa_params *params) +{ + mpz_clear(params->p); + mpz_clear(params->q); + mpz_clear(params->g); +} + +void +dsa_value_init (struct dsa_value *value, const struct dsa_params *params) +{ + value->params = params; + mpz_init (value->x); +} + +void +dsa_value_clear (struct dsa_value *value) +{ + mpz_clear (value->x); +} + void dsa_public_key_init(struct dsa_public_key *key) { - mpz_init(key->p); - mpz_init(key->q); - mpz_init(key->g); + dsa_params_init ((struct dsa_params *) key); mpz_init(key->y); } void dsa_public_key_clear(struct dsa_public_key *key) { - mpz_clear(key->p); - mpz_clear(key->q); - mpz_clear(key->g); + dsa_params_clear ((struct dsa_params *) key); mpz_clear(key->y); } diff --git a/dsa.h b/dsa.h index bcd07741..a5433f2c 100644 --- a/dsa.h +++ b/dsa.h @@ -38,6 +38,10 @@ extern "C" { #endif /* Name mangling */ +#define dsa_params_init nettle_dsa_params_init +#define dsa_params_clear nettle_dsa_params_clear +#define dsa_value_init nettle_dsa_value_init +#define dsa_value_clear nettle_dsa_value_clear #define dsa_public_key_init nettle_dsa_public_key_init #define dsa_public_key_clear nettle_dsa_public_key_clear #define dsa_private_key_init nettle_dsa_private_key_init @@ -50,6 +54,8 @@ extern "C" { #define dsa_sha256_verify nettle_dsa_sha256_verify #define dsa_sign nettle_dsa_sign #define dsa_verify nettle_dsa_verify +#define _dsa_sign _nettle_dsa_sign +#define _dsa_verify _nettle_dsa_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 @@ -66,6 +72,7 @@ extern "C" { #define dsa_openssl_private_key_from_der nettle_openssl_provate_key_from_der #define _dsa_hash _nettle_dsa_hash +/* For FIPS approved parameters */ #define DSA_SHA1_MIN_P_BITS 512 #define DSA_SHA1_Q_OCTETS 20 #define DSA_SHA1_Q_BITS 160 @@ -73,8 +80,9 @@ extern "C" { #define DSA_SHA256_MIN_P_BITS 1024 #define DSA_SHA256_Q_OCTETS 32 #define DSA_SHA256_Q_BITS 256 - -struct dsa_public_key + +/* Tentative new DSA interface */ +struct dsa_params { /* Modulo */ mpz_t p; @@ -84,7 +92,83 @@ struct dsa_public_key /* Generator */ mpz_t g; +}; + +struct dsa_signature +{ + mpz_t r; + mpz_t s; +}; + +struct dsa_value +{ + const struct dsa_params *params; + /* For private keys, represents an exponent (0 < x < q). For public + keys, represents a group element, 0 < x < p) */ + mpz_t x; +}; + +void +dsa_params_init (struct dsa_params *params); + +void +dsa_params_clear (struct dsa_params *params); + +void +dsa_value_init (struct dsa_value *value, const struct dsa_params *params); + +void +dsa_value_clear (struct dsa_value *value); + +/* Calls mpz_init to initialize bignum storage. */ +void +dsa_signature_init(struct dsa_signature *signature); + +/* Calls mpz_clear to deallocate bignum storage. */ +void +dsa_signature_clear(struct dsa_signature *signature); + +int +dsa_sign(const struct dsa_value *key, + void *random_ctx, nettle_random_func *random, + size_t digest_size, + const uint8_t *digest, + struct dsa_signature *signature); + +int +dsa_verify(const struct dsa_value *pub, + size_t digest_size, + const uint8_t *digest, + const struct dsa_signature *signature); + +void +dsa_generate_params (struct dsa_params *params, + + void *random_ctx, nettle_random_func *random, + + void *progress_ctx, nettle_progress_func *progress, + unsigned p_bits, unsigned q_bits); + +#if 0 +int +dsa_generate_keypair (struct dsa_value *pub, + struct dsa_value *key, + + void *random_ctx, nettle_random_func *random); +#endif + +/* Old nettle interface, kept for backwards compatibility */ +struct dsa_public_key +{ + /* Same as struct dsa_params, but can't use that struct here without + breaking backwards compatibility. Layout must be identical, since + this is cast to a struct dsa_param pointer for calling _dsa_sign + and _dsa_verify */ + mpz_t p; + mpz_t q; + mpz_t g; + /* Public value */ mpz_t y; }; @@ -96,12 +180,6 @@ struct dsa_private_key mpz_t x; }; -struct dsa_signature -{ - mpz_t r; - mpz_t s; -}; - /* Signing a message works as follows: * * Store the private key in a dsa_private_key struct. @@ -139,15 +217,6 @@ dsa_private_key_init(struct dsa_private_key *key); void dsa_private_key_clear(struct dsa_private_key *key); -/* Calls mpz_init to initialize bignum storage. */ -void -dsa_signature_init(struct dsa_signature *signature); - -/* Calls mpz_clear to deallocate bignum storage. */ -void -dsa_signature_clear(struct dsa_signature *signature); - - int dsa_sha1_sign(const struct dsa_public_key *pub, const struct dsa_private_key *key, @@ -173,22 +242,6 @@ dsa_sha256_verify(const struct dsa_public_key *key, const 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, - size_t digest_size, - const uint8_t *digest, - struct dsa_signature *signature); - -int -dsa_verify(const struct dsa_public_key *key, - size_t digest_size, - const uint8_t *digest, - const struct dsa_signature *signature); - -/* Maybe obsolete these functions? One can just as well call dsa_sign - and dsa_verify directly, all that matters is the digest size. */ -int dsa_sha1_sign_digest(const struct dsa_public_key *pub, const struct dsa_private_key *key, void *random_ctx, nettle_random_func *random, @@ -293,6 +346,21 @@ void _dsa_hash (mpz_t h, unsigned bit_size, size_t length, const uint8_t *digest); +int +_dsa_sign(const struct dsa_params *params, + const mpz_t key, + void *random_ctx, nettle_random_func *random, + size_t digest_size, + const uint8_t *digest, + struct dsa_signature *signature); + +int +_dsa_verify(const struct dsa_params *params, + const mpz_t pub, + size_t digest_size, + const uint8_t *digest, + const struct dsa_signature *signature); + #ifdef __cplusplus } #endif diff --git a/testsuite/testutils.c b/testsuite/testutils.c index a4829c54..09e49a45 100644 --- a/testsuite/testutils.c +++ b/testsuite/testutils.c @@ -1102,6 +1102,7 @@ test_dsa256(const struct dsa_public_key *pub, dsa_signature_clear(&signature); } +#if 0 void test_dsa_sign(const struct dsa_public_key *pub, const struct dsa_private_key *key, @@ -1158,6 +1159,7 @@ test_dsa_sign(const struct dsa_public_key *pub, free (bad_digest); dsa_signature_clear(&signature); } +#endif void test_dsa_verify(const struct dsa_public_key *pub, @@ -1179,18 +1181,21 @@ test_dsa_verify(const struct dsa_public_key *pub, mpz_set (signature.r, ref->r); mpz_set (signature.s, ref->s); - ASSERT (dsa_verify (pub, hash->digest_size, digest, - &signature)); + ASSERT (_dsa_verify ((struct dsa_params *) pub, pub->y, + hash->digest_size, digest, + &signature)); /* Try bad signature */ mpz_combit(signature.r, 17); - ASSERT (!dsa_verify (pub, hash->digest_size, digest, - &signature)); + ASSERT (!_dsa_verify ((struct dsa_params *) pub, pub->y, + hash->digest_size, digest, + &signature)); /* Try bad data */ digest[hash->digest_size / 2-1] ^= 8; - ASSERT (!dsa_verify (pub, hash->digest_size, digest, - ref)); + ASSERT (!_dsa_verify ((struct dsa_params *) pub, pub->y, + hash->digest_size, digest, + ref)); free (ctx); free (digest); -- 2.47.2