diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2019-10-08 16:08:52 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2019-10-08 16:08:52 +0900 |
commit | d66a4856eb0c39823bf3414b3ca4cf6322f32aef (patch) | |
tree | eb322bdb83210a66d9c03ca45449e1c38b0da2d8 /cipher/ecc.c | |
parent | 254c5279058f0aea2d3568d6e756002242e82f8f (diff) | |
download | libgcrypt-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.c | 58 |
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); |