From 9948f3c133b400a602751edc61c3160746c4ff85 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 21 Oct 2021 14:38:44 +0900 Subject: [PATCH] experiment: Fix ECC key handling. Signed-off-by: NIIBE Yutaka --- agent/cvt-openpgp.c | 6 +++--- common/openpgp-misc.c | 37 ++++++++++--------------------------- common/openpgpdefs.h | 6 ++---- g10/keyid.c | 4 ++-- g10/misc.c | 3 +-- g10/pkglue.c | 12 ++++++------ 6 files changed, 24 insertions(+), 44 deletions(-) diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 0bd56d73a..efddb84af 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -103,7 +103,7 @@ get_keygrip (int pubkey_algo, const char *curve, gcry_mpi_t *pkey, if (pkalgo) { - pubkey = openpgp_ecc_parse_pubkey (pkalgo, curve, pkey[0]); + pubkey = openpgp_ecc_parse_key (pkalgo, curve, pkey[0]); err = gcry_sexp_build (&s_pkey, NULL, format, curve, pubkey); gcry_mpi_release (pubkey); } @@ -189,8 +189,8 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey, if (pkalgo) { - pubkey = openpgp_ecc_parse_pubkey (pkalgo, curve, skey[0]); - seckey = openpgp_ecc_parse_seckey (pkalgo, curve, skey[1]); + pubkey = openpgp_ecc_parse_key (pkalgo, curve, skey[0]); + seckey = openpgp_ecc_parse_key (pkalgo, curve, skey[1]); err = gcry_sexp_build (&s_skey, NULL, format, curve, pubkey, seckey); gcry_mpi_release (pubkey); gcry_mpi_release (seckey); diff --git a/common/openpgp-misc.c b/common/openpgp-misc.c index 2caad9093..178a4938e 100644 --- a/common/openpgp-misc.c +++ b/common/openpgp-misc.c @@ -23,45 +23,28 @@ #include "util.h" #include "openpgpdefs.h" +/* + * Parse the key (pubkey or seckey), and return real version of the + * key; That is, for Ed448/X448, return key with prefix removed. + */ gcry_mpi_t -openpgp_ecc_parse_pubkey (pubkey_algo_t pkalgo, const char *curve, - gcry_mpi_t pubkey) +openpgp_ecc_parse_key (pubkey_algo_t pkalgo, const char *curve, + gcry_mpi_t key) { unsigned int nbits = 0; unsigned char *buf = NULL; if ((pkalgo == PUBKEY_ALGO_EDDSA && !strcmp (curve, "Ed448")) || (pkalgo == PUBKEY_ALGO_ECDH && !strcmp (curve, "X448"))) - buf = gcry_mpi_get_opaque (pubkey, &nbits); + buf = gcry_mpi_get_opaque (key, &nbits); + /* Either Ed448/X448 non-prefixed or not Ed448/X448. */ if (nbits == 0 || (pkalgo == PUBKEY_ALGO_EDDSA && (nbits+7)/8 == (448 + 8)/8) || (pkalgo == PUBKEY_ALGO_ECDH && (nbits+7)/8 == 448/8)) - return gcry_mpi_copy (pubkey); - - if (pkalgo == PUBKEY_ALGO_EDDSA) - return gcry_mpi_set_opaque_copy (NULL, buf+1, 8 + 448); - else - return gcry_mpi_set_opaque_copy (NULL, buf+1, 448); -} - - -gcry_mpi_t -openpgp_ecc_parse_seckey (pubkey_algo_t pkalgo, const char *curve, - gcry_mpi_t seckey) -{ - unsigned int nbits = 0; - unsigned char *buf = NULL; - - if ((pkalgo == PUBKEY_ALGO_EDDSA && !strcmp (curve, "Ed448")) - || (pkalgo == PUBKEY_ALGO_ECDH && !strcmp (curve, "X448"))) - buf = gcry_mpi_get_opaque (seckey, &nbits); - - if (nbits == 0 - || (pkalgo == PUBKEY_ALGO_EDDSA && (nbits+7)/8 == (448 + 8)/8) - || (pkalgo == PUBKEY_ALGO_ECDH && (nbits+7)/8 == 448/8)) - return gcry_mpi_copy (seckey); + return gcry_mpi_copy (key); + /* Ed448 or X448 prefixed. */ if (pkalgo == PUBKEY_ALGO_EDDSA) return gcry_mpi_set_opaque_copy (NULL, buf+1, 8 + 448); else diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h index 4e5500d0b..2ed4a6cd0 100644 --- a/common/openpgpdefs.h +++ b/common/openpgpdefs.h @@ -240,9 +240,7 @@ enum gcry_pk_algos map_openpgp_pk_to_gcry (pubkey_algo_t algo); /*-- openpgp-misc.c --*/ -gcry_mpi_t openpgp_ecc_parse_pubkey (pubkey_algo_t pkalgo, const char *curve, - gcry_mpi_t pubkey); -gcry_mpi_t openpgp_ecc_parse_seckey (pubkey_algo_t pkalgo, const char *curve_oid, - gcry_mpi_t seckey); +gcry_mpi_t openpgp_ecc_parse_key (pubkey_algo_t pkalgo, const char *curve, + gcry_mpi_t key); #endif /*GNUPG_COMMON_OPENPGPDEFS_H*/ diff --git a/g10/keyid.c b/g10/keyid.c index d0a3e4057..8264fe9d6 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -1068,8 +1068,8 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) err = gpg_error_from_syserror (); else { - gcry_mpi_t pubkey = openpgp_ecc_parse_pubkey (pk->pubkey_algo, - curve, pk->pkey[1]); + gcry_mpi_t pubkey = openpgp_ecc_parse_key (pk->pubkey_algo, + curve, pk->pkey[1]); err = gcry_sexp_build (&s_pkey, NULL, pk->pubkey_algo == PUBKEY_ALGO_EDDSA? diff --git a/g10/misc.c b/g10/misc.c index e83800a85..786ae52cf 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1806,8 +1806,7 @@ pubkey_nbits( int algo, gcry_mpi_t *key ) else { const char *curve_name = openpgp_oid_to_curve (curve, 1); - gcry_mpi_t pubkey = openpgp_ecc_parse_pubkey (algo, - curve_name, key[1]); + gcry_mpi_t pubkey = openpgp_ecc_parse_key (algo, curve_name, key[1]); rc = gcry_sexp_build (&sexp, NULL, "(public-key(ecc(curve%s)(q%m)))", diff --git a/g10/pkglue.c b/g10/pkglue.c index bc6f30e94..9a1db3bc8 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -194,7 +194,7 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash, gcry_mpi_t pubkey; const char *curve_name = openpgp_oid_to_curve (curve, 1); - pubkey = openpgp_ecc_parse_pubkey (pkalgo, curve_name, pkey[1]); + pubkey = openpgp_ecc_parse_key (pkalgo, curve_name, pkey[1]); if (openpgp_oid_is_ed25519 (pkey[0])) fmt = "(public-key(ecc(curve %s)(flags eddsa)(q%m)))"; else @@ -418,7 +418,7 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t pubkey; const char *curve_name = openpgp_oid_to_curve (curve, 1); - pubkey = openpgp_ecc_parse_pubkey (algo, curve_name, pkey[1]); + pubkey = openpgp_ecc_parse_key (algo, curve_name, pkey[1]); /* Now use the ephemeral secret to compute the shared point. */ rc = gcry_sexp_build (&s_pkey, NULL, with_djb_tweak_flag ? @@ -543,8 +543,8 @@ pk_check_secret_key (pubkey_algo_t pkalgo, gcry_mpi_t *skey) gcry_mpi_t seckey; const char *curve_name = openpgp_oid_to_curve (curve, 1); - pubkey = openpgp_ecc_parse_pubkey (pkalgo, curve_name, skey[1]); - seckey = openpgp_ecc_parse_seckey (pkalgo, curve_name, skey[2]); + pubkey = openpgp_ecc_parse_key (pkalgo, curve_name, skey[1]); + seckey = openpgp_ecc_parse_key (pkalgo, curve_name, skey[2]); rc = gcry_sexp_build (&s_skey, NULL, "(private-key(ecc(curve%s)(q%m)(d%m)))", curve_name, pubkey, seckey); @@ -565,8 +565,8 @@ pk_check_secret_key (pubkey_algo_t pkalgo, gcry_mpi_t *skey) gcry_mpi_t seckey; const char *curve_name = openpgp_oid_to_curve (curve, 1); - pubkey = openpgp_ecc_parse_pubkey (pkalgo, curve_name, skey[1]); - seckey = openpgp_ecc_parse_seckey (pkalgo, curve_name, skey[2]); + pubkey = openpgp_ecc_parse_key (pkalgo, curve_name, skey[1]); + seckey = openpgp_ecc_parse_key (pkalgo, curve_name, skey[2]); if (openpgp_oid_is_ed25519 (skey[0])) fmt = "(private-key(ecc(curve %s)(flags eddsa)(q%m)(d%m)))"; else