started with trust stuff
authorWerner Koch <wk@gnupg.org>
Mon, 12 Jan 1998 10:18:17 +0000 (10:18 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 12 Jan 1998 10:18:17 +0000 (10:18 +0000)
54 files changed:
INSTALL
NEWS
README
TODO
VERSION
cipher/Makefile.am
cipher/Makefile.in
cipher/md.c
cipher/md.h [new file with mode: 0644]
cipher/md5.c
cipher/md5.h
cipher/random.c
cipher/rmd.h
cipher/rmd160.c
cipher/sha1.c
cipher/sha1.h
doc/DETAILS
g10/Makefile.am
g10/Makefile.in
g10/build-packet.c
g10/elg.c
g10/filter.h
g10/free-packet.c
g10/g10.c
g10/keygen.c
g10/keyid.c
g10/main.h
g10/mainproc.c
g10/mdfilter.c
g10/packet.h
g10/parse-packet.c
g10/passphrase.c
g10/pkclist.c
g10/plaintext.c
g10/rsa.c
g10/seskey.c
g10/sig-check.c
g10/sign.c
g10/skclist.c
g10/trustdb.c
g10/trustdb.h [new file with mode: 0644]
include/cipher.h
include/errors.h
include/mpi.h
mpi/config.links
mpi/sparc32/distfiles [new file with mode: 0644]
mpi/sparc32/mpih-add1.S [new file with mode: 0644]
mpi/sparc32/udiv.S [new file with mode: 0644]
mpi/sparc32v8/distfiles [new file with mode: 0644]
mpi/sparc32v8/mpih-mul1.S [new file with mode: 0644]
mpi/sparc32v8/mpih-mul2.S [new file with mode: 0644]
mpi/sparc32v8/mpih-mul3.S [new file with mode: 0644]
mpi/supersparc/distfiles [new file with mode: 0644]
mpi/supersparc/udiv.S [new file with mode: 0644]

diff --git a/INSTALL b/INSTALL
index bf72ad4..c524222 100644 (file)
--- a/INSTALL
+++ b/INSTALL
-
-    1) Configure for your machine:
-
-        ./configure
-
-       or use
-
-        ./configure --enable-m-debug
-
-       to enable the integrated malloc debugging stuff.
-
-
-    2) Run make:
-
-       make
-
-
-    3) Install
-
-       make install
-
-
-    4) You end up with a binary "g10" in /usr/local/bin
-
-
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made. To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
 
diff --git a/NEWS b/NEWS
index e69de29..eeee0dc 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -0,0 +1,6 @@
+
+    * The string "(INSECURE!)" is appended to a new user-id if this
+      is generated on a system without a good random number generator.
+
+    * works (more or less) on a UltraPenguin (sparc64--gnu-linux)
+
diff --git a/README b/README
index 1830189..55be1b2 100644 (file)
--- a/README
+++ b/README
 
 
 
+    Installation
+    ------------
+
+    1) "./configure"
+
+       to enable the integrated malloc debugging stuff, use:
+
+       "./configure --enable-m-debug"
+
+    2) "make"
+
+    3) "make install"
+
+    4) You end up with a binary "g10" in /usr/local/bin
+
+
+
+
     Resources
     ---------
     G10 needs a directory "~/.g10" to store the default keyrings
diff --git a/TODO b/TODO
index bcd64ed..9e76209 100644 (file)
--- a/TODO
+++ b/TODO
@@ -37,4 +37,6 @@
 
     * add g10 stuff to Mutt's pgpinvoke.c
 
+    * Burn the buffers used by fopen().
+
 
diff --git a/VERSION b/VERSION
index d917d3e..b1e80bb 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.2
+0.1.3
index 0855d7d..ecd91a7 100644 (file)
@@ -23,6 +23,7 @@ cipher_SOURCES = blowfish.c   \
                 dsa.h          \
                 dsa.c          \
                 md.c           \
+                md.h           \
                 misc.c         \
                 smallprime.c
 
index 7bd7691..221efdd 100644 (file)
@@ -60,6 +60,7 @@ cipher_SOURCES = blowfish.c   \
                 dsa.h          \
                 dsa.c          \
                 md.c           \
+                md.h           \
                 misc.c         \
                 smallprime.c
 
index 67f5356..e88a45c 100644 (file)
 #include "errors.h"
 
 
-int
-md_okay( int algo )
-{
-    return check_digest_algo( algo );
-}
-
-
-MD_HANDLE *
+/****************
+ * Open a message digest handle for use with algorithm ALGO.
+ * More algorithms may be added by md_enable(). The initial algorithm
+ * may be 0.
+ */
+MD_HANDLE
 md_open( int algo, int secure )
 {
-    MD_HANDLE *hd;
-
-    hd = m_alloc( sizeof *hd + 19 );
-    hd->algo = algo;
-    hd->datalen = 0;
-    if( algo == DIGEST_ALGO_MD5 )
-       hd->u.md5 = md5_open( secure );
-    else if( algo == DIGEST_ALGO_RMD160 )
-       hd->u.rmd= rmd160_open( secure );
-    else if( algo == DIGEST_ALGO_SHA1 )
-       hd->u.sha1 = sha1_open( secure );
-    else
-       return NULL;
+    MD_HANDLE hd;
 
+    hd = secure ? m_alloc_secure_clear( sizeof *hd )
+               : m_alloc_clear( sizeof *hd );
+    if( algo )
+       md_enable( hd, algo );
     return hd;
 }
 
-
-MD_HANDLE *
-md_copy( MD_HANDLE *a )
+void
+md_enable( MD_HANDLE h, int algo )
 {
-    MD_HANDLE *hd;
-
-    hd = m_alloc( sizeof *hd + 19 );
-    hd->algo = a->algo;
-    hd->datalen = 0;
-    if( a->algo == DIGEST_ALGO_MD5 )
-       hd->u.md5 = md5_copy( a->u.md5 );
-    else if( a->algo == DIGEST_ALGO_RMD160 )
-       hd->u.rmd= rmd160_copy( a->u.rmd );
-    else if( a->algo == DIGEST_ALGO_SHA1 )
-       hd->u.sha1= sha1_copy( a->u.sha1 );
+    if( algo == DIGEST_ALGO_MD5 ) {
+       md5_init( &h->md5 );
+       h->use_md5 = 1;
+    }
+    else if( algo == DIGEST_ALGO_RMD160 ) {
+       rmd160_init( &h->rmd160 );
+       h->use_rmd160 = 1;
+    }
+    else if( algo == DIGEST_ALGO_SHA1 ) {
+       sha1_init( &h->sha1 );
+       h->use_sha1 = 1;
+    }
     else
-       log_bug(NULL);
-    return hd;
+       log_bug("md_enable(%d)", algo );
 }
 
 
-/* used for a BAD Kludge in rmd160.c, md5.c  */
-MD_HANDLE *
-md_makecontainer( int algo )
+MD_HANDLE
+md_copy( MD_HANDLE a )
 {
-    MD_HANDLE *hd;
-
-    hd = m_alloc( sizeof *hd + 19 );
-    hd->algo = algo;
-    hd->datalen = 0;
-    if( algo == DIGEST_ALGO_MD5 )
-       ;
-    else if( algo == DIGEST_ALGO_RMD160 )
-       ;
-    else if( algo == DIGEST_ALGO_SHA1 )
-       ;
-    else
-       log_bug(NULL);
-    return hd;
+    MD_HANDLE b;
+
+    b = m_is_secure(a)? m_alloc_secure( sizeof *b )
+                     : m_alloc( sizeof *b );
+    memcpy( b, a, sizeof *a );
+    return b;
 }
 
+
 void
-md_close(MD_HANDLE *a)
+md_close(MD_HANDLE a)
 {
     if( !a )
        return;
-    if( a->algo == DIGEST_ALGO_MD5 )
-       md5_close( a->u.md5 );
-    else if( a->algo == DIGEST_ALGO_RMD160 )
-       rmd160_close( a->u.rmd );
-    else if( a->algo == DIGEST_ALGO_SHA1 )
-       sha1_close( a->u.sha1 );
-    else
-       log_bug(NULL);
     m_free(a);
 }
 
 
 void
-md_write( MD_HANDLE *a, byte *inbuf, size_t inlen)
+md_write( MD_HANDLE a, byte *inbuf, size_t inlen)
 {
-    if( a->algo == DIGEST_ALGO_MD5 )
-       md5_write( a->u.md5, inbuf, inlen );
-    else if( a->algo == DIGEST_ALGO_RMD160 )
-       rmd160_write( a->u.rmd, inbuf, inlen  );
-    else if( a->algo == DIGEST_ALGO_SHA1 )
-       sha1_write( a->u.sha1, inbuf, inlen  );
-    else
-       log_bug(NULL);
+    if( a->use_rmd160 ) {
+       rmd160_write( &a->rmd160, a->buffer, a->bufcount );
+       rmd160_write( &a->rmd160, inbuf, inlen  );
+    }
+    if( a->use_sha1 ) {
+       sha1_write( &a->sha1, a->buffer, a->bufcount );
+       sha1_write( &a->sha1, inbuf, inlen  );
+    }
+    if( a->use_md5 ) {
+       md5_write( &a->md5, a->buffer, a->bufcount );
+       md5_write( &a->md5, inbuf, inlen  );
+    }
+    a->bufcount = 0;
 }
 
 
+
 void
-md_putchar( MD_HANDLE *a, int c )
+md_final(MD_HANDLE a)
 {
-    if( a->algo == DIGEST_ALGO_MD5 )
-       md5_putchar( a->u.md5, c );
-    else if( a->algo == DIGEST_ALGO_RMD160 )
-       rmd160_putchar( a->u.rmd, c );
-    else if( a->algo == DIGEST_ALGO_SHA1 )
-       sha1_putchar( a->u.sha1, c );
-    else
-       log_bug(NULL);
+    if( a->bufcount )
+       md_write( a, NULL, 0 );
+    if( a->use_rmd160 ) {
+       byte *p;
+       rmd160_final( &a->rmd160 );
+       p = rmd160_read( &a->rmd160 );
+    }
+    if( a->use_sha1 )
+       sha1_final( &a->sha1 );
+    if( a->use_md5 )
+       md5_final( &a->md5 );
 }
 
 
+/****************
+ * if ALGO is null get the digest for the used algo (which should be only one)
+ */
 byte *
