diff --git a/common/openpgp-misc.c b/common/openpgp-misc.c index 178a4938e..4d057e5ed 100644 --- a/common/openpgp-misc.c +++ b/common/openpgp-misc.c @@ -50,3 +50,47 @@ openpgp_ecc_parse_key (pubkey_algo_t pkalgo, const char *curve, else return gcry_mpi_set_opaque_copy (NULL, buf+1, 448); } + + +/* + * Fix up public key for OpenPGP adding the prefix. + */ +gpg_error_t +openpgp_fixup_pubkey_448 (int algo, gcry_mpi_t *p_pubkey) +{ + gcry_mpi_t pubkey_mpi; + gcry_mpi_t a; + unsigned char *p; + const unsigned char *p_key; + unsigned int nbits; + unsigned int len; + + pubkey_mpi = *p_pubkey; + *p_pubkey = NULL; + p_key = gcry_mpi_get_opaque (pubkey_mpi, &nbits); + len = (nbits+7)/8; + if ((algo == PUBKEY_ALGO_ECDH && len != 56) + || (algo == PUBKEY_ALGO_EDDSA && len != 57) + || (algo != PUBKEY_ALGO_ECDH && algo != PUBKEY_ALGO_EDDSA)) + { + gcry_mpi_release (pubkey_mpi); + return gpg_error (GPG_ERR_BAD_PUBKEY); + } + + p = xtrymalloc (1 + len); + if (!p) + { + gcry_mpi_release (pubkey_mpi); + return gpg_error_from_syserror (); + } + + p[0] = 0x40; + memcpy (p+1, p_key, len); + + a = gcry_mpi_set_opaque (NULL, p, 0); + gcry_mpi_set_flag (a, GCRYMPI_FLAG_USER2); + *p_pubkey = a; + gcry_mpi_release (pubkey_mpi); + + return 0; +} diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h index 2ed4a6cd0..01a0e0edf 100644 --- a/common/openpgpdefs.h +++ b/common/openpgpdefs.h @@ -242,5 +242,6 @@ enum gcry_pk_algos map_openpgp_pk_to_gcry (pubkey_algo_t algo); /*-- openpgp-misc.c --*/ gcry_mpi_t openpgp_ecc_parse_key (pubkey_algo_t pkalgo, const char *curve, gcry_mpi_t key); +gpg_error_t openpgp_fixup_pubkey_448 (int algo, gcry_mpi_t *p_pubkey); #endif /*GNUPG_COMMON_OPENPGPDEFS_H*/ diff --git a/g10/keygen.c b/g10/keygen.c index c90e95be5..dd008b200 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1283,47 +1283,6 @@ write_keybinding (ctrl_t ctrl, kbnode_t root, } -static gpg_error_t -sos_fixup_pubkey_448 (int algo, gcry_mpi_t *p_pubkey) -{ - gcry_mpi_t pubkey_mpi; - gcry_mpi_t a; - unsigned char *p; - const unsigned char *p_key; - unsigned int nbits; - unsigned int len; - - pubkey_mpi = *p_pubkey; - *p_pubkey = NULL; - p_key = gcry_mpi_get_opaque (pubkey_mpi, &nbits); - len = (nbits+7)/8; - if ((algo == PUBKEY_ALGO_ECDH && len != 56) - || (algo == PUBKEY_ALGO_EDDSA && len != 57) - || (algo != PUBKEY_ALGO_ECDH && algo != PUBKEY_ALGO_EDDSA)) - { - gcry_mpi_release (pubkey_mpi); - return gpg_error (GPG_ERR_BAD_PUBKEY); - } - - p = xtrymalloc (1 + len); - if (!p) - { - gcry_mpi_release (pubkey_mpi); - return gpg_error_from_syserror (); - } - - p[0] = 0x40; - memcpy (p+1, p_key, len); - - a = gcry_mpi_set_opaque (NULL, p, 0); - gcry_mpi_set_flag (a, GCRYMPI_FLAG_USER2); - *p_pubkey = a; - gcry_mpi_release (pubkey_mpi); - - return 0; -} - - static gpg_error_t ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) { @@ -1379,7 +1338,7 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) if (openpgp_oid_is_ed448 (array[0]) || openpgp_oid_is_cv448 (array[0])) { - err = sos_fixup_pubkey_448 (algo, &array[1]); + err = openpgp_fixup_pubkey_448 (algo, &array[1]); if (err) goto leave; } diff --git a/g10/pkglue.c b/g10/pkglue.c index 9a1db3bc8..4f727aa32 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -463,6 +463,13 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data, rc = sexp_extract_param_sos (s_ciph, "e", &public); gcry_sexp_release (s_ciph); s_ciph = NULL; + if (openpgp_oid_is_cv448 (pkey[0])) + { + rc = openpgp_fixup_pubkey_448 (algo, &public); + if (rc) + goto leave; + } + if (DBG_CRYPTO) { log_debug ("ECDH ephemeral key:");