--- Hi,
I tried to update the Nettle DSA function calls so LSH can be built with Nettle 3. The main issue seemed to be that DSA's x and y variables were removed from structs and use mpz_t types now.
The following patch against the master branch just switches to the new API and requires Nettle 3 (as did e.g. GnuTLS) instead of trying to keep compatiblity with both APIs.
Can something like this be applied to the LSH repo to support Nettle 3?
Thanks.
David
configure.ac | 4 +- spki/verify.c | 26 +++++++----- src/crypto.c | 2 +- src/dsa.c | 120 ++++++++++++++++++++++++++++--------------------------- src/lsh-keygen.c | 54 ++++++++++++++----------- 5 files changed, 111 insertions(+), 95 deletions(-)
diff --git a/configure.ac b/configure.ac index a42d4ad..b12c37e 100644 --- a/configure.ac +++ b/configure.ac @@ -422,9 +422,9 @@ AC_CHECK_LIB(gmp, __gmpz_getlimbn,,
LSH_RPATH_FIX
-AC_CHECK_LIB(hogweed, nettle_dsa_sha1_sign, [true], +AC_CHECK_LIB(hogweed, nettle_dsa_params_init, [true], [AC_MSG_ERROR( - [Nettle library not found; needs version 2.2 or later. See http://www.lysator.liu.se/~nisse/nettle/.])], [-lnettle -lgmp]) + [Nettle library not found; needs version 3.0 or later. See http://www.lysator.liu.se/~nisse/nettle/.])], [-lnettle -lgmp])
LSH_RPATH_FIX
diff --git a/spki/verify.c b/spki/verify.c index 6f16a9d..0984ca7 100644 --- a/spki/verify.c +++ b/spki/verify.c @@ -70,22 +70,25 @@ spki_verify_dsa_sha1(const uint8_t *digest, struct spki_iterator *key, struct spki_iterator *signature) { - struct dsa_public_key dsa; + struct dsa_params dsa; struct dsa_signature rs; + mpz_t pub; int res;
- dsa_public_key_init(&dsa); + dsa_params_init(&dsa); dsa_signature_init(&rs); + mpz_init(pub);
- res = (dsa_keypair_from_sexp_alist(&dsa, NULL, + res = (dsa_keypair_from_sexp_alist(&dsa, pub, NULL, DSA_SHA1_KEYSIZE_LIMIT, DSA_SHA1_Q_BITS, &key->sexp) && spki_parse_end(key) && dsa_signature_from_sexp(&rs, &signature->sexp, DSA_SHA1_Q_BITS) - && dsa_sha1_verify_digest(&dsa, digest, &rs)); + && dsa_verify(&dsa, pub, SHA1_DIGEST_SIZE, digest, &rs));
+ mpz_clear(pub); dsa_signature_clear(&rs); - dsa_public_key_clear(&dsa); + dsa_params_clear(&dsa);
return res; } @@ -95,23 +98,26 @@ spki_verify_dsa_sha256(const uint8_t *digest, struct spki_iterator *key, struct spki_iterator *signature) { - struct dsa_public_key dsa; + struct dsa_params dsa; struct dsa_signature rs; + mpz_t pub; int res;
- dsa_public_key_init(&dsa); + dsa_params_init(&dsa); dsa_signature_init(&rs); + mpz_init(pub);
- res = (dsa_keypair_from_sexp_alist(&dsa, NULL, + res = (dsa_keypair_from_sexp_alist(&dsa, pub, NULL, DSA_SHA256_KEYSIZE_LIMIT, DSA_SHA256_Q_BITS, &key->sexp) && spki_parse_end(key) && dsa_signature_from_sexp(&rs, &signature->sexp, DSA_SHA256_Q_BITS) - && dsa_sha256_verify_digest(&dsa, digest, &rs)); + && dsa_verify(&dsa, pub, SHA256_DIGEST_SIZE, digest, &rs));
+ mpz_clear(pub); dsa_signature_clear(&rs); - dsa_public_key_clear(&dsa); + dsa_params_clear(&dsa);
return res; } diff --git a/src/crypto.c b/src/crypto.c index c9aef66..6a7c774 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -366,7 +366,7 @@ make_cast128_cbc_instance(struct crypto_algorithm *algorithm, int mode, ? do_cast128_encrypt : do_cast128_decrypt);
- cast128_set_key(&self->ctx.ctx, algorithm->key_size, key); + cast5_set_key(&self->ctx.ctx, algorithm->key_size, key); CBC_SET_IV(&self->ctx, iv);
return(&self->super); diff --git a/src/dsa.c b/src/dsa.c index 230698d..21e0c6c 100644 --- a/src/dsa.c +++ b/src/dsa.c @@ -64,8 +64,8 @@ (name dsa_verifier) (super verifier) (vars - (key indirect-special "struct dsa_public_key" - #f dsa_public_key_clear))) + (params indirect-special "struct dsa_params" #f dsa_params_clear) + (public bignum))) */
/* GABA: @@ -74,8 +74,7 @@ (super signer) (vars (verifier object dsa_verifier) - (key indirect-special "struct dsa_private_key" - #f dsa_private_key_clear))) + (private bignum))) */
static int @@ -148,8 +147,8 @@ do_dsa_verify(struct verifier *c, int algorithm,
sha1_init(&hash); sha1_update(&hash, length, msg); - - res = dsa_sha1_verify(&self->key, &hash, &sv); + + res = dsa_verify(&self->params, self->public, SHA1_DIGEST_SIZE, &hash, &sv); fail:
dsa_signature_clear(&sv); @@ -164,8 +163,8 @@ do_dsa_public_key(struct verifier *s) CAST(dsa_verifier, self, s); return ssh_format("%a%n%n%n%n", ATOM_SSH_DSS, - self->key.p, self->key.q, - self->key.g, self->key.y); + self->params.p, self->params.q, + self->params.g, self->public); }
/* FIXME: Should maybe switch to the name "dsa-sha1". Not sure what we @@ -179,16 +178,17 @@ do_dsa_public_spki_key(struct verifier *s, int transport) return lsh_string_format_sexp(transport, "(%0s(%0s(%0s%b)(%0s%b)(%0s%b)(%0s%b)))", "public-key", "dsa", - "p", self->key.p, - "q", self->key.q, - "g", self->key.g, - "y", self->key.y); + "p", self->params.p, + "q", self->params.q, + "g", self->params.g, + "y", self->public); }
static void init_dsa_verifier(struct dsa_verifier *self) { - dsa_public_key_init(&self->key); + dsa_params_init(&self->params); + mpz_init(self->public);
self->super.verify = do_dsa_verify; self->super.public_spki_key = do_dsa_public_spki_key; @@ -204,18 +204,18 @@ parse_ssh_dss_public(struct simple_buffer *buffer) NEW(dsa_verifier, res); init_dsa_verifier(res);
- if (parse_bignum(buffer, res->key.p, DSA_SHA1_MAX_OCTETS) - && (mpz_sgn(res->key.p) == 1) - && parse_bignum(buffer, res->key.q, DSA_SHA1_Q_OCTETS) - && (mpz_sgn(res->key.q) == 1) - && mpz_sizeinbase(res->key.q, 2) == DSA_SHA1_Q_BITS - && (mpz_cmp(res->key.q, res->key.p) < 0) /* q < p */ - && parse_bignum(buffer, res->key.g, DSA_SHA1_MAX_OCTETS) - && (mpz_sgn(res->key.g) == 1) - && (mpz_cmp(res->key.g, res->key.p) < 0) /* g < p */ - && parse_bignum(buffer, res->key.y, DSA_SHA1_MAX_OCTETS) - && (mpz_sgn(res->key.y) == 1) - && (mpz_cmp(res->key.y, res->key.p) < 0) /* y < p */ + if (parse_bignum(buffer, res->params.p, DSA_SHA1_MAX_OCTETS) + && (mpz_sgn(res->params.p) == 1) + && parse_bignum(buffer, res->params.q, DSA_SHA1_Q_OCTETS) + && (mpz_sgn(res->params.q) == 1) + && mpz_sizeinbase(res->params.q, 2) == DSA_SHA1_Q_BITS + && (mpz_cmp(res->params.q, res->params.p) < 0) /* q < p */ + && parse_bignum(buffer, res->params.g, DSA_SHA1_MAX_OCTETS) + && (mpz_sgn(res->params.g) == 1) + && (mpz_cmp(res->params.g, res->params.p) < 0) /* g < p */ + && parse_bignum(buffer, res->public, DSA_SHA1_MAX_OCTETS) + && (mpz_sgn(res->public) == 1) + && (mpz_cmp(res->public, res->params.p) < 0) /* y < p */ && parse_eod(buffer))
return &res->super; @@ -257,8 +257,8 @@ do_dsa_sign(struct signer *c, sha1_init(&hash); sha1_update(&hash, msg_length, msg);
- if (dsa_sha1_sign(&self->verifier->key, &self->key, - NULL, lsh_random, &hash, &sv)) + if (dsa_sign(&self->verifier->params, self->private, + NULL, lsh_random, SHA1_DIGEST_SIZE, &hash, &sv)) /* Build signature */ switch (algorithm) { @@ -310,7 +310,7 @@ make_dsa_verifier(struct signature_algorithm *self UNUSED, NEW(dsa_verifier, res); init_dsa_verifier(res);
- if (dsa_keypair_from_sexp_alist(&res->key, NULL, + if (dsa_keypair_from_sexp_alist(&res->params, res->public, NULL, DSA_SHA1_MAX_BITS, DSA_SHA1_Q_BITS, i)) return &res->super; @@ -327,10 +327,11 @@ make_dsa_signer(struct signature_algorithm *self UNUSED, NEW(dsa_signer, res);
init_dsa_verifier(verifier); - - dsa_private_key_init(&res->key);
- if (dsa_keypair_from_sexp_alist(&verifier->key, &res->key, + mpz_init(res->private); + + if (dsa_keypair_from_sexp_alist(&verifier->params, + verifier->public, res->private, DSA_SHA1_MAX_BITS, DSA_SHA1_Q_BITS, i)) { @@ -411,8 +412,9 @@ do_dsa_sha256_verify(struct verifier *c, int algorithm,
sha256_init(&hash); sha256_update(&hash, length, msg); - - res = dsa_sha256_verify(&self->key, &hash, &sv); + + res = dsa_verify(&self->params, self->public, + SHA256_DIGEST_SIZE, &hash, &sv); fail:
dsa_signature_clear(&sv); @@ -427,8 +429,8 @@ do_dsa_sha256_public_key(struct verifier *s) CAST(dsa_verifier, self, s); return ssh_format("%a%n%n%n%n", ATOM_SSH_DSA, - self->key.p, self->key.q, - self->key.g, self->key.y); + self->params.p, self->params.q, + self->params.g, self->public); }
static struct lsh_string * @@ -439,16 +441,17 @@ do_dsa_sha256_public_spki_key(struct verifier *s, int transport) return lsh_string_format_sexp(transport, "(%0s(%0s(%0s%b)(%0s%b)(%0s%b)(%0s%b)))", "public-key", "dsa-sha256", - "p", self->key.p, - "q", self->key.q, - "g", self->key.g, - "y", self->key.y); + "p", self->params.p, + "q", self->params.q, + "g", self->params.g, + "y", self->public); }
static void init_dsa_sha256_verifier(struct dsa_verifier *self) { - dsa_public_key_init(&self->key); + dsa_params_init(&self->params); + mpz_init(self->public);
self->super.verify = do_dsa_sha256_verify; self->super.public_spki_key = do_dsa_sha256_public_spki_key; @@ -464,18 +467,18 @@ parse_ssh_dsa_sha256_public(struct simple_buffer *buffer) NEW(dsa_verifier, res); init_dsa_verifier(res);
- if (parse_bignum(buffer, res->key.p, DSA_SHA256_MAX_OCTETS) - && (mpz_sgn(res->key.p) == 1) - && parse_bignum(buffer, res->key.q, DSA_SHA256_Q_OCTETS) - && (mpz_sgn(res->key.q) == 1) - && mpz_sizeinbase(res->key.q, 2) == DSA_SHA256_Q_BITS - && (mpz_cmp(res->key.q, res->key.p) < 0) /* q < p */ - && parse_bignum(buffer, res->key.g, DSA_SHA256_MAX_OCTETS) - && (mpz_sgn(res->key.g) == 1) - && (mpz_cmp(res->key.g, res->key.p) < 0) /* g < p */ - && parse_bignum(buffer, res->key.y, DSA_SHA256_MAX_OCTETS) - && (mpz_sgn(res->key.y) == 1) - && (mpz_cmp(res->key.y, res->key.p) < 0) /* y < p */ + if (parse_bignum(buffer, res->params.p, DSA_SHA256_MAX_OCTETS) + && (mpz_sgn(res->params.p) == 1) + && parse_bignum(buffer, res->params.q, DSA_SHA256_Q_OCTETS) + && (mpz_sgn(res->params.q) == 1) + && mpz_sizeinbase(res->params.q, 2) == DSA_SHA256_Q_BITS + && (mpz_cmp(res->params.q, res->params.p) < 0) /* q < p */ + && parse_bignum(buffer, res->params.g, DSA_SHA256_MAX_OCTETS) + && (mpz_sgn(res->params.g) == 1) + && (mpz_cmp(res->params.g, res->params.p) < 0) /* g < p */ + && parse_bignum(buffer, res->public, DSA_SHA256_MAX_OCTETS) + && (mpz_sgn(res->public) == 1) + && (mpz_cmp(res->public, res->params.p) < 0) /* y < p */ && parse_eod(buffer))
return &res->super; @@ -507,8 +510,8 @@ do_dsa_sha256_sign(struct signer *c, sha256_init(&hash); sha256_update(&hash, msg_length, msg);
- if (dsa_sha256_sign(&self->verifier->key, &self->key, - NULL, lsh_random, &hash, &sv)) + if (dsa_sign(&self->verifier->params, self->private, + NULL, lsh_random, SHA256_DIGEST_SIZE, &hash, &sv)) /* Build signature */ switch (algorithm) { @@ -554,7 +557,7 @@ make_dsa_sha256_verifier(struct signature_algorithm *self UNUSED, NEW(dsa_verifier, res); init_dsa_sha256_verifier(res);
- if (dsa_keypair_from_sexp_alist(&res->key, NULL, + if (dsa_keypair_from_sexp_alist(&res->params, res->public, NULL, DSA_SHA256_MAX_BITS, DSA_SHA256_Q_BITS, i)) return &res->super; @@ -571,10 +574,11 @@ make_dsa_sha256_signer(struct signature_algorithm *self UNUSED, NEW(dsa_signer, res);
init_dsa_verifier(verifier); - - dsa_private_key_init(&res->key);
- if (dsa_keypair_from_sexp_alist(&verifier->key, &res->key, + mpz_init(&res->private); + + if (dsa_keypair_from_sexp_alist(&verifier->params, + verifier->public, res->private, DSA_SHA256_MAX_BITS, DSA_SHA256_Q_BITS, i)) { diff --git a/src/lsh-keygen.c b/src/lsh-keygen.c index a82663c..274a536 100644 --- a/src/lsh-keygen.c +++ b/src/lsh-keygen.c @@ -476,54 +476,60 @@ progress(void *ctx UNUSED, int c) static struct lsh_string * dsa_sha1_generate_key(unsigned bits) { - struct dsa_public_key public; - struct dsa_private_key private; + struct dsa_params params; + mpz_t public; + mpz_t private; struct lsh_string *key = NULL;
- dsa_public_key_init(&public); - dsa_private_key_init(&private); + dsa_params_init(¶ms); + mpz_init(public); + mpz_init(private);
- if (dsa_generate_keypair(&public, &private, - NULL, lsh_random, - NULL, progress, - bits, 160)) + if (dsa_generate_params(¶ms, + NULL, lsh_random, + NULL, progress, + bits, 160)) { + dsa_generate_keypair(¶ms, public, private, NULL, lsh_random); key = lsh_string_format_sexp(0, "(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))", - public.p, public.q, public.g, public.y, - private.x); + params.p, params.q, params.g, public, private); }
- dsa_public_key_clear(&public); - dsa_private_key_clear(&private); + dsa_params_clear(¶ms); + mpz_clear(public); + mpz_clear(private); return key; }
static struct lsh_string * dsa_sha256_generate_key(unsigned bits) { - struct dsa_public_key public; - struct dsa_private_key private; + struct dsa_params params; + mpz_t public; + mpz_t private; struct lsh_string *key = NULL;
- dsa_public_key_init(&public); - dsa_private_key_init(&private); + dsa_params_init(¶ms); + mpz_init(public); + mpz_init(private);
- if (dsa_generate_keypair(&public, &private, - NULL, lsh_random, - NULL, progress, - bits, 256)) + if (dsa_generate_params(¶ms, + NULL, lsh_random, + NULL, progress, + bits, 256)) { + dsa_generate_keypair(¶ms, public, private, NULL, lsh_random); key = lsh_string_format_sexp(0, "(private-key(dsa-sha256(p%b)(q%b)(g%b)(y%b)(x%b)))", - public.p, public.q, public.g, public.y, - private.x); + params.p, params.q, params.g, public, private); }
- dsa_public_key_clear(&public); - dsa_private_key_clear(&private); + dsa_params_clear(¶ms); + mpz_clear(public); + mpz_clear(private); return key; }
David Michael fedora.dm0@gmail.com writes:
I tried to update the Nettle DSA function calls so LSH can be built with Nettle 3. The main issue seemed to be that DSA's x and y variables were removed from structs and use mpz_t types now.
I ought to update lsh for nettle-3, but I haven't gotten around to that yet. You may want to have a look at the corresponding debian patch, https://sources.debian.net/src/lsh-utils/2.1-7/debian/patches/nettle3.patch/
For the DSA changes, one alternative is to include <nettle/dsa-compat.h>.
The following patch against the master branch just switches to the new API and requires Nettle 3 (as did e.g. GnuTLS) instead of trying to keep compatiblity with both APIs.
I agree it's probably not worth the effort to support both nettle-3.1 and older versions. (And I don't think supporting nettle-3.0 is very important either, so go for nettle-3.1).
Regards, /Niels