summaryrefslogtreecommitdiff
path: root/cipher/ecc-curves.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2021-01-26 10:59:15 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2021-01-26 10:59:15 +0900
commit1b74f633bd3e358fb07a856a70597019980651d2 (patch)
tree0bcb8f333ffc00a6e19372a45db49c6d0bc67340 /cipher/ecc-curves.c
parent652b102697cbfe2d7bc642fc7374cb21a9cf03e6 (diff)
downloadlibgcrypt-1b74f633bd3e358fb07a856a70597019980651d2.tar.gz
ecc: Fix Ed25519 private key handling for preceding ZEROs.
* cipher/ecc-curves.c (mpi_ec_setup_elliptic_curve): Fill-up or remove preceding ZEROs correctly, fixing the third argument of mpi_set_opaque. -- Reported-by: Vladimir Lomov <lomov.vl@yandex.ru> GnuPG-bug-id: 5267 Fixes-commit: 361a0588489cf4a539da8debd1771024a1faa218 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'cipher/ecc-curves.c')
-rw-r--r--cipher/ecc-curves.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c
index 26006d6c..900b668a 100644
--- a/cipher/ecc-curves.c
+++ b/cipher/ecc-curves.c
@@ -1200,13 +1200,18 @@ mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags,
if ((n+7)/8 != len)
{
- if ((n+7)/8 < len && ec->dialect == ECC_DIALECT_ED25519)
+ if (ec->dialect == ECC_DIALECT_ED25519)
{
/*
* GnuPG (<= 2.2) or OpenPGP implementations with no
* SOS support may remove zeros at the beginning.
* Recover those zeros.
*/
+ /*
+ * Also, GnuPG (<= 2.2) may add additional zero at
+ * the beginning, when private key is moved from
+ * OpenPGP to gpg-agent. Remove such a zero-prefix.
+ */
const unsigned char *buf;
unsigned char *value;
@@ -1214,13 +1219,26 @@ mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags,
if (!buf)
return GPG_ERR_INV_OBJ;
- value = xtrycalloc_secure (1, len);
+ value = xtrymalloc_secure (len);
if (!value)
return gpg_err_code_from_syserror ();
- memset (value, 0, len - (n+7)/8);
- memcpy (value + len - (n+7)/8, buf, (n+7)/8);
- mpi_set_opaque (ec->d, value, len);
+ if ((n+7)/8 < len)
+ /* Recover zeros. */
+ {
+ memset (value, 0, len - (n+7)/8);
+ memcpy (value + len - (n+7)/8, buf, (n+7)/8);
+ }
+ else if ((n+7)/8 == len + 1)
+ /* Remove a zero. */
+ memcpy (value, buf+1, len);
+ else
+ {
+ xfree (value);
+ return GPG_ERR_INV_OBJ;
+ }
+
+ mpi_set_opaque (ec->d, value, len*8);
}
else
{