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

* g10/ecdh.c (extract_secret_x): Add extra safety check. Allow for
x-only coordinate.
This commit is contained in:
Werner Koch 2021-03-29 14:36:52 +02:00
parent 18d884f841
commit f129b0e977
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
1 changed files with 16 additions and 7 deletions

View File

@ -101,9 +101,13 @@ extract_secret_x (byte **r_secret_x,
41 || X 41 || X
Since it may come with the prefix, the size of point is larger Since it may come with the prefix, the size of point is larger
than or equals to the size of an integer X. */ than or equals to the size of an integer X. We also better check
that the provided shared point is not larger than the size needed
to represent the point. */
if (point_nbytes < secret_x_size) if (point_nbytes < secret_x_size)
return gpg_error (GPG_ERR_BAD_DATA); return gpg_error (GPG_ERR_BAD_DATA);
if (point_nbytes < nshared)
return gpg_error (GPG_ERR_BAD_DATA);
/* Extract x component of the shared point: this is the actual /* Extract x component of the shared point: this is the actual
shared secret. */ shared secret. */
@ -113,13 +117,18 @@ extract_secret_x (byte **r_secret_x,
memcpy (secret_x, shared, nshared); memcpy (secret_x, shared, nshared);
/* Remove the prefix. */ /* Wrangle the provided point unless only the x-component w/o any
if ((point_nbytes & 1)) * prefix was provided. */
memmove (secret_x, secret_x+1, secret_x_size); if (nshared != secret_x_size)
{
/* Remove the prefix. */
if ((point_nbytes & 1))
memmove (secret_x, secret_x+1, secret_x_size);
/* Clear the rest of data. */ /* Clear the rest of data. */
if (point_nbytes - secret_x_size) if (point_nbytes - secret_x_size)
memset (secret_x+secret_x_size, 0, point_nbytes-secret_x_size); memset (secret_x+secret_x_size, 0, point_nbytes-secret_x_size);
}
if (DBG_CRYPTO) if (DBG_CRYPTO)
log_printhex (secret_x, secret_x_size, "ECDH shared secret X is:"); log_printhex (secret_x, secret_x_size, "ECDH shared secret X is:");