1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

gpg: Allow ECDH with a smartcard returning just the x-coordinate.

* g10/ecdh.c (pk_ecdh_encrypt_with_shared_point): Factor extraction
part out to  ...
(extract_secret_x): new.  Allow for x-only coordinate.
(pk_ecdh_encrypt_with_shared_point): Change arg shared_mpi
to (shared,nshared).  Move param check to the top.  Add extra safety
check.
(pk_ecdh_decrypt): Adjust for change.
* g10/pkglue.c (get_data_from_sexp): New.
(pk_encrypt): Use it for "s" and adjusted for changed
pk_ecdh_encrypt_with_shared_point.
* g10/pubkey-enc.c (get_it): Remove conversion to an MPI and call
pk_ecdh_decrypt with the frame buffer.
--

Backported-from-master: f129b0e977)
Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2021-05-04 11:51:34 +02:00
parent b410c95fe9
commit b203325ce1
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
4 changed files with 143 additions and 100 deletions

View file

@ -47,6 +47,28 @@ get_mpi_from_sexp (gcry_sexp_t sexp, const char *item, int mpifmt)
}
static byte *
get_data_from_sexp (gcry_sexp_t sexp, const char *item, size_t *r_size)
{
gcry_sexp_t list;
size_t valuelen;
const char *value;
byte *v;
if (DBG_CRYPTO)
log_printsexp ("get_data_from_sexp:", sexp);
list = gcry_sexp_find_token (sexp, item, 0);
log_assert (list);
value = gcry_sexp_nth_data (list, 1, &valuelen);
log_assert (value);
v = xtrymalloc (valuelen);
memcpy (v, value, valuelen);
gcry_sexp_release (list);
*r_size = valuelen;
return v;
}
/****************
* Emulate our old PK interface here - sometime in the future we might
@ -309,12 +331,19 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
;
else if (algo == PUBKEY_ALGO_ECDH)
{
gcry_mpi_t shared, public, result;
gcry_mpi_t public, result;
byte fp[MAX_FINGERPRINT_LEN];
size_t fpn;
byte *shared;
size_t nshared;
/* Get the shared point and the ephemeral public key. */
shared = get_mpi_from_sexp (s_ciph, "s", GCRYMPI_FMT_USG);
shared = get_data_from_sexp (s_ciph, "s", &nshared);
if (!shared)
{
rc = gpg_error_from_syserror ();
goto leave;
}
public = get_mpi_from_sexp (s_ciph, "e", GCRYMPI_FMT_USG);
gcry_sexp_release (s_ciph);
s_ciph = NULL;
@ -330,9 +359,10 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
if (fpn != 20)
rc = gpg_error (GPG_ERR_INV_LENGTH);
else
rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared,
rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/,
shared, nshared,
fp, data, pkey, &result);
gcry_mpi_release (shared);
xfree (shared);
if (!rc)
{
resarr[0] = public;
@ -352,6 +382,7 @@ pk_encrypt (pubkey_algo_t algo, gcry_mpi_t *resarr, gcry_mpi_t data,
resarr[1] = get_mpi_from_sexp (s_ciph, "b", GCRYMPI_FMT_USG);
}
leave:
gcry_sexp_release (s_ciph);
return rc;
}