-md_final(MD_HANDLE *a)
+md_read( MD_HANDLE a, int algo )
 {
-    if( a->algo == DIGEST_ALGO_MD5 ) {
-       if( !a->datalen ) {
-           md5_final( a->u.md5 );
-           memcpy(a->data, md5_read( a->u.md5 ), 16);
-           a->datalen = 16;
-       }
-       return a->data;
+    if( !algo ) {
+       if( a->use_rmd160 )
+           return rmd160_read( &a->rmd160 );
+       if( a->use_sha1 )
+           return sha1_read( &a->sha1 );
+       if( a->use_md5 )
+           return md5_read( &a->md5 );
     }
-    else if( a->algo == DIGEST_ALGO_RMD160 ) {
-       if( !a->datalen ) {
-           memcpy(a->data, rmd160_final( a->u.rmd  ), 20 );
-           a->datalen = 20;
-       }
-       return a->data;
+    else {
+       if( algo == DIGEST_ALGO_RMD160 )
+           return rmd160_read( &a->rmd160 );
+       if( algo == DIGEST_ALGO_SHA1 )
+           return sha1_read( &a->sha1 );
+       if( algo == DIGEST_ALGO_MD5 )
+           return md5_read( &a->md5 );
     }
-    else if( a->algo == DIGEST_ALGO_SHA1 ) {
-       if( !a->datalen ) {
-           memcpy(a->data, sha1_final( a->u.sha1  ), 20 );
-           a->datalen = 20;
-       }
-       return a->data;
-    }
-    else
-       log_bug(NULL);
+    log_bug(NULL);
 }
 
+int
+md_get_algo( MD_HANDLE a )
+{
+    if( a->use_rmd160 )
+       return DIGEST_ALGO_RMD160;
+    if( a->use_sha1 )
+       return DIGEST_ALGO_SHA1;
+    if( a->use_md5 )
+       return DIGEST_ALGO_MD5;
+    return 0;
+}
 
diff --git a/cipher/md.h b/cipher/md.h
new file mode 100644 (file)
index 0000000..8a7886d
--- /dev/null
@@ -0,0 +1,60 @@
+/* md.h - digest functions
+ *     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
+ */
+#ifndef G10_MD_H
+#define G10_MD_H
+
+#include "types.h"
+#include "rmd.h"
+#include "sha1.h"
+#include "md5.h"
+
+#define MD_BUFFER_SIZE 512
+
+typedef struct {
+    int use_rmd160;
+    RMD160_CONTEXT rmd160;
+    int use_sha1;
+    SHA1_CONTEXT sha1;
+    int use_md5;
+    MD5_CONTEXT md5;
+    byte buffer[MD_BUFFER_SIZE]; /* primary buffer */
+    int  bufcount;
+} *MD_HANDLE;
+
+
+#define md_putc(h,c)                                       \
+           do {                                            \
+               if( (h)->bufcount == MD_BUFFER_SIZE )       \
+                   md_write( (h), NULL, 0 );               \
+               (h)->buffer[(h)->bufcount++] = (c) & 0xff;  \
+           } while(0)
+
+/*-- md.c --*/
+MD_HANDLE md_open( int algo, int secure );
+void md_enable( MD_HANDLE hd, int algo );
+MD_HANDLE md_copy( MD_HANDLE a );
+void md_close(MD_HANDLE a);
+void md_write( MD_HANDLE a, byte *inbuf, size_t inlen);
+void md_final(MD_HANDLE a);
+byte *md_read( MD_HANDLE a, int algo );
+int md_get_algo( MD_HANDLE a );
+
+
+#endif /*G10_MD_H*/
index be26026..6906503 100644 (file)
@@ -61,7 +61,6 @@
 #include <assert.h>
 #include "util.h"
 #include "md5.h"
-#include "cipher.h"  /* kludge for md5_copy2md() */
 #include "memory.h"
 
 
@@ -74,7 +73,7 @@
 #endif
 
 
-static void Init( MD5HANDLE mdContext);
+static void Init( MD5_CONTEXT *mdContext);
 static void Transform(u32 *buf,u32 *in);
 
 static byte PADDING[64] = {
@@ -120,56 +119,9 @@ static byte PADDING[64] = {
    (a) += (b); \
   }
 
-/* The routine Init initializes the message-digest context
- * mdContext. All fields are set to zero.
- * mode should be zero is reserved for extensions.
- */
-
-MD5HANDLE
-md5_open(int secure)
-{
-    MD5HANDLE mdContext;
-
-    mdContext = secure? m_alloc_secure( sizeof *mdContext )
-                     : m_alloc( sizeof *mdContext );
-    Init(mdContext);
-    return mdContext;
-}
-
-
-MD5HANDLE
-md5_copy( MD5HANDLE a )
-{
-    MD5HANDLE mdContext;
-
-    assert(a);
-    mdContext = m_is_secure(a)? m_alloc_secure( sizeof *mdContext )
-                             : m_alloc( sizeof *mdContext );
-    memcpy( mdContext, a, sizeof *a );
-    return mdContext;
-}
-
-
-/* BAD Kludge!!! */
-MD_HANDLE *
-md5_copy2md( MD5HANDLE a )
-{
-    MD_HANDLE *md = md_makecontainer( DIGEST_ALGO_MD5 );
-    md->u.md5 = md5_copy( a );
-    return md;
-}
-
 
 void
-md5_close(MD5HANDLE hd)
-{
-    if( hd )
-       m_free(hd);
-}
-
-
-static void
-Init( MD5HANDLE mdContext)
+md5_init( MD5_CONTEXT *mdContext)
 {
     mdContext->i[0] = mdContext->i[1] = (u32)0;
     /* Load magic initialization constants.
@@ -178,7 +130,7 @@ Init( MD5HANDLE mdContext)
     mdContext->buf[1] = (u32)0xefcdab89L;
     mdContext->buf[2] = (u32)0x98badcfeL;
     mdContext->buf[3] = (u32)0x10325476L;
-    mdContext->bufcount = 0;
+    mdContext->count = 0;
 }
 
 /* The routine Update updates the message-digest context to
@@ -186,15 +138,15 @@ Init( MD5HANDLE mdContext)
  * in the message whose digest is being computed.
  */
 void
-md5_write( MD5HANDLE mdContext, byte *inBuf, size_t inLen)
+md5_write( MD5_CONTEXT *mdContext, byte *inBuf, size_t inLen)
 {
     register int i, ii;
     int mdi;
     u32 in[16];
 
-    if(mdContext->bufcount) { /* flush the buffer */
-       i = mdContext->bufcount;
-       mdContext->bufcount = 0;
+    if(mdContext->count) { /* flush the buffer */
+       i = mdContext->count;
+       mdContext->count = 0;
        md5_write( mdContext, mdContext->digest, i);
     }
     if( !inBuf )
@@ -227,20 +179,6 @@ md5_write( MD5HANDLE mdContext, byte *inBuf, size_t inLen)
 }
 
 
-/****************
- * Process a single character, this character will be buffered to
- * increase performance. The digest-field is used as a buffer.
- */
-
-void
-md5_putchar( MD5HANDLE mdContext, int c )
-{
-    if(mdContext->bufcount == 16)
-       md5_write( mdContext, NULL, 0 );
-    mdContext->digest[mdContext->bufcount++] = c & 0xff;
-}
-
-
 
 /* The routine final terminates the message-digest computation and
  * ends with the desired message digest in mdContext->digest[0...15].
@@ -249,14 +187,14 @@ md5_putchar( MD5HANDLE mdContext, int c )
  */
 
 void
-md5_final(MD5HANDLE mdContext)
+md5_final( MD5_CONTEXT *mdContext )
 {
     u32 in[16];
     int mdi;
     unsigned int i, ii;
     unsigned int padLen;
 
-    if(mdContext->bufcount) /* flush buffer */
+    if(mdContext->count) /* flush buffer */
        md5_write(mdContext, NULL, 0 );
     /* save number of bits */
     in[14] = mdContext->i[0];
@@ -284,49 +222,6 @@ md5_final(MD5HANDLE mdContext)
        mdContext->digest[ii+2] = (byte)((mdContext->buf[i] >> 16) & 0xFF);
        mdContext->digest[ii+3] = (byte)((mdContext->buf[i] >> 24) & 0xFF);
     }
-    Init(mdContext);
-}
-
-/**********
- * Returns 16 bytes representing the digest.
- */
-byte *
-md5_read(MD5HANDLE mdContext)
-{
-    return mdContext->digest;
-}
-
-
-
-/****************
- * Converts the result form Read into a printable representation.
- * This should only be used direct after a md5_read(), because it uses
- * In-Place conversion.
- * Returns digest.
- */
-
-char *
-md5_tostring( byte *digest )
-{
-    static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ."
-                            "abcdefghijklmnopqrstuvwxyz_"
-                            "0123456789";
-    int i;
-    byte *d, *s;
-
-    memmove(digest+8,digest, 16); /* make some room */
-    d = digest;
-    s = digest+8;
-    for(i=0; i < 5; i++, s += 3 ) {
-       *d++ = bintoasc[(*s >> 2) & 077];
-       *d++ = bintoasc[(((*s << 4) & 060) | ((s[1] >> 4) & 017)) & 077];
-       *d++ = bintoasc[(((s[1] << 2) & 074) | ((s[2] >> 6) & 03)) & 077];
-       *d++ = bintoasc[s[2] & 077];
-    }
-    *d++ = bintoasc[(*s >> 2) & 077];
-    *d++ = bintoasc[((*s << 4) & 060) & 077];
-    *d = 0;
-    return (char*)digest;
 }
 
 
index fa401a1..c46075a 100644 (file)
 typedef struct {
     u32 i[2];            /* number of _bits_ handled mod 2^64 */
     u32 buf[4];          /* scratch buffer */
+    int count;
     byte in[64];         /* input buffer */
     byte digest[16+8+1];  /* actual digest after Final call */
-    byte bufcount;       /* extra room for bintoascii */
-} *MD5HANDLE;
+} MD5_CONTEXT;
 
-/*-- md5.c --*/
-MD5HANDLE md5_open(int);
-MD5HANDLE md5_copy(MD5HANDLE a);
-void md5_write(MD5HANDLE hd, byte *inBuf, size_t inLen);
-void md5_putchar(MD5HANDLE hd, int c );
-void md5_final(MD5HANDLE hd);
-byte *md5_read(MD5HANDLE hd);
-char *md5_tostring( byte *digest );
-void md5_close(MD5HANDLE hd);
 
+void md5_init( MD5_CONTEXT *c );
+void md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen);
+void md5_final( MD5_CONTEXT *hd);
+#define md5_read(h) ( (h)->digest )
 
 #endif /*G10_MD5_H*/
index a95e7e5..41f001e 100644 (file)
@@ -82,13 +82,12 @@ open_device( const char *name, int minor )
        log_fatal("can't open %s: %s\n", name, strerror(errno) );
     if( fstat( fd, &sb ) )
        log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
-    if( !S_ISCHR(sb.st_mode)
-      #ifdef __linux__
-       || (sb.st_rdev >> 8) != 1
-       || (sb.st_rdev & 0xff) != minor
-      #endif
-      )
+  #if defined(__sparc__) && defined(__linux__)
+    #warning something is wrong with UltraPenguin /dev/random
+  #else
+    if( !S_ISCHR(sb.st_mode) )
        log_fatal("invalid random device!\n" );
+  #endif
     return fd;
 }
 
@@ -140,6 +139,10 @@ the OS a chance to collect more entropy! (Need %d more bytes)\n", length );
        assert( length < 200 );
        do {
            n = read(fd, buffer, length );
+           if( n > length ) {
+               log_error("bogus read from random device (n=%d)\n", n );
+               n = length;
+           }
        } while( n == -1 && errno == EINTR );
        if( n == -1 )
            log_fatal("read error on random device: %s\n", strerror(errno) );
index 3d260cd..8f53634 100644 (file)
 typedef struct {
     u32  h0,h1,h2,h3,h4;
     u32  nblocks;
-    byte buffer[64];
-    int  bufcount;
-} *RMDHANDLE;
+    byte buf[64];
+    int  count;
+} RMD160_CONTEXT;
 
 
-/****************
- * Process a single character, this character will be buffered to
- * increase performance.
- */
-#define rmd160_putchar(h,c)                                \
-           do {                                            \
-               if( (h)->bufcount == 64 )                   \
-                   rmd160_write( (h), NULL, 0 );           \
-               (h)->buffer[(h)->bufcount++] = (c) & 0xff;  \
-           } while(0)
-
-RMDHANDLE rmd160_open( int secure );
-RMDHANDLE rmd160_copy( RMDHANDLE a );
-void     rmd160_close(RMDHANDLE hd);
-void     rmd160_write( RMDHANDLE hd, byte *inbuf, size_t inlen);
-byte *   rmd160_final(RMDHANDLE hd);
-
+void rmd160_init( RMD160_CONTEXT *c );
+void rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen);
+void rmd160_final(RMD160_CONTEXT *hd);
+#define rmd160_read(h) ( (h)->buf )
 
 #endif /*G10_RMD_H*/
index e8c424f..0b501d7 100644 (file)
@@ -25,7 +25,6 @@
 #include <assert.h>
 #include "util.h"
 #include "memory.h"
-#include "cipher.h" /* grrrr */
 #include "rmd.h"
 
 /*********************************
  */
 
 
-static void
-initialize( RMDHANDLE hd )
+void
+rmd160_init( RMD160_CONTEXT *hd )
 {
     hd->h0 = 0x67452301;
     hd->h1 = 0xEFCDAB89;
     hd->h2 = 0x98BADCFE;
     hd->h3 = 0x10325476;
     hd->h4 = 0xC3D2E1F0;
-    hd->bufcount = 0;
     hd->nblocks = 0;
+    hd->count = 0;
 }
 
 
@@ -156,7 +155,7 @@ initialize( RMDHANDLE hd )
  * Transform the message X which consists of 16 32-bit-words
  */
 static void
