diff options
author | Werner Koch <wk@gnupg.org> | 2013-09-07 10:06:46 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2013-09-19 16:43:33 +0200 |
commit | 1bf08850bf9343146c938bc03917417e16393e9a (patch) | |
tree | e045f1721f71ebb6769e2048bf8d53e7d39a0320 /cipher | |
parent | 2fe084873333c4d67bcfba0b527d63cd3cff6c47 (diff) | |
download | libgcrypt-1bf08850bf9343146c938bc03917417e16393e9a.tar.gz |
pk: Move s-expr creation for genkey to the modules.
* cipher/pubkey.c (pubkey_generate): Fold into gcry_pk_genkey
(gcry_pk_genkey): Move result s-exp creation into the modules.
* cipher/dsa.c (dsa_generate): Create result as s-exp.
* cipher/elgamal.c (elg_generate): Ditto.
* cipher/rsa.c (rsa_generate): Ditto.
* cipher/ecc.c (ecc_generate): Ditto.
* src/cipher-proto.h (pk_ext_generate_t): Remove type
(gcry_pk_spec): and remove from struct.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'cipher')
-rw-r--r-- | cipher/dsa.c | 203 | ||||
-rw-r--r-- | cipher/ecc.c | 101 | ||||
-rw-r--r-- | cipher/elgamal.c | 171 | ||||
-rw-r--r-- | cipher/pubkey.c | 208 | ||||
-rw-r--r-- | cipher/rsa.c | 59 |
5 files changed, 275 insertions, 467 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 }; |