1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

experiment: Also support new ECDH encryption with 448.

Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2021-10-21 14:58:39 +09:00
parent 9948f3c133
commit 98010a02c4
4 changed files with 53 additions and 42 deletions

View File

@ -50,3 +50,47 @@ openpgp_ecc_parse_key (pubkey_algo_t pkalgo, const char *curve,
else else
return gcry_mpi_set_opaque_copy (NULL, buf+1, 448); 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;
}

View File

@ -242,5 +242,6 @@ enum gcry_pk_algos map_openpgp_pk_to_gcry (pubkey_algo_t algo);
/*-- openpgp-misc.c --*/ /*-- openpgp-misc.c --*/
gcry_mpi_t openpgp_ecc_parse_key (pubkey_algo_t pkalgo, const char *curve, gcry_mpi_t openpgp_ecc_parse_key (pubkey_algo_t pkalgo, const char *curve,
gcry_mpi_t key); gcry_mpi_t key);
gpg_error_t openpgp_fixup_pubkey_448 (int algo, gcry_mpi_t *p_pubkey);
#endif /*GNUPG_COMMON_OPENPGPDEFS_H*/ #endif /*GNUPG_COMMON_OPENPGPDEFS_H*/

View File

@ -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 static gpg_error_t
ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) 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]) if (openpgp_oid_is_ed448 (array[0])
|| openpgp_oid_is_cv448 (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) if (err)
goto leave; goto leave;
} }

View File

@ -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); rc = sexp_extract_param_sos (s_ciph, "e", &public);
gcry_sexp_release (s_ciph); gcry_sexp_release (s_ciph);
s_ciph = NULL; s_ciph = NULL;
if (openpgp_oid_is_cv448 (pkey[0]))
{
rc = openpgp_fixup_pubkey_448 (algo, &public);
if (rc)
goto leave;
}
if (DBG_CRYPTO) if (DBG_CRYPTO)
{ {
log_debug ("ECDH ephemeral key:"); log_debug ("ECDH ephemeral key:");