diff options
author | Werner Koch <wk@gnupg.org> | 2012-11-07 15:02:06 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2012-11-07 15:06:11 +0100 |
commit | 423571e111d54dbf0aa6cc7e7ef1516ae4327b3d (patch) | |
tree | 94e88b22471484fbd663bc297a1cd78c403f1417 | |
parent | 542d354b902c72d7fb19f9a0e5f3f3d21909f21a (diff) | |
download | libgcrypt-423571e111d54dbf0aa6cc7e7ef1516ae4327b3d.tar.gz |
Fix memory leak in gcry_pk_testkey for ECC.
* cipher/ecc.c (check_secret_key): Restructure for easier allocation
tracking. Fix memory leak.
-rw-r--r-- | cipher/ecc.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/cipher/ecc.c b/cipher/ecc.c index bbff7eec..b8487dc1 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -642,47 +642,48 @@ test_keys (ECC_secret_key *sk, unsigned int nbits) static int check_secret_key (ECC_secret_key * sk) { + int rc = 1; mpi_point_t Q; - gcry_mpi_t y_2, y2 = mpi_alloc (0); - mpi_ec_t ctx; + gcry_mpi_t y_2, y2; + mpi_ec_t ctx = NULL; + + point_init (&Q); /* ?primarity test of 'p' */ /* (...) //!! */ /* G in E(F_p) */ y_2 = gen_y_2 (sk->E.G.x, &sk->E); /* y^2=x^3+a*x+b */ + y2 = mpi_alloc (0); mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p); /* y^2=y*y */ if (mpi_cmp (y_2, y2)) { if (DBG_CIPHER) log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n"); - return (1); + goto leave; } /* G != PaI */ if (!mpi_cmp_ui (sk->E.G.z, 0)) { if (DBG_CIPHER) log_debug ("Bad check: 'G' cannot be Point at Infinity!\n"); - return (1); + goto leave; } - point_init (&Q); ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a); + _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx); if (mpi_cmp_ui (Q.z, 0)) { if (DBG_CIPHER) log_debug ("check_secret_key: E is not a curve of order n\n"); - point_free (&Q); - _gcry_mpi_ec_free (ctx); - return 1; + goto leave; } /* pubkey cannot be PaI */ if (!mpi_cmp_ui (sk->Q.z, 0)) { if (DBG_CIPHER) log_debug ("Bad check: Q can not be a Point at Infinity!\n"); - _gcry_mpi_ec_free (ctx); - return (1); + goto leave; } /* pubkey = [d]G over E */ _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx); @@ -691,12 +692,16 @@ check_secret_key (ECC_secret_key * sk) if (DBG_CIPHER) log_debug ("Bad check: There is NO correspondence between 'd' and 'Q'!\n"); - _gcry_mpi_ec_free (ctx); - return (1); + goto leave; } + rc = 0; /* Okay. */ + + leave: _gcry_mpi_ec_free (ctx); + mpi_free (y2); + mpi_free (y_2); point_free (&Q); - return 0; + return rc; } |