aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/ecdh.c29
-rw-r--r--g10/keygen.c14
2 files changed, 41 insertions, 2 deletions
diff --git a/g10/ecdh.c b/g10/ecdh.c
index dd9989bca..d6c30c1ca 100644
--- a/g10/ecdh.c
+++ b/g10/ecdh.c
@@ -422,10 +422,27 @@ pk_ecdh_encrypt_with_shared_point (gcry_mpi_t shared_mpi,
static gcry_mpi_t
-gen_k (unsigned nbits)
+gen_k (unsigned nbits, int little_endian, int is_opaque)
{
gcry_mpi_t k;
+ if (is_opaque)
+ {
+ unsigned char *p;
+ size_t nbytes = (nbits+7)/8;
+
+ p = gcry_random_bytes_secure (nbytes, GCRY_STRONG_RANDOM);
+ if ((nbits % 8))
+ {
+ if (little_endian)
+ p[nbytes-1] &= ((1 << (nbits % 8)) - 1);
+ else
+ p[0] &= ((1 << (nbits % 8)) - 1);
+ }
+ k = gcry_mpi_set_opaque (NULL, p, nbits);
+ return k;
+ }
+
k = gcry_mpi_snew (nbits);
if (DBG_CRYPTO)
log_debug ("choosing a random k of %u bits\n", nbits);
@@ -453,13 +470,21 @@ pk_ecdh_generate_ephemeral_key (gcry_mpi_t *pkey, gcry_mpi_t *r_k)
{
unsigned int nbits;
gcry_mpi_t k;
+ int is_little_endian = 0;
+ int require_opaque = 0;
+
+ if (openpgp_oid_is_x448 (pkey[0]))
+ {
+ is_little_endian = 1;
+ require_opaque = 1;
+ }
*r_k = NULL;
nbits = pubkey_nbits (PUBKEY_ALGO_ECDH, pkey);
if (!nbits)
return gpg_error (GPG_ERR_TOO_SHORT);
- k = gen_k (nbits);
+ k = gen_k (nbits, is_little_endian, require_opaque);
if (!k)
BUG ();
diff --git a/g10/keygen.c b/g10/keygen.c
index e25d4d925..aab5929ef 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -1748,6 +1748,8 @@ gen_ecc (int algo, const char *curve, kbnode_t pub_root,
curve = "Curve25519";
else if (!ascii_strcasecmp (curve, "ed25519"))
curve = "Ed25519";
+ else if (!ascii_strcasecmp (curve, "x448"))
+ curve = "X448";
/* Note that we use the "comp" flag with EdDSA to request the use of
a 0x40 compression prefix octet. */
@@ -1765,6 +1767,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, "X448"))
+ keyparms = xtryasprintf
+ ("(genkey(ecc(curve %zu:%s)(flags 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)))",
@@ -2319,6 +2328,8 @@ ask_algo (ctrl_t ctrl, int addmode, int *r_subkey_algo, unsigned int *r_usage,
kpi->algo = PUBKEY_ALGO_EDDSA;
else if (!strcmp (algostr, "cv25519"))
kpi->algo = PUBKEY_ALGO_ECDH;
+ else if (!strcmp (algostr, "x448"))
+ kpi->algo = PUBKEY_ALGO_ECDH;
else if ((kpi->usage & GCRY_PK_USAGE_ENCR))
kpi->algo = PUBKEY_ALGO_ECDH;
else
@@ -3472,6 +3483,8 @@ parse_key_parameter_part (ctrl_t ctrl,
algo = PUBKEY_ALGO_EDDSA;
else if (!strcmp (algostr, "cv25519"))
algo = PUBKEY_ALGO_ECDH;
+ else if (!strcmp (algostr, "x448"))
+ algo = PUBKEY_ALGO_ECDH;
else if ((kpi->usage & GCRY_PK_USAGE_ENCR))
algo = PUBKEY_ALGO_ECDH;
else
@@ -3599,6 +3612,7 @@ parse_key_parameter_part (ctrl_t ctrl,
* elg2048 := Elgamal with 2048 bit.
* ed25519 := EDDSA using curve Ed25519.
* cv25519 := ECDH using curve Curve25519.
+ * x448 := ECDH using curve X448.
* nistp256:= ECDSA or ECDH using curve NIST P-256
*
* All strings with an unknown prefix are considered an elliptic