diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2020-06-09 07:56:50 +0200 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2020-06-09 07:56:50 +0200 |
commit | e9760eb9e70b9804c988dafe01851f6600869d9e (patch) | |
tree | 7dcf574730d5a43c7a8762eaf27a12812e896f19 /g10/ecdh.c | |
parent | gpg,ecc: Handle external representation as SOS with opaque MPI. (diff) | |
download | gnupg2-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.c | 29 |
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 (); |