diff --git a/NEWS b/NEWS index 0a8ffa190..1f6fc7954 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,5 @@ Noteworthy changes in version 0.2.x ------------------------------------ +*********************************** * nearly doubled the speed of the ElGamal signature verification. @@ -7,9 +7,11 @@ Noteworthy changes in version 0.2.x * assembler stuff for Pentium; gives about 15% better perfomance. + * fixed a lot of bugs. + Noteworthy changes in version 0.2.3 ------------------------------------ +*********************************** * Found a bug in the calculation of ELG fingerprints. This is now fixed, but all existing fingerprints and keyids for ELG keys diff --git a/TODO b/TODO index 1b63c1ef8..baaa1412f 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,8 @@ - * add assembler support for more CPUs. (work, but easy) * improve iobuf by reading more than one byte at once, this shoud espceially done for the buffer in the chain. * add a way to difference between errors and eof in the underflow/flush function of iobuf. - * check that all output is filtered when displayed. * add checking of armor trailers * look for a way to reuse RSA signatures * remove all "Fixmes" diff --git a/VERSION b/VERSION index ccd3d1a11..abd410582 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.3x +0.2.4 diff --git a/checks/checkit b/checks/checkit new file mode 100755 index 000000000..3ffce35c4 --- /dev/null +++ b/checks/checkit @@ -0,0 +1,184 @@ +#!/bin/bash +# Script for G10 testing +#--------------------------------------------------------- + +#-------------------------------- +#------ constants --------------- +#-------------------------------- + +usrname1="one" +usrpass1="def" +usrname2="two" +usrpass2="abc" +plain_files="plain-1 plain-2 plain-3" +data_files="" +exp_files="" +last_command="" + + +#-------------------------------- +#------ utility functions ------- +#-------------------------------- + +fatal () { + echo "$pgmname: fatal:" $* >&2 + exit 1; +} + +error () { + echo "$pgmname:" $* >&2 + echo "($last_command) failed" >&2 + exit 1 +} + +info () { + echo "$pgmname:" $* >&2 +} + +chdir () { + cd $1 || fatal "cannot cd to $1" +} + +run_g10 () { + last_command="HOME=. ../g10/g10 $*" + eval HOME=. ../g10/g10 $* +} + +#-------------------------------- +#-------- main program ---------- +#-------------------------------- + +set -e +pgmname=$(basename $0) + +# some checks +[ -d "./.g10" ] || fatal "subdirectory .g10 missing" +for i in $plain_files; do + [ -f $i ] || fatal "$i: missing" +done +for i in $exp_files; do + [ -f $i ] || fatal "$i: script missing" +done + +cat <./.g10/options +no-greeting +no-secmem-warning +batch +EOF + +# print the G10 version +run_g10 --version + +info Checking cleartext signatures +# There is a minor glitch, which appends a lf to the cleartext. +# I do not consider that a bug, but I have to use the head .. mimic. +# It is not clear what should happen to leading LFs, we must +# change the defintion of cleartext, so that only 1 empty line +# must follow the headers, but some specs say: any number of empty lines .. +# clean-sat removes leading LFs +# I know that this does not work for random data files (due to large lines +# or what ever) - I hope we can live with it. +for i in $plain_files; do + echo "$usrpass1" | run_g10 --passphrase-fd 0 -sat -o x --yes $i || error "g10 failed: $?" + run_g10 -o y --yes x || error "g10 failed: $?" + ../tools/clean-sat < $i > z + head -c $[ $(cat y | wc -c) - 1 ] y | diff - z || error "$i: mismatch" +done + +info Creating some random data files +for i in 500 9000 32000 80000; do + head -c $i /dev/urandom >data-$i + data_files="$data_files data-$i" +done + +info Checking armored signatures +for i in $plain_files $data_files ; do + echo "$usrpass1" | run_g10 --passphrase-fd 0 -sa -o x --yes $i || error "g10 failed: $?" + run_g10 -o y --yes x || error "g10 failed: $?" + cmp $i y || error "$i: mismatch" +done + +info Checking signatures +for i in $plain_files $data_files; do + echo "$usrpass1" | run_g10 --passphrase-fd 0 -s -o x --yes $i || error "g10 failed: $?" + run_g10 -o y --yes x || error "g10 failed: $?" + cmp $i y || error "$i: mismatch" +done + + +info Checking armored encryption +for i in $plain_files $data_files ; do + run_g10 -ea -o x --yes -r "$usrname2" $i || error "g10 failed: $?" + run_g10 -o y --yes x || error "g10 failed: $?" + cmp $i y || error "$i: mismatch" +done + +info Checking armored encryption with a pipe +for i in $plain_files $data_files ; do + run_g10 -ea --yes -r "$usrname2" < $i | tee x \ + | run_g10 -o y --yes || error "g10 failed: $?" + cmp $i y || error "$i: mismatch" + run_g10 --yes < x > y || error "g10 failed: $?" + cmp $i y || error "$i: mismatch" +done + +info Checking encryption +for i in $plain_files $data_files ; do + run_g10 -e -o x --yes -r "$usrname2" $i || error "g10 failed: $?" + run_g10 -o y --yes x || error "g10 failed: $?" + cmp $i y || error "$i: mismatch" +done + +info Checking encryption with a pipe +for i in $plain_files $data_files ; do + run_g10 -e --yes -r "$usrname2" < $i \ + | run_g10 --yes > y || error "g10 failed: $?" + cmp $i y || error "$i: mismatch" +done + + +info Checking signing and encryption +for i in $plain_files $data_files ; do + echo "$usrpass1" \ + | run_g10 --passphrase-fd 0 -se -o x --yes -r "$usrname2" $i + run_g10 -o y --yes x || error "g10 failed: $?" + cmp $i y || error "$i: mismatch" +done + +info Checking armored signing and encryption +for i in $plain_files $data_files ; do + echo "$usrpass1" \ + | run_g10 --passphrase-fd 0 -sae -o x --yes -r "$usrname2" $i || error "g10 failed: $?" + run_g10 -o y --yes x || error "g10 failed: $?" + cmp $i y || error "$i: mismatch" +done + + +info Checking armored detached signatures +for i in $plain_files $data_files ; do + echo "$usrpass1" | run_g10 --passphrase-fd 0 -sab -o x --yes $i || error "g10 failed: $?" + run_g10 -o /dev/null --yes x <$i || error "$i: bad signature" +done + +info Checking detached signatures +for i in $plain_files $data_files ; do + echo "$usrpass1" | run_g10 --passphrase-fd 0 -sb -o x --yes $i || error "g10 failed: $?" + run_g10 -o /dev/null --yes x <$i || error "$i: bad signature" +done + + +info Checking detached signatures of multiple files +i="$plain_files $data_files" +echo "$usrpass1" | run_g10 --passphrase-fd 0 -sb -o x --yes $i || error "g10 failed: $?" +cat $i | run_g10 -o /dev/null --yes x || error "$i: bad signature" + +info Checking armored detached signatures of multiple files +i="$plain_files $data_files" +echo "$usrpass1" | run_g10 --passphrase-fd 0 -sab -o x --yes $i || error "g10 failed: $?" +cat $i | run_g10 -o /dev/null --yes x || error "$i: bad signature" + +rm $data_files x y z + +info "All tests passed." +exit 0 + diff --git a/checks/distfiles b/checks/distfiles new file mode 100644 index 000000000..d7edce90a --- /dev/null +++ b/checks/distfiles @@ -0,0 +1 @@ +checkit plain-1 plain-2 plain-3 diff --git a/checks/plain-1 b/checks/plain-1 new file mode 100644 index 000000000..f336a1228 --- /dev/null +++ b/checks/plain-1 @@ -0,0 +1,23 @@ + + +Name Groß-Bartloff + +

