aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ecdh.c9
-rw-r--r--g10/keygen.c22
-rw-r--r--g10/keyid.c9
-rw-r--r--g10/pkglue.c6
-rw-r--r--g10/pubkey-enc.c4
5 files changed, 36 insertions, 14 deletions
diff --git a/g10/ecdh.c b/g10/ecdh.c
index 9576a1c1a..a1b7ecfdc 100644
--- a/g10/ecdh.c
+++ b/g10/ecdh.c
@@ -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 );
diff --git a/g10/keygen.c b/g10/keygen.c
index 796d18f8e..f03c148cf 100644
--- a/g10/keygen.c
+++ b/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);
diff --git a/g10/keyid.c b/g10/keyid.c
index 68990c8bd..42a5f9fe0 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -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);
}
diff --git a/g10/pkglue.c b/g10/pkglue.c
index d72275b81..a83462187 100644
--- a/g10/pkglue.c
+++ b/g10/pkglue.c
@@ -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. */
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index cb834afab..fd7f81277 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -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;