summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2016-02-02 13:58:48 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2016-02-02 13:58:48 +0900
commita2f9afcd7fcdafd5951498b07f34957f9766dce9 (patch)
treea9881b14d01cd7165f3f2826e6e0bb9b13d84a70
parent57b60bb1718b4f2c2500bb447ebd1d4562a5aa9b (diff)
downloadlibgcrypt-a2f9afcd7fcdafd5951498b07f34957f9766dce9.tar.gz
ecc: Fix ECDH of Curve25519.
* cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): Fix calc of NBITS and prefix detection. * cipher/ecc.c (ecc_generate): Use NBITS instead of CTX->NBITS. (ecc_encrypt_raw): Use NBITS from curve instead of from P. Fix rawmpilen calculation. (ecc_decrypt_raw): Likewise. Add debug output. -- This fixes the commit dd3d06e7. NBITS is defined 256 in ecc-curves.c, thus, ecc_get_nbits returns 256. But CTX->NBITS has 255 for Montgomery curve.
-rw-r--r--cipher/ecc-misc.c21
-rw-r--r--cipher/ecc.c24
2 files changed, 27 insertions, 18 deletions
diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c
index 67e3b3d8..33af6f74 100644
--- a/cipher/ecc-misc.c
+++ b/cipher/ecc-misc.c
@@ -322,7 +322,9 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result)
}
else
{
- a = rawmpi = _gcry_mpi_get_buffer (pk, ctx->nbits/8, &rawmpilen, NULL);
+ unsigned int nbytes = (ctx->nbits+7)/8;
+
+ a = rawmpi = _gcry_mpi_get_buffer (pk, nbytes, &rawmpilen, NULL);
if (!a)
return gpg_err_code_from_syserror ();
/*
@@ -339,16 +341,17 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result)
* So, we need to check if it's really the prefix or not.
* Only when it's the prefix, we remove it.
*/
- if (ctx->nbits/8 == rawmpilen - 1)
- rawmpi++;
- else if (rawmpilen < ctx->nbits/8)
+ if (rawmpilen > nbytes)
+ {/* Prefix 0x40 or 0x00 */
+ rawmpi++;
+ rawmpilen = nbytes;
+ }
+ else if (rawmpilen < nbytes)
{/*
* It is possible for data created by older implementation
* to have shorter length when it was parsed as MPI.
*/
- unsigned int new_rawmpilen = ctx->nbits/8;
-
- rawmpi = xtrymalloc (new_rawmpilen);
+ rawmpi = xtrymalloc (nbytes);
if (!rawmpi)
{
gpg_err_code_t err = gpg_err_code_from_syserror ();
@@ -356,8 +359,8 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result)
return err;
}
- memset (rawmpi, 0, new_rawmpilen - rawmpilen);
- memcpy (rawmpi + new_rawmpilen - rawmpilen, a, rawmpilen);
+ memset (rawmpi, 0, nbytes - rawmpilen);
+ memcpy (rawmpi + nbytes - rawmpilen, a, rawmpilen);
}
}
diff --git a/cipher/ecc.c b/cipher/ecc.c
index 105650e0..7d6ad94c 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -606,8 +606,8 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
&encpk, &encpklen);
else
{
- encpk = _gcry_mpi_get_buffer_extra (Qx, ctx->nbits/8, -1,
- &encpklen, NULL);
+ encpk = _gcry_mpi_get_buffer_extra (Qx, nbits/8,
+ -1, &encpklen, NULL);
if (encpk == NULL)
rc = gpg_err_code_from_syserror ();
else
@@ -1231,6 +1231,7 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
static gcry_err_code_t
ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
{
+ unsigned int nbits;
gcry_err_code_t rc;
struct pk_encoding_ctx ctx;
gcry_sexp_t l1 = NULL;
@@ -1246,7 +1247,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
memset (&pk, 0, sizeof pk);
_gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
- ecc_get_nbits (keyparms));
+ (nbits = ecc_get_nbits (keyparms)));
/* Look for flags. */
l1 = sexp_find_token (keyparms, "flags", 0);
@@ -1371,13 +1372,13 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p);
else
{
- rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1,
- &rawmpilen, NULL);
+ rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL);
if (!rawmpi)
rc = gpg_err_code_from_syserror ();
else
{
rawmpi[0] = 0x40;
+ rawmpilen++;
mpi_s = mpi_new (0);
mpi_set_opaque (mpi_s, rawmpi, rawmpilen*8);
}
@@ -1392,13 +1393,13 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p);
else
{
- rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1,
- &rawmpilen, NULL);
+ rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL);
if (!rawmpi)
rc = gpg_err_code_from_syserror ();
else
{
rawmpi[0] = 0x40;
+ rawmpilen++;
mpi_e = mpi_new (0);
mpi_set_opaque (mpi_e, rawmpi, rawmpilen*8);
}
@@ -1447,6 +1448,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
static gcry_err_code_t
ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
{
+ unsigned int nbits;
gpg_err_code_t rc;
struct pk_encoding_ctx ctx;
gcry_sexp_t l1 = NULL;
@@ -1465,7 +1467,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
point_init (&R);
_gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
- ecc_get_nbits (keyparms));
+ (nbits = ecc_get_nbits (keyparms)));
/* Look for flags. */
l1 = sexp_find_token (keyparms, "flags", 0);
@@ -1565,6 +1567,9 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
if (rc)
goto leave;
+ if (DBG_CIPHER)
+ log_printpnt ("ecc_decrypt kG", &kG, NULL);
+
/* R = dkG */
_gcry_mpi_ec_mul_point (&R, sk.d, &kG, ec);
@@ -1588,7 +1593,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
unsigned char *rawmpi;
unsigned int rawmpilen;
- rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1,
+ rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1,
&rawmpilen, NULL);
if (!rawmpi)
{
@@ -1598,6 +1603,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
else
{
rawmpi[0] = 0x40;
+ rawmpilen++;
r = mpi_new (0);
mpi_set_opaque (r, rawmpi, rawmpilen*8);
}