summaryrefslogtreecommitdiffstats
path: root/g10/ecdh.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2020-06-09 07:56:50 +0200
committerNIIBE Yutaka <gniibe@fsij.org>2020-06-09 07:56:50 +0200
commite9760eb9e70b9804c988dafe01851f6600869d9e (patch)
tree7dcf574730d5a43c7a8762eaf27a12812e896f19 /g10/ecdh.c
parentgpg,ecc: Handle external representation as SOS with opaque MPI. (diff)
downloadgnupg2-e9760eb9e70b9804c988dafe01851f6600869d9e.tar.xz
gnupg2-e9760eb9e70b9804c988dafe01851f6600869d9e.zip
gpg: Add X448 support.
* common/openpgp-oid.c (oidtable): Add X448. (oid_x448,openpgp_oidbuf_is_x448,openpgp_oid_is_x448): New. * common/util.h (openpgp_oid_is_x448): New. * g10/ecdh.c (gen_k): Add handling of opaque MPI and support endianness. (pk_ecdh_generate_ephemeral_key): X448 requires opaque MPI. * g10/keygen.c (gen_ecc): Add support for X448. (ask_algo, parse_key_parameter_part): Likewise. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'g10/ecdh.c')
-rw-r--r--g10/ecdh.c29
1 files changed, 27 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 ();