+Der Name Urkundlich wird das +Dorf bis zur Reformation stets +Nimmt man an, daß die urkundliche, älteste Bezeichnung Bartorf die +ursprüngliche ist und nicht die mundartliche Bartloff, so könnte der +Name gut gedeutet werden als Dorf an der Vorwort +

+Der Wert einer Ortschronik ist offenbar und bedarf keiner Erörterung. +Mit Ausbruch des Weltkrieges_, inmitten der gewaltigen Geschehnisse, fühlte +der Klerus_ unseres_ Eichs_feldes_ das_ mehr wie früher und so +erstarkte das_ Streben, eine solche Orts_geschichte zu scahffen, um +unseren Nachkommen zu berichten, was_ auch die kleinsten Dörfer in +der großen Zeit geleistet, erlebt und erlitten haben. +

+Und so begann auch ich im Dezember 1914, den ????????? +Stoff, wo immer ich ihn auch nur so spärlich finden konnte, zu +sammeln, ich befragte zunächst emsig die ältesten Leute, +durchforschte sodann das ganze Pfarrarchiv, das Schulzenarchiv +beider Pfarrdörfer, das Kommissariats_archiv zu Heiligenstadt, +endlich auch 1916 das Staats_archiv zu Magdeburg. Selbstverständlich +arbeitete ich auch die einschlägige Literatur durch. Gar viele Zeit +und Mühe hat es_ gekostet um nach mehr als 8 Jahren die Ortschronik von +Großbartloff und vom Filialdorf Wilbich gesondert zu schaffen. +

+Großbartloff, den 23. März 1923. +

+ + + + + +

+

Literatur:

