From a2f9afcd7fcdafd5951498b07f34957f9766dce9 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 2 Feb 2016 13:58:48 +0900 Subject: 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. --- cipher/ecc-misc.c | 21 ++++++++++++--------- cipher/ecc.c | 24 +++++++++++++++--------- 2 files changed, 27 insertions(+), 18 deletions(-) (limited to 'cipher') 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); } -- cgit v1.2.1