diff --git a/ChangeLog b/ChangeLog index 5db61423e..d4b01c746 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Thu Jun 25 11:18:49 1998 Werner Koch (wk@isil.d.shuttle.de) + + * configure.in (--disable-dynload): New. + Wed Jun 10 07:48:59 1998 Werner Koch,mobil,,, (wk@tobold) * configure.in (GNUPG_LIBDIR): New. diff --git a/INSTALL b/INSTALL index 4950ba940..23fa6b98b 100644 --- a/INSTALL +++ b/INSTALL @@ -25,12 +25,16 @@ Configure options for GNUPG side-effect, this removes all debugging code and uses the -O2 flag for all C files. +--disable-dynload If you have problems with dynamic loading, this option + disables all dynamic loading stuff. + + Problems ======== -If you have compile problems, try the configure options "--with-included-zlib" -or "--disable-nls" (See ABOUT-NLS). +If you have compile problems, try the configure options "--with-included-zlib", +"--disable-nls" (See ABOUT-NLS) or --disable-dynload. I can't check all assembler files, so if you have problems assembling them (or the program crashes), simply delete the files in the mpi/ directory. diff --git a/NEWS b/NEWS index 01e875110..b942af624 100644 --- a/NEWS +++ b/NEWS @@ -1,11 +1,28 @@ Noteworthy changes in version 0.3.0 ----------------------------------- + * New option --emulate-checksum-bug. If your passphrase does not work anymore, use this option and --change-passphrase to rewrite your passphrase. + * More complete v4 key support: Preferences and expiration time + is set into the self signature. + * Key generation defaults to DSA/ElGamal keys, so that new keys are + interoperable with pgp5 + * DSA key generation is faster and key generation does not anymore + remove entropy from the random generator (the primes are public + parameters, so there is really no need for a cryptographic secure + prime number generator which we had used). + + * A complete new structure for representing the key parameters. + + * Removed most public key knowledge into the cipher libray. + + * Support for dynamic loading of new algorithms. + + * Moved tiger to an extension module. Noteworthy changes in version 0.2.19 diff --git a/TODO b/TODO index d9f61722a..5be913000 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,13 @@ + * make preferences work + + * rewrite --list-packets or put it into another tool. + * add field to PKT_user_id to hold the hash context * add usage arguments to get_key_byname or return a PKC_LIST with all keys and add a selection. - * add expiration date and other stuff from v4 sigs to the trust - checking. - * add readline support. Must enhance libreadline - Anyone? * Burn the buffers used by fopen(), or use read(2). @@ -21,7 +22,6 @@ * add checking of armor trailers * remove all "Fixmes" - * bug: g10/trustdb.c#build_sigrecs called to often by do_list_path and remove the bad kludge. Maybe we should put all sigs into the trustdb and mark them as valid/invalid/nopubkey, and how do we check, that @@ -29,11 +29,6 @@ record, as it does not belong to the pubkey record? * add an option to create a new user id. - Make it possible to change the signature class of the self-signatures, - which can then be used to change the displayed order of user-ids: - Put the user-id with a self-signature of class 0x13 always on top - of the displayed list (needs changes in the user-id-from-keyid - functions). * add an option to re-create a public key from a secret key. Think about a backup system of only the secret part of the secret key. diff --git a/VERSION b/VERSION index 598394464..159cf9874 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.19b +0.2.19d diff --git a/checks/Makefile.am b/checks/Makefile.am index 654922bdc..8787bc032 100644 --- a/checks/Makefile.am +++ b/checks/Makefile.am @@ -25,7 +25,7 @@ check: prepared.stamp prepared.stamp: pubring.gpg secring.gpg gnupg.sig plain-3 \ pubring.pkr secring.skr $(DATA_FILES) - @echo "def" | ../g10/gpg -v --no-operation; \ + @echo "def" | ../g10/gpg --homedir . -v --no-operation; \ echo timestamp >./prepared.stamp pubring.gpg: pubring.asc diff --git a/checks/defs.inc b/checks/defs.inc index dbd6e33b6..78954426f 100755 --- a/checks/defs.inc +++ b/checks/defs.inc @@ -70,7 +70,7 @@ pgmname=$(basename $0) cat <./options no-greeting no-secmem-warning -load-extension ../cipher/tiger.so +load-extension ../cipher/tiger batch EOF diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 354206462..92ca470da 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,6 +1,14 @@ +Thu Jun 25 11:18:25 1998 Werner Koch (wk@isil.d.shuttle.de) + + * Makefile.am: Support for extensions + +Thu Jun 18 12:09:38 1998 Werner Koch (wk@isil.d.shuttle.de) + + * random.c (mix_pool): simpler handling for level 0 + Mon Jun 15 14:40:48 1998 Werner Koch (wk@isil.d.shuttle.de) - * tiger.c: Removed from dis, will reappear as dynload module + * tiger.c: Removed from dist, will reappear as dynload module Sat Jun 13 14:16:57 1998 Werner Koch (wk@isil.d.shuttle.de) diff --git a/cipher/Makefile.am b/cipher/Makefile.am index d0c0202c9..f01bb7844 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -1,9 +1,15 @@ ## Process this file with automake to produce Makefile.in +gnupg_extensions = tiger + INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl -EXTRA_DIST = tiger.c noinst_LIBRARIES = libcipher.a +if ENABLE_GNUPG_EXTENSIONS +pkglib_PROGRAMS = $(gnupg_extensions) +else +pkglib_PROGRAMS = +endif libcipher_a_SOURCES = cipher.c \ @@ -18,6 +24,7 @@ libcipher_a_SOURCES = cipher.c \ elgamal.c \ elgamal.h \ md5.c \ + md5.h \ primegen.c \ random.h \ random.c \ @@ -34,4 +41,16 @@ libcipher_a_SOURCES = cipher.c \ g10c.c \ smallprime.c +EXTRA_tiger_SOURCES = tiger.c + +tiger: tiger.c + $(COMPILE) -shared -fPIC -o tiger tiger.c + +install-exec-hook: + @list='$(pkglib_PROGRAMS)'; for p in $$list; do \ + if test -f $(pkglibdir)/$$p; then \ + echo "chmod 644 $(pkglibdir)/$$p"; \ + chmod 644 $(pkglibdir)/$$p; \ + fi; \ + done diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 65a408ef8..3ed2ed858 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -55,7 +55,7 @@ typedef struct { u32 p[BLOWFISH_ROUNDS+2]; } BLOWFISH_context; -static void setkey( BLOWFISH_context *c, byte *key, unsigned keylen ); +static void bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen ); static void encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ); static void decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ); @@ -461,7 +461,7 @@ selftest() byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 }; byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 }; - setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 ); + bf_setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 ); encrypt_block( &c, buffer, plain ); if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) ) log_error("wrong blowfish encryption\n"); @@ -469,7 +469,7 @@ selftest() if( memcmp( buffer, plain, 8 ) ) log_bug("blowfish failed\n"); - setkey( &c, key3, 8 ); + bf_setkey( &c, key3, 8 ); encrypt_block( &c, buffer, plain3 ); if( memcmp( buffer, cipher3, 8 ) ) log_error("wrong blowfish encryption (3)\n"); @@ -481,7 +481,7 @@ selftest() static void -setkey( BLOWFISH_context *c, byte *key, unsigned keylen ) +bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen ) { int i, j; u32 data, datal, datar; @@ -563,7 +563,7 @@ blowfish_get_info( int algo, size_t *keylen, *keylen = algo == CIPHER_ALGO_BLOWFISH ? 128 : 160; *blocksize = BLOWFISH_BLOCKSIZE; *contextsize = sizeof(BLOWFISH_context); - *r_setkey = FNCCAST_SETKEY(setkey); + *r_setkey = FNCCAST_SETKEY(bf_setkey); *r_encrypt= FNCCAST_CRYPT(encrypt_block); *r_decrypt= FNCCAST_CRYPT(decrypt_block); diff --git a/cipher/cast5.c b/cipher/cast5.c index 0bd90f9df..6b2e5a969 100644 --- a/cipher/cast5.c +++ b/cipher/cast5.c @@ -57,7 +57,7 @@ typedef struct { byte Kr[16]; } CAST5_context; -static void setkey( CAST5_context *c, byte *key, unsigned keylen ); +static void cast_setkey( CAST5_context *c, byte *key, unsigned keylen ); static void encrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf ); static void decrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf ); @@ -465,7 +465,7 @@ selftest() byte cipher[8]= { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 }; byte buffer[8]; - setkey( &c, key, 16 ); + cast_setkey( &c, key, 16 ); encrypt_block( &c, buffer, plain ); if( memcmp( buffer, cipher, 8 ) ) log_error("wrong cast5-128 encryption\n"); @@ -486,10 +486,10 @@ selftest() 0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E }; for(i=0; i < 1000000; i++ ) { - setkey( &c, b0, 16 ); + cast_setkey( &c, b0, 16 ); encrypt_block( &c, a0, a0 ); encrypt_block( &c, a0+8, a0+8 ); - setkey( &c, a0, 16 ); + cast_setkey( &c, a0, 16 ); encrypt_block( &c, b0, b0 ); encrypt_block( &c, b0+8, b0+8 ); } @@ -550,7 +550,7 @@ key_schedule( u32 *x, u32 *z, u32 *k ) static void -setkey( CAST5_context *c, byte *key, unsigned keylen ) +cast_setkey( CAST5_context *c, byte *key, unsigned keylen ) { static int initialized; int i; @@ -602,7 +602,7 @@ cast5_get_info( int algo, size_t *keylen, *keylen = 128; *blocksize = CAST5_BLOCKSIZE; *contextsize = sizeof(CAST5_context); - *r_setkey = FNCCAST_SETKEY(setkey); + *r_setkey = FNCCAST_SETKEY(cast_setkey); *r_encrypt= FNCCAST_CRYPT(encrypt_block); *r_decrypt= FNCCAST_CRYPT(decrypt_block); diff --git a/cipher/dsa.c b/cipher/dsa.c index 19a59d909..46484c1e9 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -150,7 +150,7 @@ generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ) * is the secret part. */ if( DBG_CIPHER ) log_debug("choosing a random x "); - assert( qbits >= 16 ); + assert( qbits >= 160 ); x = mpi_alloc_secure( mpi_get_nlimbs(q) ); mpi_sub_ui( h, q, 1 ); /* put q-1 into h */ rndbuf = NULL; diff --git a/cipher/dynload.c b/cipher/dynload.c index 767372a7e..e22731702 100644 --- a/cipher/dynload.c +++ b/cipher/dynload.c @@ -34,6 +34,7 @@ typedef struct ext_list { void *handle; /* handle from dlopen() */ int failed; /* already tried but failed */ void * (*enumfunc)(int, int*, int*, int*); + char *hintstr; /* pointer into name */ char name[1]; } *EXTLIST; @@ -48,12 +49,19 @@ typedef struct { /**************** * Register an extension module. The last registered module will - * be loaded first. + * be loaded first. A name may have a list of classes + * appended; e.g: + * mymodule.so(1:17,3:20,3:109) + * means that this module provides digest algorithm 17 and public key + * algorithms 20 and 109. This is only a hint but if it is there the + * loader may decide to only load a module which claims to have a + * requested algorithm. */ void register_cipher_extension( const char *fname ) { EXTLIST r, el; + char *p, *pe; if( *fname != '/' ) { /* do tilde expansion etc */ char *p ; @@ -70,6 +78,14 @@ register_cipher_extension( const char *fname ) el = m_alloc_clear( sizeof *el + strlen(fname) ); strcpy(el->name, fname ); } + /* check whether we have a class hint */ + if( (p=strchr(el->name,'(')) && (pe=strchr(p+1,')')) && !pe[1] ) { + *p = *pe = 0; + el->hintstr = p+1; + } + else + el->hintstr = NULL; + /* check that it is not already registered */ for(r = extensions; r; r = r->next ) if( !compare_filenames(r->name, el->name) ) { @@ -77,8 +93,6 @@ register_cipher_extension( const char *fname ) m_free(el); return; } - if( DBG_CIPHER ) - log_debug("extension '%s' registered\n", el->name ); /* and register */ el->next = extensions; extensions = el; @@ -95,6 +109,7 @@ load_extension( EXTLIST el ) int seq = 0; int class, vers; + el->handle = dlopen(el->name, RTLD_NOW); if( !el->handle ) { log_error("%s: error loading extension: %s\n", el->name, dlerror() ); @@ -107,7 +122,10 @@ load_extension( EXTLIST el ) } if( g10_opt_verbose ) - log_info("%s: version '%s'\n", el->name, *name ); + log_info("%s: %s%s%s%s\n", el->name, *name, + el->hintstr? " (":"", + el->hintstr? el->hintstr:"", + el->hintstr? ")":""); sym = dlsym(el->handle, "gnupgext_enum_func"); if( (err=dlerror()) ) { diff --git a/cipher/md.c b/cipher/md.c index 3fd7581d7..56f639cfd 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -314,8 +314,9 @@ md_final(MD_HANDLE a) if( a->bufcount ) md_write( a, NULL, 0 ); - for(r=a->list; r; r = r->next ) + for(r=a->list; r; r = r->next ) { (*r->final)( &r->context ); + } } diff --git a/cipher/rand-unix.c b/cipher/rand-unix.c index 93afba13a..855b23b8e 100644 --- a/cipher/rand-unix.c +++ b/cipher/rand-unix.c @@ -129,23 +129,11 @@ read_random_source( byte *buffer, size_t length, int level ) fd_random = open_device( "/dev/random", 8 ); fd = fd_random; } - else if( level == 1 ) { - if( fd_urandom == -1 ) - fd_urandom = open_device( "/dev/urandom", 9 ); - fd = fd_urandom; - } else { - /* This is level 0, which only yields simple random bytes. - * We do not use /dev/urandom as this would remove entropy - * from the kernel entropy pool */ - /* FIXME !!!! */ - if( fd_urandom == -1 ) fd_urandom = open_device( "/dev/urandom", 9 ); fd = fd_urandom; } - - do { fd_set rfds; struct timeval tv; diff --git a/cipher/random.c b/cipher/random.c index ea6b90806..f44e4c3af 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -211,10 +211,6 @@ read_pool( byte *buffer, size_t length, int level ) if( length >= POOLSIZE ) BUG(); /* not allowed */ - if( !level ) { /* read simple random bytes */ - read_random_source( buffer, length, level ); - return; - } /* for level 2 make sure that there is enough random in the pool */ if( level == 2 && pool_balance < length ) { @@ -236,33 +232,45 @@ read_pool( byte *buffer, size_t length, int level ) /* make sure the pool is filled */ while( !pool_filled ) random_poll(); + /* do always a fast random poll */ fast_random_poll(); - /* mix the pool (if add_randomness() didn't it) */ - if( !just_mixed ) + if( !level ) { /* no need for cryptographic strong random */ + /* create a new pool */ + for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool; + i < POOLWORDS; i++, dp++, sp++ ) + *dp = *sp + ADD_VALUE; + /* must mix both pools */ mix_pool(rndpool); - - /* create a new pool */ - for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool; - i < POOLWORDS; i++, dp++, sp++ ) - *dp = *sp + ADD_VALUE; - /* and mix both pools */ - mix_pool(rndpool); - mix_pool(keypool); - /* read the required data - * we use a readpoiter to read from a different postion each - * time */ - while( length-- ) { - *buffer++ = keypool[pool_readpos++]; - if( pool_readpos >= POOLSIZE ) - pool_readpos = 0; - pool_balance--; + mix_pool(keypool); + memcpy( buffer, keypool, length ); + } + else { + /* mix the pool (if add_randomness() didn't it) */ + if( !just_mixed ) + mix_pool(rndpool); + /* create a new pool */ + for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool; + i < POOLWORDS; i++, dp++, sp++ ) + *dp = *sp + ADD_VALUE; + /* and mix both pools */ + mix_pool(rndpool); + mix_pool(keypool); + /* read the required data + * we use a readpoiter to read from a different postion each + * time */ + while( length-- ) { + *buffer++ = keypool[pool_readpos++]; + if( pool_readpos >= POOLSIZE ) + pool_readpos = 0; + pool_balance--; + } + if( pool_balance < 0 ) + pool_balance = 0; + /* and clear the keypool */ + memset( keypool, 0, POOLSIZE ); } - if( pool_balance < 0 ) - pool_balance = 0; - /* and clear the keypool */ - memset( keypool, 0, POOLSIZE ); } diff --git a/configure.in b/configure.in index 37e0bc6b0..005a1b5fb 100644 --- a/configure.in +++ b/configure.in @@ -31,6 +31,10 @@ AC_ARG_ENABLE(dev-random, [ --disable-dev-random disable the use of dev random], try_dev_random=$enableval, try_dev_random=yes) +AC_ARG_ENABLE(dynload, +[ --disable-dynload disable dynamic loading], + try_dynload=$enableval, try_dynload=yes) + AC_MSG_CHECKING([whether memory debugging is requested]) AC_ARG_ENABLE(m-debug, [ --enable-m-debug enable debugging of memory allocation], @@ -114,18 +118,32 @@ AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME") dnl Checks for libraries. + +if test "$try_dynload" = yes ; then AC_CHECK_LIB(dl,dlopen) if test "$ac_cv_lib_dl_dlopen" = "yes"; then AC_DEFINE(USE_DYNAMIC_LINKING) AC_DEFINE(HAVE_DL_DLOPEN) + DYNLINK_LDFLAGS=-rdynamic + use_gnupg_extensions=yes else AC_CHECK_LIB(dld,dld_link) if test "$ac_cv_lib_dld_dld_link" = "yes"; then AC_DEFINE(USE_DYNAMIC_LINKING) AC_DEFINE(HAVE_DLD_DLD_LINK) + DYNLINK_LDFLAGS=-rdynamic + use_gnupg_extensions=yes fi fi +else + AC_MSG_CHECKING(for dynamic loading) + DYNLINK_LDFLAGS= + use_gnupg_extensions=no + AC_MSG_RESULT(has been disabled) +fi +AM_CONDITIONAL(ENABLE_GNUPG_EXTENSIONS, test "$use_gnupg_extensions" = yes ) +AC_SUBST(DYNLINK_LDFLAGS) dnl Checks for header files. AC_HEADER_STDC diff --git a/doc/gpg.1pod b/doc/gpg.1pod index e5d51c62c..9fe18c5ec 100644 --- a/doc/gpg.1pod +++ b/doc/gpg.1pod @@ -215,6 +215,11 @@ B<--no-options> Shortcut for B<--options> I. This option is detected before an attempt to open an option file. +B<--load-extension> I + Load an extension module. If I does not + contain a slash it is searched in B + See the manual for more information about extensions. + B<--debug> I Set debugging flags. All flags are or-ed and I may be given in C syntax (e.g. 0x0042). @@ -335,8 +340,11 @@ gpgm(1) gpgd(1) =head1 WARNINGS -Use a B password for your user account and a non-simple passphrase -to protect your secret key. +Use a B password for your user account and a B passphrase +to protect your secret key. This passphrase is the weakest part of the +whole system. Programs to do dictionary attacks on your secret keyring +are very easy to write and so you should protect your B<~/.gnupg/> +directory very good. Keep in mind that, if this program is used over a network (telnet), it is B easy to spy out your passphrase! diff --git a/g10/ChangeLog b/g10/ChangeLog index 15fd2c81b..1e110efe4 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,20 @@ +Wed Jun 24 16:40:22 1998 Werner Koch (wk@isil.d.shuttle.de) + + * armor.c (armor_filter): Now creates valid onepass_sig packets + with all detected hash algorithms. + * mainproc.c (proc_plaintext): Now uses the hash algos as specified + in the onepass_sig packets (if there are any) + +Mon Jun 22 11:54:08 1998 Werner Koch (wk@isil.d.shuttle.de) + + * plaintext.c (handle_plaintext): add arg to disable outout + * mainproc.c (proc_plaintext): disable output when in sigs_only mode. + +Thu Jun 18 13:17:27 1998 Werner Koch (wk@isil.d.shuttle.de) + + * keygen.c: Removed all rsa packet stuff, chnaged defaults + for key generation. + Sun Jun 14 21:28:31 1998 Werner Koch (wk@isil.d.shuttle.de) * misc.c (checksum_u16): Fixed a stupid bug which caused a diff --git a/g10/Makefile.am b/g10/Makefile.am index 520a945a8..579ec6075 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -3,7 +3,7 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl EXTRA_DIST = OPTIONS pubring.asc OMIT_DEPENDENCIES = zlib.h zconf.h -LDFLAGS = -rdynamic +LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@ needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a noinst_PROGRAMS = gpgd diff --git a/g10/armor.c b/g10/armor.c index 49352a1eb..541ba3e76 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -100,8 +100,10 @@ static char *tail_strings[] = { }; -static fhdr_state_t find_header( fhdr_state_t state, byte *buf, - size_t *r_buflen, IOBUF a, size_t n, unsigned *r_empty); +static fhdr_state_t find_header( fhdr_state_t state, + byte *buf, size_t *r_buflen, + IOBUF a, size_t n, + unsigned *r_empty, int *r_hashes ); static void @@ -227,7 +229,7 @@ parse_hash_header( const char *line ) found |= 2; else if( !strncmp( s, "MD5", s2-s ) ) found |= 4; - else if( !strncmp( s, "MD2", s2-s ) ) + else if( !strncmp( s, "TIGER", s2-s ) ) found |= 8; else return 0; @@ -250,7 +252,7 @@ parse_hash_header( const char *line ) */ static fhdr_state_t find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, - IOBUF a, size_t n, unsigned *r_empty) + IOBUF a, size_t n, unsigned *r_empty, int *r_hashes ) { int c=0, i; const char *s; @@ -319,6 +321,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, if( n < buflen || c == '\n' ) { if( n && buf[0] != '\r') { /* maybe a header */ if( strchr( buf, ':') ) { /* yes */ + int hashes; if( buf[n-1] == '\r' ) buf[--n] = 0; if( opt.verbose ) { @@ -326,12 +329,15 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, print_string( stderr, buf, n, 0 ); putc('\n', stderr); } - if( clearsig && !parse_hash_header( buf ) ) { + if( clearsig && !(hashes=parse_hash_header( buf )) ) { log_error("invalid clearsig header\n"); state = fhdrERROR; } - else + else { state = fhdrWAITHeader; + if( r_hashes ) + *r_hashes |= hashes; + } } else state = fhdrCHECKDashEscaped3; @@ -602,7 +608,8 @@ check_input( armor_filter_context_t *afx, IOBUF a ) state = fhdrHASArmor; n = DIM(afx->helpbuf); - state = find_header( state, afx->helpbuf, &n, a, afx->helplen, &emplines); + state = find_header( state, afx->helpbuf, &n, a, + afx->helplen, &emplines, &afx->hashes); switch( state ) { case fhdrNOArmor: afx->inp_checked = 1; @@ -684,7 +691,8 @@ fake_packet( armor_filter_context_t *afx, IOBUF a, /* read a new one */ n = DIM(afx->helpbuf); afx->helpidx = 0; - state = find_header( state, afx->helpbuf, &n, a, 0, &emplines ); + state = find_header( state, afx->helpbuf, &n, a, 0, + &emplines, &afx->hashes ); switch( state) { case fhdrERROR: invalid_armor(); @@ -884,7 +892,7 @@ armor_filter( void *opaque, int control, *ret_len = n; } else if( control == IOBUFCTRL_UNDERFLOW ) { - if( size < 30 ) + if( size < 15+(4*15) ) /* need space for up to 4 onepass_sigs */ BUG(); /* supplied buffer too short */ if( afx->inp_eof ) { @@ -907,27 +915,53 @@ armor_filter( void *opaque, int control, afx->helplen = 0; } else if( afx->faked ) { - /* the buffer is at least 30 bytes long, so it + unsigned hashes = afx->hashes; + /* the buffer is at least 15+n*15 bytes long, so it * is easy to construct the packets */ - /* first a onepass signature packet */ - buf[0] = 0x90; /* old packet format, type 4, 1 length byte */ - buf[1] = 13; /* length */ - buf[2] = 3; /* version */ - buf[3] = 0x01; /* sigclass 0x01 (data in canonical text mode)*/ - buf[4] = 0; /* digest algo (don't know) */ - buf[5] = 0; /* public key algo (don't know) */ - memset(buf+6, 0, 8); /* don't know the keyid */ - buf[14] = 1; /* this is the last one */ + hashes &= 1|2|4|8; + if( !hashes ) + hashes |= 4; /* default to MD 5 */ + n=0; + do { + /* first some onepass signature packets */ + buf[n++] = 0x90; /* old format, type 4, 1 length byte */ + buf[n++] = 13; /* length */ + buf[n++] = 3; /* version */ + buf[n++] = 0x01; /* sigclass 0x01 (canonical text mode)*/ + if( hashes & 1 ) { + hashes &= ~1; + buf[n++] = DIGEST_ALGO_RMD160; + } + else if( hashes & 2 ) { + hashes &= ~2; + buf[n++] = DIGEST_ALGO_SHA1; + } + else if( hashes & 4 ) { + hashes &= ~4; + buf[n++] = DIGEST_ALGO_MD5; + } + else if( hashes & 8 ) { + hashes &= ~8; + buf[n++] = DIGEST_ALGO_TIGER; + } + else + buf[n++] = 0; /* (don't know) */ + + buf[n++] = 0; /* public key algo (don't know) */ + memset(buf+n, 0, 8); /* don't know the keyid */ + n += 8; + buf[n++] = !hashes; /* last one */ + } while( hashes ); /* followed by a plaintext packet */ - buf[15] = 0xaf; /* old packet format, type 11, var length */ - buf[16] = 0; /* set the length header */ - buf[17] = 6; - buf[18] = 't'; /* canonical text mode */ - buf[19] = 0; /* namelength */ - memset(buf+20, 0, 4); /* timestamp */ - n = 24; + buf[n++] = 0xaf; /* old packet format, type 11, var length */ + buf[n++] = 0; /* set the length header */ + buf[n++] = 6; + buf[n++] = 't'; /* canonical text mode */ + buf[n++] = 0; /* namelength */ + memset(buf+n, 0, 4); /* timestamp */ + n += 4; } else if( !rc ) rc = radix64_read( afx, a, &n, buf, size ); diff --git a/g10/build-packet.c b/g10/build-packet.c index 7048ad9a8..03e152e99 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -517,6 +517,11 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, switch( type ) { case SIGSUBPKT_SIG_CREATED: case SIGSUBPKT_PRIV_ADD_SIG: + case SIGSUBPKT_PREF_SYM: + case SIGSUBPKT_PREF_HASH: + case SIGSUBPKT_PREF_COMPR: + case SIGSUBPKT_KS_FLAGS: + case SIGSUBPKT_KEY_EXPIRE: hashed = 1; break; default: hashed = 0; break; } @@ -538,8 +543,8 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, : m_alloc( n+2 ); } - data[n0+0] = (n >> 8) & 0xff; - data[n0+1] = n & 0xff; + data[0] = (n >> 8) & 0xff; + data[1] = n & 0xff; data[n0+2] = buflen+1; data[n0+3] = type; memcpy(data+n0+4, buffer, buflen ); diff --git a/g10/filter.h b/g10/filter.h index 72b44086a..2dc8a3e87 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -37,6 +37,7 @@ typedef struct { byte helpbuf[100]; int helpidx, helplen; unsigned empty; /* empty line counter */ + int hashes; /* detected hash algorithms */ int faked; int parse_state; int inp_checked; /* set if inp has been checked */ diff --git a/g10/getkey.c b/g10/getkey.c index 5f607ec51..c8e8ea012 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -30,6 +30,7 @@ #include "iobuf.h" #include "keydb.h" #include "options.h" +#include "main.h" #define MAX_PKC_CACHE_ENTRIES 500 @@ -595,6 +596,58 @@ compare_name( const char *uid, size_t uidlen, const char *name, int mode ) } + +/**************** + * Assume that knode points to a public key packet and keyblock is + * the entire keyblock. This function adds all relevant information from + * a selfsignature to the public key. + */ + +static void +add_stuff_from_selfsig( KBNODE keyblock, KBNODE knode ) +{ + PKT_public_cert *pkc = knode->pkt->pkt.public_cert; + PKT_signature *sig; + KBNODE k; + u32 kid[2]; + + assert( knode->pkt->pkttype == PKT_PUBLIC_CERT + || knode->pkt->pkttype == PKT_PUBKEY_SUBCERT ); + + if( pkc->version < 4 ) + return; /* this is only needed for version >=4 packets */ + + /* find the selfsignature */ + if( knode->pkt->pkttype == PKT_PUBKEY_SUBCERT ) { + k = find_kbnode( keyblock, PKT_PUBLIC_CERT ); + if( !k ) + BUG(); /* keyblock without primary key!!! */ + keyid_from_pkc( knode->pkt->pkt.public_cert, kid ); + } + else + keyid_from_pkc( pkc, kid ); + for(k=keyblock; k; k = k->next ) { + if( k->pkt->pkttype == PKT_SIGNATURE + && (sig=k->pkt->pkt.signature)->sig_class >= 0x10 + && sig->sig_class <= 0x13 + && sig->keyid[0] == kid[0] + && sig->keyid[1] == kid[1] + && sig->version > 3 ) { + /* okay this is (the first) self-signature which can be used + * fixme: Check how to handle subkey bindings + * FIXME: We should only use this if the signature is valid + * but this is time consuming - we muts provide another + * way to handle this + */ + const byte *p; + p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL ); + pkc->valid_days = p? ((buffer_to_u32(p)+86399L)/86400L):0; + /* fixme: add usage etc. to pkc */ + break; + } + } +} + /**************** * Lookup a key by scanning all keyrings * mode 1 = lookup by NAME (exact) @@ -718,6 +771,7 @@ lookup( PKT_public_cert *pkc, int mode, u32 *keyid, assert( k->pkt->pkttype == PKT_PUBLIC_CERT || k->pkt->pkttype == PKT_PUBKEY_SUBCERT ); copy_public_cert( pkc, k->pkt->pkt.public_cert ); + add_stuff_from_selfsig( keyblock, k ); if( ret_keyblock ) { *ret_keyblock = keyblock; keyblock = NULL; diff --git a/g10/keyedit.c b/g10/keyedit.c index f5c95ea32..8f3f16511 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -347,7 +347,7 @@ sign_key( const char *username, STRLIST locusr ) node->pkt->pkt.user_id, NULL, skc_rover->skc, - 0x10, 0 ); + 0x10, 0, NULL, NULL ); if( rc ) { log_error("make_keysig_packet failed: %s\n", g10_errstr(rc)); goto leave; @@ -720,7 +720,9 @@ int make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc, PKT_user_id *uid, PKT_public_cert *subpkc, PKT_secret_cert *skc, - int sigclass, int digest_algo ) + int sigclass, int digest_algo, + int (*mksubpkt)(PKT_signature *, void *), void *opaque + ) { PKT_signature *sig; int rc=0; @@ -763,45 +765,50 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc, sig->digest_algo = digest_algo; sig->timestamp = make_timestamp(); sig->sig_class = sigclass; - - if( sig->version >= 4 ) { + if( sig->version >= 4 ) build_sig_subpkt_from_sig( sig ); - md_putc( md, sig->version ); - } - md_putc( md, sig->sig_class ); - if( sig->version < 4 ) { - u32 a = sig->timestamp; - md_putc( md, (a >> 24) & 0xff ); - md_putc( md, (a >> 16) & 0xff ); - md_putc( md, (a >> 8) & 0xff ); - md_putc( md, a & 0xff ); - } - else { - byte buf[6]; - size_t n; - md_putc( md, sig->pubkey_algo ); - md_putc( md, sig->digest_algo ); - if( sig->hashed_data ) { - n = (sig->hashed_data[0] << 8) | sig->hashed_data[1]; - md_write( md, sig->hashed_data, n+2 ); - n += 6; + if( sig->version >= 4 && mksubpkt ) + rc = (*mksubpkt)( sig, opaque ); + + if( !rc ) { + if( sig->version >= 4 ) + md_putc( md, sig->version ); + md_putc( md, sig->sig_class ); + if( sig->version < 4 ) { + u32 a = sig->timestamp; + md_putc( md, (a >> 24) & 0xff ); + md_putc( md, (a >> 16) & 0xff ); + md_putc( md, (a >> 8) & 0xff ); + md_putc( md, a & 0xff ); } - else - n = 6; - /* add some magic */ - buf[0] = sig->version; - buf[1] = 0xff; - buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */ - buf[3] = n >> 16; - buf[4] = n >> 8; - buf[5] = n; - md_write( md, buf, 6 ); + else { + byte buf[6]; + size_t n; + md_putc( md, sig->pubkey_algo ); + md_putc( md, sig->digest_algo ); + if( sig->hashed_data ) { + n = (sig->hashed_data[0] << 8) | sig->hashed_data[1]; + md_write( md, sig->hashed_data, n+2 ); + n += 6; + } + else + n = 6; + /* add some magic */ + buf[0] = sig->version; + buf[1] = 0xff; + buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */ + buf[3] = n >> 16; + buf[4] = n >> 8; + buf[5] = n; + md_write( md, buf, 6 ); + + } + md_final(md); + + rc = complete_sig( sig, skc, md ); } - md_final(md); - - rc = complete_sig( sig, skc, md ); md_close( md ); if( rc ) diff --git a/g10/keygen.c b/g10/keygen.c index 21c388bfc..b79f9b9ea 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -35,11 +35,6 @@ #include "i18n.h" -#if 0 - #define ENABLE_RSA_KEYGEN 1 -#endif - - static void write_uid( KBNODE root, const char *s ) { @@ -54,6 +49,65 @@ write_uid( KBNODE root, const char *s ) } + +static int +add_key_expire( PKT_signature *sig, void *opaque ) +{ + PKT_secret_cert *skc = opaque; + byte buf[8]; + u32 u; + + if( skc->valid_days ) { + u = skc->valid_days * 86400L; + buf[0] = (u >> 24) & 0xff; + buf[1] = (u >> 16) & 0xff; + buf[2] = (u >> 8) & 0xff; + buf[3] = u & 0xff; + build_sig_subpkt( sig, SIGSUBPKT_KEY_EXPIRE, buf, 4 ); + } + + return 0; +} + + +/**************** + * Add preference to the self signature packet. + * This is only called for packets with version > 3. + */ +static int +add_prefs( PKT_signature *sig, void *opaque ) +{ + byte buf[8]; + + add_key_expire( sig, opaque ); + + buf[0] = CIPHER_ALGO_BLOWFISH; + buf[1] = CIPHER_ALGO_CAST5; + build_sig_subpkt( sig, SIGSUBPKT_PREF_SYM, buf, 2 ); + + buf[0] = DIGEST_ALGO_RMD160; + buf[1] = DIGEST_ALGO_SHA1; + buf[2] = DIGEST_ALGO_TIGER; + buf[3] = DIGEST_ALGO_MD5; + build_sig_subpkt( sig, SIGSUBPKT_PREF_HASH, buf, 4 ); + + buf[0] = 2; + buf[1] = 1; + build_sig_subpkt( sig, SIGSUBPKT_PREF_COMPR, buf, 2 ); + + buf[0] = 0x80; /* no modify - It is reasonable that a key holder + * has the possibility to reject signatures from users + * who are known to sign everything without any + * validation - so a signed key should be send + * to the holder who in turn can put it on a keyserver + */ + build_sig_subpkt( sig, SIGSUBPKT_KS_FLAGS, buf, 1 ); + + return 0; +} + + + static int write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc ) { @@ -79,7 +133,8 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc ) pkc = node->pkt->pkt.public_cert; /* and make the signature */ - rc = make_keysig_packet( &sig, pkc, uid, NULL, skc, 0x13, 0 ); + rc = make_keysig_packet( &sig, pkc, uid, NULL, skc, 0x13, 0, + add_prefs, skc ); if( rc ) { log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) ); return rc; @@ -119,7 +174,8 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc ) BUG(); /* and make the signature */ - rc = make_keysig_packet( &sig, pkc, NULL, subpkc, skc, 0x18, 0 ); + rc = make_keysig_packet( &sig, pkc, NULL, subpkc, skc, 0x18, 0, + add_key_expire, skc ); if( rc ) { log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) ); return rc; @@ -134,7 +190,7 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc ) static int -gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, +gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, STRING2KEY *s2k, PKT_secret_cert **ret_skc, u16 valid_days, int version ) { @@ -146,7 +202,8 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, MPI skey[4]; MPI *factors; - rc = pubkey_generate( PUBKEY_ALGO_ELGAMAL, nbits, skey, &factors ); + assert( is_ELGAMAL(algo) ); + rc = pubkey_generate( algo, nbits, skey, &factors ); if( rc ) { log_error("pubkey_generate failed: %s\n", g10_errstr(rc) ); return rc; @@ -157,7 +214,7 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, skc->timestamp = pkc->timestamp = make_timestamp(); skc->version = pkc->version = version; skc->valid_days = pkc->valid_days = valid_days; - skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL; + skc->pubkey_algo = pkc->pubkey_algo = algo; pkc->pkey[0] = mpi_copy( skey[0] ); pkc->pkey[1] = mpi_copy( skey[1] ); pkc->pkey[2] = mpi_copy( skey[2] ); @@ -203,73 +260,6 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, } - -#ifdef ENABLE_RSA_KEYGEN -static int -gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, - STRING2KEY *s2k, PKT_secret_cert **ret_skc, u16 valid_days ) -{ - int rc; - PACKET *pkt; - PKT_secret_cert *skc; - PKT_public_cert *pkc; - RSA_public_key pk; - RSA_secret_key sk; - - rsa_generate( &pk, &sk, nbits ); - - skc = m_alloc_clear( sizeof *skc ); - pkc = m_alloc_clear( sizeof *pkc ); - skc->timestamp = pkc->timestamp = make_timestamp(); - skc->valid_days = pkc->valid_days = valid_days; - skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_RSA; - memset(&pkc->mfx, 0, sizeof pkc->mfx); - pkc->d.rsa.rsa_n = pk.n; - pkc->d.rsa.rsa_e = pk.e; - skc->d.rsa.rsa_n = sk.n; - skc->d.rsa.rsa_e = sk.e; - skc->d.rsa.rsa_d = sk.d; - skc->d.rsa.rsa_p = sk.p; - skc->d.rsa.rsa_q = sk.q; - skc->d.rsa.rsa_u = sk.u; - skc->d.rsa.csum = checksum_mpi_counted_nbits( skc->d.rsa.rsa_d ); - skc->d.rsa.csum += checksum_mpi_counted_nbits( skc->d.rsa.rsa_p ); - skc->d.rsa.csum += checksum_mpi_counted_nbits( skc->d.rsa.rsa_q ); - skc->d.rsa.csum += checksum_mpi_counted_nbits( skc->d.rsa.rsa_u ); - - if( ret_skc ) /* not a subkey: return an unprotected version of the skc */ - *ret_skc = copy_secret_cert( NULL, skc ); - - if( dek ) { - skc->d.rsa.is_protected = 1; - skc->d.rsa.protect_algo = CIPHER_ALGO_BLOWFISH; - randomize_buffer( skc->d.rsa.protect.blowfish.iv, 8, 1); - skc->d.rsa.csum += checksum_counted_nbits( - skc->d.rsa.protect.blowfish.iv, 8 ); - rc = protect_secret_key( skc, dek ); - if( rc ) { - log_error("protect_secret_key failed: %s\n", g10_errstr(rc) ); - free_public_cert(pkc); - free_secret_cert(skc); - return rc; - } - } - - pkt = m_alloc_clear(sizeof *pkt); - pkt->pkttype = ret_skc ? PKT_PUBLIC_CERT : PKT_PUBKEY_SUBCERT; - pkt->pkt.public_cert = pkc; - add_kbnode(pub_root, new_kbnode( pkt )); - - pkt = m_alloc_clear(sizeof *pkt); - pkt->pkttype = ret_skc ? PKT_SECRET_CERT : PKT_SECKEY_SUBCERT; - pkt->pkt.secret_cert = skc; - add_kbnode(sec_root, new_kbnode( pkt )); - - return rc; -} -#endif /*ENABLE_RSA_KEYGEN*/ - - /**************** * Generate a DSA key */ @@ -298,15 +288,12 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, pkc = m_alloc_clear( sizeof *pkc ); skc->timestamp = pkc->timestamp = make_timestamp(); skc->version = pkc->version = 4; - /* valid days are not stored in the packet, but it is - * used here to put it into the signature. - */ skc->valid_days = pkc->valid_days = valid_days; skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_DSA; - pkc->pkey[0] = skey[0]; - pkc->pkey[1] = skey[1]; - pkc->pkey[2] = skey[2]; - pkc->pkey[3] = skey[3]; + pkc->pkey[0] = mpi_copy( skey[0] ); + pkc->pkey[1] = mpi_copy( skey[1] ); + pkc->pkey[2] = mpi_copy( skey[2] ); + pkc->pkey[3] = mpi_copy( skey[3] ); skc->skey[0] = skey[0]; skc->skey[1] = skey[1]; skc->skey[2] = skey[2]; @@ -317,7 +304,7 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, skc->csum = checksum_mpi_counted_nbits( skc->skey[4] ); if( ret_skc ) /* not a subkey: return an unprotected version of the skc */ - *ret_skc = copy_secret_cert( NULL, skc ); + *ret_skc = copy_secret_cert( NULL, skc ); if( dek ) { skc->protect.algo = dek->algo; @@ -383,47 +370,52 @@ check_valid_days( const char *s ) } +/**************** + * Returns o to create both a DSA and a ElGamal key. + */ static int -ask_algo( int *ret_v4 ) +ask_algo( int *ret_v4, int addmode ) { char *answer; int algo; - tty_printf(_("Please select the algorithm to use:\n" - " (1) ElGamal is the suggested one.\n" - " (2) ElGamal using v4 packets (OpenPGP)\n" - " (3) DSA can only be used for signatures.\n")); - #ifdef ENABLE_RSA_KEYGEN - tty_printf(_(" (4) RSA cannot be used in the U.S.\n")); - #endif + tty_printf(_("Please select what kind of key you want:\n")); + if( !addmode ) + tty_printf(_(" (%d) DSA and ElGamal (default)\n"), 1 ); + tty_printf( _(" (%d) ElGamal (sign and encrypt)\n"), 2 ); + tty_printf( _(" (%d) ElGamal (encrypt only)\n"), 3 ); + tty_printf( _(" (%d) DSA (sign only)\n"), 4 ); + tty_printf( _(" (%d) ElGamal in a v3 packet\n"), 5 ); - *ret_v4 = 0; + *ret_v4 = 1; for(;;) { - #ifdef ENABLE_RSA_KEYGEN - answer = tty_get(_("Your selection? (1,2,3,4) ")); - #else - answer = tty_get(_("Your selection? (1,2,3) ")); - #endif + answer = tty_get(_("Your selection? ")); tty_kill_prompt(); algo = *answer? atoi(answer): 1; m_free(answer); - if( algo == 1 || algo == 2 ) { - if( algo == 2 ) - *ret_v4 = 1; + if( algo == 1 && !addmode ) { + algo = 0; /* create both keys */ + break; + } + else if( algo == 2 ) { algo = PUBKEY_ALGO_ELGAMAL; break; } else if( algo == 3 ) { - *ret_v4 = 1; + algo = PUBKEY_ALGO_ELGAMAL_E; + break; + } + else if( algo == 4 ) { algo = PUBKEY_ALGO_DSA; break; } - #ifdef ENABLE_RSA_KEYGEN - else if( algo == 4 ) { - algo = PUBKEY_ALGO_RSA; + else if( algo == 5 ) { + algo = PUBKEY_ALGO_ELGAMAL_E; + *ret_v4 = 0; break; } - #endif + else + tty_printf(_("Invalid selection.\n")); } return algo; } @@ -703,13 +695,9 @@ do_create( int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, "network and the disks) during the prime generation; this gives the random\n" "number generator a better chance to gain enough entropy.\n") ); - if( algo == PUBKEY_ALGO_ELGAMAL ) - rc = gen_elg(nbits, pub_root, sec_root, dek, s2k, + if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E ) + rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, skc, valid_days, v4_packet? 4:3 ); - #ifdef ENABLE_RSA_KEYGEN - else if( algo == PUBKEY_ALGO_RSA ) - rc = gen_rsa(nbits, pub_root, sec_root, dek, s2k, skc, valid_days ); - #endif else if( algo == PUBKEY_ALGO_DSA ) rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, skc, valid_days); else @@ -745,13 +733,19 @@ generate_keypair() int algo; int ndays; int v4; + int both = 0; if( opt.batch || opt.answer_yes || opt.answer_no ) { log_error(_("Key generation can only be used in interactive mode\n")); return; } - algo = ask_algo( &v4 ); + algo = ask_algo( &v4, 0 ); + if( !algo ) { + algo = PUBKEY_ALGO_ELGAMAL; + both = 1; + tty_printf(_("DSA keypair will have 1024 bits.\n")); + } nbits = ask_keysize( algo ); ndays = ask_valid_days(); uid = ask_user_id(); @@ -774,7 +768,12 @@ generate_keypair() pub_root = make_comment_node("#"); delete_kbnode(pub_root); sec_root = make_comment_node("#"); delete_kbnode(sec_root); - rc = do_create( algo, nbits, pub_root, sec_root, dek, s2k, &skc, ndays, v4); + if( both ) + rc = do_create( PUBKEY_ALGO_DSA, 1024, pub_root, sec_root, + dek, s2k, &skc, ndays, 1); + else + rc = do_create( algo, nbits, pub_root, sec_root, + dek, s2k, &skc, ndays, v4); if( !rc ) write_uid(pub_root, uid ); if( !rc ) @@ -784,6 +783,16 @@ generate_keypair() if( !rc ) rc = write_selfsig(sec_root, pub_root, skc); + if( both ) { + rc = do_create( algo, nbits, pub_root, sec_root, + dek, s2k, NULL, ndays, 1 ); + if( !rc ) + rc = write_keybinding(pub_root, pub_root, skc); + if( !rc ) + rc = write_keybinding(sec_root, pub_root, skc); + } + + if( !rc ) { KBPOS pub_kbpos; KBPOS sec_kbpos; @@ -958,7 +967,8 @@ generate_subkeypair( const char *username ) goto leave; - algo = ask_algo( &v4 ); + algo = ask_algo( &v4, 1 ); + assert(algo); nbits = ask_keysize( algo ); ndays = ask_valid_days(); diff --git a/g10/main.h b/g10/main.h index 0b30084e3..c50a07147 100644 --- a/g10/main.h +++ b/g10/main.h @@ -50,6 +50,7 @@ u16 checksum_u16( unsigned n ); u16 checksum( byte *p, unsigned n ); u16 checksum_mpi( MPI a ); u16 checksum_mpi_counted_nbits( MPI a ); +u32 buffer_to_u32( const byte *buffer ); /*-- encode.c --*/ int encode_symmetric( const char *filename ); diff --git a/g10/mainproc.c b/g10/mainproc.c index a807f85d9..a69217a3a 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -232,25 +232,42 @@ static void proc_plaintext( CTX c, PACKET *pkt ) { PKT_plaintext *pt = pkt->pkt.plaintext; - int rc; + int any, rc; + KBNODE n; if( opt.verbose ) log_info("original file name='%.*s'\n", pt->namelen, pt->name); free_md_filter_context( &c->mfx ); - /* FIXME: take the digest algo(s) to use from the - * onepass_sig packet (if we have these) - * And look at the sigclass to check whether we should use the - * textmode filter (sigclass 0x01) + /* fixme: look at the sigclass to check whether we should use the + * textmode filter (sigclass 0x01) */ - c->mfx.md = md_open( DIGEST_ALGO_RMD160, 0); - /*md_start_debug(c->mfx.md, "proc_plaintext");*/ - md_enable( c->mfx.md, DIGEST_ALGO_SHA1 ); - md_enable( c->mfx.md, DIGEST_ALGO_MD5 ); - if( !check_digest_algo(DIGEST_ALGO_TIGER) ) - md_enable( c->mfx.md, DIGEST_ALGO_TIGER ); - rc = handle_plaintext( pt, &c->mfx ); + c->mfx.md = md_open( 0, 0); + any = 0; + for(n=c->list; n; n = n->next ) { + if( n->pkt->pkttype == PKT_ONEPASS_SIG + && n->pkt->pkt.onepass_sig->digest_algo ) { + md_enable( c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo ); + any = 1; + } + } + if( !any ) { /* no onepass sig packet: enable all algos */ + md_enable( c->mfx.md, DIGEST_ALGO_RMD160 ); + md_enable( c->mfx.md, DIGEST_ALGO_SHA1 ); + md_enable( c->mfx.md, DIGEST_ALGO_MD5 ); + } + if( c->mfx.md ) { + m_check(c->mfx.md); + if( c->mfx.md->list ) + m_check( c->mfx.md->list ); + } + rc = handle_plaintext( pt, &c->mfx, c->sigs_only ); if( rc ) log_error( "handle plaintext failed: %s\n", g10_errstr(rc)); + if( c->mfx.md ) { + m_check(c->mfx.md); + if( c->mfx.md->list ) + m_check( c->mfx.md->list ); + } free_packet(pkt); c->last_was_session_key = 0; } @@ -312,6 +329,12 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig ) if( (rc=check_digest_algo(algo)) ) return rc; + if( c->mfx.md ) { + m_check(c->mfx.md); + if( c->mfx.md->list ) + m_check( c->mfx.md->list ); + } + if( sig->sig_class == 0x00 ) { if( c->mfx.md ) md = md_copy( c->mfx.md ); @@ -792,7 +815,7 @@ check_sig_and_print( CTX c, KBNODE node ) tstr = asctime(localtime (&stamp)); astr = pubkey_algo_to_string( sig->pubkey_algo ); log_info(_("Signature made %.*s using %s key ID %08lX\n"), - strlen(tstr)-1, tstr, astr? astr: "?", (ulong)sig->keyid[1] ); + (int)strlen(tstr)-1, tstr, astr? astr: "?", (ulong)sig->keyid[1] ); rc = do_check_sig(c, node, NULL ); if( !rc || rc == G10ERR_BAD_SIGN ) { diff --git a/g10/misc.c b/g10/misc.c index 0c2b6ac4a..470307363 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -152,3 +152,15 @@ checksum_mpi_counted_nbits( MPI a ) return csum; } + +u32 +buffer_to_u32( const byte *buffer ) +{ + unsigned long a; + a = *buffer << 24; + a |= buffer[1] << 16; + a |= buffer[2] << 8; + a |= buffer[3]; + return a; +} + diff --git a/g10/packet.h b/g10/packet.h index 4f04e1ae4..c928cf46d 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -276,7 +276,7 @@ int decrypt_data( PKT_encrypted *ed, DEK *dek ); int encrypt_data( PKT_encrypted *ed, DEK *dek ); /*-- plaintext.c --*/ -int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ); +int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,int nooutput); int ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname ); /*-- comment.c --*/ @@ -286,6 +286,8 @@ int write_comment( IOBUF out, const char *s ); int make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc, PKT_user_id *uid, PKT_public_cert *subpkc, PKT_secret_cert *skc, - int sigclass, int digest_algo ); + int sigclass, int digest_algo, + int (*mksubpkt)(PKT_signature *, void *), + void *opaque ); #endif /*G10_PACKET_H*/ diff --git a/g10/parse-packet.c b/g10/parse-packet.c index ba26089c5..bf26b7a39 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -32,6 +32,7 @@ #include "memory.h" #include "filter.h" #include "options.h" +#include "main.h" static int mpi_print_mode = 0; static int list_mode = 0; @@ -85,16 +86,6 @@ read_32(IOBUF inp) return a; } -static unsigned long -buffer_to_u32( const byte *buffer ) -{ - unsigned long a; - a = *buffer << 24; - a |= buffer[1] << 16; - a |= buffer[2] << 8; - a |= buffer[3]; - return a; -} int set_packet_list_mode( int mode ) @@ -622,6 +613,8 @@ parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n ) *ret_n = n; switch( type ) { case SIGSUBPKT_SIG_CREATED: + case SIGSUBPKT_SIG_EXPIRE: + case SIGSUBPKT_KEY_EXPIRE: if( n < 4 ) break; return buffer; diff --git a/g10/plaintext.c b/g10/plaintext.c index cdf4fe2a2..161db58d4 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -40,16 +40,18 @@ * bytes from the plaintext. */ int -handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ) +handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, int nooutput ) { - char *fname; + char *fname = NULL; FILE *fp = NULL; int rc = 0; int c; int convert = pt->mode == 't'; /* create the filename as C string */ - if( opt.outfile ) { + if( nooutput ) + ; + else if( opt.outfile ) { fname = m_alloc( strlen( opt.outfile ) + 1); strcpy(fname, opt.outfile ); } @@ -59,14 +61,16 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ) fname[pt->namelen] = 0; } - if( !*fname || (*fname=='-' && !fname[1])) { + if( nooutput ) + ; + else if( !*fname || (*fname=='-' && !fname[1])) { /* no filename or "-" given; write to stdout */ fp = stdout; } else if( overwrite_filep( fname ) ) goto leave; - if( fp ) + if( fp || nooutput ) ; else if( !(fp = fopen(fname,"wb")) ) { log_error("Error creating '%s': %s\n", fname, strerror(errno) ); @@ -86,10 +90,13 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ) md_putc(mfx->md, c ); if( convert && c == '\r' ) continue; /* FIXME: this hack is too simple */ - if( putc( c, fp ) == EOF ) { - log_error("Error writing to '%s': %s\n", fname, strerror(errno) ); - rc = G10ERR_WRITE_FILE; - goto leave; + if( fp ) { + if( putc( c, fp ) == EOF ) { + log_error("Error writing to '%s': %s\n", + fname, strerror(errno) ); + rc = G10ERR_WRITE_FILE; + goto leave; + } } } } @@ -99,11 +106,13 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ) md_putc(mfx->md, c ); if( convert && c == '\r' ) continue; /* FIXME: this hack is too simple */ - if( putc( c, fp ) == EOF ) { - log_error("Error writing to '%s': %s\n", - fname, strerror(errno) ); - rc = G10ERR_WRITE_FILE; - goto leave; + if( fp ) { + if( putc( c, fp ) == EOF ) { + log_error("Error writing to '%s': %s\n", + fname, strerror(errno) ); + rc = G10ERR_WRITE_FILE; + goto leave; + } } } iobuf_clear_eof(pt->buf); diff --git a/g10/revoke.c b/g10/revoke.c index cafe84de3..4819d91c2 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -159,7 +159,7 @@ gen_revoke( const char *uname ) /* create it */ - rc = make_keysig_packet( &sig, pkc, NULL, NULL, skc, 0x20, 0); + rc = make_keysig_packet( &sig, pkc, NULL, NULL, skc, 0x20, 0, NULL, NULL); if( rc ) { log_error("make_keysig_packet failed: %s\n", g10_errstr(rc)); goto leave; diff --git a/g10/sig-check.c b/g10/sig-check.c index 76f0aaca7..200d67048 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -31,6 +31,7 @@ #include "cipher.h" #include "main.h" #include "status.h" +#include "i18n.h" struct cmp_help_context_s { PKT_signature *sig; @@ -148,6 +149,7 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest ) MPI result = NULL; int rc=0; struct cmp_help_context_s ctx; + u32 cur_time; if( pkc->version == 4 && pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { log_info("this is a PGP generated " @@ -158,6 +160,21 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest ) if( pkc->timestamp > sig->timestamp ) return G10ERR_TIME_CONFLICT; /* pubkey newer that signature */ + cur_time = make_timestamp(); + if( pkc->timestamp > cur_time ) { + log_info(_("public key created in future (time warp or clock problem)\n")); + return G10ERR_TIME_CONFLICT; + } + + if( pkc->valid_days && add_days_to_timestamp(pkc->timestamp, + pkc->valid_days) < cur_time ) { + log_info(_("warning: signature key expired %s\n"), strtimestamp( + add_days_to_timestamp(pkc->timestamp, + pkc->valid_days))); + write_status(STATUS_SIGEXPIRED); + } + + if( (rc=check_digest_algo(sig->digest_algo)) ) return rc; if( (rc=check_pubkey_algo(sig->pubkey_algo)) ) diff --git a/g10/sign.c b/g10/sign.c index 2505526ce..9245f67f7 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -98,7 +98,22 @@ hash_for(int pubkey_algo ) return DEFAULT_DIGEST_ALGO; } +static int +only_old_style( SKC_LIST skc_list ) +{ + SKC_LIST skc_rover = NULL; + int old_style = 0; + /* if there are only old style capable key we use the old sytle */ + for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) { + PKT_secret_cert *skc = skc_rover->skc; + if( skc->pubkey_algo == PUBKEY_ALGO_RSA && skc->version < 4 ) + old_style = 1; + else + return 0; + } + return old_style; +} /**************** * Sign the files whose names are in FILENAME. @@ -131,6 +146,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, SKC_LIST skc_list = NULL; SKC_LIST skc_rover = NULL; int multifile = 0; + int old_style = opt.rfc1991; + memset( &afx, 0, sizeof afx); memset( &zfx, 0, sizeof zfx); @@ -151,6 +168,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, if( (rc=build_skc_list( locusr, &skc_list, 1, 1 )) ) goto leave; + if( !old_style ) + old_style = only_old_style( skc_list ); if( encrypt ) { if( (rc=build_pkc_list( remusr, &pkc_list, 2 )) ) goto leave; @@ -204,11 +223,13 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, iobuf_push_filter( out, encrypt_filter, &efx ); } - if( opt.compress && !outfile ) + if( opt.compress && !outfile ) { + if( old_style ) + zfx.algo = 1; iobuf_push_filter( out, compress_filter, &zfx ); + } - - if( !detached && !opt.rfc1991 ) { + if( !detached && !old_style ) { /* loop over the secret certificates and build headers */ for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) { PKT_secret_cert *skc; @@ -439,6 +460,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) int rc = 0; SKC_LIST skc_list = NULL; SKC_LIST skc_rover = NULL; + int old_style = opt.rfc1991; memset( &afx, 0, sizeof afx); memset( &tfx, 0, sizeof tfx); @@ -446,6 +468,8 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) if( (rc=build_skc_list( locusr, &skc_list, 1, 1 )) ) goto leave; + if( !old_style ) + old_style = only_old_style( skc_list ); /* prepare iobufs */ if( !(inp = iobuf_open(fname)) ) { @@ -469,9 +493,9 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) goto leave; } - /* FIXME: This stuff is not correct if mutliple hash algos are used*/ + /* FIXME: This stuff is not correct if multiple hash algos are used*/ iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----\n" ); - if( opt.rfc1991 + if( old_style || (opt.def_digest_algo?opt.def_digest_algo:DEFAULT_DIGEST_ALGO) == DIGEST_ALGO_MD5 ) iobuf_writestr(out, "\n" ); diff --git a/g10/status.c b/g10/status.c index 2546626ba..35367fbba 100644 --- a/g10/status.c +++ b/g10/status.c @@ -53,6 +53,7 @@ write_status_text( int no, const char *text) case STATUS_LEAVE : s = "LEAVE\n"; break; case STATUS_ABORT : s = "ABORT\n"; break; case STATUS_GOODSIG: s = "GOODSIG\n"; break; + case STATUS_SIGEXPIRED: s = "SIGEXPIRED\n"; break; case STATUS_BADSIG : s = "BADSIG\n"; break; case STATUS_ERRSIG : s = "ERRSIG\n"; break; case STATUS_BADARMOR : s = "BADARMOR\n"; break; diff --git a/g10/status.h b/g10/status.h index 6b0950f5f..8b5ffdacd 100644 --- a/g10/status.h +++ b/g10/status.h @@ -33,7 +33,7 @@ #define STATUS_BADARMOR 7 #define STATUS_RSA_OR_IDEA 8 - +#define STATUS_SIGEXPIRED 9 /*-- status.c --*/ void set_status_fd( int fd ); diff --git a/g10/trustdb.c b/g10/trustdb.c index bb4942c41..6ee436128 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1705,7 +1705,7 @@ check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel ) TRUSTREC rec; unsigned trustlevel = TRUST_UNKNOWN; int rc=0; - int cur_time; + u32 cur_time; if( DBG_TRUST ) log_info("check_trust() called.\n"); diff --git a/include/cipher.h b/include/cipher.h index 8544ee2e0..972b2ffe7 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -78,7 +78,9 @@ typedef struct { int bufcount; int secure; FILE *debug; + int guard1; struct md_digest_list_s *list; + int guard2; } *MD_HANDLE; diff --git a/mpi/ChangeLog b/mpi/ChangeLog index 15da105fe..0519495c9 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -1,3 +1,7 @@ +Thu Jun 25 11:50:01 1998 Werner Koch (wk@isil.d.shuttle.de) + + * mips3/*.S: New + Mon May 18 13:47:06 1998 Werner Koch (wk@isil.d.shuttle.de) * config.links: split mpih-shift into mpih-[lr]shift and diff --git a/mpi/mips3/distfiles b/mpi/mips3/distfiles new file mode 100644 index 000000000..b88f4f869 --- /dev/null +++ b/mpi/mips3/distfiles @@ -0,0 +1,9 @@ +README +mpih-add1.S +mpih-sub1.S +mpih-mul1.S +mpih-mul2.S +mpih-mul3.S +mpih-lshift.S +mpih-rshift.S + diff --git a/mpi/mips3/mpih-add1.S b/mpi/mips3/mpih-add1.S new file mode 100644 index 000000000..7ac5f38bd --- /dev/null +++ b/mpi/mips3/mpih-add1.S @@ -0,0 +1,122 @@ +/* mips3 add_n -- Add two limb vectors of the same length > 0 and store + * sum in a third limb vector. + * Copyright (C) 1995, 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 + */ + + +/******************* + * mpi_limb_t + * mpihelp_add_n( mpi_ptr_t res_ptr, ($4) + * mpi_ptr_t s1_ptr, ($5) + * mpi_ptr_t s2_ptr, ($6) + * mpi_size_t size) ($7) + */ + + .text + .align 2 + .globl mpihelp_add_n + .ent mpihelp_add_n +mpihelp_add_n: + .set noreorder + .set nomacro + + ld $10,0($5) + ld $11,0($6) + + daddiu $7,$7,-1 + and $9,$7,4-1 # number of limbs in first loop + beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop + move $2,$0 + + dsubu $7,$7,$9 + +.Loop0: daddiu $9,$9,-1 + ld $12,8($5) + daddu $11,$11,$2 + ld $13,8($6) + sltu $8,$11,$2 + daddu $11,$10,$11 + sltu $2,$11,$10 + sd $11,0($4) + or $2,$2,$8 + + daddiu $5,$5,8 + daddiu $6,$6,8 + move $10,$12 + move $11,$13 + bne $9,$0,.Loop0 + daddiu $4,$4,8 + +.L0: beq $7,$0,.Lend + nop + +.Loop: daddiu $7,$7,-4 + + ld $12,8($5) + daddu $11,$11,$2 + ld $13,8($6) + sltu $8,$11,$2 + daddu $11,$10,$11 + sltu $2,$11,$10 + sd $11,0($4) + or $2,$2,$8 + + ld $10,16($5) + daddu $13,$13,$2 + ld $11,16($6) + sltu $8,$13,$2 + daddu $13,$12,$13 + sltu $2,$13,$12 + sd $13,8($4) + or $2,$2,$8 + + ld $12,24($5) + daddu $11,$11,$2 + ld $13,24($6) + sltu $8,$11,$2 + daddu $11,$10,$11 + sltu $2,$11,$10 + sd $11,16($4) + or $2,$2,$8 + + ld $10,32($5) + daddu $13,$13,$2 + ld $11,32($6) + sltu $8,$13,$2 + daddu $13,$12,$13 + sltu $2,$13,$12 + sd $13,24($4) + or $2,$2,$8 + + daddiu $5,$5,32 + daddiu $6,$6,32 + + bne $7,$0,.Loop + daddiu $4,$4,32 + +.Lend: daddu $11,$11,$2 + sltu $8,$11,$2 + daddu $11,$10,$11 + sltu $2,$11,$10 + sd $11,0($4) + j $31 + or $2,$2,$8 + + .end mpihelp_add_n + diff --git a/mpi/mips3/mpih-lshift.S b/mpi/mips3/mpih-lshift.S new file mode 100644 index 000000000..37e9a5e1b --- /dev/null +++ b/mpi/mips3/mpih-lshift.S @@ -0,0 +1,95 @@ +/* mips3 lshift + * Copyright (C) 1995, 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 + */ + +/******************* + * mpi_limb_t + * mpihelp_lshift( mpi_ptr_t wp, ($4) + * mpi_ptr_t up, ($5) + * mpi_size_t usize, ($6) + * unsigned cnt) ($7) + */ + + .text + .align 2 + .globl mpihelp_lshift + .ent mpihelp_lshift +mpihelp_lshift: + .set noreorder + .set nomacro + + dsll $2,$6,3 + daddu $5,$5,$2 # make r5 point at end of src + ld $10,-8($5) # load first limb + dsubu $13,$0,$7 + daddu $4,$4,$2 # make r4 point at end of res + daddiu $6,$6,-1 + and $9,$6,4-1 # number of limbs in first loop + beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop + dsrl $2,$10,$13 # compute function result + + dsubu $6,$6,$9 + +.Loop0: ld $3,-16($5) + daddiu $4,$4,-8 + daddiu $5,$5,-8 + daddiu $9,$9,-1 + dsll $11,$10,$7 + dsrl $12,$3,$13 + move $10,$3 + or $8,$11,$12 + bne $9,$0,.Loop0 + sd $8,0($4) + +.L0: beq $6,$0,.Lend + nop + +.Loop: ld $3,-16($5) + daddiu $4,$4,-32 + daddiu $6,$6,-4 + dsll $11,$10,$7 + dsrl $12,$3,$13 + + ld $10,-24($5) + dsll $14,$3,$7 + or $8,$11,$12 + sd $8,24($4) + dsrl $9,$10,$13 + + ld $3,-32($5) + dsll $11,$10,$7 + or $8,$14,$9 + sd $8,16($4) + dsrl $12,$3,$13 + + ld $10,-40($5) + dsll $14,$3,$7 + or $8,$11,$12 + sd $8,8($4) + dsrl $9,$10,$13 + + daddiu $5,$5,-32 + or $8,$14,$9 + bgtz $6,.Loop + sd $8,0($4) + +.Lend: dsll $8,$10,$7 + j $31 + sd $8,-8($4) + .end mpihelp_lshift diff --git a/mpi/mips3/mpih-mul1.S b/mpi/mips3/mpih-mul1.S new file mode 100644 index 000000000..fd349ee97 --- /dev/null +++ b/mpi/mips3/mpih-mul1.S @@ -0,0 +1,87 @@ +/* mips3 mpih-mul1.S -- Multiply a limb vector with a limb and store + * the result in a second limb vector. + * Copyright (C) 1992, 1994, 1995, 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 + */ + + +/******************* + * mpi_limb_t + * mpihelp_mul_1( mpi_ptr_t res_ptr, (r4) + * mpi_ptr_t s1_ptr, (r5) + * mpi_size_t s1_size, (r6) + * mpi_limb_t s2_limb) (r7) + */ + + .text + .align 4 + .globl mpihelp_mul_1 + .ent mpihelp_mul_1 +mpihelp_mul_1: + .set noreorder + .set nomacro + + # warm up phase 0 + ld $8,0($5) + + # warm up phase 1 + daddiu $5,$5,8 + dmultu $8,$7 + + daddiu $6,$6,-1 + beq $6,$0,$LC0 + move $2,$0 # zero cy2 + + daddiu $6,$6,-1 + beq $6,$0,$LC1 + ld $8,0($5) # load new s1 limb as early as possible + +Loop: mflo $10 + mfhi $9 + daddiu $5,$5,8 + daddu $10,$10,$2 # add old carry limb to low product limb + dmultu $8,$7 + ld $8,0($5) # load new s1 limb as early as possible + daddiu $6,$6,-1 # decrement loop counter + sltu $2,$10,$2 # carry from previous addition -> $2 + sd $10,0($4) + daddiu $4,$4,8 + bne $6,$0,Loop + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 1 +$LC1: mflo $10 + mfhi $9 + daddu $10,$10,$2 + sltu $2,$10,$2 + dmultu $8,$7 + sd $10,0($4) + daddiu $4,$4,8 + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 0 +$LC0: mflo $10 + mfhi $9 + daddu $10,$10,$2 + sltu $2,$10,$2 + sd $10,0($4) + j $31 + daddu $2,$9,$2 # add high product limb and carry from addition + + .end mpihelp_mul_1 + diff --git a/mpi/mips3/mpih-mul2.S b/mpi/mips3/mpih-mul2.S new file mode 100644 index 000000000..1474b4f06 --- /dev/null +++ b/mpi/mips3/mpih-mul2.S @@ -0,0 +1,99 @@ +/* MIPS3 addmul_1 -- Multiply a limb vector with a single limb and + * add the product to a second limb vector. + * Copyright (C) 1992, 1994, 1995, 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 + */ + + +/******************* + * mpi_limb_t + * mpihelp_addmul_1( mpi_ptr_t res_ptr, (r4) + * mpi_ptr_t s1_ptr, (r5) + * mpi_size_t s1_size, (r6) + * mpi_limb_t s2_limb) (r7) + */ + + .text + .align 4 + .globl mpihelp_addmul_1 + .ent mpihelp_addmul_1 +mpihelp_addmul_1: + .set noreorder + .set nomacro + + # warm up phase 0 + ld $8,0($5) + + # warm up phase 1 + daddiu $5,$5,8 + dmultu $8,$7 + + daddiu $6,$6,-1 + beq $6,$0,$LC0 + move $2,$0 # zero cy2 + + daddiu $6,$6,-1 + beq $6,$0,$LC1 + ld $8,0($5) # load new s1 limb as early as possible + +Loop: ld $10,0($4) + mflo $3 + mfhi $9 + daddiu $5,$5,8 + daddu $3,$3,$2 # add old carry limb to low product limb + dmultu $8,$7 + ld $8,0($5) # load new s1 limb as early as possible + daddiu $6,$6,-1 # decrement loop counter + sltu $2,$3,$2 # carry from previous addition -> $2 + daddu $3,$10,$3 + sltu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + daddiu $4,$4,8 + bne $6,$0,Loop + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 1 +$LC1: ld $10,0($4) + mflo $3 + mfhi $9 + daddu $3,$3,$2 + sltu $2,$3,$2 + dmultu $8,$7 + daddu $3,$10,$3 + sltu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + daddiu $4,$4,8 + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 0 +$LC0: ld $10,0($4) + mflo $3 + mfhi $9 + daddu $3,$3,$2 + sltu $2,$3,$2 + daddu $3,$10,$3 + sltu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + j $31 + daddu $2,$9,$2 # add high product limb and carry from addition + + .end mpihelp_addmul_1 + diff --git a/mpi/mips3/mpih-mul3.S b/mpi/mips3/mpih-mul3.S new file mode 100644 index 000000000..4616732f5 --- /dev/null +++ b/mpi/mips3/mpih-mul3.S @@ -0,0 +1,99 @@ +/* MIPS3 submul_1 -- Multiply a limb vector with a single limb and + * subtract the product from a second limb vector. + * Copyright (C) 1992, 1994, 1995, 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 + */ + + +/******************* + * mpi_limb_t + * mpihelp_submul_1( mpi_ptr_t res_ptr, (r4) + * mpi_ptr_t s1_ptr, (r5) + * mpi_size_t s1_size, (r6) + * mpi_limb_t s2_limb) (r7) + */ + + .text + .align 4 + .globl mpihelp_submul_1 + .ent mpihelp_submul_1 +mpihelp_submul_1: + .set noreorder + .set nomacro + + # warm up phase 0 + ld $8,0($5) + + # warm up phase 1 + daddiu $5,$5,8 + dmultu $8,$7 + + daddiu $6,$6,-1 + beq $6,$0,$LC0 + move $2,$0 # zero cy2 + + daddiu $6,$6,-1 + beq $6,$0,$LC1 + ld $8,0($5) # load new s1 limb as early as possible + +Loop: ld $10,0($4) + mflo $3 + mfhi $9 + daddiu $5,$5,8 + daddu $3,$3,$2 # add old carry limb to low product limb + dmultu $8,$7 + ld $8,0($5) # load new s1 limb as early as possible + daddiu $6,$6,-1 # decrement loop counter + sltu $2,$3,$2 # carry from previous addition -> $2 + dsubu $3,$10,$3 + sgtu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + daddiu $4,$4,8 + bne $6,$0,Loop + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 1 +$LC1: ld $10,0($4) + mflo $3 + mfhi $9 + daddu $3,$3,$2 + sltu $2,$3,$2 + dmultu $8,$7 + dsubu $3,$10,$3 + sgtu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + daddiu $4,$4,8 + daddu $2,$9,$2 # add high product limb and carry from addition + + # cool down phase 0 +$LC0: ld $10,0($4) + mflo $3 + mfhi $9 + daddu $3,$3,$2 + sltu $2,$3,$2 + dsubu $3,$10,$3 + sgtu $10,$3,$10 + daddu $2,$2,$10 + sd $3,0($4) + j $31 + daddu $2,$9,$2 # add high product limb and carry from addition + + .end mpihelp_submul_1 + diff --git a/mpi/mips3/mpih-rshift.S b/mpi/mips3/mpih-rshift.S new file mode 100644 index 000000000..7bc084500 --- /dev/null +++ b/mpi/mips3/mpih-rshift.S @@ -0,0 +1,93 @@ +/* mips3 rshift + * Copyright (C) 1995, 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 + */ + +/******************* + * mpi_limb_t + * mpihelp_rshift( mpi_ptr_t wp, ($4) + * mpi_ptr_t up, ($5) + * mpi_size_t usize, ($6) + * unsigned cnt) ($7) + */ + + .text + .align 2 + .globl mpihelp_rshift + .ent mpihelp_rshift +mpihelp_rshift: + .set noreorder + .set nomacro + + ld $10,0($5) # load first limb + dsubu $13,$0,$7 + daddiu $6,$6,-1 + and $9,$6,4-1 # number of limbs in first loop + beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop + dsll $2,$10,$13 # compute function result + + dsubu $6,$6,$9 + +.Loop0: ld $3,8($5) + daddiu $4,$4,8 + daddiu $5,$5,8 + daddiu $9,$9,-1 + dsrl $11,$10,$7 + dsll $12,$3,$13 + move $10,$3 + or $8,$11,$12 + bne $9,$0,.Loop0 + sd $8,-8($4) + +.L0: beq $6,$0,.Lend + nop + +.Loop: ld $3,8($5) + daddiu $4,$4,32 + daddiu $6,$6,-4 + dsrl $11,$10,$7 + dsll $12,$3,$13 + + ld $10,16($5) + dsrl $14,$3,$7 + or $8,$11,$12 + sd $8,-32($4) + dsll $9,$10,$13 + + ld $3,24($5) + dsrl $11,$10,$7 + or $8,$14,$9 + sd $8,-24($4) + dsll $12,$3,$13 + + ld $10,32($5) + dsrl $14,$3,$7 + or $8,$11,$12 + sd $8,-16($4) + dsll $9,$10,$13 + + daddiu $5,$5,32 + or $8,$14,$9 + bgtz $6,.Loop + sd $8,-8($4) + +.Lend: dsrl $8,$10,$7 + j $31 + sd $8,0($4) + .end mpihelp_rshift + diff --git a/mpi/mips3/mpih-sub1.S b/mpi/mips3/mpih-sub1.S new file mode 100644 index 000000000..f4ad4c999 --- /dev/null +++ b/mpi/mips3/mpih-sub1.S @@ -0,0 +1,123 @@ +/* mips3 sub_n -- Subtract two limb vectors of the same length > 0 and + * store difference in a third limb vector. + * Copyright (C) 1995, 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 + */ + + +/******************* + * mpi_limb_t + * mpihelp_sub_n( mpi_ptr_t res_ptr, (r4) + * mpi_ptr_t s1_ptr, (r5) + * mpi_ptr_t s2_ptr, (r6) + * mpi_size_t size) (r7) + */ + + + .text + .align 2 + .globl mpihelp_sub_n + .ent mpihelp_sub_n +mpihelp_sub_n: + .set noreorder + .set nomacro + + ld $10,0($5) + ld $11,0($6) + + daddiu $7,$7,-1 + and $9,$7,4-1 # number of limbs in first loop + beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop + move $2,$0 + + dsubu $7,$7,$9 + +.Loop0: daddiu $9,$9,-1 + ld $12,8($5) + daddu $11,$11,$2 + ld $13,8($6) + sltu $8,$11,$2 + dsubu $11,$10,$11 + sltu $2,$10,$11 + sd $11,0($4) + or $2,$2,$8 + + daddiu $5,$5,8 + daddiu $6,$6,8 + move $10,$12 + move $11,$13 + bne $9,$0,.Loop0 + daddiu $4,$4,8 + +.L0: beq $7,$0,.Lend + nop + +.Loop: daddiu $7,$7,-4 + + ld $12,8($5) + daddu $11,$11,$2 + ld $13,8($6) + sltu $8,$11,$2 + dsubu $11,$10,$11 + sltu $2,$10,$11 + sd $11,0($4) + or $2,$2,$8 + + ld $10,16($5) + daddu $13,$13,$2 + ld $11,16($6) + sltu $8,$13,$2 + dsubu $13,$12,$13 + sltu $2,$12,$13 + sd $13,8($4) + or $2,$2,$8 + + ld $12,24($5) + daddu $11,$11,$2 + ld $13,24($6) + sltu $8,$11,$2 + dsubu $11,$10,$11 + sltu $2,$10,$11 + sd $11,16($4) + or $2,$2,$8 + + ld $10,32($5) + daddu $13,$13,$2 + ld $11,32($6) + sltu $8,$13,$2 + dsubu $13,$12,$13 + sltu $2,$12,$13 + sd $13,24($4) + or $2,$2,$8 + + daddiu $5,$5,32 + daddiu $6,$6,32 + + bne $7,$0,.Loop + daddiu $4,$4,32 + +.Lend: daddu $11,$11,$2 + sltu $8,$11,$2 + dsubu $11,$10,$11 + sltu $2,$10,$11 + sd $11,0($4) + j $31 + or $2,$2,$8 + + .end mpihelp_sub_n + n diff --git a/po/de.po b/po/de.po index ce6b9b073..3b2eed1ea 100644 --- a/po/de.po +++ b/po/de.po @@ -563,10 +563,6 @@ msgstr "" " (1) ElGamal wird empfohlen.\n" " (2) DSA kann nur für Signaturen verwendet werden.\n" -#: g10/keygen.c:305 -msgid " (3) RSA cannot be used in the U.S.\n" -msgstr " (3) RSA darf in den USA nicht benutzt werden\n" - #: g10/keygen.c:314 msgid "Your selection? (1,2,3) " msgstr "Ihre Auswahl? (1,2,3) " @@ -575,10 +571,6 @@ msgstr "Ihre Auswahl? (1,2,3) " msgid "Your selection? (1,2) " msgstr "Ihre Auswahl? (1,2) " -#: g10/keygen.c:330 -msgid "Sorry; DSA is not yet supported.\n" -msgstr "Pardon; DSA wird noch nicht unterstützt.\n" - #: g10/keygen.c:343 msgid "" "About to generate a new %s keypair.\n" diff --git a/tools/mk-tdata b/tools/mk-tdata index 85e567d45..85e20d812 100755 Binary files a/tools/mk-tdata and b/tools/mk-tdata differ diff --git a/util/secmem.c b/util/secmem.c index b1d86ebf1..ab4503db1 100644 --- a/util/secmem.c +++ b/util/secmem.c @@ -71,7 +71,7 @@ lock_pool( void *p, size_t n ) uid_t uid; int err; - err = mlock( p, n ); + err = -1; mlock( p, n ); if( err && errno ) err = errno; diff --git a/zlib/Makefile b/zlib/Makefile index e3aa756ed..6f76a64ea 100644 --- a/zlib/Makefile +++ b/zlib/Makefile @@ -91,7 +91,7 @@ POSUB = po RANLIB = ranlib USE_INCLUDED_LIBINTL = yes USE_NLS = yes -VERSION = 0.2.19b +VERSION = 0.2.19c ZLIBS = l = @@ -121,7 +121,7 @@ LIBRARIES = $(noinst_LIBRARIES) DEFS = -DHAVE_CONFIG_H -I. -I$(srcdir) -I.. CPPFLAGS = LDFLAGS = -LIBS = -ldl -lz +LIBS = -lz libzlib_a_LIBADD = libzlib_a_OBJECTS = adler32.o compress.o crc32.o gzio.o uncompr.o \ deflate.o trees.o zutil.o inflate.o infblock.o inftrees.o infcodes.o \