aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2021-03-29 12:36:52 +0000
committerWerner Koch <[email protected]>2021-03-29 12:36:52 +0000
commitf129b0e97730b47d62482fba9599db39b526f3d2 (patch)
tree847af18cb7713093d8b1da266ee2596ff4261d81
parentgpgconf: Do not i18n an empty string to the PO files meta data. (diff)
downloadgnupg-f129b0e97730b47d62482fba9599db39b526f3d2.tar.gz
gnupg-f129b0e97730b47d62482fba9599db39b526f3d2.zip
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.
-rw-r--r--g10/ecdh.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/g10/ecdh.c b/g10/ecdh.c
index 9a1f535a0..d048951d7 100644
--- a/g10/ecdh.c
+++ b/g10/ecdh.c
@@ -101,9 +101,13 @@ extract_secret_x (byte **r_secret_x,
41 || X
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)
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
shared secret. */
@@ -113,13 +117,18 @@ extract_secret_x (byte **r_secret_x,
memcpy (secret_x, shared, nshared);
- /* Remove the prefix. */
- if ((point_nbytes & 1))
- memmove (secret_x, secret_x+1, secret_x_size);
+ /* Wrangle the provided point unless only the x-component w/o any
+ * prefix was provided. */
+ 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. */
- if (point_nbytes - secret_x_size)
- memset (secret_x+secret_x_size, 0, point_nbytes-secret_x_size);
+ /* Clear the rest of data. */
+ if (point_nbytes - secret_x_size)
+ memset (secret_x+secret_x_size, 0, point_nbytes-secret_x_size);
+ }
if (DBG_CRYPTO)
log_printhex (secret_x, secret_x_size, "ECDH shared secret X is:");