diff --git a/checks/defs.inc b/checks/defs.inc index 14c657543..dbd6e33b6 100755 --- a/checks/defs.inc +++ b/checks/defs.inc @@ -70,6 +70,7 @@ pgmname=$(basename $0) cat <./options no-greeting no-secmem-warning +load-extension ../cipher/tiger.so batch EOF diff --git a/checks/secring.asc b/checks/secring.asc index 6be8c6da2..09e059d6f 100644 --- a/checks/secring.asc +++ b/checks/secring.asc @@ -6,17 +6,17 @@ sec 800G/2E5FA4F4 1998-04-28 test two (no pp) sec 768G/6D11D6D3 1998-04-28 test three (pp=abc) -----BEGIN PGP ARMORED FILE----- -Version: GNUPG v0.2.16 (Linux) +Version: GNUPG v0.2.19b (GNU/Linux) Comment: This is an alpha version! Comment: Use "gpgm --dearmor" for unpacking lQFHAzVFgbgERxADAPG0kMNVRUl24GfpzV4TPcXgw/jqSkFOIVGgin7k7UR6GOUMUz89wxVk ZRXsLAOdDrtvI5T1sSCmWmhsTKmw7aslLJugBM/70YuVSolR39vF1JDK8kEkx748CRVW+/ul mwADBQMA12YmsDbYGLI8FXnb/8V3YU7K39E5//Bwo90vTfzAE9Mwp1y9H5WHqoai/6JLgXK8 -DAOGpgCFhlVu8LO5O0IK3yaFhtkhC8SE/TKLzC76uSoeeSex+mJ+rqBcyDl9AONx/wQBA/c/ -kLpBoHpDRQ4A6ETACZ8C/1NQCBF5zcnjFERni2jcwTiASGFAB4nnIwr7lm9lZ3JxF2xW3LSY -2EwlJixA1kIUWWLJHo/kEAT8rCd3wG+a/UMJwuTgSd4odq/lFe13dxo8eah8cgAY+dlFiBap -r9WclDDI/SojOkVMR19mYWN0b3I6AADKAiaJiV+4kJIpYCgbjafKyy11LI3mgHQV8Hf9KiM6 +DAOGpgCFhlVu8LO5O0IK3yaFhtkhC8SE/TKLzC76uSoeeSex+mJ+rqBcyDl9AONx/wQBA1ax +FAGSVKH6no4iMVtLeiYDACtVsQ4oTGIR7wAakh4QkO5j81Vg0+v3AGMNvTMlTmwtlGtmKv2M +01WryUpzA9dKe8RBhe4Uofa7OVOAaN8RujSNXMM2XWCoH+Om8oGSzmMvT2MTOa4rrk6+Noer +tShKnDDI/SojOkVMR19mYWN0b3I6AADKAiaJiV+4kJIpYCgbjafKyy11LI3mgHQV8Hf9KiM6 RUxHX2ZhY3RvcjoAAMoDjg2kuv69NwxJNr89un9g6yT/mlXDM36tFf0qIzpFTEdfZmFjdG9y OgAAygPBg2CM/6uXiIHWF2kf/4p3sDJXQ3jZm8bH/SIjY3JlYXRlZCBieSBHTlVQRyB2MC4y LjE1YSAoTGludXgptChUZXN0IG9uZSAocHA9ZGVmKSA8b25lQHRlc3Qubm93aGVyZS5uaWw+ @@ -29,10 +29,10 @@ fjKjGo5fe24OYlGBmpueTxApJKMzpbHA8wxfXsVmOrHsuOHQUREIYFy1VhOBmdRt7MvOWg/r FR4McJc/AAMFAyCwFfMOhS+z6YInnQDh7JTLan+7IdSHjUpAo0XarzAioCq6Ei0LaPVqa1zF L9yh5ky+06WTWnfvMSVCu0eRh1E0dTiBUDCb06HRvEVOiTmhqHk6loLOtb9NHxYMGOrGDtdX JJrHAAMfaR/MS44PJRtwrFDIBTOJWqjdX1Mu3wzB3443rS+hv9onUUjeLNbXFzXAxxHTLm4Z -0JQ1Um2Yi4XGTYZkFNRPq5jE+Imoj/trN+T2rri1f+m/Y5ugSH/Zx7hurhc/3yJ//oCGYTNY -0CsjOkVMR19mYWN0b3I6AADVEOrdw68kJz/XyG9/nJZ40oqzBklaf+BeatFD0CsjOkVMR19m -YWN0b3I6AADVF7ggxjMhZ+iMjbJxRSS5vmro7mbuP+5W5gLR0CsjOkVMR19mYWN0b3I6AADV -F5fMXChN1OIqFi7DHiaDKWyRJcNk6EaDu0BF0CIjY3JlYXRlZCBieSBHTlVQRyB2MC4yLjE1 +0JQ1Um2Yi4XGTYZkFNRPq5jE+Imoj/trN+T2rri1f+m/Y5ugSH/Zx7hurhc/3yJ//oCGYTNb +/SsjOkVMR19mYWN0b3I6AADVEOrdw68kJz/XyG9/nJZ40oqzBklaf+BeatFD/SsjOkVMR19m +YWN0b3I6AADVF7ggxjMhZ+iMjbJxRSS5vmro7mbuP+5W5gLR/SsjOkVMR19mYWN0b3I6AADV +F5fMXChN1OIqFi7DHiaDKWyRJcNk6EaDu0BF/SIjY3JlYXRlZCBieSBHTlVQRyB2MC4yLjE1 YSAoTGludXgptCd0ZXN0IHR3byAobm8gcHApIDx0d29AdGVzdC5ub3doZXJlLm5pbD6I3wMF EzVFggEO+eDoLl+k9BADkLEDHR+OG+ItBNWQE75V5vFHruJ0blRPEPaJL0GnVW/Lgi8jcUaM 7RwJyZ2XeMiCeJHU1kgHTa/E5VSUZJM5q/w1c1vcy76Izxqgnx19TEFEcGxzbzHLyT3APQVg @@ -42,9 +42,9 @@ tGRBuqSVAUcDNUWCZQAAEAMAlmULKDSSSPLtZ1fuVWWl2amQZ/rpN36f5su5fWC0HleUvVO+ joHcNJWv2Ill9pvAMPoTuO6WLMLMkYtpbvxRP3a9KNAgedyweBJxST4gR6wfK5t8CNeNgUHi fQ4+WFPzAAMGAv9YAdDaBZdkIW2GPN7bi4P1JSJDPAmbcbV0fb30KtFIK1bg6Hi8dP5pZ1pv KZibB0ftK/LC9so5ez9EUPhSbYmjE1R4oScoV7pAjtWzzNz1/C/0LJlxc1nH5mr5NdcaTzX/ -BAEDCeZ5R0kN6fg2yGkyrcFmxQL/ZFqgKUqFq7IuzbBnliDeqVTUCiMoRS/T2ygWVgScPfSU -iSixO3hRnJ6Z1tpIizlS+Al7SnpMJX7Qt46g3THrqQtax5KyLShgAtepL0Q32PTd66siLLb3 -iFPiLpggl2rxMMb9KiM6RUxHX2ZhY3RvcjoAAMoCbaGz3MaDbSFTmKdOGCSNFFsowjco3mWH +BAEDG+unPjMgny2Egnnpj+C75wL9WMnkY/0W6WbEnAa5AQisByWpoBmEox4n3ujQqonm6UXY +/gjQXe4Xc7ZwNOvDMo7FpSb22HAbXM0RX7WYSYiH3bFTS8ZbodTx9xhDK0rMPE/Ci7wbYMWZ +YyTuRz49WOO1MMb9KiM6RUxHX2ZhY3RvcjoAAMoCbaGz3MaDbSFTmKdOGCSNFFsowjco3mWH U/0qIzpFTEdfZmFjdG9yOgAAygLi9An6HulYgRcvIO1/Rn1ZAcrG447MbdxD/SojOkVMR19m YWN0b3I6AADKAo2787sJdMSkDQ6ENCcVlu+yXsVSWa++zWH9IiNjcmVhdGVkIGJ5IEdOVVBH IHYwLjIuMTVhIChMaW51eCm0LHRlc3QgdGhyZWUgKHBwPWFiYykgPHRocmVlQHRlc3Qubm93 @@ -53,5 +53,5 @@ aGVyZS5uaWw+iNcDBRM1RYJlZE80um0R1tMQA1bRAv9mehnmJtPFKcQ+S9AzBHDNF77nk58l dYdmlrSD+53gOH91KGeqpSrd7l0C/2ZhobXCxF03goKfNENvjej4HAGnzN0q0mpfu7L2wsCG 4/kXKv8W6Z2JtYpnszyw6xJCh0dyup2RSYKbfZMrb1BfjwlrZE03Ah4QRmat5byprwl9oosJ tW5GlGnLFCLsPQ== -=onv+ +=VGBx -----END PGP ARMORED FILE----- diff --git a/checks/signencrypt-dsa.test b/checks/signencrypt-dsa.test index d556f58f7..9a7f46bd7 100755 --- a/checks/signencrypt-dsa.test +++ b/checks/signencrypt-dsa.test @@ -10,7 +10,7 @@ for i in $plain_files $data_files ; do cmp $i y || error "$i: mismatch" done -for da in rmd160 sha1 md5; do +for da in ripemd160 sha1 md5; do for i in $plain_files; do ./run-gpg $dsa_keyrings -se -o x --yes --digest-algo $da \ -u "$dsa_usrname1" -r "$dsa_usrname2" $i diff --git a/checks/sigs-dsa.test b/checks/sigs-dsa.test index 6f07288f4..4e532c0c0 100755 --- a/checks/sigs-dsa.test +++ b/checks/sigs-dsa.test @@ -9,7 +9,7 @@ for i in $plain_files $data_files; do cmp $i y || error "$i: mismatch" done -for da in rmd160 sha1 md5; do +for da in ripemd160 sha1 md5; do for i in $plain_files; do ./run-gpg $dsa_keyrings --digest-algo $da \ -s -o x --yes -u $dsa_usrname1 $i diff --git a/checks/sigs.test b/checks/sigs.test index 4b3894c28..f3766a814 100755 --- a/checks/sigs.test +++ b/checks/sigs.test @@ -9,7 +9,7 @@ for i in $plain_files $data_files; do cmp $i y || error "$i: mismatch" done -for da in rmd160 sha1 md5 tiger; do +for da in ripemd160 sha1 md5 tiger; do for i in $plain_files; do echo "$usrpass1" | ./run-gpg --passphrase-fd 0 --digest-algo $da \ -s -o x --yes $i diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 2cb4ddc41..d0c0202c9 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -9,7 +9,6 @@ noinst_LIBRARIES = libcipher.a libcipher_a_SOURCES = cipher.c \ pubkey.c \ md.c \ - md.h \ dynload.c \ dynload.h \ blowfish.c \ @@ -19,7 +18,6 @@ libcipher_a_SOURCES = cipher.c \ elgamal.c \ elgamal.h \ md5.c \ - md5.h \ primegen.c \ random.h \ random.c \ diff --git a/cipher/cipher.c b/cipher/cipher.c index cedcb37af..df38850ad 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -35,7 +35,7 @@ #define STD_BLOCKSIZE 8 -#define TABLE_SIZE 20 +#define TABLE_SIZE 10 struct cipher_table_s { const char *name; @@ -79,13 +79,9 @@ static void setup_cipher_table() { - static int initialized = 0; int i; size_t blocksize; - if( initialized ) - return; - i = 0; cipher_table[i].algo = CIPHER_ALGO_BLOWFISH; cipher_table[i].name = blowfish_get_info( cipher_table[i].algo, @@ -131,7 +127,6 @@ setup_cipher_table() for( ; i < TABLE_SIZE; i++ ) cipher_table[i].name = NULL; - initialized = 1; } @@ -142,6 +137,7 @@ static int load_cipher_modules() { static int done = 0; + static int initialized = 0; void *context = NULL; struct cipher_table_s *ct; int ct_idx; @@ -150,6 +146,12 @@ load_cipher_modules() const char *name; int any = 0; + if( !initialized ) { + setup_cipher_table(); /* load static modules on the first call */ + initialized = 1; + return 1; + } + if( done ) return 0; done = 1; @@ -208,7 +210,6 @@ string_to_cipher_algo( const char *string ) int i; const char *s; - setup_cipher_table(); do { for(i=0; (s=cipher_table[i].name); i++ ) if( !stricmp( s, string ) ) @@ -225,7 +226,6 @@ cipher_algo_to_string( int algo ) { int i; - setup_cipher_table(); do { for(i=0; cipher_table[i].name; i++ ) if( cipher_table[i].algo == algo ) @@ -242,7 +242,6 @@ check_cipher_algo( int algo ) { int i; - setup_cipher_table(); do { for(i=0; cipher_table[i].name; i++ ) if( cipher_table[i].algo == algo ) @@ -258,7 +257,6 @@ cipher_get_keylen( int algo ) int i; unsigned len = 0; - setup_cipher_table(); do { for(i=0; cipher_table[i].name; i++ ) { if( cipher_table[i].algo == algo ) { @@ -284,7 +282,6 @@ cipher_open( int algo, int mode, int secure ) CIPHER_HANDLE hd; int i; - setup_cipher_table(); fast_random_poll(); do { for(i=0; cipher_table[i].name; i++ ) diff --git a/cipher/dynload.c b/cipher/dynload.c index 71f0d1959..767372a7e 100644 --- a/cipher/dynload.c +++ b/cipher/dynload.c @@ -22,7 +22,9 @@ #include #include #include -#include +#ifdef HAVE_DL_DLOPEN + #include +#endif #include "util.h" #include "cipher.h" #include "dynload.h" @@ -86,6 +88,7 @@ register_cipher_extension( const char *fname ) static int load_extension( EXTLIST el ) { + #ifdef USE_DYNAMIC_LINKING char **name; void *sym; const char *err; @@ -143,11 +146,68 @@ load_extension( EXTLIST el ) el->handle = NULL; } el->failed = 1; + #endif /*USE_DYNAMIC_LINKING*/ return -1; } +int +enum_gnupgext_digests( void **enum_context, + int *algo, + const char *(**r_get_info)( int, size_t*,byte**, int*, int*, + void (**)(void*), + void (**)(void*,byte*,size_t), + void (**)(void*),byte *(**)(void*)) ) +{ + EXTLIST r; + ENUMCONTEXT *ctx; + + if( !*enum_context ) { /* init context */ + ctx = m_alloc_clear( sizeof( *ctx ) ); + ctx->r = extensions; + *enum_context = ctx; + } + else if( !algo ) { /* release the context */ + m_free(*enum_context); + *enum_context = NULL; + return 0; + } + else + ctx = *enum_context; + + for( r = ctx->r; r; r = r->next ) { + int class, vers; + + if( r->failed ) + continue; + if( !r->handle && load_extension(r) ) + continue; + /* get a digest info function */ + if( ctx->sym ) + goto inner_loop; + while( (ctx->sym = (*r->enumfunc)(10, &ctx->seq1, &class, &vers)) ) { + void *sym; + /* must check class because enumfunc may be wrong coded */ + if( vers != 1 || class != 10 ) + continue; + inner_loop: + *r_get_info = ctx->sym; + while( (sym = (*r->enumfunc)(11, &ctx->seq2, &class, &vers)) ) { + if( vers != 1 || class != 11 ) + continue; + *algo = *(int*)sym; + ctx->r = r; + return 1; + } + ctx->seq2 = 0; + } + ctx->seq1 = 0; + } + ctx->r = r; + return 0; +} + const char * enum_gnupgext_ciphers( void **enum_context, int *algo, size_t *keylen, size_t *blocksize, size_t *contextsize, diff --git a/cipher/dynload.h b/cipher/dynload.h index 2d829c717..fd87bbeef 100644 --- a/cipher/dynload.h +++ b/cipher/dynload.h @@ -20,6 +20,14 @@ #ifndef G10_CIPHER_DYNLOAD_H #define G10_CIPHER_DYNLOAD_H +int +enum_gnupgext_digests( void **enum_context, + int *algo, + const char *(**r_get_info)( int, size_t*,byte**, int*, int*, + void (**)(void*), + void (**)(void*,byte*,size_t), + void (**)(void*),byte *(**)(void*)) ); + const char * enum_gnupgext_ciphers( void **enum_context, int *algo, size_t *keylen, size_t *blocksize, size_t *contextsize, @@ -28,6 +36,7 @@ enum_gnupgext_ciphers( void **enum_context, int *algo, void (**decrypt)( void *c, byte *outbuf, byte *inbuf ) ); + const char * enum_gnupgext_pubkeys( void **enum_context, int *algo, int *npkey, int *nskey, int *nenc, int *nsig, int *usage, diff --git a/cipher/md.c b/cipher/md.c index b116dd975..3fd7581d7 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -18,6 +18,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#define DEFINES_MD_HANDLE 1 + #include #include #include @@ -26,20 +28,125 @@ #include "util.h" #include "cipher.h" #include "errors.h" +#include "dynload.h" +#include "md5.h" +#include "sha1.h" +#include "rmd.h" + + +/**************** + * This structure is used for the list of available algorithms + * and for the list of algorithms in MD_HANDLE. + */ +struct md_digest_list_s { + struct md_digest_list_s *next; + const char *name; + int algo; + byte *asnoid; + int asnlen; + int mdlen; + void (*init)( void *c ); + void (*write)( void *c, byte *buf, size_t nbytes ); + void (*final)( void *c ); + byte *(*read)( void *c ); + size_t contextsize; /* allocate this amount of context */ + char context[1]; +}; + +static struct md_digest_list_s *digest_list; -/* Note: the first string is the one used by ascii armor */ -static struct { const char *name; int algo;} digest_names[] = { - { "MD5", DIGEST_ALGO_MD5 }, - { "SHA1", DIGEST_ALGO_SHA1 }, - { "SHA-1", DIGEST_ALGO_SHA1 }, - { "RIPEMD160", DIGEST_ALGO_RMD160 }, - { "RMD160", DIGEST_ALGO_RMD160 }, - { "RMD-160", DIGEST_ALGO_RMD160 }, - { "RIPE-MD-160", DIGEST_ALGO_RMD160 }, - {NULL} }; +static struct md_digest_list_s * +new_list_item( int algo, + const char *(*get_info)( int, size_t*,byte**, int*, int*, + void (**)(void*), + void (**)(void*,byte*,size_t), + void (**)(void*),byte *(**)(void*)) ) +{ + struct md_digest_list_s *r; + r = m_alloc_clear( sizeof *r ); + r->algo = algo, + r->name = (*get_info)( algo, &r->contextsize, + &r->asnoid, &r->asnlen, &r->mdlen, + &r->init, &r->write, &r->final, &r->read ); + if( !r->name ) { + m_free(r); + r = NULL; + } + return r; +} + +/**************** + * Put the static entries into the table. + */ +static void +setup_digest_list() +{ + struct md_digest_list_s *r; + + r = new_list_item( DIGEST_ALGO_MD5, md5_get_info ); + if( r ) { r->next = digest_list; digest_list = r; } + + r = new_list_item( DIGEST_ALGO_RMD160, rmd160_get_info ); + if( r ) { r->next = digest_list; digest_list = r; } + + r = new_list_item( DIGEST_ALGO_SHA1, sha1_get_info ); + if( r ) { r->next = digest_list; digest_list = r; } +} + + +/**************** + * Try to load all modules and return true if new modules are available + */ +static int +load_digest_modules() +{ + static int done = 0; + static int initialized = 0; + struct md_digest_list_s *r; + void *context = NULL; + int algo; + int any = 0; + const char *(*get_info)( int, size_t*,byte**, int*, int*, + void (**)(void*), + void (**)(void*,byte*,size_t), + void (**)(void*),byte *(**)(void*)); + + if( !initialized ) { + setup_digest_list(); /* load static modules on the first call */ + initialized = 1; + return 1; + } + + if( done ) + return 0; + done = 1; + + while( enum_gnupgext_digests( &context, &algo, &get_info ) ) { + for(r=digest_list; r; r = r->next ) + if( r->algo == algo ) + break; + if( r ) { + log_info("skipping digest %d: already loaded\n", algo ); + continue; + } + r = new_list_item( algo, get_info ); + if( ! r ) { + log_info("skipping digest %d: no name\n", algo ); + continue; + } + /* put it into the list */ + if( g10_opt_verbose > 1 ) + log_info("loaded digest %d\n", algo); + r->next = digest_list; + digest_list = r; + any = 1; + } + enum_gnupgext_digests( &context, NULL, NULL ); + return any; +} @@ -49,12 +156,13 @@ static struct { const char *name; int algo;} digest_names[] = { int string_to_digest_algo( const char *string ) { - int i; - const char *s; + struct md_digest_list_s *r; - for(i=0; (s=digest_names[i].name); i++ ) - if( !stricmp( s, string ) ) - return digest_names[i].algo; + do { + for(r = digest_list; r; r = r->next ) + if( !stricmp( r->name, string ) ) + return r->algo; + } while( !r && load_digest_modules() ); return 0; } @@ -65,11 +173,13 @@ string_to_digest_algo( const char *string ) const char * digest_algo_to_string( int algo ) { - int i; + struct md_digest_list_s *r; - for(i=0; digest_names[i].name; i++ ) - if( digest_names[i].algo == algo ) - return digest_names[i].name; + do { + for(r = digest_list; r; r = r->next ) + if( r->algo == algo ) + return r->name; + } while( !r && load_digest_modules() ); return NULL; } @@ -77,22 +187,18 @@ digest_algo_to_string( int algo ) int check_digest_algo( int algo ) { - switch( algo ) { - case DIGEST_ALGO_MD5: - case DIGEST_ALGO_RMD160: - case DIGEST_ALGO_SHA1: - return 0; - default: - return G10ERR_DIGEST_ALGO; - } + struct md_digest_list_s *r; + + do { + for(r = digest_list; r; r = r->next ) + if( r->algo == algo ) + return 0; + } while( !r && load_digest_modules() ); + return G10ERR_DIGEST_ALGO; } - - - - /**************** * Open a message digest handle for use with algorithm ALGO. * More algorithms may be added by md_enable(). The initial algorithm @@ -102,7 +208,6 @@ MD_HANDLE md_open( int algo, int secure ) { MD_HANDLE hd; - hd = secure ? m_alloc_secure_clear( sizeof *hd ) : m_alloc_clear( sizeof *hd ); hd->secure = secure; @@ -115,23 +220,29 @@ md_open( int algo, int secure ) void md_enable( MD_HANDLE h, int algo ) { - if( algo == DIGEST_ALGO_MD5 ) { - if( !h->use_md5 ) - md5_init( &h->md5 ); - h->use_md5 = 1; + struct md_digest_list_s *r, *ac; + + for( ac=h->list; ac; ac = ac->next ) + if( ac->algo == algo ) + return ; /* already enabled */ + /* find the algorithm */ + do { + for(r = digest_list; r; r = r->next ) + if( r->algo == algo ) + break; + } while( !r && load_digest_modules() ); + if( !r ) { + log_error("md_enable: algorithm %d not available\n", algo ); + return; } - else if( algo == DIGEST_ALGO_RMD160 ) { - if( !h->use_rmd160 ) - rmd160_init( &h->rmd160 ); - h->use_rmd160 = 1; - } - else if( algo == DIGEST_ALGO_SHA1 ) { - if( !h->use_sha1 ) - sha1_init( &h->sha1 ); - h->use_sha1 = 1; - } - else - log_bug("md_enable(%d)", algo ); + /* and allocate a new list entry */ + ac = h->secure? m_alloc_secure( sizeof *ac + r->contextsize ) + : m_alloc( sizeof *ac + r->contextsize ); + *ac = *r; + ac->next = h->list; + h->list = ac; + /* and init this instance */ + (*ac->init)( &ac->context ); } @@ -139,10 +250,21 @@ MD_HANDLE md_copy( MD_HANDLE a ) { MD_HANDLE b; + struct md_digest_list_s *ar, *br; b = a->secure ? m_alloc_secure( sizeof *b ) : m_alloc( sizeof *b ); memcpy( b, a, sizeof *a ); + b->list = NULL; + /* and now copy the compelte list of algorithms */ + /* I know that the copied list is reversed, but that doesn't matter */ + for( ar=a->list; ar; ar = ar->next ) { + br = a->secure ? m_alloc_secure( sizeof *br + ar->contextsize ) + : m_alloc( sizeof *br + ar->contextsize ); + memcpy( br, ar, sizeof(*br) + ar->contextsize ); + br->next = b->list; + b->list = br; + } return b; } @@ -150,10 +272,16 @@ md_copy( MD_HANDLE a ) void md_close(MD_HANDLE a) { + struct md_digest_list_s *r, *r2; + if( !a ) return; if( a->debug ) md_stop_debug(a); + for(r=a->list; r; r = r2 ) { + r2 = r->next; + m_free(r); + } m_free(a); } @@ -161,23 +289,17 @@ md_close(MD_HANDLE a) void md_write( MD_HANDLE 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 ) BUG(); if( inlen && fwrite(inbuf, inlen, 1, a->debug ) != 1 ) BUG(); } - if( a->use_rmd160 ) { - rmd160_write( &a->rmd160, a->buffer, a->bufcount ); - rmd160_write( &a->rmd160, inbuf, inlen ); - } - if( a->use_sha1 ) { - sha1_write( &a->sha1, a->buffer, a->bufcount ); - sha1_write( &a->sha1, inbuf, inlen ); - } - if( a->use_md5 ) { - md5_write( &a->md5, a->buffer, a->bufcount ); - md5_write( &a->md5, inbuf, inlen ); + for(r=a->list; r; r = r->next ) { + (*r->write)( &r->context, a->buffer, a->bufcount ); + (*r->write)( &r->context, inbuf, inlen ); } a->bufcount = 0; } @@ -187,14 +309,13 @@ md_write( MD_HANDLE a, byte *inbuf, size_t inlen) void md_final(MD_HANDLE a) { + struct md_digest_list_s *r; + if( a->bufcount ) md_write( a, NULL, 0 ); - if( a->use_rmd160 ) - rmd160_final( &a->rmd160 ); - if( a->use_sha1 ) - sha1_final( &a->sha1 ); - if( a->use_md5 ) - md5_final( &a->md5 ); + + for(r=a->list; r; r = r->next ) + (*r->final)( &r->context ); } @@ -204,34 +325,34 @@ md_final(MD_HANDLE a) byte * md_read( MD_HANDLE a, int algo ) { - if( !algo ) { - if( a->use_rmd160 ) - return rmd160_read( &a->rmd160 ); - if( a->use_sha1 ) - return sha1_read( &a->sha1 ); - if( a->use_md5 ) - return md5_read( &a->md5 ); + struct md_digest_list_s *r; + + if( !algo ) { /* return the first algorithm */ + if( (r=a->list) ) { + if( r->next ) + log_error("warning: more than algorithm in md_read(0)\n"); + return (*r->read)( &r->context ); + } } else { - if( algo == DIGEST_ALGO_RMD160 ) - return rmd160_read( &a->rmd160 ); - if( algo == DIGEST_ALGO_SHA1 ) - return sha1_read( &a->sha1 ); - if( algo == DIGEST_ALGO_MD5 ) - return md5_read( &a->md5 ); + for(r=a->list; r; r = r->next ) + if( r->algo == algo ) + return (*r->read)( &r->context ); } BUG(); + return NULL; } int md_get_algo( MD_HANDLE a ) { - if( a->use_rmd160 ) - return DIGEST_ALGO_RMD160; - if( a->use_sha1 ) - return DIGEST_ALGO_SHA1; - if( a->use_md5 ) - return DIGEST_ALGO_MD5; + struct md_digest_list_s *r; + + if( (r=a->list) ) { + if( r->next ) + log_error("warning: more than algorithm in md_get_algo()\n"); + return r->algo; + } return 0; } @@ -241,67 +362,39 @@ md_get_algo( MD_HANDLE a ) int md_digest_length( int algo ) { - switch( algo ) { - case DIGEST_ALGO_RMD160: - case DIGEST_ALGO_SHA1: - return 20; - default: - return 16; - } + struct md_digest_list_s *r; + + do { + for(r = digest_list; r; r = r->next ) { + if( r->algo == algo ) + return r->mdlen; + } + } while( !r && load_digest_modules() ); + log_error("warning: no length for md algo %d\n", algo); + return 0; } -/* fixme: put the oids in a table and add a mode to enumerate the OIDs - * to make g10/sig-check.c more portable */ +/* fixme: add a mode to enumerate the OIDs + * to make g10/sig-check.c more portable */ const byte * md_asn_oid( int algo, size_t *asnlen, size_t *mdlen ) { - size_t alen; - byte *p; + struct md_digest_list_s *r; - if( algo == DIGEST_ALGO_MD5 ) { - static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */ - { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48, - 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; - alen = DIM(asn); p = asn; - } - else if( algo == DIGEST_ALGO_RMD160 ) { - static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, - 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; - alen = DIM(asn); p = asn; - } - else if( algo == DIGEST_ALGO_TIGER ) { - /* 40: SEQUENCE { - * 12: SEQUENCE { - * 8: OCTET STRING :54 49 47 45 52 31 39 32 - * 0: NULL - * : } - * 24: OCTET STRING - * : } - * - * By replacing the 5th byte (0x04) with 0x16 we would have; - * 8: IA5String 'TIGER192' - */ - static byte asn[18] = - { 0x30, 0x28, 0x30, 0x0c, 0x04, 0x08, 0x54, 0x49, 0x47, - 0x45, 0x52, 0x31, 0x39, 0x32, 0x05, 0x00, 0x04, 0x18 }; - alen = DIM(asn); p = asn; - } - else if( algo == DIGEST_ALGO_SHA1 ) { - static byte asn[15] = /* Object ID is 1.3.14.3.2.26 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; - alen = DIM(asn); p = asn; - } - else - log_bug("md_asn_oid(%d)", algo ); - - if( asnlen ) - *asnlen = alen; - if( mdlen ) - *mdlen = p[alen-1]; - return p; + do { + for(r = digest_list; r; r = r->next ) { + if( r->algo == algo ) { + if( asnlen ) + *asnlen = r->asnlen; + if( mdlen ) + *mdlen = r->mdlen; + return r->asnoid; + } + } + } while( !r && load_digest_modules() ); + log_bug("warning: no asn for md algo %d\n", algo); + return NULL; } diff --git a/cipher/md.h b/cipher/md.h deleted file mode 100644 index b4d690793..000000000 --- a/cipher/md.h +++ /dev/null @@ -1,74 +0,0 @@ -/* md.h - digest functions - * 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 G10_MD_H -#define G10_MD_H - -#include -#include "types.h" -#include "rmd.h" -#include "sha1.h" -#include "md5.h" - -#define MD_BUFFER_SIZE 512 - -typedef struct { - int use_rmd160; - RMD160_CONTEXT rmd160; - int use_sha1; - SHA1_CONTEXT sha1; - #ifdef WITH_TIGER_HASH - int use_tiger; - TIGER_CONTEXT tiger; - #endif - int use_md5; - MD5_CONTEXT md5; - byte buffer[MD_BUFFER_SIZE]; /* primary buffer */ - int bufcount; - int secure; - FILE *debug; -} *MD_HANDLE; - - -#define md_putc(h,c) \ - do { \ - if( (h)->bufcount == MD_BUFFER_SIZE ) \ - md_write( (h), NULL, 0 ); \ - (h)->buffer[(h)->bufcount++] = (c) & 0xff; \ - } while(0) - -/*-- md.c --*/ -int string_to_digest_algo( const char *string ); -const char * digest_algo_to_string( int algo ); -int check_digest_algo( int algo ); -MD_HANDLE md_open( int algo, int secure ); -void md_enable( MD_HANDLE hd, int algo ); -MD_HANDLE md_copy( MD_HANDLE a ); -void md_close(MD_HANDLE a); -void md_write( MD_HANDLE a, byte *inbuf, size_t inlen); -void md_final(MD_HANDLE a); -byte *md_read( MD_HANDLE a, int algo ); -int md_get_algo( MD_HANDLE a ); -int md_digest_length( int algo ); -const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen ); -void md_start_debug( MD_HANDLE a, const char *suffix ); -void md_stop_debug( MD_HANDLE a ); -#define md_is_secure(a) ((a)->secure) - -#endif /*G10_MD_H*/ diff --git a/cipher/md5.c b/cipher/md5.c index 7cc22b3bb..72fce0e22 100644 --- a/cipher/md5.c +++ b/cipher/md5.c @@ -38,6 +38,15 @@ #include "memory.h" +typedef struct { + u32 A,B,C,D; /* chaining variables */ + u32 total[2]; + u32 buflen; + char buffer[128]; +} MD5_CONTEXT; + + + #ifdef BIG_ENDIAN_HOST #define SWAP(n) \ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) @@ -49,7 +58,7 @@ 64-byte boundary. (RFC 1321, 3.1: Step 1) */ static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; -void +static void md5_init( MD5_CONTEXT *ctx ) { ctx->A = 0x67452301; @@ -237,7 +246,7 @@ transform( MD5_CONTEXT *ctx, const void *buffer, size_t len ) * account for the presence of each of the characters inBuf[0..inLen-1] * in the message whose digest is being computed. */ -void +static void md5_write( MD5_CONTEXT *ctx, const void *buffer, size_t len) { /* When we already have some bits in our internal buffer concatenate @@ -287,7 +296,7 @@ md5_write( MD5_CONTEXT *ctx, const void *buffer, size_t len) * Returns 16 bytes representing the digest. */ -void +static void md5_final( MD5_CONTEXT *ctx ) { /* Take yet unprocessed bytes into account. */ @@ -317,6 +326,46 @@ md5_final( MD5_CONTEXT *ctx ) ((u32 *)ctx->buffer)[3] = SWAP (ctx->D); } +static byte * +md5_read( MD5_CONTEXT *hd ) +{ + return hd->buffer; +} + +/**************** + * Return some information about the algorithm. We need algo here to + * distinguish different flavors of the algorithm. + * Returns: A pointer to string describing the algorithm or NULL if + * the ALGO is invalid. + */ +const char * +md5_get_info( int algo, size_t *contextsize, + byte **r_asnoid, int *r_asnlen, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ) +{ + static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */ + { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48, + 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; + + if( algo != 1 ) + return NULL; + + *contextsize = sizeof(MD5_CONTEXT); + *r_asnoid = asn; + *r_asnlen = DIM(asn); + *r_mdlen = 16; + *r_init = (void (*)(void *))md5_init; + *r_write = (void (*)(void *, byte*, size_t))md5_write; + *r_final = (void (*)(void *))md5_final; + *r_read = (byte *(*)(void *))md5_read; + + return "MD5"; +} + /* end of file */ diff --git a/cipher/md5.h b/cipher/md5.h index 817a526a4..a4bcf5c63 100644 --- a/cipher/md5.h +++ b/cipher/md5.h @@ -20,19 +20,15 @@ #ifndef G10_MD5_H #define G10_MD5_H -#include "types.h" -typedef struct { - u32 A,B,C,D; /* chaining variables */ - u32 total[2]; - u32 buflen; - char buffer[128]; -} MD5_CONTEXT; +const char * +md5_get_info( int algo, size_t *contextsize, + byte **r_asnoid, int *r_asn_len, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ); -void md5_init( MD5_CONTEXT *ctx ); -void md5_write( MD5_CONTEXT *ctx, const void *buffer, size_t len); -void md5_final( MD5_CONTEXT *ctx); -#define md5_read(h) ( (h)->buffer ) - #endif /*G10_MD5_H*/ diff --git a/cipher/pubkey.c b/cipher/pubkey.c index b18f1c316..f59996c4d 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -33,7 +33,7 @@ #include "dynload.h" -#define TABLE_SIZE 20 +#define TABLE_SIZE 10 struct pubkey_table_s { const char *name; @@ -93,13 +93,8 @@ dummy_get_nbits( int algo, MPI *pkey ) static void setup_pubkey_table() { - - static int initialized = 0; int i; - if( initialized ) - return; - i = 0; pubkey_table[i].algo = PUBKEY_ALGO_ELGAMAL; pubkey_table[i].name = elg_get_info( pubkey_table[i].algo, @@ -155,7 +150,6 @@ setup_pubkey_table() for( ; i < TABLE_SIZE; i++ ) pubkey_table[i].name = NULL; - initialized = 1; } @@ -165,6 +159,7 @@ setup_pubkey_table() static int load_pubkey_modules() { + static int initialized = 0; static int done = 0; void *context = NULL; struct pubkey_table_s *ct; @@ -173,6 +168,12 @@ load_pubkey_modules() const char *name; int any = 0; + + if( !initialized ) { + setup_pubkey_table(); + initialized = 1; + return 1; + } if( done ) return 0; done = 1; @@ -237,7 +238,6 @@ string_to_pubkey_algo( const char *string ) int i; const char *s; - setup_pubkey_table(); do { for(i=0; (s=pubkey_table[i].name); i++ ) if( !stricmp( s, string ) ) @@ -255,7 +255,6 @@ pubkey_algo_to_string( int algo ) { int i; - setup_pubkey_table(); do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) @@ -280,7 +279,6 @@ check_pubkey_algo2( int algo, unsigned usage ) { int i; - setup_pubkey_table(); do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) { @@ -304,7 +302,6 @@ int pubkey_get_npkey( int algo ) { int i; - setup_pubkey_table(); do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) @@ -320,7 +317,6 @@ int pubkey_get_nskey( int algo ) { int i; - setup_pubkey_table(); do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) @@ -336,7 +332,6 @@ int pubkey_get_nsig( int algo ) { int i; - setup_pubkey_table(); do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) @@ -352,7 +347,6 @@ int pubkey_get_nenc( int algo ) { int i; - setup_pubkey_table(); do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) @@ -369,7 +363,6 @@ pubkey_nbits( int algo, MPI *pkey ) { int i; - setup_pubkey_table(); do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) @@ -384,7 +377,6 @@ pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) { int i; - setup_pubkey_table(); do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) @@ -400,7 +392,6 @@ pubkey_check_secret_key( int algo, MPI *skey ) { int i; - setup_pubkey_table(); do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) @@ -423,7 +414,6 @@ pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey ) /* FIXME: check that data fits into the key (in xxx_encrypt)*/ - setup_pubkey_table(); if( DBG_CIPHER ) { log_debug("pubkey_encrypt: algo=%d\n", algo ); for(i=0; i < pubkey_get_npkey(algo); i++ ) @@ -461,7 +451,6 @@ pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey ) { int i, rc; - setup_pubkey_table(); *result = NULL; /* so the caller can always do an mpi_free */ if( DBG_CIPHER ) { log_debug("pubkey_decrypt: algo=%d\n", algo ); @@ -498,7 +487,6 @@ pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey ) { int i, rc; - setup_pubkey_table(); if( DBG_CIPHER ) { log_debug("pubkey_sign: algo=%d\n", algo ); for(i=0; i < pubkey_get_nskey(algo); i++ ) @@ -532,7 +520,6 @@ pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey, { int i, rc; - setup_pubkey_table(); do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) { diff --git a/cipher/rmd.h b/cipher/rmd.h index f3a67243b..64a8a02b5 100644 --- a/cipher/rmd.h +++ b/cipher/rmd.h @@ -20,8 +20,8 @@ #ifndef G10_RMD_H #define G10_RMD_H -#include "types.h" +/* we need this here because random.c must have direct access */ typedef struct { u32 h0,h1,h2,h3,h4; u32 nblocks; @@ -29,11 +29,19 @@ typedef struct { int count; } RMD160_CONTEXT; - -void rmd160_init( RMD160_CONTEXT *c ); -void rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen); -void rmd160_final(RMD160_CONTEXT *hd); +void rmd160_init( RMD160_CONTEXT *hd ); void rmd160_mixblock( RMD160_CONTEXT *hd, char *buffer ); -#define rmd160_read(h) ( (h)->buf ) + + + +const char * +rmd160_get_info( int algo, size_t *contextsize, + byte **r_asnoid, int *r_asn_len, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ); + #endif /*G10_RMD_H*/ diff --git a/cipher/rmd160.c b/cipher/rmd160.c index ad28299fc..e38172498 100644 --- a/cipher/rmd160.c +++ b/cipher/rmd160.c @@ -27,6 +27,7 @@ #include "memory.h" #include "rmd.h" + /********************************* * RIPEMD-160 is not patented, see (as of 25.10.97) * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html @@ -411,7 +412,7 @@ transform( RMD160_CONTEXT *hd, byte *data ) /* Update the message digest with the contents * of INBUF with length INLEN. */ -void +static void rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen) { if( hd->count == 64 ) { /* flush the buffer */ @@ -443,7 +444,7 @@ rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen) /**************** * Apply the rmd160 transform function on the buffer which must have * a length 64 bytes. Do not use this function together with the - * other functions, use rmd160_init to initialize intzernal variables. + * other functions, use rmd160_init to initialize internal variables. * Returns: 16 bytes in buffer with the mixed contentes of buffer. */ void @@ -464,7 +465,7 @@ rmd160_mixblock( RMD160_CONTEXT *hd, char *buffer ) /* The routine terminates the computation */ -void +static void rmd160_final( RMD160_CONTEXT *hd ) { u32 t, msb, lsb; @@ -523,4 +524,43 @@ rmd160_final( RMD160_CONTEXT *hd ) #undef X } +static byte * +rmd160_read( RMD160_CONTEXT *hd ) +{ + return hd->buf; +} + +/**************** + * Return some information about the algorithm. We need algo here to + * distinguish different flavors of the algorithm. + * Returns: A pointer to string describing the algorithm or NULL if + * the ALGO is invalid. + */ +const char * +rmd160_get_info( int algo, size_t *contextsize, + byte **r_asnoid, int *r_asnlen, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ) +{ + static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */ + { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, + 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; + + if( algo != 3 ) + return NULL; + + *contextsize = sizeof(RMD160_CONTEXT); + *r_asnoid = asn; + *r_asnlen = DIM(asn); + *r_mdlen = 20; + *r_init = (void (*)(void *))rmd160_init; + *r_write = (void (*)(void *, byte*, size_t))rmd160_write; + *r_final = (void (*)(void *))rmd160_final; + *r_read = (byte *(*)(void *))rmd160_read; + + return "RIPEMD160"; +} diff --git a/cipher/sha1.c b/cipher/sha1.c index 941e69b8d..0a6ffab2c 100644 --- a/cipher/sha1.c +++ b/cipher/sha1.c @@ -41,6 +41,12 @@ #include "sha1.h" +typedef struct { + u32 h0,h1,h2,h3,h4; + u32 nblocks; + byte buf[64]; + int count; +} SHA1_CONTEXT; #if defined(__GNUC__) && defined(__i386__) @@ -216,7 +222,7 @@ transform( SHA1_CONTEXT *hd, byte *data ) /* Update the message digest with the contents * of INBUF with length INLEN. */ -void +static void sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen) { if( hd->count == 64 ) { /* flush the buffer */ @@ -253,7 +259,7 @@ sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen) * Returns: 20 bytes representing the digest. */ -void +static void sha1_final(SHA1_CONTEXT *hd) { u32 t, msb, lsb; @@ -313,4 +319,42 @@ sha1_final(SHA1_CONTEXT *hd) } +static byte * +sha1_read( SHA1_CONTEXT *hd ) +{ + return hd->buf; +} + +/**************** + * Return some information about the algorithm. We need algo here to + * distinguish different flavors of the algorithm. + * Returns: A pointer to string describing the algorithm or NULL if + * the ALGO is invalid. + */ +const char * +sha1_get_info( int algo, size_t *contextsize, + byte **r_asnoid, int *r_asnlen, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ) +{ + static byte asn[15] = /* Object ID is 1.3.14.3.2.26 */ + { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, + 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; + if( algo != 2 ) + return NULL; + + *contextsize = sizeof(SHA1_CONTEXT); + *r_asnoid = asn; + *r_asnlen = DIM(asn); + *r_mdlen = 20; + *r_init = (void (*)(void *))sha1_init; + *r_write = (void (*)(void *, byte*, size_t))sha1_write; + *r_final = (void (*)(void *))sha1_final; + *r_read = (byte *(*)(void *))sha1_read; + + return "SHA1"; +} diff --git a/cipher/sha1.h b/cipher/sha1.h index 1a183ffb8..2a47b3e91 100644 --- a/cipher/sha1.h +++ b/cipher/sha1.h @@ -20,19 +20,14 @@ #ifndef G10_SHA1_H #define G10_SHA1_H -#include "types.h" -typedef struct { - u32 h0,h1,h2,h3,h4; - u32 nblocks; - byte buf[64]; - int count; -} SHA1_CONTEXT; - - -void sha1_init( SHA1_CONTEXT *c ); -void sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen); -void sha1_final( SHA1_CONTEXT *hd); -#define sha1_read(h) ( (h)->buf ) +const char * +sha1_get_info( int algo, size_t *contextsize, + byte **r_asnoid, int *r_asn_len, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ); #endif /*G10_SHA1_H*/ diff --git a/cipher/tiger.c b/cipher/tiger.c index 11c11b461..2560e8ab7 100644 --- a/cipher/tiger.c +++ b/cipher/tiger.c @@ -625,7 +625,7 @@ print_data( const char *text, u64 a, u64 b, u64 c, } -void +static void tiger_init( TIGER_CONTEXT *hd ) { hd->a = 0x0123456789abcdefLL; @@ -758,7 +758,7 @@ transform( TIGER_CONTEXT *hd, byte *data ) /* Update the message digest with the contents * of INBUF with length INLEN. */ -void +static void tiger_write( TIGER_CONTEXT *hd, byte *inbuf, size_t inlen) { if( hd->count == 64 ) { /* flush the buffer */ @@ -792,7 +792,7 @@ tiger_write( TIGER_CONTEXT *hd, byte *inbuf, size_t inlen) /* The routine terminates the computation */ -void +static void tiger_final( TIGER_CONTEXT *hd ) { u32 t, msb, lsb; @@ -851,3 +851,118 @@ tiger_final( TIGER_CONTEXT *hd ) #undef X } +static byte * +tiger_read( TIGER_CONTEXT *hd ) +{ + return hd->buf; +} + +/**************** + * Return some information about the algorithm. We need algo here to + * distinguish different flavors of the algorithm. + * Returns: A pointer to string describing the algorithm or NULL if + * the ALGO is invalid. + */ +static const char * +tiger_get_info( int algo, size_t *contextsize, + byte **r_asnoid, int *r_asnlen, int *r_mdlen, + void (**r_init)( void *c ), + void (**r_write)( void *c, byte *buf, size_t nbytes ), + void (**r_final)( void *c ), + byte *(**r_read)( void *c ) + ) +{ + /* 40: SEQUENCE { + * 12: SEQUENCE { + * 8: OCTET STRING :54 49 47 45 52 31 39 32 + * 0: NULL + * : } + * 24: OCTET STRING + * : } + * + * By replacing the 5th byte (0x04) with 0x16 we would have; + * 8: IA5String 'TIGER192' + */ + static byte asn[18] = + { 0x30, 0x28, 0x30, 0x0c, 0x04, 0x08, 0x54, 0x49, 0x47, + 0x45, 0x52, 0x31, 0x39, 0x32, 0x05, 0x00, 0x04, 0x18 }; + + if( algo != 6 ) + return NULL; + + *contextsize = sizeof(TIGER_CONTEXT); + *r_asnoid = asn; + *r_asnlen = DIM(asn); + *r_mdlen = 24; + *r_init = (void (*)(void *))tiger_init; + *r_write = (void (*)(void *, byte*, size_t))tiger_write; + *r_final = (void (*)(void *))tiger_final; + *r_read = (byte *(*)(void *))tiger_read; + + return "TIGER"; +} + + + +const char * const gnupgext_version = "TIGER ($Revision$)"; + +static struct { + int class; + int version; + int value; + void (*func)(void); +} func_table[] = { + { 10, 1, 0, (void(*)(void))tiger_get_info }, + { 11, 1, 6 }, +}; + + + +/**************** + * Enumerate the names of the functions together with informations about + * this function. Set sequence to an integer with a initial value of 0 and + * do not change it. + * If what is 0 all kind of functions are returned. + * Return values: class := class of function: + * 10 = message digest algorithm info function + * 11 = integer with available md algorithms + * 20 = cipher algorithm info function + * 21 = integer with available cipher algorithms + * 30 = public key algorithm info function + * 31 = integer with available pubkey algorithms + * version = interface version of the function/pointer + * (currently this is 1 for all functions) + */ +void * +gnupgext_enum_func( int what, int *sequence, int *class, int *vers ) +{ + void *ret; + int i = *sequence; + + /*log_info("gnupgext_enum_func in rsa+idea called what=%d i=%d: ", what, i);*/ + do { + if( i >= DIM(func_table) || i < 0 ) { + /*fprintf(stderr, "failed\n");*/ + return NULL; + } + *class = func_table[i].class; + *vers = func_table[i].version; + switch( *class ) { + case 11: + case 21: + case 31: + ret = &func_table[i].value; + break; + default: + ret = func_table[i].func; + break; + } + i++; + } while( what && what != *class ); + + *sequence = i; + /*fprintf(stderr, "success\n");*/ + return ret; +} + + diff --git a/g10/misc.c b/g10/misc.c index d1bacf694..0c2b6ac4a 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -30,7 +30,12 @@ #include "main.h" #include "options.h" -volatile int + +const char *g10m_revision_string(int); +const char *g10c_revision_string(int); +const char *g10u_revision_string(int); + +volatile void pull_in_libs(void) { g10m_revision_string(0); @@ -140,6 +145,7 @@ checksum_mpi_counted_nbits( MPI a ) buffer = mpi_get_buffer( a, &nbytes, NULL ); nbits = mpi_get_nbits(a); + mpi_set_nbit_info(a,nbits); csum = checksum_u16_nobug( nbits ); csum += checksum( buffer, nbytes ); m_free( buffer ); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 9e469b644..ba26089c5 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1004,6 +1004,8 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, * we can assume, that he operates an open system :=(. * So we put the key into secure memory when we unprotect it. */ n = pktlen; cert->skey[3] = mpi_read(inp, &n, 0 ); pktlen -=n; + if( cert->is_protected ) + mpi_set_protect_flag(cert->skey[3]); cert->csum = read_16(inp); pktlen -= 2; if( list_mode ) { @@ -1129,6 +1131,8 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, * we can assume, that he operates an open system :=(. * So we put the key into secure memory when we unprotect it. */ n = pktlen; cert->skey[4] = mpi_read(inp, &n, 0 ); pktlen -=n; + if( cert->is_protected ) + mpi_set_protect_flag(cert->skey[4]); cert->csum = read_16(inp); pktlen -= 2; if( list_mode ) { @@ -1184,6 +1188,12 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, n = pktlen; cert->skey[3] = mpi_read(inp, &n, 0 ); pktlen -=n; n = pktlen; cert->skey[4] = mpi_read(inp, &n, 0 ); pktlen -=n; n = pktlen; cert->skey[5] = mpi_read(inp, &n, 0 ); pktlen -=n; + if( cert->is_protected ) { + mpi_set_protect_flag(cert->skey[2]); + mpi_set_protect_flag(cert->skey[3]); + mpi_set_protect_flag(cert->skey[4]); + mpi_set_protect_flag(cert->skey[5]); + } cert->csum = read_16(inp); pktlen -= 2; if( list_mode ) { diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index f30e5d0e9..508187fb8 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -69,14 +69,14 @@ do_check( PKT_secret_cert *cert ) i < pubkey_get_nskey(cert->pubkey_algo); i++ ) { buffer = mpi_get_secure_buffer( cert->skey[i], &nbytes, NULL ); cipher_sync( cipher_hd ); + assert( mpi_is_protected(cert->skey[i]) ); cipher_decrypt( cipher_hd, buffer, buffer, nbytes ); mpi_set_buffer( cert->skey[i], buffer, nbytes, 0 ); + mpi_clear_protect_flag( cert->skey[i] ); csum += checksum_mpi( cert->skey[i] ); m_free( buffer ); } if( opt.emulate_bugs & 1 ) { - log_debug("secret key csum is=%04hx should=%04hx algos=%d/%d\n", - csum, cert->csum, cert->pubkey_algo,cert->protect.algo ); csum = cert->csum; } cipher_close( cipher_hd ); @@ -193,10 +193,11 @@ protect_secret_key( PKT_secret_cert *cert, DEK *dek ) i < pubkey_get_nskey(cert->pubkey_algo); i++ ) { csum += checksum_mpi_counted_nbits( cert->skey[i] ); buffer = mpi_get_buffer( cert->skey[i], &nbytes, NULL ); - log_debug("protecing i=%d csum=%04hx nbytes=%u\n", i, csum, nbytes ); cipher_sync( cipher_hd ); + assert( !mpi_is_protected(cert->skey[i]) ); cipher_encrypt( cipher_hd, buffer, buffer, nbytes ); mpi_set_buffer( cert->skey[i], buffer, nbytes, 0 ); + mpi_set_protect_flag( cert->skey[i] ); m_free( buffer ); } cert->csum = csum; diff --git a/include/cipher.h b/include/cipher.h index 6481ceeda..8544ee2e0 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -1,19 +1,14 @@ /* cipher.h - * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1998 Free Software Foundation, Inc. * - * ATTENTION: This code should not be exported from the United States - * nor should it be used their without a license agreement with PKP. - * The RSA alorithm is protected by U.S. Patent #4,405,829 which - * expires on September 20, 2000! + * This file is part of GNUPG. * - * This file is part of G10. - * - * G10 is free software; you can redistribute it and/or modify + * 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. * - * G10 is distributed in the hope that it will be useful, + * 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. @@ -28,7 +23,6 @@ #define DBG_CIPHER g10c_debug_mode #include "mpi.h" -#include "../cipher/md.h" #include "../cipher/random.h" @@ -77,12 +71,54 @@ struct cipher_handle_s { char does_not_matter[1]; }; #define CIPHER_MODE_DUMMY 5 /* used with algo DUMMY for no encryption */ +#define MD_BUFFER_SIZE 512 + +typedef struct { + byte buffer[MD_BUFFER_SIZE]; + int bufcount; + int secure; + FILE *debug; + struct md_digest_list_s *list; +} *MD_HANDLE; + + +#ifndef DEFINES_MD_HANDLE /* not really the handle but the algorithm list */ +struct md_digest_list_s { char does_not_matter[1]; }; +#endif + + + int g10c_debug_mode; int g10_opt_verbose; /*-- dynload.c --*/ void register_cipher_extension( const char *fname ); +/*-- md.c --*/ +int string_to_digest_algo( const char *string ); +const char * digest_algo_to_string( int algo ); +int check_digest_algo( int algo ); +MD_HANDLE md_open( int algo, int secure ); +void md_enable( MD_HANDLE hd, int algo ); +MD_HANDLE md_copy( MD_HANDLE a ); +void md_close(MD_HANDLE a); +void md_write( MD_HANDLE a, byte *inbuf, size_t inlen); +void md_final(MD_HANDLE a); +byte *md_read( MD_HANDLE a, int algo ); +int md_get_algo( MD_HANDLE a ); +int md_digest_length( int algo ); +const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen ); +void md_start_debug( MD_HANDLE a, const char *suffix ); +void md_stop_debug( MD_HANDLE a ); +#define md_is_secure(a) ((a)->secure) +#define md_putc(h,c) \ + do { \ + if( (h)->bufcount == MD_BUFFER_SIZE ) \ + md_write( (h), NULL, 0 ); \ + (h)->buffer[(h)->bufcount++] = (c) & 0xff; \ + } while(0) + + /*-- cipher.c --*/ int string_to_cipher_algo( const char *string ); const char * cipher_algo_to_string( int algo ); diff --git a/include/errors.h b/include/errors.h index dc7486598..f2ec2073b 100644 --- a/include/errors.h +++ b/include/errors.h @@ -1,14 +1,14 @@ /* errors.h - erro code - * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1998 Free Software Foundation, Inc. * - * This file is part of G10. + * This file is part of GNUPG. * - * G10 is free software; you can redistribute it and/or modify + * 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. * - * G10 is distributed in the hope that it will be useful, + * 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. diff --git a/include/g10lib.h b/include/g10lib.h index 338737831..fe144add5 100644 --- a/include/g10lib.h +++ b/include/g10lib.h @@ -1,7 +1,21 @@ /* g10lib.h - GNU digital encryption libray interface * Copyright (C) 1998 Free Software Foundation, Inc. * - * FIXME: This should allow XFree programs etc to use the header. + * 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_G10LIB_H diff --git a/include/i18n.h b/include/i18n.h index 4a0f1ac78..105a64328 100644 --- a/include/i18n.h +++ b/include/i18n.h @@ -1,14 +1,14 @@ /* i18n.h - * Copyright (c) 1998 by Werner Koch (dd9jn) + * Copyright (C) 1998 Free Software Foundation, Inc. * - * This file is part of G10. + * This file is part of GNUPG. * - * G10 is free software; you can redistribute it and/or modify + * 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. * - * G10 is distributed in the hope that it will be useful, + * 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. diff --git a/include/iobuf.h b/include/iobuf.h index 61c765395..7fd4f7bd1 100644 --- a/include/iobuf.h +++ b/include/iobuf.h @@ -1,14 +1,14 @@ /* iobuf.h - I/O buffer - * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1998 Free Software Foundation, Inc. * - * This file is part of G10. + * This file is part of GNUPG. * - * G10 is free software; you can redistribute it and/or modify + * 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. * - * G10 is distributed in the hope that it will be useful, + * 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. diff --git a/include/memory.h b/include/memory.h index d9dd295a9..08bccd5ec 100644 --- a/include/memory.h +++ b/include/memory.h @@ -1,14 +1,14 @@ /* memory.h - memory allocation - * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1998 Free Software Foundation, Inc. * - * This file is part of G10. + * This file is part of GNUPG. * - * G10 is free software; you can redistribute it and/or modify + * 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. * - * G10 is distributed in the hope that it will be useful, + * 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. diff --git a/include/mpi.h b/include/mpi.h index 9d93d8505..6e0e42eaa 100644 --- a/include/mpi.h +++ b/include/mpi.h @@ -48,7 +48,8 @@ typedef struct mpi_struct { int nlimbs; /* number of valid limbs */ int nbits; /* the real number of valid bits (info only) */ int sign; /* indicates a negative number */ - int secure; /* array must be allocated in secure memory space */ + unsigned flags; /* bit 0: array must be allocated in secure memory space */ + /* bit 1: the mpi is encrypted */ mpi_limb_t *d; /* array with the limbs */ } *MPI; @@ -56,6 +57,7 @@ typedef struct mpi_struct { #define mpi_get_nlimbs(a) ((a)->nlimbs) #define mpi_get_nbit_info(a) ((a)->nbits) +#define mpi_set_nbit_info(a,b) ((a)->nbits = (b)) #define mpi_is_neg(a) ((a)->sign) /*-- mpiutil.c --*/ @@ -78,7 +80,10 @@ typedef struct mpi_struct { void mpi_resize( MPI a, unsigned nlimbs ); MPI mpi_copy( MPI a ); #endif -#define mpi_is_secure(a) ((a) && (a)->secure) +#define mpi_is_protected(a) ((a) && ((a)->flags&2)) +#define mpi_set_protect_flag(a) ((a)->flags |= 2) +#define mpi_clear_protect_flag(a) ((a)->flags &= ~2) +#define mpi_is_secure(a) ((a) && ((a)->flags&1)) void mpi_set_secure( MPI a ); void mpi_clear( MPI a ); void mpi_set( MPI w, MPI u); diff --git a/include/ttyio.h b/include/ttyio.h index 6d599870f..2949cfd19 100644 --- a/include/ttyio.h +++ b/include/ttyio.h @@ -1,14 +1,14 @@ /* ttyio.h - * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1998 Free Software Foundation, Inc. * - * This file is part of G10. + * This file is part of GNUPG. * - * G10 is free software; you can redistribute it and/or modify + * 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. * - * G10 is distributed in the hope that it will be useful, + * 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. diff --git a/include/types.h b/include/types.h index 543cbad62..328a1a93c 100644 --- a/include/types.h +++ b/include/types.h @@ -1,14 +1,14 @@ /* types.h - some common typedefs - * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1998 Free Software Foundation, Inc. * - * This file is part of G10. + * This file is part of GNUPG. * - * G10 is free software; you can redistribute it and/or modify + * 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. * - * G10 is distributed in the hope that it will be useful, + * 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. diff --git a/include/util.h b/include/util.h index 3dec01cdd..24fea1260 100644 --- a/include/util.h +++ b/include/util.h @@ -1,14 +1,14 @@ /* util.h - * Copyright (c) 1997 by Werner Koch (dd9jn) + * Copyright (C) 1998 Free Software Foundation, Inc. * - * This file is part of G10. + * This file is part of GNUPG. * - * G10 is free software; you can redistribute it and/or modify + * 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. * - * G10 is distributed in the hope that it will be useful, + * 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. @@ -60,29 +60,39 @@ void log_set_name( const char *name ); const char *log_get_name(void); void log_set_pid( int pid ); int log_get_errorcount( int clear ); -void log_hexdump( const char *text, char *buf, size_t len ); -void log_mpidump( const char *text, MPI a ); +void g10_log_hexdump( const char *text, char *buf, size_t len ); +void g10_log_mpidump( const char *text, MPI a ); #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) - void log_bug( const char *fmt, ... ) + void g10_log_bug( const char *fmt, ... ) __attribute__ ((noreturn, format (printf,1,2))); - void log_bug0( const char *, int, const char * ) __attribute__ ((noreturn)); - void log_fatal( const char *fmt, ... ) + void g10_log_bug0( const char *, int, const char * ) __attribute__ ((noreturn)); + void g10_log_fatal( const char *fmt, ... ) __attribute__ ((noreturn, format (printf,1,2))); - void log_error( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); - void log_info( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); - void log_debug( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); - #define BUG() log_bug0( __FILE__ , __LINE__, __FUNCTION__ ) + void g10_log_error( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); + void g10_log_info( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); + void g10_log_debug( const char *fmt, ... ) __attribute__ ((format (printf,1,2))); + #define BUG() g10_log_bug0( __FILE__ , __LINE__, __FUNCTION__ ) #else - void log_bug( const char *fmt, ... ); - void log_bug0( const char *, int ); - void log_fatal( const char *fmt, ... ); - void log_error( const char *fmt, ... ); - void log_info( const char *fmt, ... ); - void log_debug( const char *fmt, ... ); - #define BUG() log_bug0( __FILE__ , __LINE__ ) + 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, ... ); + #define BUG() g10_log_bug0( __FILE__ , __LINE__ ) #endif +#define log_hexdump g10_log_hexdump +#define log_mpidump g10_log_mpidump +#define log_bug g10_log_bug +#define log_bug0 g10_log_bug0 +#define log_fatal g10_log_fatal +#define log_error g10_log_error +#define log_info g10_log_info +#define log_debug g10_log_debug + + /*-- errors.c --*/ const char * g10_errstr( int no ); diff --git a/mpi/mpi-bit.c b/mpi/mpi-bit.c index d74abbf6d..2e420875b 100644 --- a/mpi/mpi-bit.c +++ b/mpi/mpi-bit.c @@ -60,6 +60,13 @@ mpi_get_nbits( MPI a ) { unsigned n; + if( mpi_is_protected(a) ) { + n = mpi_get_nbit_info(a); + if( !n ) + n = a->nlimbs * BITS_PER_MPI_LIMB; + return n; + } + if( a->nlimbs ) { mpi_limb_t alimb = a->d[a->nlimbs-1]; if( alimb ) diff --git a/mpi/mpi-div.c b/mpi/mpi-div.c index f057232a2..62ac87158 100644 --- a/mpi/mpi-div.c +++ b/mpi/mpi-div.c @@ -198,7 +198,7 @@ mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den) /* Make sure QP and NP point to different objects. Otherwise the * numerator would be gradually overwritten by the quotient limbs. */ if(qp == np) { /* Copy NP object to temporary space. */ - np = marker[markidx++] = mpi_alloc_limb_space(nsize,quot->secure); + np = marker[markidx++] = mpi_alloc_limb_space(nsize,mpi_is_secure(quot)); MPN_COPY(np, qp, nsize); } } @@ -218,7 +218,7 @@ mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den) /* Shift up the denominator setting the most significant bit of * the most significant word. Use temporary storage not to clobber * the original contents of the denominator. */ - tp = marker[markidx++] = mpi_alloc_limb_space(dsize,den->secure); + tp = marker[markidx++] = mpi_alloc_limb_space(dsize,mpi_is_secure(den)); mpihelp_lshift( tp, dp, dsize, normalization_steps ); dp = tp; @@ -239,7 +239,7 @@ mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den) if( dp == rp || (quot && (dp == qp))) { mpi_ptr_t tp; - tp = marker[markidx++] = mpi_alloc_limb_space(dsize, den->secure); + tp = marker[markidx++] = mpi_alloc_limb_space(dsize, mpi_is_secure(den)); MPN_COPY( tp, dp, dsize ); dp = tp; } diff --git a/mpi/mpi-mul.c b/mpi/mpi-mul.c index bfca5d0d5..74967fa6b 100644 --- a/mpi/mpi-mul.c +++ b/mpi/mpi-mul.c @@ -123,21 +123,21 @@ mpi_mul( MPI w, MPI u, MPI v) if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */ usize = v->nlimbs; usign = v->sign; - usecure = v->secure; + usecure = mpi_is_secure(v); up = v->d; vsize = u->nlimbs; vsign = u->sign; - vsecure = u->secure; + vsecure = mpi_is_secure(u); vp = u->d; } else { usize = u->nlimbs; usign = u->sign; - usecure = u->secure; + usecure = mpi_is_secure(u); up = u->d; vsize = v->nlimbs; vsign = v->sign; - vsecure = v->secure; + vsecure = mpi_is_secure(v); vp = v->d; } sign_product = usign ^ vsign; @@ -147,7 +147,7 @@ mpi_mul( MPI w, MPI u, MPI v) wsize = usize + vsize; if( w->alloced < wsize ) { if( wp == up || wp == vp ) { - wp = mpi_alloc_limb_space( wsize, w->secure ); + wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) ); assign_wp = 1; } else { diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c index 2a0a4ef3b..24430489e 100644 --- a/mpi/mpi-pow.c +++ b/mpi/mpi-pow.c @@ -60,10 +60,10 @@ mpi_powm( MPI res, MPI base, MPI exp, MPI mod) esign = exp->sign; msign = mod->sign; - esec = exp->secure; - msec = mod->secure; - bsec = base->secure; - rsec = res->secure; + esec = mpi_is_secure(exp); + msec = mpi_is_secure(mod); + bsec = mpi_is_secure(base); + rsec = mpi_is_secure(res); rp = res->d; ep = exp->d; diff --git a/mpi/mpicoder.c b/mpi/mpicoder.c index a868923fe..eba82a287 100644 --- a/mpi/mpicoder.c +++ b/mpi/mpicoder.c @@ -210,8 +210,15 @@ mpi_print( FILE *fp, MPI a, int mode ) if( a == MPI_NULL ) return fprintf(fp, "[MPI_NULL]"); - if( !mode ) - n += fprintf(fp, "[%u bits]", mpi_get_nbits(a) ); + if( !mode ) { + unsigned n1, n2; + n1 = mpi_get_nbits(a); + n2 = mpi_get_nbit_info(a); + if( n2 && n2 != n1 ) + n += fprintf(fp, "[%u bits (%u)]", n1, n2 ); + else + n += fprintf(fp, "[%u bits]", n1); + } else { if( a->sign ) putc('-', fp); @@ -278,8 +285,8 @@ do_get_buffer( MPI a, unsigned *nbytes, int *sign, int force_secure ) if( sign ) *sign = a->sign; *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB; - p = buffer = force_secure || a->secure ? m_alloc_secure( *nbytes) - : m_alloc( *nbytes ); + p = buffer = force_secure || mpi_is_secure(a) ? m_alloc_secure( *nbytes) + : m_alloc( *nbytes ); for(i=a->nlimbs-1; i >= 0; i-- ) { alimb = a->d[i]; diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c index 7c661094f..92b16538f 100644 --- a/mpi/mpiutil.c +++ b/mpi/mpiutil.c @@ -63,7 +63,7 @@ mpi_alloc( unsigned nlimbs ) a->alloced = nlimbs; a->nlimbs = 0; a->sign = 0; - a->secure = 0; + a->flags = 0; return a; } @@ -93,7 +93,7 @@ mpi_alloc_secure( unsigned nlimbs ) a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL; #endif a->alloced = nlimbs; - a->secure = 1; + a->flags |= 1; a->nlimbs = 0; a->sign = 0; return a; @@ -204,9 +204,9 @@ mpi_set_secure( MPI a ) { mpi_ptr_t ap, bp; - if( a->secure ) + if( (a->flags & 1) ) return; - a->secure = 1; + a->flags |= 1; ap = a->d; if( !a->nlimbs ) { assert(!ap); @@ -243,15 +243,15 @@ mpi_copy( MPI a ) if( a ) { #ifdef M_DEBUG - b = a->secure? mpi_debug_alloc_secure( a->nlimbs, info ) - : mpi_debug_alloc( a->nlimbs, info ); + b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info ) + : mpi_debug_alloc( a->nlimbs, info ); #else - b = a->secure? mpi_alloc_secure( a->nlimbs ) - : mpi_alloc( a->nlimbs ); + b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs ) + : mpi_alloc( a->nlimbs ); #endif b->nlimbs = a->nlimbs; b->sign = a->sign; - b->secure = a->secure; + b->flags = a->flags; b->nbits = a->nbits; for(i=0; i < b->nlimbs; i++ ) b->d[i] = a->d[i]; diff --git a/util/logger.c b/util/logger.c index 5ccc44cfa..4ae74547d 100644 --- a/util/logger.c +++ b/util/logger.c @@ -74,7 +74,7 @@ print_prefix(const char *text) } void -log_info( const char *fmt, ... ) +g10_log_info( const char *fmt, ... ) { va_list arg_ptr ; @@ -85,7 +85,7 @@ log_info( const char *fmt, ... ) } void -log_error( const char *fmt, ... ) +g10_log_error( const char *fmt, ... ) { va_list arg_ptr ; @@ -97,7 +97,7 @@ log_error( const char *fmt, ... ) } void -log_fatal( const char *fmt, ... ) +g10_log_fatal( const char *fmt, ... ) { va_list arg_ptr ; @@ -110,7 +110,7 @@ log_fatal( const char *fmt, ... ) } void -log_bug( const char *fmt, ... ) +g10_log_bug( const char *fmt, ... ) { va_list arg_ptr ; @@ -126,20 +126,20 @@ log_bug( const char *fmt, ... ) #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) void -log_bug0( const char *file, int line, const char *func ) +g10_log_bug0( const char *file, int line, const char *func ) { log_bug("Ohhhh jeeee ... (%s:%d:%s)\n", file, line, func ); } #else void -log_bug0( const char *file, int line ) +g10_log_bug0( const char *file, int line ) { log_bug("Ohhhh jeeee ... (%s:%d)\n", file, line); } #endif void -log_debug( const char *fmt, ... ) +g10_log_debug( const char *fmt, ... ) { va_list arg_ptr ; @@ -152,7 +152,7 @@ log_debug( const char *fmt, ... ) void -log_hexdump( const char *text, char *buf, size_t len ) +g10_log_hexdump( const char *text, char *buf, size_t len ) { int i; @@ -164,7 +164,7 @@ log_hexdump( const char *text, char *buf, size_t len ) void -log_mpidump( const char *text, MPI a ) +g10_log_mpidump( const char *text, MPI a ) { print_prefix(text); mpi_print(stderr, a, 1 );