-transform( RMDHANDLE hd, byte *data )
+transform( RMD160_CONTEXT *hd, byte *data )
 {
     static int r[80] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
@@ -257,68 +256,22 @@ transform( RMDHANDLE hd, byte *data )
 
 
 
-
-RMDHANDLE
-rmd160_open( int secure )
-{
-    RMDHANDLE hd;
-
-    hd = secure? m_alloc_secure( sizeof *hd )
-              : m_alloc( sizeof *hd );
-    initialize(hd);
-    return hd;
-}
-
-
-RMDHANDLE
-rmd160_copy( RMDHANDLE a )
-{
-    RMDHANDLE b;
-
-    assert(a);
-    b = m_is_secure(a)? m_alloc_secure( sizeof *b )
-                     : m_alloc( sizeof *b );
-    memcpy( b, a, sizeof *a );
-    return b;
-}
-
-
-/* BAD Kludge!!! */
-MD_HANDLE *
-rmd160_copy2md( RMDHANDLE a )
-{
-    MD_HANDLE *md = md_makecontainer( DIGEST_ALGO_RMD160 );
-    md->u.rmd = rmd160_copy( a );
-    return md;
-}
-
-
-
-void
-rmd160_close(RMDHANDLE hd)
-{
-    if( hd )
-       m_free(hd);
-}
-
-
-
 /* Update the message digest with the contents
  * of INBUF with length INLEN.
  */
 void
-rmd160_write( RMDHANDLE hd, byte *inbuf, size_t inlen)
+rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
 {
-    if( hd->bufcount == 64 ) { /* flush the buffer */
-       transform( hd, hd->buffer );
-       hd->bufcount = 0;
+    if( hd->count == 64 ) { /* flush the buffer */
+       transform( hd, hd->buf );
+       hd->count = 0;
        hd->nblocks++;
     }
     if( !inbuf )
        return;
-    if( hd->bufcount ) {
-       for( ; inlen && hd->bufcount < 64; inlen-- )
-           hd->buffer[hd->bufcount++] = *inbuf++;
+    if( hd->count ) {
+       for( ; inlen && hd->count < 64; inlen-- )
+           hd->buf[hd->count++] = *inbuf++;
        rmd160_write( hd, NULL, 0 );
        if( !inlen )
            return;
@@ -326,25 +279,21 @@ rmd160_write( RMDHANDLE hd, byte *inbuf, size_t inlen)
 
     while( inlen >= 64 ) {
        transform( hd, inbuf );
-       hd->bufcount = 0;
+       hd->count = 0;
        hd->nblocks++;
        inlen -= 64;
        inbuf += 64;
     }
-    for( ; inlen && hd->bufcount < 64; inlen-- )
-       hd->buffer[hd->bufcount++] = *inbuf++;
+    for( ; inlen && hd->count < 64; inlen-- )
+       hd->buf[hd->count++] = *inbuf++;
 }
 
 
-/* The routine final terminates the computation and
- * returns the digest.
- * The handle is prepared for a new cycle, but adding bytes to the
- * handle will the destroy the returned buffer.
- * Returns: 20 bytes representing the digest.
+/* The routine terminates the computation
  */
 
-byte *
-rmd160_final(RMDHANDLE hd)
+void
+rmd160_final( RMD160_CONTEXT *hd )
 {
     u32 t, msb, lsb;
     byte *p;
@@ -357,37 +306,37 @@ rmd160_final(RMDHANDLE hd)
        msb++;
     msb += t >> 26;
     t = lsb;
-    if( (lsb = t + hd->bufcount) < t ) /* add the bufcount */
+    if( (lsb = t + hd->count) < t ) /* add the count */
        msb++;
     t = lsb;
     if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
        msb++;
     msb += t >> 29;
 
-    if( hd->bufcount < 56 ) { /* enough room */
-       hd->buffer[hd->bufcount++] = 0x80; /* pad */
-       while( hd->bufcount < 56 )
-           hd->buffer[hd->bufcount++] = 0;  /* pad */
+    if( hd->count < 56 ) { /* enough room */
+       hd->buf[hd->count++] = 0x80; /* pad */
+       while( hd->count < 56 )
+           hd->buf[hd->count++] = 0;  /* pad */
     }
     else { /* need one extra block */
-       hd->buffer[hd->bufcount++] = 0x80; /* pad character */
-       while( hd->bufcount < 64 )
-           hd->buffer[hd->bufcount++] = 0;
+       hd->buf[hd->count++] = 0x80; /* pad character */
+       while( hd->count < 64 )
+           hd->buf[hd->count++] = 0;
        rmd160_write(hd, NULL, 0);  /* flush */;
-       memset(hd->buffer, 0, 56 ); /* fill next block with zeroes */
+       memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
     }
     /* append the 64 bit count */
-    hd->buffer[56] = lsb      ;
-    hd->buffer[57] = lsb >>  8;
-    hd->buffer[58] = lsb >> 16;
-    hd->buffer[59] = lsb >> 24;
-    hd->buffer[60] = msb      ;
-    hd->buffer[61] = msb >>  8;
-    hd->buffer[62] = msb >> 16;
-    hd->buffer[63] = msb >> 24;
-    transform( hd, hd->buffer );
-
-    p = hd->buffer;
+    hd->buf[56] = lsb     ;
+    hd->buf[57] = lsb >>  8;
+    hd->buf[58] = lsb >> 16;
+    hd->buf[59] = lsb >> 24;
+    hd->buf[60] = msb     ;
+    hd->buf[61] = msb >>  8;
+    hd->buf[62] = msb >> 16;
+    hd->buf[63] = msb >> 24;
+    transform( hd, hd->buf );
+
+    p = hd->buf;
   #ifdef BIG_ENDIAN_HOST
     #define X(a) do { *p++ = hd->h##a     ; *p++ = hd->h##a >> 8;      \
                      *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
@@ -400,10 +349,6 @@ rmd160_final(RMDHANDLE hd)
     X(3);
     X(4);
   #undef X
-
-    initialize( hd );  /* prepare for next cycle */
-    return hd->buffer; /* now contains the digest */
 }
 
 
-
index 1685058..51029c4 100644 (file)
@@ -84,7 +84,6 @@
 #include <assert.h>
 #include "util.h"
 #include "memory.h"
-#include "cipher.h" /* grrrr */
 #include "sha1.h"
 
 
     ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
 
 
-static void
-initialize( SHA1HANDLE hd )
+void
+sha1_init( SHA1_CONTEXT *hd )
 {
     hd->h0 = 0x67452301;
     hd->h1 = 0xefcdab89;
     hd->h2 = 0x98badcfe;
     hd->h3 = 0x10325476;
     hd->h4 = 0xc3d2e1f0;
-    hd->bufcount = 0;
     hd->nblocks = 0;
+    hd->count = 0;
 }
 
 
@@ -127,7 +126,7 @@ initialize( SHA1HANDLE hd )
  * Transform the message X which consists of 16 32-bit-words
  */
 static void
-transform( SHA1HANDLE hd, byte *data )
+transform( SHA1_CONTEXT *hd, byte *data )
 {
     u32 A, B, C, D, E;    /* Local vars */
     u32 eData[ 16 ];      /* Expanded data */
@@ -247,69 +246,22 @@ transform( SHA1HANDLE hd, byte *data )
 }
 
 
-
-
-SHA1HANDLE
-sha1_open( int secure )
-{
-    SHA1HANDLE hd;
-
-    hd = secure? m_alloc_secure( sizeof *hd )
-              : m_alloc( sizeof *hd );
-    initialize(hd);
-    return hd;
-}
-
-
-SHA1HANDLE
-sha1_copy( SHA1HANDLE a )
-{
-    SHA1HANDLE b;
-
-    assert(a);
-    b = m_is_secure(a)? m_alloc_secure( sizeof *b )
-                     : m_alloc( sizeof *b );
-    memcpy( b, a, sizeof *a );
-    return b;
-}
-
-
-/* BAD Kludge!!! */
-MD_HANDLE *
-sha1_copy2md( SHA1HANDLE a )
-{
-    MD_HANDLE *md = md_makecontainer( DIGEST_ALGO_SHA1 );
-    md->u.sha1 = sha1_copy( a );
-    return md;
-}
-
-
-
-void
-sha1_close(SHA1HANDLE hd)
-{
-    if( hd )
-       m_free(hd);
-}
-
-
-
 /* Update the message digest with the contents
  * of INBUF with length INLEN.
  */
 void
-sha1_write( SHA1HANDLE hd, byte *inbuf, size_t inlen)
+sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen)
 {
-    if( hd->bufcount == 64 ) { /* flush the buffer */
-       transform( hd, hd->buffer );
-       hd->bufcount = 0;
+    if( hd->count == 64 ) { /* flush the buffer */
+       transform( hd, hd->buf );
+       hd->count = 0;
        hd->nblocks++;
     }
     if( !inbuf )
        return;
-    if( hd->bufcount ) {
-       for( ; inlen && hd->bufcount < 64; inlen-- )
-           hd->buffer[hd->bufcount++] = *inbuf++;
+    if( hd->count ) {
+       for( ; inlen && hd->count < 64; inlen-- )
+           hd->buf[hd->count++] = *inbuf++;
        sha1_write( hd, NULL, 0 );
        if( !inlen )
            return;
@@ -317,13 +269,13 @@ sha1_write( SHA1HANDLE hd, byte *inbuf, size_t inlen)
 
     while( inlen >= 64 ) {
        transform( hd, inbuf );
-       hd->bufcount = 0;
+       hd->count = 0;
        hd->nblocks++;
        inlen -= 64;
        inbuf += 64;
     }
-    for( ; inlen && hd->bufcount < 64; inlen-- )
-       hd->buffer[hd->bufcount++] = *inbuf++;
+    for( ; inlen && hd->count < 64; inlen-- )
+       hd->buf[hd->count++] = *inbuf++;
 }
 
 
@@ -334,8 +286,8 @@ sha1_write( SHA1HANDLE hd, byte *inbuf, size_t inlen)
  * Returns: 20 bytes representing the digest.
  */
 
-byte *
-sha1_final(SHA1HANDLE hd)
+void
+sha1_final(SHA1_CONTEXT *hd)
 {
     u32 t, msb, lsb;
     byte *p;
@@ -348,37 +300,37 @@ sha1_final(SHA1HANDLE hd)
        msb++;
     msb += t >> 26;
     t = lsb;
-    if( (lsb = t + hd->bufcount) < t ) /* add the bufcount */
+    if( (lsb = t + hd->count) < t ) /* add the count */
        msb++;
     t = lsb;
     if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
        msb++;
     msb += t >> 29;
 
-    if( hd->bufcount < 56 ) { /* enough room */
-       hd->buffer[hd->bufcount++] = 0x80; /* pad */
-       while( hd->bufcount < 56 )
-           hd->buffer[hd->bufcount++] = 0;  /* pad */
+    if( hd->count < 56 ) { /* enough room */
+       hd->buf[hd->count++] = 0x80; /* pad */
+       while( hd->count < 56 )
+           hd->buf[hd->count++] = 0;  /* pad */
     }
     else { /* need one extra block */
-       hd->buffer[hd->bufcount++] = 0x80; /* pad character */
-       while( hd->bufcount < 64 )
-           hd->buffer[hd->bufcount++] = 0;
+       hd->buf[hd->count++] = 0x80; /* pad character */
+       while( hd->count < 64 )
+           hd->buf[hd->count++] = 0;
        sha1_write(hd, NULL, 0);  /* flush */;
-       memset(hd->buffer, 0, 56 ); /* fill next block with zeroes */
+       memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
     }
     /* append the 64 bit count */
-    hd->buffer[56] = msb >> 24;
-    hd->buffer[57] = msb >> 16;
-    hd->buffer[58] = msb >>  8;
-    hd->buffer[59] = msb      ;
-    hd->buffer[60] = lsb >> 24;
-    hd->buffer[61] = lsb >> 16;
-    hd->buffer[62] = lsb >>  8;
-    hd->buffer[63] = lsb      ;
-    transform( hd, hd->buffer );
-
-    p = hd->buffer;
+    hd->buf[56] = msb >> 24;
+    hd->buf[57] = msb >> 16;
+    hd->buf[58] = msb >>  8;
+    hd->buf[59] = msb     ;
+    hd->buf[60] = lsb >> 24;
+    hd->buf[61] = lsb >> 16;
+    hd->buf[62] = lsb >>  8;
+    hd->buf[63] = lsb     ;
+    transform( hd, hd->buf );
+
+    p = hd->buf;
   #ifdef BIG_ENDIAN_HOST
     #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
   #else /* little endian */
@@ -392,8 +344,6 @@ sha1_final(SHA1HANDLE hd)
     X(4);
   #undef X
 
-    initialize( hd );  /* prepare for next cycle */
-    return hd->buffer; /* now contains the digest */
 }
 
 
index ca03936..93af2ca 100644 (file)
 typedef struct {
     u32  h0,h1,h2,h3,h4;
     u32  nblocks;
-    byte buffer[64];
-    int  bufcount;
-} *SHA1HANDLE;
+    byte buf[64];
+    int  count;
+} SHA1_CONTEXT;
 
 
-/****************
- * Process a single character, this character will be buffered to
- * increase performance.
- */
-#define sha1_putchar(h,c)                                  \
-           do {                                            \
-               if( (h)->bufcount == 64 )                   \
-                   sha1_write( (h), NULL, 0 );             \
-               (h)->buffer[(h)->bufcount++] = (c) & 0xff;  \
-           } while(0)
-
-SHA1HANDLE sha1_open( int secure );
-SHA1HANDLE sha1_copy( SHA1HANDLE a );
-void      sha1_close( SHA1HANDLE hd );
-void      sha1_write( SHA1HANDLE hd, byte *inbuf, size_t inlen );
-byte *    sha1_final( SHA1HANDLE hd );
+void sha1_init( SHA1_CONTEXT *c );
+void sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen);
+void sha1_final( SHA1_CONTEXT *hd);
+#define sha1_read(h) ( (h)->buf )
 
 #endif /*G10_SHA1_H*/
index 3b447c7..a3a2773 100644 (file)
@@ -2,6 +2,107 @@
 
     * For packet version 3 we calculate the keyids this way:
        RSA     := low 64 bits of n
-       ELGAMAL := low 64 bits of y
+       ELGAMAL := build a v3 pubkey packet (with CTB 0x99) and calculate
+                  a rmd160 hash value from it. This is used as the
+                  fingerprint and the low 64 bits are the keyid.
 
 
+
+
+Layout of the TrustDB
+=====================
+The TrustDB is build from fixed length records, where the first bytes
+describes the record type.  All numeric values are stored in network
+byte order. The length of each record is 40 bytes. The first record of
+the DB is always of type 1 and this is the only record of this type.
+
+Record type 0:
+--------------
+    Unused record, can be reused for any purpose.
+
+Record type 1:
+--------------
+    Version information for this TrustDB.  This is always the first
+    record of the DB and the onyl one with type 1.
+     1 byte value 1
+     3 bytes 'g10'  magic value
+     1 byte Version of the TrustDB
+     3 byte reserved
+     1 u32  locked by (pid) 0 = not locked.
+     1 u32  timestamp of trustdb creation
+     1 u32  timestamp of last modification
+     1 u32  timestamp of last validation
+           (Used to keep track of the time, when this TrustDB was checked
+            against the pubring)
+     1 u32  Local-Id-Counter.  Used to keep track of Local-IDs.
+           32 bits are enough numbers for all practial purposes; if this
+           counter rolls over (due to deleted keyblock,an d new ones),
+           the software should reassign new Local-Ids to the whole
+           database (not expected to ever occur).
+     1 byte marginals needed
+     1 byte completes needed
+     1 byte max. cert depth
+           If any of this 3 values are changed, all cache records
+           muts be invalidated.
+     9 bytes reserved
+
+Record type 2:
+--------------
+    Informations about a public key certificate.
+
+     1 byte value 2
+     1 byte   reserved
+     1 u32   Local-Id. This is used to bind all records for
+            a given certificate together. It is valid only in this TrustDB
+            and usefull if we have duplicate keyids
+            It is not defined, how an implementaion selects such
+            a Local-Id, but it may use the local-ID counter from
+            record type 1
+     8 bytes keyid (of the primary key)
+     1 byte pubkey algorithm
+     1 byte reserved
+     20 bytes fingerprint of the public key
+     1 byte ownertrust:
+             Bits 2-0:
+              0 = undefined (not yet initialized)
+              1 = unknown owner (could not initialize it)
+              2 = do not trust this owner
+              3 = usually trust this owner
+              4 = always trust this owner
+              5 = ultimately trust this owner.  This can only be set if
+                  we have control over the secret key too.
+             Bit 3: set if key is revoked; do not use it.
+             Bit 7-4: reserved
+     3 byte reserved
+
+
+Record type 3: (cache record)
+--------------
+    Used to bind the trustDB to the concrete instance of keyblock in
+    a pubring. This is used to cache informations.
+
+     1 byte   value 3
+     1 byte   reserved
+     1 u32    Local-Id.
+     8 bytes  keyid of the primary key
+     1 byte   cache-is-valid the following stuff is only
+             valid if this is set.
+     1 byte   reserved
+     20 bytes rmd160 hash value over the complete keyblock
+             This is used to detect any changes of the keyblock with all
+             CTBs and lengths headers. Calculation is easy if the keyblock
+             is optained from a keyserved: simply create the hash from all
+             received data bytes.
+
+     1 byte   number of untrusted signatures.
+     1 byte   number of marginal trusted signatures.
+     1 byte   number of fully trusted signatures.
+             (255 is stored for all values greater than 254)
+     1 byte   Trustlevel
+               0 = undefined (not calculated)
+               1 = unknown
+               2 = not trusted
+               3 = marginally trusted
+               4 = fully trusted
+               5 = ultimately trusted (have secret key too).
+
index 901370f..b6b9ce5 100644 (file)
@@ -31,6 +31,7 @@ g10_SOURCES = g10.c           \
              openfile.c        \
              keyid.c           \
              trustdb.c         \
+             trustdb.h         \
              packet.h          \
              parse-packet.c    \
              passphrase.c      \
index 531b1b8..7e5ef73 100644 (file)
@@ -69,6 +69,7 @@ g10_SOURCES = g10.c           \
              openfile.c        \
              keyid.c           \
              trustdb.c         \
+             trustdb.h         \
              packet.h          \
              parse-packet.c    \
              passphrase.c      \
index 6c526e3..5bacf3f 100644 (file)
@@ -196,7 +196,7 @@ do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc )
  * Make a hash value from the public key certificate
  */
 void
-hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc )
+hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
 {
     PACKET pkt;
     int rc = 0;
@@ -210,7 +210,7 @@ hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc )
     if( (rc = build_packet( a, &pkt )) )
        log_fatal("build public_cert for hashing failed: %s\n", g10_errstr(rc));
     while( (c=iobuf_get(a)) != -1 )
-       md_putchar( md, c );
+       md_putc( md, c );
 
     iobuf_cancel(a);
 }
index 9f11d63..492049a 100644 (file)
--- a/g10/elg.c
+++ b/g10/elg.c
@@ -66,7 +66,7 @@ g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
 
 
 void
-g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md )
+g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md )
 {
     ELG_secret_key skey;
     MPI frame;
@@ -74,9 +74,10 @@ g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md )
 
     assert( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL );
 
-    dp = md_final( md );
+    md_final( md );
+    dp = md_read( md, 0 );
     keyid_from_skc( skc, sig->keyid );
-    sig->d.elg.digest_algo = md->algo;
+    sig->d.elg.digest_algo = md_get_algo(md);
     sig->d.elg.digest_start[0] = dp[0];
     sig->d.elg.digest_start[1] = dp[1];
     sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );
