From 6cb6df9dddac6ad246002b83c2ce0aaa0ecf30e5 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 2 Feb 2016 20:58:04 +0900 Subject: ecc: Fix Curve25519 for data by older implementation. * cipher/ecc-misc.c (gcry_ecc_mont_decodepoint): Fix code path for short length data. -- Signed-off-by: NIIBE Yutaka --- cipher/ecc-misc.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index e0dfec3c..8f7b8c4d 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -292,7 +292,6 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec, gpg_err_code_t _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) { - unsigned char *a; unsigned char *rawmpi; unsigned int rawmpilen; @@ -312,8 +311,8 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) buf++; } - a = rawmpi = xtrymalloc (rawmpilen? rawmpilen:1); - if (!a) + rawmpi = xtrymalloc (rawmpilen? rawmpilen:1); + if (!rawmpi) return gpg_err_code_from_syserror (); p = rawmpi + rawmpilen; @@ -324,8 +323,8 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) { unsigned int nbytes = (ctx->nbits+7)/8; - a = rawmpi = _gcry_mpi_get_buffer (pk, nbytes, &rawmpilen, NULL); - if (!a) + rawmpi = _gcry_mpi_get_buffer (pk, nbytes, &rawmpilen, NULL); + if (!rawmpi) return gpg_err_code_from_syserror (); /* * It is not reliable to assume that 0x40 means the prefix. @@ -341,30 +340,29 @@ _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 (rawmpilen > nbytes) - /* Prefix 0x40 or 0x00, which comes at the end (reverse) */ - rawmpilen = nbytes; - else if (rawmpilen < nbytes) + if (pk->nlimbs * BYTES_PER_MPI_LIMB < nbytes) {/* * It is possible for data created by older implementation * to have shorter length when it was parsed as MPI. */ - rawmpi = xtrymalloc (nbytes); - if (!rawmpi) - { - gpg_err_code_t err = gpg_err_code_from_syserror (); - xfree (a); - return err; - } - - memset (rawmpi, 0, nbytes - rawmpilen); - memcpy (rawmpi + nbytes - rawmpilen, a, rawmpilen); + unsigned int len = pk->nlimbs * BYTES_PER_MPI_LIMB; + + memmove (rawmpi + nbytes - len, rawmpi, len); + memset (rawmpi, 0, nbytes - len); } + + /* + * When we have the prefix (0x40 or 0x00), it comes at the end, + * since it is taken by _gcry_mpi_get_buffer with little endian. + * Just setting RAWMPILEN to NBYTES is enough in this case. + * Othewise, RAWMPILEN is NBYTES already. + */ + rawmpilen = nbytes; } rawmpi[0] &= (1 << (ctx->nbits % 8)) - 1; _gcry_mpi_set_buffer (result->x, rawmpi, rawmpilen, 0); - xfree (a); + xfree (rawmpi); mpi_set_ui (result->z, 1); return 0; -- cgit v1.2.1