summaryrefslogtreecommitdiff
path: root/cipher/ecc.c
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2019-10-08 16:08:52 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2019-10-08 16:08:52 +0900
commitd66a4856eb0c39823bf3414b3ca4cf6322f32aef (patch)
treeeb322bdb83210a66d9c03ca45449e1c38b0da2d8 /cipher/ecc.c
parent254c5279058f0aea2d3568d6e756002242e82f8f (diff)
downloadlibgcrypt-d66a4856eb0c39823bf3414b3ca4cf6322f32aef.tar.gz
ecc: Fix hard-coded value for 25519 to allow other modern curves.
* cipher/ecc.c (nist_generate_key): Support other modern curves. (test_ecdh_only_keys): Likewise. (check_secret_key): Don't use ECC_DIALECT_ED25519 for the check. (_gcry_pk_ecc_get_sexp): Support Montgomery curve. Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'cipher/ecc.c')
-rw-r--r--cipher/ecc.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/cipher/ecc.c b/cipher/ecc.c
index 52e379a4..4679eca2 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -164,13 +164,17 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
if (ctx->dialect == ECC_DIALECT_ED25519 || (flags & PUBKEY_FLAG_DJB_TWEAK))
{
char *rndbuf;
-
- sk->d = mpi_snew (256);
- rndbuf = _gcry_random_bytes_secure (32, random_level);
- rndbuf[0] &= 0x7f; /* Clear bit 255. */
- rndbuf[0] |= 0x40; /* Set bit 254. */
- rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0 */
- _gcry_mpi_set_buffer (sk->d, rndbuf, 32, 0);
+ int len = (pbits+7)/8;
+ unsigned int h;
+
+ mpi_get_ui (&h, E->h);
+ sk->d = mpi_snew (pbits);
+ rndbuf = _gcry_random_bytes_secure (len, random_level);
+ if ((pbits % 8))
+ rndbuf[0] &= (1 << (pbits % 8)) - 1;
+ rndbuf[0] |= (1 << ((pbits + 7) % 8));
+ rndbuf[(pbits-1)/8] &= (256 - h);
+ _gcry_mpi_set_buffer (sk->d, rndbuf, len, 0);
xfree (rndbuf);
}
else
@@ -341,13 +345,18 @@ test_ecdh_only_keys (ECC_secret_key *sk, unsigned int nbits, int flags)
if ((flags & PUBKEY_FLAG_DJB_TWEAK))
{
char *rndbuf;
-
- test = mpi_new (256);
- rndbuf = _gcry_random_bytes (32, GCRY_WEAK_RANDOM);
- rndbuf[0] &= 0x7f; /* Clear bit 255. */
- rndbuf[0] |= 0x40; /* Set bit 254. */
- rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0 */
- _gcry_mpi_set_buffer (test, rndbuf, 32, 0);
+ const unsigned int pbits = mpi_get_nbits (sk->E.p);
+ int len = (pbits+7)/8;
+ unsigned int h;
+
+ mpi_get_ui (&h, sk->E.h);
+ test = mpi_new (pbits);
+ rndbuf = _gcry_random_bytes (len, GCRY_WEAK_RANDOM);
+ if ((pbits % 8))
+ rndbuf[0] &= (1 << (pbits % 8)) - 1;
+ rndbuf[0] |= (1 << ((pbits + 7) % 8));
+ rndbuf[(pbits-1)/8] &= (256 - h);
+ _gcry_mpi_set_buffer (test, rndbuf, len, 0);
xfree (rndbuf);
}
else
@@ -431,7 +440,7 @@ check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags)
}
/* Check order of curve. */
- if (sk->E.dialect != ECC_DIALECT_ED25519 && !(flags & PUBKEY_FLAG_DJB_TWEAK))
+ if (sk->E.dialect == ECC_DIALECT_STANDARD && !(flags & PUBKEY_FLAG_DJB_TWEAK))
{
_gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ec);
if (mpi_cmp_ui (Q.z, 0))
@@ -2008,6 +2017,25 @@ _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
mpi_Q = mpi_set_opaque (NULL, encpk, encpklen*8);
encpk = NULL;
}
+ else if (ec->model == MPI_EC_MONTGOMERY)
+ {
+ unsigned char *encpk;
+ unsigned int encpklen;
+
+ encpk = _gcry_mpi_get_buffer_extra (ec->Q->x, (ec->nbits+7)/8,
+ -1, &encpklen, NULL);
+ if (encpk == NULL)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ encpk[0] = 0x40;
+ encpklen++;
+ rc = 0;
+ }
+ if (rc)
+ goto leave;
+ mpi_Q = mpi_set_opaque (NULL, encpk, encpklen*8);
+ }
else
{
mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);