index 83ed3d1..bedacf9 100644 (file)
@@ -23,9 +23,7 @@
 #include "cipher.h"
 
 typedef struct {
-    MD_HANDLE *md;     /* catch all */
-    MD5HANDLE md5;     /* if !NULL create md5  */
-    RMDHANDLE rmd160;  /* if !NULL create rmd160  */
+    MD_HANDLE md;      /* catch all */
     size_t maxbuf_size;
 } md_filter_context_t;
 
index dfd6f4b..fb5949a 100644 (file)
@@ -68,8 +68,7 @@ free_public_cert( PKT_public_cert *cert )
        mpi_free( cert->d.rsa.rsa_n );
        mpi_free( cert->d.rsa.rsa_e );
     }
-    md5_close( cert->mfx.md5 );
-    rmd160_close( cert->mfx.rmd160 );
+    md_close( cert->mfx.md );
     m_free(cert);
 }
 
@@ -88,8 +87,7 @@ copy_public_cert( PKT_public_cert *d, PKT_public_cert *s )
        d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n );
        d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e );
     }
-    d->mfx.md5 = NULL;
-    d->mfx.rmd160 =NULL;
+    d->mfx.md = NULL;
     return d;
 }
 
index 30776cc..e5c7139 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -34,6 +34,7 @@
 #include "mpi.h"
 #include "cipher.h"
 #include "filter.h"
+#include "trustdb.h"
 
 enum cmd_values { aNull = 0,
     aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
@@ -392,6 +393,13 @@ main( int argc, char **argv )
        }
     }
 
+    if( cmd != aPrimegen && cmd != aPrintMDs ) {
+       rc = check_trustdb(0);
+       if( rc )
+           log_error("failed to initialize the TrustDB: %s\n", g10_errstr(rc));
+    }
+
+
     switch( cmd ) {
       case aStore: /* only store the file */
        if( argc > 1 )
@@ -582,9 +590,7 @@ print_mds( const char *fname )
     FILE *fp;
     char buf[1024];
     size_t n;
-    MD5HANDLE md5;
-    RMDHANDLE rmd160;
-    SHA1HANDLE sha1;
+    MD_HANDLE md;
 
     if( !fname ) {
        fp = stdin;
@@ -597,31 +603,26 @@ print_mds( const char *fname )
        return;
     }
 
-    md5    = md5_open(0);
-    rmd160 = rmd160_open(0);
-    sha1   = sha1_open(0);
+    md = md_open( DIGEST_ALGO_MD5, 0 );
+    md_enable( md, DIGEST_ALGO_RMD160 );
+    md_enable( md, DIGEST_ALGO_SHA1 );
 
-    while( (n=fread( buf, 1, DIM(buf), fp )) ) {
-       md5_write( md5, buf, n );
-       rmd160_write( rmd160, buf, n );
-       sha1_write( sha1, buf, n );
-    }
+    while( (n=fread( buf, 1, DIM(buf), fp )) )
+       md_write( md, buf, n );
     if( ferror(fp) )
        log_error("%s: %s\n", fname, strerror(errno) );
     else {
        byte *p;
 
-       md5_final(md5);
-       printf(  "%s:    MD5 =", fname ); print_hex(md5_read(md5), 16 );
-       printf("\n%s: RMD160 =", fname ); print_hex(rmd160_final(rmd160), 20 );
-       printf("\n%s:   SHA1 =", fname ); print_hex(sha1_final(sha1), 20 );
+       md_final(md);
+       printf(  "%s:    MD5 =", fname ); print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
+       printf("\n%s: RMD160 =", fname ); print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
+       printf("\n%s:   SHA1 =", fname ); print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
        putchar('\n');
     }
 
 
-    md5_close(md5);
-    rmd160_close(rmd160);
-    sha1_close(sha1);
+    md_close(md);
 
     if( fp != stdin )
        fclose(fp);
index fddeedb..c83d866 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 #include <errno.h>
 #include <assert.h>
 #include "util.h"
@@ -408,7 +409,7 @@ generate_keypair()
     tty_printf( "\n"
 "You need a User-ID to identify your key; the software constructs the user id\n"
 "from Real Name, Comment and Email Address in this form:\n"
-"    \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n" );
+"    \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n\n" );
     uid = NULL;
     aname=acomment=amail=NULL;
     for(;;) {
@@ -422,6 +423,8 @@ generate_keypair()
                tty_kill_prompt();
                if( strpbrk( aname, "<([])>" ) )
                    tty_printf("Invalid character in name\n");
+               else if( isdigit(*aname) )
+                   tty_printf("Name may not start with a digit\n");
                else if( strlen(aname) < 5 )
                    tty_printf("Name must be at least 5 characters long\n");
                else
@@ -464,12 +467,15 @@ generate_keypair()
        }
 
        m_free(uid);
-       uid = p = m_alloc(strlen(aname)+strlen(amail)+strlen(acomment)+10);
+       uid = p = m_alloc(strlen(aname)+strlen(amail)+strlen(acomment)+12+10);
        p = stpcpy(p, aname );
        if( *acomment )
            p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")");
        if( *amail )
            p = stpcpy(stpcpy(stpcpy(p," <"), amail),">");
+      #ifndef HAVE_DEV_RANDOM
+       strcpy(p, " (INSECURE!)" );
+      #endif
 
        tty_printf("You selected this USER-ID:\n    \"%s\"\n\n", uid);
        for(;;) {
index 43413e0..01604df 100644 (file)
@@ -48,14 +48,14 @@ pubkey_letter( int algo )
 
 /* this is special code for V3 which uses ElGamal and
  * calculates a fingerprint like V4, but with rmd160
- * and a version byte of 3. Returns an rmd160 handle, caller must
- * do rmd160_final()
+ * and a version byte of 3. Returns an md handle, caller must
+ * do md_close()
  */
 
-static RMDHANDLE
+static MD_HANDLE
 v3_elg_fingerprint_md( PKT_public_cert *pkc )
 {
-    RMDHANDLE md;
+    MD_HANDLE md;
     byte *buf1, *buf2, *buf3;
     byte *p1, *p2, *p3;
     unsigned n1, n2, n3;
@@ -73,35 +73,36 @@ v3_elg_fingerprint_md( PKT_public_cert *pkc )
 
     /* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */
     n = 14 + n1 + n2 + n3;
-    md = rmd160_open(0);
+    md = md_open( DIGEST_ALGO_RMD160, 0);
 
-    rmd160_putchar( md, 0x99 );     /* ctb */
-    rmd160_putchar( md, n >> 8 );   /* 2 byte length header */
-    rmd160_putchar( md, n );
-    rmd160_putchar( md, 3 );       /* version */
+    md_putc( md, 0x99 );     /* ctb */
+    md_putc( md, n >> 8 );   /* 2 byte length header */
+    md_putc( md, n );
+    md_putc( md, 3 );       /* version */
     {  u32 a = pkc->timestamp;
-       rmd160_putchar( md, a >> 24 );
-       rmd160_putchar( md, a >> 16 );
-       rmd160_putchar( md, a >>  8 );
-       rmd160_putchar( md, a       );
+       md_putc( md, a >> 24 );
+       md_putc( md, a >> 16 );
+       md_putc( md, a >>  8 );
+       md_putc( md, a       );
     }
     {  u16 a = pkc->valid_days;
-       rmd160_putchar( md, a >> 8 );
-       rmd160_putchar( md, a      );
+       md_putc( md, a >> 8 );
+       md_putc( md, a      );
     }
-    rmd160_putchar( md, pkc->pubkey_algo );
-    rmd160_putchar( md, n1>>8); rmd160_putchar( md, n1 ); rmd160_write( md, p1, n1 );
-    rmd160_putchar( md, n2>>8); rmd160_putchar( md, n2 ); rmd160_write( md, p2, n2 );
-    rmd160_putchar( md, n3>>8); rmd160_putchar( md, n3 ); rmd160_write( md, p3, n3 );
+    md_putc( md, pkc->pubkey_algo );
+    md_putc( md, n1>>8); md_putc( md, n1 ); md_write( md, p1, n1 );
+    md_putc( md, n2>>8); md_putc( md, n2 ); md_write( md, p2, n2 );
+    md_putc( md, n3>>8); md_putc( md, n3 ); md_write( md, p3, n3 );
     m_free(buf1);
     m_free(buf2);
     m_free(buf3);
+    md_final( md );
 
     return md;
 }
 
 
-static RMDHANDLE
+static MD_HANDLE
 v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
 {
     PKT_public_cert pkc;
@@ -133,13 +134,13 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
 
     if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
        const byte *dp;
-       RMDHANDLE md;
+       MD_HANDLE md;
        md = v3_elg_fingerprint_md_skc(skc);
-       dp = rmd160_final( md );
+       dp = md_read( md, DIGEST_ALGO_RMD160 );
        keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
        keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
        lowbits = keyid[1];
-       rmd160_close(md);
+       md_close(md);
     }
     else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
        lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid );
@@ -166,13 +167,13 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
 
     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
        const byte *dp;
-       RMDHANDLE md;
+       MD_HANDLE md;
        md = v3_elg_fingerprint_md(pkc);
-       dp = rmd160_final( md );
+       dp = md_read( md, DIGEST_ALGO_RMD160 );
        keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
        keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
        lowbits = keyid[1];
-       rmd160_close(md);
+       md_close(md);
     }
     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
        lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
@@ -310,33 +311,33 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
     unsigned n;
 
     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
-       RMDHANDLE md;
+       MD_HANDLE md;
        md = v3_elg_fingerprint_md(pkc);
-       dp = rmd160_final( md );
+       dp = md_read( md, DIGEST_ALGO_RMD160 );
        array = m_alloc( 20 );
        len = 20;
        memcpy(array, dp, 20 );
-       rmd160_close(md);
+       md_close(md);
     }
     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
-       MD5HANDLE md;
+       MD_HANDLE md;
 
-       md = md5_open(0);
+       md = md_open( DIGEST_ALGO_MD5, 0);
        p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL );
        for( ; !*p && n; p++, n-- )
            ;
-       md5_write( md, p, n );
+       md_write( md, p, n );
        m_free(buf);
        p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL );
        for( ; !*p && n; p++, n-- )
            ;
-       md5_write( md, p, n );
+       md_write( md, p, n );
        m_free(buf);
-       md5_final(md);
+       md_final(md);
        array = m_alloc( 16 );
        len = 16;
-       memcpy(array, md5_read(md), 16 );
-       md5_close(md);
+       memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
+       md_close(md);
     }
     else {
        array = m_alloc(1);
index 747ab70..a10ce4b 100644 (file)
@@ -64,18 +64,18 @@ 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 );
+MPI encode_md_value( MD_HANDLE md, unsigned nbits );
 
 /*-- comment.c --*/
 KBNODE make_comment_node( const char *s );
 
 /*-- elg.c --*/
 void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
-void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md );
+void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md );
 
 /*-- rsa.c --*/
 void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
-void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md );
+void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md );
 
 
 #endif /*G10_MAIN_H*/
index a99c975..f64a2cd 100644 (file)
@@ -268,7 +268,7 @@ proc_plaintext( CTX c, PACKET *pkt )
      * And look at the sigclass to check wether we should use the
      * textmode filter (sigclass 0x01)
      */
-    c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
+    c->mfx.md = md_open( DIGEST_ALGO_RMD160, 0);
     rc = handle_plaintext( pt, &c->mfx );
     if( rc )
        log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
@@ -302,7 +302,7 @@ static int
 do_check_sig( CTX c, KBNODE node )
 {
     PKT_signature *sig;
-    MD_HANDLE *md;
+    MD_HANDLE md;
     int algo, rc;
 
     assert( node->pkt->pkttype == PKT_SIGNATURE );
@@ -314,7 +314,7 @@ do_check_sig( CTX c, KBNODE node )
        algo = sig->d.rsa.digest_algo;
     else
        return G10ERR_PUBKEY_ALGO;
-    if( (rc=md_okay(algo)) )
+    if( (rc=check_digest_algo(algo)) )
        return rc;
 
     if( sig->sig_class == 0x00 ) {
@@ -328,10 +328,6 @@ do_check_sig( CTX c, KBNODE node )
 
                if( c->cert->pkt->pkt.public_cert->mfx.md )
                    md = md_copy( c->cert->pkt->pkt.public_cert->mfx.md );
-               else if( algo == DIGEST_ALGO_RMD160 )
-                   md = rmd160_copy2md( c->cert->pkt->pkt.public_cert->mfx.rmd160 );
-               else if( algo == DIGEST_ALGO_MD5 )
-                   md = md5_copy2md( c->cert->pkt->pkt.public_cert->mfx.md5 );
                else
                    log_bug(NULL);
                md_write( md, n1->pkt->pkt.user_id->name, n1->pkt->pkt.user_id->len);
index 5a77c90..17cf259 100644 (file)
@@ -53,12 +53,8 @@ md_filter( void *opaque, int control,
            buf[i] = c;
        }
 
-       if( i ) {
-           if( mfx->md5 )
-               md5_write(mfx->md5, buf, i );
-           if( mfx->rmd160 )
-               rmd160_write(mfx->rmd160, buf, i );
-       }
+       if( i )
+           md_write(mfx->md, buf, i );
        else
            rc = -1; /* eof */
        *ret_len = i;
@@ -72,12 +68,8 @@ md_filter( void *opaque, int control,
 void
 free_md_filter_context( md_filter_context_t *mfx )
 {
-    if( mfx->md5 )
-       md5_close(mfx->md5);
-    mfx->md5 = NULL;
-    if( mfx->rmd160 )
-       rmd160_close(mfx->rmd160);
-    mfx->rmd160 = NULL;
+    md_close(mfx->md);
+    mfx->md = NULL;
     mfx->maxbuf_size = 0;
 }
 
index 03a7f32..e82248a 100644 (file)
@@ -220,7 +220,7 @@ int parse_packet( IOBUF inp, PACKET *ret_pkt);
 /*-- build-packet.c --*/
 int build_packet( IOBUF inp, PACKET *pkt );
 u32 calc_packet_length( PACKET *pkt );
-void hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc );
+void hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc );
 
 /*-- free-packet.c --*/
 void free_pubkey_enc( PKT_pubkey_enc *enc );
@@ -235,7 +235,7 @@ PKT_secret_cert *copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s );
 
 
 /*-- sig-check.c --*/
