summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2020-10-30 10:07:35 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2020-10-30 10:07:35 +0900
commit361a0588489cf4a539da8debd1771024a1faa218 (patch)
tree4dd7902b7d97ae9ca82caace73dc55c57a37771b
parent24341f58f0d38bd62c45d285bcf8472f82b56135 (diff)
downloadlibgcrypt-361a0588489cf4a539da8debd1771024a1faa218.tar.gz
ecc: Handle removed zeros at the beginning for Ed25519.
* cipher/ecc-curves.c (mpi_ec_setup_elliptic_curve): Accept private key with removed zeros. -- We have existing keys of Ed25519, which was created by implementations before SOS clarification. We should support those keys and implementations with no SOS support. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r--cipher/ecc-curves.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c
index a019e054..63a38fec 100644
--- a/cipher/ecc-curves.c
+++ b/cipher/ecc-curves.c
@@ -1155,7 +1155,7 @@ mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags,
errc = mpi_from_keyparam (&ec->d, keyparam, "d", is_opaque_bytes);
/* Size of opaque bytes should match size of P. */
- if (ec->d && is_opaque_bytes)
+ if (!errc && ec->d && is_opaque_bytes)
{
unsigned int n = mpi_get_nbits (ec->d);
unsigned int len;
@@ -1167,11 +1167,36 @@ mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags,
if ((n+7)/8 != len)
{
- if (DBG_CIPHER)
- log_debug ("scalar size (%d) != prime size (%d)",
- (n+7)/8, len);
+ if ((n+7)/8 < len && ec->dialect == ECC_DIALECT_ED25519)
+ {
+ /*
+ * GnuPG (<= 2.2) or OpenPGP implementations with no
+ * SOS support may remove zeros at the beginning.
+ * Recover those zeros.
+ */
+ const unsigned char *buf;
+ unsigned char *value;
+
+ buf = mpi_get_opaque (ec->d, &n);
+ if (!buf)
+ return GPG_ERR_INV_OBJ;
+
+ value = xtrycalloc_secure (1, 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);
+ }
+ else
+ {
+ if (DBG_CIPHER)
+ log_debug ("scalar size (%d) != prime size (%d)",
+ (n+7)/8, len);
- errc = GPG_ERR_INV_OBJ;
+ errc = GPG_ERR_INV_OBJ;
+ }
}
}
}