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
|
||||
---------
|
||||
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
|
||||
|
||||
* Burn the buffers used by fopen().
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@ cipher_SOURCES = blowfish.c \
|
||||
dsa.h \
|
||||
dsa.c \
|
||||
md.c \
|
||||
md.h \
|
||||
misc.c \
|
||||
smallprime.c
|
||||
|
||||
|
@ -60,6 +60,7 @@ cipher_SOURCES = blowfish.c \
|
||||
dsa.h \
|
||||
dsa.c \
|
||||
md.c \
|
||||
md.h \
|
||||
misc.c \
|
||||
smallprime.c
|
||||
|
||||
|
213
cipher/md.c
213
cipher/md.c
@ -27,146 +27,135 @@
|
||||
#include "errors.h"
|
||||
|
||||
|
||||
int
|
||||
md_okay( int algo )
|
||||
{
|
||||
return check_digest_algo( algo );
|
||||
}
|
||||
|
||||
|
||||
MD_HANDLE *
|
||||
/****************
|
||||
* Open a message digest handle for use with algorithm ALGO.
|
||||
* More algorithms may be added by md_enable(). The initial algorithm
|
||||
* may be 0.
|
||||
*/
|
||||
MD_HANDLE
|
||||
md_open( int algo, int secure )
|
||||
{
|
||||
MD_HANDLE *hd;
|
||||
MD_HANDLE hd;
|
||||
|
||||
hd = m_alloc( sizeof *hd + 19 );
|
||||
hd->algo = algo;
|
||||
hd->datalen = 0;
|
||||
if( algo == DIGEST_ALGO_MD5 )
|
||||
hd->u.md5 = md5_open( secure );
|
||||
else if( algo == DIGEST_ALGO_RMD160 )
|
||||
hd->u.rmd= rmd160_open( secure );
|
||||
else if( algo == DIGEST_ALGO_SHA1 )
|
||||
hd->u.sha1 = sha1_open( secure );
|
||||
else
|
||||
return NULL;
|
||||
|
||||
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);
|
||||
hd = secure ? m_alloc_secure_clear( sizeof *hd )
|
||||
: m_alloc_clear( sizeof *hd );
|
||||
if( algo )
|
||||
md_enable( hd, algo );
|
||||
return hd;
|
||||
}
|
||||
|
||||
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 )
|
||||
return;
|
||||
if( a->algo == DIGEST_ALGO_MD5 )
|
||||
md5_close( a->u.md5 );
|
||||
else if( a->algo == DIGEST_ALGO_RMD160 )
|
||||
rmd160_close( a->u.rmd );
|
||||
else if( a->algo == DIGEST_ALGO_SHA1 )
|
||||
sha1_close( a->u.sha1 );
|
||||
else
|
||||
log_bug(NULL);
|
||||
m_free(a);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md_write( MD_HANDLE *a, byte *inbuf, size_t inlen)
|
||||
md_write( MD_HANDLE a, byte *inbuf, size_t inlen)
|
||||
{
|
||||
if( a->algo == DIGEST_ALGO_MD5 )
|
||||
md5_write( a->u.md5, inbuf, inlen );
|
||||
else if( a->algo == DIGEST_ALGO_RMD160 )
|
||||
rmd160_write( a->u.rmd, inbuf, inlen );
|
||||
else if( a->algo == DIGEST_ALGO_SHA1 )
|
||||
sha1_write( a->u.sha1, inbuf, inlen );
|
||||
else
|
||||
log_bug(NULL);
|
||||
if( a->use_rmd160 ) {
|
||||
rmd160_write( &a->rmd160, a->buffer, a->bufcount );
|
||||
rmd160_write( &a->rmd160, inbuf, inlen );
|
||||
}
|
||||
if( a->use_sha1 ) {
|
||||
sha1_write( &a->sha1, a->buffer, a->bufcount );
|
||||
sha1_write( &a->sha1, inbuf, inlen );
|
||||
}
|
||||
if( a->use_md5 ) {
|
||||
md5_write( &a->md5, a->buffer, a->bufcount );
|
||||
md5_write( &a->md5, inbuf, inlen );
|
||||
}
|
||||
a->bufcount = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
md_putchar( MD_HANDLE *a, int c )
|
||||
md_final(MD_HANDLE a)
|
||||
{
|
||||
if( a->algo == DIGEST_ALGO_MD5 )
|
||||
md5_putchar( a->u.md5, c );
|
||||
else if( a->algo == DIGEST_ALGO_RMD160 )
|
||||
rmd160_putchar( a->u.rmd, c );
|
||||
else if( a->algo == DIGEST_ALGO_SHA1 )
|
||||
sha1_putchar( a->u.sha1, c );
|
||||
else
|
||||
log_bug(NULL);
|
||||
if( a->bufcount )
|
||||
md_write( a, NULL, 0 );
|
||||
if( a->use_rmd160 ) {
|
||||
byte *p;
|
||||
rmd160_final( &a->rmd160 );
|
||||
p = rmd160_read( &a->rmd160 );
|
||||
}
|
||||
if( a->use_sha1 )
|
||||
sha1_final( &a->sha1 );
|
||||
if( a->use_md5 )
|
||||
md5_final( &a->md5 );
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* if ALGO is null get the digest for the used algo (which should be only one)
|
||||
*/
|
||||
byte *
|
||||
md_final(MD_HANDLE *a)
|
||||
md_read( MD_HANDLE a, int algo )
|
||||
{
|
||||
if( a->algo == DIGEST_ALGO_MD5 ) {
|
||||
if( !a->datalen ) {
|
||||
md5_final( a->u.md5 );
|
||||
memcpy(a->data, md5_read( a->u.md5 ), 16);
|
||||
a->datalen = 16;
|
||||
}
|
||||
return a->data;
|
||||
if( !algo ) {
|
||||
if( a->use_rmd160 )
|
||||
return rmd160_read( &a->rmd160 );
|
||||
if( a->use_sha1 )
|
||||
return sha1_read( &a->sha1 );
|
||||
if( a->use_md5 )
|
||||
return md5_read( &a->md5 );
|
||||
}
|
||||
else if( a->algo == DIGEST_ALGO_RMD160 ) {
|
||||
if( !a->datalen ) {
|
||||
memcpy(a->data, rmd160_final( a->u.rmd ), 20 );
|
||||
a->datalen = 20;
|
||||
}
|
||||
return a->data;
|
||||
else {
|
||||
if( algo == DIGEST_ALGO_RMD160 )
|
||||
return rmd160_read( &a->rmd160 );
|
||||
if( algo == DIGEST_ALGO_SHA1 )
|
||||
return sha1_read( &a->sha1 );
|
||||
if( algo == DIGEST_ALGO_MD5 )
|
||||
return md5_read( &a->md5 );
|
||||
}
|
||||
else if( a->algo == DIGEST_ALGO_SHA1 ) {
|
||||
if( !a->datalen ) {
|
||||
memcpy(a->data, sha1_final( a->u.sha1 ), 20 );
|
||||
a->datalen = 20;
|
||||
}
|
||||
return a->data;
|
||||
}
|
||||
else
|
||||
log_bug(NULL);
|
||||
log_bug(NULL);
|
||||
}
|
||||
|
||||
int
|
||||
md_get_algo( MD_HANDLE a )
|
||||
{
|
||||
if( a->use_rmd160 )
|
||||
return DIGEST_ALGO_RMD160;
|
||||
if( a->use_sha1 )
|
||||
return DIGEST_ALGO_SHA1;
|
||||
if( a->use_md5 )
|
||||
return DIGEST_ALGO_MD5;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
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 "util.h"
|
||||
#include "md5.h"
|
||||
#include "cipher.h" /* kludge for md5_copy2md() */
|
||||
#include "memory.h"
|
||||
|
||||
|
||||
@ -74,7 +73,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
static void Init( MD5HANDLE mdContext);
|
||||
static void Init( MD5_CONTEXT *mdContext);
|
||||
static void Transform(u32 *buf,u32 *in);
|
||||
|
||||
static byte PADDING[64] = {
|
||||
@ -120,56 +119,9 @@ static byte PADDING[64] = {
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
/* The routine Init initializes the message-digest context
|
||||
* mdContext. All fields are set to zero.
|
||||
* mode should be zero is reserved for extensions.
|
||||
*/
|
||||
|
||||
MD5HANDLE
|
||||
md5_open(int secure)
|
||||
{
|
||||
MD5HANDLE mdContext;
|
||||
|
||||
mdContext = secure? m_alloc_secure( sizeof *mdContext )
|
||||
: m_alloc( sizeof *mdContext );
|
||||
Init(mdContext);
|
||||
return mdContext;
|
||||
}
|
||||
|
||||
|
||||
MD5HANDLE
|
||||
md5_copy( MD5HANDLE a )
|
||||
{
|
||||
MD5HANDLE mdContext;
|
||||
|
||||
assert(a);
|
||||
mdContext = m_is_secure(a)? m_alloc_secure( sizeof *mdContext )
|
||||
: m_alloc( sizeof *mdContext );
|
||||
memcpy( mdContext, a, sizeof *a );
|
||||
return mdContext;
|
||||
}
|
||||
|
||||
|
||||
/* BAD Kludge!!! */
|
||||
MD_HANDLE *
|
||||
md5_copy2md( MD5HANDLE a )
|
||||
{
|
||||
MD_HANDLE *md = md_makecontainer( DIGEST_ALGO_MD5 );
|
||||
md->u.md5 = md5_copy( a );
|
||||
return md;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
md5_close(MD5HANDLE hd)
|
||||
{
|
||||
if( hd )
|
||||
m_free(hd);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Init( MD5HANDLE mdContext)
|
||||
md5_init( MD5_CONTEXT *mdContext)
|
||||
{
|
||||
mdContext->i[0] = mdContext->i[1] = (u32)0;
|
||||
/* Load magic initialization constants.
|
||||
@ -178,7 +130,7 @@ Init( MD5HANDLE mdContext)
|
||||
mdContext->buf[1] = (u32)0xefcdab89L;
|
||||
mdContext->buf[2] = (u32)0x98badcfeL;
|
||||
mdContext->buf[3] = (u32)0x10325476L;
|
||||
mdContext->bufcount = 0;
|
||||
mdContext->count = 0;
|
||||
}
|
||||
|
||||
/* The routine Update updates the message-digest context to
|
||||
@ -186,15 +138,15 @@ Init( MD5HANDLE mdContext)
|
||||
* in the message whose digest is being computed.
|
||||
*/
|
||||
void
|
||||
md5_write( MD5HANDLE mdContext, byte *inBuf, size_t inLen)
|
||||
md5_write( MD5_CONTEXT *mdContext, byte *inBuf, size_t inLen)
|
||||
{
|
||||
register int i, ii;
|
||||
int mdi;
|
||||
u32 in[16];
|
||||
|
||||
if(mdContext->bufcount) { /* flush the buffer */
|
||||
i = mdContext->bufcount;
|
||||
mdContext->bufcount = 0;
|
||||
if(mdContext->count) { /* flush the buffer */
|
||||
i = mdContext->count;
|
||||
mdContext->count = 0;
|
||||
md5_write( mdContext, mdContext->digest, i);
|
||||
}
|
||||
if( !inBuf )
|
||||
@ -227,20 +179,6 @@ md5_write( MD5HANDLE mdContext, byte *inBuf, size_t inLen)
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Process a single character, this character will be buffered to
|
||||
* increase performance. The digest-field is used as a buffer.
|
||||
*/
|
||||
|
||||
void
|
||||
md5_putchar( MD5HANDLE mdContext, int c )
|
||||
{
|
||||
if(mdContext->bufcount == 16)
|
||||
md5_write( mdContext, NULL, 0 );
|
||||
mdContext->digest[mdContext->bufcount++] = c & 0xff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The routine final terminates the message-digest computation and
|
||||
* ends with the desired message digest in mdContext->digest[0...15].
|
||||
@ -249,14 +187,14 @@ md5_putchar( MD5HANDLE mdContext, int c )
|
||||
*/
|
||||
|
||||
void
|
||||
md5_final(MD5HANDLE mdContext)
|
||||
md5_final( MD5_CONTEXT *mdContext )
|
||||
{
|
||||
u32 in[16];
|
||||
int mdi;
|
||||
unsigned int i, ii;
|
||||
unsigned int padLen;
|
||||
|
||||
if(mdContext->bufcount) /* flush buffer */
|
||||
if(mdContext->count) /* flush buffer */
|
||||
md5_write(mdContext, NULL, 0 );
|
||||
/* save number of bits */
|
||||
in[14] = mdContext->i[0];
|
||||
@ -284,49 +222,6 @@ md5_final(MD5HANDLE mdContext)
|
||||
mdContext->digest[ii+2] = (byte)((mdContext->buf[i] >> 16) & 0xFF);
|
||||
mdContext->digest[ii+3] = (byte)((mdContext->buf[i] >> 24) & 0xFF);
|
||||
}
|
||||
Init(mdContext);
|
||||
}
|
||||
|
||||
/**********
|
||||
* Returns 16 bytes representing the digest.
|
||||
*/
|
||||
byte *
|
||||
md5_read(MD5HANDLE mdContext)
|
||||
{
|
||||
return mdContext->digest;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Converts the result form Read into a printable representation.
|
||||
* This should only be used direct after a md5_read(), because it uses
|
||||
* In-Place conversion.
|
||||
* Returns digest.
|
||||
*/
|
||||
|
||||
char *
|
||||
md5_tostring( byte *digest )
|
||||
{
|
||||
static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ."
|
||||
"abcdefghijklmnopqrstuvwxyz_"
|
||||
"0123456789";
|
||||
int i;
|
||||
byte *d, *s;
|
||||
|
||||
memmove(digest+8,digest, 16); /* make some room */
|
||||
d = digest;
|
||||
s = digest+8;
|
||||
for(i=0; i < 5; i++, s += 3 ) {
|
||||
*d++ = bintoasc[(*s >> 2) & 077];
|
||||
*d++ = bintoasc[(((*s << 4) & 060) | ((s[1] >> 4) & 017)) & 077];
|
||||
*d++ = bintoasc[(((s[1] << 2) & 074) | ((s[2] >> 6) & 03)) & 077];
|
||||
*d++ = bintoasc[s[2] & 077];
|
||||
}
|
||||
*d++ = bintoasc[(*s >> 2) & 077];
|
||||
*d++ = bintoasc[((*s << 4) & 060) & 077];
|
||||
*d = 0;
|
||||
return (char*)digest;
|
||||
}
|
||||
|
||||
|
||||
|
17
cipher/md5.h
17
cipher/md5.h
@ -25,20 +25,15 @@
|
||||
typedef struct {
|
||||
u32 i[2]; /* number of _bits_ handled mod 2^64 */
|
||||
u32 buf[4]; /* scratch buffer */
|
||||
int count;
|
||||
byte in[64]; /* input buffer */
|
||||
byte digest[16+8+1]; /* actual digest after Final call */
|
||||
byte bufcount; /* extra room for bintoascii */
|
||||
} *MD5HANDLE;
|
||||
} MD5_CONTEXT;
|
||||
|
||||
/*-- md5.c --*/
|
||||
MD5HANDLE md5_open(int);
|
||||
MD5HANDLE md5_copy(MD5HANDLE a);
|
||||
void md5_write(MD5HANDLE hd, byte *inBuf, size_t inLen);
|
||||
void md5_putchar(MD5HANDLE hd, int c );
|
||||
void md5_final(MD5HANDLE hd);
|
||||
byte *md5_read(MD5HANDLE hd);
|
||||
char *md5_tostring( byte *digest );
|
||||
void md5_close(MD5HANDLE hd);
|
||||
|
||||
void md5_init( MD5_CONTEXT *c );
|
||||
void md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen);
|
||||
void md5_final( MD5_CONTEXT *hd);
|
||||
#define md5_read(h) ( (h)->digest )
|
||||
|
||||
#endif /*G10_MD5_H*/
|
||||
|
@ -82,13 +82,12 @@ open_device( const char *name, int minor )
|
||||
log_fatal("can't open %s: %s\n", name, strerror(errno) );
|
||||
if( fstat( fd, &sb ) )
|
||||
log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
|
||||
if( !S_ISCHR(sb.st_mode)
|
||||
#ifdef __linux__
|
||||
|| (sb.st_rdev >> 8) != 1
|
||||
|| (sb.st_rdev & 0xff) != minor
|
||||
#endif
|
||||
)
|
||||
#if defined(__sparc__) && defined(__linux__)
|
||||
#warning something is wrong with UltraPenguin /dev/random
|
||||
#else
|
||||
if( !S_ISCHR(sb.st_mode) )
|
||||
log_fatal("invalid random device!\n" );
|
||||
#endif
|
||||
return fd;
|
||||
}
|
||||
|
||||
@ -140,6 +139,10 @@ the OS a chance to collect more entropy! (Need %d more bytes)\n", length );
|
||||
assert( length < 200 );
|
||||
do {
|
||||
n = read(fd, buffer, length );
|
||||
if( n > length ) {
|
||||
log_error("bogus read from random device (n=%d)\n", n );
|
||||
n = length;
|
||||
}
|
||||
} while( n == -1 && errno == EINTR );
|
||||
if( n == -1 )
|
||||
log_fatal("read error on random device: %s\n", strerror(errno) );
|
||||
|
27
cipher/rmd.h
27
cipher/rmd.h
@ -25,27 +25,14 @@
|
||||
typedef struct {
|
||||
u32 h0,h1,h2,h3,h4;
|
||||
u32 nblocks;
|
||||
byte buffer[64];
|
||||
int bufcount;
|
||||
} *RMDHANDLE;
|
||||
byte buf[64];
|
||||
int count;
|
||||
} RMD160_CONTEXT;
|
||||
|
||||
|
||||
/****************
|
||||
* Process a single character, this character will be buffered to
|
||||
* increase performance.
|
||||
*/
|
||||
#define rmd160_putchar(h,c) \
|
||||
do { \
|
||||
if( (h)->bufcount == 64 ) \
|
||||
rmd160_write( (h), NULL, 0 ); \
|
||||
(h)->buffer[(h)->bufcount++] = (c) & 0xff; \
|
||||
} while(0)
|
||||
|
||||
RMDHANDLE rmd160_open( int secure );
|
||||
RMDHANDLE rmd160_copy( RMDHANDLE a );
|
||||
void rmd160_close(RMDHANDLE hd);
|
||||
void rmd160_write( RMDHANDLE hd, byte *inbuf, size_t inlen);
|
||||
byte * rmd160_final(RMDHANDLE hd);
|
||||
|
||||
void rmd160_init( RMD160_CONTEXT *c );
|
||||
void rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen);
|
||||
void rmd160_final(RMD160_CONTEXT *hd);
|
||||
#define rmd160_read(h) ( (h)->buf )
|
||||
|
||||
#endif /*G10_RMD_H*/
|
||||
|
127
cipher/rmd160.c
127
cipher/rmd160.c
@ -25,7 +25,6 @@
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "cipher.h" /* grrrr */
|
||||
#include "rmd.h"
|
||||
|
||||
/*********************************
|
||||
@ -139,16 +138,16 @@
|
||||
*/
|
||||
|
||||
|
||||
static void
|
||||
initialize( RMDHANDLE hd )
|
||||
void
|
||||
rmd160_init( RMD160_CONTEXT *hd )
|
||||
{
|
||||
hd->h0 = 0x67452301;
|
||||
hd->h1 = 0xEFCDAB89;
|
||||
hd->h2 = 0x98BADCFE;
|
||||
hd->h3 = 0x10325476;
|
||||
hd->h4 = 0xC3D2E1F0;
|
||||
hd->bufcount = 0;
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -156,7 +155,7 @@ initialize( RMDHANDLE hd )
|
||||
* Transform the message X which consists of 16 32-bit-words
|
||||
*/
|
||||
static void
|
||||
transform( RMDHANDLE hd, byte *data )
|
||||
transform( RMD160_CONTEXT *hd, byte *data )
|
||||
{
|
||||
static int r[80] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
@ -257,68 +256,22 @@ transform( RMDHANDLE hd, byte *data )
|
||||
|
||||
|
||||
|
||||
|
||||
RMDHANDLE
|
||||
rmd160_open( int secure )
|
||||
{
|
||||
RMDHANDLE hd;
|
||||
|
||||
hd = secure? m_alloc_secure( sizeof *hd )
|
||||
: m_alloc( sizeof *hd );
|
||||
initialize(hd);
|
||||
return hd;
|
||||
}
|
||||
|
||||
|
||||
RMDHANDLE
|
||||
rmd160_copy( RMDHANDLE a )
|
||||
{
|
||||
RMDHANDLE b;
|
||||
|
||||
assert(a);
|
||||
b = m_is_secure(a)? m_alloc_secure( sizeof *b )
|
||||
: m_alloc( sizeof *b );
|
||||
memcpy( b, a, sizeof *a );
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
/* BAD Kludge!!! */
|
||||
MD_HANDLE *
|
||||
rmd160_copy2md( RMDHANDLE a )
|
||||
{
|
||||
MD_HANDLE *md = md_makecontainer( DIGEST_ALGO_RMD160 );
|
||||
md->u.rmd = rmd160_copy( a );
|
||||
return md;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
rmd160_close(RMDHANDLE hd)
|
||||
{
|
||||
if( hd )
|
||||
m_free(hd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update the message digest with the contents
|
||||
* of INBUF with length INLEN.
|
||||
*/
|
||||
void
|
||||
rmd160_write( RMDHANDLE hd, byte *inbuf, size_t inlen)
|
||||
rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
|
||||
{
|
||||
if( hd->bufcount == 64 ) { /* flush the buffer */
|
||||
transform( hd, hd->buffer );
|
||||
hd->bufcount = 0;
|
||||
if( hd->count == 64 ) { /* flush the buffer */
|
||||
transform( hd, hd->buf );
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
}
|
||||
if( !inbuf )
|
||||
return;
|
||||
if( hd->bufcount ) {
|
||||
for( ; inlen && hd->bufcount < 64; inlen-- )
|
||||
hd->buffer[hd->bufcount++] = *inbuf++;
|
||||
if( hd->count ) {
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
rmd160_write( hd, NULL, 0 );
|
||||
if( !inlen )
|
||||
return;
|
||||
@ -326,25 +279,21 @@ rmd160_write( RMDHANDLE hd, byte *inbuf, size_t inlen)
|
||||
|
||||
while( inlen >= 64 ) {
|
||||
transform( hd, inbuf );
|
||||
hd->bufcount = 0;
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
inlen -= 64;
|
||||
inbuf += 64;
|
||||
}
|
||||
for( ; inlen && hd->bufcount < 64; inlen-- )
|
||||
hd->buffer[hd->bufcount++] = *inbuf++;
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
}
|
||||
|
||||
|
||||
/* The routine final terminates the computation and
|
||||
* returns the digest.
|
||||
* The handle is prepared for a new cycle, but adding bytes to the
|
||||
* handle will the destroy the returned buffer.
|
||||
* Returns: 20 bytes representing the digest.
|
||||
/* The routine terminates the computation
|
||||
*/
|
||||
|
||||
byte *
|
||||
rmd160_final(RMDHANDLE hd)
|
||||
void
|
||||
rmd160_final( RMD160_CONTEXT *hd )
|
||||
{
|
||||
u32 t, msb, lsb;
|
||||
byte *p;
|
||||
@ -357,37 +306,37 @@ rmd160_final(RMDHANDLE hd)
|
||||
msb++;
|
||||
msb += t >> 26;
|
||||
t = lsb;
|
||||
if( (lsb = t + hd->bufcount) < t ) /* add the bufcount */
|
||||
if( (lsb = t + hd->count) < t ) /* add the count */
|
||||
msb++;
|
||||
t = lsb;
|
||||
if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
|
||||
msb++;
|
||||
msb += t >> 29;
|
||||
|
||||
if( hd->bufcount < 56 ) { /* enough room */
|
||||
hd->buffer[hd->bufcount++] = 0x80; /* pad */
|
||||
while( hd->bufcount < 56 )
|
||||
hd->buffer[hd->bufcount++] = 0; /* pad */
|
||||
if( hd->count < 56 ) { /* enough room */
|
||||
hd->buf[hd->count++] = 0x80; /* pad */
|
||||
while( hd->count < 56 )
|
||||
hd->buf[hd->count++] = 0; /* pad */
|
||||
}
|
||||
else { /* need one extra block */
|
||||
hd->buffer[hd->bufcount++] = 0x80; /* pad character */
|
||||
while( hd->bufcount < 64 )
|
||||
hd->buffer[hd->bufcount++] = 0;
|
||||
hd->buf[hd->count++] = 0x80; /* pad character */
|
||||
while( hd->count < 64 )
|
||||
hd->buf[hd->count++] = 0;
|
||||
rmd160_write(hd, NULL, 0); /* flush */;
|
||||
memset(hd->buffer, 0, 56 ); /* fill next block with zeroes */
|
||||
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
|
||||
}
|
||||
/* append the 64 bit count */
|
||||
hd->buffer[56] = lsb ;
|
||||
hd->buffer[57] = lsb >> 8;
|
||||
hd->buffer[58] = lsb >> 16;
|
||||
hd->buffer[59] = lsb >> 24;
|
||||
hd->buffer[60] = msb ;
|
||||
hd->buffer[61] = msb >> 8;
|
||||
hd->buffer[62] = msb >> 16;
|
||||
hd->buffer[63] = msb >> 24;
|
||||
transform( hd, hd->buffer );
|
||||
hd->buf[56] = lsb ;
|
||||
hd->buf[57] = lsb >> 8;
|
||||
hd->buf[58] = lsb >> 16;
|
||||
hd->buf[59] = lsb >> 24;
|
||||
hd->buf[60] = msb ;
|
||||
hd->buf[61] = msb >> 8;
|
||||
hd->buf[62] = msb >> 16;
|
||||
hd->buf[63] = msb >> 24;
|
||||
transform( hd, hd->buf );
|
||||
|
||||
p = hd->buffer;
|
||||
p = hd->buf;
|
||||
#ifdef BIG_ENDIAN_HOST
|
||||
#define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \
|
||||
*p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
|
||||
@ -400,10 +349,6 @@ rmd160_final(RMDHANDLE hd)
|
||||
X(3);
|
||||
X(4);
|
||||
#undef X
|
||||
|
||||
initialize( hd ); /* prepare for next cycle */
|
||||
return hd->buffer; /* now contains the digest */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
120
cipher/sha1.c
120
cipher/sha1.c
@ -84,7 +84,6 @@
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
#include "memory.h"
|
||||
#include "cipher.h" /* grrrr */
|
||||
#include "sha1.h"
|
||||
|
||||
|
||||
@ -110,16 +109,16 @@
|
||||
( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
|
||||
|
||||
|
||||
static void
|
||||
initialize( SHA1HANDLE hd )
|
||||
void
|
||||
sha1_init( SHA1_CONTEXT *hd )
|
||||
{
|
||||
hd->h0 = 0x67452301;
|
||||
hd->h1 = 0xefcdab89;
|
||||
hd->h2 = 0x98badcfe;
|
||||
hd->h3 = 0x10325476;
|
||||
hd->h4 = 0xc3d2e1f0;
|
||||
hd->bufcount = 0;
|
||||
hd->nblocks = 0;
|
||||
hd->count = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -127,7 +126,7 @@ initialize( SHA1HANDLE hd )
|
||||
* Transform the message X which consists of 16 32-bit-words
|
||||
*/
|
||||
static void
|
||||
transform( SHA1HANDLE hd, byte *data )
|
||||
transform( SHA1_CONTEXT *hd, byte *data )
|
||||
{
|
||||
u32 A, B, C, D, E; /* Local vars */
|
||||
u32 eData[ 16 ]; /* Expanded data */
|
||||
@ -247,69 +246,22 @@ transform( SHA1HANDLE hd, byte *data )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SHA1HANDLE
|
||||
sha1_open( int secure )
|
||||
{
|
||||
SHA1HANDLE hd;
|
||||
|
||||
hd = secure? m_alloc_secure( sizeof *hd )
|
||||
: m_alloc( sizeof *hd );
|
||||
initialize(hd);
|
||||
return hd;
|
||||
}
|
||||
|
||||
|
||||
SHA1HANDLE
|
||||
sha1_copy( SHA1HANDLE a )
|
||||
{
|
||||
SHA1HANDLE b;
|
||||
|
||||
assert(a);
|
||||
b = m_is_secure(a)? m_alloc_secure( sizeof *b )
|
||||
: m_alloc( sizeof *b );
|
||||
memcpy( b, a, sizeof *a );
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
/* BAD Kludge!!! */
|
||||
MD_HANDLE *
|
||||
sha1_copy2md( SHA1HANDLE a )
|
||||
{
|
||||
MD_HANDLE *md = md_makecontainer( DIGEST_ALGO_SHA1 );
|
||||
md->u.sha1 = sha1_copy( a );
|
||||
return md;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
sha1_close(SHA1HANDLE hd)
|
||||
{
|
||||
if( hd )
|
||||
m_free(hd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Update the message digest with the contents
|
||||
* of INBUF with length INLEN.
|
||||
*/
|
||||
void
|
||||
sha1_write( SHA1HANDLE hd, byte *inbuf, size_t inlen)
|
||||
sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen)
|
||||
{
|
||||
if( hd->bufcount == 64 ) { /* flush the buffer */
|
||||
transform( hd, hd->buffer );
|
||||
hd->bufcount = 0;
|
||||
if( hd->count == 64 ) { /* flush the buffer */
|
||||
transform( hd, hd->buf );
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
}
|
||||
if( !inbuf )
|
||||
return;
|
||||
if( hd->bufcount ) {
|
||||
for( ; inlen && hd->bufcount < 64; inlen-- )
|
||||
hd->buffer[hd->bufcount++] = *inbuf++;
|
||||
if( hd->count ) {
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
sha1_write( hd, NULL, 0 );
|
||||
if( !inlen )
|
||||
return;
|
||||
@ -317,13 +269,13 @@ sha1_write( SHA1HANDLE hd, byte *inbuf, size_t inlen)
|
||||
|
||||
while( inlen >= 64 ) {
|
||||
transform( hd, inbuf );
|
||||
hd->bufcount = 0;
|
||||
hd->count = 0;
|
||||
hd->nblocks++;
|
||||
inlen -= 64;
|
||||
inbuf += 64;
|
||||
}
|
||||
for( ; inlen && hd->bufcount < 64; inlen-- )
|
||||
hd->buffer[hd->bufcount++] = *inbuf++;
|
||||
for( ; inlen && hd->count < 64; inlen-- )
|
||||
hd->buf[hd->count++] = *inbuf++;
|
||||
}
|
||||
|
||||
|
||||
@ -334,8 +286,8 @@ sha1_write( SHA1HANDLE hd, byte *inbuf, size_t inlen)
|
||||
* Returns: 20 bytes representing the digest.
|
||||
*/
|
||||
|
||||
byte *
|
||||
sha1_final(SHA1HANDLE hd)
|
||||
void
|
||||
sha1_final(SHA1_CONTEXT *hd)
|
||||
{
|
||||
u32 t, msb, lsb;
|
||||
byte *p;
|
||||
@ -348,37 +300,37 @@ sha1_final(SHA1HANDLE hd)
|
||||
msb++;
|
||||
msb += t >> 26;
|
||||
t = lsb;
|
||||
if( (lsb = t + hd->bufcount) < t ) /* add the bufcount */
|
||||
if( (lsb = t + hd->count) < t ) /* add the count */
|
||||
msb++;
|
||||
t = lsb;
|
||||
if( (lsb = t << 3) < t ) /* multiply by 8 to make a bit count */
|
||||
msb++;
|
||||
msb += t >> 29;
|
||||
|
||||
if( hd->bufcount < 56 ) { /* enough room */
|
||||
hd->buffer[hd->bufcount++] = 0x80; /* pad */
|
||||
while( hd->bufcount < 56 )
|
||||
hd->buffer[hd->bufcount++] = 0; /* pad */
|
||||
if( hd->count < 56 ) { /* enough room */
|
||||
hd->buf[hd->count++] = 0x80; /* pad */
|
||||
while( hd->count < 56 )
|
||||
hd->buf[hd->count++] = 0; /* pad */
|
||||
}
|
||||
else { /* need one extra block */
|
||||
hd->buffer[hd->bufcount++] = 0x80; /* pad character */
|
||||
while( hd->bufcount < 64 )
|
||||
hd->buffer[hd->bufcount++] = 0;
|
||||
hd->buf[hd->count++] = 0x80; /* pad character */
|
||||
while( hd->count < 64 )
|
||||
hd->buf[hd->count++] = 0;
|
||||
sha1_write(hd, NULL, 0); /* flush */;
|
||||
memset(hd->buffer, 0, 56 ); /* fill next block with zeroes */
|
||||
memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
|
||||
}
|
||||
/* append the 64 bit count */
|
||||
hd->buffer[56] = msb >> 24;
|
||||
hd->buffer[57] = msb >> 16;
|
||||
hd->buffer[58] = msb >> 8;
|
||||
hd->buffer[59] = msb ;
|
||||
hd->buffer[60] = lsb >> 24;
|
||||
hd->buffer[61] = lsb >> 16;
|
||||
hd->buffer[62] = lsb >> 8;
|
||||
hd->buffer[63] = lsb ;
|
||||
transform( hd, hd->buffer );
|
||||
hd->buf[56] = msb >> 24;
|
||||
hd->buf[57] = msb >> 16;
|
||||
hd->buf[58] = msb >> 8;
|
||||
hd->buf[59] = msb ;
|
||||
hd->buf[60] = lsb >> 24;
|
||||
hd->buf[61] = lsb >> 16;
|
||||
hd->buf[62] = lsb >> 8;
|
||||
hd->buf[63] = lsb ;
|
||||
transform( hd, hd->buf );
|
||||
|
||||
p = hd->buffer;
|
||||
p = hd->buf;
|
||||
#ifdef BIG_ENDIAN_HOST
|
||||
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
|
||||
#else /* little endian */
|
||||
@ -392,8 +344,6 @@ sha1_final(SHA1HANDLE hd)
|
||||
X(4);
|
||||
#undef X
|
||||
|
||||
initialize( hd ); /* prepare for next cycle */
|
||||
return hd->buffer; /* now contains the digest */
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,26 +25,14 @@
|
||||
typedef struct {
|
||||
u32 h0,h1,h2,h3,h4;
|
||||
u32 nblocks;
|
||||
byte buffer[64];
|
||||
int bufcount;
|
||||
} *SHA1HANDLE;
|
||||
byte buf[64];
|
||||
int count;
|
||||
} SHA1_CONTEXT;
|
||||
|
||||
|
||||
/****************
|
||||
* Process a single character, this character will be buffered to
|
||||
* increase performance.
|
||||
*/
|
||||
#define sha1_putchar(h,c) \
|
||||
do { \
|
||||
if( (h)->bufcount == 64 ) \
|
||||
sha1_write( (h), NULL, 0 ); \
|
||||
(h)->buffer[(h)->bufcount++] = (c) & 0xff; \
|
||||
} while(0)
|
||||
|
||||
SHA1HANDLE sha1_open( int secure );
|
||||
SHA1HANDLE sha1_copy( SHA1HANDLE a );
|
||||
void sha1_close( SHA1HANDLE hd );
|
||||
void sha1_write( SHA1HANDLE hd, byte *inbuf, size_t inlen );
|
||||
byte * sha1_final( SHA1HANDLE hd );
|
||||
void sha1_init( SHA1_CONTEXT *c );
|
||||
void sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen);
|
||||
void sha1_final( SHA1_CONTEXT *hd);
|
||||
#define sha1_read(h) ( (h)->buf )
|
||||
|
||||
#endif /*G10_SHA1_H*/
|
||||
|
103
doc/DETAILS
103
doc/DETAILS
@ -2,6 +2,107 @@
|
||||
|
||||
* For packet version 3 we calculate the keyids this way:
|
||||
RSA := low 64 bits of n
|
||||
ELGAMAL := low 64 bits of y
|
||||
ELGAMAL := build a v3 pubkey packet (with CTB 0x99) and calculate
|
||||
a rmd160 hash value from it. This is used as the
|
||||
fingerprint and the low 64 bits are the keyid.
|
||||
|
||||
|
||||
|
||||
|
||||
Layout of the TrustDB
|
||||
=====================
|
||||
The TrustDB is build from fixed length records, where the first bytes
|
||||
describes the record type. All numeric values are stored in network
|
||||
byte order. The length of each record is 40 bytes. The first record of
|
||||
the DB is always of type 1 and this is the only record of this type.
|
||||
|
||||
Record type 0:
|
||||
--------------
|
||||
Unused record, can be reused for any purpose.
|
||||
|
||||
Record type 1:
|
||||
--------------
|
||||
Version information for this TrustDB. This is always the first
|
||||
record of the DB and the onyl one with type 1.
|
||||
1 byte value 1
|
||||
3 bytes 'g10' magic value
|
||||
1 byte Version of the TrustDB
|
||||
3 byte reserved
|
||||
1 u32 locked by (pid) 0 = not locked.
|
||||
1 u32 timestamp of trustdb creation
|
||||
1 u32 timestamp of last modification
|
||||
1 u32 timestamp of last validation
|
||||
(Used to keep track of the time, when this TrustDB was checked
|
||||
against the pubring)
|
||||
1 u32 Local-Id-Counter. Used to keep track of Local-IDs.
|
||||
32 bits are enough numbers for all practial purposes; if this
|
||||
counter rolls over (due to deleted keyblock,an d new ones),
|
||||
the software should reassign new Local-Ids to the whole
|
||||
database (not expected to ever occur).
|
||||
1 byte marginals needed
|
||||
1 byte completes needed
|
||||
1 byte max. cert depth
|
||||
If any of this 3 values are changed, all cache records
|
||||
muts be invalidated.
|
||||
9 bytes reserved
|
||||
|
||||
Record type 2:
|
||||
--------------
|
||||
Informations about a public key certificate.
|
||||
|
||||
1 byte value 2
|
||||
1 byte reserved
|
||||
1 u32 Local-Id. This is used to bind all records for
|
||||
a given certificate together. It is valid only in this TrustDB
|
||||
and usefull if we have duplicate keyids
|
||||
It is not defined, how an implementaion selects such
|
||||
a Local-Id, but it may use the local-ID counter from
|
||||
record type 1
|
||||
8 bytes keyid (of the primary key)
|
||||
1 byte pubkey algorithm
|
||||
1 byte reserved
|
||||
20 bytes fingerprint of the public key
|
||||
1 byte ownertrust:
|
||||
Bits 2-0:
|
||||
0 = undefined (not yet initialized)
|
||||
1 = unknown owner (could not initialize it)
|
||||
2 = do not trust this owner
|
||||
3 = usually trust this owner
|
||||
4 = always trust this owner
|
||||
5 = ultimately trust this owner. This can only be set if
|
||||
we have control over the secret key too.
|
||||
Bit 3: set if key is revoked; do not use it.
|
||||
Bit 7-4: reserved
|
||||
3 byte reserved
|
||||
|
||||
|
||||
Record type 3: (cache record)
|
||||
--------------
|
||||
Used to bind the trustDB to the concrete instance of keyblock in
|
||||
a pubring. This is used to cache informations.
|
||||
|
||||
1 byte value 3
|
||||
1 byte reserved
|
||||
1 u32 Local-Id.
|
||||
8 bytes keyid of the primary key
|
||||
1 byte cache-is-valid the following stuff is only
|
||||
valid if this is set.
|
||||
1 byte reserved
|
||||
20 bytes rmd160 hash value over the complete keyblock
|
||||
This is used to detect any changes of the keyblock with all
|
||||
CTBs and lengths headers. Calculation is easy if the keyblock
|
||||
is optained from a keyserved: simply create the hash from all
|
||||
received data bytes.
|
||||
|
||||
1 byte number of untrusted signatures.
|
||||
1 byte number of marginal trusted signatures.
|
||||
1 byte number of fully trusted signatures.
|
||||
(255 is stored for all values greater than 254)
|
||||
1 byte Trustlevel
|
||||
0 = undefined (not calculated)
|
||||
1 = unknown
|
||||
2 = not trusted
|
||||
3 = marginally trusted
|
||||
4 = fully trusted
|
||||
5 = ultimately trusted (have secret key too).
|
||||
|
||||
|
@ -31,6 +31,7 @@ g10_SOURCES = g10.c \
|
||||
openfile.c \
|
||||
keyid.c \
|
||||
trustdb.c \
|
||||
trustdb.h \
|
||||
packet.h \
|
||||
parse-packet.c \
|
||||
passphrase.c \
|
||||
|
@ -69,6 +69,7 @@ g10_SOURCES = g10.c \
|
||||
openfile.c \
|
||||
keyid.c \
|
||||
trustdb.c \
|
||||
trustdb.h \
|
||||
packet.h \
|
||||
parse-packet.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
|
||||
*/
|
||||
void
|
||||
hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc )
|
||||
hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
|
||||
{
|
||||
PACKET pkt;
|
||||
int rc = 0;
|
||||
@ -210,7 +210,7 @@ hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc )
|
||||
if( (rc = build_packet( a, &pkt )) )
|
||||
log_fatal("build public_cert for hashing failed: %s\n", g10_errstr(rc));
|
||||
while( (c=iobuf_get(a)) != -1 )
|
||||
md_putchar( md, c );
|
||||
md_putc( md, c );
|
||||
|
||||
iobuf_cancel(a);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
|
||||
|
||||
|
||||
void
|
||||
g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md )
|
||||
g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md )
|
||||
{
|
||||
ELG_secret_key skey;
|
||||
MPI frame;
|
||||
@ -74,9 +74,10 @@ g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md )
|
||||
|
||||
assert( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL );
|
||||
|
||||
dp = md_final( md );
|
||||
md_final( md );
|
||||
dp = md_read( md, 0 );
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->d.elg.digest_algo = md->algo;
|
||||
sig->d.elg.digest_algo = md_get_algo(md);
|
||||
sig->d.elg.digest_start[0] = dp[0];
|
||||
sig->d.elg.digest_start[1] = dp[1];
|
||||
sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) );
|
||||
|
@ -23,9 +23,7 @@
|
||||
#include "cipher.h"
|
||||
|
||||
typedef struct {
|
||||
MD_HANDLE *md; /* catch all */
|
||||
MD5HANDLE md5; /* if !NULL create md5 */
|
||||
RMDHANDLE rmd160; /* if !NULL create rmd160 */
|
||||
MD_HANDLE md; /* catch all */
|
||||
size_t maxbuf_size;
|
||||
} md_filter_context_t;
|
||||
|
||||
|
@ -68,8 +68,7 @@ free_public_cert( PKT_public_cert *cert )
|
||||
mpi_free( cert->d.rsa.rsa_n );
|
||||
mpi_free( cert->d.rsa.rsa_e );
|
||||
}
|
||||
md5_close( cert->mfx.md5 );
|
||||
rmd160_close( cert->mfx.rmd160 );
|
||||
md_close( cert->mfx.md );
|
||||
m_free(cert);
|
||||
}
|
||||
|
||||
@ -88,8 +87,7 @@ copy_public_cert( PKT_public_cert *d, PKT_public_cert *s )
|
||||
d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n );
|
||||
d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e );
|
||||
}
|
||||
d->mfx.md5 = NULL;
|
||||
d->mfx.rmd160 =NULL;
|
||||
d->mfx.md = NULL;
|
||||
return d;
|
||||
}
|
||||
|
||||
|
37
g10/g10.c
37
g10/g10.c
@ -34,6 +34,7 @@
|
||||
#include "mpi.h"
|
||||
#include "cipher.h"
|
||||
#include "filter.h"
|
||||
#include "trustdb.h"
|
||||
|
||||
enum cmd_values { aNull = 0,
|
||||
aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
|
||||
@ -392,6 +393,13 @@ main( int argc, char **argv )
|
||||
}
|
||||
}
|
||||
|
||||
if( cmd != aPrimegen && cmd != aPrintMDs ) {
|
||||
rc = check_trustdb(0);
|
||||
if( rc )
|
||||
log_error("failed to initialize the TrustDB: %s\n", g10_errstr(rc));
|
||||
}
|
||||
|
||||
|
||||
switch( cmd ) {
|
||||
case aStore: /* only store the file */
|
||||
if( argc > 1 )
|
||||
@ -582,9 +590,7 @@ print_mds( const char *fname )
|
||||
FILE *fp;
|
||||
char buf[1024];
|
||||
size_t n;
|
||||
MD5HANDLE md5;
|
||||
RMDHANDLE rmd160;
|
||||
SHA1HANDLE sha1;
|
||||
MD_HANDLE md;
|
||||
|
||||
if( !fname ) {
|
||||
fp = stdin;
|
||||
@ -597,31 +603,26 @@ print_mds( const char *fname )
|
||||
return;
|
||||
}
|
||||
|
||||
md5 = md5_open(0);
|
||||
rmd160 = rmd160_open(0);
|
||||
sha1 = sha1_open(0);
|
||||
md = md_open( DIGEST_ALGO_MD5, 0 );
|
||||
md_enable( md, DIGEST_ALGO_RMD160 );
|
||||
md_enable( md, DIGEST_ALGO_SHA1 );
|
||||
|
||||
while( (n=fread( buf, 1, DIM(buf), fp )) ) {
|
||||
md5_write( md5, buf, n );
|
||||
rmd160_write( rmd160, buf, n );
|
||||
sha1_write( sha1, buf, n );
|
||||
}
|
||||
while( (n=fread( buf, 1, DIM(buf), fp )) )
|
||||
md_write( md, buf, n );
|
||||
if( ferror(fp) )
|
||||
log_error("%s: %s\n", fname, strerror(errno) );
|
||||
else {
|
||||
byte *p;
|
||||
|
||||
md5_final(md5);
|
||||
printf( "%s: MD5 =", fname ); print_hex(md5_read(md5), 16 );
|
||||
printf("\n%s: RMD160 =", fname ); print_hex(rmd160_final(rmd160), 20 );
|
||||
printf("\n%s: SHA1 =", fname ); print_hex(sha1_final(sha1), 20 );
|
||||
md_final(md);
|
||||
printf( "%s: MD5 =", fname ); print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
|
||||
printf("\n%s: RMD160 =", fname ); print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
|
||||
printf("\n%s: SHA1 =", fname ); print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
md5_close(md5);
|
||||
rmd160_close(rmd160);
|
||||
sha1_close(sha1);
|
||||
md_close(md);
|
||||
|
||||
if( fp != stdin )
|
||||
fclose(fp);
|
||||
|
10
g10/keygen.c
10
g10/keygen.c
@ -22,6 +22,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
@ -408,7 +409,7 @@ generate_keypair()
|
||||
tty_printf( "\n"
|
||||
"You need a User-ID to identify your key; the software constructs the user id\n"
|
||||
"from Real Name, Comment and Email Address in this form:\n"
|
||||
" \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n" );
|
||||
" \"Heinrich Heine (Der Dichter) <heinrichh@uni-duesseldorf.de>\"\n\n" );
|
||||
uid = NULL;
|
||||
aname=acomment=amail=NULL;
|
||||
for(;;) {
|
||||
@ -422,6 +423,8 @@ generate_keypair()
|
||||
tty_kill_prompt();
|
||||
if( strpbrk( aname, "<([])>" ) )
|
||||
tty_printf("Invalid character in name\n");
|
||||
else if( isdigit(*aname) )
|
||||
tty_printf("Name may not start with a digit\n");
|
||||
else if( strlen(aname) < 5 )
|
||||
tty_printf("Name must be at least 5 characters long\n");
|
||||
else
|
||||
@ -464,12 +467,15 @@ generate_keypair()
|
||||
}
|
||||
|
||||
m_free(uid);
|
||||
uid = p = m_alloc(strlen(aname)+strlen(amail)+strlen(acomment)+10);
|
||||
uid = p = m_alloc(strlen(aname)+strlen(amail)+strlen(acomment)+12+10);
|
||||
p = stpcpy(p, aname );
|
||||
if( *acomment )
|
||||
p = stpcpy(stpcpy(stpcpy(p," ("), acomment),")");
|
||||
if( *amail )
|
||||
p = stpcpy(stpcpy(stpcpy(p," <"), amail),">");
|
||||
#ifndef HAVE_DEV_RANDOM
|
||||
strcpy(p, " (INSECURE!)" );
|
||||
#endif
|
||||
|
||||
tty_printf("You selected this USER-ID:\n \"%s\"\n\n", uid);
|
||||
for(;;) {
|
||||
|
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
|
||||
* calculates a fingerprint like V4, but with rmd160
|
||||
* and a version byte of 3. Returns an rmd160 handle, caller must
|
||||
* do rmd160_final()
|
||||
* and a version byte of 3. Returns an md handle, caller must
|
||||
* do md_close()
|
||||
*/
|
||||
|
||||
static RMDHANDLE
|
||||
static MD_HANDLE
|
||||
v3_elg_fingerprint_md( PKT_public_cert *pkc )
|
||||
{
|
||||
RMDHANDLE md;
|
||||
MD_HANDLE md;
|
||||
byte *buf1, *buf2, *buf3;
|
||||
byte *p1, *p2, *p3;
|
||||
unsigned n1, n2, n3;
|
||||
@ -73,35 +73,36 @@ v3_elg_fingerprint_md( PKT_public_cert *pkc )
|
||||
|
||||
/* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */
|
||||
n = 14 + n1 + n2 + n3;
|
||||
md = rmd160_open(0);
|
||||
md = md_open( DIGEST_ALGO_RMD160, 0);
|
||||
|
||||
rmd160_putchar( md, 0x99 ); /* ctb */
|
||||
rmd160_putchar( md, n >> 8 ); /* 2 byte length header */
|
||||
rmd160_putchar( md, n );
|
||||
rmd160_putchar( md, 3 ); /* version */
|
||||
md_putc( md, 0x99 ); /* ctb */
|
||||
md_putc( md, n >> 8 ); /* 2 byte length header */
|
||||
md_putc( md, n );
|
||||
md_putc( md, 3 ); /* version */
|
||||
{ u32 a = pkc->timestamp;
|
||||
rmd160_putchar( md, a >> 24 );
|
||||
rmd160_putchar( md, a >> 16 );
|
||||
rmd160_putchar( md, a >> 8 );
|
||||
rmd160_putchar( md, a );
|
||||
md_putc( md, a >> 24 );
|
||||
md_putc( md, a >> 16 );
|
||||
md_putc( md, a >> 8 );
|
||||
md_putc( md, a );
|
||||
}
|
||||
{ u16 a = pkc->valid_days;
|
||||
rmd160_putchar( md, a >> 8 );
|
||||
rmd160_putchar( md, a );
|
||||
md_putc( md, a >> 8 );
|
||||
md_putc( md, a );
|
||||
}
|
||||
rmd160_putchar( md, pkc->pubkey_algo );
|
||||
rmd160_putchar( md, n1>>8); rmd160_putchar( md, n1 ); rmd160_write( md, p1, n1 );
|
||||
rmd160_putchar( md, n2>>8); rmd160_putchar( md, n2 ); rmd160_write( md, p2, n2 );
|
||||
rmd160_putchar( md, n3>>8); rmd160_putchar( md, n3 ); rmd160_write( md, p3, n3 );
|
||||
md_putc( md, pkc->pubkey_algo );
|
||||
md_putc( md, n1>>8); md_putc( md, n1 ); md_write( md, p1, n1 );
|
||||
md_putc( md, n2>>8); md_putc( md, n2 ); md_write( md, p2, n2 );
|
||||
md_putc( md, n3>>8); md_putc( md, n3 ); md_write( md, p3, n3 );
|
||||
m_free(buf1);
|
||||
m_free(buf2);
|
||||
m_free(buf3);
|
||||
md_final( md );
|
||||
|
||||
return md;
|
||||
}
|
||||
|
||||
|
||||
static RMDHANDLE
|
||||
static MD_HANDLE
|
||||
v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
|
||||
{
|
||||
PKT_public_cert pkc;
|
||||
@ -133,13 +134,13 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
|
||||
|
||||
if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
const byte *dp;
|
||||
RMDHANDLE md;
|
||||
MD_HANDLE md;
|
||||
md = v3_elg_fingerprint_md_skc(skc);
|
||||
dp = rmd160_final( md );
|
||||
dp = md_read( md, DIGEST_ALGO_RMD160 );
|
||||
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||
lowbits = keyid[1];
|
||||
rmd160_close(md);
|
||||
md_close(md);
|
||||
}
|
||||
else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid );
|
||||
@ -166,13 +167,13 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
|
||||
|
||||
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
const byte *dp;
|
||||
RMDHANDLE md;
|
||||
MD_HANDLE md;
|
||||
md = v3_elg_fingerprint_md(pkc);
|
||||
dp = rmd160_final( md );
|
||||
dp = md_read( md, DIGEST_ALGO_RMD160 );
|
||||
keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||
keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||
lowbits = keyid[1];
|
||||
rmd160_close(md);
|
||||
md_close(md);
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
|
||||
@ -310,33 +311,33 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
|
||||
unsigned n;
|
||||
|
||||
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
RMDHANDLE md;
|
||||
MD_HANDLE md;
|
||||
md = v3_elg_fingerprint_md(pkc);
|
||||
dp = rmd160_final( md );
|
||||
dp = md_read( md, DIGEST_ALGO_RMD160 );
|
||||
array = m_alloc( 20 );
|
||||
len = 20;
|
||||
memcpy(array, dp, 20 );
|
||||
rmd160_close(md);
|
||||
md_close(md);
|
||||
}
|
||||
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
|
||||
MD5HANDLE md;
|
||||
MD_HANDLE md;
|
||||
|
||||
md = md5_open(0);
|
||||
md = md_open( DIGEST_ALGO_MD5, 0);
|
||||
p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL );
|
||||
for( ; !*p && n; p++, n-- )
|
||||
;
|
||||
md5_write( md, p, n );
|
||||
md_write( md, p, n );
|
||||
m_free(buf);
|
||||
p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL );
|
||||
for( ; !*p && n; p++, n-- )
|
||||
;
|
||||
md5_write( md, p, n );
|
||||
md_write( md, p, n );
|
||||
m_free(buf);
|
||||
md5_final(md);
|
||||
md_final(md);
|
||||
array = m_alloc( 16 );
|
||||
len = 16;
|
||||
memcpy(array, md5_read(md), 16 );
|
||||
md5_close(md);
|
||||
memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
|
||||
md_close(md);
|
||||
}
|
||||
else {
|
||||
array = m_alloc(1);
|
||||
|
@ -64,18 +64,18 @@ MPI encode_session_key( DEK *dek, unsigned nbits );
|
||||
MPI encode_sha1_value( byte *md, unsigned len, unsigned nbits );
|
||||
MPI encode_rmd160_value( byte *md, unsigned len, unsigned nbits );
|
||||
MPI encode_md5_value( byte *md, unsigned len, unsigned nbits );
|
||||
MPI encode_md_value( MD_HANDLE *md, unsigned nbits );
|
||||
MPI encode_md_value( MD_HANDLE md, unsigned nbits );
|
||||
|
||||
/*-- comment.c --*/
|
||||
KBNODE make_comment_node( const char *s );
|
||||
|
||||
/*-- elg.c --*/
|
||||
void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
|
||||
void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md );
|
||||
void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md );
|
||||
|
||||
/*-- rsa.c --*/
|
||||
void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek );
|
||||
void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md );
|
||||
void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md );
|
||||
|
||||
|
||||
#endif /*G10_MAIN_H*/
|
||||
|
@ -268,7 +268,7 @@ proc_plaintext( CTX c, PACKET *pkt )
|
||||
* And look at the sigclass to check wether we should use the
|
||||
* textmode filter (sigclass 0x01)
|
||||
*/
|
||||
c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
|
||||
c->mfx.md = md_open( DIGEST_ALGO_RMD160, 0);
|
||||
rc = handle_plaintext( pt, &c->mfx );
|
||||
if( rc )
|
||||
log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
|
||||
@ -302,7 +302,7 @@ static int
|
||||
do_check_sig( CTX c, KBNODE node )
|
||||
{
|
||||
PKT_signature *sig;
|
||||
MD_HANDLE *md;
|
||||
MD_HANDLE md;
|
||||
int algo, rc;
|
||||
|
||||
assert( node->pkt->pkttype == PKT_SIGNATURE );
|
||||
@ -314,7 +314,7 @@ do_check_sig( CTX c, KBNODE node )
|
||||
algo = sig->d.rsa.digest_algo;
|
||||
else
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
if( (rc=md_okay(algo)) )
|
||||
if( (rc=check_digest_algo(algo)) )
|
||||
return rc;
|
||||
|
||||
if( sig->sig_class == 0x00 ) {
|
||||
@ -328,10 +328,6 @@ do_check_sig( CTX c, KBNODE node )
|
||||
|
||||
if( c->cert->pkt->pkt.public_cert->mfx.md )
|
||||
md = md_copy( c->cert->pkt->pkt.public_cert->mfx.md );
|
||||
else if( algo == DIGEST_ALGO_RMD160 )
|
||||
md = rmd160_copy2md( c->cert->pkt->pkt.public_cert->mfx.rmd160 );
|
||||
else if( algo == DIGEST_ALGO_MD5 )
|
||||
md = md5_copy2md( c->cert->pkt->pkt.public_cert->mfx.md5 );
|
||||
else
|
||||
log_bug(NULL);
|
||||
md_write( md, n1->pkt->pkt.user_id->name, n1->pkt->pkt.user_id->len);
|
||||
|
@ -53,12 +53,8 @@ md_filter( void *opaque, int control,
|
||||
buf[i] = c;
|
||||
}
|
||||
|
||||
if( i ) {
|
||||
if( mfx->md5 )
|
||||
md5_write(mfx->md5, buf, i );
|
||||
if( mfx->rmd160 )
|
||||
rmd160_write(mfx->rmd160, buf, i );
|
||||
}
|
||||
if( i )
|
||||
md_write(mfx->md, buf, i );
|
||||
else
|
||||
rc = -1; /* eof */
|
||||
*ret_len = i;
|
||||
@ -72,12 +68,8 @@ md_filter( void *opaque, int control,
|
||||
void
|
||||
free_md_filter_context( md_filter_context_t *mfx )
|
||||
{
|
||||
if( mfx->md5 )
|
||||
md5_close(mfx->md5);
|
||||
mfx->md5 = NULL;
|
||||
if( mfx->rmd160 )
|
||||
rmd160_close(mfx->rmd160);
|
||||
mfx->rmd160 = NULL;
|
||||
md_close(mfx->md);
|
||||
mfx->md = NULL;
|
||||
mfx->maxbuf_size = 0;
|
||||
}
|
||||
|
||||
|
@ -220,7 +220,7 @@ int parse_packet( IOBUF inp, PACKET *ret_pkt);
|
||||
/*-- build-packet.c --*/
|
||||
int build_packet( IOBUF inp, PACKET *pkt );
|
||||
u32 calc_packet_length( PACKET *pkt );
|
||||
void hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc );
|
||||
void hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc );
|
||||
|
||||
/*-- free-packet.c --*/
|
||||
void free_pubkey_enc( PKT_pubkey_enc *enc );
|
||||
@ -235,7 +235,7 @@ PKT_secret_cert *copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s );
|
||||
|
||||
|
||||
/*-- sig-check.c --*/
|
||||
int signature_check( PKT_signature *sig, MD_HANDLE *digest );
|
||||
int signature_check( PKT_signature *sig, MD_HANDLE digest );
|
||||
|
||||
/*-- seckey-cert.c --*/
|
||||
int is_secret_key_protected( PKT_secret_cert *cert );
|
||||
|
@ -438,11 +438,11 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
int is_v4=0;
|
||||
|
||||
if( pkttype == PKT_PUBLIC_CERT ) {
|
||||
pkt->pkt.public_cert->mfx.md5 = md5_open(0);
|
||||
pkt->pkt.public_cert->mfx.rmd160 = rmd160_open(0);
|
||||
pkt->pkt.public_cert->mfx.md = md_open(DIGEST_ALGO_MD5, 0);
|
||||
md_enable(pkt->pkt.public_cert->mfx.md, DIGEST_ALGO_RMD160);
|
||||
md_enable(pkt->pkt.public_cert->mfx.md, DIGEST_ALGO_SHA1);
|
||||
pkt->pkt.public_cert->mfx.maxbuf_size = 1;
|
||||
md5_write(pkt->pkt.public_cert->mfx.md5, hdr, hdrlen);
|
||||
rmd160_write(pkt->pkt.public_cert->mfx.rmd160, hdr, hdrlen);
|
||||
md_write(pkt->pkt.public_cert->mfx.md, hdr, hdrlen);
|
||||
iobuf_push_filter( inp, md_filter, &pkt->pkt.public_cert->mfx );
|
||||
}
|
||||
|
||||
|
@ -143,13 +143,14 @@ hash_passphrase( DEK *dek, char *pw )
|
||||
|
||||
dek->keylen = 0;
|
||||
if( dek->algo == CIPHER_ALGO_BLOWFISH ) {
|
||||
RMDHANDLE rmd;
|
||||
MD_HANDLE md;
|
||||
|
||||
rmd = rmd160_open(1);
|
||||
rmd160_write( rmd, pw, strlen(pw) );
|
||||
md = md_open(DIGEST_ALGO_RMD160, 1);
|
||||
md_write( md, pw, strlen(pw) );
|
||||
md_final( md );
|
||||
dek->keylen = 20;
|
||||
memcpy( dek->key, rmd160_final(rmd), dek->keylen );
|
||||
rmd160_close(rmd);
|
||||
memcpy( dek->key, md_read(md,0), dek->keylen );
|
||||
md_close(md);
|
||||
}
|
||||
else
|
||||
rc = G10ERR_UNSUPPORTED;
|
||||
|
@ -31,6 +31,22 @@
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "trustdb.h"
|
||||
|
||||
|
||||
/****************
|
||||
* Check wether we can trust this pkc which has a trustlevel of TRUSTLEVEL
|
||||
* Returns: true if we trust.
|
||||
*/
|
||||
static int
|
||||
do_we_trust( PKT_public_cert *pkc, int trustlevel )
|
||||
{
|
||||
/* Eventuell fragen falls der trustlevel nicht ausreichend ist */
|
||||
|
||||
|
||||
return 1; /* yes */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
@ -64,13 +80,27 @@ build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list )
|
||||
free_public_cert( pkc ); pkc = NULL;
|
||||
log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) );
|
||||
}
|
||||
else if( is_valid_pubkey_algo(pkc->pubkey_algo) ) {
|
||||
PKC_LIST r;
|
||||
r = m_alloc( sizeof *r );
|
||||
r->pkc = pkc; pkc = NULL;
|
||||
r->next = pkc_list;
|
||||
r->mark = 0;
|
||||
pkc_list = r;
|
||||
else if( !(rc=check_pubkey_algo(pkc->pubkey_algo)) ) {
|
||||
int trustlevel;
|
||||
|
||||
rc = check_pkc_trust( pkc, &trustlevel );
|
||||
if( rc ) {
|
||||
free_public_cert( pkc ); pkc = NULL;
|
||||
log_error("error checking pkc of '%s': %s\n",
|
||||
remusr->d, g10_errstr(rc) );
|
||||
}
|
||||
else if( do_we_trust( pkc, trustlevel ) ) {
|
||||
PKC_LIST r;
|
||||
|
||||
r = m_alloc( sizeof *r );
|
||||
r->pkc = pkc; pkc = NULL;
|
||||
r->next = pkc_list;
|
||||
r->mark = 0;
|
||||
pkc_list = r;
|
||||
}
|
||||
else { /* we don't trust this pkc */
|
||||
free_public_cert( pkc ); pkc = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
free_public_cert( pkc ); pkc = NULL;
|
||||
|
@ -79,11 +79,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
|
||||
goto leave;
|
||||
}
|
||||
if( mfx->md )
|
||||
md_putchar(mfx->md, c );
|
||||
if( mfx->rmd160 )
|
||||
rmd160_putchar(mfx->rmd160, c );
|
||||
if( mfx->md5 )
|
||||
md5_putchar(mfx->md5, c );
|
||||
md_putc(mfx->md, c );
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
log_error("Error writing to '%s': %s\n", fname, strerror(errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
@ -93,10 +89,8 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
|
||||
}
|
||||
else {
|
||||
while( (c = iobuf_get(pt->buf)) != -1 ) {
|
||||
if( mfx->rmd160 )
|
||||
rmd160_putchar(mfx->rmd160, c );
|
||||
if( mfx->md5 )
|
||||
md5_putchar(mfx->md5, c );
|
||||
if( mfx->md )
|
||||
md_putc(mfx->md, c );
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
log_error("Error writing to '%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
@ -162,11 +156,7 @@ ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname )
|
||||
|
||||
while( (c = iobuf_get(fp)) != -1 ) {
|
||||
if( mfx->md )
|
||||
md_putchar(mfx->md, c );
|
||||
if( mfx->rmd160 )
|
||||
rmd160_putchar(mfx->rmd160, c );
|
||||
if( mfx->md5 )
|
||||
md5_putchar(mfx->md5, c );
|
||||
md_putc(mfx->md, c );
|
||||
}
|
||||
iobuf_close(fp);
|
||||
|
||||
|
@ -64,7 +64,7 @@ g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek )
|
||||
|
||||
|
||||
void
|
||||
g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md )
|
||||
g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md )
|
||||
{
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
RSA_secret_key skey;
|
||||
@ -72,10 +72,11 @@ g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE *md )
|
||||
|
||||
assert( sig->pubkey_algo == PUBKEY_ALGO_RSA );
|
||||
|
||||
dp = md_final( md );
|
||||
md_final( md );
|
||||
dp = md_read( md, 0 );
|
||||
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->d.rsa.digest_algo = md->algo;
|
||||
sig->d.rsa.digest_algo = md_get_algo( md );
|
||||
sig->d.rsa.digest_start[0] = dp[0];
|
||||
sig->d.rsa.digest_start[1] = dp[1];
|
||||
sig->d.rsa.rsa_integer =
|
||||
|
19
g10/seskey.c
19
g10/seskey.c
@ -226,16 +226,17 @@ encode_md5_value( byte *md, unsigned len, unsigned nbits )
|
||||
}
|
||||
|
||||
MPI
|
||||
encode_md_value( MD_HANDLE *md, unsigned nbits )
|
||||
encode_md_value( MD_HANDLE md, unsigned nbits )
|
||||
{
|
||||
byte *p = md_final( md );
|
||||
if( md->algo == DIGEST_ALGO_MD5 )
|
||||
return encode_md5_value( p, 16, nbits );
|
||||
else if( md->algo == DIGEST_ALGO_RMD160 )
|
||||
return encode_rmd160_value( p, 20, nbits );
|
||||
else if( md->algo == DIGEST_ALGO_SHA1 )
|
||||
return encode_sha1_value( p, 20, nbits );
|
||||
else
|
||||
switch( md_get_algo( md ) ) {
|
||||
case DIGEST_ALGO_MD5:
|
||||
return encode_md5_value( md_read(md, DIGEST_ALGO_MD5), 16, nbits );
|
||||
case DIGEST_ALGO_RMD160:
|
||||
return encode_rmd160_value( md_read(md, DIGEST_ALGO_RMD160), 20, nbits );
|
||||
case DIGEST_ALGO_SHA1:
|
||||
return encode_sha1_value( md_read(md, DIGEST_ALGO_SHA1), 20, nbits );
|
||||
default:
|
||||
log_bug(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
* is able to append some data, before getting the digest.
|
||||
*/
|
||||
int
|
||||
signature_check( PKT_signature *sig, MD_HANDLE *digest )
|
||||
signature_check( PKT_signature *sig, MD_HANDLE digest )
|
||||
{
|
||||
PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
|
||||
MPI result = NULL;
|
||||
@ -54,16 +54,17 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
|
||||
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
ELG_public_key pkey;
|
||||
|
||||
if( (rc=md_okay(sig->d.elg.digest_algo)) )
|
||||
if( (rc=check_digest_algo(sig->d.elg.digest_algo)) )
|
||||
goto leave;
|
||||
/* complete the digest */
|
||||
md_putchar( digest, sig->sig_class );
|
||||
md_putc( digest, sig->sig_class );
|
||||
{ u32 a = sig->timestamp;
|
||||
md_putchar( digest, (a >> 24) & 0xff );
|
||||
md_putchar( digest, (a >> 16) & 0xff );
|
||||
md_putchar( digest, (a >> 8) & 0xff );
|
||||
md_putchar( digest, a & 0xff );
|
||||
md_putc( digest, (a >> 24) & 0xff );
|
||||
md_putc( digest, (a >> 16) & 0xff );
|
||||
md_putc( digest, (a >> 8) & 0xff );
|
||||
md_putc( digest, a & 0xff );
|
||||
}
|
||||
md_final( digest );
|
||||
result = encode_md_value( digest, mpi_get_nbits(pkc->d.elg.p));
|
||||
pkey.p = pkc->d.elg.p;
|
||||
pkey.g = pkc->d.elg.g;
|
||||
@ -134,14 +135,15 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
|
||||
}
|
||||
|
||||
/* complete the digest */
|
||||
md_putchar( digest, sig->sig_class );
|
||||
md_putc( digest, sig->sig_class );
|
||||
{ u32 a = sig->timestamp;
|
||||
md_putchar( digest, (a >> 24) & 0xff );
|
||||
md_putchar( digest, (a >> 16) & 0xff );
|
||||
md_putchar( digest, (a >> 8) & 0xff );
|
||||
md_putchar( digest, a & 0xff );
|
||||
md_putc( digest, (a >> 24) & 0xff );
|
||||
md_putc( digest, (a >> 16) & 0xff );
|
||||
md_putc( digest, (a >> 8) & 0xff );
|
||||
md_putc( digest, a & 0xff );
|
||||
}
|
||||
dp = md_final( digest );
|
||||
md_final( digest );
|
||||
dp = md_read( digest, 0 );
|
||||
for(i=19; i >= 0; i--, dp++ )
|
||||
if( mpi_getbyte( result, i ) != *dp ) {
|
||||
rc = G10ERR_BAD_SIGN;
|
||||
@ -177,14 +179,15 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
|
||||
}
|
||||
|
||||
/* complete the digest */
|
||||
md_putchar( digest, sig->sig_class );
|
||||
md_putc( digest, sig->sig_class );
|
||||
{ u32 a = sig->timestamp;
|
||||
md_putchar( digest, (a >> 24) & 0xff );
|
||||
md_putchar( digest, (a >> 16) & 0xff );
|
||||
md_putchar( digest, (a >> 8) & 0xff );
|
||||
md_putchar( digest, a & 0xff );
|
||||
md_putc( digest, (a >> 24) & 0xff );
|
||||
md_putc( digest, (a >> 16) & 0xff );
|
||||
md_putc( digest, (a >> 8) & 0xff );
|
||||
md_putc( digest, a & 0xff );
|
||||
}
|
||||
dp = md_final( digest );
|
||||
md_final( digest );
|
||||
dp = md_read( digest, 0 );
|
||||
for(i=15; i >= 0; i--, dp++ )
|
||||
if( mpi_getbyte( result, i ) != *dp ) {
|
||||
rc = G10ERR_BAD_SIGN;
|
||||
@ -220,7 +223,7 @@ int
|
||||
check_key_signature( KBNODE root, KBNODE node )
|
||||
{
|
||||
KBNODE unode;
|
||||
MD_HANDLE *md;
|
||||
MD_HANDLE md;
|
||||
PKT_public_cert *pkc;
|
||||
PKT_signature *sig;
|
||||
int algo;
|
||||
@ -239,7 +242,7 @@ check_key_signature( KBNODE root, KBNODE node )
|
||||
algo = sig->d.rsa.digest_algo;
|
||||
else
|
||||
return G10ERR_PUBKEY_ALGO;
|
||||
if( (rc=md_okay(algo)) )
|
||||
if( (rc=check_digest_algo(algo)) )
|
||||
return rc;
|
||||
|
||||
unode = find_kbparent( root, node );
|
||||
|
39
g10/sign.c
39
g10/sign.c
@ -41,7 +41,7 @@
|
||||
|
||||
|
||||
static int
|
||||
complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE *md )
|
||||
complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE md )
|
||||
{
|
||||
int rc=0;
|
||||
|
||||
@ -119,7 +119,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
|
||||
/* prepare to calculate the MD over the input */
|
||||
if( opt.textmode && opt.armor )
|
||||
iobuf_push_filter( inp, text_filter, &tfx );
|
||||
mfx.rmd160 = rmd160_open(0);
|
||||
mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
|
||||
iobuf_push_filter( inp, md_filter, &mfx );
|
||||
|
||||
if( opt.armor )
|
||||
@ -194,7 +194,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
|
||||
for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) {
|
||||
PKT_secret_cert *skc;
|
||||
PKT_signature *sig;
|
||||
RMDHANDLE rmd;
|
||||
MD_HANDLE md;
|
||||
byte *dp;
|
||||
|
||||
skc = skc_rover->skc;
|
||||
@ -205,15 +205,16 @@ sign_file( const char *filename, int detached, STRLIST locusr,
|
||||
sig->timestamp = make_timestamp();
|
||||
sig->sig_class = opt.textmode? 0x01 : 0x00;
|
||||
|
||||
rmd = rmd160_copy( mfx.rmd160 );
|
||||
rmd160_putchar( rmd, sig->sig_class );
|
||||
md = md_copy( mfx.md );
|
||||
md_putc( md, sig->sig_class );
|
||||
{ u32 a = sig->timestamp;
|
||||
rmd160_putchar( rmd, (a >> 24) & 0xff );
|
||||
rmd160_putchar( rmd, (a >> 16) & 0xff );
|
||||
rmd160_putchar( rmd, (a >> 8) & 0xff );
|
||||
rmd160_putchar( rmd, a & 0xff );
|
||||
md_putc( md, (a >> 24) & 0xff );
|
||||
md_putc( md, (a >> 16) & 0xff );
|
||||
md_putc( md, (a >> 8) & 0xff );
|
||||
md_putc( md, a & 0xff );
|
||||
}
|
||||
dp = rmd160_final( rmd );
|
||||
md_final( md );
|
||||
dp = md_read( md, DIGEST_ALGO_RMD160 );
|
||||
|
||||
if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
|
||||
ELG_secret_key skey;
|
||||
@ -268,7 +269,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
|
||||
else
|
||||
log_bug(NULL);
|
||||
|
||||
rmd160_close( rmd );
|
||||
md_close( md );
|
||||
|
||||
/* and write it */
|
||||
init_packet(&pkt);
|
||||
@ -289,7 +290,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
|
||||
else
|
||||
iobuf_close(out);
|
||||
iobuf_close(inp);
|
||||
rmd160_close( mfx.rmd160 );
|
||||
md_close( mfx.md );
|
||||
release_skc_list( skc_list );
|
||||
release_pkc_list( pkc_list );
|
||||
return rc;
|
||||
@ -621,7 +622,7 @@ sign_key( const char *username, STRLIST locusr )
|
||||
leave:
|
||||
release_kbnode( keyblock );
|
||||
release_skc_list( skc_list );
|
||||
rmd160_close( mfx.rmd160 );
|
||||
md_close( mfx.md );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -830,7 +831,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
|
||||
{
|
||||
PKT_signature *sig;
|
||||
int rc=0;
|
||||
MD_HANDLE *md;
|
||||
MD_HANDLE md;
|
||||
|
||||
assert( sigclass >= 0x10 && sigclass <= 0x13 );
|
||||
md = md_open( digest_algo, 0 );
|
||||
@ -843,12 +844,12 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
|
||||
sig->timestamp = make_timestamp();
|
||||
sig->sig_class = sigclass;
|
||||
|
||||
md_putchar( md, sig->sig_class );
|
||||
md_putc( md, sig->sig_class );
|
||||
{ u32 a = sig->timestamp;
|
||||
md_putchar( md, (a >> 24) & 0xff );
|
||||
md_putchar( md, (a >> 16) & 0xff );
|
||||
md_putchar( md, (a >> 8) & 0xff );
|
||||
md_putchar( md, a & 0xff );
|
||||
md_putc( md, (a >> 24) & 0xff );
|
||||
md_putc( md, (a >> 16) & 0xff );
|
||||
md_putc( md, (a >> 8) & 0xff );
|
||||
md_putc( md, a & 0xff );
|
||||
}
|
||||
|
||||
rc = complete_sig( sig, skc, md );
|
||||
|
@ -60,7 +60,7 @@ build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock )
|
||||
free_secret_cert( skc ); skc = NULL;
|
||||
log_error("no default secret key: %s\n", g10_errstr(rc) );
|
||||
}
|
||||
else if( is_valid_pubkey_algo(skc->pubkey_algo) ) {
|
||||
else if( !(rc=check_pubkey_algo(skc->pubkey_algo)) ) {
|
||||
SKC_LIST r;
|
||||
r = m_alloc( sizeof *r );
|
||||
r->skc = skc; skc = NULL;
|
||||
@ -82,7 +82,7 @@ build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock )
|
||||
free_secret_cert( skc ); skc = NULL;
|
||||
log_error("skipped '%s': %s\n", locusr->d, g10_errstr(rc) );
|
||||
}
|
||||
else if ( is_valid_pubkey_algo(skc->pubkey_algo) ) {
|
||||
else if( !(rc=check_pubkey_algo(skc->pubkey_algo)) ) {
|
||||
SKC_LIST r;
|
||||
r = m_alloc( sizeof *r );
|
||||
r->skc = skc; skc = NULL;
|
||||
|
210
g10/trustdb.c
210
g10/trustdb.c
@ -22,6 +22,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
@ -30,6 +31,215 @@
|
||||
#include "keydb.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "trustdb.h"
|
||||
#include "options.h"
|
||||
|
||||
|
||||
#define TRUST_RECORD_LEN 40
|
||||
|
||||
struct trust_record {
|
||||
byte rectype;
|
||||
byte reserved;
|
||||
union {
|
||||
byte raw[TRUST_RECORD_LEN-2];
|
||||
struct { /* version record: */
|
||||
byte magic[2];
|
||||
byte version; /* should be 1 */
|
||||
byte reserved[3];
|
||||
u32 locked; /* pid of process which holds a lock */
|
||||
u32 created; /* timestamp of trustdb creation */
|
||||
u32 modified; /* timestamp of last modification */
|
||||
u32 validated; /* timestamp of last validation */
|
||||
u32 local_id_counter;
|
||||
byte marginals_needed;
|
||||
byte completes_needed;
|
||||
byte max_cert_depth;
|
||||
} version;
|
||||
struct { /* public key record */
|
||||
u32 local_id;
|
||||
u32 keyid[2];
|
||||
byte algo;
|
||||
byte reserved;
|
||||
byte fingerprint[20];
|
||||
byte ownertrust;
|
||||
} pubkey;
|
||||
struct { /* cache record */
|
||||
u32 local_id;
|
||||
u32 keyid[2];
|
||||
byte valid;
|
||||
byte reserved;
|
||||
byte blockhash[20];
|
||||
byte n_untrusted;
|
||||
byte n_marginal;
|
||||
byte n_fully;
|
||||
byte trustlevel;
|
||||
} cache;
|
||||
} r;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static char *db_name;
|
||||
|
||||
/**************************************************
|
||||
************** read and write helpers ************
|
||||
**************************************************/
|
||||
|
||||
static void
|
||||
fwrite_8(FILE *fp, byte a)
|
||||
{
|
||||
if( putc( a & 0xff, fp ) == EOF )
|
||||
log_fatal("error writing byte to trustdb: %s\n", strerror(errno) );
|
||||
}
|
||||
|
||||
static void
|
||||
fwrite_16(FILE *fp, u16 a)
|
||||
{
|
||||
putc( (a>>8) & 0x0ff , fp );
|
||||
if( putc( a & 0xff, fp ) == EOF )
|
||||
log_fatal("error writing u16 to trustdb: %s\n", strerror(errno) );
|
||||
}
|
||||
|
||||
static int
|
||||
fwrite_32( FILE*fp, u32 a)
|
||||
{
|
||||
putc( (a>>24) & 0xff, fp );
|
||||
putc( (a>>16) & 0xff, fp );
|
||||
putc( (a>> 8) & 0xff, fp );
|
||||
if( putc( a & 0xff, fp ) == EOF )
|
||||
log_fatal("error writing u32 to trustdb: %s\n", strerror(errno) );
|
||||
}
|
||||
|
||||
static int
|
||||
fwrite_zeros( FILE *fp, size_t n)
|
||||
{
|
||||
while( n-- )
|
||||
if( putc( 0, fp ) == EOF )
|
||||
log_fatal("error writing zeros to trustdb: %s\n", strerror(errno) );
|
||||
}
|
||||
|
||||
|
||||
/**************************************************
|
||||
************** read and write stuff **************
|
||||
**************************************************/
|
||||
|
||||
|
||||
/****************
|
||||
* Create a new trustdb
|
||||
*/
|
||||
static void
|
||||
create_db( const char *fname )
|
||||
{
|
||||
FILE *fp;
|
||||
u32 along;
|
||||
u16 ashort;
|
||||
|
||||
fp =fopen( fname, "w" );
|
||||
if( !fp )
|
||||
log_fatal("can't create %s: %s\n", fname, strerror(errno) );
|
||||
fwrite_8( fp, 1 );
|
||||
fwrite_8( fp, 'g' );
|
||||
fwrite_8( fp, '1' );
|
||||
fwrite_8( fp, '0' );
|
||||
fwrite_8( fp, 1 ); /* version */
|
||||
fwrite_zeros( fp, 3 ); /* reserved */
|
||||
fwrite_32( fp, 0 ); /* not locked */
|
||||
fwrite_32( fp, make_timestamp() ); /* created */
|
||||
fwrite_32( fp, 0 ); /* not yet modified */
|
||||
fwrite_32( fp, 0 ); /* not yet validated*/
|
||||
fwrite_32( fp, 0 ); /* local-id-counter */
|
||||
fwrite_8( fp, 3 ); /* marginals needed */
|
||||
fwrite_8( fp, 1 ); /* completes needed */
|
||||
fwrite_8( fp, 4 ); /* max_cet_depth */
|
||||
fwrite_zeros( fp, 9 ); /* filler */
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************************
|
||||
************* trust logic *******************
|
||||
***********************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*********************************************************
|
||||
**************** API Interface ************************
|
||||
*********************************************************/
|
||||
|
||||
/****************
|
||||
* Perform some checks over the trustdb
|
||||
* level 0: used on initial program startup
|
||||
*/
|
||||
int
|
||||
check_trustdb( int level )
|
||||
{
|
||||
if( !level ) {
|
||||
char *fname = make_filename("~/.g10", "trustDB", NULL );
|
||||
if( access( fname, R_OK ) ) {
|
||||
if( errno != ENOENT ) {
|
||||
log_error("can't access %s: %s\n", fname, strerror(errno) );
|
||||
m_free(fname);
|
||||
return G10ERR_TRUSTDB;
|
||||
}
|
||||
create_db( fname );
|
||||
}
|
||||
m_free(db_name);
|
||||
db_name = fname;
|
||||
|
||||
/* we can verify a signature about our local data (secring and trustdb)
|
||||
* in ~/.g10/ here
|
||||
*/
|
||||
}
|
||||
else
|
||||
log_bug(NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Get the trustlevel for this PKC.
|
||||
* Note: This does not ask any questions
|
||||
* Returns: 0 okay of an errorcode
|
||||
*
|
||||
* It operates this way:
|
||||
* locate the pkc in the trustdb
|
||||
* found:
|
||||
* Do we have a valid cache record for it?
|
||||
* yes: return trustlevel from cache
|
||||
* no: make a cache record
|
||||
* not found:
|
||||
* Return with a trustlevel, saying that we do not have
|
||||
* a trust record for it. The caller may use insert_trust_record()
|
||||
* and then call this function here again.
|
||||
*
|
||||
* Problems: How do we get the complete keyblock to check that the
|
||||
* cache record is actually valid? Think we need a clever
|
||||
* cache in getkey.c to keep track of this stuff. Maybe it
|
||||
* is not necessary to check this if we use a local pubring. Hmmmm.
|
||||
*/
|
||||
int
|
||||
check_pkc_trust( PKT_public_cert *pkc, int *r_trustlevel )
|
||||
{
|
||||
int trustlevel = 0;
|
||||
|
||||
if( opt.verbose )
|
||||
log_info("check_pkc_trust() called.\n");
|
||||
|
||||
*r_trustlevel = trustlevel;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
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
|
||||
|
||||
#include "mpi.h"
|
||||
#include "../cipher/md5.h"
|
||||
#include "../cipher/rmd.h"
|
||||
#include "../cipher/sha1.h"
|
||||
#include "../cipher/md.h"
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
#include "../cipher/rsa.h"
|
||||
#endif
|
||||
@ -67,26 +65,9 @@ typedef struct {
|
||||
byte key[20]; /* this is the largest used keylen */
|
||||
} DEK;
|
||||
|
||||
typedef struct {
|
||||
int algo; /* digest algo */
|
||||
union {
|
||||
MD5HANDLE md5;
|
||||
RMDHANDLE rmd;
|
||||
SHA1HANDLE sha1;
|
||||
} u;
|
||||
int datalen;
|
||||
char data[1];
|
||||
} MD_HANDLE;
|
||||
|
||||
|
||||
int cipher_debug_mode;
|
||||
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
#define is_valid_pubkey_algo(a) ( (a) == PUBKEY_ALGO_ELGAMAL \
|
||||
|| (a) == PUBKEY_ALGO_RSA )
|
||||
#else
|
||||
#define is_valid_pubkey_algo(a) ( (a) == PUBKEY_ALGO_ELGAMAL )
|
||||
#endif
|
||||
|
||||
/*-- misc.c --*/
|
||||
int string_to_cipher_algo( const char *string );
|
||||
@ -96,19 +77,6 @@ int check_cipher_algo( int algo );
|
||||
int check_pubkey_algo( int algo );
|
||||
int check_digest_algo( int algo );
|
||||
|
||||
/*-- md.c --*/
|
||||
int md_okay( int algo );
|
||||
MD_HANDLE *md_open( int algo, int secure );
|
||||
MD_HANDLE *md_copy( MD_HANDLE *a );
|
||||
MD_HANDLE *md_makecontainer( int algo ); /* used for a bad kludge */
|
||||
void md_write( MD_HANDLE *a, byte *inbuf, size_t inlen);
|
||||
void md_putchar( MD_HANDLE *a, int c );
|
||||
byte *md_final(MD_HANDLE *a);
|
||||
void md_close(MD_HANDLE *a);
|
||||
|
||||
MD_HANDLE *md5_copy2md( MD5HANDLE a ); /* (in md5.c) */
|
||||
MD_HANDLE *rmd160_copy2md( RMDHANDLE a ); /* (in rmd160.c) */
|
||||
|
||||
/*-- random.c --*/
|
||||
void randomize_buffer( byte *buffer, size_t length, int level );
|
||||
byte get_random_byte( int level );
|
||||
|
@ -52,5 +52,6 @@
|
||||
#define G10ERR_BAD_MPI 30
|
||||
#define G10ERR_RESOURCE_LIMIT 31
|
||||
#define G10ERR_INV_KEYRING 32
|
||||
#define G10ERR_TRUSTDB 33 /* a problem with the trustdb */
|
||||
|
||||
#endif /*G10_ERRORS_H*/
|
||||
|
@ -39,27 +39,11 @@
|
||||
#define DBG_MPI mpi_debug_mode
|
||||
int mpi_debug_mode;
|
||||
|
||||
#if defined(__i386__)
|
||||
#define BITS_PER_MPI_LIMB 32
|
||||
#define BYTES_PER_MPI_LIMB 4
|
||||
#define BYTES_PER_MPI_LIMB2 8
|
||||
typedef unsigned long int mpi_limb_t;
|
||||
typedef signed long int mpi_limb_signed_t;
|
||||
#elif defined(__hppa__)
|
||||
#define BITS_PER_MPI_LIMB 32
|
||||
#define BYTES_PER_MPI_LIMB 4
|
||||
#define BYTES_PER_MPI_LIMB2 8
|
||||
typedef unsigned long int mpi_limb_t;
|
||||
typedef signed long int mpi_limb_signed_t;
|
||||
#elif defined(__alpha__)
|
||||
#define BITS_PER_MPI_LIMB 64
|
||||
#define BYTES_PER_MPI_LIMB 8
|
||||
#define BYTES_PER_MPI_LIMB2 16
|
||||
typedef unsigned long int mpi_limb_t;
|
||||
typedef signed long int mpi_limb_signed_t;
|
||||
#else
|
||||
#error add definions for this machine here
|
||||
#endif
|
||||
#define BITS_PER_MPI_LIMB (8*SIZEOF_UNSIGNED_LONG)
|
||||
#define BYTES_PER_MPI_LIMB SIZEOF_UNSIGNED_LONG
|
||||
#define BYTES_PER_MPI_LIMB2 (2*SIZEOF_UNSIGNED_LONG)
|
||||
typedef unsigned long int mpi_limb_t;
|
||||
typedef signed long int mpi_limb_signed_t;
|
||||
|
||||
typedef struct mpi_struct {
|
||||
int alloced; /* array size (# of allocated limbs) */
|
||||
|
@ -48,6 +48,24 @@ case "${target}" in
|
||||
path="pa7100 hppa1_1 hppa"
|
||||
mpi_extra_modules="udiv-qrnnd"
|
||||
;;
|
||||
sparc9*-*-* | sparc64*-*-* | ultrasparc*-*-*)
|
||||
echo '/* configured for sparc9 or higher */' >>./mpi/asm-syntax.h
|
||||
path="sparc32v8 sparc32"
|
||||
;;
|
||||
sparc8*-*-* | microsparc*-*-*)
|
||||
echo '/* configured for sparc8 */' >>./mpi/asm-syntax.h
|
||||
path="sparc32v8"
|
||||
;;
|
||||
supersparc*-*-*)
|
||||
echo '/* configured for supersparc */' >>./mpi/asm-syntax.h
|
||||
path="supersparc sparc32v8 sparc32"
|
||||
mpi_extra_modules="udiv"
|
||||
;;
|
||||
sparc*-*-*)
|
||||
echo '/* configured for sparc */' >>./mpi/asm-syntax.h
|
||||
path="sparc32"
|
||||
mpi_extra_modules="udiv"
|
||||
;;
|
||||
*)
|
||||
echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
|
||||
path=""
|
||||
|
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