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:
parent
762d3d7197
commit
ed36092588
177
INSTALL
177
INSTALL
@ -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
6
NEWS
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
* The string "(INSECURE!)" is appended to a new user-id if this
|
||||||
|
is generated on a system without a good random number generator.
|
||||||
|
|
||||||
|
* works (more or less) on a UltraPenguin (sparc64--gnu-linux)
|
||||||
|
|
18
README
18
README
@ -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
2
TODO
@ -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().
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
211
cipher/md.c
211
cipher/md.c
@ -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
60
cipher/md.h
Normal 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*/
|
123
cipher/md5.c
123
cipher/md5.c
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
17
cipher/md5.h
17
cipher/md5.h
@ -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*/
|
||||||
|
@ -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) );
|
||||||
|
27
cipher/rmd.h
27
cipher/rmd.h
@ -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*/
|
||||||
|
127
cipher/rmd160.c
127
cipher/rmd160.c
@ -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 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
120
cipher/sha1.c
120
cipher/sha1.c
@ -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 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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*/
|
||||||
|
103
doc/DETAILS
103
doc/DETAILS
@ -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).
|
||||||
|
|
||||||
|
@ -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 \
|
||||||
|
@ -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 \
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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) );
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
g10/g10.c
37
g10/g10.c
@ -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);
|
||||||
|
10
g10/keygen.c
10
g10/keygen.c
@ -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(;;) {
|
||||||
|
73
g10/keyid.c
73
g10/keyid.c
@ -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);
|
||||||
|
@ -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*/
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 );
|
||||||
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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) );
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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 =
|
||||||
|
19
g10/seskey.c
19
g10/seskey.c
@ -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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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 );
|
||||||
|
39
g10/sign.c
39
g10/sign.c
@ -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 );
|
||||||
|
@ -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;
|
||||||
|
210
g10/trustdb.c
210
g10/trustdb.c
@ -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
28
g10/trustdb.h
Normal 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*/
|
@ -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 );
|
||||||
|
@ -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*/
|
||||||
|
@ -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) */
|
||||||
|
@ -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
4
mpi/sparc32/distfiles
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
mpih-add1.S
|
||||||
|
udiv.S
|
||||||
|
|
237
mpi/sparc32/mpih-add1.S
Normal file
237
mpi/sparc32/mpih-add1.S
Normal 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
188
mpi/sparc32/udiv.S
Normal 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
5
mpi/sparc32v8/distfiles
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
mpih-mul1.S
|
||||||
|
mpih-mul2.S
|
||||||
|
mpih-mul3.S
|
||||||
|
|
101
mpi/sparc32v8/mpih-mul1.S
Normal file
101
mpi/sparc32v8/mpih-mul1.S
Normal 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
124
mpi/sparc32v8/mpih-mul2.S
Normal 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
60
mpi/sparc32v8/mpih-mul3.S
Normal 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
3
mpi/supersparc/distfiles
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
udiv.S
|
||||||
|
|
110
mpi/supersparc/udiv.S
Normal file
110
mpi/supersparc/udiv.S
Normal 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
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user