mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
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>
This commit is contained in:
parent
9ae48b173c
commit
402aa0f948
20 changed files with 574 additions and 139 deletions
77
g10/pkglue.c
77
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue