mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
Curve25519 support.
* agent/cvt-openpgp.c (get_keygrip): Handle Curve25519. (convert_secret_key, convert_transfer_key): Ditto. * common/openpgp-oid.c (oidtable): Add Curve25519. (oid_crv25519, openpgp_oid_is_crv25519): New. * common/util.h (openpgp_oid_is_crv25519): New. * g10/ecdh.c (pk_ecdh_encrypt_with_shared_point): Handle the case with Montgomery curve which uses x-only coordinate. * g10/keygen.c (gen_ecc): Handle Curve25519. (ask_curve): Change the API and second arg is to return subkey algo. (generate_keypair, generate_subkeypair): Follow chage of ask_curve. * g10/keyid.c (keygrip_from_pk): Handle Curve25519. * g10/pkglue.c (pk_encrypt): Handle Curve25519. * g10/pubkey-enc.c (get_it): Handle the case with Montgomery curve. * scd/app-openpgp.c (ECC_FLAG_DJB_TWEAK): New. (send_key_attr): Work with general ECC, Ed25519, and Curve25519. (get_public_key): Likewise. (ecc_writekey): Handle flag_djb_tweak. -- When libgcrypt has Curve25519, GnuPG now supports Curve25519.
This commit is contained in:
parent
a6e4053089
commit
e5891a82c3
9 changed files with 181 additions and 105 deletions
|
@ -134,9 +134,12 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi,
|
|||
}
|
||||
|
||||
secret_x_size = (nbits+7)/8;
|
||||
assert (nbytes > secret_x_size);
|
||||
memmove (secret_x, secret_x+1, secret_x_size);
|
||||
memset (secret_x+secret_x_size, 0, nbytes-secret_x_size);
|
||||
assert (nbytes >= secret_x_size);
|
||||
if ((nbytes & 1))
|
||||
/* Remove the "04" prefix of non-compressed format. */
|
||||
memmove (secret_x, secret_x+1, secret_x_size);
|
||||
if (nbytes - secret_x_size)
|
||||
memset (secret_x+secret_x_size, 0, nbytes-secret_x_size);
|
||||
|
||||
if (DBG_CRYPTO)
|
||||
log_printhex ("ECDH shared secret X is:", secret_x, secret_x_size );
|
||||
|
|
22
g10/keygen.c
22
g10/keygen.c
|
@ -1520,6 +1520,13 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root,
|
|||
(((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
|
||||
&& (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
|
||||
" transient-key" : ""));
|
||||
else if (algo == PUBKEY_ALGO_ECDH && !strcmp (curve, "Curve25519"))
|
||||
keyparms = xtryasprintf
|
||||
("(genkey(ecc(curve %zu:%s)(flags djb-tweak comp%s)))",
|
||||
strlen (curve), curve,
|
||||
(((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY)
|
||||
&& (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))?
|
||||
" transient-key" : ""));
|
||||
else
|
||||
keyparms = xtryasprintf
|
||||
("(genkey(ecc(curve %zu:%s)(flags nocomp%s)))",
|
||||
|
@ -2125,7 +2132,7 @@ ask_keysize (int algo, unsigned int primary_keysize)
|
|||
function may adjust. Returns a malloced string with the name of
|
||||
the curve. BOTH tells that gpg creates a primary and subkey. */
|
||||
static char *
|
||||
ask_curve (int *algo, int both)
|
||||
ask_curve (int *algo, int *subkey_algo)
|
||||
{
|
||||
struct {
|
||||
const char *name;
|
||||
|
@ -2176,7 +2183,7 @@ ask_curve (int *algo, int both)
|
|||
continue;
|
||||
if (!gcry_pk_get_curve (keyparms, 0, NULL))
|
||||
continue;
|
||||
if (both && curves[idx].fix_curve)
|
||||
if (subkey_algo && curves[idx].fix_curve)
|
||||
{
|
||||
/* Both Curve 25519 keys are to be created. Check that
|
||||
Libgcrypt also supports the real Curve25519. */
|
||||
|
@ -2241,6 +2248,11 @@ ask_curve (int *algo, int both)
|
|||
if ((*algo == PUBKEY_ALGO_ECDSA || *algo == PUBKEY_ALGO_EDDSA)
|
||||
&& curves[idx].fix_curve)
|
||||
{
|
||||
if (subkey_algo && *subkey_algo == PUBKEY_ALGO_ECDSA)
|
||||
{
|
||||
*subkey_algo = PUBKEY_ALGO_EDDSA;
|
||||
result = xstrdup ("Ed25519");
|
||||
}
|
||||
*algo = PUBKEY_ALGO_EDDSA;
|
||||
result = xstrdup ("Ed25519");
|
||||
}
|
||||
|
@ -3672,7 +3684,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||
|| algo == PUBKEY_ALGO_EDDSA
|
||||
|| algo == PUBKEY_ALGO_ECDH)
|
||||
{
|
||||
curve = ask_curve (&algo, both);
|
||||
curve = ask_curve (&algo, &subkey_algo);
|
||||
r = xmalloc_clear( sizeof *r + 20 );
|
||||
r->key = pKEYTYPE;
|
||||
sprintf( r->u.value, "%d", algo);
|
||||
|
@ -3743,7 +3755,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
|
|||
|| algo == PUBKEY_ALGO_EDDSA
|
||||
|| algo == PUBKEY_ALGO_ECDH)
|
||||
{
|
||||
curve = ask_curve (&algo, 0);
|
||||
curve = ask_curve (&algo, NULL);
|
||||
nbits = 0;
|
||||
r = xmalloc_clear (sizeof *r + strlen (curve));
|
||||
r->key = pKEYCURVE;
|
||||
|
@ -4292,7 +4304,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock)
|
|||
else if (algo == PUBKEY_ALGO_ECDSA
|
||||
|| algo == PUBKEY_ALGO_EDDSA
|
||||
|| algo == PUBKEY_ALGO_ECDH)
|
||||
curve = ask_curve (&algo, 0);
|
||||
curve = ask_curve (&algo, NULL);
|
||||
else
|
||||
nbits = ask_keysize (algo, 0);
|
||||
|
||||
|
|
|
@ -766,9 +766,12 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
|
|||
else
|
||||
{
|
||||
err = gcry_sexp_build (&s_pkey, NULL,
|
||||
pk->pubkey_algo == PUBKEY_ALGO_EDDSA ?
|
||||
"(public-key(ecc(curve%s)(flags eddsa)(q%m)))"
|
||||
: "(public-key(ecc(curve%s)(q%m)))",
|
||||
pk->pubkey_algo == PUBKEY_ALGO_EDDSA?
|
||||
"(public-key(ecc(curve%s)(flags eddsa)(q%m)))":
|
||||
(pk->pubkey_algo == PUBKEY_ALGO_ECDH
|
||||
&& openpgp_oid_is_crv25519 (pk->pkey[0]))?
|
||||
"(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))":
|
||||
"(public-key(ecc(curve%s)(q%m)))",
|
||||
curve, pk->pkey[1]);
|
||||
xfree (curve);
|
||||
}
|
||||
|
|
|
@ -228,9 +228,13 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
|
|||
rc = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
int with_djb_tweak_flag = openpgp_oid_is_crv25519 (pkey[0]);
|
||||
|
||||
/* Now use the ephemeral secret to compute the shared point. */
|
||||
rc = gcry_sexp_build (&s_pkey, NULL,
|
||||
"(public-key(ecdh(curve%s)(q%m)))",
|
||||
with_djb_tweak_flag ?
|
||||
"(public-key(ecdh(curve%s)(flags djb-tweak)(q%m)))"
|
||||
: "(public-key(ecdh(curve%s)(q%m)))",
|
||||
curve, pkey[1]);
|
||||
xfree (curve);
|
||||
/* Put K into a simplified S-expression. */
|
||||
|
|
|
@ -250,8 +250,8 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
|
|||
if(err)
|
||||
goto leave;
|
||||
|
||||
/* Reuse NFRAME, which size is sufficient to include the session key. */
|
||||
err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded);
|
||||
xfree (frame);
|
||||
err = gcry_mpi_aprint (GCRYMPI_FMT_USG, &frame, &nframe, decoded);
|
||||
mpi_release (decoded);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue