bug fixes
authorWerner Koch <wk@gnupg.org>
Wed, 11 Feb 1998 23:22:09 +0000 (23:22 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 11 Feb 1998 23:22:09 +0000 (23:22 +0000)
37 files changed:
NEWS
TODO
VERSION
checks/checkit [new file with mode: 0755]
checks/distfiles [new file with mode: 0644]
checks/plain-1 [new file with mode: 0644]
checks/plain-2 [new file with mode: 0644]
checks/plain-3 [new file with mode: 0644]
cipher/elgamal.c
cipher/md.c
cipher/md.h
g10/OPTIONS
g10/armor.c
g10/g10.c
g10/getkey.c
g10/kbnode.c
g10/keygen.c
g10/main.h
g10/mainproc.c
g10/pkclist.c
g10/plaintext.c
g10/seskey.c
g10/sign.c
g10/trustdb.c
include/memory.h
include/util.h
mpi/alpha/README [new file with mode: 0644]
mpi/alpha/distfiles
mpi/alpha/mpih-add1.S [new file with mode: 0644]
mpi/alpha/mpih-shift.S [new file with mode: 0644]
tools/Makefile.am
tools/Makefile.in
tools/clean-sat.c [new file with mode: 0644]
util/argparse.c
util/logger.c
util/secmem.c
util/strgutil.c

diff --git a/NEWS b/NEWS
index 0a8ffa1..1f6fc79 100644 (file)
--- 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 1b63c1e..baaa141 100644 (file)
--- 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 ccd3d1a..abd4105 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.2.3x
+0.2.4
diff --git a/checks/checkit b/checks/checkit
new file mode 100755 (executable)
index 0000000..3ffce35
--- /dev/null
@@ -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 <<EOF  >./.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 (file)
index 0000000..d7edce9
--- /dev/null
@@ -0,0 +1 @@
+checkit plain-1 plain-2 plain-3
diff --git a/checks/plain-1 b/checks/plain-1
new file mode 100644 (file)
index 0000000..f336a12
--- /dev/null
@@ -0,0 +1,23 @@
+<!-- Dies ist Seite 3, dort ist keine Seitenzahl angegeben,
+     oben rechts ist wieder der Stempel von meinem Opa zu finden -->
+
+<sect1>Name <q>Groß-Bartloff</>
+
+<p>
+Der Name <q/Bartloff/ ist schwer zu deuten. Man hat viele Mutmaßungen
+angestellt, von denen man aber bislang keine einzige als unbedingt
+richtig erklären kann.
+<fontinfo rem="mit Leerzeichen geschrieben">Urkundlich</> wird das
+Dorf bis zur Reformation stets <q/Bartorf/ (anno 1253) und
+<q/Bardorf/ (1306, 1318, 1329, 1429) genannt und das_ sowohl Klein-
+wie Großbartloff. Erst 1586 im Bischofssteiner Jurisdiktionalbuch
+heißt unser Dorf <q/Bartteloff/ und so auch in der ältesten noch
+vorhandenen Kirchenrechnung vom Jahre 1651. NAch dem Jahre 1700 wird
+in den Urkunden begonnen, den vollen Namen <q/Groß-Bartloff/ und
+<q/Klein-Bartloff/ zu schreiben.
+---------------- [wegen dashed escaped text]
+<p>
+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 <q/Borde/ oder am Rande
+oder an der Grenze entweder des Waldes
diff --git a/checks/plain-2 b/checks/plain-2
new file mode 100644 (file)
index 0000000..5a10a97
--- /dev/null
@@ -0,0 +1,49 @@
+
+
+<sect>Vorwort
+<p>
+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.
+<p>
+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.
+<p vspace="2ex">
+<bf>Großbartloff,</> den 23. März 1923.
+<p vspace="3ex" align=right>
+<bf/Nikolaus Göring,/ Pfarrer.
+</p>
+
+<!-- Hier folgt ein Stempel von meinem Opa:
+         Rud. Koch
+     Großbartloff/Eichsfeld
+       Anger 161
+-->
+<!-- FIXME: hier kommt einen Zierlinie -->
+
+<p vspace=fill> <!-- Der Rest kam am Ende der Seite -->
+<p align=center> Literatur: </p>
+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???
+
+<!-- FIXME: Der Rest fehlt noch -->
+
+
+
+
+
+
+
+
+</sect>
diff --git a/checks/plain-3 b/checks/plain-3
new file mode 100644 (file)
index 0000000..8a6e6b6
--- /dev/null
@@ -0,0 +1 @@
+Dies ist eine einfache Zeile ohne LF am Ende.
\ No newline at end of file
index 13b8579..6defbc5 100644 (file)
@@ -322,6 +322,16 @@ elg_verify(MPI a, MPI b, MPI input, ELG_public_key *pkey )
 
   #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;
     base[2] = NULL;    exp[2] = NULL;
index c89c8bb..c87f328 100644 (file)
@@ -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 );
index 8a7886d..7a710e7 100644 (file)
@@ -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*/
index 4f21a9e..37c6ec4 100644 (file)
@@ -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
index 37e37e7..1b31f62 100644 (file)
@@ -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();
index 8036694..dedcc7c 100644 (file)
--- 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;
index 6564f10..7182f4d 100644 (file)
@@ -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));
 }
 
 
index 3096c4d..dd4f0ce 100644 (file)
@@ -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;
index 09d2dc2..f9e68a0 100644 (file)
@@ -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;
index 55b99ce..0c59de2 100644 (file)
@@ -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 --*/
index 1ef8a8b..a7c17f9 100644 (file)
@@ -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;
 }
 
index 411435f..f123fc0 100644 (file)
@@ -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();
index 196da81..11953b8 100644 (file)
@@ -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);
index 63e7b28..dd8ad13 100644 (file)
@@ -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();
     }
index a59598c..52718b3 100644 (file)
@@ -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;
index 3f567e8..466dd79 100644 (file)
@@ -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.
index bf4e66b..f2048e2 100644 (file)
@@ -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);
 
 
 
index 962efa5..1eca49a 100644 (file)
@@ -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 (file)
index 0000000..55c0a29
--- /dev/null
@@ -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
+
index 4dd0ffe..e92d183 100644 (file)
@@ -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 (file)
index 0000000..6f88499
--- /dev/null
@@ -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 (file)
index 0000000..dcf0a1f
--- /dev/null
@@ -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
+
index fb88d91..5101e67 100644 (file)
@@ -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)
 
index add8db5..9bb4a1e 100644 (file)
@@ -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 (file)
index 0000000..a4f88e5
--- /dev/null
@@ -0,0 +1,25 @@
+/* clean-sat.c
+ */
+
+#include <stdio.h>
+
+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;
+}
+
index 795e876..0c8ad8f 100644 (file)
@@ -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 */
index 04dac2c..7d101c2 100644 (file)
@@ -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, ... )
index 2777ca8..a54848d 100644 (file)
@@ -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);
index a687d0a..e04367a 100644 (file)
@@ -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.