From 402aa0f94854bb00475c934be5ca6043a4632126 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 15 Nov 2013 08:59:45 +0100 Subject: 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 --- common/openpgp-oid.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) (limited to 'common/openpgp-oid.c') diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c index 19fadd3f2..a1ceba4ef 100644 --- a/common/openpgp-oid.c +++ b/common/openpgp-oid.c @@ -1,5 +1,6 @@ /* openpgp-oids.c - OID helper for OpenPGP * Copyright (C) 2011 Free Software Foundation, Inc. + * Copyright (C) 2013 Werner Koch * * This file is part of GnuPG. * @@ -36,6 +37,11 @@ #include "util.h" +/* The OID for Curve Ed25519 in OpenPGP format. */ +static const char oid_ed25519[] = + { 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01 }; + + /* Helper for openpgp_oid_from_str. */ static size_t make_flagged_int (unsigned long value, char *buf, size_t buflen) @@ -236,3 +242,88 @@ openpgp_oid_to_str (gcry_mpi_t a) xfree (string); return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973"); } + + + +/* Return true if A represents the OID for Ed25519. */ +int +openpgp_oid_is_ed25519 (gcry_mpi_t a) +{ + const unsigned char *buf; + unsigned int nbits; + size_t n; + + if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) + return 0; + + buf = gcry_mpi_get_opaque (a, &nbits); + n = (nbits+7)/8; + return (n == DIM (oid_ed25519) + && !memcmp (buf, oid_ed25519, DIM (oid_ed25519))); +} + + + +/* Map the Libgcrypt ECC curve NAME to an OID. If R_NBITS is not NULL + store the bit size of the curve there. Returns NULL for unknown + curve names. */ +const char * +openpgp_curve_to_oid (const char *name, unsigned int *r_nbits) +{ + unsigned int nbits = 0; + const char *oidstr; + + if (!name) + oidstr = NULL; + else if (!strcmp (name, "Ed25519")) + { + oidstr = "1.3.6.1.4.1.3029.1.5.1"; + nbits = 255; + } + else if (!strcmp (name, "nistp256")) + { + oidstr = "1.2.840.10045.3.1.7"; + nbits = 256; + } + else if (!strcmp (name, "nistp384")) + { + oidstr = "1.3.132.0.34"; + nbits = 384; + } + else if (!strcmp (name, "nistp521")) + { + oidstr = "1.3.132.0.35"; + nbits = 521; + } + else + oidstr = NULL; + + if (r_nbits) + *r_nbits = nbits; + return oidstr; +} + + +/* Map an OpenPGP OID to the Libgcrypt curve NAME. If R_NBITS is not + NULL store the bit size of the curve there. Returns "?" for + unknown curve names. */ +const char * +openpgp_oid_to_curve (const char *oid) +{ + const char *name; + + if (!oid) + name = ""; + else if (!strcmp (oid, "1.3.6.1.4.1.3029.1.5.1")) + name = "Ed25519"; + else if (!strcmp (oid, "1.2.840.10045.3.1.7")) + name = "NIST P-256"; + else if (!strcmp (oid, "1.3.132.0.34")) + name = "NIST P-384"; + else if (!strcmp (oid, "1.3.132.0.35")) + name = "NIST P-521"; + else /* FIXME: Lookup via Libgcrypt. */ + name = "?"; + + return name; +} -- cgit v1.2.3