diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | Makefile.am | 15 | ||||
-rw-r--r-- | THANKS | 199 | ||||
-rw-r--r-- | cipher/ChangeLog | 18 | ||||
-rw-r--r-- | cipher/cipher.c | 366 | ||||
-rw-r--r-- | cipher/elgamal.c | 4 | ||||
-rw-r--r-- | cipher/md.c | 430 | ||||
-rw-r--r-- | cipher/pubkey.c | 83 | ||||
-rw-r--r-- | configure.in | 20 | ||||
-rw-r--r-- | doc/ChangeLog | 36 | ||||
-rw-r--r-- | doc/Makefile.am | 2 | ||||
-rw-r--r-- | scripts/ChangeLog | 5 | ||||
-rw-r--r-- | src/ChangeLog | 11 | ||||
-rw-r--r-- | src/Makefile.am | 11 | ||||
-rw-r--r-- | src/g10lib.h | 208 | ||||
-rw-r--r-- | src/gcrypt.h | 118 | ||||
-rw-r--r-- | src/mdapi.c | 127 | ||||
-rw-r--r-- | src/pkapi.c | 67 | ||||
-rw-r--r-- | src/symapi.c | 280 |
19 files changed, 1017 insertions, 993 deletions
@@ -1,3 +1,13 @@ +Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de> + + * README-alpha: New + + * configure.in: Fixed quoting in test for development version. + + * THANKS: Add entries for Michael, Brenno and J Horacio who did + very nice Howto documents - I apoligize for forgetting to mention them + earlier. + Fri Sep 17 12:56:42 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> diff --git a/Makefile.am b/Makefile.am index bf6e3e2d..1d3bec69 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,12 +1,15 @@ ## Process this file with automake to produce Makefile.in -if COMPILE_LIBGCRYPT +#if COMPILE_LIBGCRYPT +#gcrypt = gcrypt +#my_clean_gcrypt = +#else +#gcrypt = +#my_clean_gcrypt = gcrypt/Makefile +#endif + gcrypt = gcrypt my_clean_gcrypt = -else -gcrypt = -my_clean_gcrypt = gcrypt/Makefile -endif if CROSS_COMPILING checks = @@ -15,7 +18,7 @@ checks = checks endif SUBDIRS = intl zlib util mpi cipher tools g10 po doc ${checks} ${gcrypt} -EXTRA_DIST = VERSION PROJECTS BUGS +EXTRA_DIST = README-alpha VERSION PROJECTS BUGS # gettext never gets it right, so we take here care of deleting the # symlink. my_clean_gcrypt is just a kludge until we can include # libgcrypt. @@ -3,106 +3,109 @@ reporting problems, suggesting various improvements or submitting actual code. Here is a list of those people. Help me keep it complete and free of errors. -Allan Clark allanc@sco.com -Anand Kumria wildfire@progsoc.uts.edu.au -Ariel T Glenn ariel@columbia.edu -Bodo Moeller Bodo_Moeller@public.uni-hamburg.de -Bryan Fullerton bryanf@samurai.com -Brian Moore bem@cmc.net -Brian Warner warner@lothar.com -Caskey L. Dickson caskey@technocage.com -Cees van de Griend cees-list@griend.xs4all.nl -Charles Levert charles@comm.polymtl.ca -Christian von Roques roques@pond.sub.org -Christopher Oliver oliver@fritz.traverse.net -Christian Recktenwald chris@citecs.de -Daniel Eisenbud eisenbud@cs.swarthmore.edu -Daniel Koening dan@mail.isis.de -David Ellement ellement@sdd.hp.com -Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de -Dirk Lattermann dlatt@t-online.de -Ed Boraas ecxjo@esperanto.org -Enzo Michelangeli em@MailAndNews.com -Ernst Molitor ernst.molitor@uni-bonn.de -Fabio Coatti cova@felix.unife.it -Felix von Leitner leitner@amdiv.de -Frank Heckenbach heckenb@mi.uni-erlangen.de -Frank Stajano frank.stajano@cl.cam.ac.uk -Gaël Quéri gqueri@mail.dotcom.fr -Greg Louis glouis@dynamicro.on.ca -Greg Troxel gdt@ir.bbn.com -Gregory Steuck steuck@iname.com -Geoff Keating geoffk@ozemail.com.au -Harald Denker harry@hal.westfalen.de -Hendrik Buschkamp buschkamp@rheumanet.org -Holger Schurig holger@d.om.org -Hugh Daniel hugh@toad.com -Ian McKellar imckellar@harvestroad.com.au -Janusz A. Urbanowicz alex@bofh.torun.pl -James Troup james@nocrew.org -Jean-loup Gailly gzip@prep.ai.mit.edu -Jens Bachem bachem@rrz.uni-koeln.de -Joachim Backes backes@rhrk.uni-kl.de -John A. Martin jam@jamux.com -Johnny Teveßen j.tevessen@gmx.de -Jörg Schilling schilling@fokus.gmd.de -Jun Kuriyama kuriyama@sky.rim.or.jp -Karl Fogel kfogel@guanabana.onshore.com -Karsten Thygesen karthy@kom.auc.dk -Katsuhiro Kondou kondou@nec.co.jp -Kazu Yamamoto kazu@iijlab.net -Lars Kellogg-Stedman lars@bu.edu -Marco d'Itri md@linux.it -Mark Adler madler@alumni.caltech.edu -Mark Elbrecht snowball3@bigfoot.com -Markus Friedl Markus.Friedl@informatik.uni-erlangen.de -Martin Kahlert martin.kahlert@provi.de +Allan Clark allanc@sco.com +Anand Kumria wildfire@progsoc.uts.edu.au +Ariel T Glenn ariel@columbia.edu +Bodo Moeller Bodo_Moeller@public.uni-hamburg.de +Brenno de Winter brenno@dewinter.com +Brian Moore bem@cmc.net +Brian Warner warner@lothar.com +Bryan Fullerton bryanf@samurai.com +Caskey L. Dickson caskey@technocage.com +Cees van de Griend cees-list@griend.xs4all.nl +Charles Levert charles@comm.polymtl.ca +Christian von Roques roques@pond.sub.org +Christopher Oliver oliver@fritz.traverse.net +Christian Recktenwald chris@citecs.de +Daniel Eisenbud eisenbud@cs.swarthmore.edu +Daniel Koening dan@mail.isis.de +David Ellement ellement@sdd.hp.com +Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de +Dirk Lattermann dlatt@t-online.de +Ed Boraas ecxjo@esperanto.org +Enzo Michelangeli em@MailAndNews.com +Ernst Molitor ernst.molitor@uni-bonn.de +Fabio Coatti cova@felix.unife.it +Felix von Leitner leitner@amdiv.de +Frank Heckenbach heckenb@mi.uni-erlangen.de +Frank Stajano frank.stajano@cl.cam.ac.uk +Gaël Quéri gqueri@mail.dotcom.fr +Greg Louis glouis@dynamicro.on.ca +Greg Troxel gdt@ir.bbn.com +Gregory Steuck steuck@iname.com +Geoff Keating geoffk@ozemail.com.au +Harald Denker harry@hal.westfalen.de +Hendrik Buschkamp buschkamp@rheumanet.org +Holger Schurig holger@d.om.org +Hugh Daniel hugh@toad.com +Ian McKellar imckellar@harvestroad.com.au +Janusz A. Urbanowicz alex@bofh.torun.pl +James Troup james@nocrew.org +Jean-loup Gailly gzip@prep.ai.mit.edu +Jens Bachem bachem@rrz.uni-koeln.de +J Horacio MG homega@ciberia.es +Joachim Backes backes@rhrk.uni-kl.de +John A. Martin jam@jamux.com +Johnny Teveßen j.tevessen@gmx.de +Jörg Schilling schilling@fokus.gmd.de +Jun Kuriyama kuriyama@sky.rim.or.jp +Karl Fogel kfogel@guanabana.onshore.com +Karsten Thygesen karthy@kom.auc.dk +Katsuhiro Kondou kondou@nec.co.jp +Kazu Yamamoto kazu@iijlab.net +Lars Kellogg-Stedman lars@bu.edu +Marco d'Itri md@linux.it +Mark Adler madler@alumni.caltech.edu +Mark Elbrecht snowball3@bigfoot.com +Markus Friedl Markus.Friedl@informatik.uni-erlangen.de +Martin Kahlert martin.kahlert@provi.de Martin Hamilton -Martin Schulte schulte@thp.uni-koeln.de -Matthew Skala mskala@ansuz.sooke.bc.ca -Max Valianskiy maxcom@maxcom.ml.org -Michael Roth mroth@nessie.de -Michael Sobolev mss@despair.transas.com -Nicolas Graner Nicolas.Graner@cri.u-psud.fr -NIIBE Yutaka gniibe@chroot.org +Martin Schulte schulte@thp.uni-koeln.de +Matthew Skala mskala@ansuz.sooke.bc.ca +Max Valianskiy maxcom@maxcom.ml.org +Michael Fischer v. Mollard mfvm@gmx.de +Michael Roth mroth@nessie.de +Michael Sobolev mss@despair.transas.com +Nicolas Graner Nicolas.Graner@cri.u-psud.fr +NIIBE Yutaka gniibe@chroot.org Niklas Hernaeus -Nimrod Zimerman zimerman@forfree.at -N J Doye nic@niss.ac.uk -Oliver Haakert haakert@hsp.de -Oskari Jääskeläinen f33003a@cc.hut.fi -Paul D. Smith psmith@baynetworks.com -Philippe Laliberte arsphl@oeil.qc.ca -Peter Gutmann pgut001@cs.auckland.ac.nz -QingLong qinglong@bolizm.ihep.su -Ralph Gillen gillen@theochem.uni-duesseldorf.de -Rat ratinox@peorth.gweep.net -Reinhard Wobst R.Wobst@ifw-dresden.de -Rémi Guyomarch rguyom@mail.dotcom.fr -Reuben Sumner rasumner@wisdom.weizmann.ac.il -Richard Outerbridge outer@interlog.com -Roddy Strachan roddy@satlink.com.au -Roland Rosenfeld roland@spinnaker.rhein.de -Ross Golder rossigee@bigfoot.com -Serge Munhoven munhoven@mema.ucl.ac.be -SL Baur steve@xemacs.org -Stefan Karrmann S.Karrmann@gmx.net -Stefan Keller dres@cs.tu-berlin.de -Steffen Ullrich ccrlphr@xensei.com -Steffen Zahn zahn@berlin.snafu.de -Steven Bakker steven@icoe.att.com -Susanne Schultz schultz@hsp.de -Thiago Jung Bauermann jungmann@cwb.matrix.com.br -Thomas Roessler roessler@guug.de -Tom Spindler dogcow@home.merit.edu -Tom Zerucha tzeruch@ceddec.com -Tomas Fasth tomas.fasth@twinspot.net -Thomas Mikkelsen tbm@image.dk -Ulf Möller 3umoelle@informatik.uni-hamburg.de -Urko Lusa ulusa@lacueva.ddns.org -Walter Koch koch@hsp.de -Werner Koch werner.koch@guug.de -Wim Vandeputte bunbun@reptile.rug.ac.be - nbecker@hns.com +Nimrod Zimerman zimerman@forfree.at +N J Doye nic@niss.ac.uk +Oliver Haakert haakert@hsp.de +Oskari Jääskeläinen f33003a@cc.hut.fi +Paul D. Smith psmith@baynetworks.com +Philippe Laliberte arsphl@oeil.qc.ca +Peter Gutmann pgut001@cs.auckland.ac.nz +QingLong qinglong@bolizm.ihep.su +Ralph Gillen gillen@theochem.uni-duesseldorf.de +Rat ratinox@peorth.gweep.net +Reinhard Wobst R.Wobst@ifw-dresden.de +Rémi Guyomarch rguyom@mail.dotcom.fr +Reuben Sumner rasumner@wisdom.weizmann.ac.il +Richard Outerbridge outer@interlog.com +Roddy Strachan roddy@satlink.com.au +Roland Rosenfeld roland@spinnaker.rhein.de +Ross Golder rossigee@bigfoot.com +Serge Munhoven munhoven@mema.ucl.ac.be +SL Baur steve@xemacs.org +Stefan Karrmann S.Karrmann@gmx.net +Stefan Keller dres@cs.tu-berlin.de +Steffen Ullrich ccrlphr@xensei.com +Steffen Zahn zahn@berlin.snafu.de +Steven Bakker steven@icoe.att.com +Susanne Schultz schultz@hsp.de +Thiago Jung Bauermann jungmann@cwb.matrix.com.br +Thomas Roessler roessler@guug.de +Tom Spindler dogcow@home.merit.edu +Tom Zerucha tzeruch@ceddec.com +Tomas Fasth tomas.fasth@twinspot.net +Thomas Mikkelsen tbm@image.dk +Ulf Möller 3umoelle@informatik.uni-hamburg.de +Urko Lusa ulusa@lacueva.ddns.org +Walter Koch koch@hsp.de +Werner Koch werner.koch@guug.de +Wim Vandeputte bunbun@reptile.rug.ac.be + nbecker@hns.com Thanks to the German Unix User Group for providing FTP space, Martin Hamilton for hosting the mailing list and HSP for diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 944510a3..ea23ca18 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,21 @@ +Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de> + + * elgamal.c (sign): Hugh found strange code here. Replaced by BUG(). + + * cipher.c: Merged with gcrypt/symapi.c. + + * pubkey.c (string_to_pubkey_algo): Renamed function to ... + (gcry_pk_map_name): ... this. + (pubkey_algo_to_string): Renamed function to ... + (gcry_pk_algo_name): ... this. + (gcry_pk_algo_info): New. + * pubkey.c: Merged with gcrypt/pkapi.c. + + * md.c (md_reset): Clear finalized; thanks to Ulf Moeller for + fixing this bug. + + * md.c: Merged with gcrypt/mdapi.c + Wed Sep 15 14:39:59 CEST 1999 Michael Roth <mroth@nessie.de> * des.c: Various speed improvements: One bit pre rotation diff --git a/cipher/cipher.c b/cipher/cipher.c index 7224ab69..277dd13f 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -24,6 +24,8 @@ #include <string.h> #include <errno.h> #include <assert.h> + +#include "g10lib.h" #include "util.h" #include "errors.h" #include "cipher.h" @@ -32,9 +34,10 @@ #include "cast5.h" #include "dynload.h" - #define MAX_BLOCKSIZE 16 #define TABLE_SIZE 10 +#define CTX_MAGIC_NORMAL 0x24091964 +#define CTX_MAGIC_SECURE 0x46919042 struct cipher_table_s { const char *name; @@ -50,10 +53,11 @@ struct cipher_table_s { static struct cipher_table_s cipher_table[TABLE_SIZE]; static int disabled_algos[TABLE_SIZE]; - -struct cipher_handle_s { +struct gcry_cipher_handle { + int magic; int algo; int mode; + unsigned int flags; size_t blocksize; byte iv[MAX_BLOCKSIZE]; /* (this should be ulong aligned) */ byte lastiv[MAX_BLOCKSIZE]; @@ -209,16 +213,13 @@ load_cipher_modules(void) } - - - - - /**************** - * Map a string to the cipher algo + * Map a string to the cipher algo. + * Returns: The algo ID of the cipher for the gioven name or + * 0 if the name is not known. */ int -string_to_cipher_algo( const char *string ) +gcry_cipher_map_name( const char *string ) { int i; const char *s; @@ -234,7 +235,7 @@ string_to_cipher_algo( const char *string ) /**************** * Map a cipher algo to a string */ -const char * +static const char * cipher_algo_to_string( int algo ) { int i; @@ -247,8 +248,20 @@ cipher_algo_to_string( int algo ) return NULL; } +/**************** + * This function simply returns the name of the algorithm or some constant + * string when there is no algo. It will never return NULL. + */ +const char * +gcry_cipher_algo_name( int algo ) +{ + const char *s = cipher_algo_to_string( algo ); + return s? s: ""; +} -void + + +static void disable_cipher_algo( int algo ) { int i; @@ -266,7 +279,7 @@ disable_cipher_algo( int algo ) /**************** * Return 0 if the cipher algo is available */ -int +static int check_cipher_algo( int algo ) { int i; @@ -285,7 +298,7 @@ check_cipher_algo( int algo ) } -unsigned +static unsigned cipher_get_keylen( int algo ) { int i; @@ -305,7 +318,7 @@ cipher_get_keylen( int algo ) return 0; } -unsigned +static unsigned cipher_get_blocksize( int algo ) { int i; @@ -328,70 +341,98 @@ cipher_get_blocksize( int algo ) /**************** * Open a cipher handle for use with algorithm ALGO, in mode MODE - * and put it into secure memory if SECURE is true. + * and return the handle. Return NULL and set the internal error variable + * if something goes wrong. */ -CIPHER_HANDLE -cipher_open( int algo, int mode, int secure ) + +GCRY_CIPHER_HD +gcry_cipher_open( int algo, int mode, unsigned int flags ) { - CIPHER_HANDLE hd; - int i; + GCRY_CIPHER_HD h; + int idx; + int secure = (flags & GCRY_CIPHER_SECURE); fast_random_poll(); - do { - for(i=0; cipher_table[i].name; i++ ) - if( cipher_table[i].algo == algo ) - break; - } while( !cipher_table[i].name && load_cipher_modules() ); - if( !cipher_table[i].name ) { - log_fatal("cipher_open: algorithm %d not available\n", algo ); + + /* check whether the algo is available */ + if( check_cipher_algo( algo ) ) { + set_lasterr( GCRYERR_INV_ALGO ); return NULL; } - /* ? perform selftest here and mark this with a flag in cipher_table ? */ + /* check flags */ + if( (flags & ~(GCRY_CIPHER_SECURE|GCRY_CIPHER_ENABLE_SYNC)) ) { + set_lasterr( GCRYERR_INV_ARG ); + return NULL; + } + + /* get the table index of the algo */ + for(idx=0; cipher_table[idx].name; idx++ ) + if( cipher_table[idx].algo == algo ) + break; + if( !cipher_table[idx].name ) + BUG(); /* check_cipher_algo() should have loaded the algo */ - hd = secure ? m_alloc_secure_clear( sizeof *hd - + cipher_table[i].contextsize - - sizeof(PROPERLY_ALIGNED_TYPE) ) - : m_alloc_clear( sizeof *hd + cipher_table[i].contextsize - - sizeof(PROPERLY_ALIGNED_TYPE) ); - hd->algo = algo; - hd->blocksize = cipher_table[i].blocksize; - hd->setkey = cipher_table[i].setkey; - hd->encrypt = cipher_table[i].encrypt; - hd->decrypt = cipher_table[i].decrypt; if( algo == CIPHER_ALGO_DUMMY ) - hd->mode = CIPHER_MODE_DUMMY; - else if( mode == CIPHER_MODE_AUTO_CFB ) { - #warning Remove this code and the AUTO:CFB macro. - if( algo >= 100 ) - hd->mode = CIPHER_MODE_CFB; - else - hd->mode = CIPHER_MODE_PHILS_CFB; + mode = GCRY_CIPHER_MODE_NONE; /* force this mode for dummy algo */ + + /* check that a valid mode has been requested */ + switch( mode ) { + case GCRY_CIPHER_MODE_ECB: + case GCRY_CIPHER_MODE_CBC: + case GCRY_CIPHER_MODE_CFB: + break; + case GCRY_CIPHER_MODE_NONE: + /* FIXME: issue a warning when this mode is used */ + break; + default: + set_lasterr( GCRYERR_INV_ALGO ); + return NULL; } - else - hd->mode = mode; - return hd; + /* ? perform selftest here and mark this with a flag in cipher_table ? */ + + h = secure ? m_alloc_secure_clear( sizeof *h + + cipher_table[idx].contextsize + - sizeof(PROPERLY_ALIGNED_TYPE) ) + : m_alloc_clear( sizeof *h + cipher_table[idx].contextsize + - sizeof(PROPERLY_ALIGNED_TYPE) ); + h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL; + h->algo = algo; + h->mode = mode; + h->flags = flags; + h->blocksize = cipher_table[idx].blocksize; + h->setkey = cipher_table[idx].setkey; + h->encrypt = cipher_table[idx].encrypt; + h->decrypt = cipher_table[idx].decrypt; + + return h; } void -cipher_close( CIPHER_HANDLE c ) +gcry_cipher_close( GCRY_CIPHER_HD h ) { - m_free(c); + if( !h ) + return; + if( h->magic != CTX_MAGIC_SECURE && h->magic != CTX_MAGIC_NORMAL ) { + fatal_invalid_arg("gcry_cipher_close: already closed/invalid handle"); + return; + } + h->magic = 0; + m_free(h); } -int -cipher_setkey( CIPHER_HANDLE c, byte *key, unsigned keylen ) +static int +cipher_setkey( GCRY_CIPHER_HD c, byte *key, unsigned keylen ) { return (*c->setkey)( &c->context.c, key, keylen ); } - -void -cipher_setiv( CIPHER_HANDLE c, const byte *iv, unsigned ivlen ) +static void +cipher_setiv( GCRY_CIPHER_HD c, const byte *iv, unsigned ivlen ) { memset( c->iv, 0, c->blocksize ); if( iv ) { @@ -408,7 +449,7 @@ cipher_setiv( CIPHER_HANDLE c, const byte *iv, unsigned ivlen ) static void -do_ecb_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nblocks ) +do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) { unsigned n; @@ -420,7 +461,7 @@ do_ecb_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nblocks ) } static void -do_ecb_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nblocks ) +do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) { unsigned n; @@ -432,7 +473,7 @@ do_ecb_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nblocks ) } static void -do_cbc_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nblocks ) +do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) { unsigned int n; byte *ivp; @@ -453,7 +494,7 @@ do_cbc_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nblocks ) } static void -do_cbc_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nblocks ) +do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) { unsigned int n; byte *ivp; @@ -476,7 +517,7 @@ do_cbc_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nblocks ) static void -do_cfb_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) +do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes ) { byte *ivp; size_t blocksize = c->blocksize; @@ -520,7 +561,7 @@ do_cfb_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) } static void -do_cfb_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) +do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes ) { byte *ivp; ulong temp; @@ -582,23 +623,22 @@ do_cfb_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) * inbuf and outbuf may overlap or be the same. * Depending on the mode some some contraints apply to NBYTES. */ -void -cipher_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) +static void +cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes ) { switch( c->mode ) { - case CIPHER_MODE_ECB: + case GCRY_CIPHER_MODE_ECB: assert(!(nbytes%8)); do_ecb_encrypt(c, outbuf, inbuf, nbytes/8 ); break; - case CIPHER_MODE_CBC: + case GCRY_CIPHER_MODE_CBC: assert(!(nbytes%8)); /* fixme: should be blocksize */ do_cbc_encrypt(c, outbuf, inbuf, nbytes/8 ); break; - case CIPHER_MODE_CFB: - case CIPHER_MODE_PHILS_CFB: + case GCRY_CIPHER_MODE_CFB: do_cfb_encrypt(c, outbuf, inbuf, nbytes ); break; - case CIPHER_MODE_DUMMY: + case GCRY_CIPHER_MODE_NONE: if( inbuf != outbuf ) memmove( outbuf, inbuf, nbytes ); break; @@ -608,27 +648,53 @@ cipher_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) /**************** + * Encrypt IN and write it to OUT. If IN is NULL, in-place encryption has + * been requested, + */ +int +gcry_cipher_encrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize, + const byte *in, size_t inlen ) +{ + if( !in ) { + /* caller requested in-place encryption */ + /* actullay cipher_encrypt() does not need to know about it, but + * we may chnage this to get better performace */ + cipher_encrypt( h, out, out, outsize ); + } + else { + if( outsize < inlen ) + return set_lasterr( GCRYERR_TOO_SHORT ); + /* fixme: check that the inlength is a multipe of the blocksize + * if a blockoriented mode is used, or modify cipher_encrypt to + * return an error in this case */ + cipher_encrypt( h, out, in, inlen ); + } + return 0; +} + + + +/**************** * Decrypt INBUF to OUTBUF with the mode selected at open. * inbuf and outbuf may overlap or be the same. * Depending on the mode some some contraints apply to NBYTES. */ -void -cipher_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) +static void +cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes ) { switch( c->mode ) { - case CIPHER_MODE_ECB: + case GCRY_CIPHER_MODE_ECB: assert(!(nbytes%8)); do_ecb_decrypt(c, outbuf, inbuf, nbytes/8 ); break; - case CIPHER_MODE_CBC: + case GCRY_CIPHER_MODE_CBC: assert(!(nbytes%8)); /* fixme: should assert on blocksize */ do_cbc_decrypt(c, outbuf, inbuf, nbytes/8 ); break; - case CIPHER_MODE_CFB: - case CIPHER_MODE_PHILS_CFB: + case GCRY_CIPHER_MODE_CFB: do_cfb_decrypt(c, outbuf, inbuf, nbytes ); break; - case CIPHER_MODE_DUMMY: + case GCRY_CIPHER_MODE_NONE: if( inbuf != outbuf ) memmove( outbuf, inbuf, nbytes ); break; @@ -637,18 +703,160 @@ cipher_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) } +int +gcry_cipher_decrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize, + const byte *in, size_t inlen ) +{ + if( !in ) { + /* caller requested in-place encryption */ + /* actullay cipher_encrypt() does not need to know about it, but + * we may chnage this to get better performace */ + cipher_decrypt( h, out, out, outsize ); + } + else { + if( outsize < inlen ) + return set_lasterr( GCRYERR_TOO_SHORT ); + /* fixme: check that the inlength is a multipe of the blocksize + * if a blockoriented mode is used, or modify cipher_encrypt to + * return an error in this case */ + cipher_decrypt( h, out, in, inlen ); + } + return 0; +} + + /**************** * Used for PGP's somewhat strange CFB mode. Only works if - * the handle is in PHILS_CFB mode + * the corresponding flag is set. */ -void -cipher_sync( CIPHER_HANDLE c ) +static void +cipher_sync( GCRY_CIPHER_HD c ) { - if( c->mode == CIPHER_MODE_PHILS_CFB && c->unused ) { + if( (c->flags & GCRY_CIPHER_ENABLE_SYNC) && c->unused ) { memmove(c->iv + c->unused, c->iv, c->blocksize - c->unused ); memcpy(c->iv, c->lastiv + c->blocksize - c->unused, c->unused); c->unused = 0; } } + +int +gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen) +{ + switch( cmd ) { + case GCRYCTL_SET_KEY: + cipher_setkey( h, buffer, buflen ); + break; + case GCRYCTL_SET_IV: + cipher_setiv( h, buffer, buflen ); + break; + case GCRYCTL_CFB_SYNC: + cipher_sync( h ); + break; + + case GCRYCTL_DISABLE_ALGO: + /* this one expects a NULL handle and buffer pointing to an + * integer with the algo number. + */ + if( h || !buffer || buflen != sizeof(int) ) + return set_lasterr( GCRYERR_INV_ARG ); + disable_cipher_algo( *(int*)buffer ); + break; + + default: + return set_lasterr( GCRYERR_INV_OP ); + } + return 0; +} + + +/**************** + * Return information about the cipher handle. + * -1 is returned on error and gcry_errno() may be used to get more information + * about the error. + */ +int +gcry_cipher_info( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t *nbytes) +{ + switch( cmd ) { + default: + set_lasterr( GCRYERR_INV_OP ); + return -1; + } + return 0; +} + +/**************** + * Return information about the given cipher algorithm + * WHAT select the kind of information returned: + * GCRYCTL_GET_KEYLEN: + * Return the length of the key, if the algorithm + * supports multiple key length, the maximum supported value + * is returnd. The length is return as number of octets. + * buffer and nbytes must be zero. + * The keylength is returned in _bytes_. + * GCRYCTL_GET_BLKLEN: + * Return the blocklength of the algorithm counted in octets. + * buffer and nbytes must be zero. + * GCRYCTL_TEST_ALGO: + * Returns 0 when the specified algorithm is available for use. + * buffer and nbytes must be zero. + * + * On error the value -1 is returned and the error reason may be + * retrieved by gcry_errno(). + * Note: Because this function is in most caes used to return an + * integer value, we can make it easier for the caller to just look at + * the return value. The caller will in all cases consult the value + * and thereby detecting whether a error occured or not (i.e. while checking + * the block size) + */ +int +gcry_cipher_algo_info( int algo, int what, void *buffer, size_t *nbytes) +{ + unsigned int ui; + + switch( what ) { + case GCRYCTL_GET_KEYLEN: + if( buffer || nbytes ) { + set_lasterr( GCRYERR_INV_ARG ); + break; + } + ui = cipher_get_keylen( algo ); + if( ui > 0 && ui <= 512 ) + return (int)ui/8; + /* the only reason is an invalid algo or a strange blocksize */ + set_lasterr( GCRYERR_INV_ALGO ); + break; + + case GCRYCTL_GET_BLKLEN: + if( buffer || nbytes ) { + set_lasterr( GCRYERR_INV_ARG ); + break; + } + ui = cipher_get_blocksize( algo ); + if( ui > 0 && ui < 10000 ) + return (int)ui; + /* the only reason is an invalid algo or a strange blocksize */ + set_lasterr( GCRYERR_INV_ALGO ); + break; + + case GCRYCTL_TEST_ALGO: + if( buffer || nbytes ) { + set_lasterr( GCRYERR_INV_ARG ); + break; + } + if( check_cipher_algo( algo ) ) { + set_lasterr( GCRYERR_INV_ALGO ); + break; + } + return 0; + + default: + set_lasterr( GCRYERR_INV_OP ); + } + return -1; +} + + + diff --git a/cipher/elgamal.c b/cipher/elgamal.c index bbf9c278..9f98ce2e 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -351,8 +351,10 @@ sign(MPI a, MPI b, MPI input, ELG_secret_key *skey ) mpi_powm( a, skey->g, k, skey->p ); mpi_mul(t, skey->x, a ); mpi_subm(t, input, t, p_1 ); - while( mpi_is_neg(t) ) + while( mpi_is_neg(t) ) { + BUG(); /* That is nonsense code - left over from a very early test?*/ mpi_add(t, t, p_1); + } mpi_invm(inv, k, p_1 ); mpi_mulm(b, t, inv, p_1 ); diff --git a/cipher/md.c b/cipher/md.c index be921e4b..f0dc9394 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -24,6 +24,8 @@ #include <string.h> #include <errno.h> #include <assert.h> + +#include "g10lib.h" #include "util.h" #include "cipher.h" #include "errors.h" @@ -31,9 +33,38 @@ #include "rmd.h" +struct md_digest_list_s; + +/* this structure is put right after the GCRY_MD_HD buffer, so that + * only one memory block is needed. */ +struct gcry_md_context { + int magic; + int secure; + FILE *debug; + int finalized; + struct md_digest_list_s *list; +}; +#define CTX_MAGIC_NORMAL 0x11071961 +#define CTX_MAGIC_SECURE 0x16917011 + +static const char * digest_algo_to_string( int algo ); +static int check_digest_algo( int algo ); +static GCRY_MD_HD md_open( int algo, int secure ); +static int md_enable( GCRY_MD_HD hd, int algo ); +static GCRY_MD_HD md_copy( GCRY_MD_HD a ); +static void md_close(GCRY_MD_HD a); +static void md_write( GCRY_MD_HD a, byte *inbuf, size_t inlen); +static void md_final(GCRY_MD_HD a); +static byte *md_read( GCRY_MD_HD a, int algo ); +static int md_get_algo( GCRY_MD_HD a ); +static int md_digest_length( int algo ); +static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen ); +static void md_start_debug( GCRY_MD_HD a, const char *suffix ); +static void md_stop_debug( GCRY_MD_HD a ); + /**************** * This structure is used for the list of available algorithms - * and for the list of algorithms in MD_HANDLE. + * and for the list of algorithms in GCRY_MD_HD. */ struct md_digest_list_s { struct md_digest_list_s *next; @@ -146,7 +177,7 @@ load_digest_module( int req_algo ) * Map a string to the digest algo */ int -string_to_digest_algo( const char *string ) +gcry_md_map_name( const char *string ) { struct md_digest_list_s *r; @@ -162,7 +193,7 @@ string_to_digest_algo( const char *string ) /**************** * Map a digest algo to a string */ -const char * +static const char * digest_algo_to_string( int algo ) { struct md_digest_list_s *r; @@ -175,8 +206,21 @@ digest_algo_to_string( int algo ) return NULL; } +/**************** + * This function simply returns the name of the algorithm or some constant + * string when there is no algo. It will never return NULL. + * Use the macro gcry_md_test_algo() to check whether the algorithm + * is valid. + */ +const char * +gcry_md_algo_name( int algo ) +{ + const char *s = digest_algo_to_string( algo ); + return s? s: "?"; +} -int + +static int check_digest_algo( int algo ) { struct md_digest_list_s *r; @@ -196,37 +240,73 @@ check_digest_algo( int algo ) * More algorithms may be added by md_enable(). The initial algorithm * may be 0. */ -MD_HANDLE +static GCRY_MD_HD md_open( int algo, int secure ) { - MD_HANDLE hd; - int bufsize; - - if( secure ) { - bufsize = 512 - sizeof( *hd ); - hd = m_alloc_secure_clear( sizeof *hd + bufsize ); - } - else { - bufsize = 1024 - sizeof( *hd ); - hd = m_alloc_clear( sizeof *hd + bufsize ); + GCRY_MD_HD hd; + struct gcry_md_context *ctx; + int bufsize = secure? 512 : 1024; + size_t n; + + /* Allocate a memory area to hold the caller visible buffer with it's + * control information and the data required by this module. Set the + * context pointer at the beginning to this area. + * We have to use this strange scheme because we want to hide the + * internal data but have a variable sized buffer. + * + * +---+------+---........------+-------------+ + * !ctx! bctl ! buffer ! private ! + * +---+------+---........------+-------------+ + * ! ^ + * !---------------------------! + * + * We have to make sture that private is well aligned. + */ + n = sizeof( struct gcry_md_handle ) + bufsize; + n = ((n + sizeof(PROPERLY_ALIGNED_TYPE)-1) + / sizeof(PROPERLY_ALIGNED_TYPE) ) * sizeof(PROPERLY_ALIGNED_TYPE); + + /* allocate and set the Context pointer to the private data */ + hd = secure ? m_alloc_secure( n + sizeof( struct gcry_md_context ) ) + : m_alloc( n + sizeof( struct gcry_md_context ) ); + hd->ctx = ctx = (struct gcry_md_context*)( (char*)hd + n ); + /* setup the globally visible data (bctl in the diagram)*/ + hd->bufsize = n - sizeof( struct gcry_md_handle ) + 1; + hd->bufpos = 0; + /* initialize the private data */ + memset( hd->ctx, 0, sizeof *hd->ctx ); + ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL; + ctx->secure = secure; + fast_random_poll(); /* FIXME: should we really do that? */ + if( algo && md_enable( hd, algo ) ) { + md_close( hd ); + return NULL; } + return hd; +} + - hd->bufsize = bufsize+1; /* hd has already one byte allocated */ - hd->secure = secure; - if( algo ) - md_enable( hd, algo ); - fast_random_poll(); +GCRY_MD_HD +gcry_md_open( int algo, unsigned int flags ) +{ + GCRY_MD_HD hd; + /* fixme: check that algo is available and that only valid + * flag values are used */ + hd = md_open( algo, (flags & GCRY_MD_FLAG_SECURE) ); return hd; } -void -md_enable( MD_HANDLE h, int algo ) + + +static int +md_enable( GCRY_MD_HD hd, int algo ) { + struct gcry_md_context *h = hd->ctx; struct md_digest_list_s *r, *ac; for( ac=h->list; ac; ac = ac->next ) if( ac->algo == algo ) - return ; /* already enabled */ + return 0; /* already enabled */ /* find the algorithm */ do { for(r = digest_list; r; r = r->next ) @@ -234,8 +314,8 @@ md_enable( MD_HANDLE h, int algo ) break; } while( !r && load_digest_module( algo ) ); if( !r ) { - log_error("md_enable: algorithm %d not available\n", algo ); - return; + log_debug("md_enable: algorithm %d not available\n", algo ); + return set_lasterr( GCRYERR_INV_ALGO ); } /* and allocate a new list entry */ ac = h->secure? m_alloc_secure( sizeof *ac + r->contextsize @@ -247,20 +327,37 @@ md_enable( MD_HANDLE h, int algo ) h->list = ac; /* and init this instance */ (*ac->init)( &ac->context.c ); + return 0; } -MD_HANDLE -md_copy( MD_HANDLE a ) +int +gcry_md_enable( GCRY_MD_HD hd, int algo ) { - MD_HANDLE b; - struct md_digest_list_s *ar, *br; + return md_enable( hd, algo ); +} - if( a->bufcount ) - md_write( a, NULL, 0 ); - b = a->secure ? m_alloc_secure( sizeof *b + a->bufsize - 1 ) - : m_alloc( sizeof *b + a->bufsize - 1 ); - memcpy( b, a, sizeof *a + a->bufsize - 1 ); +static GCRY_MD_HD +md_copy( GCRY_MD_HD ahd ) +{ + struct gcry_md_context *a = ahd->ctx; + struct gcry_md_context *b; + GCRY_MD_HD bhd; + struct md_digest_list_s *ar, *br; + size_t n; + + if( ahd->bufpos ) + md_write( ahd, NULL, 0 ); + + n = (char*)ahd->ctx - (char*)ahd; + bhd = a->secure ? m_alloc_secure( n + sizeof( struct gcry_md_context ) ) + : m_alloc( n + sizeof( struct gcry_md_context ) ); + bhd->ctx = b = (struct gcry_md_context*)( (char*)bhd + n ); + /* no need to copy the buffer due to the write above */ + assert( ahd->bufsize == (n - sizeof( struct gcry_md_handle ) + 1) ); + bhd->bufsize = ahd->bufsize; + bhd->bufpos = 0; assert( !ahd->bufpos ); + memcpy( b, a, sizeof *a ); b->list = NULL; b->debug = NULL; /* and now copy the complete list of algorithms */ @@ -277,38 +374,43 @@ md_copy( MD_HANDLE a ) } if( a->debug ) - md_start_debug( b, "unknown" ); - return b; + md_start_debug( bhd, "unknown" ); + return bhd; } +GCRY_MD_HD +gcry_md_copy( GCRY_MD_HD hd ) +{ + return md_copy( hd ); +} /**************** * Reset all contexts and discard any buffered stuff. This may be used * instead of a md_close(); md_open(). */ void -md_reset( MD_HANDLE a ) +gcry_md_reset( GCRY_MD_HD a ) { struct md_digest_list_s *r; - a->bufcount = 0; - for( r=a->list; r; r = r->next ) { + a->bufpos = a->ctx->finalized = 0; + for( r=a->ctx->list; r; r = r->next ) { memset( r->context.c, 0, r->contextsize ); (*r->init)( &r->context.c ); } } -void -md_close(MD_HANDLE a) +static void +md_close(GCRY_MD_HD a) { struct md_digest_list_s *r, *r2; if( !a ) return; - if( a->debug ) + if( a->ctx->debug ) md_stop_debug(a); - for(r=a->list; r; r = r2 ) { + for(r=a->ctx->list; r; r = r2 ) { r2 = r->next; m_free(r); } @@ -317,60 +419,86 @@ md_close(MD_HANDLE a) void -md_write( MD_HANDLE a, byte *inbuf, size_t inlen) +gcry_md_close( GCRY_MD_HD hd ) +{ + md_close( hd ); +} + + +static void +md_write( GCRY_MD_HD a, byte *inbuf, size_t inlen) { struct md_digest_list_s *r; - if( a->debug ) { - if( a->bufcount && fwrite(a->buffer, a->bufcount, 1, a->debug ) != 1 ) + if( a->ctx->debug ) { + if( a->bufpos && fwrite(a->buf, a->bufpos, 1, a->ctx->debug ) != 1 ) BUG(); - if( inlen && fwrite(inbuf, inlen, 1, a->debug ) != 1 ) + if( inlen && fwrite(inbuf, inlen, 1, a->ctx->debug ) != 1 ) BUG(); } - for(r=a->list; r; r = r->next ) { - (*r->write)( &r->context.c, a->buffer, a->bufcount ); + for(r=a->ctx->list; r; r = r->next ) { + if( a->bufpos ) + (*r->write)( &r->context.c, a->buf, a->bufpos ); (*r->write)( &r->context.c, inbuf, inlen ); } - a->bufcount = 0; + a->bufpos = 0; } - void -md_final(MD_HANDLE a) +gcry_md_write( GCRY_MD_HD hd, const byte *inbuf, size_t inlen) +{ + md_write( hd, (byte*)inbuf, inlen ); +} + + + +static void +md_final(GCRY_MD_HD a) { struct md_digest_list_s *r; - if( a->finalized ) + if( a->ctx->finalized ) return; - if( a->bufcount ) + if( a->bufpos ) md_write( a, NULL, 0 ); - for(r=a->list; r; r = r->next ) { + for(r=a->ctx->list; r; r = r->next ) { (*r->final)( &r->context.c ); } - a->finalized = 1; + a->ctx->finalized = 1; +} + + +int +gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen) +{ + if( cmd == GCRYCTL_FINALIZE ) + md_final( hd ); + else + return GCRYERR_INV_OP; + return 0; } /**************** * if ALGO is null get the digest for the used algo (which should be only one) */ -byte * -md_read( MD_HANDLE a, int algo ) +static byte * +md_read( GCRY_MD_HD a, int algo ) { struct md_digest_list_s *r; if( !algo ) { /* return the first algorithm */ - if( (r=a->list) ) { + if( (r=a->ctx->list) ) { if( r->next ) log_debug("more than algorithm in md_read(0)\n"); return (*r->read)( &r->context.c ); } } else { - for(r=a->list; r; r = r->next ) + for(r=a->ctx->list; r; r = r->next ) if( r->algo == algo ) return (*r->read)( &r->context.c ); } @@ -378,6 +506,17 @@ md_read( MD_HANDLE a, int algo ) return NULL; } +/**************** + * Read out the complete digest, this function implictly finalizes + * the hash. + */ +byte * +gcry_md_read( GCRY_MD_HD hd, int algo ) +{ + gcry_md_ctl( hd, GCRYCTL_FINALIZE, NULL, 0 ); + return md_read( hd, algo); +} + /**************** * This function combines md_final and md_read but keeps the context @@ -388,22 +527,23 @@ md_read( MD_HANDLE a, int algo ) * hold the complete digest, the buffer is filled with as many bytes are * possible and this value is returned. */ -int -md_digest( MD_HANDLE a, int algo, byte *buffer, int buflen ) +#if 0 +static int +md_digest( GCRY_MD_HD a, int algo, byte *buffer, int buflen ) { struct md_digest_list_s *r = NULL; char *context; char *digest; - if( a->bufcount ) + if( a->bufpos ) md_write( a, NULL, 0 ); if( !algo ) { /* return digest for the first algorithm */ - if( (r=a->list) && r->next ) + if( (r=a->ctx->list) && r->next ) log_debug("more than algorithm in md_digest(0)\n"); } else { - for(r=a->list; r; r = r->next ) + for(r=a->ctx->list; r; r = r->next ) if( r->algo == algo ) break; } @@ -414,9 +554,9 @@ md_digest( MD_HANDLE a, int algo, byte *buffer, int buflen ) return r->mdlen; /* I don't want to change the interface, so I simply work on a copy - * the context (extra overhead - should be fixed)*/ - context = a->secure ? m_alloc_secure( r->contextsize ) - : m_alloc( r->contextsize ); + * of the context (extra overhead - should be fixed)*/ + context = a->ctx->secure ? m_alloc_secure( r->contextsize ) + : m_alloc( r->contextsize ); memcpy( context, r->context.c, r->contextsize ); (*r->final)( context ); digest = (*r->read)( context ); @@ -428,14 +568,26 @@ md_digest( MD_HANDLE a, int algo, byte *buffer, int buflen ) m_free(context); return buflen; } +#endif - +/**************** + * Read out an intermediate digest. + */ int -md_get_algo( MD_HANDLE a ) +gcry_md_get( GCRY_MD_HD hd, int algo, byte *buffer, int buflen ) +{ + /*md_digest ... */ + return GCRYERR_INTERNAL; +} + + + +static int +md_get_algo( GCRY_MD_HD a ) { struct md_digest_list_s *r; - if( (r=a->list) ) { + if( (r=a->ctx->list) ) { if( r->next ) log_error("WARNING: more than algorithm in md_get_algo()\n"); return r->algo; @@ -443,10 +595,18 @@ md_get_algo( MD_HANDLE a ) return 0; } + +int +gcry_md_get_algo( GCRY_MD_HD hd ) +{ + return md_get_algo( hd ); /* fixme: we need error handling */ +} + + /**************** * Return the length of the digest */ -int +static int md_digest_length( int algo ) { struct md_digest_list_s *r; @@ -457,14 +617,35 @@ md_digest_length( int algo ) return r->mdlen; } } while( !r && load_digest_module( algo ) ); - log_error("WARNING: no length for md algo %d\n", algo); return 0; } +/**************** + * Return the length of the digest in bytes. + * This function will return 0 in case of errors. + */ +unsigned int +gcry_md_get_algo_dlen( int algo ) +{ + /* we do some very quick checks here */ + switch( algo ) + { + case GCRY_MD_MD5: return 16; + case GCRY_MD_SHA1: + case GCRY_MD_RMD160: return 20; + default: { + int len = md_digest_length( algo ); + if( !len ) + set_lasterr( GCRYERR_INV_ALGO ); + return 0; + } + } +} + /* Hmmm: add a mode to enumerate the OIDs * to make g10/sig-check.c more portable */ -const byte * +static const byte * md_asn_oid( int algo, size_t *asnlen, size_t *mdlen ) { struct md_digest_list_s *r; @@ -485,31 +666,92 @@ md_asn_oid( int algo, size_t *asnlen, size_t *mdlen ) } + +/**************** + * Return information about the given cipher algorithm + * WHAT select the kind of information returned: + * GCRYCTL_TEST_ALGO: + * Returns 0 when the specified algorithm is available for use. + * buffer and nbytes must be zero. + * GCRYCTL_GET_ASNOID: + * Return the ASNOID of the algorithm in buffer. if buffer is NULL, only + * the required length is returned. + * + * On error the value -1 is returned and the error reason may be + * retrieved by gcry_errno(). + * Note: Because this function is in most caes used to return an + * integer value, we can make it easier for the caller to just look at + * the return value. The caller will in all cases consult the value + * and thereby detecting whether a error occured or not (i.e. while checking + * the block size) + */ +int +gcry_md_algo_info( int algo, int what, void *buffer, size_t *nbytes) +{ + switch( what ) { + case GCRYCTL_TEST_ALGO: + if( buffer || nbytes ) { + set_lasterr( GCRYERR_INV_ARG ); + return -1; + } + if( check_digest_algo( algo ) ) { + set_lasterr( GCRYERR_INV_ALGO ); + return -1; + } + break; + + case GCRYCTL_GET_ASNOID: { + size_t asnlen; + const char *asn = md_asn_oid( algo, &asnlen, NULL ); + if( buffer && *nbytes >= asnlen ) { + memcpy( buffer, asn, asnlen ); + *nbytes = asnlen; + return 0; + } + if( !buffer && nbytes ) { + *nbytes = asnlen; + return 0; + } + set_lasterr( buffer ? GCRYERR_TOO_SHORT : GCRYERR_INV_ARG ); + return -1; + } + break; + + default: + set_lasterr( GCRYERR_INV_OP ); + return -1; + } + return 0; +} + + + + void -md_start_debug( MD_HANDLE md, const char *suffix ) +md_start_debug( GCRY_MD_HD md, const char *suffix ) { static int idx=0; char buf[25]; - if( md->debug ) { + if( md->ctx->debug ) { log_debug("Oops: md debug already started\n"); return; } idx++; sprintf(buf, "dbgmd-%05d.%.10s", idx, suffix ); - md->debug = fopen(buf, "w"); - if( !md->debug ) + md->ctx->debug = fopen(buf, "w"); + if( !md->ctx->debug ) log_debug("md debug: can't open %s\n", buf ); } void -md_stop_debug( MD_HANDLE md ) +md_stop_debug( GCRY_MD_HD md ) { - if( md->debug ) { - if( md->bufcount ) + if( md->ctx->debug ) { + if( md->bufpos ) md_write( md, NULL, 0 ); - fclose(md->debug); - md->debug = NULL; + fclose(md->ctx->debug); + md->ctx->debug = NULL; } #ifdef HAVE_U64_TYPEDEF { /* a kludge to pull in the __muldi3 for Solaris */ @@ -521,3 +763,25 @@ md_stop_debug( MD_HANDLE md ) #endif } + + +/**************** + * Return information about the digest handle. + * GCRYCTL_IS_SECURE: + * Returns 1 when the handle works on secured memory + * otherwise 0 is returned. There is no error return. + */ +int +gcry_md_info( GCRY_MD_HD h, int cmd, void *buffer, size_t *nbytes) +{ + switch( cmd ) { + case GCRYCTL_IS_SECURE: + return h->ctx->secure; + + default: + set_lasterr( GCRYERR_INV_OP ); + return -1; + } + return 0; +} + diff --git a/cipher/pubkey.c b/cipher/pubkey.c index a03af302..4561f2ff 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -1,5 +1,5 @@ /* pubkey.c - pubkey dispatcher - * Copyright (C) 1998 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -24,6 +24,8 @@ #include <string.h> #include <errno.h> #include <assert.h> + +#include "g10lib.h" #include "util.h" #include "errors.h" #include "mpi.h" @@ -236,7 +238,7 @@ load_pubkey_modules(void) * Map a string to the pubkey algo */ int -string_to_pubkey_algo( const char *string ) +gcry_pk_map_name( const char *string ) { int i; const char *s; @@ -254,7 +256,7 @@ string_to_pubkey_algo( const char *string ) * Map a pubkey algo to a string */ const char * -pubkey_algo_to_string( int algo ) +gcry_pk_algo_name( int algo ) { int i; @@ -565,3 +567,78 @@ pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey, return rc; } + +int +gcry_pk_encrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey ) +{ + /* ... */ + return 0; +} + +int +gcry_pk_decrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey ) +{ + /* ... */ + return 0; +} + +int +gcry_pk_sign( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey ) +{ + GCRY_SEXP s; + /* get the secret key */ + s = NULL; /*gcry_sexp_find_token( skey, "private-key", 0 );*/ + if( !s ) + return -1; /* no private key */ + /* ... */ + return 0; +} + +int +gcry_pk_verify( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey ) +{ + /* ... */ + return 0; +} + + + + +/**************** + * Return information about the given algorithm + * WHAT select the kind of information returned: + * GCRYCTL_TEST_ALGO: + * Returns 0 when the specified algorithm is available for use. + * buffer and nbytes must be zero. + * + * On error the value -1 is returned and the error reason may be + * retrieved by gcry_errno(). + * Note: Because this function is in most caes used to return an + * integer value, we can make it easier for the caller to just look at + * the return value. The caller will in all cases consult the value + * and thereby detecting whether a error occured or not (i.e. while checking + * the block size) + */ +int +gcry_pk_algo_info( int algo, int what, void *buffer, size_t *nbytes) +{ + switch( what ) { + case GCRYCTL_TEST_ALGO: + if( buffer || nbytes ) { + set_lasterr( GCRYERR_INV_ARG ); + return -1; + } + if( check_pubkey_algo( algo ) ) { + set_lasterr( GCRYERR_INV_ALGO ); + return -1; + } + break; + + default: + set_lasterr( GCRYERR_INV_OP ); + return -1; + } + return 0; +} + + diff --git a/configure.in b/configure.in index ef3479a4..8f1ab0b2 100644 --- a/configure.in +++ b/configure.in @@ -109,22 +109,9 @@ dnl Check wether we want to compile libgcrypt dnl AC_MSG_CHECKING([whether compilation of libgcrypt is requested]) AC_ARG_ENABLE(libgcrypt, - [ --enable-libgcrypt compile the libgcrypt [default=no]], + [ --enable-libgcrypt compile the libgcrypt [default=yes]], [compile_libgcrypt="$enableval"],[compile_libgcrypt=no]) AC_MSG_RESULT($compile_libgcrypt) -if test x$compile_libgcrypt = xyes ; then - if test -f $srcdir/gcrypt/gcrypt.h; then - : - else - compile_libgcrypt=no - AC_MSG_WARN([[ -*** -*** LIBGCRYPT is not yet ready for public testing. -*** Maybe you have more luck with the next release of GnuPG -*** Watch the gnupg-announce mailing list or the webpage. -***]]) - fi -fi AM_CONDITIONAL(COMPILE_LIBGCRYPT, test x$compile_libgcrypt = xyes) @@ -680,10 +667,13 @@ AC_SUBST(ZLIBS) changequote(,)dnl tmp_pat='[a-zA-Z]' changequote([,])dnl -if echo "$VERSION" | grep $tmp_pat >/dev/null ; then +if echo "$VERSION" | grep "$tmp_pat" >/dev/null ; then AC_DEFINE(IS_DEVELOPMENT_VERSION) fi +dnl Temp workaround: +GNUPG_LINK_FILES(gcrypt/gcrypt.h, gcrypt.h ) + AM_CONDITIONAL(CROSS_COMPILING, test x$cross_compiling = xyes) GNUPG_DO_LINK_FILES diff --git a/doc/ChangeLog b/doc/ChangeLog new file mode 100644 index 00000000..b83adc83 --- /dev/null +++ b/doc/ChangeLog @@ -0,0 +1,36 @@ +Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de> + + * Makefile.am (SUBDIRS): Removed gph from this development series + +Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> + + * Makefile.am (SUBDIRS): New subdir gph for the manual. + +Thu Jul 22 20:03:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> + + * gpg.sgml (--always-trust): Added. + +Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> + + * Makefile.am: Create a dummy man page if docbook-to-man is missing. + +Wed Jun 16 20:16:21 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> + + * gpg1.pod: Removed. + * gpg.sgml: New. Replaces the pod file + * Makefile.am: Add rule to make a man file from sgml + +Tue Jun 15 12:21:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> + + * Makefile.in.in: Use DESTDIR. + +Mon May 31 19:41:10 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> + + * gpg.1pod: Enhanced the Bugs section (Michael). + +Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de> + + * gpg.1pod: Spelling and grammar corrections (John A. Martin) + * FAQ: Ditto. + * DETAILS: Ditto. + diff --git a/doc/Makefile.am b/doc/Makefile.am index ae5cdb50..9d06f9bd 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to create Makefile.in -SUBDIRS = gph +##SUBDIRS = gph EXTRA_DIST = DETAILS gpg.sgml gpg.1 FAQ HACKING OpenPGP diff --git a/scripts/ChangeLog b/scripts/ChangeLog index ce00b369..e7420553 100644 --- a/scripts/ChangeLog +++ b/scripts/ChangeLog @@ -1,3 +1,8 @@ +Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de> + + * commit: Remove leading and trailing empty lines when copying + Changes to Changelog + Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> diff --git a/src/ChangeLog b/src/ChangeLog index 01862f02..29f9c8b6 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,14 @@ -Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> +Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de> + + * pkapi.c: Removed. + + * symapi.c: Removed. + * g10lib.h: Moved to ../include. + + * mdapi.c: Removed. + +Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de> * sexp.c: New. diff --git a/src/Makefile.am b/src/Makefile.am index d1f3af8b..2faa4970 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,9 +3,9 @@ EXTRA_DIST = README INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -noinst_PROGRAMS = sexp -sexp_SOURCES = sexp.c mpiapi.c -sexp_LDADD = ../cipher/libcipher.la ../mpi/libmpi.la ../util/libutil.la @INTLLIBS@ +#noinst_PROGRAMS = sexp +#sexp_SOURCES = sexp.c mpiapi.c +#sexp_LDADD = ../cipher/libcipher.la ../mpi/libmpi.la ../util/libutil.la ./libgcrypt.la @INTLLIBS@ lib_LTLIBRARIES = libgcrypt.la @@ -15,10 +15,7 @@ libgcrypt_la_SOURCES = gcrypt.h \ g10lib.h \ misc.c \ global.c \ - mpiapi.c \ - symapi.c \ - mdapi.c \ - pkapi.c + mpiapi.c libgcrypt_la_DEPENDENCIES = libgcrypt.sym libgcrypt_la_LIBADD = ../cipher/libcipher.la \ diff --git a/src/g10lib.h b/src/g10lib.h deleted file mode 100644 index 031dc950..00000000 --- a/src/g10lib.h +++ /dev/null @@ -1,208 +0,0 @@ -/* g10lib.h - internal defintions for libgcrypt - * Copyright (C) 1998 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifndef G10LIB_H -#define G10LIB_H 1 - -#ifdef _GCRYPT_H - #error gcrypt.h already included -#endif - -#include "gcrypt.h" - -#ifdef G10_I18N_H - #error i18n should not be included here -#endif - -#define _(a) g10_gettext(a) -#define N_(a) (a) - -/*-- global.c --*/ -int set_lasterr( int ec ); - -/*-- misc.c --*/ -const char *g10_gettext( const char *key ); -int fatal_invalid_arg(const char *text); - -#if 0 -/* This used to be the old include/g10lib.h */ - -#include "mpi.h" - -int g10c_debug_mode; -int g10_opt_verbose; - -/******************************** - ******* math functions ******* - ********************************/ -MPI g10m_new( unsigned nbits ); -MPI g10m_new_secure( unsigned nbits ); -void g10m_release( MPI a ); -void g10m_resize( MPI a, unsigned nbits ); -MPI g10m_copy( MPI a ); -void g10m_swap( MPI a, MPI b); -void g10m_set( MPI w, MPI u); -void g10m_set_ui( MPI w, unsigned long u); -void g10m_set_bytes( MPI a, unsigned nbits, unsigned char (*fnc)(int), int opaque ); -int g10m_cmp( MPI u, MPI v ); -int g10m_cmp_ui( MPI u, unsigned long v ); - - -void g10m_add(MPI w, MPI u, MPI v); -void g10m_add_ui(MPI w, MPI u, unsigned long v ); -void g10m_sub( MPI w, MPI u, MPI v); -void g10m_sub_ui(MPI w, MPI u, unsigned long v ); - -void g10m_mul_ui(MPI w, MPI u, unsigned long v ); -void g10m_mul_2exp( MPI w, MPI u, unsigned long cnt); -void g10m_mul( MPI w, MPI u, MPI v); -void g10m_mulm( MPI w, MPI u, MPI v, MPI m); - -void g10m_fdiv_q( MPI quot, MPI dividend, MPI divisor ); - -void g10m_powm( MPI res, MPI base, MPI exp, MPI mod); - -int g10m_gcd( MPI g, MPI a, MPI b ); -int g10m_invm( MPI x, MPI u, MPI v ); - -unsigned g10m_get_nbits( MPI a ); -unsigned g10m_get_size( MPI a ); - -void g10m_set_buffer( MPI a, const char *buffer, unsigned nbytes, int sign ); - - -/******************************************** - ******* symmetric cipher functions ******* - ********************************************/ - - - -/********************************************* - ******* asymmetric cipher functions ******* - *********************************************/ - - - - -/********************************************* - ******* cryptograhic hash functions ******* - *********************************************/ - - -/***************************************** - ******* miscellaneous functions ******* - *****************************************/ - -const char *g10m_revision_string(int mode); -const char *g10c_revision_string(int mode); -const char *g10u_revision_string(int mode); - -MPI g10c_generate_secret_prime( unsigned nbits ); -char *g10c_get_random_bits( unsigned nbits, int level, int secure ); - - -void *g10_malloc( size_t n ); -void *g10_calloc( size_t n ); -void *g10_malloc_secure( size_t n ); -void *g10_calloc_secure( size_t n ); -void *g10_realloc( void *a, size_t n ); -void g10_free( void *p ); -char *g10_strdup( const char * a); - -void g10_log_bug( const char *fmt, ... ); -void g10_log_bug0( const char *, int ); -void g10_log_fatal( const char *fmt, ... ); -void g10_log_error( const char *fmt, ... ); -void g10_log_info( const char *fmt, ... ); -void g10_log_debug( const char *fmt, ... ); -void g10_log_hexdump( const char *text, char *buf, size_t len ); -void g10_log_mpidump( const char *text, MPI a ); - - -/*************************** - ******* constants ******* - **************************/ -#define CIPHER_ALGO_NONE 0 -#define CIPHER_ALGO_IDEA 1 -#define CIPHER_ALGO_3DES 2 -#define CIPHER_ALGO_CAST5 3 -#define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */ -#define CIPHER_ALGO_SAFER_SK128 5 -#define CIPHER_ALGO_DES_SK 6 -#define CIPHER_ALGO_BLOWFISH160 42 /* blowfish 160 bit key (not in OpenPGP)*/ -#define CIPHER_ALGO_DUMMY 110 /* no encryption at all */ - -#define PUBKEY_ALGO_RSA 1 -#define PUBKEY_ALGO_RSA_E 2 /* RSA encrypt only */ -#define PUBKEY_ALGO_RSA_S 3 /* RSA sign only */ -#define PUBKEY_ALGO_ELGAMAL_E 16 /* encrypt only ElGamal (but not vor v3)*/ -#define PUBKEY_ALGO_DSA 17 -#define PUBKEY_ALGO_ELGAMAL 20 /* sign and encrypt elgamal */ - -#define DIGEST_ALGO_MD5 1 -#define DIGEST_ALGO_SHA1 2 -#define DIGEST_ALGO_RMD160 3 -#define DIGEST_ALGO_TIGER 6 - -#define is_RSA(a) ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \ - || (a)==PUBKEY_ALGO_RSA_S ) -#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E) - -#define G10ERR_GENERAL 1 -#define G10ERR_PUBKEY_ALGO 4 -#define G10ERR_DIGEST_ALGO 5 -#define G10ERR_BAD_PUBKEY 6 -#define G10ERR_BAD_SECKEY 7 -#define G10ERR_BAD_SIGN 8 -#define G10ERR_CIPHER_ALGO 12 -#define G10ERR_WRONG_SECKEY 18 -#define G10ERR_UNSUPPORTED 19 -#define G10ERR_NI_PUBKEY 27 -#define G10ERR_NI_CIPHER 28 -#define G10ERR_BAD_MPI 30 -#define G10ERR_WR_PUBKEY_ALGO 41 - - -/*********************************** - ******* some handy macros ******* - ***********************************/ - -#ifndef BUG - #define BUG() g10_log_bug0( __FILE__ , __LINE__ ) -#endif - -#ifndef STR - #define STR(v) #v - #define STR2(v) STR(v) -#endif - -#ifndef DIM - #define DIM(v) (sizeof(v)/sizeof((v)[0])) - #define DIMof(type,member) DIM(((type *)0)->member) -#endif - - -#define DBG_CIPHER g10c_debug_mode -#define OPT_VERBOSE g10_opt_verbose - -#endif /* if 0 */ - - -#endif /* G10LIB_H */ diff --git a/src/gcrypt.h b/src/gcrypt.h index cb4cb43f..bc0e440f 100644 --- a/src/gcrypt.h +++ b/src/gcrypt.h @@ -24,6 +24,9 @@ extern "C" { #endif +#ifndef GCRYPT_NO_MPI_MACROS +#define GCRYPT_NO_MPI_MACROS +#endif #ifndef HAVE_BYTE_TYPEDEF #undef byte /* maybe there is a macro with this name */ @@ -49,6 +52,7 @@ enum { GCRYERR_TOO_SHORT = 8, /* provided buffer too short */ GCRYERR_TOO_LARGE = 9, /* object is too large */ GCRYERR_INV_OBJ = 10, /* an object is not valid */ + GCRYERR_WEAK_KEY = 11, /* weak encryption key */ }; @@ -64,6 +68,10 @@ enum gcry_ctl_cmds { GCRYCTL_GET_KEYLEN = 6, GCRYCTL_GET_BLKLEN = 7, GCRYCTL_TEST_ALGO = 8, + GCRYCTL_IS_SECURE = 9, + GCRYCTL_GET_ASNOID = 10, + GCRYCTL_ENABLE_ALGO = 11, + GCRYCTL_DISABLE_ALGO = 12, }; int gcry_control( enum gcry_ctl_cmds, ... ); @@ -116,6 +124,7 @@ enum gcry_mpi_format { GCRYMPI_FMT_USG = 4, /* like STD but this is an unsigned one */ }; + struct gcry_mpi; typedef struct gcry_mpi *GCRY_MPI; @@ -156,8 +165,8 @@ void gcry_mpi_powm( GCRY_MPI w, ******* symmetric cipher functions ******* ********************************************/ -struct gcry_cipher_context; -typedef struct gcry_cipher_context *GCRY_CIPHER_HD; +struct gcry_cipher_handle; +typedef struct gcry_cipher_handle *GCRY_CIPHER_HD; enum gcry_cipher_algos { GCRY_CIPHER_NONE = 0, @@ -182,17 +191,13 @@ enum gcry_cipher_flags { }; -#if 0 /* not yet done */ -int gcry_string_to_cipher_algo( const char *string ); -int gcry_check_cipher_algo( int algo ); -#endif - -GCRY_CIPHER_HD r gcry_cipher_open( int algo, int mode, unsigned flags); +GCRY_CIPHER_HD gcry_cipher_open( int algo, int mode, unsigned flags); void gcry_cipher_close( GCRY_CIPHER_HD h ); -int gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, byte *buffer, size_t buflen); +int gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen); int gcry_cipher_info( GCRY_CIPHER_HD h, int what, void *buffer, size_t *nbytes); int gcry_cipher_algo_info( int algo, int what, void *buffer, size_t *nbytes); const char *gcry_cipher_algo_name( int algo ); +int gcry_cipher_map_name( const char* name ); int gcry_cipher_encrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize, const byte *in, size_t inlen ); @@ -209,11 +214,11 @@ int gcry_cipher_decrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize, NULL, 0 ) #define gcry_cipher_get_algo_keylen(a) \ - gcry_cipher_algo_info( (a), GCRYCTL_GET_KEYLEN, NULL, NULL ); + gcry_cipher_algo_info( (a), GCRYCTL_GET_KEYLEN, NULL, NULL ) #define gcry_cipher_get_algo_blklen(a) \ - gcry_cipher_algo_info( (a), GCRYCTL_GET_BLKLEN, NULL, NULL ); + gcry_cipher_algo_info( (a), GCRYCTL_GET_BLKLEN, NULL, NULL ) #define gcry_cipher_test_algo(a) \ - gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ); + gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) /********************************************* @@ -225,14 +230,18 @@ int gcry_pk_decrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey ); int gcry_pk_sign( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey ); int gcry_pk_verify( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey ); +int gcry_pk_algo_info( int algo, int what, void *buffer, size_t *nbytes); +const char *gcry_pk_algo_name( int algo ); +int gcry_pk_map_name( const char* name ); + + +#define gcry_pk_test_algo(a) \ + gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) /********************************************* ******* cryptograhic hash functions ******* *********************************************/ -struct gcry_md_context; -typedef struct gcry_md_context *GCRY_MD_HD; /* same as the old MD_HANDLE */ - enum gcry_md_algos { GCRY_MD_NONE = 0, GCRY_MD_MD5 = 1, @@ -246,17 +255,47 @@ enum gcry_md_flags { }; +struct gcry_md_context; +struct gcry_md_handle { + struct gcry_md_context *ctx; + int bufpos; + int bufsize; + byte buf[1]; +}; +typedef struct gcry_md_handle *GCRY_MD_HD; + + GCRY_MD_HD gcry_md_open( int algo, unsigned flags ); void gcry_md_close( GCRY_MD_HD hd ); int gcry_md_enable( GCRY_MD_HD hd, int algo ); GCRY_MD_HD gcry_md_copy( GCRY_MD_HD hd ); +void gcry_md_reset( GCRY_MD_HD hd ); int gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen); void gcry_md_write( GCRY_MD_HD hd, const byte *buffer, size_t length); byte *gcry_md_read( GCRY_MD_HD hd, int algo ); int gcry_md_get_algo( GCRY_MD_HD hd ); -int gcry_md_get_dlen( int algo ); +unsigned int gcry_md_get_algo_dlen( int algo ); /*??int gcry_md_get( GCRY_MD_HD hd, int algo, byte *buffer, int buflen );*/ +int gcry_md_info( GCRY_MD_HD h, int what, void *buffer, size_t *nbytes); +int gcry_md_algo_info( int algo, int what, void *buffer, size_t *nbytes); +const char *gcry_md_algo_name( int algo ); +int gcry_md_map_name( const char* name ); + +#define gcry_md_putc(h,c) \ + do { \ + if( (h)->bufpos == (h)->bufsize ) \ + gcry_md_write( (h), NULL, 0 ); \ + (h)->buf[(h)->bufpos++] = (c) & 0xff; \ + } while(0) + +#define gcry_md_final(a) \ + gcry_md_ctl( (a), GCRYCTL_FINALIZE, NULL, 0 ) + +#define gcry_md_is_secure(a) \ + gcry_md_info( (a), GCRYCTL_IS_SECURE, NULL, NULL ) +#define gcry_md_test_algo(a) \ + gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) /***************************************** ******* miscellaneous functions ******* @@ -342,10 +381,55 @@ void g10_log_mpidump( const char *text, MPI a ); typedef struct gcry_mpi *MPI; - #endif /* GCRYPT_NO_MPI_MACROS */ #ifdef __cplusplus } #endif + + +/***************************************** + ******** Stuff to be changed ************ + *****************************************/ + +/*-- cipher/pubkey.c --*/ +#define PUBKEY_MAX_NPKEY 4 +#define PUBKEY_MAX_NSKEY 6 +#define PUBKEY_MAX_NSIG 2 +#define PUBKEY_MAX_NENC 2 + +#ifndef DID_MPI_TYPEDEF + typedef struct gcry_mpi * MPI; + #define DID_MPI_TYPEDEF +#endif + +int string_to_pubkey_algo( const char *string ); +const char * pubkey_algo_to_string( int algo ); +void disable_pubkey_algo( int algo ); +int check_pubkey_algo( int algo ); +int check_pubkey_algo2( int algo, unsigned use ); +int pubkey_get_npkey( int algo ); +int pubkey_get_nskey( int algo ); +int pubkey_get_nsig( int algo ); +int pubkey_get_nenc( int algo ); +unsigned pubkey_nbits( int algo, MPI *pkey ); +int pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ); +int pubkey_check_secret_key( int algo, MPI *skey ); +int pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey ); +int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey ); +int pubkey_sign( int algo, MPI *resarr, MPI hash, MPI *skey ); +int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey, + int (*cmp)(void *, MPI), void *opaque ); + + + + +/*-- primegen.c --*/ +MPI generate_secret_prime( unsigned nbits ); +MPI generate_public_prime( unsigned nbits ); +MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits, + MPI g, MPI **factors ); + + + #endif /* _GCRYPT_H */ diff --git a/src/mdapi.c b/src/mdapi.c deleted file mode 100644 index 5fd2eb61..00000000 --- a/src/mdapi.c +++ /dev/null @@ -1,127 +0,0 @@ -/* mdapi.c - message digest function interface - * Copyright (C) 1998 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <assert.h> - -#define GCRYPT_NO_MPI_MACROS 1 -#include "g10lib.h" -#include "cipher.h" -#include "memory.h" - - -GCRY_MD_HD -gcry_md_open( GCRY_MD_HD *ret_hd, int algo, unsigned int flags ) -{ - /* fixme: check that algo is available and that only valid - * flag values are used */ - hd = md_open( algo, (flags & GCRY_MD_FLAG_SECURE) ); - return hd; -} - -void -gcry_md_close( GCRY_MD_HD hd ) -{ - md_close( hd ); -} - -int -gcry_md_enable( GCRY_MD_HD hd, int algo ) -{ - /* fixme: check that algo is available */ - md_enable( hd, algo ); - return 0; -} - -GCRY_MD_HD -gcry_md_copy( GCRY_MD_HD hd ) -{ - return md_copy( hd ); -} - -int -gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen) -{ - if( cmd == GCRYCTL_FINALIZE ) - md_final( hd ); - else - return GCRYERR_INV_OP; - return 0; -} - -void -gcry_md_write( GCRY_MD_HD hd, const byte *inbuf, size_t inlen) -{ - md_write( hd, (byte*)inbuf, inlen ); -} - -/**************** - * Read out the complete digest, this function implictly finalizes - * the hash. - */ -byte * -gcry_md_read( GCRY_MD_HD hd, int algo ) -{ - gcry_md_ctl( hd, GCRYCTL_FINALIZE, NULL, 0 ); - return md_read( hd, algo); -} - -int -gcry_md_get_algo( GCRY_MD_HD hd ) -{ - return md_get_algo( hd ); /* fixme: we need error handling */ -} - -/**************** - * Return the length of the digest in bytes. - * This function will return 0 in case of errors. - */ -unsigned int -gcry_md_get_algo_dlen( int algo ) -{ - /* we do some very quick checks here */ - switch( algo ) - { - case GCRY_MD_MD5: return 16; - case GCRY_MD_SHA1: - case GCRY_MD_RMD160: return 20; - default: - /* fixme: pass it to a lookup function */ - set_lasterr( GCRYERR_INV_ALGO ); - return -1; - } -} - - -/**************** - * Read out an intermediate digest. - */ -int -gcry_md_get( GCRY_MD_HD hd, int algo, byte *buffer, int buflen ) -{ - return GCRYERR_INTERNAL; -} - - - diff --git a/src/pkapi.c b/src/pkapi.c deleted file mode 100644 index 7d48c4c9..00000000 --- a/src/pkapi.c +++ /dev/null @@ -1,67 +0,0 @@ -/* pkapi.c - public key function interface - * Copyright (C) 1998 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <assert.h> - -#include "g10lib.h" - - - - - - -int -gcry_pk_encrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey ) -{ - /* ... */ - return 0; -} - -int -gcry_pk_decrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey ) -{ - /* ... */ - return 0; -} - -int -gcry_pk_sign( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey ) -{ - GCRY_SEXP s; - /* get the secret key */ - s = gcry_sexp_find_token( skey, "private-key", 0 ); - if( !s ) - return -1; /* no private key */ - /* ... */ - return 0; -} - -int -gcry_pk_verify( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey ) -{ - /* ... */ - return 0; -} - diff --git a/src/symapi.c b/src/symapi.c deleted file mode 100644 index 5cd21775..00000000 --- a/src/symapi.c +++ /dev/null @@ -1,280 +0,0 @@ -/* symapi.c - symmetric cipher function interface - * Copyright (C) 1998 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -/* fixme: merge this function with ../cipher/cipher.c */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <assert.h> - -#include "g10lib.h" -#define G10_MPI_H /* fake mpi.h header */ -#include "cipher.h" - -/* FIXME: We should really have the m_lib functions to allow - * overriding of the default malloc functions - * For now use this kludge: */ -#define m_lib_alloc m_alloc -#define m_lib_alloc_clear m_alloc_clear -#define m_lib_free m_free - - -#define CONTEXT_MAGIC 0x12569afe - -struct gcry_cipher_context { - u32 magic; - int mode; - unsigned flags; - CIPHER_HANDLE hd; -}; - - -GCRY_CIPHER_HD -gcry_cipher_open( int algo, int mode, unsigned flags ) -{ - GCRY_CIPHER_HD h; - - /* check whether the algo is available */ - if( check_cipher_algo( algo ) ) { - set_lasterr( GCRYERR_INV_ALGO ); - return NULL; - } - - /* check flags */ - if( (flags & ~(GCRY_CIPHER_SECURE|GCRY_CIPHER_ENABLE_SYNC)) ) { - set_lasterr( GCRYERR_INV_ARG ); - return NULL; - } - - /* map mode to internal mode */ - switch( mode ) { - case GCRY_CIPHER_MODE_NONE: - mode = CIPHER_MODE_DUMMY; - break; - case GCRY_CIPHER_MODE_ECB: - mode = CIPHER_MODE_ECB; - break; - case GCRY_CIPHER_MODE_CFB: - mode = (flags & GCRY_CIPHER_ENABLE_SYNC) ? CIPHER_MODE_PHILS_CFB - : CIPHER_MODE_CFB; - break; - case GCRY_CIPHER_MODE_CBC: mode = CIPHER_MODE_CBC; - break; - default: - set_lasterr( GCRYERR_INV_ALGO ); - return NULL; - } - - /* FIXME: issue a warning when CIPHER_MODE_NONE is used */ - - /* allocate the handle */ - h = m_lib_alloc_clear( sizeof *h ); - if( !h ) { - set_lasterr( GCRYERR_NOMEM ); - return NULL; - } - h->magic = CONTEXT_MAGIC; - h->mode = mode; - h->hd = cipher_open( algo, mode, (flags & GCRY_CIPHER_SECURE) ); - if( !h ) { - m_lib_free( h ); - set_lasterr( GCRYERR_INTERNAL ); - return NULL; - } - - return h; -} - - -void -gcry_cipher_close( GCRY_CIPHER_HD h ) -{ - if( !h ) - return; - if( h->magic != CONTEXT_MAGIC ) { - fatal_invalid_arg("gcry_cipher_close: already closed/invalid handle"); - return; - } - cipher_close( h->hd ); - h->magic = 0; - m_lib_free(h); -} - -int gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, byte *buffer, size_t buflen) -{ - switch( cmd ) { - case GCRYCTL_SET_KEY: - cipher_setkey( h->hd, buffer, buflen ); - break; - case GCRYCTL_SET_IV: - cipher_setiv( h->hd, buffer, buflen ); - break; - case GCRYCTL_CFB_SYNC: - cipher_sync( h->hd ); - default: - return set_lasterr( GCRYERR_INV_OP ); - } - return 0; -} - - -/**************** - * Return information about the cipher handle. - * -1 is returned on error and gcry_errno() may be used to get more information - * about the error. - */ -int -gcry_cipher_info( GCRY_CIPHER_HD h, int cmd, byte *buffer, size_t *nbytes) -{ - switch( cmd ) { - default: - set_lasterr( GCRYERR_INV_OP ); - return -1; - } - return 0; -} - -/**************** - * Return information about the given cipher algorithm - * WHAT select the kind of information returned: - * GCRYCTL_GET_KEYLEN: - * Return the length of the key, if the algorithm - * supports multiple key length, the maximum supported value - * is returnd. The length is return as number of octets. - * buffer and nbytes must be zero. - * GCRYCTL_GET_BLKLEN: - * Return the blocklength of the algorithm counted in octets. - * buffer and nbytes must be zero. - * GCRYCTL_TEST_ALGO: - * Returns 0 when the specified algorithm is available for use. - * buffer and nbytes must be zero. - * - * On error the value -1 is returned and the error reason may be - * retrieved by gcry_errno(). - * Note: Because this function is in most caes used to return an - * integer value, we can make it easier for the caller to just look at - * the return value. The caller will in all cases consult the value - * and thereby detecting whether a error occured or not (i.e. while checking - * the block size) - */ -int -gcry_cipher_algo_info( int algo, int what, void *buffer, size_t *nbytes) -{ - switch( what ) { - case GCRYCTL_GET_KEYLEN: - if( buffer || nbytes ) { - set_lasterr( GCRYERR_INV_ARG ); - return -1; - } - BUG(); /* FIXME: implement this */ - break; - - case GCRYCTL_GET_BLKLEN: - if( buffer || nbytes ) { - set_lasterr( GCRYERR_INV_ARG ); - return -1; - } - ui = cipher_get_blocksize( algo ); - if( ui > 0 && ui < 10000 ) - return (int)ui; - /* the only reason is an invalid algo or a strange blocksize */ - set_lasterr( GCRYERR_INV_ALGO ); - return -1; - - case GCRYCTL_TEST_ALGO: - if( buffer || nbytes ) { - set_lasterr( GCRYERR_INV_ARG ); - return -1; - } - if( check_cipher_algo( algo ) ) { - set_lasterr( GCRYERR_INV_ALGO ); - return -1; - } - return 0; - - - default: - set_lasterr( GCRYERR_INV_OP ); - return -1; - } - return 0; -} - - -/**************** - * This function simply returns the name of the algorithm or soem constant - * string when there is no algo. It will never return NULL. - */ -const char * -gcry_cipher_algo_name( int algo ) -{ - return cipher_algo_to_string( algo ); -} - - -/**************** - * Encrypt IN and write it to OUT. If IN is NULL, in-place encryption has - * been requested, - */ -int -gcry_cipher_encrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize, - const byte *in, size_t inlen ) -{ - if( !in ) { - /* caller requested in-place encryption */ - /* actullay cipher_encrypt() does not need to know about it, but - * we may chnage this to get better performace */ - cipher_encrypt( h->hd, out, out, outsize ); - } - else { - if( outsize < inlen ) - return set_lasterr( GCRYERR_TOO_SHORT ); - /* fixme: check that the inlength is a multipe of the blocksize - * if a blockoriented mode is used, or modify cipher_encrypt to - * return an error in this case */ - cipher_encrypt( h->hd, out, in, inlen ); - } - return 0; -} - -int -gcry_cipher_decrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize, - const byte *in, size_t inlen ) -{ - if( !in ) { - /* caller requested in-place encryption */ - /* actullay cipher_encrypt() does not need to know about it, but - * we may chnage this to get better performace */ - cipher_decrypt( h->hd, out, out, outsize ); - } - else { - if( outsize < inlen ) - return set_lasterr( GCRYERR_TOO_SHORT ); - /* fixme: check that the inlength is a multipe of the blocksize - * if a blockoriented mode is used, or modify cipher_encrypt to - * return an error in this case */ - cipher_decrypt( h->hd, out, in, inlen ); - } - return 0; -} - |