-int signature_check( PKT_signature *sig, MD_HANDLE *digest );
+int signature_check( PKT_signature *sig, MD_HANDLE digest );
 
 /*-- seckey-cert.c --*/
 int is_secret_key_protected( PKT_secret_cert *cert );
index 70eef40..1d056d8 100644 (file)
@@ -438,11 +438,11 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
     int is_v4=0;
 
     if( pkttype == PKT_PUBLIC_CERT ) {
-       pkt->pkt.public_cert->mfx.md5 = md5_open(0);
-       pkt->pkt.public_cert->mfx.rmd160 = rmd160_open(0);
+       pkt->pkt.public_cert->mfx.md = md_open(DIGEST_ALGO_MD5, 0);
+       md_enable(pkt->pkt.public_cert->mfx.md, DIGEST_ALGO_RMD160);
+       md_enable(pkt->pkt.public_cert->mfx.md, DIGEST_ALGO_SHA1);
        pkt->pkt.public_cert->mfx.maxbuf_size = 1;
-       md5_write(pkt->pkt.public_cert->mfx.md5, hdr, hdrlen);
-       rmd160_write(pkt->pkt.public_cert->mfx.rmd160, hdr, hdrlen);
+       md_write(pkt->pkt.public_cert->mfx.md, hdr, hdrlen);
        iobuf_push_filter( inp, md_filter, &pkt->pkt.public_cert->mfx );
     }
 
index df8ac71..462c7c7 100644 (file)
@@ -143,13 +143,14 @@ hash_passphrase( DEK *dek, char *pw )
 
     dek->keylen = 0;
     if( dek->algo == CIPHER_ALGO_BLOWFISH ) {
-       RMDHANDLE rmd;
+       MD_HANDLE md;
 
-       rmd = rmd160_open(1);
-       rmd160_write( rmd, pw, strlen(pw) );
+       md = md_open(DIGEST_ALGO_RMD160, 1);
+       md_write( md, pw, strlen(pw) );
+       md_final( md );
        dek->keylen = 20;
-       memcpy( dek->key, rmd160_final(rmd), dek->keylen );
-       rmd160_close(rmd);
+       memcpy( dek->key, md_read(md,0), dek->keylen );
+       md_close(md);
     }
     else
        rc = G10ERR_UNSUPPORTED;
index 1356a06..f753eb6 100644 (file)
 #include "keydb.h"
 #include "memory.h"
 #include "util.h"
+#include "trustdb.h"
+
+
+/****************
+ * Check wether we can trust this pkc which has a trustlevel of TRUSTLEVEL
+ * Returns: true if we trust.
+ */
+static int
+do_we_trust( PKT_public_cert *pkc, int trustlevel )
+{
+    /* Eventuell fragen falls der trustlevel nicht ausreichend ist */
+
+
+    return 1; /* yes */
+}
+
 
 
 void
@@ -64,13 +80,27 @@ build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list )
                free_public_cert( pkc ); pkc = NULL;
                log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) );
            }
-           else if( is_valid_pubkey_algo(pkc->pubkey_algo) ) {
-               PKC_LIST r;
-               r = m_alloc( sizeof *r );
-               r->pkc = pkc; pkc = NULL;
-               r->next = pkc_list;
-               r->mark = 0;
-               pkc_list = r;
+           else if( !(rc=check_pubkey_algo(pkc->pubkey_algo)) ) {
+               int trustlevel;
+
+               rc = check_pkc_trust( pkc, &trustlevel );
+               if( rc ) {
+                   free_public_cert( pkc ); pkc = NULL;
+                   log_error("error checking pkc of '%s': %s\n",
+                                                     remusr->d, g10_errstr(rc) );
+               }
+               else if( do_we_trust( pkc, trustlevel ) ) {
+                   PKC_LIST r;
+
+                   r = m_alloc( sizeof *r );
+                   r->pkc = pkc; pkc = NULL;
+                   r->next = pkc_list;
+                   r->mark = 0;
+                   pkc_list = r;
+               }
+               else { /* we don't trust this pkc */
+                   free_public_cert( pkc ); pkc = NULL;
+               }
            }
            else {
                free_public_cert( pkc ); pkc = NULL;
index 114db1d..ea43a1e 100644 (file)
@@ -79,11 +79,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
                goto leave;
            }
            if( mfx->md )
-               md_putchar(mfx->md, c );
-           if( mfx->rmd160 )
-               rmd160_putchar(mfx->rmd160, c );
-           if( mfx->md5 )
-               md5_putchar(mfx->md5, c );
+               md_putc(mfx->md, c );
            if( putc( c, fp ) == EOF ) {
                log_error("Error writing to '%s': %s\n", fname, strerror(errno) );
                rc = G10ERR_WRITE_FILE;
@@ -93,10 +89,8 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
     }
     else {
        while( (c = iobuf_get(pt->buf)) != -1 ) {
-           if( mfx->rmd160 )
-               rmd160_putchar(mfx->rmd160, c );
-           if( mfx->md5 )
-               md5_putchar(mfx->md5, c );
+           if( mfx->md )
+               md_putc(mfx->md, c );
            if( putc( c, fp ) == EOF ) {
                log_error("Error writing to '%s': %s\n",
                                            fname, strerror(errno) );
@@ -162,11 +156,7 @@ ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname )
 
     while( (c = iobuf_get(fp)) != -1 ) {
        if( mfx->md )
-           md_putchar(mfx->md, c );
-       if( mfx->rmd160 )
-           rmd160_putchar(mfx->rmd160, c );
-       if( mfx->md5 )
-           md5_putchar(mfx->md5, c );
+           md_putc(mfx->md, c );
     }
     iobuf_close(fp);
 
index fe4ba2e..c626651 100644 (file)
--- a/g10/rsa.c
+++ b/g10/rsa.c
@@ -64,7 +64,7 @@ g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
 
 
 void
-g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md )
+g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md )
 {
  #ifdef HAVE_RSA_CIPHER
     RSA_secret_key skey;
@@ -72,10 +72,11 @@ g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md )
 
     assert( sig->pubkey_algo == PUBKEY_ALGO_RSA );
 
-    dp = md_final( md );
+    md_final( md );
+    dp = md_read( md, 0 );
 
     keyid_from_skc( skc, sig->keyid );
-    sig->d.rsa.digest_algo = md->algo;
+    sig->d.rsa.digest_algo = md_get_algo( md );
     sig->d.rsa.digest_start[0] = dp[0];
     sig->d.rsa.digest_start[1] = dp[1];
     sig->d.rsa.rsa_integer =
index 2698c73..c99bed5 100644 (file)
@@ -226,16 +226,17 @@ encode_md5_value( byte *md, unsigned len, unsigned nbits )
 }
 
 MPI
-encode_md_value( MD_HANDLE *md, unsigned nbits )
+encode_md_value( MD_HANDLE md, unsigned nbits )
 {
-    byte *p = md_final( md );
-    if( md->algo == DIGEST_ALGO_MD5 )
-       return encode_md5_value( p, 16, nbits );
-    else if( md->algo == DIGEST_ALGO_RMD160 )
-       return encode_rmd160_value( p, 20, nbits );
-    else if( md->algo == DIGEST_ALGO_SHA1 )
-       return encode_sha1_value( p, 20, nbits );
-    else
+    switch( md_get_algo( md ) ) {
+      case DIGEST_ALGO_MD5:
+       return encode_md5_value( md_read(md, DIGEST_ALGO_MD5), 16, nbits );
+      case DIGEST_ALGO_RMD160:
+       return encode_rmd160_value( md_read(md, DIGEST_ALGO_RMD160), 20, nbits );
+      case DIGEST_ALGO_SHA1:
+       return encode_sha1_value( md_read(md, DIGEST_ALGO_SHA1), 20, nbits );
+      default:
        log_bug(NULL);
+    }
 }
 
index 856d57d..7451750 100644 (file)
@@ -38,7 +38,7 @@
  * is able to append some data, before getting the digest.
  */
 int
-signature_check( PKT_signature *sig, MD_HANDLE *digest )
+signature_check( PKT_signature *sig, MD_HANDLE digest )
 {
     PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
     MPI result = NULL;
@@ -54,16 +54,17 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
        ELG_public_key pkey;
 
-       if( (rc=md_okay(sig->d.elg.digest_algo)) )
+       if( (rc=check_digest_algo(sig->d.elg.digest_algo)) )
            goto leave;
        /* complete the digest */
-       md_putchar( digest, sig->sig_class );
+       md_putc( digest, sig->sig_class );
        {   u32 a = sig->timestamp;
-           md_putchar( digest, (a >> 24) & 0xff );
-           md_putchar( digest, (a >> 16) & 0xff );
-           md_putchar( digest, (a >>  8) & 0xff );
-           md_putchar( digest,  a        & 0xff );
+           md_putc( digest, (a >> 24) & 0xff );
+           md_putc( digest, (a >> 16) & 0xff );
+           md_putc( digest, (a >>  8) & 0xff );
+           md_putc( digest,  a        & 0xff );
        }
+       md_final( digest );
        result = encode_md_value( digest, mpi_get_nbits(pkc->d.elg.p));
        pkey.p = pkc->d.elg.p;
        pkey.g = pkc->d.elg.g;
@@ -134,14 +135,15 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
            }
 
            /* complete the digest */
-           md_putchar( digest, sig->sig_class );
+           md_putc( digest, sig->sig_class );
            {   u32 a = sig->timestamp;
-               md_putchar( digest, (a >> 24) & 0xff );
-               md_putchar( digest, (a >> 16) & 0xff );
-               md_putchar( digest, (a >>  8) & 0xff );
-               md_putchar( digest,  a        & 0xff );
+               md_putc( digest, (a >> 24) & 0xff );
+               md_putc( digest, (a >> 16) & 0xff );
+               md_putc( digest, (a >>  8) & 0xff );
+               md_putc( digest,  a        & 0xff );
            }
-           dp = md_final( digest );
+           md_final( digest );
+           dp = md_read( digest, 0 );
            for(i=19; i >= 0; i--, dp++ )
                if( mpi_getbyte( result, i ) != *dp ) {
                    rc = G10ERR_BAD_SIGN;
@@ -177,14 +179,15 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
            }
 
            /* complete the digest */
-           md_putchar( digest, sig->sig_class );
+           md_putc( digest, sig->sig_class );
            {   u32 a = sig->timestamp;
-               md_putchar( digest, (a >> 24) & 0xff );
-               md_putchar( digest, (a >> 16) & 0xff );
-               md_putchar( digest, (a >>  8) & 0xff );
-               md_putchar( digest,  a        & 0xff );
+               md_putc( digest, (a >> 24) & 0xff );
+               md_putc( digest, (a >> 16) & 0xff );
+               md_putc( digest, (a >>  8) & 0xff );
+               md_putc( digest,  a        & 0xff );
            }
