summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2014-08-21 11:39:17 +0200
committerWerner Koch <wk@gnupg.org>2014-08-21 12:22:37 +0200
commit18056ace7f466cb8c1eaf08e5dc0400516d83b4c (patch)
treec9da7e759ba962071b2a961082d2c5a32326df58
parent34bb55ee36df3aca3ebca88f8b61c786cd0c0701 (diff)
downloadlibgcrypt-18056ace7f466cb8c1eaf08e5dc0400516d83b4c.tar.gz
cipher: Fix possible NULL deref in call to prime generator.
* cipher/primegen.c (_gcry_generate_elg_prime): Change to return an error code. * cipher/dsa.c (generate): Take care of new return code. * cipher/elgamal.c (generate): Change to return an error code. Take care of _gcry_generate_elg_prime return code. (generate_using_x): Take care of _gcry_generate_elg_prime return code. (elg_generate): Propagate return code from generate. -- GnuPG-bug-id: 1699, 1700 Reported-by: S.K. Gupta Note that the NULL deref may have only happened on malloc failure.
-rw-r--r--cipher/dsa.c6
-rw-r--r--cipher/elgamal.c28
-rw-r--r--cipher/primegen.c25
-rw-r--r--src/g10lib.h9
4 files changed, 47 insertions, 21 deletions
diff --git a/cipher/dsa.c b/cipher/dsa.c
index 1707d8cf..09cd9693 100644
--- a/cipher/dsa.c
+++ b/cipher/dsa.c
@@ -196,6 +196,7 @@ static gpg_err_code_t
generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors )
{
+ gpg_err_code_t rc;
gcry_mpi_t p; /* the prime */
gcry_mpi_t q; /* the 160 bit prime factor */
gcry_mpi_t g; /* the generator */
@@ -247,7 +248,10 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
else
{
/* Generate new domain parameters. */
- p = _gcry_generate_elg_prime (1, nbits, qbits, NULL, ret_factors);
+ rc = _gcry_generate_elg_prime (1, nbits, qbits, NULL, &p, ret_factors);
+ if (rc)
+ return rc;
+
/* Get q out of factors. */
q = mpi_copy ((*ret_factors)[0]);
gcry_assert (mpi_get_nbits (q) == qbits);
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index a71a9bcb..cb3ca43a 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -61,7 +61,8 @@ static const char *elg_names[] =
static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie);
static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k);
-static void generate (ELG_secret_key *sk, unsigned nbits, gcry_mpi_t **factors);
+static gcry_err_code_t generate (ELG_secret_key *sk, unsigned nbits,
+ gcry_mpi_t **factors);
static int check_secret_key (ELG_secret_key *sk);
static void do_encrypt (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
ELG_public_key *pkey);
@@ -268,9 +269,10 @@ gen_k( gcry_mpi_t p, int small_k )
* Returns: 2 structures filled with all needed values
* and an array with n-1 factors of (p-1)
*/
-static void
+static gcry_err_code_t
generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
{
+ gcry_err_code_t rc;
gcry_mpi_t p; /* the prime */
gcry_mpi_t p_min1;
gcry_mpi_t g;
@@ -285,7 +287,13 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
if( qbits & 1 ) /* better have a even one */
qbits++;
g = mpi_alloc(1);
- p = _gcry_generate_elg_prime( 0, nbits, qbits, g, ret_factors );
+ rc = _gcry_generate_elg_prime (0, nbits, qbits, g, &p, ret_factors);
+ if (rc)
+ {
+ mpi_free (p_min1);
+ mpi_free (g);
+ return rc;
+ }
mpi_sub_ui(p_min1, p, 1);
@@ -359,6 +367,8 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
/* Now we can test our keys (this should never fail!) */
test_keys ( sk, nbits - 64, 0 );
+
+ return 0;
}
@@ -373,6 +383,7 @@ static gcry_err_code_t
generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
gcry_mpi_t **ret_factors )
{
+ gcry_err_code_t rc;
gcry_mpi_t p; /* The prime. */
gcry_mpi_t p_min1; /* The prime minus 1. */
gcry_mpi_t g; /* The generator. */
@@ -395,7 +406,13 @@ generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
if ( (qbits & 1) ) /* Better have an even one. */
qbits++;
g = mpi_alloc (1);
- p = _gcry_generate_elg_prime ( 0, nbits, qbits, g, ret_factors );
+ rc = _gcry_generate_elg_prime (0, nbits, qbits, g, &p, ret_factors );
+ if (rc)
+ {
+ mpi_free (p_min1);
+ mpi_free (g);
+ return rc;
+ }
mpi_sub_ui (p_min1, p, 1);
if (DBG_CIPHER)
@@ -662,8 +679,7 @@ elg_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
}
else
{
- generate (&sk, nbits, &factors);
- rc = 0;
+ rc = generate (&sk, nbits, &factors);
}
if (rc)
goto leave;
diff --git a/cipher/primegen.c b/cipher/primegen.c
index 9f6ec705..14a5ccfe 100644
--- a/cipher/primegen.c
+++ b/cipher/primegen.c
@@ -726,19 +726,22 @@ prime_generate_internal (int need_q_factor,
/* Generate a prime used for discrete logarithm algorithms; i.e. this
- prime will be public and no strong random is required. */
-gcry_mpi_t
+ prime will be public and no strong random is required. On success
+ R_PRIME receives a new MPI with the prime. On error R_PRIME is set
+ to NULL and an error code is returned. If RET_FACTORS is not NULL
+ it is set to an allocated array of factors on success or to NULL on
+ error. */
+gcry_err_code_t
_gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
- gcry_mpi_t g, gcry_mpi_t **ret_factors)
+ gcry_mpi_t g,
+ gcry_mpi_t *r_prime, gcry_mpi_t **ret_factors)
{
- gcry_mpi_t prime = NULL;
-
- if (prime_generate_internal ((mode == 1), &prime, pbits, qbits, g,
- ret_factors, GCRY_WEAK_RANDOM, 0, 0,
- NULL, NULL))
- prime = NULL; /* (Should be NULL in the error case anyway.) */
-
- return prime;
+ *r_prime = NULL;
+ if (ret_factors)
+ *ret_factors = NULL;
+ return prime_generate_internal ((mode == 1), r_prime, pbits, qbits, g,
+ ret_factors, GCRY_WEAK_RANDOM, 0, 0,
+ NULL, NULL);
}
diff --git a/src/g10lib.h b/src/g10lib.h
index 43dc0113..238871d0 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -236,9 +236,12 @@ gcry_mpi_t _gcry_generate_public_prime (unsigned int nbits,
gcry_random_level_t random_level,
int (*extra_check)(void*, gcry_mpi_t),
void *extra_check_arg);
-gcry_mpi_t _gcry_generate_elg_prime (int mode,
- unsigned int pbits, unsigned int qbits,
- gcry_mpi_t g, gcry_mpi_t **factors);
+gcry_err_code_t _gcry_generate_elg_prime (int mode,
+ unsigned int pbits,
+ unsigned int qbits,
+ gcry_mpi_t g,
+ gcry_mpi_t *r_prime,
+ gcry_mpi_t **factors);
gcry_mpi_t _gcry_derive_x931_prime (const gcry_mpi_t xp,
const gcry_mpi_t xp1, const gcry_mpi_t xp2,
const gcry_mpi_t e,