+1) Joh. Wolf: Politische Geschichte des Eichsf. Gött. 1792 und +Löffler 1921. 2) K. Geschichte, Wolf 1816 Gött. 3) Knieb: Gesch. +der Ref. u. Gegenref??? + + + + + + + + + + + diff --git a/checks/plain-3 b/checks/plain-3 new file mode 100644 index 000000000..8a6e6b6a7 --- /dev/null +++ b/checks/plain-3 @@ -0,0 +1 @@ +Dies ist eine einfache Zeile ohne LF am Ende. \ No newline at end of file diff --git a/cipher/elgamal.c b/cipher/elgamal.c index 13b8579fe..6defbc5f8 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -321,6 +321,16 @@ elg_verify(MPI a, MPI b, MPI input, ELG_public_key *pkey ) t2 = mpi_alloc( mpi_get_nlimbs(a) ); #if 0 + /* t1 = (y^a mod p) * (a^b mod p) mod p */ + mpi_powm( t1, pkey->y, a, pkey->p ); + mpi_powm( t2, a, b, pkey->p ); + mpi_mulm( t1, t1, t2, pkey->p ); + + /* t2 = g ^ input mod p */ + mpi_powm( t2, pkey->g, input, pkey->p ); + + rc = !mpi_cmp( t1, t2 ); + #elif 0 /* t1 = (y^a mod p) * (a^b mod p) mod p */ base[0] = pkey->y; exp[0] = a; base[1] = a; exp[1] = b; diff --git a/cipher/md.c b/cipher/md.c index c89c8bb95..c87f3286b 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -28,7 +28,7 @@ #include "errors.h" -static FILE *dumpfp; +/*static FILE *dumpfp;*/ /**************** * Open a message digest handle for use with algorithm ALGO. @@ -40,14 +40,16 @@ md_open( int algo, int secure ) { MD_HANDLE hd; + #if 0 if( !dumpfp ) dumpfp = fopen("md.out", "w"); if( !dumpfp ) BUG(); { int i; for(i=0; i < 16; i++ ) putc('\xff', dumpfp ); } - + #endif hd = secure ? m_alloc_secure_clear( sizeof *hd ) : m_alloc_clear( sizeof *hd ); + hd->secure = secure; if( algo ) md_enable( hd, algo ); return hd; @@ -78,9 +80,9 @@ md_copy( MD_HANDLE a ) { MD_HANDLE b; - { int i; for(i=0; i < 16; i++ ) putc('\xee', dumpfp ); } - b = m_is_secure(a)? m_alloc_secure( sizeof *b ) - : m_alloc( sizeof *b ); + /*{ int i; for(i=0; i < 16; i++ ) putc('\xee', dumpfp ); }*/ + b = a->secure ? m_alloc_secure( sizeof *b ) + : m_alloc( sizeof *b ); memcpy( b, a, sizeof *a ); return b; } @@ -98,10 +100,10 @@ md_close(MD_HANDLE a) void md_write( MD_HANDLE a, byte *inbuf, size_t inlen) { - if( a->bufcount && fwrite(a->buffer, a->bufcount, 1, dumpfp ) != 1 ) + /* if( a->bufcount && fwrite(a->buffer, a->bufcount, 1, dumpfp ) != 1 ) BUG(); if( inlen && fwrite(inbuf, inlen, 1, dumpfp ) != 1 ) - BUG(); + BUG(); */ if( a->use_rmd160 ) { rmd160_write( &a->rmd160, a->buffer, a->bufcount ); rmd160_write( &a->rmd160, inbuf, inlen ); @@ -124,7 +126,7 @@ md_final(MD_HANDLE a) { if( a->bufcount ) md_write( a, NULL, 0 ); - { int i; for(i=0; i < 16; i++ ) putc('\xcc', dumpfp ); } + /*{ int i; for(i=0; i < 16; i++ ) putc('\xcc', dumpfp ); }*/ if( a->use_rmd160 ) { byte *p; rmd160_final( &a->rmd160 ); diff --git a/cipher/md.h b/cipher/md.h index 8a7886d03..7a710e795 100644 --- a/cipher/md.h +++ b/cipher/md.h @@ -36,6 +36,7 @@ typedef struct { MD5_CONTEXT md5; byte buffer[MD_BUFFER_SIZE]; /* primary buffer */ int bufcount; + int secure; } *MD_HANDLE; @@ -55,6 +56,6 @@ 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 ); - +#define md_is_secure(a) ((a)->secure) #endif /*G10_MD_H*/ diff --git a/g10/OPTIONS b/g10/OPTIONS index 4f21a9e21..37c6ec485 100644 --- a/g10/OPTIONS +++ b/g10/OPTIONS @@ -154,7 +154,10 @@ dry-run keyring filename -# add this filename to the list of keyrings +# add this filename to the list of keyrings. +# If the filename begins with a tilde and a slash, these are replaced +# by the HOME directory. If the filename does not contain a slash, it +# is assumed to be in "~/.g10" local-user user-string # use this user-string to sign or decrypt @@ -191,6 +194,7 @@ remote-user secret-keyring filename # add filename to the list of secret keyrings +# see "keyring" for further informations status-fd n # Write status informations to this file descriptor. If this option diff --git a/g10/armor.c b/g10/armor.c index 37e37e726..1b31f6263 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -288,9 +288,11 @@ 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 */ - log_debug("armor header: "); - print_string( stderr, buf, n ); - putc('\n', stderr); + if( opt.verbose ) { + log_info("armor header: "); + print_string( stderr, buf, n ); + putc('\n', stderr); + } if( clearsig && !parse_hash_header( buf ) ) { log_error("invalid clearsig header\n"); state = fhdrERROR; @@ -321,9 +323,11 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, } else if( c != -1 ) { if( strchr( buf, ':') ) { /* buffer to short, but this is okay*/ - log_debug("armor header: "); - print_string( stderr, buf, n ); - fputs("[...]\n", stderr); /* indicate it is truncated */ + if( opt.verbose ) { + log_info("armor header: "); + print_string( stderr, buf, n ); + fputs("[...]\n", stderr); /* indicate it is truncated */ + } state = fhdrSKIPHeader; /* skip rest of line */ } else /* line too long */ @@ -380,7 +384,8 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, state = fhdrWAITHeader; if( hdr_line == BEGIN_SIGNED_MSG_IDX ) clearsig = 1; - log_debug("armor: %s\n", head_strings[hdr_line]); + if( opt.verbose > 1 ) + log_info("armor: %s\n", head_strings[hdr_line]); break; case fhdrCLEARSIG: @@ -432,15 +437,24 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, break; case fhdrCHECKClearsig: - case fhdrCHECKClearsig2: /* check the clearsig line */ if( n > 15 && !memcmp(buf, "-----", 5 ) ) state = fhdrENDClearsig; else if( buf[0] == '-' && buf[1] == ' ' ) state = fhdrCHECKDashEscaped; else { - state = state == fhdrCHECKClearsig2 ? - fhdrREADClearsig : fhdrTESTSpaces; + state = fhdrTESTSpaces; + } + break; + + case fhdrCHECKClearsig2: + /* check the clearsig line */ + if( n > 15 && !memcmp(buf, "-----", 5 ) ) + state = fhdrENDClearsig; + else if( buf[0] == '-' && buf[1] == ' ' ) + state = fhdrCHECKDashEscaped2; + else { + state = fhdrREADClearsig; } break; @@ -812,7 +826,7 @@ armor_filter( void *opaque, int control, int idx, idx2; size_t n=0; u32 crc; - #if 1 + #if 0 static FILE *fp ; if( !fp ) { @@ -884,7 +898,7 @@ armor_filter( void *opaque, int control, } else rc = radix64_read( afx, a, &n, buf, size ); - #if 1 + #if 0 if( n ) if( fwrite(buf, n, 1, fp ) != 1 ) BUG(); diff --git a/g10/g10.c b/g10/g10.c index 8036694cf..dedcc7c55 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -215,6 +215,7 @@ main( int argc, char **argv ) { 537, "export", 0, N_("export all or the given keys") }, { 538, "trustdb-name", 2, "\r" }, { 539, "clearsign", 0, N_("make a clear text signature") }, + { 540, "no-secmem-warning", 0, "\r" }, /* used only by regression tests */ {0} }; ARGPARSE_ARGS pargs; @@ -231,7 +232,7 @@ main( int argc, char **argv ) FILE *configfp = NULL; char *configname = NULL; unsigned configlineno; - int parse_verbose = 0; + int parse_debug = 0; int default_config =1; int errors=0; int default_keyring = 1; @@ -259,8 +260,8 @@ main( int argc, char **argv ) pargs.argv = &argv; pargs.flags= 1; /* do not remove the args */ while( arg_parse( &pargs, opts) ) { - if( pargs.r_opt == 'v' ) - parse_verbose++; + if( pargs.r_opt == 510 || pargs.r_opt == 511 ) + parse_debug++; else if( pargs.r_opt == 518 ) { /* yes there is one, so we do not try the default one, but * read the option file when it is encountered at the commandline @@ -283,7 +284,7 @@ main( int argc, char **argv ) configfp = fopen( configname, "r" ); if( !configfp ) { if( default_config ) { - if( parse_verbose > 1 ) + if( parse_debug ) log_info(_("note: no default option file '%s'\n"), configname ); } else @@ -291,7 +292,7 @@ main( int argc, char **argv ) configname, strerror(errno) ); m_free(configname); configname = NULL; } - if( parse_verbose > 1 && configname ) + if( parse_debug && configname ) log_info(_("reading options from '%s'\n"), configname ); default_config = 0; } @@ -370,6 +371,7 @@ main( int argc, char **argv ) case 537: set_cmd( &cmd, aExport); break; case 538: trustdb_name = pargs.r.ret_str; break; case 539: set_cmd( &cmd, aClearsign); break; + case 540: secmem_set_flags( secmem_get_flags() | 1 ); break; default : errors++; pargs.err = configfp? 1:2; break; } } @@ -403,6 +405,13 @@ main( int argc, char **argv ) if( errors ) g10_exit(2); + if( greeting ) { + if( *(s=strusage(10)) ) + tty_printf("%s", s); + if( *(s=strusage(30)) ) + tty_printf("%s", s); + } + /* initialize the secure memory. */ secmem_init( 16384 ); /* Okay, we are now working under our real uid */ @@ -425,23 +434,11 @@ main( int argc, char **argv ) } if( opt.verbose > 1 ) set_packet_list_mode(1); - if( greeting ) { - if( *(s=strusage(10)) ) - tty_printf("%s", s); - if( *(s=strusage(30)) ) - tty_printf("%s", s); - } - if( !sec_nrings || default_keyring ) { /* add default secret rings */ - char *p = make_filename("~/.g10", "secring.g10", NULL ); - add_secret_keyring(p); - m_free(p); - } - if( !nrings || default_keyring ) { /* add default ring */ - char *p = make_filename("~/.g10", "pubring.g10", NULL ); - add_keyring(p); - m_free(p); - } + if( !sec_nrings || default_keyring ) /* add default secret rings */ + add_secret_keyring("secring.g10"); + if( !nrings || default_keyring ) /* add default ring */ + add_keyring("pubring.g10"); if( argc ) { fname_print = fname = *argv; diff --git a/g10/getkey.c b/g10/getkey.c index 6564f1095..7182f4d4f 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -73,7 +73,8 @@ static int scan_keyring( PKT_public_cert *pkc, u32 *keyid, static int scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid, const char *name, const char *filename); - +/* note this function may be called before secure memory is + * available */ void add_keyring( const char *name ) { @@ -81,19 +82,32 @@ add_keyring( const char *name ) int rc; /* FIXME: check wether this one is available etc */ - /* my be we should do this later */ - sl = m_alloc( sizeof *sl + strlen(name) ); - strcpy(sl->d, name ); + /* maybe we should do this later */ + if( *name != '/' ) { /* do tilde expansion etc */ + char *p ; + + if( strchr(name, '/') ) + p = make_filename(name, NULL); + else + p = make_filename("~/.g10", name, NULL); + sl = m_alloc( sizeof *sl + strlen(p) ); + strcpy(sl->d, p ); + m_free(p); + } + else { + sl = m_alloc( sizeof *sl + strlen(name) ); + strcpy(sl->d, name ); + } sl->next = keyrings; keyrings = sl; - /* FIXME: We should remove much out of this mpdule and + /* FIXME: We should remove much out of this module and * combine it with the keyblock stuff from ringedit.c * For now we will simple add the filename as keyblock resource */ - rc = add_keyblock_resource( name, 0, 0 ); + rc = add_keyblock_resource( sl->d, 0, 0 ); if( rc ) - log_error("keyblock resource '%s': %s\n", name, g10_errstr(rc) ); + log_error("keyblock resource '%s': %s\n", sl->d, g10_errstr(rc) ); } @@ -119,8 +133,21 @@ add_secret_keyring( const char *name ) /* FIXME: check wether this one is available etc */ /* my be we should do this later */ - sl = m_alloc( sizeof *sl + strlen(name) ); - strcpy(sl->d, name ); + if( *name != '/' ) { /* do tilde expansion etc */ + char *p ; + + if( strchr(name, '/') ) + p = make_filename(name, NULL); + else + p = make_filename("~/.g10", name, NULL); + sl = m_alloc( sizeof *sl + strlen(p) ); + strcpy(sl->d, p ); + m_free(p); + } + else { + sl = m_alloc( sizeof *sl + strlen(name) ); + strcpy(sl->d, name ); + } sl->next = secret_keyrings; secret_keyrings = sl; @@ -128,9 +155,9 @@ add_secret_keyring( const char *name ) * combine it with the keyblock stuff from ringedit.c * For now we will simple add the filename as keyblock resource */ - rc = add_keyblock_resource( name, 0, 1 ); + rc = add_keyblock_resource( sl->d, 0, 1 ); if( rc ) - log_error("secret keyblock resource '%s': %s\n", name, g10_errstr(rc) ); + log_error("secret keyblock resource '%s': %s\n", sl->d, g10_errstr(rc)); } diff --git a/g10/kbnode.c b/g10/kbnode.c index 3096c4df5..dd4f0ce24 100644 --- a/g10/kbnode.c +++ b/g10/kbnode.c @@ -180,11 +180,8 @@ walk_kbnode( KBNODE root, KBNODE *context, int all ) return root; } - n = *context; - if( n->next ) { - n = n->next; - *context = n; - } + n = (*context)->next; + *context = n; } while( !all && n && (n->private_flag & 1) ); return n; diff --git a/g10/keygen.c b/g10/keygen.c index 09d2dc222..f9e68a083 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -114,7 +114,7 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc ) BUG(); /* no user id packet in tree */ uid = node->pkt->pkt.user_id; /* get the pkc packet from the pub_tree */ - node = find_kbnode( root, PKT_PUBLIC_CERT ); + node = find_kbnode( pub_root, PKT_PUBLIC_CERT ); if( !node ) BUG(); pkc = node->pkt->pkt.public_cert; diff --git a/g10/main.h b/g10/main.h index 55b99cef1..0c59de222 100644 --- a/g10/main.h +++ b/g10/main.h @@ -69,9 +69,6 @@ IOBUF open_sigfile( const char *iname ); /*-- seskey.c --*/ void make_session_key( DEK *dek ); MPI encode_session_key( DEK *dek, unsigned nbits ); -MPI encode_sha1_value( byte *md, unsigned len, unsigned nbits ); -MPI encode_rmd160_value( byte *md, unsigned len, unsigned nbits ); -MPI encode_md5_value( byte *md, unsigned len, unsigned nbits ); MPI encode_md_value( MD_HANDLE md, unsigned nbits ); /*-- comment.c --*/ diff --git a/g10/mainproc.c b/g10/mainproc.c index 1ef8a8b96..a7c17f9c8 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -135,7 +135,7 @@ add_user_id( CTX c, PACKET *pkt ) static int add_signature( CTX c, PACKET *pkt ) { - KBNODE node, n1, n2; + KBNODE node; if( pkt->pkttype == PKT_SIGNATURE && !c->cert ) { /* This is the first signature for a following datafile. @@ -143,34 +143,25 @@ add_signature( CTX c, PACKET *pkt ) * onepass-sig packets. The drawback of PGP's method * of prepending the signtaure to the data is, * that it is not possible to make a signature from data read - * from stdin. (Anyway, G10 is are able to read these stuff) */ + * from stdin. (Anyway, G10 is able to read these stuff) */ node = new_kbnode( pkt ); c->cert = node; return 1; } else if( !c->cert ) - return 0; /* oops */ + return 0; /* oops (invalid packet sequence)*/ else if( !c->cert->pkt ) - BUG(); + BUG(); /* so nicht */ else if( c->cert->pkt->pkttype == PKT_ONEPASS_SIG ) { - /* The root is a onepass signature, so we are signing data */ + /* The root is a onepass signature: we are signing data */ node = new_kbnode( pkt ); add_kbnode( c->cert, node ); return 1; } - /* goto the last user id */ - for(n2=NULL, n1=c->cert; n1->next; n1 = n1->next ) - if( n1->pkt->pkttype == PKT_USER_ID ) - n2 = n1; - if( !n2 ) { - log_error("no user id for signature packet\n"); - return 0; - } - n1 = n2; - /* and add a new signature node id at the end */ + /* add a new signature node id at the end */ node = new_kbnode( pkt ); - insert_kbnode( n1, node, PKT_USER_ID ); + add_kbnode( c->cert, node ); return 1; } diff --git a/g10/pkclist.c b/g10/pkclist.c index 411435f60..f123fc0d8 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -213,11 +213,13 @@ do_we_trust( PKT_public_cert *pkc, int trustlevel ) return 1; /* yes */ case TRUST_FULLY: - log_info("This key probably belongs to the owner\n"); + if( opt.verbose ) + log_info("This key probably belongs to the owner\n"); return 1; /* yes */ case TRUST_ULTIMATE: - log_info("Our own keys is always good.\n"); + if( opt.verbose ) + log_info("This key belongs to us (we have the secret key)\n"); return 1; /* yes */ default: BUG(); diff --git a/g10/plaintext.c b/g10/plaintext.c index 196da81f4..11953b8d4 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -45,10 +45,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx ) FILE *fp = NULL; int rc = 0; int c; -static FILE *abc; -if( !abc ) - abc=fopen("plaintext.out", "wb"); -if( !abc ) BUG(); + int convert = pt->mode == 't'; /* create the filename as C string */ if( opt.outfile ) { @@ -82,9 +79,10 @@ if( !abc ) BUG(); rc = G10ERR_READ_FILE; goto leave; } - putc( c, abc ); if( mfx->md ) 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; @@ -94,9 +92,10 @@ if( !abc ) BUG(); } else { while( (c = iobuf_get(pt->buf)) != -1 ) { - putc( c, abc ); if( mfx->md ) 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) ); @@ -136,7 +135,7 @@ ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname ) int c; fp = open_sigfile( inname ); /* open default file */ - if( !fp ) { + if( !fp && !opt.batch ) { int any=0; tty_printf("Detached signature.\n"); do { @@ -160,11 +159,20 @@ ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname ) } while( !fp ); } - while( (c = iobuf_get(fp)) != -1 ) { - if( mfx->md ) - md_putc(mfx->md, c ); + if( !fp ) { + log_info("reading stdin ...\n"); + while( (c = getchar()) != EOF ) { + if( mfx->md ) + md_putc(mfx->md, c ); + } + } + else { + while( (c = iobuf_get(fp)) != -1 ) { + if( mfx->md ) + md_putc(mfx->md, c ); + } + iobuf_close(fp); } - iobuf_close(fp); leave: m_free(answer); diff --git a/g10/seskey.c b/g10/seskey.c index 63e7b28f1..dd8ad13ab 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -109,8 +109,8 @@ encode_session_key( DEK *dek, unsigned nbits ) * returns: A mpi with the session key (caller must free) * RMD160 Object ID is 1.3.36.3.2.1 */ -MPI -encode_rmd160_value( byte *md, unsigned len, unsigned nbits ) +static MPI +encode_rmd160_value( byte *md, unsigned len, unsigned nbits, int secure ) { static byte asn[15] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, @@ -128,7 +128,8 @@ encode_rmd160_value( byte *md, unsigned len, unsigned nbits ) * * PAD consists of FF bytes. */ - frame = mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB ); + frame = secure ? mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB ) + : mpi_alloc( nframe / BYTES_PER_MPI_LIMB ); n = 0; for(i=20-1; i >= 0; i--, n++ ) mpi_putbyte(frame, n, md[i] ); @@ -148,8 +149,8 @@ encode_rmd160_value( byte *md, unsigned len, unsigned nbits ) * returns: A mpi with the session key (caller must free) * SHA-1 Objet ID is 1.3.14.3.2.26 */ -MPI -encode_sha1_value( byte *md, unsigned len, unsigned nbits ) +static MPI +encode_sha1_value( byte *md, unsigned len, unsigned nbits, int secure ) { static byte asn[15] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, @@ -167,7 +168,8 @@ encode_sha1_value( byte *md, unsigned len, unsigned nbits ) * * PAD consists of FF bytes. */ - frame = mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB ); + frame = secure ? mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB ) + : mpi_alloc( nframe / BYTES_PER_MPI_LIMB ); n = 0; for(i=20-1; i >= 0; i--, n++ ) mpi_putbyte(frame, n, md[i] ); @@ -188,8 +190,8 @@ encode_sha1_value( byte *md, unsigned len, unsigned nbits ) * returns: A mpi with the session key (caller must free) * MD5 Object ID is 1.2.840.113549.2.5 */ -MPI -encode_md5_value( byte *md, unsigned len, unsigned nbits ) +static MPI +encode_md5_value( byte *md, unsigned len, unsigned nbits, int secure ) { static byte asn[18] = { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48, @@ -207,7 +209,8 @@ encode_md5_value( byte *md, unsigned len, unsigned nbits ) * * PAD consists of FF bytes. */ - frame = mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB ); + frame = secure ? mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB ) + : mpi_alloc( nframe / BYTES_PER_MPI_LIMB ); n = 0; for(i=16-1; i >= 0; i--, n++ ) mpi_putbyte(frame, n, md[i] ); @@ -227,11 +230,14 @@ encode_md_value( MD_HANDLE md, unsigned nbits ) { switch( md_get_algo( md ) ) { case DIGEST_ALGO_MD5: - return encode_md5_value( md_read(md, DIGEST_ALGO_MD5), 16, nbits ); + return encode_md5_value( md_read(md, DIGEST_ALGO_MD5), + 16, nbits, md_is_secure(md) ); case DIGEST_ALGO_RMD160: - return encode_rmd160_value( md_read(md, DIGEST_ALGO_RMD160), 20, nbits ); + return encode_rmd160_value( md_read(md, DIGEST_ALGO_RMD160), + 20, nbits, md_is_secure(md) ); case DIGEST_ALGO_SHA1: - return encode_sha1_value( md_read(md, DIGEST_ALGO_SHA1), 20, nbits ); + return encode_sha1_value( md_read(md, DIGEST_ALGO_SHA1), + 20, nbits, md_is_secure(md) ); default: BUG(); } diff --git a/g10/sign.c b/g10/sign.c index a59598c8f..52718b390 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -190,11 +190,13 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, /* setup the inner packet */ if( detached ) { if( multifile ) { - STRLIST sl = filenames; + STRLIST sl; if( opt.verbose ) log_info("signing:" ); - for(; sl; sl = sl->next ) { + /* must walk reverse trough this list */ + for( sl = strlist_last(filenames); sl; + sl = strlist_prev( filenames, sl ) ) { if( !(inp = iobuf_open(sl->d)) ) { log_error("can't open %s: %s\n", sl->d, strerror(errno) ); rc = G10ERR_OPEN_FILE; @@ -345,7 +347,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) armor_filter_context_t afx; compress_filter_context_t zfx; text_filter_context_t tfx; - MD_HANDLE textmd; + MD_HANDLE textmd = NULL; IOBUF inp = NULL, out = NULL; PACKET pkt; int rc = 0; diff --git a/g10/trustdb.c b/g10/trustdb.c index 3f567e887..466dd7982 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1423,10 +1423,13 @@ do_check( ulong pubkeyid, TRUSTREC *dr, unsigned *trustlevel ) if( tsl->dup ) continue; - log_debug("tslist segs:" ); - for(i=0; i < tsl->nseg; i++ ) - fprintf(stderr, " %lu/%02x", tsl->seg[i].lid, tsl->seg[i].trust ); - putc('\n',stderr); + if( opt.verbose ) { + log_info("tslist segs:" ); + for(i=0; i < tsl->nseg; i++ ) + fprintf(stderr, " %lu/%02x", tsl->seg[i].lid, + tsl->seg[i].trust ); + putc('\n',stderr); + } } /* and look wether there is a trusted path. diff --git a/include/memory.h b/include/memory.h index bf4e66b2a..f2048e291 100644 --- a/include/memory.h +++ b/include/memory.h @@ -67,6 +67,8 @@ void secmem_term( void ); void *secmem_malloc( size_t size ); void secmem_free( void *a ); void secmem_dump_stats(void); +void secmem_set_flags( unsigned flags ); +unsigned secmem_get_flags(void); diff --git a/include/util.h b/include/util.h index 962efa503..1eca49ac4 100644 --- a/include/util.h +++ b/include/util.h @@ -66,20 +66,22 @@ void log_mpidump( const char *text, MPI a ); __attribute__ ((format (printf,2,3))); void log_bug( const char *fmt, ... ) __attribute__ ((noreturn, format (printf,1,2))); - void log_bug0( void ) __attribute__ ((noreturn)); + void log_bug0( const char *, int, const char * ) __attribute__ ((noreturn)); void 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__ ) #else void printstr( int level, const char *fmt, ... ); void log_bug( const char *fmt, ... ); - void log_bug0( void ); + 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__ ) #endif @@ -110,6 +112,8 @@ int answer_is_yes( const char *s ); void free_strlist( STRLIST sl ); #define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0) void add_to_strlist( STRLIST *list, const char *string ); +STRLIST strlist_prev( STRLIST head, STRLIST node ); +STRLIST strlist_last( STRLIST node ); char *memistr( char *buf, size_t buflen, const char *sub ); char *mem2str( char *, const void *, size_t); char *trim_spaces( char *string ); @@ -133,6 +137,5 @@ char *strlwr(char *a); #define STR2(v) STR(v) #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) -#define BUG() log_bug0() #endif /*G10_UTIL_H*/ diff --git a/mpi/alpha/README b/mpi/alpha/README new file mode 100644 index 000000000..55c0a2917 --- /dev/null +++ b/mpi/alpha/README @@ -0,0 +1,53 @@ +This directory contains mpn functions optimized for DEC Alpha processors. + +RELEVANT OPTIMIZATION ISSUES + +EV4 + +1. This chip has very limited store bandwidth. The on-chip L1 cache is +write-through, and a cache line is transfered from the store buffer to the +off-chip L2 in as much 15 cycles on most systems. This delay hurts +mpn_add_n, mpn_sub_n, mpn_lshift, and mpn_rshift. + +2. Pairing is possible between memory instructions and integer arithmetic +instructions. + +3. mulq and umulh is documented to have a latency of 23 cycles, but 2 of +these cycles are pipelined. Thus, multiply instructions can be issued at a +rate of one each 21nd cycle. + +EV5 + +1. The memory bandwidth of this chip seems excellent, both for loads and +stores. Even when the working set is larger than the on-chip L1 and L2 +caches, the perfromance remain almost unaffected. + +2. mulq has a measured latency of 13 cycles and an issue rate of 1 each 8th +cycle. umulh has a measured latency of 15 cycles and an issue rate of 1 +each 10th cycle. But the exact timing is somewhat confusing. + +3. mpn_add_n. With 4-fold unrolling, we need 37 instructions, whereof 12 + are memory operations. This will take at least + ceil(37/2) [dual issue] + 1 [taken branch] = 20 cycles + We have 12 memory cycles, plus 4 after-store conflict cycles, or 16 data + cache cycles, which should be completely hidden in the 20 issue cycles. + The computation is inherently serial, with these dependencies: + addq + / \ + addq cmpult + | | + cmpult | + \ / + or + I.e., there is a 4 cycle path for each limb, making 16 cycles the absolute + minimum. We could replace the `or' with a cmoveq/cmovne, which would save + a cycle on EV5, but that might waste a cycle on EV4. Also, cmov takes 2 + cycles. + addq + / \ + addq cmpult + | \ + cmpult -> cmovne + +STATUS + diff --git a/mpi/alpha/distfiles b/mpi/alpha/distfiles index 4dd0ffe3a..e92d183d2 100644 --- a/mpi/alpha/distfiles +++ b/mpi/alpha/distfiles @@ -1,3 +1,6 @@ +README +mpih-add1.S +mpih-shift.S udiv-qrnnd.S diff --git a/mpi/alpha/mpih-add1.S b/mpi/alpha/mpih-add1.S new file mode 100644 index 000000000..6f88499c9 --- /dev/null +++ b/mpi/alpha/mpih-add1.S @@ -0,0 +1,134 @@ +/* alpha add_n -- Add two limb vectors of the same length > 0 and store + * sum in a third limb vector. + * + * Copyright (C) 1995 Free Software Foundation, Inc. + * Copyright (c) 1997 by Werner Koch (dd9jn) + * + * This file is part of G10. + * + * G10 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, + * 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 + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. + */ + + + +/******************* + * mpi_limb_t + * mpihelp_add_n( mpi_ptr_t res_ptr, ($16) + * mpi_ptr_t s1_ptr, ($17) + * mpi_ptr_t s2_ptr, ($18) + * mpi_size_t size) ($19) + */ + + + .set noreorder + .set noat +.text + .align 3 + .globl mpihelp_add_n + .ent mpihelp_add_n +mpihelp_add_n: + .frame $30,0,$26,0 + + ldq $3,0($17) + ldq $4,0($18) + + subq $19,1,$19 + and $19,4-1,$2 # number of limbs in first loop + bis $31,$31,$0 + beq $2,.L0 # if multiple of 4 limbs, skip first loop + + subq $19,$2,$19 + +.Loop0: subq $2,1,$2 + ldq $5,8($17) + addq $4,$0,$4 + ldq $6,8($18) + cmpult $4,$0,$1 + addq $3,$4,$4 + cmpult $4,$3,$0 + stq $4,0($16) + or $0,$1,$0 + + addq $17,8,$17 + addq $18,8,$18 + bis $5,$5,$3 + bis $6,$6,$4 + addq $16,8,$16 + bne $2,.Loop0 + +.L0: beq $19,.Lend + + .align 3 +.Loop: subq $19,4,$19 + + ldq $5,8($17) + addq $4,$0,$4 + ldq $6,8($18) + cmpult $4,$0,$1 + addq $3,$4,$4 + cmpult $4,$3,$0 + stq $4,0($16) + or $0,$1,$0 + + ldq $3,16($17) + addq $6,$0,$6 + ldq $4,16($18) + cmpult $6,$0,$1 + addq $5,$6,$6 + cmpult $6,$5,$0 + stq $6,8($16) + or $0,$1,$0 + + ldq $5,24($17) + addq $4,$0,$4 + ldq $6,24($18) + cmpult $4,$0,$1 + addq $3,$4,$4 + cmpult $4,$3,$0 + stq $4,16($16) + or $0,$1,$0 + + ldq $3,32($17) + addq $6,$0,$6 + ldq $4,32($18) + cmpult $6,$0,$1 + addq $5,$6,$6 + cmpult $6,$5,$0 + stq $6,24($16) + or $0,$1,$0 + + addq $17,32,$17 + addq $18,32,$18 + addq $16,32,$16 + bne $19,.Loop + +.Lend: addq $4,$0,$4 + cmpult $4,$0,$1 + addq $3,$4,$4 + cmpult $4,$3,$0 + stq $4,0($16) + or $0,$1,$0 + ret $31,($26),1 + + .end mpihelp_add_n + diff --git a/mpi/alpha/mpih-shift.S b/mpi/alpha/mpih-shift.S new file mode 100644 index 000000000..dcf0a1f46 --- /dev/null +++ b/mpi/alpha/mpih-shift.S @@ -0,0 +1,213 @@ +/* alpha rshift, lshift + * Copyright (C) 1994, 1995 Free Software Foundation, Inc. + * Copyright (c) 1997 by Werner Koch (dd9jn) + * + * This file is part of G10. + * + * G10 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, + * 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 + * + * Note: This code is heavily based on the GNU MP Library. + * Actually it's the same code with only minor changes in the + * way the data is stored; this is to support the abstraction + * of an optional secure memory allocation which may be used + * to avoid revealing of sensitive data due to paging etc. + * The GNU MP Library itself is published under the LGPL; + * however I decided to publish this code under the plain GPL. + */ + + + +/******************* + * mpi_limb_t + * mpihelp_lshift( mpi_ptr_t wp, (r16) + * mpi_ptr_t up, (r17) + * mpi_size_t usize, (r18) + * unsigned cnt) (r19) + * + * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling, + * it would take 4 cycles/limb. It should be possible to get down to 3 + * cycles/limb since both ldq and stq can be paired with the other used + * instructions. But there are many restrictions in the 21064 pipeline that + * makes it hard, if not impossible, to get down to 3 cycles/limb: + * + * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay. + * 2. Only aligned instruction pairs can be paired. + * 3. The store buffer or silo might not be able to deal with the bandwidth. + */ + + .set noreorder + .set noat +.text + .align 3 + .globl mpihelp_lshift + .ent mpihelp_lshift +mpihelp_lshift: + .frame $30,0,$26,0 + + s8addq $18,$17,$17 # make r17 point at end of s1 + ldq $4,-8($17) # load first limb + subq $17,8,$17 + subq $31,$19,$7 + s8addq $18,$16,$16 # make r16 point at end of RES + subq $18,1,$18 + and $18,4-1,$20 # number of limbs in first loop + srl $4,$7,$0 # compute function result + + beq $20,.L0 + subq $18,$20,$18 + + .align 3 +.Loop0: + ldq $3,-8($17) + subq $16,8,$16 + subq $17,8,$17 + subq $20,1,$20 + sll $4,$19,$5 + srl $3,$7,$6 + bis $3,$3,$4 + bis $5,$6,$8 + stq $8,0($16) + bne $20,.Loop0 + +.L0: beq $18,.Lend + + .align 3 +.Loop: ldq $3,-8($17) + subq $16,32,$16 + subq $18,4,$18 + sll $4,$19,$5 + srl $3,$7,$6 + + ldq $4,-16($17) + sll $3,$19,$1 + bis $5,$6,$8 + stq $8,24($16) + srl $4,$7,$2 + + ldq $3,-24($17) + sll $4,$19,$5 + bis $1,$2,$8 + stq $8,16($16) + srl $3,$7,$6 + + ldq $4,-32($17) + sll $3,$19,$1 + bis $5,$6,$8 + stq $8,8($16) + srl $4,$7,$2 + + subq $17,32,$17 + bis $1,$2,$8 + stq $8,0($16) + + bgt $18,.Loop + +.Lend: sll $4,$19,$8 + stq $8,-8($16) + ret $31,($26),1 + .end mpihelp_lshift + + + + + +/******************* + * mpi_limb_t + * mpihelp_rshift( mpi_ptr_t wp, (r16) + * mpi_ptr_t up, (r17) + * mpi_size_t usize, (r18) + * unsigned cnt) (r19) + * + * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling, + * it would take 4 cycles/limb. It should be possible to get down to 3 + * cycles/limb since both ldq and stq can be paired with the other used + * instructions. But there are many restrictions in the 21064 pipeline that + * makes it hard, if not impossible, to get down to 3 cycles/limb: + * + * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay. + * 2. Only aligned instruction pairs can be paired. + * 3. The store buffer or silo might not be able to deal with the bandwidth. + */ + + .set noreorder + .set noat +.text + .align 3 + .globl mpihelp_rshift + .ent mpihelp_rshift +mpihelp_rshift: + .frame $30,0,$26,0 + + ldq $4,0($17) # load first limb + addq $17,8,$17 + subq $31,$19,$7 + subq $18,1,$18 + and $18,4-1,$20 # number of limbs in first loop + sll $4,$7,$0 # compute function result + + beq $20,.R0 + subq $18,$20,$18 + + .align 3 +.Roop0: + ldq $3,0($17) + addq $16,8,$16 + addq $17,8,$17 + subq $20,1,$20 + srl $4,$19,$5 + sll $3,$7,$6 + bis $3,$3,$4 + bis $5,$6,$8 + stq $8,-8($16) + bne $20,.Roop0 + +.R0: beq $18,.Rend + + .align 3 +.Roop: ldq $3,0($17) + addq $16,32,$16 + subq $18,4,$18 + srl $4,$19,$5 + sll $3,$7,$6 + + ldq $4,8($17) + srl $3,$19,$1 + bis $5,$6,$8 + stq $8,-32($16) + sll $4,$7,$2 + + ldq $3,16($17) + srl $4,$19,$5 + bis $1,$2,$8 + stq $8,-24($16) + sll $3,$7,$6 + + ldq $4,24($17) + srl $3,$19,$1 + bis $5,$6,$8 + stq $8,-16($16) + sll $4,$7,$2 + + addq $17,32,$17 + bis $1,$2,$8 + stq $8,-8($16) + + bgt $18,.Roop + +.Rend: srl $4,$19,$8 + stq $8,0($16) + ret $31,($26),1 + .end mpihelp_rshift + diff --git a/tools/Makefile.am b/tools/Makefile.am index fb88d9171..5101e67a8 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -3,14 +3,17 @@ INCLUDES = -I$(top_srcdir)/include needed_libs = ../cipher/libcipher.a ../util/libutil.a ../mpi/libmpi.a ../util/libutil.a -noinst_PROGRAMS = mpicalc bftest +noinst_PROGRAMS = mpicalc bftest clean-sat mpicalc_SOURCES = mpicalc.c bftest_SOURCES = bftest.c +clean_sat_SOURCES = clean-sat.c -LDADD = @INTLLIBS@ $(needed_libs) -$(PROGRAMS): $(needed_libs) +mpicalc_LDADD = @INTLLIBS@ $(needed_libs) +bftest_LDADD = @INTLLIBS@ $(needed_libs) + +mpicalc bftest: $(needed_libs) diff --git a/tools/Makefile.in b/tools/Makefile.in index add8db5f5..9bb4a1e16 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -89,13 +89,16 @@ VERSION = @VERSION@ INCLUDES = -I$(top_srcdir)/include needed_libs = ../cipher/libcipher.a ../util/libutil.a ../mpi/libmpi.a ../util/libutil.a -noinst_PROGRAMS = mpicalc bftest +noinst_PROGRAMS = mpicalc bftest clean-sat mpicalc_SOURCES = mpicalc.c bftest_SOURCES = bftest.c -LDADD = @INTLLIBS@ $(needed_libs) +clean_sat_SOURCES = clean-sat.c + +mpicalc_LDADD = @INTLLIBS@ $(needed_libs) +bftest_LDADD = @INTLLIBS@ $(needed_libs) mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = @@ -107,15 +110,17 @@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ mpicalc_OBJECTS = mpicalc.o -mpicalc_LDADD = $(LDADD) mpicalc_DEPENDENCIES = ../cipher/libcipher.a ../util/libutil.a \ ../mpi/libmpi.a ../util/libutil.a mpicalc_LDFLAGS = bftest_OBJECTS = bftest.o -bftest_LDADD = $(LDADD) bftest_DEPENDENCIES = ../cipher/libcipher.a ../util/libutil.a \ ../mpi/libmpi.a ../util/libutil.a bftest_LDFLAGS = +clean_sat_OBJECTS = clean-sat.o +clean_sat_LDADD = $(LDADD) +clean_sat_DEPENDENCIES = +clean_sat_LDFLAGS = CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ @@ -126,9 +131,9 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP = --best -DEP_FILES = .deps/bftest.P .deps/mpicalc.P -SOURCES = $(mpicalc_SOURCES) $(bftest_SOURCES) -OBJECTS = $(mpicalc_OBJECTS) $(bftest_OBJECTS) +DEP_FILES = .deps/bftest.P .deps/clean-sat.P .deps/mpicalc.P +SOURCES = $(mpicalc_SOURCES) $(bftest_SOURCES) $(clean_sat_SOURCES) +OBJECTS = $(mpicalc_OBJECTS) $(bftest_OBJECTS) $(clean_sat_OBJECTS) default: all @@ -178,6 +183,10 @@ bftest: $(bftest_OBJECTS) $(bftest_DEPENDENCIES) @rm -f bftest $(LINK) $(bftest_LDFLAGS) $(bftest_OBJECTS) $(bftest_LDADD) $(LIBS) +clean-sat: $(clean_sat_OBJECTS) $(clean_sat_DEPENDENCIES) + @rm -f clean-sat + $(LINK) $(clean_sat_LDFLAGS) $(clean_sat_OBJECTS) $(clean_sat_LDADD) $(LIBS) + tags: TAGS ID: $(HEADERS) $(SOURCES) $(LISP) @@ -306,7 +315,7 @@ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean -$(PROGRAMS): $(needed_libs) +mpicalc bftest: $(needed_libs) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/tools/clean-sat.c b/tools/clean-sat.c new file mode 100644 index 000000000..a4f88e55f --- /dev/null +++ b/tools/clean-sat.c @@ -0,0 +1,25 @@ +/* clean-sat.c + */ + +#include + +int +main(int argc, char **argv) +{ + int c, c2; + + if( argc > 1 ) { + fprintf(stderr, "no arguments, please\n"); + return 1; + } + + while( (c=getchar()) == '\n' ) + ; + while( c != EOF ) { + putchar(c); + c = getchar(); + } + + return 0; +} + diff --git a/util/argparse.c b/util/argparse.c index 795e87648..0c8ad8f0b 100644 --- a/util/argparse.c +++ b/util/argparse.c @@ -221,10 +221,10 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno, arg->r_opt = -arg->r_opt; if( !opts[index].short_opt ) arg->r_opt = -2; /* unknown option */ - else if( (opts[index].flags & 8) ) /* no optional argument */ - arg->r_type = 0; /* okay */ - else /* no required argument */ + else if( (opts[index].flags & 8) ) /* no argument */ arg->r_opt = -3; /* error */ + else /* no or optiona argument */ + arg->r_type = 0; /* okay */ break; } else if( state == 3 ) { /* no argument found */ diff --git a/util/logger.c b/util/logger.c index 04dac2ce6..7d101c29a 100644 --- a/util/logger.c +++ b/util/logger.c @@ -129,11 +129,19 @@ log_bug( const char *fmt, ... ) abort(); } +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) void -log_bug0() +log_bug0( const char *file, int line, const char *func ) { - log_bug("Ohhhh jeeee ...\n"); + log_bug("Ohhhh jeeee ... (%s:%d:%s)\n", file, line, func ); } +#else +void +log_bug0( const char *file, int line ) +{ + log_bug("Ohhhh jeeee ... (%s:%d)\n", file, line); +} +#endif void log_debug( const char *fmt, ... ) diff --git a/util/secmem.c b/util/secmem.c index 2777ca8ca..a54848d54 100644 --- a/util/secmem.c +++ b/util/secmem.c @@ -61,6 +61,8 @@ static unsigned cur_alloced; static unsigned max_blocks; static unsigned cur_blocks; static int disable_secmem; +static int show_warning; +static int no_warning; static void lock_pool( void *p, size_t n ) @@ -82,7 +84,7 @@ lock_pool( void *p, size_t n ) if( err ) { if( errno != EPERM ) log_error("can´t lock memory: %s\n", strerror(err)); - log_info(_("Warning: using insecure memory!\n")); + show_warning = 1; } #else @@ -132,6 +134,17 @@ compress_pool(void) } +void +secmem_set_flags( unsigned flags ) +{ + no_warning = flags & 1; +} + +unsigned +secmem_get_flags(void) +{ + return no_warning ? 1:0; +} void secmem_init( size_t n ) @@ -156,7 +169,12 @@ secmem_malloc( size_t size ) int compressed=0; if( !pool_okay ) - init_pool(DEFAULT_POOLSIZE); + log_bug("secmem not initialized\n"); + if( show_warning ) { + show_warning = 0; + if( !no_warning ) + log_info(_("Warning: using insecure memory!\n")); + } /* blocks are always a multiple of 32 */ size += sizeof(MEMBLOCK); diff --git a/util/strgutil.c b/util/strgutil.c index a687d0af3..e04367a7e 100644 --- a/util/strgutil.c +++ b/util/strgutil.c @@ -50,6 +50,28 @@ add_to_strlist( STRLIST *list, const char *string ) *list = sl; } + + +STRLIST +strlist_prev( STRLIST head, STRLIST node ) +{ + STRLIST n; + + for(n=NULL; head && head != node; head = head->next ) + n = head; + return n; +} + +STRLIST +strlist_last( STRLIST node ) +{ + if( node ) + for( ; node->next ; node = node->next ) + ; + return node; +} + + /**************** * look for the substring SUB in buffer and return a pointer to that * substring in BUF or NULL if not found.