-           dp = md_final( digest );
+           md_final( digest );
+           dp = md_read( digest, 0 );
            for(i=15; i >= 0; i--, dp++ )
                if( mpi_getbyte( result, i ) != *dp ) {
                    rc = G10ERR_BAD_SIGN;
@@ -220,7 +223,7 @@ int
 check_key_signature( KBNODE root, KBNODE node )
 {
     KBNODE unode;
-    MD_HANDLE *md;
+    MD_HANDLE md;
     PKT_public_cert *pkc;
     PKT_signature *sig;
     int algo;
@@ -239,7 +242,7 @@ check_key_signature( KBNODE root, KBNODE node )
        algo = sig->d.rsa.digest_algo;
     else
        return G10ERR_PUBKEY_ALGO;
-    if( (rc=md_okay(algo)) )
+    if( (rc=check_digest_algo(algo)) )
        return rc;
 
     unode = find_kbparent( root, node );
index d0596d6..04ae72a 100644 (file)
@@ -41,7 +41,7 @@
 
 
 static int
-complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE *md )
+complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE md )
 {
     int rc=0;
 
@@ -119,7 +119,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
     /* prepare to calculate the MD over the input */
     if( opt.textmode && opt.armor )
        iobuf_push_filter( inp, text_filter, &tfx );
-    mfx.rmd160 = rmd160_open(0);
+    mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
     iobuf_push_filter( inp, md_filter, &mfx );
 
     if( opt.armor )
@@ -194,7 +194,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
     for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) {
        PKT_secret_cert *skc;
        PKT_signature *sig;
-       RMDHANDLE rmd;
+       MD_HANDLE md;
        byte *dp;
 
        skc = skc_rover->skc;
@@ -205,15 +205,16 @@ sign_file( const char *filename, int detached, STRLIST locusr,
        sig->timestamp = make_timestamp();
        sig->sig_class = opt.textmode? 0x01 : 0x00;
 
-       rmd = rmd160_copy( mfx.rmd160 );
-       rmd160_putchar( rmd, sig->sig_class );
+       md = md_copy( mfx.md );
+       md_putc( md, sig->sig_class );
        {   u32 a = sig->timestamp;
-           rmd160_putchar( rmd, (a >> 24) & 0xff );
-           rmd160_putchar( rmd, (a >> 16) & 0xff );
-           rmd160_putchar( rmd, (a >>  8) & 0xff );
-           rmd160_putchar( rmd,  a        & 0xff );
+           md_putc( md, (a >> 24) & 0xff );
+           md_putc( md, (a >> 16) & 0xff );
+           md_putc( md, (a >>  8) & 0xff );
+           md_putc( md,  a        & 0xff );
        }
-       dp = rmd160_final( rmd );
+       md_final( md );
+       dp = md_read( md, DIGEST_ALGO_RMD160 );
 
        if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
            ELG_secret_key skey;
@@ -268,7 +269,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
        else
            log_bug(NULL);
 
-       rmd160_close( rmd );
+       md_close( md );
 
        /* and write it */
        init_packet(&pkt);
@@ -289,7 +290,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
     else
        iobuf_close(out);
     iobuf_close(inp);
-    rmd160_close( mfx.rmd160 );
+    md_close( mfx.md );
     release_skc_list( skc_list );
     release_pkc_list( pkc_list );
     return rc;
@@ -621,7 +622,7 @@ sign_key( const char *username, STRLIST locusr )
   leave:
     release_kbnode( keyblock );
     release_skc_list( skc_list );
-    rmd160_close( mfx.rmd160 );
+    md_close( mfx.md );
     return rc;
 }
 
@@ -830,7 +831,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
 {
     PKT_signature *sig;
     int rc=0;
-    MD_HANDLE *md;
+    MD_HANDLE md;
 
     assert( sigclass >= 0x10 && sigclass <= 0x13 );
     md = md_open( digest_algo, 0 );
@@ -843,12 +844,12 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
     sig->timestamp = make_timestamp();
     sig->sig_class = sigclass;
 
-    md_putchar( md, sig->sig_class );
+    md_putc( md, sig->sig_class );
     {  u32 a = sig->timestamp;
-       md_putchar( md, (a >> 24) & 0xff );
-       md_putchar( md, (a >> 16) & 0xff );
-       md_putchar( md, (a >>  8) & 0xff );
-       md_putchar( md,  a        & 0xff );
+       md_putc( md, (a >> 24) & 0xff );
+       md_putc( md, (a >> 16) & 0xff );
+       md_putc( md, (a >>  8) & 0xff );
+       md_putc( md,  a        & 0xff );
     }
 
     rc = complete_sig( sig, skc, md );
index 75e547f..e7c9071 100644 (file)
@@ -60,7 +60,7 @@ build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock )
            free_secret_cert( skc ); skc = NULL;
            log_error("no default secret key: %s\n", g10_errstr(rc) );
        }
-       else if( is_valid_pubkey_algo(skc->pubkey_algo) ) {
+       else if( !(rc=check_pubkey_algo(skc->pubkey_algo)) ) {
            SKC_LIST r;
            r = m_alloc( sizeof *r );
            r->skc = skc; skc = NULL;
@@ -82,7 +82,7 @@ build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock )
                free_secret_cert( skc ); skc = NULL;
                log_error("skipped '%s': %s\n", locusr->d, g10_errstr(rc) );
            }
-           else if ( is_valid_pubkey_algo(skc->pubkey_algo) ) {
+           else if( !(rc=check_pubkey_algo(skc->pubkey_algo)) ) {
                SKC_LIST r;
                r = m_alloc( sizeof *r );
                r->skc = skc; skc = NULL;
index 00774f5..46c9500 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include <errno.h>
 #include <assert.h>
 
 #include "keydb.h"
 #include "memory.h"
 #include "util.h"
+#include "trustdb.h"
+#include "options.h"
 
 
+#define TRUST_RECORD_LEN 40
+
+struct trust_record {
+    byte rectype;
+    byte reserved;
+    union {
+       byte raw[TRUST_RECORD_LEN-2];
+       struct {            /* version record: */
+           byte magic[2];
+           byte version;   /* should be 1 */
+           byte reserved[3];
+           u32  locked;    /* pid of process which holds a lock */
+           u32  created;   /* timestamp of trustdb creation  */
+           u32  modified;  /* timestamp of last modification */
+           u32  validated; /* timestamp of last validation   */
+           u32  local_id_counter;
+           byte marginals_needed;
+           byte completes_needed;
+           byte max_cert_depth;
+       } version;
+       struct {            /* public key record */
+           u32 local_id;
+           u32 keyid[2];
+           byte algo;
+           byte reserved;
+           byte fingerprint[20];
+           byte ownertrust;
+       } pubkey;
+       struct {            /* cache record */
+           u32 local_id;
+           u32 keyid[2];
+           byte valid;
+           byte reserved;
+           byte blockhash[20];
+           byte n_untrusted;
+           byte n_marginal;
+           byte n_fully;
+           byte trustlevel;
+       } cache;
+    } r;
+};
+
+
+
+static char *db_name;
+
+/**************************************************
+ ************** read and write helpers ************
+ **************************************************/
+
+static void
+fwrite_8(FILE *fp, byte a)
+{
+    if( putc( a & 0xff, fp ) == EOF )
+       log_fatal("error writing byte to trustdb: %s\n", strerror(errno) );
+}
+
+static void
+fwrite_16(FILE *fp, u16 a)
+{
+    putc( (a>>8) & 0x0ff , fp );
+    if( putc( a & 0xff, fp ) == EOF )
+       log_fatal("error writing u16 to trustdb: %s\n", strerror(errno) );
+}
+
+static int
+fwrite_32( FILE*fp, u32 a)
+{
+    putc( (a>>24) & 0xff, fp );
+    putc( (a>>16) & 0xff, fp );
+    putc( (a>> 8) & 0xff, fp );
+    if( putc( a & 0xff, fp ) == EOF )
+       log_fatal("error writing u32 to trustdb: %s\n", strerror(errno) );
+}
+
+static int
+fwrite_zeros( FILE *fp, size_t n)
+{
+    while( n-- )
+       if( putc( 0, fp ) == EOF )
+           log_fatal("error writing zeros to trustdb: %s\n", strerror(errno) );
+}
+
+
+/**************************************************
+ ************** read and write stuff **************
+ **************************************************/
+
+
+/****************
+ * Create a new trustdb
+ */
+static void
+create_db( const char *fname )
+{
+    FILE *fp;
+    u32 along;
+    u16 ashort;
+
+    fp =fopen( fname, "w" );
+    if( !fp )
+       log_fatal("can't create %s: %s\n", fname, strerror(errno) );
+    fwrite_8( fp, 1 );
+    fwrite_8( fp, 'g' );
+    fwrite_8( fp, '1' );
+    fwrite_8( fp, '0' );
+    fwrite_8( fp, 1 ); /* version */
+    fwrite_zeros( fp, 3 ); /* reserved */
+    fwrite_32( fp, 0 ); /* not locked */
+    fwrite_32( fp, make_timestamp() ); /* created */
+    fwrite_32( fp, 0 ); /* not yet modified */
+    fwrite_32( fp, 0 ); /* not yet validated*/
+    fwrite_32( fp, 0 ); /* local-id-counter */
+    fwrite_8( fp, 3 ); /* marginals needed */
+    fwrite_8( fp, 1 ); /* completes needed */
+    fwrite_8( fp, 4 ); /* max_cet_depth */
+    fwrite_zeros( fp, 9 ); /* filler */
+    fclose(fp);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+/***********************************************
+ ************* trust logic  *******************
+ ***********************************************/
+
+
+
+
+
+/*********************************************************
+ ****************  API Interface  ************************
+ *********************************************************/
+
+/****************
+ * Perform some checks over the trustdb
+ *  level 0: used on initial program startup
+ */
+int
+check_trustdb( int level )
+{
+    if( !level ) {
+       char *fname = make_filename("~/.g10", "trustDB", NULL );
+       if( access( fname, R_OK ) ) {
+           if( errno != ENOENT ) {
+               log_error("can't access %s: %s\n", fname, strerror(errno) );
+               m_free(fname);
+               return G10ERR_TRUSTDB;
+           }
+           create_db( fname );
+       }
+       m_free(db_name);
+       db_name = fname;
+
+       /* we can verify a signature about our local data (secring and trustdb)
+        * in ~/.g10/ here
+        */
+    }
+    else
+       log_bug(NULL);
+
+    return 0;
+}
+
+
+/****************
+ * Get the trustlevel for this PKC.
+ * Note: This does not ask any questions
+ * Returns: 0 okay of an errorcode
+ *
+ * It operates this way:
+ *  locate the pkc in the trustdb
+ *     found:
+ *         Do we have a valid cache record for it?
+ *             yes: return trustlevel from cache
+ *             no:  make a cache record
+ *     not found:
+ *         Return with a trustlevel, saying that we do not have
+ *         a trust record for it. The caller may use insert_trust_record()
+ *         and then call this function here again.
+ *
+ * Problems: How do we get the complete keyblock to check that the
+ *          cache record is actually valid?  Think we need a clever
+ *          cache in getkey.c  to keep track of this stuff. Maybe it
+ *          is not necessary to check this if we use a local pubring. Hmmmm.
+ */
+int
+check_pkc_trust( PKT_public_cert *pkc, int *r_trustlevel )
+{
+    int trustlevel = 0;
+
+    if( opt.verbose )
+       log_info("check_pkc_trust() called.\n");
+
+    *r_trustlevel = trustlevel;
+    return 0;
+}
 
diff --git a/g10/trustdb.h b/g10/trustdb.h
new file mode 100644 (file)
index 0000000..01f1268
--- /dev/null
@@ -0,0 +1,28 @@
+/* trustdb.h - Trust database
+ *     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
+ */
+
+#ifndef G10_TRUSTDB_H
+#define G10_TRUSTDB_H
+
+/*-- trustdb.c --*/
+int check_trustdb( int level );
+int check_pkc_trust( PKT_public_cert *pkc, int *r_trustlevel );
+
+#endif /*G10_TRUSTDB_H*/
index fd7886c..1f615e5 100644 (file)
@@ -28,9 +28,7 @@
 #define DBG_CIPHER cipher_debug_mode
 
 #include "mpi.h"
-#include "../cipher/md5.h"
-#include "../cipher/rmd.h"
-#include "../cipher/sha1.h"
+#include "../cipher/md.h"
 #ifdef HAVE_RSA_CIPHER
   #include "../cipher/rsa.h"
 #endif
@@ -67,26 +65,9 @@ typedef struct {
     byte key[20]; /* this is the largest used keylen */
 } DEK;
 
-typedef struct {
-    int algo;  /* digest algo */
-    union {
-      MD5HANDLE md5;
-      RMDHANDLE rmd;
-      SHA1HANDLE sha1;
-    } u;
-    int datalen;
-    char data[1];
-} MD_HANDLE;
-
 
 int cipher_debug_mode;
 
-#ifdef HAVE_RSA_CIPHER
-  #define is_valid_pubkey_algo(a) ( (a) == PUBKEY_ALGO_ELGAMAL \
-                                   || (a) == PUBKEY_ALGO_RSA )
-#else
-  #define is_valid_pubkey_algo(a) ( (a) == PUBKEY_ALGO_ELGAMAL )
-#endif
 
 /*-- misc.c --*/
 int string_to_cipher_algo( const char *string );
@@ -96,19 +77,6 @@ int check_cipher_algo( int algo );
 int check_pubkey_algo( int algo );
 int check_digest_algo( int algo );
 
-/*-- md.c --*/
-int md_okay( int algo );
-MD_HANDLE *md_open( int algo, int secure );
-MD_HANDLE *md_copy( MD_HANDLE *a );
-MD_HANDLE *md_makecontainer( int algo ); /* used for a bad kludge */
-void md_write( MD_HANDLE *a, byte *inbuf, size_t inlen);
-void md_putchar( MD_HANDLE *a, int c );
-byte *md_final(MD_HANDLE *a);
-void md_close(MD_HANDLE *a);
-
-MD_HANDLE *md5_copy2md( MD5HANDLE a ); /* (in md5.c) */
-MD_HANDLE *rmd160_copy2md( RMDHANDLE a ); /* (in rmd160.c) */
-
 /*-- random.c --*/
 void randomize_buffer( byte *buffer, size_t length, int level );
 byte get_random_byte( int level );
index 9679e91..450d910 100644 (file)
@@ -52,5 +52,6 @@
 #define G10ERR_BAD_MPI       30
 #define G10ERR_RESOURCE_LIMIT 31
 #define G10ERR_INV_KEYRING    32
+#define G10ERR_TRUSTDB       33 /* a problem with the trustdb */
 
 #endif /*G10_ERRORS_H*/
index 4e25ab2..7c4639f 100644 (file)
 #define DBG_MPI     mpi_debug_mode
 int mpi_debug_mode;
 
-#if defined(__i386__)
-  #define BITS_PER_MPI_LIMB  32
-  #define BYTES_PER_MPI_LIMB  4
-  #define BYTES_PER_MPI_LIMB2 8
-  typedef unsigned long int mpi_limb_t;
-  typedef   signed long int mpi_limb_signed_t;
-#elif defined(__hppa__)
-  #define BITS_PER_MPI_LIMB   32
-  #define BYTES_PER_MPI_LIMB   4
-  #define BYTES_PER_MPI_LIMB2  8
-  typedef unsigned long int mpi_limb_t;
-  typedef   signed long int mpi_limb_signed_t;
-#elif defined(__alpha__)
-  #define BITS_PER_MPI_LIMB   64
-  #define BYTES_PER_MPI_LIMB   8
-  #define BYTES_PER_MPI_LIMB2 16
-  typedef unsigned long int mpi_limb_t;
-  typedef   signed long int mpi_limb_signed_t;
-#else
-  #error add definions for this machine here
-#endif
+#define BITS_PER_MPI_LIMB    (8*SIZEOF_UNSIGNED_LONG)
+#define BYTES_PER_MPI_LIMB   SIZEOF_UNSIGNED_LONG
+#define BYTES_PER_MPI_LIMB2  (2*SIZEOF_UNSIGNED_LONG)
+typedef unsigned long int mpi_limb_t;
+typedef   signed long int mpi_limb_signed_t;
 
 typedef struct mpi_struct {
     int alloced;    /* array size (# of allocated limbs) */
index 9ee1d05..fd580e5 100644 (file)
@@ -48,6 +48,24 @@ case "${target}" in
        path="pa7100 hppa1_1 hppa"
        mpi_extra_modules="udiv-qrnnd"
        ;;
+    sparc9*-*-* | sparc64*-*-* | ultrasparc*-*-*)
+       echo '/* configured for sparc9 or higher */' >>./mpi/asm-syntax.h
+       path="sparc32v8 sparc32"
+       ;;
+    sparc8*-*-* | microsparc*-*-*)
+       echo '/* configured for sparc8 */' >>./mpi/asm-syntax.h
+       path="sparc32v8"
+       ;;
+    supersparc*-*-*)
+       echo '/* configured for supersparc */' >>./mpi/asm-syntax.h
+       path="supersparc sparc32v8 sparc32"
+       mpi_extra_modules="udiv"
+       ;;
+    sparc*-*-*)
+       echo '/* configured for sparc */' >>./mpi/asm-syntax.h
+       path="sparc32"
+       mpi_extra_modules="udiv"
+       ;;
     *)
        echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
        path=""
