1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

started with trust stuff

This commit is contained in:
Werner Koch 1998-01-12 10:18:17 +00:00
parent 762d3d7197
commit ed36092588
54 changed files with 1861 additions and 700 deletions

177
INSTALL
View File

@ -1,26 +1,183 @@
Basic Installation
==================
1) Configure for your machine: These are generic installation instructions.
./configure 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').
or use 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.
./configure --enable-m-debug 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'.
to enable the integrated malloc debugging stuff. 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.
2) Run make: Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
make 2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
3) Install 4. Type `make install' to install the programs and any data files and
documentation.
make install 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
=====================
4) You end up with a binary "g10" in /usr/local/bin 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.

6
NEWS
View File

@ -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)

18
README
View File

@ -42,6 +42,24 @@
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 Resources
--------- ---------
G10 needs a directory "~/.g10" to store the default keyrings G10 needs a directory "~/.g10" to store the default keyrings

2
TODO
View File

@ -37,4 +37,6 @@
* add g10 stuff to Mutt's pgpinvoke.c * add g10 stuff to Mutt's pgpinvoke.c
* Burn the buffers used by fopen().

View File

@ -1 +1 @@
0.1.2 0.1.3

View File

@ -23,6 +23,7 @@ cipher_SOURCES = blowfish.c \
dsa.h \ dsa.h \
dsa.c \ dsa.c \
md.c \ md.c \
md.h \
misc.c \ misc.c \
smallprime.c smallprime.c

View File

@ -60,6 +60,7 @@ cipher_SOURCES = blowfish.c \
dsa.h \ dsa.h \
dsa.c \ dsa.c \
md.c \ md.c \
md.h \
misc.c \ misc.c \
smallprime.c smallprime.c

View File

@ -27,146 +27,135 @@
#include "errors.h" #include "errors.h"
int /****************
md_okay( int algo ) * Open a message digest handle for use with algorithm ALGO.
{ * More algorithms may be added by md_enable(). The initial algorithm
return check_digest_algo( algo ); * may be 0.
} */
MD_HANDLE
MD_HANDLE *
md_open( int algo, int secure ) md_open( int algo, int secure )
{ {
MD_HANDLE *hd; MD_HANDLE hd;
hd = m_alloc( sizeof *hd + 19 ); hd = secure ? m_alloc_secure_clear( sizeof *hd )
hd->algo = algo; : m_alloc_clear( sizeof *hd );
hd->datalen = 0; if( algo )
if( algo == DIGEST_ALGO_MD5 ) md_enable( hd, algo );
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;
return hd;
}
MD_HANDLE *
md_copy( MD_HANDLE *a )
{
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 );
else
log_bug(NULL);
return hd;
}
/* used for a BAD Kludge in rmd160.c, md5.c */
MD_HANDLE *
md_makecontainer( int algo )
{
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; return hd;
} }
void void
md_close(MD_HANDLE *a) md_enable( MD_HANDLE h, int algo )
{
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("md_enable(%d)", algo );
}
MD_HANDLE
md_copy( MD_HANDLE a )
{
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)
{ {
if( !a ) if( !a )
return; 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); m_free(a);
} }
void 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 ) if( a->use_rmd160 ) {
md5_write( a->u.md5, inbuf, inlen ); rmd160_write( &a->rmd160, a->buffer, a->bufcount );
else if( a->algo == DIGEST_ALGO_RMD160 ) rmd160_write( &a->rmd160, inbuf, inlen );
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_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 void
md_putchar( MD_HANDLE *a, int c ) md_final(MD_HANDLE a)
{ {
if( a->algo == DIGEST_ALGO_MD5 ) if( a->bufcount )
md5_putchar( a->u.md5, c ); md_write( a, NULL, 0 );
else if( a->algo == DIGEST_ALGO_RMD160 ) if( a->use_rmd160 ) {
rmd160_putchar( a->u.rmd, c ); byte *p;
else if( a->algo == DIGEST_ALGO_SHA1 ) rmd160_final( &a->rmd160 );
sha1_putchar( a->u.sha1, c ); p = rmd160_read( &a->rmd160 );
else }
log_bug(NULL); 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 * byte *
md_final(MD_HANDLE *a) md_read( MD_HANDLE a, int algo )
{ {
if( a->algo == DIGEST_ALGO_MD5 ) { if( !algo ) {
if( !a->datalen ) { if( a->use_rmd160 )
md5_final( a->u.md5 ); return rmd160_read( &a->rmd160 );
memcpy(a->data, md5_read( a->u.md5 ), 16); if( a->use_sha1 )
a->datalen = 16; return sha1_read( &a->sha1 );
if( a->use_md5 )
return md5_read( &a->md5 );
} }
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_RMD160 ) {
if( !a->datalen ) {
memcpy(a->data, rmd160_final( a->u.rmd ), 20 );
a->datalen = 20;
}
return a->data;
}
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;
}

60
cipher/md.h Normal file
View File

@ -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*/

View File

@ -61,7 +61,6 @@
#include <assert.h> #include <assert.h>
#include "util.h" #include "util.h"
#include "md5.h" #include "md5.h"
#include "cipher.h" /* kludge for md5_copy2md() */
#include "memory.h" #include "memory.h"
@ -74,7 +73,7 @@
#endif #endif
static void Init( MD5HANDLE mdContext); static void Init( MD5_CONTEXT *mdContext);
static void Transform(u32 *buf,u32 *in); static void Transform(u32 *buf,u32 *in);
static byte PADDING[64] = { static byte PADDING[64] = {
@ -120,56 +119,9 @@ static byte PADDING[64] = {
(a) += (b); \ (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 void
md5_close(MD5HANDLE hd) md5_init( MD5_CONTEXT *mdContext)
{
if( hd )
m_free(hd);
}
static void
Init( MD5HANDLE mdContext)
{ {
mdContext->i[0] = mdContext->i[1] = (u32)0; mdContext->i[0] = mdContext->i[1] = (u32)0;
/* Load magic initialization constants. /* Load magic initialization constants.
@ -178,7 +130,7 @@ Init( MD5HANDLE mdContext)
mdContext->buf[1] = (u32)0xefcdab89L; mdContext->buf[1] = (u32)0xefcdab89L;
mdContext->buf[2] = (u32)0x98badcfeL; mdContext->buf[2] = (u32)0x98badcfeL;
mdContext->buf[3] = (u32)0x10325476L; mdContext->buf[3] = (u32)0x10325476L;
mdContext->bufcount = 0; mdContext->count = 0;
} }
/* The routine Update updates the message-digest context to /* The routine Update updates the message-digest context to
@ -186,15 +138,15 @@ Init( MD5HANDLE mdContext)
* in the message whose digest is being computed. * in the message whose digest is being computed.
*/ */
void void
md5_write( MD5HANDLE mdContext, byte *inBuf, size_t inLen) md5_write( MD5_CONTEXT *mdContext, byte *inBuf, size_t inLen)
{ {
register int i, ii; register int i, ii;
int mdi; int mdi;
u32 in[16]; u32 in[16];
if(mdContext->bufcount) { /* flush the buffer */ if(mdContext->count) { /* flush the buffer */
i = mdContext->bufcount; i = mdContext->count;
mdContext->bufcount = 0; mdContext->count = 0;
md5_write( mdContext, mdContext->digest, i); md5_write( mdContext, mdContext->digest, i);
} }
if( !inBuf ) 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 /* The routine final terminates the message-digest computation and
* ends with the desired message digest in mdContext->digest[0...15]. * ends with the desired message digest in mdContext->digest[0...15].
@ -249,14 +187,14 @@ md5_putchar( MD5HANDLE mdContext, int c )
*/ */
void void
md5_final(MD5HANDLE mdContext) md5_final( MD5_CONTEXT *mdContext )
{ {
u32 in[16]; u32 in[16];
int mdi; int mdi;
unsigned int i, ii; unsigned int i, ii;
unsigned int padLen; unsigned int padLen;
if(mdContext->bufcount) /* flush buffer */ if(mdContext->count) /* flush buffer */
md5_write(mdContext, NULL, 0 ); md5_write(mdContext, NULL, 0 );
/* save number of bits */ /* save number of bits */
in[14] = mdContext->i[0]; 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+2] = (byte)((mdContext->buf[i] >> 16) & 0xFF);
mdContext->digest[ii+3] = (byte)((mdContext->buf[i] >> 24) & 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;
} }

View File

@ -25,20 +25,15 @@
typedef struct { typedef struct {
u32 i[2]; /* number of _bits_ handled mod 2^64 */ u32 i[2]; /* number of _bits_ handled mod 2^64 */
u32 buf[4]; /* scratch buffer */ u32 buf[4]; /* scratch buffer */
int count;
byte in[64]; /* input buffer */ byte in[64]; /* input buffer */
byte digest[16+8+1]; /* actual digest after Final call */ byte digest[16+8+1]; /* actual digest after Final call */
byte bufcount; /* extra room for bintoascii */ } MD5_CONTEXT;
} *MD5HANDLE;
/*-- 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*/ #endif /*G10_MD5_H*/

View File

@ -82,13 +82,12 @@ open_device( const char *name, int minor )
log_fatal("can't open %s: %s\n", name, strerror(errno) ); log_fatal("can't open %s: %s\n", name, strerror(errno) );
if( fstat( fd, &sb ) ) if( fstat( fd, &sb ) )
log_fatal("stat() off %s failed: %s\n", name, strerror(errno) ); log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
if( !S_ISCHR(sb.st_mode) #if defined(__sparc__) && defined(__linux__)
#ifdef __linux__ #warning something is wrong with UltraPenguin /dev/random
|| (sb.st_rdev >> 8) != 1 #else
|| (sb.st_rdev & 0xff) != minor if( !S_ISCHR(sb.st_mode) )
#endif
)
log_fatal("invalid random device!\n" ); log_fatal("invalid random device!\n" );
#endif
return fd; return fd;
} }
@ -140,6 +139,10 @@ the OS a chance to collect more entropy! (Need %d more bytes)\n", length );
assert( length < 200 ); assert( length < 200 );
do { do {
n = read(fd, buffer, length ); 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 ); } while( n == -1 && errno == EINTR );
if( n == -1 ) if( n == -1 )
log_fatal("read error on random device: %s\n", strerror(errno) ); log_fatal("read error on random device: %s\n", strerror(errno) );

View File

@ -25,27 +25,14 @@
typedef struct { typedef struct {
u32 h0,h1,h2,h3,h4; u32 h0,h1,h2,h3,h4;
u32 nblocks; u32 nblocks;
byte buffer[64]; byte buf[64];
int bufcount; int count;
} *RMDHANDLE; } RMD160_CONTEXT;
/**************** void rmd160_init( RMD160_CONTEXT *c );
* Process a single character, this character will be buffered to void rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen);
* increase performance. void rmd160_final(RMD160_CONTEXT *hd);
*/ #define rmd160_read(h) ( (h)->buf )
#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);
#endif /*G10_RMD_H*/ #endif /*G10_RMD_H*/

View File

@ -25,7 +25,6 @@
#include <assert.h> #include <assert.h>
#include "util.h" #include "util.h"
#include "memory.h" #include "memory.h"
#include "cipher.h" /* grrrr */
#include "rmd.h" #include "rmd.h"
/********************************* /*********************************
@ -139,16 +138,16 @@
*/ */
static void void
initialize( RMDHANDLE hd ) rmd160_init( RMD160_CONTEXT *hd )
{ {
hd->h0 = 0x67452301; hd->h0 = 0x67452301;
hd->h1 = 0xEFCDAB89; hd->h1 = 0xEFCDAB89;
hd->h2 = 0x98BADCFE; hd->h2 = 0x98BADCFE;
hd->h3 = 0x10325476; hd->h3 = 0x10325476;
hd->h4 = 0xC3D2E1F0; hd->h4 = 0xC3D2E1F0;
hd->bufcount = 0;
hd->nblocks = 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 * Transform the message X which consists of 16 32-bit-words
*/ */
static void static void
transform( RMDHANDLE hd, byte *data ) transform( RMD160_CONTEXT *hd, byte *data )
{ {
static int r[80] = { static int r[80] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 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 /* Update the message digest with the contents
* of INBUF with length INLEN. * of INBUF with length INLEN.
*/ */
void 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 */ if( hd->count == 64 ) { /* flush the buffer */
transform( hd, hd->buffer ); transform( hd, hd->buf );
hd->bufcount = 0; hd->count = 0;
hd->nblocks++; hd->nblocks++;
} }
if( !inbuf ) if( !inbuf )
return; return;
if( hd->bufcount ) { if( hd->count ) {
for( ; inlen && hd->bufcount < 64; inlen-- ) for( ; inlen && hd->count < 64; inlen-- )
hd->buffer[hd->bufcount++] = *inbuf++; hd->buf[hd->count++] = *inbuf++;
rmd160_write( hd, NULL, 0 ); rmd160_write( hd, NULL, 0 );
if( !inlen ) if( !inlen )
return; return;
@ -326,25 +279,21 @@ rmd160_write( RMDHANDLE hd, byte *inbuf, size_t inlen)
while( inlen >= 64 ) { while( inlen >= 64 ) {
transform( hd, inbuf ); transform( hd, inbuf );
hd->bufcount = 0; hd->count = 0;
hd->nblocks++; hd->nblocks++;
inlen -= 64; inlen -= 64;
inbuf += 64; inbuf += 64;
} }
for( ; inlen && hd->bufcount < 64; inlen-- ) for( ; inlen && hd->count < 64; inlen-- )
hd->buffer[hd->bufcount++] = *inbuf++; hd->buf[hd->count++] = *inbuf++;
} }
/* The routine final terminates the computation and /* The routine terminates the computation
* 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.
*/ */
byte * void
rmd160_final(RMDHANDLE hd) rmd160_final( RMD160_CONTEXT *hd )
{ {
u32 t, msb, lsb; u32 t, msb, lsb;
byte *p; byte *p;
@ -357,37 +306,37 @@ rmd160_final(RMDHANDLE hd)
msb++; msb++;
msb += t >> 26; msb += t >> 26;
t = lsb; t = lsb;
if( (lsb = t + hd->bufcount) < t ) /* add the bufcount */ if( (lsb = t + hd->count) < t ) /* add the count */
msb++; msb++;
t = lsb; t = lsb;
if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */ if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
msb++; msb++;
msb += t >> 29; msb += t >> 29;
if( hd->bufcount < 56 ) { /* enough room */ if( hd->count < 56 ) { /* enough room */
hd->buffer[hd->bufcount++] = 0x80; /* pad */ hd->buf[hd->count++] = 0x80; /* pad */
while( hd->bufcount < 56 ) while( hd->count < 56 )
hd->buffer[hd->bufcount++] = 0; /* pad */ hd->buf[hd->count++] = 0; /* pad */
} }
else { /* need one extra block */ else { /* need one extra block */
hd->buffer[hd->bufcount++] = 0x80; /* pad character */ hd->buf[hd->count++] = 0x80; /* pad character */
while( hd->bufcount < 64 ) while( hd->count < 64 )
hd->buffer[hd->bufcount++] = 0; hd->buf[hd->count++] = 0;
rmd160_write(hd, NULL, 0); /* flush */; 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 */ /* append the 64 bit count */
hd->buffer[56] = lsb ; hd->buf[56] = lsb ;
hd->buffer[57] = lsb >> 8; hd->buf[57] = lsb >> 8;
hd->buffer[58] = lsb >> 16; hd->buf[58] = lsb >> 16;
hd->buffer[59] = lsb >> 24; hd->buf[59] = lsb >> 24;
hd->buffer[60] = msb ; hd->buf[60] = msb ;
hd->buffer[61] = msb >> 8; hd->buf[61] = msb >> 8;
hd->buffer[62] = msb >> 16; hd->buf[62] = msb >> 16;
hd->buffer[63] = msb >> 24; hd->buf[63] = msb >> 24;
transform( hd, hd->buffer ); transform( hd, hd->buf );
p = hd->buffer; p = hd->buf;
#ifdef BIG_ENDIAN_HOST #ifdef BIG_ENDIAN_HOST
#define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \ #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) *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
@ -400,10 +349,6 @@ rmd160_final(RMDHANDLE hd)
X(3); X(3);
X(4); X(4);
#undef X #undef X
initialize( hd ); /* prepare for next cycle */
return hd->buffer; /* now contains the digest */
} }

View File

@ -84,7 +84,6 @@
#include <assert.h> #include <assert.h>
#include "util.h" #include "util.h"
#include "memory.h" #include "memory.h"
#include "cipher.h" /* grrrr */
#include "sha1.h" #include "sha1.h"
@ -110,16 +109,16 @@
( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) ) ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
static void void
initialize( SHA1HANDLE hd ) sha1_init( SHA1_CONTEXT *hd )
{ {
hd->h0 = 0x67452301; hd->h0 = 0x67452301;
hd->h1 = 0xefcdab89; hd->h1 = 0xefcdab89;
hd->h2 = 0x98badcfe; hd->h2 = 0x98badcfe;
hd->h3 = 0x10325476; hd->h3 = 0x10325476;
hd->h4 = 0xc3d2e1f0; hd->h4 = 0xc3d2e1f0;
hd->bufcount = 0;
hd->nblocks = 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 * Transform the message X which consists of 16 32-bit-words
*/ */
static void static void
transform( SHA1HANDLE hd, byte *data ) transform( SHA1_CONTEXT *hd, byte *data )
{ {
u32 A, B, C, D, E; /* Local vars */ u32 A, B, C, D, E; /* Local vars */
u32 eData[ 16 ]; /* Expanded data */ 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 /* Update the message digest with the contents
* of INBUF with length INLEN. * of INBUF with length INLEN.
*/ */
void 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 */ if( hd->count == 64 ) { /* flush the buffer */
transform( hd, hd->buffer ); transform( hd, hd->buf );
hd->bufcount = 0; hd->count = 0;
hd->nblocks++; hd->nblocks++;
} }
if( !inbuf ) if( !inbuf )
return; return;
if( hd->bufcount ) { if( hd->count ) {
for( ; inlen && hd->bufcount < 64; inlen-- ) for( ; inlen && hd->count < 64; inlen-- )
hd->buffer[hd->bufcount++] = *inbuf++; hd->buf[hd->count++] = *inbuf++;
sha1_write( hd, NULL, 0 ); sha1_write( hd, NULL, 0 );
if( !inlen ) if( !inlen )
return; return;
@ -317,13 +269,13 @@ sha1_write( SHA1HANDLE hd, byte *inbuf, size_t inlen)
while( inlen >= 64 ) { while( inlen >= 64 ) {
transform( hd, inbuf ); transform( hd, inbuf );
hd->bufcount = 0; hd->count = 0;
hd->nblocks++; hd->nblocks++;
inlen -= 64; inlen -= 64;
inbuf += 64; inbuf += 64;
} }
for( ; inlen && hd->bufcount < 64; inlen-- ) for( ; inlen && hd->count < 64; inlen-- )
hd->buffer[hd->bufcount++] = *inbuf++; hd->buf[hd->count++] = *inbuf++;
} }
@ -334,8 +286,8 @@ sha1_write( SHA1HANDLE hd, byte *inbuf, size_t inlen)
* Returns: 20 bytes representing the digest. * Returns: 20 bytes representing the digest.
*/ */
byte * void
sha1_final(SHA1HANDLE hd) sha1_final(SHA1_CONTEXT *hd)
{ {
u32 t, msb, lsb; u32 t, msb, lsb;
byte *p; byte *p;
@ -348,37 +300,37 @@ sha1_final(SHA1HANDLE hd)
msb++; msb++;
msb += t >> 26; msb += t >> 26;
t = lsb; t = lsb;
if( (lsb = t + hd->bufcount) < t ) /* add the bufcount */ if( (lsb = t + hd->count) < t ) /* add the count */
msb++; msb++;
t = lsb; t = lsb;
if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */ if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
msb++; msb++;
msb += t >> 29; msb += t >> 29;
if( hd->bufcount < 56 ) { /* enough room */ if( hd->count < 56 ) { /* enough room */
hd->buffer[hd->bufcount++] = 0x80; /* pad */ hd->buf[hd->count++] = 0x80; /* pad */
while( hd->bufcount < 56 ) while( hd->count < 56 )
hd->buffer[hd->bufcount++] = 0; /* pad */ hd->buf[hd->count++] = 0; /* pad */
} }
else { /* need one extra block */ else { /* need one extra block */
hd->buffer[hd->bufcount++] = 0x80; /* pad character */ hd->buf[hd->count++] = 0x80; /* pad character */
while( hd->bufcount < 64 ) while( hd->count < 64 )
hd->buffer[hd->bufcount++] = 0; hd->buf[hd->count++] = 0;
sha1_write(hd, NULL, 0); /* flush */; 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 */ /* append the 64 bit count */
hd->buffer[56] = msb >> 24; hd->buf[56] = msb >> 24;
hd->buffer[57] = msb >> 16; hd->buf[57] = msb >> 16;
hd->buffer[58] = msb >> 8; hd->buf[58] = msb >> 8;
hd->buffer[59] = msb ; hd->buf[59] = msb ;
hd->buffer[60] = lsb >> 24; hd->buf[60] = lsb >> 24;
hd->buffer[61] = lsb >> 16; hd->buf[61] = lsb >> 16;
hd->buffer[62] = lsb >> 8; hd->buf[62] = lsb >> 8;
hd->buffer[63] = lsb ; hd->buf[63] = lsb ;
transform( hd, hd->buffer ); transform( hd, hd->buf );
p = hd->buffer; p = hd->buf;
#ifdef BIG_ENDIAN_HOST #ifdef BIG_ENDIAN_HOST
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) #define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
#else /* little endian */ #else /* little endian */
@ -392,8 +344,6 @@ sha1_final(SHA1HANDLE hd)
X(4); X(4);
#undef X #undef X
initialize( hd ); /* prepare for next cycle */
return hd->buffer; /* now contains the digest */
} }

View File

@ -25,26 +25,14 @@
typedef struct { typedef struct {
u32 h0,h1,h2,h3,h4; u32 h0,h1,h2,h3,h4;
u32 nblocks; u32 nblocks;
byte buffer[64]; byte buf[64];
int bufcount; int count;
} *SHA1HANDLE; } SHA1_CONTEXT;
/**************** void sha1_init( SHA1_CONTEXT *c );
* Process a single character, this character will be buffered to void sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen);
* increase performance. void sha1_final( SHA1_CONTEXT *hd);
*/ #define sha1_read(h) ( (h)->buf )
#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 );
#endif /*G10_SHA1_H*/ #endif /*G10_SHA1_H*/

View File

@ -2,6 +2,107 @@
* For packet version 3 we calculate the keyids this way: * For packet version 3 we calculate the keyids this way:
RSA := low 64 bits of n 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).

View File

@ -31,6 +31,7 @@ g10_SOURCES = g10.c \
openfile.c \ openfile.c \
keyid.c \ keyid.c \
trustdb.c \ trustdb.c \
trustdb.h \
packet.h \ packet.h \
parse-packet.c \ parse-packet.c \
passphrase.c \ passphrase.c \

View File

@ -69,6 +69,7 @@ g10_SOURCES = g10.c \
openfile.c \ openfile.c \
keyid.c \ keyid.c \
trustdb.c \ trustdb.c \
trustdb.h \
packet.h \ packet.h \
parse-packet.c \ parse-packet.c \
passphrase.c \ passphrase.c \

View 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 * Make a hash value from the public key certificate
*/ */
void void
hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc ) hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
{ {
PACKET pkt; PACKET pkt;
int rc = 0; int rc = 0;
@ -210,7 +210,7 @@ hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc )
if( (rc = build_packet( a, &pkt )) ) if( (rc = build_packet( a, &pkt )) )
log_fatal("build public_cert for hashing failed: %s\n", g10_errstr(rc)); log_fatal("build public_cert for hashing failed: %s\n", g10_errstr(rc));
while( (c=iobuf_get(a)) != -1 ) while( (c=iobuf_get(a)) != -1 )
md_putchar( md, c ); md_putc( md, c );
iobuf_cancel(a); iobuf_cancel(a);
} }

View File

@ -66,7 +66,7 @@ g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
void 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; ELG_secret_key skey;
MPI frame; 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 ); 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 ); 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[0] = dp[0];
sig->d.elg.digest_start[1] = dp[1]; sig->d.elg.digest_start[1] = dp[1];
sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) ); sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );

View File

@ -23,9 +23,7 @@
#include "cipher.h" #include "cipher.h"
typedef struct { typedef struct {
MD_HANDLE *md; /* catch all */ MD_HANDLE md; /* catch all */
MD5HANDLE md5; /* if !NULL create md5 */
RMDHANDLE rmd160; /* if !NULL create rmd160 */
size_t maxbuf_size; size_t maxbuf_size;
} md_filter_context_t; } md_filter_context_t;

View 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_n );
mpi_free( cert->d.rsa.rsa_e ); mpi_free( cert->d.rsa.rsa_e );
} }
md5_close( cert->mfx.md5 ); md_close( cert->mfx.md );
rmd160_close( cert->mfx.rmd160 );
m_free(cert); 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_n = mpi_copy( s->d.rsa.rsa_n );
d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e ); d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e );
} }
d->mfx.md5 = NULL; d->mfx.md = NULL;
d->mfx.rmd160 =NULL;
return d; return d;
} }

View File

@ -34,6 +34,7 @@
#include "mpi.h" #include "mpi.h"
#include "cipher.h" #include "cipher.h"
#include "filter.h" #include "filter.h"
#include "trustdb.h"
enum cmd_values { aNull = 0, enum cmd_values { aNull = 0,
aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr, 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 ) { switch( cmd ) {
case aStore: /* only store the file */ case aStore: /* only store the file */
if( argc > 1 ) if( argc > 1 )
@ -582,9 +590,7 @@ print_mds( const char *fname )
FILE *fp; FILE *fp;
char buf[1024]; char buf[1024];
size_t n; size_t n;
MD5HANDLE md5; MD_HANDLE md;
RMDHANDLE rmd160;
SHA1HANDLE sha1;
if( !fname ) { if( !fname ) {
fp = stdin; fp = stdin;
@ -597,31 +603,26 @@ print_mds( const char *fname )
return; return;
} }
md5 = md5_open(0); md = md_open( DIGEST_ALGO_MD5, 0 );
rmd160 = rmd160_open(0); md_enable( md, DIGEST_ALGO_RMD160 );
sha1 = sha1_open(0); md_enable( md, DIGEST_ALGO_SHA1 );
while( (n=fread( buf, 1, DIM(buf), fp )) ) { while( (n=fread( buf, 1, DIM(buf), fp )) )
md5_write( md5, buf, n ); md_write( md, buf, n );
rmd160_write( rmd160, buf, n );
sha1_write( sha1, buf, n );
}
if( ferror(fp) ) if( ferror(fp) )
log_error("%s: %s\n", fname, strerror(errno) ); log_error("%s: %s\n", fname, strerror(errno) );
else { else {
byte *p; byte *p;
md5_final(md5); md_final(md);
printf( "%s: MD5 =", fname ); print_hex(md5_read(md5), 16 ); printf( "%s: MD5 =", fname ); print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
printf("\n%s: RMD160 =", fname ); print_hex(rmd160_final(rmd160), 20 ); printf("\n%s: RMD160 =", fname ); print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
printf("\n%s: SHA1 =", fname ); print_hex(sha1_final(sha1), 20 ); printf("\n%s: SHA1 =", fname ); print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
putchar('\n'); putchar('\n');
} }
md5_close(md5); md_close(md);
rmd160_close(rmd160);
sha1_close(sha1);
if( fp != stdin ) if( fp != stdin )
fclose(fp); fclose(fp);

View File

@ -22,6 +22,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include "util.h" #include "util.h"
@ -408,7 +409,7 @@ generate_keypair()
tty_printf( "\n" tty_printf( "\n"
"You need a User-ID to identify your key; the software constructs the user id\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" "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; uid = NULL;
aname=acomment=amail=NULL; aname=acomment=amail=NULL;
for(;;) { for(;;) {
@ -422,6 +423,8 @@ generate_keypair()
tty_kill_prompt(); tty_kill_prompt();
if( strpbrk( aname, "<([])>" ) ) if( strpbrk( aname, "<([])>" ) )
tty_printf("Invalid character in name\n"); 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 ) else if( strlen(aname) < 5 )
tty_printf("Name must be at least 5 characters long\n"); tty_printf("Name must be at least 5 characters long\n");
else else
@ -464,12 +467,15 @@ generate_keypair()
} }
m_free(uid); 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 ); p = stpcpy(p, aname );
if( *acomment ) if( *acomment )
p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")"); p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")");
if( *amail ) if( *amail )
p = stpcpy(stpcpy(stpcpy(p," <"), 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); tty_printf("You selected this USER-ID:\n \"%s\"\n\n", uid);
for(;;) { for(;;) {

View File

@ -48,14 +48,14 @@ pubkey_letter( int algo )
/* this is special code for V3 which uses ElGamal and /* this is special code for V3 which uses ElGamal and
* calculates a fingerprint like V4, but with rmd160 * calculates a fingerprint like V4, but with rmd160
* and a version byte of 3. Returns an rmd160 handle, caller must * and a version byte of 3. Returns an md handle, caller must
* do rmd160_final() * do md_close()
*/ */
static RMDHANDLE static MD_HANDLE
v3_elg_fingerprint_md( PKT_public_cert *pkc ) v3_elg_fingerprint_md( PKT_public_cert *pkc )
{ {
RMDHANDLE md; MD_HANDLE md;
byte *buf1, *buf2, *buf3; byte *buf1, *buf2, *buf3;
byte *p1, *p2, *p3; byte *p1, *p2, *p3;
unsigned n1, n2, n3; 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) */ /* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */
n = 14 + n1 + n2 + n3; n = 14 + n1 + n2 + n3;
md = rmd160_open(0); md = md_open( DIGEST_ALGO_RMD160, 0);
rmd160_putchar( md, 0x99 ); /* ctb */ md_putc( md, 0x99 ); /* ctb */
rmd160_putchar( md, n >> 8 ); /* 2 byte length header */ md_putc( md, n >> 8 ); /* 2 byte length header */
rmd160_putchar( md, n ); md_putc( md, n );
rmd160_putchar( md, 3 ); /* version */ md_putc( md, 3 ); /* version */
{ u32 a = pkc->timestamp; { u32 a = pkc->timestamp;
rmd160_putchar( md, a >> 24 ); md_putc( md, a >> 24 );
rmd160_putchar( md, a >> 16 ); md_putc( md, a >> 16 );
rmd160_putchar( md, a >> 8 ); md_putc( md, a >> 8 );
rmd160_putchar( md, a ); md_putc( md, a );
} }
{ u16 a = pkc->valid_days; { u16 a = pkc->valid_days;
rmd160_putchar( md, a >> 8 ); md_putc( md, a >> 8 );
rmd160_putchar( md, a ); md_putc( md, a );
} }
rmd160_putchar( md, pkc->pubkey_algo ); md_putc( md, pkc->pubkey_algo );
rmd160_putchar( md, n1>>8); rmd160_putchar( md, n1 ); rmd160_write( md, p1, n1 ); md_putc( md, n1>>8); md_putc( md, n1 ); md_write( md, p1, n1 );
rmd160_putchar( md, n2>>8); rmd160_putchar( md, n2 ); rmd160_write( md, p2, n2 ); md_putc( md, n2>>8); md_putc( md, n2 ); md_write( md, p2, n2 );
rmd160_putchar( md, n3>>8); rmd160_putchar( md, n3 ); rmd160_write( md, p3, n3 ); md_putc( md, n3>>8); md_putc( md, n3 ); md_write( md, p3, n3 );
m_free(buf1); m_free(buf1);
m_free(buf2); m_free(buf2);
m_free(buf3); m_free(buf3);
md_final( md );
return md; return md;
} }
static RMDHANDLE static MD_HANDLE
v3_elg_fingerprint_md_skc( PKT_secret_cert *skc ) v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
{ {
PKT_public_cert pkc; PKT_public_cert pkc;
@ -133,13 +134,13 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
const byte *dp; const byte *dp;
RMDHANDLE md; MD_HANDLE md;
md = v3_elg_fingerprint_md_skc(skc); 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[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] ; keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
lowbits = keyid[1]; lowbits = keyid[1];
rmd160_close(md); md_close(md);
} }
else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) { else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid ); 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 ) { if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
const byte *dp; const byte *dp;
RMDHANDLE md; MD_HANDLE md;
md = v3_elg_fingerprint_md(pkc); 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[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] ; keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
lowbits = keyid[1]; lowbits = keyid[1];
rmd160_close(md); md_close(md);
} }
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid ); 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; unsigned n;
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
RMDHANDLE md; MD_HANDLE md;
md = v3_elg_fingerprint_md(pkc); md = v3_elg_fingerprint_md(pkc);
dp = rmd160_final( md ); dp = md_read( md, DIGEST_ALGO_RMD160 );
array = m_alloc( 20 ); array = m_alloc( 20 );
len = 20; len = 20;
memcpy(array, dp, 20 ); memcpy(array, dp, 20 );
rmd160_close(md); md_close(md);
} }
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { 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 ); p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL );
for( ; !*p && n; p++, n-- ) for( ; !*p && n; p++, n-- )
; ;
md5_write( md, p, n ); md_write( md, p, n );
m_free(buf); m_free(buf);
p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL ); p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL );
for( ; !*p && n; p++, n-- ) for( ; !*p && n; p++, n-- )
; ;
md5_write( md, p, n ); md_write( md, p, n );
m_free(buf); m_free(buf);
md5_final(md); md_final(md);
array = m_alloc( 16 ); array = m_alloc( 16 );
len = 16; len = 16;
memcpy(array, md5_read(md), 16 ); memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
md5_close(md); md_close(md);
} }
else { else {
array = m_alloc(1); array = m_alloc(1);

View 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_sha1_value( byte *md, unsigned len, unsigned nbits );
MPI encode_rmd160_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_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 --*/ /*-- comment.c --*/
KBNODE make_comment_node( const char *s ); KBNODE make_comment_node( const char *s );
/*-- elg.c --*/ /*-- elg.c --*/
void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ); 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 --*/ /*-- rsa.c --*/
void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ); 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*/ #endif /*G10_MAIN_H*/

View File

@ -302,7 +302,7 @@ static int
do_check_sig( CTX c, KBNODE node ) do_check_sig( CTX c, KBNODE node )
{ {
PKT_signature *sig; PKT_signature *sig;
MD_HANDLE *md; MD_HANDLE md;
int algo, rc; int algo, rc;
assert( node->pkt->pkttype == PKT_SIGNATURE ); assert( node->pkt->pkttype == PKT_SIGNATURE );
@ -314,7 +314,7 @@ do_check_sig( CTX c, KBNODE node )
algo = sig->d.rsa.digest_algo; algo = sig->d.rsa.digest_algo;
else else
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( (rc=md_okay(algo)) ) if( (rc=check_digest_algo(algo)) )
return rc; return rc;
if( sig->sig_class == 0x00 ) { 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 ) if( c->cert->pkt->pkt.public_cert->mfx.md )
md = md_copy( 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 else
log_bug(NULL); log_bug(NULL);
md_write( md, n1->pkt->pkt.user_id->name, n1->pkt->pkt.user_id->len); md_write( md, n1->pkt->pkt.user_id->name, n1->pkt->pkt.user_id->len);

View File

@ -53,12 +53,8 @@ md_filter( void *opaque, int control,
buf[i] = c; buf[i] = c;
} }
if( i ) { if( i )
if( mfx->md5 ) md_write(mfx->md, buf, i );
md5_write(mfx->md5, buf, i );
if( mfx->rmd160 )
rmd160_write(mfx->rmd160, buf, i );
}
else else
rc = -1; /* eof */ rc = -1; /* eof */
*ret_len = i; *ret_len = i;
@ -72,12 +68,8 @@ md_filter( void *opaque, int control,
void void
free_md_filter_context( md_filter_context_t *mfx ) free_md_filter_context( md_filter_context_t *mfx )
{ {
if( mfx->md5 ) md_close(mfx->md);
md5_close(mfx->md5); mfx->md = NULL;
mfx->md5 = NULL;
if( mfx->rmd160 )
rmd160_close(mfx->rmd160);
mfx->rmd160 = NULL;
mfx->maxbuf_size = 0; mfx->maxbuf_size = 0;
} }

View File

@ -220,7 +220,7 @@ int parse_packet( IOBUF inp, PACKET *ret_pkt);
/*-- build-packet.c --*/ /*-- build-packet.c --*/
int build_packet( IOBUF inp, PACKET *pkt ); int build_packet( IOBUF inp, PACKET *pkt );
u32 calc_packet_length( 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 --*/ /*-- free-packet.c --*/
void free_pubkey_enc( PKT_pubkey_enc *enc ); 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 --*/ /*-- sig-check.c --*/
int signature_check( PKT_signature *sig, MD_HANDLE *digest ); int signature_check( PKT_signature *sig, MD_HANDLE digest );
/*-- seckey-cert.c --*/ /*-- seckey-cert.c --*/
int is_secret_key_protected( PKT_secret_cert *cert ); int is_secret_key_protected( PKT_secret_cert *cert );

View File

@ -438,11 +438,11 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
int is_v4=0; int is_v4=0;
if( pkttype == PKT_PUBLIC_CERT ) { if( pkttype == PKT_PUBLIC_CERT ) {
pkt->pkt.public_cert->mfx.md5 = md5_open(0); pkt->pkt.public_cert->mfx.md = md_open(DIGEST_ALGO_MD5, 0);
pkt->pkt.public_cert->mfx.rmd160 = rmd160_open(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; pkt->pkt.public_cert->mfx.maxbuf_size = 1;
md5_write(pkt->pkt.public_cert->mfx.md5, hdr, hdrlen); md_write(pkt->pkt.public_cert->mfx.md, hdr, hdrlen);
rmd160_write(pkt->pkt.public_cert->mfx.rmd160, hdr, hdrlen);
iobuf_push_filter( inp, md_filter, &pkt->pkt.public_cert->mfx ); iobuf_push_filter( inp, md_filter, &pkt->pkt.public_cert->mfx );
} }

View File

@ -143,13 +143,14 @@ hash_passphrase( DEK *dek, char *pw )
dek->keylen = 0; dek->keylen = 0;
if( dek->algo == CIPHER_ALGO_BLOWFISH ) { if( dek->algo == CIPHER_ALGO_BLOWFISH ) {
RMDHANDLE rmd; MD_HANDLE md;
rmd = rmd160_open(1); md = md_open(DIGEST_ALGO_RMD160, 1);
rmd160_write( rmd, pw, strlen(pw) ); md_write( md, pw, strlen(pw) );
md_final( md );
dek->keylen = 20; dek->keylen = 20;
memcpy( dek->key, rmd160_final(rmd), dek->keylen ); memcpy( dek->key, md_read(md,0), dek->keylen );
rmd160_close(rmd); md_close(md);
} }
else else
rc = G10ERR_UNSUPPORTED; rc = G10ERR_UNSUPPORTED;

View File

@ -31,6 +31,22 @@
#include "keydb.h" #include "keydb.h"
#include "memory.h" #include "memory.h"
#include "util.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 void
@ -64,14 +80,28 @@ build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list )
free_public_cert( pkc ); pkc = NULL; free_public_cert( pkc ); pkc = NULL;
log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) ); log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) );
} }
else if( is_valid_pubkey_algo(pkc->pubkey_algo) ) { 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; PKC_LIST r;
r = m_alloc( sizeof *r ); r = m_alloc( sizeof *r );
r->pkc = pkc; pkc = NULL; r->pkc = pkc; pkc = NULL;
r->next = pkc_list; r->next = pkc_list;
r->mark = 0; r->mark = 0;
pkc_list = r; pkc_list = r;
} }
else { /* we don't trust this pkc */
free_public_cert( pkc ); pkc = NULL;
}
}
else { else {
free_public_cert( pkc ); pkc = NULL; free_public_cert( pkc ); pkc = NULL;
log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) ); log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) );

View File

@ -79,11 +79,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
goto leave; goto leave;
} }
if( mfx->md ) if( mfx->md )
md_putchar(mfx->md, c ); md_putc(mfx->md, c );
if( mfx->rmd160 )
rmd160_putchar(mfx->rmd160, c );
if( mfx->md5 )
md5_putchar(mfx->md5, c );
if( putc( c, fp ) == EOF ) { if( putc( c, fp ) == EOF ) {
log_error("Error writing to '%s': %s\n", fname, strerror(errno) ); log_error("Error writing to '%s': %s\n", fname, strerror(errno) );
rc = G10ERR_WRITE_FILE; rc = G10ERR_WRITE_FILE;
@ -93,10 +89,8 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
} }
else { else {
while( (c = iobuf_get(pt->buf)) != -1 ) { while( (c = iobuf_get(pt->buf)) != -1 ) {
if( mfx->rmd160 ) if( mfx->md )
rmd160_putchar(mfx->rmd160, c ); md_putc(mfx->md, c );
if( mfx->md5 )
md5_putchar(mfx->md5, c );
if( putc( c, fp ) == EOF ) { if( putc( c, fp ) == EOF ) {
log_error("Error writing to '%s': %s\n", log_error("Error writing to '%s': %s\n",
fname, strerror(errno) ); 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 ) { while( (c = iobuf_get(fp)) != -1 ) {
if( mfx->md ) if( mfx->md )
md_putchar(mfx->md, c ); md_putc(mfx->md, c );
if( mfx->rmd160 )
rmd160_putchar(mfx->rmd160, c );
if( mfx->md5 )
md5_putchar(mfx->md5, c );
} }
iobuf_close(fp); iobuf_close(fp);

View File

@ -64,7 +64,7 @@ g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
void 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 #ifdef HAVE_RSA_CIPHER
RSA_secret_key skey; 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 ); 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 ); 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[0] = dp[0];
sig->d.rsa.digest_start[1] = dp[1]; sig->d.rsa.digest_start[1] = dp[1];
sig->d.rsa.rsa_integer = sig->d.rsa.rsa_integer =

View File

@ -226,16 +226,17 @@ encode_md5_value( byte *md, unsigned len, unsigned nbits )
} }
MPI MPI
encode_md_value( MD_HANDLE *md, unsigned nbits ) encode_md_value( MD_HANDLE md, unsigned nbits )
{ {
byte *p = md_final( md ); switch( md_get_algo( md ) ) {
if( md->algo == DIGEST_ALGO_MD5 ) case DIGEST_ALGO_MD5:
return encode_md5_value( p, 16, nbits ); return encode_md5_value( md_read(md, DIGEST_ALGO_MD5), 16, nbits );
else if( md->algo == DIGEST_ALGO_RMD160 ) case DIGEST_ALGO_RMD160:
return encode_rmd160_value( p, 20, nbits ); return encode_rmd160_value( md_read(md, DIGEST_ALGO_RMD160), 20, nbits );
else if( md->algo == DIGEST_ALGO_SHA1 ) case DIGEST_ALGO_SHA1:
return encode_sha1_value( p, 20, nbits ); return encode_sha1_value( md_read(md, DIGEST_ALGO_SHA1), 20, nbits );
else default:
log_bug(NULL); log_bug(NULL);
} }
}

View File

@ -38,7 +38,7 @@
* is able to append some data, before getting the digest. * is able to append some data, before getting the digest.
*/ */
int 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 ); PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
MPI result = NULL; MPI result = NULL;
@ -54,16 +54,17 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
ELG_public_key pkey; 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; goto leave;
/* complete the digest */ /* complete the digest */
md_putchar( digest, sig->sig_class ); md_putc( digest, sig->sig_class );
{ u32 a = sig->timestamp; { u32 a = sig->timestamp;
md_putchar( digest, (a >> 24) & 0xff ); md_putc( digest, (a >> 24) & 0xff );
md_putchar( digest, (a >> 16) & 0xff ); md_putc( digest, (a >> 16) & 0xff );
md_putchar( digest, (a >> 8) & 0xff ); md_putc( digest, (a >> 8) & 0xff );
md_putchar( digest, a & 0xff ); md_putc( digest, a & 0xff );
} }
md_final( digest );
result = encode_md_value( digest, mpi_get_nbits(pkc->d.elg.p)); result = encode_md_value( digest, mpi_get_nbits(pkc->d.elg.p));
pkey.p = pkc->d.elg.p; pkey.p = pkc->d.elg.p;
pkey.g = pkc->d.elg.g; pkey.g = pkc->d.elg.g;
@ -134,14 +135,15 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
} }
/* complete the digest */ /* complete the digest */
md_putchar( digest, sig->sig_class ); md_putc( digest, sig->sig_class );
{ u32 a = sig->timestamp; { u32 a = sig->timestamp;
md_putchar( digest, (a >> 24) & 0xff ); md_putc( digest, (a >> 24) & 0xff );
md_putchar( digest, (a >> 16) & 0xff ); md_putc( digest, (a >> 16) & 0xff );
md_putchar( digest, (a >> 8) & 0xff ); md_putc( digest, (a >> 8) & 0xff );
md_putchar( digest, a & 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++ ) for(i=19; i >= 0; i--, dp++ )
if( mpi_getbyte( result, i ) != *dp ) { if( mpi_getbyte( result, i ) != *dp ) {
rc = G10ERR_BAD_SIGN; rc = G10ERR_BAD_SIGN;
@ -177,14 +179,15 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
} }
/* complete the digest */ /* complete the digest */
md_putchar( digest, sig->sig_class ); md_putc( digest, sig->sig_class );
{ u32 a = sig->timestamp; { u32 a = sig->timestamp;
md_putchar( digest, (a >> 24) & 0xff ); md_putc( digest, (a >> 24) & 0xff );
md_putchar( digest, (a >> 16) & 0xff ); md_putc( digest, (a >> 16) & 0xff );
md_putchar( digest, (a >> 8) & 0xff ); md_putc( digest, (a >> 8) & 0xff );
md_putchar( digest, a & 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++ ) for(i=15; i >= 0; i--, dp++ )
if( mpi_getbyte( result, i ) != *dp ) { if( mpi_getbyte( result, i ) != *dp ) {
rc = G10ERR_BAD_SIGN; rc = G10ERR_BAD_SIGN;
@ -220,7 +223,7 @@ int
check_key_signature( KBNODE root, KBNODE node ) check_key_signature( KBNODE root, KBNODE node )
{ {
KBNODE unode; KBNODE unode;
MD_HANDLE *md; MD_HANDLE md;
PKT_public_cert *pkc; PKT_public_cert *pkc;
PKT_signature *sig; PKT_signature *sig;
int algo; int algo;
@ -239,7 +242,7 @@ check_key_signature( KBNODE root, KBNODE node )
algo = sig->d.rsa.digest_algo; algo = sig->d.rsa.digest_algo;
else else
return G10ERR_PUBKEY_ALGO; return G10ERR_PUBKEY_ALGO;
if( (rc=md_okay(algo)) ) if( (rc=check_digest_algo(algo)) )
return rc; return rc;
unode = find_kbparent( root, node ); unode = find_kbparent( root, node );

View File

@ -41,7 +41,7 @@
static int 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; int rc=0;
@ -119,7 +119,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
/* prepare to calculate the MD over the input */ /* prepare to calculate the MD over the input */
if( opt.textmode && opt.armor ) if( opt.textmode && opt.armor )
iobuf_push_filter( inp, text_filter, &tfx ); 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 ); iobuf_push_filter( inp, md_filter, &mfx );
if( opt.armor ) 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 ) { for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) {
PKT_secret_cert *skc; PKT_secret_cert *skc;
PKT_signature *sig; PKT_signature *sig;
RMDHANDLE rmd; MD_HANDLE md;
byte *dp; byte *dp;
skc = skc_rover->skc; skc = skc_rover->skc;
@ -205,15 +205,16 @@ sign_file( const char *filename, int detached, STRLIST locusr,
sig->timestamp = make_timestamp(); sig->timestamp = make_timestamp();
sig->sig_class = opt.textmode? 0x01 : 0x00; sig->sig_class = opt.textmode? 0x01 : 0x00;
rmd = rmd160_copy( mfx.rmd160 ); md = md_copy( mfx.md );
rmd160_putchar( rmd, sig->sig_class ); md_putc( md, sig->sig_class );
{ u32 a = sig->timestamp; { u32 a = sig->timestamp;
rmd160_putchar( rmd, (a >> 24) & 0xff ); md_putc( md, (a >> 24) & 0xff );
rmd160_putchar( rmd, (a >> 16) & 0xff ); md_putc( md, (a >> 16) & 0xff );
rmd160_putchar( rmd, (a >> 8) & 0xff ); md_putc( md, (a >> 8) & 0xff );
rmd160_putchar( rmd, a & 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 ) { if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
ELG_secret_key skey; ELG_secret_key skey;
@ -268,7 +269,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
else else
log_bug(NULL); log_bug(NULL);
rmd160_close( rmd ); md_close( md );
/* and write it */ /* and write it */
init_packet(&pkt); init_packet(&pkt);
@ -289,7 +290,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
else else
iobuf_close(out); iobuf_close(out);
iobuf_close(inp); iobuf_close(inp);
rmd160_close( mfx.rmd160 ); md_close( mfx.md );
release_skc_list( skc_list ); release_skc_list( skc_list );
release_pkc_list( pkc_list ); release_pkc_list( pkc_list );
return rc; return rc;
@ -621,7 +622,7 @@ sign_key( const char *username, STRLIST locusr )
leave: leave:
release_kbnode( keyblock ); release_kbnode( keyblock );
release_skc_list( skc_list ); release_skc_list( skc_list );
rmd160_close( mfx.rmd160 ); md_close( mfx.md );
return rc; return rc;
} }
@ -830,7 +831,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
{ {
PKT_signature *sig; PKT_signature *sig;
int rc=0; int rc=0;
MD_HANDLE *md; MD_HANDLE md;
assert( sigclass >= 0x10 && sigclass <= 0x13 ); assert( sigclass >= 0x10 && sigclass <= 0x13 );
md = md_open( digest_algo, 0 ); 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->timestamp = make_timestamp();
sig->sig_class = sigclass; sig->sig_class = sigclass;
md_putchar( md, sig->sig_class ); md_putc( md, sig->sig_class );
{ u32 a = sig->timestamp; { u32 a = sig->timestamp;
md_putchar( md, (a >> 24) & 0xff ); md_putc( md, (a >> 24) & 0xff );
md_putchar( md, (a >> 16) & 0xff ); md_putc( md, (a >> 16) & 0xff );
md_putchar( md, (a >> 8) & 0xff ); md_putc( md, (a >> 8) & 0xff );
md_putchar( md, a & 0xff ); md_putc( md, a & 0xff );
} }
rc = complete_sig( sig, skc, md ); rc = complete_sig( sig, skc, md );

View File

@ -60,7 +60,7 @@ build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock )
free_secret_cert( skc ); skc = NULL; free_secret_cert( skc ); skc = NULL;
log_error("no default secret key: %s\n", g10_errstr(rc) ); 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; SKC_LIST r;
r = m_alloc( sizeof *r ); r = m_alloc( sizeof *r );
r->skc = skc; skc = NULL; 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; free_secret_cert( skc ); skc = NULL;
log_error("skipped '%s': %s\n", locusr->d, g10_errstr(rc) ); 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; SKC_LIST r;
r = m_alloc( sizeof *r ); r = m_alloc( sizeof *r );
r->skc = skc; skc = NULL; r->skc = skc; skc = NULL;

View File

@ -22,6 +22,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
@ -30,6 +31,215 @@
#include "keydb.h" #include "keydb.h"
#include "memory.h" #include "memory.h"
#include "util.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;
}

28
g10/trustdb.h Normal file
View File

@ -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*/

View File

@ -28,9 +28,7 @@
#define DBG_CIPHER cipher_debug_mode #define DBG_CIPHER cipher_debug_mode
#include "mpi.h" #include "mpi.h"
#include "../cipher/md5.h" #include "../cipher/md.h"
#include "../cipher/rmd.h"
#include "../cipher/sha1.h"
#ifdef HAVE_RSA_CIPHER #ifdef HAVE_RSA_CIPHER
#include "../cipher/rsa.h" #include "../cipher/rsa.h"
#endif #endif
@ -67,26 +65,9 @@ typedef struct {
byte key[20]; /* this is the largest used keylen */ byte key[20]; /* this is the largest used keylen */
} DEK; } 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; 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 --*/ /*-- misc.c --*/
int string_to_cipher_algo( const char *string ); 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_pubkey_algo( int algo );
int check_digest_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 --*/ /*-- random.c --*/
void randomize_buffer( byte *buffer, size_t length, int level ); void randomize_buffer( byte *buffer, size_t length, int level );
byte get_random_byte( int level ); byte get_random_byte( int level );

View File

@ -52,5 +52,6 @@
#define G10ERR_BAD_MPI 30 #define G10ERR_BAD_MPI 30
#define G10ERR_RESOURCE_LIMIT 31 #define G10ERR_RESOURCE_LIMIT 31
#define G10ERR_INV_KEYRING 32 #define G10ERR_INV_KEYRING 32
#define G10ERR_TRUSTDB 33 /* a problem with the trustdb */
#endif /*G10_ERRORS_H*/ #endif /*G10_ERRORS_H*/

View File

@ -39,27 +39,11 @@
#define DBG_MPI mpi_debug_mode #define DBG_MPI mpi_debug_mode
int mpi_debug_mode; int mpi_debug_mode;
#if defined(__i386__) #define BITS_PER_MPI_LIMB (8*SIZEOF_UNSIGNED_LONG)
#define BITS_PER_MPI_LIMB 32 #define BYTES_PER_MPI_LIMB SIZEOF_UNSIGNED_LONG
#define BYTES_PER_MPI_LIMB 4 #define BYTES_PER_MPI_LIMB2 (2*SIZEOF_UNSIGNED_LONG)
#define BYTES_PER_MPI_LIMB2 8
typedef unsigned long int mpi_limb_t; typedef unsigned long int mpi_limb_t;
typedef signed long int mpi_limb_signed_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
typedef struct mpi_struct { typedef struct mpi_struct {
int alloced; /* array size (# of allocated limbs) */ int alloced; /* array size (# of allocated limbs) */

View File

@ -48,6 +48,24 @@ case "${target}" in
path="pa7100 hppa1_1 hppa" path="pa7100 hppa1_1 hppa"
mpi_extra_modules="udiv-qrnnd" 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 echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
path="" path=""

4
mpi/sparc32/distfiles Normal file
View File

@ -0,0 +1,4 @@
mpih-add1.S
udiv.S

237
mpi/sparc32/mpih-add1.S Normal file
View File

@ -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

188
mpi/sparc32/udiv.S Normal file
View File

@ -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

5
mpi/sparc32v8/distfiles Normal file
View File

@ -0,0 +1,5 @@
mpih-mul1.S
mpih-mul2.S
mpih-mul3.S

101
mpi/sparc32v8/mpih-mul1.S Normal file
View File

@ -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

124
mpi/sparc32v8/mpih-mul2.S Normal file
View File

@ -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

60
mpi/sparc32v8/mpih-mul3.S Normal file
View File

@ -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

3
mpi/supersparc/distfiles Normal file
View File

@ -0,0 +1,3 @@
udiv.S

110
mpi/supersparc/udiv.S Normal file
View File

@ -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