summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cipher/dsa.c203
-rw-r--r--cipher/ecc.c101
-rw-r--r--cipher/elgamal.c171
-rw-r--r--cipher/pubkey.c208
-rw-r--r--cipher/rsa.c59
-rw-r--r--src/cipher-proto.h17
6 files changed, 279 insertions, 480 deletions
diff --git a/cipher/dsa.c b/cipher/dsa.c
index 13a4fc26..ceff947c 100644
--- a/cipher/dsa.c
+++ b/cipher/dsa.c
@@ -271,7 +271,7 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
* part. The random quality depends on the transient_key flag. */
random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
if (DBG_CIPHER)
- log_debug("choosing a random x%s", transient_key? " (transient-key)":"");
+ log_debug("choosing a random x%s\n", transient_key? " (transient-key)":"");
gcry_assert( qbits >= 160 );
x = mpi_alloc_secure( mpi_get_nlimbs(q) );
mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
@@ -689,25 +689,26 @@ verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
*********************************************/
static gcry_err_code_t
-dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
- const gcry_sexp_t genparms,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors,
- gcry_sexp_t *r_extrainfo)
+dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
+ const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
{
- gpg_err_code_t ec;
+ gpg_err_code_t rc;
DSA_secret_key sk;
gcry_sexp_t l1;
unsigned int qbits = 0;
gcry_sexp_t deriveparms = NULL;
gcry_sexp_t seedinfo = NULL;
+ gcry_sexp_t misc_info = NULL;
int transient_key = 0;
int use_fips186_2 = 0;
int use_fips186 = 0;
dsa_domain_t domain;
+ gcry_mpi_t *factors = NULL;
(void)algo; /* No need to check it. */
(void)evalue; /* Not required for DSA. */
+ memset (&sk, 0, sizeof sk);
memset (&domain, 0, sizeof domain);
if (genparms)
@@ -809,141 +810,116 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
size_t seedlen;
gcry_mpi_t h_value;
- ec = generate_fips186 (&sk, nbits, qbits, deriveparms, use_fips186_2,
+ rc = generate_fips186 (&sk, nbits, qbits, deriveparms, use_fips186_2,
&domain,
&counter, &seed, &seedlen, &h_value);
- gcry_sexp_release (deriveparms);
- if (!ec && h_value)
+ if (!rc && h_value)
{
/* Format the seed-values unless domain parameters are used
for which a H_VALUE of NULL is an indication. */
- ec = gpg_err_code (gcry_sexp_build
+ rc = gpg_err_code (gcry_sexp_build
(&seedinfo, NULL,
"(seed-values(counter %d)(seed %b)(h %m))",
counter, (int)seedlen, seed, h_value));
- if (ec)
- {
- gcry_mpi_release (sk.p); sk.p = NULL;
- gcry_mpi_release (sk.q); sk.q = NULL;
- gcry_mpi_release (sk.g); sk.g = NULL;
- gcry_mpi_release (sk.y); sk.y = NULL;
- gcry_mpi_release (sk.x); sk.x = NULL;
- }
gcry_free (seed);
gcry_mpi_release (h_value);
}
}
else
{
- ec = generate (&sk, nbits, qbits, transient_key, &domain, retfactors);
+ rc = generate (&sk, nbits, qbits, transient_key, &domain, &factors);
}
- gcry_mpi_release (domain.p);
- gcry_mpi_release (domain.q);
- gcry_mpi_release (domain.g);
-
- if (!ec)
+ if (!rc)
{
- skey[0] = sk.p;
- skey[1] = sk.q;
- skey[2] = sk.g;
- skey[3] = sk.y;
- skey[4] = sk.x;
-
- if (!r_extrainfo)
- {
- /* Old style interface - return the factors - if any - at
- retfactors. */
- }
- else if (!*retfactors && !seedinfo)
- {
- /* No factors and no seedinfo, thus there is nothing to return. */
- *r_extrainfo = NULL;
- }
+ /* Put the factors into MISC_INFO. Note that the factors are
+ not confidential thus we can store them in standard memory. */
+ int nfactors, i, j;
+ char *p;
+ char *format = NULL;
+ void **arg_list = NULL;
+
+ for (nfactors=0; factors && factors[nfactors]; nfactors++)
+ ;
+ /* Allocate space for the format string:
+ "(misc-key-info%S(pm1-factors%m))"
+ with one "%m" for each factor and construct it. */
+ format = gcry_malloc (50 + 2*nfactors);
+ if (!format)
+ rc = gpg_err_code_from_syserror ();
else
{
- /* Put the factors into extrainfo and set retfactors to NULL
- to make use of the new interface. Note that the factors
- are not confidential thus we can store them in standard
- memory. */
- int nfactors, i, j;
- char *p;
- char *format = NULL;
- void **arg_list = NULL;
-
- for (nfactors=0; *retfactors && (*retfactors)[nfactors]; nfactors++)
- ;
- /* Allocate space for the format string:
- "(misc-key-info%S(pm1-factors%m))"
- with one "%m" for each factor and construct it. */
- format = gcry_malloc (50 + 2*nfactors);
- if (!format)
- ec = gpg_err_code_from_syserror ();
- else
+ p = stpcpy (format, "(misc-key-info");
+ if (seedinfo)
+ p = stpcpy (p, "%S");
+ if (nfactors)
{
- p = stpcpy (format, "(misc-key-info");
- if (seedinfo)
- p = stpcpy (p, "%S");
- if (nfactors)
- {
- p = stpcpy (p, "(pm1-factors");
- for (i=0; i < nfactors; i++)
- p = stpcpy (p, "%m");
- p = stpcpy (p, ")");
- }
+ p = stpcpy (p, "(pm1-factors");
+ for (i=0; i < nfactors; i++)
+ p = stpcpy (p, "%m");
p = stpcpy (p, ")");
-
- /* Allocate space for the list of factors plus one for
- an S-expression plus an extra NULL entry for safety
- and fill it with the factors. */
- arg_list = gcry_calloc (nfactors+1+1, sizeof *arg_list);
- if (!arg_list)
- ec = gpg_err_code_from_syserror ();
- else
- {
- i = 0;
- if (seedinfo)
- arg_list[i++] = &seedinfo;
- for (j=0; j < nfactors; j++)
- arg_list[i++] = (*retfactors) + j;
- arg_list[i] = NULL;
-
- ec = gpg_err_code (gcry_sexp_build_array
- (r_extrainfo, NULL, format, arg_list));
- }
}
-
- gcry_free (arg_list);
- gcry_free (format);
- for (i=0; i < nfactors; i++)
- {
- gcry_mpi_release ((*retfactors)[i]);
- (*retfactors)[i] = NULL;
- }
- gcry_free (*retfactors);
- *retfactors = NULL;
- if (ec)
+ p = stpcpy (p, ")");
+
+ /* Allocate space for the list of factors plus one for the
+ seedinfo s-exp plus an extra NULL entry for safety and
+ fill it with the factors. */
+ arg_list = gcry_calloc (nfactors+1+1, sizeof *arg_list);
+ if (!arg_list)
+ rc = gpg_err_code_from_syserror ();
+ else
{
- for (i=0; i < 5; i++)
- {
- gcry_mpi_release (skey[i]);
- skey[i] = NULL;
- }
+ i = 0;
+ if (seedinfo)
+ arg_list[i++] = &seedinfo;
+ for (j=0; j < nfactors; j++)
+ arg_list[i++] = factors + j;
+ arg_list[i] = NULL;
+
+ rc = gpg_err_code (gcry_sexp_build_array
+ (&misc_info, NULL, format, arg_list));
}
}
+
+ gcry_free (arg_list);
+ gcry_free (format);
}
- gcry_sexp_release (seedinfo);
- return ec;
-}
+ if (!rc)
+ rc = gcry_err_code (gcry_sexp_build
+ (r_skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (dsa(p%m)(q%m)(g%m)(y%m)))"
+ " (private-key"
+ " (dsa(p%m)(q%m)(g%m)(y%m)(x%m)))"
+ " %S)",
+ sk.p, sk.q, sk.g, sk.y,
+ sk.p, sk.q, sk.g, sk.y, sk.x,
+ misc_info));
+
+
+ gcry_mpi_release (sk.p);
+ gcry_mpi_release (sk.q);
+ gcry_mpi_release (sk.g);
+ gcry_mpi_release (sk.y);
+ gcry_mpi_release (sk.x);
+ gcry_mpi_release (domain.p);
+ gcry_mpi_release (domain.q);
+ gcry_mpi_release (domain.g);
-static gcry_err_code_t
-dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
- (void)evalue;
- return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
+ gcry_sexp_release (seedinfo);
+ gcry_sexp_release (misc_info);
+ gcry_sexp_release (deriveparms);
+ if (factors)
+ {
+ gcry_mpi_t *mp;
+ for (mp = factors; *mp; mp++)
+ mpi_free (*mp);
+ gcry_free (factors);
+ }
+ return rc;
}
@@ -1223,6 +1199,5 @@ gcry_pk_spec_t _gcry_pubkey_spec_dsa =
dsa_sign,
dsa_verify,
dsa_get_nbits,
- run_selftests,
- dsa_generate_ext
+ run_selftests
};
diff --git a/cipher/ecc.c b/cipher/ecc.c
index b7d62397..9a9c21b9 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -1152,12 +1152,9 @@ verify_eddsa (gcry_mpi_t input, ECC_public_key *pkey,
************** interface ******************
*********************************************/
-/* Extended version of ecc_generate. */
static gcry_err_code_t
-ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
- const gcry_sexp_t genparms,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors,
- gcry_sexp_t *r_extrainfo)
+ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
+ const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
{
gpg_err_code_t rc;
elliptic_curve_t E;
@@ -1169,10 +1166,17 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
int transient_key = 0;
gcry_random_level_t random_level;
mpi_ec_t ctx = NULL;
+ gcry_sexp_t curve_info = NULL;
+ gcry_mpi_t base = NULL;
+ gcry_mpi_t public = NULL;
+ gcry_mpi_t secret = NULL;
(void)algo;
(void)evalue;
+ memset (&E, 0, sizeof E);
+ memset (&sk, 0, sizeof sk);
+
if (genparms)
{
/* Parse the optional "curve" parameter. */
@@ -1240,7 +1244,7 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
/* Copy data to the result. */
if (_gcry_mpi_ec_get_affine (x, y, &sk.E.G, ctx))
log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
- skey[3] = _gcry_ecc_ec2os (x, y, sk.E.p);
+ base = _gcry_ecc_ec2os (x, y, sk.E.p);
if (sk.E.dialect == ECC_DIALECT_ED25519)
{
unsigned char *encpk;
@@ -1249,68 +1253,69 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
rc = eddsa_encodepoint (&sk.Q, 256/8, ctx, x, y, &encpk, &encpklen);
if (rc)
return rc;
- skey[5] = mpi_new (0);
- gcry_mpi_set_opaque (skey[5], encpk, encpklen*8);
+ public = mpi_new (0);
+ gcry_mpi_set_opaque (public, encpk, encpklen*8);
encpk = NULL;
- if (DBG_CIPHER)
- log_printmpi ("ecgen e_pk", skey[5]);
}
else
{
if (_gcry_mpi_ec_get_affine (x, y, &sk.Q, ctx))
log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
- skey[5] = _gcry_ecc_ec2os (x, y, sk.E.p);
+ public = _gcry_ecc_ec2os (x, y, sk.E.p);
}
- skey[0] = sk.E.p; sk.E.p = NULL;
- skey[1] = sk.E.a; sk.E.a = NULL;
- skey[2] = sk.E.b; sk.E.b = NULL;
- skey[4] = sk.E.n; sk.E.n = NULL;
- skey[6] = sk.d; sk.d = NULL;
-
- if (E.name) /* Fixme: No error return checking. */
- gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", E.name);
-
- /* Make an dummy list of factors. */
- *retfactors = gcry_calloc ( 1, sizeof **retfactors );
- if (!*retfactors)
+ secret = sk.d; sk.d = NULL;
+ if (E.name)
{
- rc = gpg_err_code_from_syserror ();
- goto leave;
+ rc = gcry_sexp_build (&curve_info, NULL, "(curve %s)", E.name);
+ if (rc)
+ goto leave;
}
+ rc = gcry_err_code (gcry_sexp_build
+ (r_skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (ecc%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))"
+ " (private-key"
+ " (ecc%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))"
+ " )",
+ curve_info,
+ sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public,
+ curve_info,
+ sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, secret));
+ if (rc)
+ goto leave;
+
if (DBG_CIPHER)
{
- log_printmpi ("ecgen result p", skey[0]);
- log_printmpi ("ecgen result a", skey[1]);
- log_printmpi ("ecgen result b", skey[2]);
- log_printmpi ("ecgen result G", skey[3]);
- log_printmpi ("ecgen result n", skey[4]);
- log_printmpi ("ecgen result Q", skey[5]);
- log_printmpi ("ecgen result d", skey[6]);
+ log_printmpi ("ecgen result p", sk.E.p);
+ log_printmpi ("ecgen result a", sk.E.a);
+ log_printmpi ("ecgen result b", sk.E.b);
+ log_printmpi ("ecgen result G", base);
+ log_printmpi ("ecgen result n", sk.E.n);
+ log_printmpi ("ecgen result Q", public);
+ log_printmpi ("ecgen result d", secret);
}
- rc = 0;
leave:
- point_free (&sk.E.G);
- point_free (&sk.Q);
- _gcry_mpi_ec_free (ctx);
+ mpi_free (secret);
+ mpi_free (public);
+ mpi_free (base);
+ {
+ _gcry_ecc_curve_free (&sk.E);
+ point_free (&sk.Q);
+ mpi_free (sk.d);
+ }
_gcry_ecc_curve_free (&E);
- gcry_mpi_release (x);
- gcry_mpi_release (y);
+ mpi_free (x);
+ mpi_free (y);
+ _gcry_mpi_ec_free (ctx);
+ gcry_sexp_release (curve_info);
return rc;
}
static gcry_err_code_t
-ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
- (void)evalue;
- return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
-}
-
-
-static gcry_err_code_t
ecc_check_secret_key (int algo, gcry_mpi_t *skey)
{
gpg_err_code_t err;
@@ -2020,7 +2025,6 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
ecc_verify,
ecc_get_nbits,
run_selftests,
- ecc_generate_ext,
compute_keygrip,
_gcry_ecc_get_param,
_gcry_ecc_get_curve,
@@ -2041,7 +2045,6 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
NULL,
ecc_get_nbits,
run_selftests,
- ecc_generate_ext,
compute_keygrip,
_gcry_ecc_get_param,
_gcry_ecc_get_curve,
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index 447d089d..c2a953bd 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -1,6 +1,7 @@
/* Elgamal.c - Elgamal Public Key encryption
* Copyright (C) 1998, 2000, 2001, 2002, 2003,
* 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -197,7 +198,7 @@ gen_k( gcry_mpi_t p, int small_k )
nbytes = (nbits+7)/8;
if( DBG_CIPHER )
- log_debug("choosing a random k ");
+ log_debug("choosing a random k\n");
mpi_sub_ui( p_1, p, 1);
for(;;)
{
@@ -292,7 +293,7 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
BUG();
x = gcry_mpi_snew ( xbits );
if( DBG_CIPHER )
- log_debug("choosing a random x of size %u", xbits );
+ log_debug("choosing a random x of size %u\n", xbits );
rndbuf = NULL;
do
{
@@ -330,11 +331,11 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
if( DBG_CIPHER )
{
- progress('\n');
- log_mpidump("elg p= ", p );
- log_mpidump("elg g= ", g );
- log_mpidump("elg y= ", y );
- log_mpidump("elg x= ", x );
+ progress ('\n');
+ log_mpidump ("elg p", p );
+ log_mpidump ("elg g", g );
+ log_mpidump ("elg y", y );
+ log_mpidump ("elg x", x );
}
/* Copy the stuff to the key structures */
@@ -402,10 +403,10 @@ generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
if ( DBG_CIPHER )
{
progress ('\n');
- log_mpidump ("elg p= ", p );
- log_mpidump ("elg g= ", g );
- log_mpidump ("elg y= ", y );
- log_mpidump ("elg x= ", x );
+ log_mpidump ("elg p", p );
+ log_mpidump ("elg g", g );
+ log_mpidump ("elg y", y );
+ log_mpidump ("elg x", x );
}
/* Copy the stuff to the key structures */
@@ -469,12 +470,12 @@ do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
#if 0
if( DBG_CIPHER )
{
- log_mpidump("elg encrypted y= ", pkey->y);
- log_mpidump("elg encrypted p= ", pkey->p);
- log_mpidump("elg encrypted k= ", k);
- log_mpidump("elg encrypted M= ", input);
- log_mpidump("elg encrypted a= ", a);
- log_mpidump("elg encrypted b= ", b);
+ log_mpidump("elg encrypted y", pkey->y);
+ log_mpidump("elg encrypted p", pkey->p);
+ log_mpidump("elg encrypted k", k);
+ log_mpidump("elg encrypted M", input);
+ log_mpidump("elg encrypted a", a);
+ log_mpidump("elg encrypted b", b);
}
#endif
mpi_free(k);
@@ -495,11 +496,11 @@ decrypt(gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey )
#if 0
if( DBG_CIPHER )
{
- log_mpidump("elg decrypted x= ", skey->x);
- log_mpidump("elg decrypted p= ", skey->p);
- log_mpidump("elg decrypted a= ", a);
- log_mpidump("elg decrypted b= ", b);
- log_mpidump("elg decrypted M= ", output);
+ log_mpidump ("elg decrypted x", skey->x);
+ log_mpidump ("elg decrypted p", skey->p);
+ log_mpidump ("elg decrypted a", a);
+ log_mpidump ("elg decrypted b", b);
+ log_mpidump ("elg decrypted M", output);
}
#endif
mpi_free(t1);
@@ -535,14 +536,14 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
#if 0
if( DBG_CIPHER )
{
- log_mpidump("elg sign p= ", skey->p);
- log_mpidump("elg sign g= ", skey->g);
- log_mpidump("elg sign y= ", skey->y);
- log_mpidump("elg sign x= ", skey->x);
- log_mpidump("elg sign k= ", k);
- log_mpidump("elg sign M= ", input);
- log_mpidump("elg sign a= ", a);
- log_mpidump("elg sign b= ", b);
+ log_mpidump ("elg sign p", skey->p);
+ log_mpidump ("elg sign g", skey->g);
+ log_mpidump ("elg sign y", skey->y);
+ log_mpidump ("elg sign x", skey->x);
+ log_mpidump ("elg sign k", k);
+ log_mpidump ("elg sign M", input);
+ log_mpidump ("elg sign a", a);
+ log_mpidump ("elg sign b", b);
}
#endif
mpi_free(k);
@@ -613,19 +614,20 @@ verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
*********************************************/
static gpg_err_code_t
-elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
- const gcry_sexp_t genparms,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors,
- gcry_sexp_t *r_extrainfo)
+elg_generate (int algo, unsigned int nbits, unsigned long evalue,
+ const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
{
- gpg_err_code_t ec;
+ gpg_err_code_t rc;
ELG_secret_key sk;
gcry_mpi_t xvalue = NULL;
gcry_sexp_t l1;
+ gcry_mpi_t *factors = NULL;
+ gcry_sexp_t misc_info = NULL;
(void)algo;
(void)evalue;
- (void)r_extrainfo;
+
+ memset (&sk, 0, sizeof sk);
if (genparms)
{
@@ -642,40 +644,79 @@ elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
if (xvalue)
{
- ec = generate_using_x (&sk, nbits, xvalue, retfactors);
+ rc = generate_using_x (&sk, nbits, xvalue, &factors);
mpi_free (xvalue);
}
else
{
- generate (&sk, nbits, retfactors);
- ec = 0;
+ generate (&sk, nbits, &factors);
+ rc = 0;
}
+ if (rc)
+ goto leave;
- skey[0] = sk.p;
- skey[1] = sk.g;
- skey[2] = sk.y;
- skey[3] = sk.x;
-
- return ec;
-}
-
-
-static gcry_err_code_t
-elg_generate (int algo, unsigned int nbits, unsigned long evalue,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
- ELG_secret_key sk;
-
- (void)algo;
- (void)evalue;
+ if (factors && factors[0])
+ {
+ int nfac;
+ void **arg_list;
+ char *buffer, *p;
+
+ for (nfac = 0; factors[nfac]; nfac++)
+ ;
+ arg_list = gcry_calloc (nfac+1, sizeof *arg_list);
+ if (!arg_list)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ buffer = gcry_malloc (30 + nfac*2 + 2 + 1);
+ if (!buffer)
+ {
+ rc = gpg_err_code_from_syserror ();
+ gcry_free (arg_list);
+ goto leave;
+ }
+ p = stpcpy (buffer, "(misc-key-info(pm1-factors");
+ for(nfac = 0; factors[nfac]; nfac++)
+ {
+ p = stpcpy (p, "%m");
+ arg_list[nfac] = factors + nfac;
+ }
+ p = stpcpy (p, "))");
+ rc = gcry_sexp_build_array (&misc_info, NULL, buffer, arg_list);
+ gcry_free (arg_list);
+ gcry_free (buffer);
+ if (rc)
+ goto leave;
+ }
- generate (&sk, nbits, retfactors);
- skey[0] = sk.p;
- skey[1] = sk.g;
- skey[2] = sk.y;
- skey[3] = sk.x;
+ rc = gcry_err_code (gcry_sexp_build
+ (r_skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (elg(p%m)(g%m)(y%m)))"
+ " (private-key"
+ " (elg(p%m)(g%m)(y%m)(x%m)))"
+ " %S)",
+ sk.p, sk.g, sk.y,
+ sk.p, sk.g, sk.y, sk.x,
+ misc_info));
+
+ leave:
+ mpi_free (sk.p);
+ mpi_free (sk.g);
+ mpi_free (sk.y);
+ mpi_free (sk.x);
+ gcry_sexp_release (misc_info);
+ if (factors)
+ {
+ gcry_mpi_t *mp;
+ for (mp = factors; *mp; mp++)
+ mpi_free (*mp);
+ gcry_free (factors);
+ }
- return GPG_ERR_NO_ERROR;
+ return rc;
}
@@ -863,8 +904,6 @@ gcry_pk_spec_t _gcry_pubkey_spec_elg =
elg_sign,
elg_verify,
elg_get_nbits,
- NULL,
- elg_generate_ext
};
gcry_pk_spec_t _gcry_pubkey_spec_elg_e =
@@ -879,7 +918,5 @@ gcry_pk_spec_t _gcry_pubkey_spec_elg_e =
elg_decrypt,
elg_sign,
elg_verify,
- elg_get_nbits,
- NULL,
- elg_generate_ext
+ elg_get_nbits
};
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 25859817..736d4b92 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -247,39 +247,6 @@ pubkey_get_nenc (int algo)
}
-/* Generate a new public key with algorithm ALGO of size NBITS
- and return it at SKEY. USE_E depends on the ALGORITHM. GENPARMS
- is passed to the algorithm module if it features an extended
- generation function. RETFACTOR is used by some algorithms to
- return certain additional information which are in general not
- required.
-
- The function returns the error code number or 0 on success. */
-static gcry_err_code_t
-pubkey_generate (int algo,
- unsigned int nbits,
- unsigned long use_e,
- gcry_sexp_t genparms,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors,
- gcry_sexp_t *r_extrainfo)
-{
- gcry_err_code_t rc;
- gcry_pk_spec_t *spec = spec_from_algo (algo);
-
- if (spec && spec->ext_generate)
- rc = spec->ext_generate (algo, nbits, use_e, genparms,
- skey, retfactors, r_extrainfo);
- else if (spec && spec->generate)
- rc = spec->generate (algo, nbits, use_e, skey, retfactors);
- else if (spec)
- rc = GPG_ERR_NOT_IMPLEMENTED;
- else
- rc = GPG_ERR_PUBKEY_ALGO;
-
- return rc;
-}
-
-
static gcry_err_code_t
pubkey_check_secret_key (int algo, gcry_mpi_t *skey)
{
@@ -1942,16 +1909,9 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
char *name = NULL;
size_t n;
gcry_err_code_t rc = GPG_ERR_NO_ERROR;
- int i, j;
- const char *algo_name = NULL;
- const char *sec_elems = NULL, *pub_elems = NULL;
- gcry_mpi_t skey[12];
- gcry_mpi_t *factors = NULL;
- gcry_sexp_t extrainfo = NULL;
unsigned int nbits = 0;
unsigned long use_e = 0;
- skey[0] = NULL;
*r_key = NULL;
list = gcry_sexp_find_token (s_parms, "genkey", 0);
@@ -1987,14 +1947,6 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
goto leave;
}
- algo_name = spec->aliases? *spec->aliases : NULL;
- if (!algo_name || !*algo_name)
- algo_name = spec->name;
- pub_elems = spec->elements_pkey;
- sec_elems = spec->elements_skey;
- if (strlen (sec_elems) >= DIM(skey))
- BUG ();
-
/* Handle the optional rsa-use-e element. Actually this belong into
the algorithm module but we have this parameter in the public
module API, so we need to parse it right here. */
@@ -2041,164 +1993,14 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
else
nbits = 0;
- /* Pass control to the algorithm module. */
- rc = pubkey_generate (spec->algo, nbits, use_e, list, skey,
- &factors, &extrainfo);
- gcry_sexp_release (list); list = NULL;
- if (rc)
- goto leave;
-
- /* Key generation succeeded: Build an S-expression. */
- {
- char *string, *p;
- size_t nelem=0, nelem_cp = 0, needed=0;
- gcry_mpi_t mpis[30];
- int percent_s_idx = -1;
- int percent_s_idx2 = -1;
-
- /* Estimate size of format string. */
- nelem = strlen (pub_elems) + strlen (sec_elems);
- if (factors)
- {
- for (i = 0; factors[i]; i++)
- nelem++;
- }
- if (extrainfo)
- nelem += 2;
- nelem_cp = nelem;
-
- needed += nelem * 10;
- /* (+10 for two times EXTRAINFO ("%S")). */
- needed += 2 * strlen (algo_name) + 300 + 10;
- if (nelem > DIM (mpis))
- BUG ();
-
- /* Build the string. */
- nelem = 0;
- string = p = gcry_malloc (needed);
- if (!string)
- {
- rc = gpg_err_code_from_syserror ();
- goto leave;
- }
- p = stpcpy (p, "(key-data");
- p = stpcpy (p, "(public-key(");
- p = stpcpy (p, algo_name);
- for(i = 0; pub_elems[i]; i++)
- {
- *p++ = '(';
- *p++ = pub_elems[i];
- p = stpcpy (p, "%m)");
- mpis[nelem++] = skey[i];
- }
- if (extrainfo
- && (spec->algo == GCRY_PK_ECDSA || spec->algo == GCRY_PK_ECDH))
- {
- /* Very ugly hack to insert the used curve parameter into the
- list of public key parameters. */
- percent_s_idx = nelem++;
- p = stpcpy (p, "%S");
- }
- p = stpcpy (p, "))");
- p = stpcpy (p, "(private-key(");
- p = stpcpy (p, algo_name);
- for (i = 0; sec_elems[i]; i++)
- {
- *p++ = '(';
- *p++ = sec_elems[i];
- p = stpcpy (p, "%m)");
- mpis[nelem++] = skey[i];
- }
- if (extrainfo
- && (spec->algo == GCRY_PK_ECDSA || spec->algo == GCRY_PK_ECDH))
- {
- percent_s_idx2 = nelem++;
- p = stpcpy (p, "%S");
- }
- p = stpcpy (p, "))");
-
- /* Hack to make release_mpi_array() work. */
- skey[i] = NULL;
-
- if (extrainfo)
- {
- /* If we have extrainfo we should not have any factors. */
- if (percent_s_idx == -1)
- {
- percent_s_idx = nelem++;
- p = stpcpy (p, "%S");
- }
- }
- else if (factors && factors[0])
- {
- p = stpcpy (p, "(misc-key-info(pm1-factors");
- for(i = 0; factors[i]; i++)
- {
- p = stpcpy (p, "%m");
- mpis[nelem++] = factors[i];
- }
- p = stpcpy (p, "))");
- }
- strcpy (p, ")");
- gcry_assert (p - string < needed);
-
- while (nelem < DIM (mpis))
- mpis[nelem++] = NULL;
-
- {
- int elem_n = strlen (pub_elems) + strlen (sec_elems);
- void **arg_list;
-
- if (percent_s_idx != -1)
- elem_n++;
- if (percent_s_idx2 != -1)
- elem_n++;
-
- arg_list = gcry_calloc (nelem_cp, sizeof *arg_list);
- if (!arg_list)
- {
- rc = gpg_err_code_from_syserror ();
- goto leave;
- }
- for (i = j = 0; i < elem_n; i++)
- {
- if (i == percent_s_idx)
- arg_list[j++] = &extrainfo;
- else if (i == percent_s_idx2)
- arg_list[j++] = &extrainfo;
- else
- arg_list[j++] = mpis + i;
- }
- if (extrainfo)
- ;
- else if (factors && factors[0])
- {
- for (; i < nelem_cp; i++)
- arg_list[j++] = factors + i - elem_n;
- }
- rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
- gcry_free (arg_list);
- if (rc)
- BUG ();
- gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
- the array gets increased if
- new parameters are added. */
- }
- gcry_free (string);
- }
+ if (spec->generate)
+ rc = spec->generate (spec->algo, nbits, use_e, list, r_key);
+ else
+ rc = GPG_ERR_NOT_IMPLEMENTED;
leave:
+ gcry_sexp_release (list); list = NULL;
gcry_free (name);
- gcry_sexp_release (extrainfo);
- release_mpi_array (skey);
- /* Don't free SKEY itself, it is an stack allocated array. */
-
- if (factors)
- {
- release_mpi_array ( factors );
- gcry_free (factors);
- }
-
gcry_sexp_release (l3);
gcry_sexp_release (l2);
gcry_sexp_release (list);
diff --git a/cipher/rsa.c b/cipher/rsa.c
index 91349db1..5754e438 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -783,10 +783,8 @@ rsa_unblind (gcry_mpi_t x, gcry_mpi_t ri, gcry_mpi_t n)
*********************************************/
static gcry_err_code_t
-rsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
- const gcry_sexp_t genparms,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors,
- gcry_sexp_t *r_extrainfo)
+rsa_generate (int algo, unsigned int nbits, unsigned long evalue,
+ const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
{
RSA_secret_key sk;
gpg_err_code_t ec;
@@ -794,10 +792,11 @@ rsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
int transient_key = 0;
int use_x931 = 0;
gcry_sexp_t l1;
+ gcry_sexp_t swap_info = NULL;
(void)algo;
- *retfactors = NULL; /* We don't return them. */
+ memset (&sk, 0, sizeof sk);
deriveparms = (genparms?
gcry_sexp_find_token (genparms, "derive-parms", 0) : NULL);
@@ -817,20 +816,8 @@ rsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
int swapped;
ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped);
gcry_sexp_release (deriveparms);
- if (!ec && r_extrainfo && swapped)
- {
- ec = gcry_sexp_new (r_extrainfo,
- "(misc-key-info(p-q-swapped))", 0, 1);
- if (ec)
- {
- gcry_mpi_release (sk.n); sk.n = NULL;
- gcry_mpi_release (sk.e); sk.e = NULL;
- gcry_mpi_release (sk.p); sk.p = NULL;
- gcry_mpi_release (sk.q); sk.q = NULL;
- gcry_mpi_release (sk.d); sk.d = NULL;
- gcry_mpi_release (sk.u); sk.u = NULL;
- }
- }
+ if (!ec && swapped)
+ ec = gcry_sexp_new (&swap_info, "(misc-key-info(p-q-swapped))", 0, 1);
}
else
{
@@ -847,23 +834,28 @@ rsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
if (!ec)
{
- skey[0] = sk.n;
- skey[1] = sk.e;
- skey[2] = sk.d;
- skey[3] = sk.p;
- skey[4] = sk.q;
- skey[5] = sk.u;
+ ec = gcry_err_code (gcry_sexp_build
+ (r_skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (rsa(n%m)(e%m)))"
+ " (private-key"
+ " (rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))"
+ " %S)",
+ sk.n, sk.e,
+ sk.n, sk.e, sk.d, sk.p, sk.q, sk.u,
+ swap_info));
}
- return ec;
-}
-
+ mpi_free (sk.n);
+ mpi_free (sk.e);
+ mpi_free (sk.p);
+ mpi_free (sk.q);
+ mpi_free (sk.d);
+ mpi_free (sk.u);
+ gcry_sexp_release (swap_info);
-static gcry_err_code_t
-rsa_generate (int algo, unsigned int nbits, unsigned long evalue,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
- return rsa_generate_ext (algo, nbits, evalue, NULL, skey, retfactors, NULL);
+ return ec;
}
@@ -1440,6 +1432,5 @@ gcry_pk_spec_t _gcry_pubkey_spec_rsa =
rsa_verify,
rsa_get_nbits,
run_selftests,
- rsa_generate_ext,
compute_keygrip
};
diff --git a/src/cipher-proto.h b/src/cipher-proto.h
index 121d9f57..1285fe85 100644
--- a/src/cipher-proto.h
+++ b/src/cipher-proto.h
@@ -49,18 +49,10 @@ typedef gpg_err_code_t (*selftest_func_t)
/* Type for the pk_generate function. */
typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo,
- unsigned int nbits,
- unsigned long use_e,
- gcry_mpi_t *skey,
- gcry_mpi_t **retfactors);
-/* Type for the extended generate function. */
-typedef gcry_err_code_t (*pk_ext_generate_t) (int algo,
- unsigned int nbits,
- unsigned long evalue,
- gcry_sexp_t genparms,
- gcry_mpi_t *skey,
- gcry_mpi_t **retfactors,
- gcry_sexp_t *extrainfo);
+ unsigned int nbits,
+ unsigned long evalue,
+ gcry_sexp_t genparms,
+ gcry_sexp_t *r_skey);
/* Type for the pk_check_secret_key function. */
typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
@@ -143,7 +135,6 @@ typedef struct gcry_pk_spec
gcry_pk_verify_t verify;
gcry_pk_get_nbits_t get_nbits;
selftest_func_t selftest;
- pk_ext_generate_t ext_generate;
pk_comp_keygrip_t comp_keygrip;
pk_get_param_t get_param;
pk_get_curve_t get_curve;