diff --git a/mpi/sparc32/distfiles b/mpi/sparc32/distfiles
new file mode 100644 (file)
index 0000000..7933edc
--- /dev/null
@@ -0,0 +1,4 @@
+
+mpih-add1.S
+udiv.S
+
diff --git a/mpi/sparc32/mpih-add1.S b/mpi/sparc32/mpih-add1.S
new file mode 100644 (file)
index 0000000..04315d1
--- /dev/null
@@ -0,0 +1,237 @@
+! SPARC __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+! sum in a third limb vector.
+
+! Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library 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 Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+/*******************
+ *  mpi_limb_t
+ *  mpihelp_add_n( mpi_ptr_t res_ptr,
+ *                mpi_ptr_t s1_ptr,
+ *                mpi_ptr_t s2_ptr,
+ *                mpi_size_t size)
+ */
+
+! INPUT PARAMETERS
+#define res_ptr %o0
+#define s1_ptr %o1
+#define s2_ptr %o2
+#define size   %o3
+
+#include "sysdep.h"
+
+       .text
+       .align  4
+       .global C_SYMBOL_NAME(mpihelp_add_n)
+C_SYMBOL_NAME(mpihelp_add_n):
+       xor     s2_ptr,res_ptr,%g1
+       andcc   %g1,4,%g0
+       bne     L1                      ! branch if alignment differs
+       nop
+! **  V1a  **
+L0:    andcc   res_ptr,4,%g0           ! res_ptr unaligned? Side effect: cy=0
+       be      L_v1                    ! if no, branch
+       nop
+/* Add least significant limb separately to align res_ptr and s2_ptr */
+       ld      [s1_ptr],%g4
+       add     s1_ptr,4,s1_ptr
+       ld      [s2_ptr],%g2
+       add     s2_ptr,4,s2_ptr
+       add     size,-1,size
+       addcc   %g4,%g2,%o4
+       st      %o4,[res_ptr]
+       add     res_ptr,4,res_ptr
+L_v1:  addx    %g0,%g0,%o4             ! save cy in register
+       cmp     size,2                  ! if size < 2 ...
+       bl      Lend2                   ! ... branch to tail code
+       subcc   %g0,%o4,%g0             ! restore cy
+
+       ld      [s1_ptr+0],%g4
+       addcc   size,-10,size
+       ld      [s1_ptr+4],%g1
+       ldd     [s2_ptr+0],%g2
+       blt     Lfin1
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop1: addxcc  %g4,%g2,%o4
+       ld      [s1_ptr+8],%g4
+       addxcc  %g1,%g3,%o5
+       ld      [s1_ptr+12],%g1
+       ldd     [s2_ptr+8],%g2
+       std     %o4,[res_ptr+0]
+       addxcc  %g4,%g2,%o4
+       ld      [s1_ptr+16],%g4
+       addxcc  %g1,%g3,%o5
+       ld      [s1_ptr+20],%g1
+       ldd     [s2_ptr+16],%g2
+       std     %o4,[res_ptr+8]
+       addxcc  %g4,%g2,%o4
+       ld      [s1_ptr+24],%g4
+       addxcc  %g1,%g3,%o5
+       ld      [s1_ptr+28],%g1
+       ldd     [s2_ptr+24],%g2
+       std     %o4,[res_ptr+16]
+       addxcc  %g4,%g2,%o4
+       ld      [s1_ptr+32],%g4
+       addxcc  %g1,%g3,%o5
+       ld      [s1_ptr+36],%g1
+       ldd     [s2_ptr+32],%g2
+       std     %o4,[res_ptr+24]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-8,size
+       add     s1_ptr,32,s1_ptr
+       add     s2_ptr,32,s2_ptr
+       add     res_ptr,32,res_ptr
+       bge     Loop1
+       subcc   %g0,%o4,%g0             ! restore cy
+
+Lfin1: addcc   size,8-2,size
+       blt     Lend1
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+Loope1: addxcc %g4,%g2,%o4
+       ld      [s1_ptr+8],%g4
+       addxcc  %g1,%g3,%o5
+       ld      [s1_ptr+12],%g1
+       ldd     [s2_ptr+8],%g2
+       std     %o4,[res_ptr+0]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-2,size
+       add     s1_ptr,8,s1_ptr
+       add     s2_ptr,8,s2_ptr
+       add     res_ptr,8,res_ptr
+       bge     Loope1
+       subcc   %g0,%o4,%g0             ! restore cy
+Lend1: addxcc  %g4,%g2,%o4
+       addxcc  %g1,%g3,%o5
+       std     %o4,[res_ptr+0]
+       addx    %g0,%g0,%o4             ! save cy in register
+
+       andcc   size,1,%g0
+       be      Lret1
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add last limb */
+       ld      [s1_ptr+8],%g4
+       ld      [s2_ptr+8],%g2
+       addxcc  %g4,%g2,%o4
+       st      %o4,[res_ptr+8]
+
+Lret1: retl
+       addx    %g0,%g0,%o0     ! return carry-out from most sign. limb
+
+L1:    xor     s1_ptr,res_ptr,%g1
+       andcc   %g1,4,%g0
+       bne     L2
+       nop
+! **  V1b  **
+       mov     s2_ptr,%g1
+       mov     s1_ptr,s2_ptr
+       b       L0
+       mov     %g1,s1_ptr
+
+! **  V2  **
+/* If we come here, the alignment of s1_ptr and res_ptr as well as the
+   alignment of s2_ptr and res_ptr differ.  Since there are only two ways
+   things can be aligned (that we care about) we now know that the alignment
+   of s1_ptr and s2_ptr are the same.  */
+
+L2:    cmp     size,1
+       be      Ljone
+       nop
+       andcc   s1_ptr,4,%g0            ! s1_ptr unaligned? Side effect: cy=0
+       be      L_v2                    ! if no, branch
+       nop
+/* Add least significant limb separately to align s1_ptr and s2_ptr */
+       ld      [s1_ptr],%g4
+       add     s1_ptr,4,s1_ptr
+       ld      [s2_ptr],%g2
+       add     s2_ptr,4,s2_ptr
+       add     size,-1,size
+       addcc   %g4,%g2,%o4
+       st      %o4,[res_ptr]
+       add     res_ptr,4,res_ptr
+
+L_v2:  addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-8,size
+       blt     Lfin2
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop2: ldd     [s1_ptr+0],%g2
+       ldd     [s2_ptr+0],%o4
+       addxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+0]
+       addxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+4]
+       ldd     [s1_ptr+8],%g2
+       ldd     [s2_ptr+8],%o4
+       addxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+8]
+       addxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+12]
+       ldd     [s1_ptr+16],%g2
+       ldd     [s2_ptr+16],%o4
+       addxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+16]
+       addxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+20]
+       ldd     [s1_ptr+24],%g2
+       ldd     [s2_ptr+24],%o4
+       addxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+24]
+       addxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+28]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-8,size
+       add     s1_ptr,32,s1_ptr
+       add     s2_ptr,32,s2_ptr
+       add     res_ptr,32,res_ptr
+       bge     Loop2
+       subcc   %g0,%o4,%g0             ! restore cy
+
+Lfin2: addcc   size,8-2,size
+       blt     Lend2
+       subcc   %g0,%o4,%g0             ! restore cy
+Loope2: ldd    [s1_ptr+0],%g2
+       ldd     [s2_ptr+0],%o4
+       addxcc  %g2,%o4,%g2
+       st      %g2,[res_ptr+0]
+       addxcc  %g3,%o5,%g3
+       st      %g3,[res_ptr+4]
+       addx    %g0,%g0,%o4             ! save cy in register
+       addcc   size,-2,size
+       add     s1_ptr,8,s1_ptr
+       add     s2_ptr,8,s2_ptr
+       add     res_ptr,8,res_ptr
+       bge     Loope2
+       subcc   %g0,%o4,%g0             ! restore cy
+Lend2: andcc   size,1,%g0
+       be      Lret2
+       subcc   %g0,%o4,%g0             ! restore cy
+/* Add last limb */
+Ljone: ld      [s1_ptr],%g4
+       ld      [s2_ptr],%g2
+       addxcc  %g4,%g2,%o4
+       st      %o4,[res_ptr]
+
+Lret2: retl
+       addx    %g0,%g0,%o0     ! return carry-out from most sign. limb
+
+
+
diff --git a/mpi/sparc32/udiv.S b/mpi/sparc32/udiv.S
new file mode 100644 (file)
index 0000000..3e2376c
--- /dev/null
@@ -0,0 +1,188 @@
+! SPARC v7 __udiv_qrnnd division support, used from longlong.h.
+! This is for v7 CPUs without a floating-point unit.
+
+! Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library 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 Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! rem_ptr      o0
+! n1           o1
+! n0           o2
+! d            o3
+
+#include "sysdep.h"
+
+       .text
+       .align 4
+       .global C_SYMBOL_NAME(__udiv_qrnnd)
+C_SYMBOL_NAME(__udiv_qrnnd):
+       tst     %o3
+       bneg    Largedivisor
+       mov     8,%g1
+
+       b       Lp1
+       addxcc  %o2,%o2,%o2
+
+Lplop: bcc     Ln1
+       addxcc  %o2,%o2,%o2
+Lp1:   addx    %o1,%o1,%o1
+       subcc   %o1,%o3,%o4
+       bcc     Ln2
+       addxcc  %o2,%o2,%o2
+Lp2:   addx    %o1,%o1,%o1
+       subcc   %o1,%o3,%o4
+       bcc     Ln3
+       addxcc  %o2,%o2,%o2
+Lp3:   addx    %o1,%o1,%o1
+       subcc   %o1,%o3,%o4
+       bcc     Ln4
+       addxcc  %o2,%o2,%o2
+Lp4:   addx    %o1,%o1,%o1
+       addcc   %g1,-1,%g1
+       bne     Lplop
+       subcc   %o1,%o3,%o4
+       bcc     Ln5
+       addxcc  %o2,%o2,%o2
+Lp5:   st      %o1,[%o0]
+       retl
+       xnor    %g0,%o2,%o0
+
+Lnlop: bcc     Lp1
+       addxcc  %o2,%o2,%o2
+Ln1:   addx    %o4,%o4,%o4
+       subcc   %o4,%o3,%o1
+       bcc     Lp2
+       addxcc  %o2,%o2,%o2
+Ln2:   addx    %o4,%o4,%o4
+       subcc   %o4,%o3,%o1
+       bcc     Lp3
+       addxcc  %o2,%o2,%o2
+Ln3:   addx    %o4,%o4,%o4
+       subcc   %o4,%o3,%o1
+       bcc     Lp4
+       addxcc  %o2,%o2,%o2
+Ln4:   addx    %o4,%o4,%o4
+       addcc   %g1,-1,%g1
+       bne     Lnlop
+       subcc   %o4,%o3,%o1
+       bcc     Lp5
+       addxcc  %o2,%o2,%o2
+Ln5:   st      %o4,[%o0]
+       retl
+       xnor    %g0,%o2,%o0
+
+Largedivisor:
+       and     %o2,1,%o5       ! %o5 = n0 & 1
+
+       srl     %o2,1,%o2
+       sll     %o1,31,%g2
+       or      %g2,%o2,%o2     ! %o2 = lo(n1n0 >> 1)
+       srl     %o1,1,%o1       ! %o1 = hi(n1n0 >> 1)
+
+       and     %o3,1,%g2
+       srl     %o3,1,%g3       ! %g3 = floor(d / 2)
+       add     %g3,%g2,%g3     ! %g3 = ceil(d / 2)
+
+       b       LLp1
+       addxcc  %o2,%o2,%o2
+
+LLplop: bcc    LLn1
+       addxcc  %o2,%o2,%o2
+LLp1:  addx    %o1,%o1,%o1
+       subcc   %o1,%g3,%o4
+       bcc     LLn2
+       addxcc  %o2,%o2,%o2
+LLp2:  addx    %o1,%o1,%o1
+       subcc   %o1,%g3,%o4
+       bcc     LLn3
+       addxcc  %o2,%o2,%o2
+LLp3:  addx    %o1,%o1,%o1
+       subcc   %o1,%g3,%o4
+       bcc     LLn4
+       addxcc  %o2,%o2,%o2
+LLp4:  addx    %o1,%o1,%o1
+       addcc   %g1,-1,%g1
+       bne     LLplop
+       subcc   %o1,%g3,%o4
+       bcc     LLn5
+       addxcc  %o2,%o2,%o2
+LLp5:  add     %o1,%o1,%o1     ! << 1
+       tst     %g2
+       bne     Oddp
+       add     %o5,%o1,%o1
+       st      %o1,[%o0]
+       retl
+       xnor    %g0,%o2,%o0
+
+LLnlop: bcc    LLp1
+       addxcc  %o2,%o2,%o2
+LLn1:  addx    %o4,%o4,%o4
+       subcc   %o4,%g3,%o1
+       bcc     LLp2
+       addxcc  %o2,%o2,%o2
+LLn2:  addx    %o4,%o4,%o4
+       subcc   %o4,%g3,%o1
+       bcc     LLp3
+       addxcc  %o2,%o2,%o2
+LLn3:  addx    %o4,%o4,%o4
+       subcc   %o4,%g3,%o1
+       bcc     LLp4
+       addxcc  %o2,%o2,%o2
+LLn4:  addx    %o4,%o4,%o4
+       addcc   %g1,-1,%g1
+       bne     LLnlop
+       subcc   %o4,%g3,%o1
+       bcc     LLp5
+       addxcc  %o2,%o2,%o2
+LLn5:  add     %o4,%o4,%o4     ! << 1
+       tst     %g2
+       bne     Oddn
+       add     %o5,%o4,%o4
+       st      %o4,[%o0]
+       retl
+       xnor    %g0,%o2,%o0
+
+Oddp:  xnor    %g0,%o2,%o2
+       ! q' in %o2. r' in %o1
+       addcc   %o1,%o2,%o1
+       bcc     LLp6
+       addx    %o2,0,%o2
+       sub     %o1,%o3,%o1
+LLp6:  subcc   %o1,%o3,%g0
+       bcs     LLp7
+       subx    %o2,-1,%o2
+       sub     %o1,%o3,%o1
+LLp7:  st      %o1,[%o0]
+       retl
+       mov     %o2,%o0
+
+Oddn:  xnor    %g0,%o2,%o2
+       ! q' in %o2. r' in %o4
+       addcc   %o4,%o2,%o4
+       bcc     LLn6
+       addx    %o2,0,%o2
+       sub     %o4,%o3,%o4
+LLn6:  subcc   %o4,%o3,%g0
+       bcs     LLn7
+       subx    %o2,-1,%o2
+       sub     %o4,%o3,%o4
+LLn7:  st      %o4,[%o0]
+       retl
+       mov     %o2,%o0
diff --git a/mpi/sparc32v8/distfiles b/mpi/sparc32v8/distfiles
new file mode 100644 (file)
index 0000000..5789f35
--- /dev/null
@@ -0,0 +1,5 @@
+
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+
diff --git a/mpi/sparc32v8/mpih-mul1.S b/mpi/sparc32v8/mpih-mul1.S
new file mode 100644 (file)
index 0000000..8bc1db5
--- /dev/null
@@ -0,0 +1,101 @@
+! SPARC v8 __mpn_mul_1 -- Multiply a limb vector with a single limb and
+! store the product in a second limb vector.
+
+! Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library 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 Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr      o0
+! s1_ptr       o1
+! size         o2
+! s2_limb      o3
+
+#include "sysdep.h"
+
+.text
+       .align  8
+       .global C_SYMBOL_NAME(mpihelp_mul_1)
+C_SYMBOL_NAME(mpihelp_mul_1):
+       sll     %o2,4,%g1
+       and     %g1,(4-1)<<4,%g1
+#if PIC
+       mov     %o7,%g4                 ! Save return address register
+       call    1f
+       add     %o7,LL-1f,%g3
+1:     mov     %g4,%o7                 ! Restore return address register
+#else
+       sethi   %hi(LL),%g3
+       or      %g3,%lo(LL),%g3
+#endif
+       jmp     %g3+%g1
+       ld      [%o1+0],%o4     ! 1
+LL:
+LL00:  add     %o0,-4,%o0
+       add     %o1,-4,%o1
+       b       Loop00          /* 4, 8, 12, ... */
+       orcc    %g0,%g0,%g2
+LL01:  b       Loop01          /* 1, 5, 9, ... */
+       orcc    %g0,%g0,%g2
+       nop
+       nop
+LL10:  add     %o0,-12,%o0     /* 2, 6, 10, ... */
+       add     %o1,4,%o1
+       b       Loop10
+       orcc    %g0,%g0,%g2
+       nop
+LL11:  add     %o0,-8,%o0      /* 3, 7, 11, ... */
+       add     %o1,-8,%o1
+       b       Loop11
+       orcc    %g0,%g0,%g2
+
+Loop:  addcc   %g3,%g2,%g3     ! 1
+       ld      [%o1+4],%o4     ! 2
+       st      %g3,[%o0+0]     ! 1
+       rd      %y,%g2          ! 1
+Loop00: umul   %o4,%o3,%g3     ! 2
+       addxcc  %g3,%g2,%g3     ! 2
+       ld      [%o1+8],%o4     ! 3
+       st      %g3,[%o0+4]     ! 2
+       rd      %y,%g2          ! 2
+Loop11: umul   %o4,%o3,%g3     ! 3
+       addxcc  %g3,%g2,%g3     ! 3
+       ld      [%o1+12],%o4    ! 4
+       add     %o1,16,%o1
+       st      %g3,[%o0+8]     ! 3
+       rd      %y,%g2          ! 3
+Loop10: umul   %o4,%o3,%g3     ! 4
+       addxcc  %g3,%g2,%g3     ! 4
+       ld      [%o1+0],%o4     ! 1
+       st      %g3,[%o0+12]    ! 4
+       add     %o0,16,%o0
+       rd      %y,%g2          ! 4
+       addx    %g0,%g2,%g2
+Loop01: addcc  %o2,-4,%o2
+       bg      Loop
+       umul    %o4,%o3,%g3     ! 1
+
+       addcc   %g3,%g2,%g3     ! 4
+       st      %g3,[%o0+0]     ! 4
+       rd      %y,%g2          ! 4
+
+       retl
+       addx    %g0,%g2,%o0
+
+
diff --git a/mpi/sparc32v8/mpih-mul2.S b/mpi/sparc32v8/mpih-mul2.S
new file mode 100644 (file)
index 0000000..9055f89
--- /dev/null
@@ -0,0 +1,124 @@
+! SPARC v8 __mpn_addmul_1 -- Multiply a limb vector with a limb and
+! add the result to a second limb vector.
+
+! Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library 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 Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr      o0
+! s1_ptr       o1
+! size         o2
+! s2_limb      o3
+
+#include "sysdep.h"
+
+.text
+       .align 4
+       .global C_SYMBOL_NAME(mpihelp_addmul_1)
+C_SYMBOL_NAME(mpihelp_addmul_1):
+       orcc    %g0,%g0,%g2
+       ld      [%o1+0],%o4     ! 1
+
+       sll     %o2,4,%g1
+       and     %g1,(4-1)<<4,%g1
+#if PIC
+       mov     %o7,%g4                 ! Save return address register
+       call    1f
+       add     %o7,LL-1f,%g3
+1:     mov     %g4,%o7                 ! Restore return address register
+#else
+       sethi   %hi(LL),%g3
+       or      %g3,%lo(LL),%g3
+#endif
+       jmp     %g3+%g1
+       nop
+LL:
+LL00:  add     %o0,-4,%o0
+       b       Loop00          /* 4, 8, 12, ... */
+       add     %o1,-4,%o1
+       nop
+LL01:  b       Loop01          /* 1, 5, 9, ... */
+       nop
+       nop
+       nop
+LL10:  add     %o0,-12,%o0     /* 2, 6, 10, ... */
+       b       Loop10
+       add     %o1,4,%o1
+       nop
+LL11:  add     %o0,-8,%o0      /* 3, 7, 11, ... */
+       b       Loop11
+       add     %o1,-8,%o1
+       nop
+
+1:     addcc   %g3,%g2,%g3     ! 1
+       ld      [%o1+4],%o4     ! 2
+       rd      %y,%g2          ! 1
+       addx    %g0,%g2,%g2
+       ld      [%o0+0],%g1     ! 2
+       addcc   %g1,%g3,%g3
+       st      %g3,[%o0+0]     ! 1
+Loop00: umul   %o4,%o3,%g3     ! 2
+       ld      [%o0+4],%g1     ! 2
+       addxcc  %g3,%g2,%g3     ! 2
+       ld      [%o1+8],%o4     ! 3
+       rd      %y,%g2          ! 2
+       addx    %g0,%g2,%g2
+       nop
+       addcc   %g1,%g3,%g3
+       st      %g3,[%o0+4]     ! 2
+Loop11: umul   %o4,%o3,%g3     ! 3
+       addxcc  %g3,%g2,%g3     ! 3
+       ld      [%o1+12],%o4    ! 4
+       rd      %y,%g2          ! 3
+       add     %o1,16,%o1
+       addx    %g0,%g2,%g2
+       ld      [%o0+8],%g1     ! 2
+       addcc   %g1,%g3,%g3
+       st      %g3,[%o0+8]     ! 3
+Loop10: umul   %o4,%o3,%g3     ! 4
+       addxcc  %g3,%g2,%g3     ! 4
+       ld      [%o1+0],%o4     ! 1
+       rd      %y,%g2          ! 4
+       addx    %g0,%g2,%g2
+       ld      [%o0+12],%g1    ! 2
+       addcc   %g1,%g3,%g3
+       st      %g3,[%o0+12]    ! 4
+       add     %o0,16,%o0
+       addx    %g0,%g2,%g2
+Loop01: addcc  %o2,-4,%o2
+       bg      1b
+       umul    %o4,%o3,%g3     ! 1
+
+       addcc   %g3,%g2,%g3     ! 4
+       rd      %y,%g2          ! 4
+       addx    %g0,%g2,%g2
+       ld      [%o0+0],%g1     ! 2
+       addcc   %g1,%g3,%g3
+       st      %g3,[%o0+0]     ! 4
+       addx    %g0,%g2,%o0
+
+       retl
+        nop
+
+
+!      umul, ld, addxcc, rd, st
+
+!      umul, ld, addxcc, rd, ld, addcc, st, addx
+
diff --git a/mpi/sparc32v8/mpih-mul3.S b/mpi/sparc32v8/mpih-mul3.S
new file mode 100644 (file)
index 0000000..efd83de
--- /dev/null
@@ -0,0 +1,60 @@
+! SPARC v8 __mpn_submul_1 -- Multiply a limb vector with a limb and
+! subtract the result from a second limb vector.
+
+! Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library 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 Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! res_ptr      o0
+! s1_ptr       o1
+! size         o2
+! s2_limb      o3
+
+#include "sysdep.h"
+
+.text
+       .align 4
+       .global C_SYMBOL_NAME(mpihelp_submul_1)
+C_SYMBOL_NAME(mpihelp_submul_1):
+       sub     %g0,%o2,%o2             ! negate ...
+       sll     %o2,2,%o2               ! ... and scale size
+       sub     %o1,%o2,%o1             ! o1 is offset s1_ptr
+       sub     %o0,%o2,%g1             ! g1 is offset res_ptr
+
+       mov     0,%o0                   ! clear cy_limb
+
+Loop:  ld      [%o1+%o2],%o4
+       ld      [%g1+%o2],%g2
+       umul    %o4,%o3,%o5
+       rd      %y,%g3
+       addcc   %o5,%o0,%o5
+       addx    %g3,0,%o0
+       subcc   %g2,%o5,%g2
+       addx    %o0,0,%o0
+       st      %g2,[%g1+%o2]
+
+       addcc   %o2,4,%o2
+       bne     Loop
+        nop
+
+       retl
+        nop
+
+
diff --git a/mpi/supersparc/distfiles b/mpi/supersparc/distfiles
new file mode 100644 (file)
index 0000000..5506c41
--- /dev/null
@@ -0,0 +1,3 @@
+
+udiv.S
+
diff --git a/mpi/supersparc/udiv.S b/mpi/supersparc/udiv.S
new file mode 100644 (file)
index 0000000..07d904c
--- /dev/null
@@ -0,0 +1,110 @@
+! SuperSPARC __udiv_qrnnd division support, used from longlong.h.
+! This is for SuperSPARC only, to compensate for its semi-functional
+! udiv instruction.
+
+! Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
+
+! This file is part of the GNU MP Library.
+
+! The GNU MP Library is free software; you can redistribute it and/or modify
+! it under the terms of the GNU Library General Public License as published by
+! the Free Software Foundation; either version 2 of the License, or (at your
+! option) any later version.
+
+! The GNU MP Library 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 Library General Public
+! License for more details.
+
+! You should have received a copy of the GNU Library General Public License
+! along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
+! the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+! MA 02111-1307, USA.
+
+
+! INPUT PARAMETERS
+! rem_ptr      i0
+! n1           i1
+! n0           i2
+! d            i3
+
+#include "sysdep.h"
+#undef ret     /* Kludge for glibc */
+
+       .text
+       .align  8
+LC0:   .double 0r4294967296
+LC1:   .double 0r2147483648
+
+       .align  4
+       .global C_SYMBOL_NAME(__udiv_qrnnd)
+C_SYMBOL_NAME(__udiv_qrnnd):
+       !#PROLOGUE# 0
+       save    %sp,-104,%sp
+       !#PROLOGUE# 1
+       st      %i1,[%fp-8]
+       ld      [%fp-8],%f10
+       sethi   %hi(LC0),%o7
+       fitod   %f10,%f4
+       ldd     [%o7+%lo(LC0)],%f8
+       cmp     %i1,0
+       bge     L248
+       mov     %i0,%i5
+       faddd   %f4,%f8,%f4
+L248:
+       st      %i2,[%fp-8]
+       ld      [%fp-8],%f10
+       fmuld   %f4,%f8,%f6
+       cmp     %i2,0
+       bge     L249
+       fitod   %f10,%f2
+       faddd   %f2,%f8,%f2
+L249:
+       st      %i3,[%fp-8]
+       faddd   %f6,%f2,%f2
+       ld      [%fp-8],%f10
+       cmp     %i3,0
+       bge     L250
+       fitod   %f10,%f4
+       faddd   %f4,%f8,%f4
+L250:
+       fdivd   %f2,%f4,%f2
+       sethi   %hi(LC1),%o7
+       ldd     [%o7+%lo(LC1)],%f4
+       fcmped  %f2,%f4
+       nop
+       fbge,a  L251
+       fsubd   %f2,%f4,%f2
+       fdtoi   %f2,%f2
+       st      %f2,[%fp-8]
+       b       L252
+       ld      [%fp-8],%i4
+L251:
+       fdtoi   %f2,%f2
+       st      %f2,[%fp-8]
+       ld      [%fp-8],%i4
+       sethi   %hi(-2147483648),%g2
+       xor     %i4,%g2,%i4
+L252:
+       umul    %i3,%i4,%g3
+       rd      %y,%i0
+       subcc   %i2,%g3,%o7
+       subxcc  %i1,%i0,%g0
+       be      L253
+       cmp     %o7,%i3
+
+       add     %i4,-1,%i0
+       add     %o7,%i3,%o7
+       st      %o7,[%i5]
+       ret
+       restore
+L253:
+       blu     L246
+       mov     %i4,%i0
+       add     %i4,1,%i0
+       sub     %o7,%i3,%o7
+L246:
+       st      %o7,[%i5]
+       ret
+       restore
+