diff options
author | Werner Koch <wk@gnupg.org> | 2013-11-15 08:59:45 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-11-15 09:01:11 +0100 |
commit | 402aa0f94854bb00475c934be5ca6043a4632126 (patch) | |
tree | 8ecfd73ed627790d25acf9d8c4cbd1813801d0e5 /g10/pkglue.c | |
parent | kbx: Fix possible segv in kbxdump. (diff) | |
download | gnupg2-402aa0f94854bb00475c934be5ca6043a4632126.tar.xz gnupg2-402aa0f94854bb00475c934be5ca6043a4632126.zip |
gpg: Rework ECC support and add experimental support for Ed25519.
* agent/findkey.c (key_parms_from_sexp): Add algo name "ecc".
(agent_is_dsa_key): Ditto.
(agent_is_eddsa_key): New. Not finished, though.
* agent/pksign.c (do_encode_eddsa): New.
(agent_pksign_do): Use gcry_log_debug functions.
* agent/protect.c (agent_protect): Parse a flags parameter.
* g10/keygen.c (gpg_curve_to_oid): Move to ...
* common/openpgp-oid.c (openpgp_curve_to_oid): here and rename.
(oid_ed25519): New.
(openpgp_oid_is_ed25519): New.
(openpgp_oid_to_curve): New.
* common/t-openpgp-oid.c (test_openpgp_oid_is_ed25519): New.
* g10/build-packet.c (gpg_mpi_write): Write the length header also for
opaque MPIs.
(gpg_mpi_write_nohdr): New.
(do_key): Use gpg_mpi_write_nohdr depending on algorithm.
(do_pubkey_enc): Ditto.
* g10/ecdh.c (pk_ecdh_encrypt_with_shared_point): Use
gpg_mpi_write_nohdr.
* g10/export.c (transfer_format_to_openpgp):
* g10/keygen.c (ecckey_from_sexp): Return the error.
(gen_ecc): Repalce arg NBITS by CURVE.
(read_parameter_file): Add keywords "Key-Curve" and "Subkey-Curve".
(ask_curve): New.
(generate_keypair, generate_subkeypair): Use ask_curve.
(do_generate_keypair): Also pass curve name.
* g10/keylist.c (list_keyblock_print, list_keyblock_colon): Print
curve name.
* g10/parse-packet.c (mpi_read): Remove workaround for
Libcgrypt < 1.5.
(parse_key): Fix ECC case. Print the curve name.
* g10/pkglue.c (mpi_from_sexp): Rename to get_mpi_from_sexp.
(pk_verify, pk_check_secret_key): Add special case for Ed25519.
* g10/seskey.c (encode_md_value): Ditto.
* g10/sign.c (do_sign, hash_for, sign_file): Ditto.
--
Be warned that this code is subject to further changes and that the
format will very likely change before a release. There are also known
bugs and missing code.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'g10/pkglue.c')
-rw-r--r-- | g10/pkglue.c | 77 |
1 files changed, 55 insertions, 22 deletions
diff --git a/g10/pkglue.c b/g10/pkglue.c index 3a078bd3f..7e50a1c3d 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -33,14 +33,14 @@ /* FIXME: Better chnage the fucntion name because mpi_ is used by gcrypt macros. */ gcry_mpi_t -mpi_from_sexp (gcry_sexp_t sexp, const char * item) +get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt) { gcry_sexp_t list; gcry_mpi_t data; list = gcry_sexp_find_token (sexp, item, 0); assert (list); - data = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG); + data = gcry_sexp_nth_mpi (list, 1, mpifmt); assert (data); gcry_sexp_release (list); return data; @@ -58,6 +58,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey) gcry_sexp_t s_sig, s_hash, s_pkey; int rc; const int pkalgo = map_pk_openpgp_to_gcry (algo); + int is_ed25519 = 0; /* Make a sexp from pkey. */ if (pkalgo == GCRY_PK_DSA) @@ -79,15 +80,24 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey) } else if (pkalgo == GCRY_PK_ECDSA) /* Same as GCRY_PK_ECDH */ { - char *curve = openpgp_oid_to_str (pkey[0]); - if (!curve) - rc = gpg_error_from_syserror (); + is_ed25519 = openpgp_oid_is_ed25519 (pkey[0]); + if (is_ed25519) + rc = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecc(curve Ed25519)" + "(flags eddsa)(q%m)))", + pkey[1]); else { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(ecdsa(curve %s)(q%m)))", - curve, pkey[1]); - xfree (curve); + char *curve = openpgp_oid_to_str (pkey[0]); + if (!curve) + rc = gpg_error_from_syserror (); + else + { + rc = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecdsa(curve %s)(q%m)))", + curve, pkey[1]); + xfree (curve); + } } } else @@ -97,8 +107,18 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey) BUG (); /* gcry_sexp_build should never fail. */ /* Put hash into a S-Exp s_hash. */ - if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) - BUG (); /* gcry_sexp_build should never fail. */ + if (is_ed25519) + { + if (gcry_sexp_build (&s_hash, NULL, + "(data(flags eddsa)(hash-algo sha512)(value %m))", + hash)) + BUG (); /* gcry_sexp_build should never fail. */ + } + else + { + if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) + BUG (); /* gcry_sexp_build should never fail. */ + } /* Put data into a S-Exp s_sig. */ s_sig = NULL; @@ -114,6 +134,9 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey) { if (!data[0] || !data[1]) rc = gpg_error (GPG_ERR_BAD_MPI); + else if (is_ed25519) + rc = gcry_sexp_build (&s_sig, NULL, + "(sig-val(eddsa(r%M)(s%M)))", data[0], data[1]); else rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(ecdsa(r%m)(s%m)))", data[0], data[1]); @@ -223,8 +246,8 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, size_t fpn; /* Get the shared point and the ephemeral public key. */ - shared = mpi_from_sexp (s_ciph, "s"); - public = mpi_from_sexp (s_ciph, "e"); + shared = get_mpi_from_sexp (s_ciph, "s", GCRYMPI_FMT_USG); + public = get_mpi_from_sexp (s_ciph, "e", GCRYMPI_FMT_USG); gcry_sexp_release (s_ciph); s_ciph = NULL; if (DBG_CIPHER) @@ -256,9 +279,9 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, else /* Elgamal or RSA case. */ { /* Fixme: Add better error handling or make gnupg use S-expressions directly. */ - resarr[0] = mpi_from_sexp (s_ciph, "a"); + resarr[0] = get_mpi_from_sexp (s_ciph, "a", GCRYMPI_FMT_USG); if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E) - resarr[1] = mpi_from_sexp (s_ciph, "b"); + resarr[1] = get_mpi_from_sexp (s_ciph, "b", GCRYMPI_FMT_USG); } gcry_sexp_release (s_ciph); @@ -296,15 +319,25 @@ pk_check_secret_key (int algo, gcry_mpi_t *skey) } else if (gcry_pkalgo == GCRY_PK_ECDSA || gcry_pkalgo == GCRY_PK_ECDH) { - char *curve = openpgp_oid_to_str (skey[0]); - if (!curve) - rc = gpg_error_from_syserror (); - else + if (openpgp_oid_is_ed25519 (skey[0])) { rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(ecdsa(curve%s)(q%m)(d%m)))", - curve, skey[1], skey[2]); - xfree (curve); + "(private-key(ecc(curve Ed25519)" + "(flags eddsa)(q%m)(d%m)))", + skey[1], skey[2]); + } + else + { + char *curve = openpgp_oid_to_str (skey[0]); + if (!curve) + rc = gpg_error_from_syserror (); + else + { + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(ecdsa(curve%s)(q%m)(d%m)))", + curve, skey[1], skey[2]); + xfree (curve); + } } } else |