Import gcrypt public-key cryptography and implement signature checking.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-01-11 21:32:42 +01:00
parent 535714bdcf
commit 5e3b8dcbb5
238 changed files with 40500 additions and 417 deletions

View file

@ -1,3 +1,7 @@
2013-01-11 Vladimir Serbinenko <phcoder@gmail.com>
Import gcrypt public-key cryptography and implement signature checking.
2013-01-10 Vladimir Serbinenko <phcoder@gmail.com> 2013-01-10 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/fs/ntfs.c: Ue more appropriate types. * grub-core/fs/ntfs.c: Ue more appropriate types.

View file

@ -213,8 +213,6 @@ program = {
ldadd = libgrubkern.a; ldadd = libgrubkern.a;
ldadd = grub-core/gnulib/libgnu.a; ldadd = grub-core/gnulib/libgnu.a;
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
cflags = '$(CFLAGS_GCRY)';
cppflags = '$(CPPFLAGS_GCRY)';
}; };
program = { program = {
@ -245,9 +243,6 @@ program = {
common = grub-core/kern/emu/hostfs.c; common = grub-core/kern/emu/hostfs.c;
common = grub-core/disk/host.c; common = grub-core/disk/host.c;
cflags = '$(CFLAGS_GCRY)';
cppflags = '$(CPPFLAGS_GCRY)';
ldadd = libgrubmods.a; ldadd = libgrubmods.a;
ldadd = libgrubgcry.a; ldadd = libgrubgcry.a;
ldadd = libgrubkern.a; ldadd = libgrubkern.a;

View file

@ -13,6 +13,16 @@ python util/import_unicode.py unicode/UnicodeData.txt unicode/BidiMirroring.txt
echo "Importing libgcrypt..." echo "Importing libgcrypt..."
python util/import_gcry.py grub-core/lib/libgcrypt/ grub-core python util/import_gcry.py grub-core/lib/libgcrypt/ grub-core
sed -n -f util/import_gcrypth.sed < grub-core/lib/libgcrypt/src/gcrypt.h.in > include/grub/gcrypt/gcrypt.h
rm include/grub/gcrypt/g10lib.h
rm -rf grub-core/lib/libgcrypt-grub/mpi/generic
ln -s ../../../grub-core/lib/libgcrypt-grub/src/g10lib.h include/grub/gcrypt/g10lib.h
cp -R grub-core/lib/libgcrypt/mpi/generic grub-core/lib/libgcrypt-grub/mpi/generic
for x in mpi-asm-defs.h mpih-add1.c mpih-sub1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c mpih-lshift.c mpih-rshift.c; do
rm grub-core/lib/libgcrypt-grub/mpi/"$x"
ln -s generic/"$x" grub-core/lib/libgcrypt-grub/mpi/"$x"
done
echo "Creating Makefile.tpl..." echo "Creating Makefile.tpl..."
python gentpl.py | sed -e '/^$/{N;/^\n$/D;}' > Makefile.tpl python gentpl.py | sed -e '/^$/{N;/^\n$/D;}' > Makefile.tpl

View file

@ -47,6 +47,8 @@ CPPFLAGS_DEFAULT += -I$(top_builddir)
CPPFLAGS_DEFAULT += -I$(top_srcdir) CPPFLAGS_DEFAULT += -I$(top_srcdir)
CPPFLAGS_DEFAULT += -I$(top_srcdir)/include CPPFLAGS_DEFAULT += -I$(top_srcdir)/include
CPPFLAGS_DEFAULT += -I$(top_builddir)/include CPPFLAGS_DEFAULT += -I$(top_builddir)/include
CPPFLAGS_DEFAULT += -I$(top_srcdir)/grub-core/lib/libgcrypt-grub/include
CPPFLAGS_DEFAULT += -I$(top_srcdir)/grub-core/lib/libgcrypt-grub/src/
CCASFLAGS_DEFAULT = -DASM_FILE=1 CCASFLAGS_DEFAULT = -DASM_FILE=1
LDADD_KERNEL = LDADD_KERNEL =
@ -102,15 +104,15 @@ grubconfdir = $(sysconfdir)/grub.d
platformdir = $(pkglibdir)/$(target_cpu)-$(platform) platformdir = $(pkglibdir)/$(target_cpu)-$(platform)
starfielddir = $(pkgdatadir)/themes/starfield starfielddir = $(pkgdatadir)/themes/starfield
CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers
CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap
CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -Wno-old-style-definition -Wno-unsafe-loop-optimizations CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -Wno-old-style-definition -Wno-unsafe-loop-optimizations
CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib
CFLAGS_POSIX = -fno-builtin CFLAGS_POSIX = -fno-builtin
CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap
CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers $(CFLAGS_POSIX)
CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap $(CPPFLAGS_POSIX) -D_GCRYPT_IN_LIBGCRYPT=1 -I$(top_srcdir)/include/grub/gcrypt
CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime
# List file macros for recognizing /interesting/ modules # List file macros for recognizing /interesting/ modules

View file

@ -686,6 +686,13 @@ module = {
common = commands/hashsum.c; common = commands/hashsum.c;
}; };
module = {
name = verify;
common = commands/verify.c;
cflags = '$(CFLAGS_POSIX)';
cppflags = '-I$(srcdir)/lib/posix_wrap';
};
module = { module = {
name = hdparm; name = hdparm;
common = commands/hdparm.c; common = commands/hdparm.c;
@ -1844,6 +1851,35 @@ module = {
common = lib/crc64.c; common = lib/crc64.c;
}; };
module = {
name = mpi;
common = lib/libgcrypt-grub/mpi/mpiutil.c;
common = lib/libgcrypt-grub/mpi/mpi-bit.c;
common = lib/libgcrypt-grub/mpi/mpi-add.c;
common = lib/libgcrypt-grub/mpi/mpi-mul.c;
common = lib/libgcrypt-grub/mpi/mpi-mod.c;
common = lib/libgcrypt-grub/mpi/mpi-gcd.c;
common = lib/libgcrypt-grub/mpi/mpi-div.c;
common = lib/libgcrypt-grub/mpi/mpi-cmp.c;
common = lib/libgcrypt-grub/mpi/mpi-inv.c;
common = lib/libgcrypt-grub/mpi/mpi-pow.c;
common = lib/libgcrypt-grub/mpi/mpi-mpow.c;
common = lib/libgcrypt-grub/mpi/mpih-lshift.c;
common = lib/libgcrypt-grub/mpi/mpih-mul.c;
common = lib/libgcrypt-grub/mpi/mpih-mul1.c;
common = lib/libgcrypt-grub/mpi/mpih-mul2.c;
common = lib/libgcrypt-grub/mpi/mpih-mul3.c;
common = lib/libgcrypt-grub/mpi/mpih-add1.c;
common = lib/libgcrypt-grub/mpi/mpih-sub1.c;
common = lib/libgcrypt-grub/mpi/mpih-div.c;
common = lib/libgcrypt-grub/mpi/mpicoder.c;
common = lib/libgcrypt-grub/mpi/mpih-rshift.c;
common = lib/libgcrypt_wrap/mem.c;
cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare';
cppflags = '$(CPPFLAGS_GCRY)';
};
module = { module = {
name = all_video; name = all_video;
common = lib/fake_module.c; common = lib/fake_module.c;

View file

@ -63,7 +63,7 @@ hextoval (char c)
static grub_err_t static grub_err_t
hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result) hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result)
{ {
grub_uint8_t context[hash->contextsize]; GRUB_PROPERLY_ALIGNED_ARRAY (context, hash->contextsize);
grub_uint8_t readbuf[4096]; grub_uint8_t readbuf[4096];
grub_memset (context, 0, sizeof (context)); grub_memset (context, 0, sizeof (context));

763
grub-core/commands/verify.c Normal file
View file

@ -0,0 +1,763 @@
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2011 Free Software Foundation, Inc.
*
* GRUB 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 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/types.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/file.h>
#include <grub/command.h>
#include <grub/crypto.h>
#include <grub/i18n.h>
#include <grub/gcrypt/gcrypt.h>
#include <grub/pubkey.h>
#include <grub/env.h>
#include <grub/kernel.h>
GRUB_MOD_LICENSE ("GPLv3+");
static grub_err_t
read_packet_header (grub_file_t sig, grub_uint8_t *out_type, grub_size_t *len)
{
grub_uint8_t type;
grub_uint8_t l;
grub_uint16_t l16;
grub_uint32_t l32;
/* New format. */
switch (grub_file_read (sig, &type, sizeof (type)))
{
case 1:
break;
case 0:
{
*out_type = 0xff;
return 0;
}
default:
if (grub_errno)
return grub_errno;
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
}
if (type == 0)
{
*out_type = 0xfe;
return 0;
}
if (!(type & 0x80))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
if (type & 0x40)
{
*out_type = (type & 0x3f);
if (grub_file_read (sig, &l, sizeof (l)) != 1)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
if (l < 192)
{
*len = l;
return 0;
}
if (l < 224)
{
*len = (l - 192) << 8;
if (grub_file_read (sig, &l, sizeof (l)) != 1)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
*len |= l;
return 0;
}
if (l == 255)
{
if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
*len = grub_be_to_cpu32 (l32);
return 0;
}
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
}
*out_type = ((type >> 2) & 0xf);
switch (type & 0x3)
{
case 0:
if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
*len = l;
return 0;
case 1:
if (grub_file_read (sig, &l16, sizeof (l16)) != sizeof (l16))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
*len = grub_be_to_cpu16 (l16);
return 0;
case 2:
if (grub_file_read (sig, &l32, sizeof (l32)) != sizeof (l32))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
*len = grub_be_to_cpu32 (l32);
return 0;
}
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
}
struct signature_v4_header
{
grub_uint8_t type;
grub_uint8_t pkeyalgo;
grub_uint8_t hash;
grub_uint16_t hashed_sub;
} __attribute__ ((packed));
const char *hashes[] = {
"md5", "sha1", "ripemd160",
[0x0a] = "sha512"
};
struct
{
const char *name;
grub_size_t nmpisig;
grub_size_t nmpipub;
} pkalgos[] =
{
[1] = { "rsa", 1, 2 },
[3] = { "rsa", 1, 2 },
[17] = { "dsa", 2, 4 },
};
struct grub_public_key
{
struct grub_public_key *next;
struct grub_public_subkey *subkeys;
};
struct grub_public_subkey
{
struct grub_public_subkey *next;
grub_uint8_t type;
grub_uint32_t fingerprint[5];
gcry_mpi_t mpis[10];
};
static void
free_pk (struct grub_public_key *pk)
{
struct grub_public_subkey *nsk, *sk;
for (sk = pk->subkeys; sk; sk = nsk)
{
nsk = sk->next;
grub_free (sk);
}
grub_free (pk);
}
struct grub_public_key *
grub_load_public_key (grub_file_t f)
{
grub_err_t err;
struct grub_public_key *ret;
struct grub_public_subkey **last = 0;
ret = grub_zalloc (sizeof (*ret));
if (!ret)
return NULL;
last = &ret->subkeys;
while (1)
{
grub_uint8_t type;
grub_size_t len;
grub_uint8_t v, pk;
grub_uint32_t creation_time;
grub_off_t pend;
struct grub_public_subkey *sk;
grub_size_t i;
grub_uint16_t len_be;
GRUB_PROPERLY_ALIGNED_ARRAY (fingerprint_context, GRUB_MD_SHA1->contextsize);
err = read_packet_header (f, &type, &len);
if (err)
goto fail;
if (type == 0xfe)
continue;
if (type == 0xff)
return ret;
grub_dprintf ("crypt", "len = %x\n", (int) len);
pend = grub_file_tell (f) + len;
if (type != 6 && type != 14
&& type != 5 && type != 7)
{
grub_file_seek (f, pend);
continue;
}
if (grub_file_read (f, &v, sizeof (v)) != sizeof (v))
{
grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
goto fail;
}
grub_dprintf ("crypt", "v = %x\n", v);
if (v != 4)
{
grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
goto fail;
}
if (grub_file_read (f, &creation_time, sizeof (creation_time)) != sizeof (creation_time))
{
grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
goto fail;
}
grub_dprintf ("crypt", "time = %x\n", creation_time);
if (grub_file_read (f, &pk, sizeof (pk)) != sizeof (pk))
{
grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
goto fail;
}
grub_dprintf ("crypt", "pk = %x\n", pk);
if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL)
{
grub_file_seek (f, pend);
continue;
}
sk = grub_zalloc (sizeof (struct grub_public_subkey));
if (!sk)
goto fail;
grub_memset (fingerprint_context, 0, sizeof (fingerprint_context));
GRUB_MD_SHA1->init (fingerprint_context);
GRUB_MD_SHA1->write (fingerprint_context, "\x99", 1);
len_be = grub_cpu_to_be16 (len);
GRUB_MD_SHA1->write (fingerprint_context, &len_be, sizeof (len_be));
GRUB_MD_SHA1->write (fingerprint_context, &v, sizeof (v));
GRUB_MD_SHA1->write (fingerprint_context, &creation_time, sizeof (creation_time));
GRUB_MD_SHA1->write (fingerprint_context, &pk, sizeof (pk));
for (i = 0; i < pkalgos[pk].nmpipub; i++)
{
grub_uint16_t l;
grub_size_t lb;
grub_uint8_t buffer[4096];
if (grub_file_read (f, &l, sizeof (l)) != sizeof (l))
{
grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
goto fail;
}
lb = (grub_be_to_cpu16 (l) + 7) / 8;
if (lb > sizeof (buffer) - sizeof (grub_uint16_t))
{
grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
goto fail;
}
if (grub_file_read (f, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
{
grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
goto fail;
}
grub_memcpy (buffer, &l, sizeof (l));
GRUB_MD_SHA1->write (fingerprint_context, buffer, lb + sizeof (grub_uint16_t));
if (gcry_mpi_scan (&sk->mpis[i], GCRYMPI_FMT_PGP,
buffer, lb + sizeof (grub_uint16_t), 0))
{
grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
goto fail;
}
}
GRUB_MD_SHA1->final (fingerprint_context);
grub_memcpy (sk->fingerprint, GRUB_MD_SHA1->read (fingerprint_context), 20);
*last = sk;
last = &sk->next;
for (i = 0; i < 20; i += 2)
grub_printf ("%02x%02x ", ((grub_uint8_t *) sk->fingerprint)[i], ((grub_uint8_t *) sk->fingerprint)[i + 1]);
grub_printf ("\n");
grub_dprintf ("crypt", "actual pos: %x, expected: %x\n", (int)grub_file_tell (f), (int)pend);
grub_file_seek (f, pend);
}
fail:
free_pk (ret);
return NULL;
}
struct grub_public_key *grub_pk_trusted;
struct grub_public_subkey *
grub_crypto_pk_locate_subkey (grub_uint64_t keyid, struct grub_public_key *pkey)
{
struct grub_public_subkey *sk;
for (sk = pkey->subkeys; sk; sk = sk->next)
if (grub_memcmp (sk->fingerprint + 3, &keyid, 8) == 0)
return sk;
return 0;
}
struct grub_public_subkey *
grub_crypto_pk_locate_subkey_in_trustdb (grub_uint64_t keyid)
{
struct grub_public_key *pkey;
struct grub_public_subkey *sk;
for (pkey = grub_pk_trusted; pkey; pkey = pkey->next)
{
sk = grub_crypto_pk_locate_subkey (keyid, pkey);
if (sk)
return sk;
}
return 0;
}
grub_err_t
grub_verify_signature (grub_file_t f, grub_file_t sig,
struct grub_public_key *pkey)
{
grub_size_t len;
grub_uint8_t v;
grub_uint8_t h;
grub_uint8_t t;
grub_uint8_t pk;
const gcry_md_spec_t *hash;
struct signature_v4_header v4;
grub_err_t err;
grub_size_t i;
gcry_mpi_t mpis[10];
grub_uint8_t type;
err = read_packet_header (sig, &type, &len);
if (err)
return err;
if (type != 0x2)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
if (grub_file_read (sig, &v, sizeof (v)) != sizeof (v))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
if (v != 4)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
if (grub_file_read (sig, &v4, sizeof (v4)) != sizeof (v4))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
h = v4.hash;
t = v4.type;
pk = v4.pkeyalgo;
if (t != 0)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
if (h >= ARRAY_SIZE (hashes) || hashes[h] == NULL)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "unknown hash");
if (pk >= ARRAY_SIZE (pkalgos) || pkalgos[pk].name == NULL)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
hash = grub_crypto_lookup_md_by_name (hashes[h]);
if (!hash)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "hash `%s' not loaded", hashes[h]);
grub_dprintf ("crypt", "alive\n");
{
GRUB_PROPERLY_ALIGNED_ARRAY (context, hash->contextsize);
unsigned char *hval;
grub_ssize_t rem = grub_be_to_cpu16 (v4.hashed_sub);
grub_uint32_t headlen = grub_cpu_to_be32 (rem + 6);
grub_uint8_t s;
grub_uint16_t unhashed_sub;
grub_ssize_t r;
grub_uint8_t hash_start[2];
gcry_mpi_t hmpi;
grub_uint64_t keyid = 0;
struct grub_public_subkey *sk;
grub_memset (context, 0, sizeof (context));
hash->init (context);
while (1)
{
grub_uint8_t readbuf[4096];
r = grub_file_read (f, readbuf, sizeof (readbuf));
if (r < 0)
return grub_errno;
if (r == 0)
break;
hash->write (context, readbuf, r);
}
hash->write (context, &v, sizeof (v));
hash->write (context, &v4, sizeof (v4));
while (rem)
{
grub_uint8_t readbuf[4096];
r = grub_file_read (sig, readbuf, rem < (grub_ssize_t) sizeof (readbuf) ? rem : (grub_ssize_t) sizeof (readbuf));
if (r < 0)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
if (r == 0)
break;
hash->write (context, readbuf, r);
rem -= r;
}
hash->write (context, &v, sizeof (v));
s = 0xff;
hash->write (context, &s, sizeof (s));
hash->write (context, &headlen, sizeof (headlen));
r = grub_file_read (sig, &unhashed_sub, sizeof (unhashed_sub));
if (r != sizeof (unhashed_sub))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
{
grub_uint8_t readbuf[4096];
grub_uint8_t *ptr;
grub_uint32_t l;
rem = grub_be_to_cpu16 (unhashed_sub);
if (rem > (int) sizeof (readbuf))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
r = grub_file_read (sig, readbuf, rem);
if (r != rem)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
for (ptr = readbuf; ptr < readbuf + rem; ptr += l)
{
if (*ptr < 192)
l = *ptr++;
else if (*ptr < 255)
{
if (ptr + 1 >= readbuf + rem)
break;
l = (((ptr[0] & ~192) << 8) | ptr[1]) + 192;
ptr += 2;
}
else
{
if (ptr + 5 >= readbuf + rem)
break;
l = grub_be_to_cpu32 (grub_get_unaligned32 (ptr + 1));
ptr += 5;
}
if (*ptr == 0x10 && l >= 8)
keyid = grub_get_unaligned64 (ptr + 1);
}
}
hash->final (context);
grub_dprintf ("crypt", "alive\n");
hval = hash->read (context);
if (grub_file_read (sig, hash_start, sizeof (hash_start)) != sizeof (hash_start))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
if (grub_memcmp (hval, hash_start, sizeof (hash_start)) != 0)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
grub_dprintf ("crypt", "@ %x\n", (int)grub_file_tell (sig));
for (i = 0; i < pkalgos[pk].nmpisig; i++)
{
grub_uint16_t l;
grub_size_t lb;
grub_uint8_t buffer[4096];
grub_dprintf ("crypt", "alive\n");
if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
grub_dprintf ("crypt", "alive\n");
lb = (grub_be_to_cpu16 (l) + 7) / 8;
grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l));
if (lb > sizeof (buffer) - sizeof (grub_uint16_t))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
grub_dprintf ("crypt", "alive\n");
if (grub_file_read (sig, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
grub_dprintf ("crypt", "alive\n");
grub_memcpy (buffer, &l, sizeof (l));
grub_dprintf ("crypt", "alive\n");
if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP,
buffer, lb + sizeof (grub_uint16_t), 0))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
grub_dprintf ("crypt", "alive\n");
}
if (pkey)
sk = grub_crypto_pk_locate_subkey (keyid, pkey);
else
sk = grub_crypto_pk_locate_subkey_in_trustdb (keyid);
if (!sk)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "key not found");
int nbits = gcry_mpi_get_nbits (sk->mpis[1]);
grub_dprintf ("crypt", "must be %d bits got %d bits\n", (int)nbits, (int)(8 * hash->mdlen));
if (gcry_mpi_scan (&hmpi, GCRYMPI_FMT_USG, hval, nbits / 8 < (int) hash->mdlen ? nbits / 8 : (int) hash->mdlen, 0))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
if (!grub_crypto_pk_dsa)
return grub_error (GRUB_ERR_BAD_SIGNATURE, "DSA module is not loaded");
if (grub_crypto_pk_dsa->verify (0, hmpi, mpis, sk->mpis, 0, 0))
return grub_error (GRUB_ERR_BAD_SIGNATURE, "bad signature");
}
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_trust (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
grub_file_t pkf;
struct grub_public_key *pk = NULL;
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "one argument required");
grub_file_filter_disable_all ();
pkf = grub_file_open (args[0]);
if (!pkf)
return grub_errno;
pk = grub_load_public_key (pkf);
if (!pk)
{
grub_file_close (pkf);
return grub_errno;
}
grub_file_close (pkf);
pk->next = grub_pk_trusted;
grub_pk_trusted = pk;
return GRUB_ERR_NONE;
}
static grub_err_t
grub_cmd_distrust (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
grub_uint32_t keyid, keyid_be;
struct grub_public_key **pkey;
struct grub_public_subkey *sk;
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "one argument required");
keyid = grub_strtoull (args[0], 0, 16);
if (grub_errno)
return grub_errno;
keyid_be = grub_cpu_to_be32 (keyid);
for (pkey = &grub_pk_trusted; *pkey; pkey = &((*pkey)->next))
{
struct grub_public_key *next;
for (sk = (*pkey)->subkeys; sk; sk = sk->next)
if (grub_memcmp (sk->fingerprint + 4, &keyid_be, 4) == 0)
break;
if (!sk)
continue;
next = (*pkey)->next;
free_pk (*pkey);
*pkey = next;
return GRUB_ERR_NONE;
}
return grub_error (GRUB_ERR_BAD_ARGUMENT, "key %08x not found", keyid);
}
static grub_err_t
grub_cmd_verify_signature (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
grub_file_t f, sig;
grub_err_t err;
struct grub_public_key *pk = NULL;
grub_dprintf ("crypt", "alive\n");
if (argc < 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments required");
grub_dprintf ("crypt", "alive\n");
if (argc > 2)
{
grub_file_t pkf;
grub_file_filter_disable_all ();
pkf = grub_file_open (args[2]);
if (!pkf)
return grub_errno;
pk = grub_load_public_key (pkf);
if (!pk)
{
grub_file_close (pkf);
return grub_errno;
}
grub_file_close (pkf);
}
grub_file_filter_disable_all ();
f = grub_file_open (args[0]);
if (!f)
return grub_errno;
grub_file_filter_disable_all ();
sig = grub_file_open (args[1]);
if (!sig)
{
grub_file_close (f);
return grub_errno;
}
err = grub_verify_signature (f, sig, pk);
grub_file_close (f);
grub_file_close (sig);
return err;
}
static int sec = 0;
static grub_file_t
grub_pubkey_open (grub_file_t io, const char *filename)
{
grub_file_t sig;
char *fsuf, *ptr;
grub_err_t err;
grub_file_filter_t curfilt[GRUB_FILE_FILTER_MAX];
if (!sec)
return io;
fsuf = grub_malloc (grub_strlen (filename) + sizeof (".sig"));
if (!fsuf)
return NULL;
ptr = grub_stpcpy (fsuf, filename);
grub_memcpy (ptr, ".sig", sizeof (".sig"));
grub_memcpy (curfilt, grub_file_filters_enabled,
sizeof (curfilt));
grub_file_filter_disable_all ();
sig = grub_file_open (fsuf);
grub_memcpy (grub_file_filters_enabled, curfilt,
sizeof (curfilt));
grub_free (fsuf);
if (!sig)
return NULL;
err = grub_verify_signature (io, sig, NULL);
grub_file_close (sig);
if (err)
return NULL;
grub_file_seek (io, 0);
return io;
}
static char *
grub_env_write_sec (struct grub_env_var *var __attribute__ ((unused)),
const char *val)
{
sec = (*val == '1') || (*val == 'e');
return grub_strdup (sec ? "enforce" : "no");
}
static grub_ssize_t
pseudo_read (struct grub_file *file, char *buf, grub_size_t len)
{
grub_memcpy (buf, (grub_uint8_t *) file->data + file->offset, len);
return len;
}
/* Filesystem descriptor. */
struct grub_fs pseudo_fs =
{
.name = "pseudo",
.read = pseudo_read
};
struct gcry_pk_spec *grub_crypto_pk_dsa;
struct gcry_pk_spec *grub_crypto_pk_ecdsa;
struct gcry_pk_spec *grub_crypto_pk_rsa;
static grub_command_t cmd, cmd_trust, cmd_distrust;
GRUB_MOD_INIT(verify)
{
const char *val;
struct grub_module_header *header;
val = grub_env_get ("check_signatures");
if (val && (val[0] == '1' || val[0] == 'e'))
sec = 1;
else
sec = 0;
grub_file_filter_register (GRUB_FILE_FILTER_PUBKEY, grub_pubkey_open);
grub_register_variable_hook ("check_signatures", 0, grub_env_write_sec);
grub_env_export ("check_signatures");
grub_pk_trusted = 0;
FOR_MODULES (header)
{
struct grub_file pseudo_file;
struct grub_public_key *pk = NULL;
grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
/* Not an ELF module, skip. */
if (header->type != OBJ_TYPE_PUBKEY)
continue;
pseudo_file.fs = &pseudo_fs;
pseudo_file.size = (header->size - sizeof (struct grub_module_header));
pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
pk = grub_load_public_key (&pseudo_file);
if (!pk)
grub_fatal ("error loading initial key: %s\n", grub_errmsg);
pk->next = grub_pk_trusted;
grub_pk_trusted = pk;
}
if (!val)
grub_env_set ("check_signatures", grub_pk_trusted ? "enforce" : "no");
cmd = grub_register_command ("verify_detached", grub_cmd_verify_signature,
"FILE SIGFILE [PKFILE]",
N_("Verify detached signature."));
cmd_trust = grub_register_command ("trust", grub_cmd_trust,
"PKFILE",
N_("Add PKFILE to trusted keys."));
cmd_distrust = grub_register_command ("distrust", grub_cmd_distrust,
"KEYID",
N_("Remove KEYID from trusted keys."));
}
GRUB_MOD_FINI(verify)
{
grub_file_filter_unregister (GRUB_FILE_FILTER_PUBKEY);
grub_unregister_command (cmd);
grub_unregister_command (cmd_trust);
grub_unregister_command (cmd_distrust);
}

View file

@ -1125,7 +1125,7 @@ initialize_tables (grub_gzio_t gzio)
even if IO does not contain data compressed by gzip, return a valid file even if IO does not contain data compressed by gzip, return a valid file
object. Note that this function won't close IO, even if an error occurs. */ object. Note that this function won't close IO, even if an error occurs. */
static grub_file_t static grub_file_t
grub_gzio_open (grub_file_t io) grub_gzio_open (grub_file_t io, const char *name __attribute__ ((unused)))
{ {
grub_file_t file; grub_file_t file;
grub_gzio_t gzio = 0; grub_gzio_t gzio = 0;

View file

@ -409,7 +409,8 @@ CORRUPTED:
} }
static grub_file_t static grub_file_t
grub_lzopio_open (grub_file_t io) grub_lzopio_open (grub_file_t io,
const char *name __attribute__ ((unused)))
{ {
grub_file_t file; grub_file_t file;
grub_lzopio_t lzopio; grub_lzopio_t lzopio;

View file

@ -169,7 +169,8 @@ ERROR:
} }
static grub_file_t static grub_file_t
grub_xzio_open (grub_file_t io) grub_xzio_open (grub_file_t io,
const char *name __attribute__ ((unused)))
{ {
grub_file_t file; grub_file_t file;
grub_xzio_t xzio; grub_xzio_t xzio;

View file

@ -107,7 +107,7 @@ grub_file_open (const char *name)
if (grub_file_filters_enabled[filter]) if (grub_file_filters_enabled[filter])
{ {
last_file = file; last_file = file;
file = grub_file_filters_enabled[filter] (file); file = grub_file_filters_enabled[filter] (file, name);
} }
if (!file) if (!file)
grub_file_close (last_file); grub_file_close (last_file);

View file

@ -23,6 +23,7 @@
#include <grub/term.h> #include <grub/term.h>
#include <grub/dl.h> #include <grub/dl.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/env.h>
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
#include <termios.h> #include <termios.h>
@ -56,6 +57,38 @@ grub_burn_stack (grub_size_t size)
grub_burn_stack (size - sizeof (buf)); grub_burn_stack (size - sizeof (buf));
} }
void
_gcry_burn_stack (int size)
{
grub_burn_stack (size);
}
void __attribute__ ((noreturn))
_gcry_assert_failed (const char *expr, const char *file, int line,
const char *func)
{
grub_fatal ("assertion %s at %s:%d (%s) failed\n", expr, file, line, func);
}
void _gcry_log_error (const char *fmt, ...)
{
va_list args;
const char *debug = grub_env_get ("debug");
if (! debug)
return;
if (grub_strword (debug, "all") || grub_strword (debug, "gcrypt"))
{
grub_printf ("gcrypt error: ");
va_start (args, fmt);
grub_vprintf (fmt, args);
va_end (args);
grub_refresh ();
}
}
void void
grub_cipher_register (gcry_cipher_spec_t *cipher) grub_cipher_register (gcry_cipher_spec_t *cipher)
@ -477,3 +510,4 @@ grub_password_get (char buf[], unsigned buf_size)
return (key != '\e'); return (key != '\e');
#endif #endif
} }

View file

@ -1,3 +1,93 @@
2010-08-19 Werner Koch <wk@g10code.com>
* cipher.c (gcry_cipher_open): Remove double release of the module.
Fixes bug#1263.
2010-06-10 Jeff Johnson <n3npq@mac.com> (wk)
* ecc.c (ecc_generate_ext): Parse transient-key flag.
(generate_key): Add arg TRANSIENT_KEY and use it to set the random
level.
2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
Spelling fixes.
2010-03-26 Werner Koch <wk@g10code.com>
* tiger.c (asn): Unfetter the old TIGER from an OID.
(TIGER_CONTEXT): Add field VARIANT.
(tiger_init): Factor code out to ...
(do_init): New.
(tiger1_init, tiger2_init): New.
(_gcry_digest_spec_tiger1, _gcry_digest_spec_tiger2): New.
* md.c (digest_table): Add TIGER1 and TIGER2 variants.
2009-12-11 Werner Koch <wk@g10code.com>
* sha256.c (Cho, Maj, Sum0, Sum1): Turn macros into inline
functions.
(transform): Partly unroll to interweave the chain variables
* sha512.c (ROTR, Ch, Maj, Sum0, Sum1): Turn macros into inline
functions.
(transform): Partly unroll to interweave the chain variables.
Suggested by Christian Grothoff.
2009-12-10 Werner Koch <wk@g10code.com>
* Makefile.am (o_flag_munging): New.
(tiger.o, tiger.lo): Use it.
* cipher.c (do_ctr_encrypt): Add arg OUTBUFLEN. Check for
suitable value. Add check for valid inputlen. Wipe temporary
memory.
(do_ctr_decrypt): Likewise.
(do_cbc_encrypt, do_cbc_decrypt): Add arg OUTBUFLEN. Check for
suitable value. Move check for valid inputlen to here; change
returned error from INV_ARG to INV_LENGTH.
(do_ecb_encrypt, do_ecb_decrypt): Ditto.
(do_cfb_encrypt, do_cfb_decrypt): Ditto.
(do_ofb_encrypt, do_ofb_decrypt): Ditto.
(cipher_encrypt, cipher_encrypt): Adjust for above changes.
(gcry_cipher_encrypt, gcry_cipher_decrypt): Simplify.
2009-12-09 Werner Koch <wk@g10code.com>
* cipher.c (gcry_cipher_open): Allow for GCRY_CIPHER_MODE_AESWRAP.
(cipher_encrypt, cipher_decrypt): Ditto.
(do_aeswrap_encrypt, do_aeswrap_decrypt): New.
(struct gcry_cipher_handle): Add field marks.
(cipher_setkey, cipher_setiv): Update marks flags.
(cipher_reset): Reset marks.
(cipher_encrypt, cipher_decrypt): Add new arg OUTBUFLEN.
(gcry_cipher_encrypt, gcry_cipher_decrypt): Pass outbuflen to
cipher_encrypt. Replace GPG_ERR_TOO_SHORT by
GPG_ERR_BUFFER_TOO_SHORT.
2009-08-21 Werner Koch <wk@g10code.com>
* dsa.c (dsa_generate_ext): Release retfactors array before
setting it to NULL. Reported by Daiko Ueno.
2009-07-02 Werner Koch <wk@g10code.com>
* md.c (md_read): Fix incomplete check for NULL.
Reported by Fabian Kail.
2009-03-31 Werner Koch <wk@g10code.com>
* rsa.c (rsa_check_secret_key): Return GPG_ERR_BAD_SECKEY and not
GPG_ERR_PUBKEY_ALGO.
2009-02-16 Werner Koch <wk@g10code.com>
* rsa.c (generate_x931): Do not initialize TBL with automatic
variables.
* whirlpool.c, tiger.c, sha256.c, sha1.c, rmd160.c, md5.c
* md4.c, crc.c: Remove memory.h. This is garbage from gnupg.
Reported by Dan Fandrich.
2009-01-22 Werner Koch <wk@g10code.com> 2009-01-22 Werner Koch <wk@g10code.com>
* ecc.c (compute_keygrip): Remove superfluous const. * ecc.c (compute_keygrip): Remove superfluous const.
@ -3888,8 +3978,8 @@ Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de)
(digest_algo_to_string): New. (digest_algo_to_string): New.
Copyright 1998,1999,2000,2001,2002,2003,2004,2005,2006 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
2007, 2008, 2009 Free Software Foundation, Inc. 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is free software; as a special exception the author gives This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without unlimited permission to copy and/or distribute it, with or without

View file

@ -0,0 +1,82 @@
# Makefile for cipher modules
# Copyright (C) 1998, 1999, 2000, 2001, 2002,
# 2003, 2009 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# Libgcrypt is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Libgcrypt 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, see <http://www.gnu.org/licenses/>.
# Process this file with automake to produce Makefile.in
EXTRA_DIST = Manifest
# Need to include ../src in addition to top_srcdir because gcrypt.h is
# a built header.
AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
AM_CFLAGS = $(GPG_ERROR_CFLAGS)
noinst_LTLIBRARIES = libcipher.la
GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ @GCRYPT_DIGESTS@
libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES)
libcipher_la_LIBADD = $(GCRYPT_MODULES)
libcipher_la_SOURCES = \
cipher.c pubkey.c ac.c md.c \
hmac-tests.c \
bithelp.h \
primegen.c \
hash-common.c hash-common.h \
rmd.h
EXTRA_libcipher_la_SOURCES = \
arcfour.c \
blowfish.c \
cast5.c \
crc.c \
des.c \
dsa.c \
elgamal.c \
ecc.c \
md4.c \
md5.c \
rijndael.c rijndael-tables.h \
rmd160.c \
rsa.c \
seed.c \
serpent.c \
sha1.c \
sha256.c \
sha512.c \
tiger.c \
whirlpool.c \
twofish.c \
rfc2268.c \
camellia.c camellia.h camellia-glue.c
if ENABLE_O_FLAG_MUNGING
o_flag_munging = sed -e 's/-O[2-9s]*/-O1/g'
else
o_flag_munging = cat
endif
# We need to lower the optimization for this module.
tiger.o: $(srcdir)/tiger.c
`echo $(COMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) `
tiger.lo: $(srcdir)/tiger.c
`echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) `

View file

@ -0,0 +1,73 @@
# Manifest - checksums of the cipher directory
# Copyright 2003 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# Libgcrypt is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser general Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Libgcrypt 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser 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
# Checksums for all source files in this directory. Format is
# filename, blanks, base-64 part of an OpenPGP detached signature
# without the header lines. Blank lines and lines beginning with a
# hash mark are ignored. A tool to process this file is available by
# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool
#
# The special entry "$names$" holds a signature over all sorted
# filenames excluding itself.
# Algorithm API
cipher.c iQCVAwUAQDzrVjEAnp832S/7AQIPDgP+OVJ/YNWY5m7c09EBbPAzL/WsGoj6wrBNMmkRlMOqTHeh+OOtjuFHt1f9uhfM2Nzl7sJ5+h4ryZKLEZmQPRMTZTnAqkvGdsrJWJnigUA9QwYdV0ONqC9C63gpuG465gO9TZVOqlQu/FTxSRuTQYUulkaBNG71n8nZEOusBVwV2YA==58xH
pubkey.c iQCVAwUAP9XQ3jEAnp832S/7AQJ5UgQAyHfEBvPVJ8wTRg8c7ixS2GiVmIgwIo5tvQaiQJTPWASevvYrB+2Z2qa9cATyu50ACjLzbaquGBgPzjJV3dU/qttT1gCqRuN/LCNvXFe5qnIZezejc3RAadFNTw/pOTHq0wxD1Keg66ruei9R36Nba59pEQIWIBXTfubRft2hMYk==E09t
ac.c iQCVAwUAQDzsOzEAnp832S/7AQJCBQP/WI6EV/dsR4rmha6RVhvkjZo17kQ8z6pIl5J3cXOvqEkIFeD2HYu3HHrWST5l7yXlffhpDkVHkfMih4ruK76q6Fm0dxZ98pO4C/dVtgimlvvcy/wOQjpzsE0fYAe1BYdg81LJ09X33vW5x6C29lunfKROO2tPlV5i8ffeoFvmMF8==j26g
md.c iQCVAwUAP+NFGjEAnp832S/7AQJs8wP/Qdk0EAKsyr3O1/pmOSN8AG4rPKbd6KDTzvoBPAN4upFwKYY4hWwvy12Q3YU9DmECrzZkRCXHR7mljVQKs6B7CRZJKjFKmOELpcJDtKvu40vTs1bOH4k9iJYZpGgRA83nkQ+ELAcphAbCA+KIpVr2K4mCJAB0FhpC2uOQ50JHAko==BeF6
primegen.c iQCVAwUAQDzsoDEAnp832S/7AQKYRwP/TqAQBm1rHTnF0HYE05PqXfWlOqa6EosqVpaOcs/OIW6PaqX0xH1UlrukK7jNOjK3xC4o1qNQ1UKzz2dvQaq1bMvNNizeavxAh10SJZc0hIc/ofc83IbjLh8SZVWQ67JxjsUd3DOXmSmhPZ+Pqd7cUIiw8fDoF+I9EZqy3COu1wY==1ebT
# Algorithm implementations
arcfour.c iQCVAwUAP9XR/TEAnp832S/7AQJcRwP6AlvYEx++fpT4mIYo0xRDqKEQeqMQvbaRhIg2eV74JxItpHa3q5YsYIl+n1yUz5g35JRWWXSWmAZBwO5wLKsHii4kRUhgrKWnSoQZoPpl49L5+N3R58ON3S0ru5lsBiEJEze3xplf2vqwrH9v1QHVD+gU7UTlfNqrIJoOUXN+1O4==Tq+x
blowfish.c iQCVAwUAP9XTETEAnp832S/7AQJaEgQAgiqqfuO+zQtscgTB0rvOzVymIKjRKjYhFuLjVuc79G4z1RCAffvIn/YM2d7kt+Z/QF7zjcTAOgETCQL1XokpX2zz9HPAMi2tlDY5zsDufTNqj0n4WBL9nM7w6XAvsiwP1B3bqCTv9SjJV4KbxJ58vw1yQE+sqW74R/QIHFvC7mU==wZnX
cast5.c iQCVAwUAP9XT6DEAnp832S/7AQJ3xgP/ehLjEN3GELGudbqeo91Xd+PqitHrkuBbtRIYX7Udd/fyXLN+h8rMJVyIQX2m+mpxbBxudVU3x8/DNT8B0ZHAwK6qqJmEBLLhEYPgIuF76i9LMrP1KqUPhAwRZ2OppjIIugBQ+rP74aD4eLyd/aKQHNuXML8QGWR6KwQShohXM5I==/BRh
crc.c iQCVAwUAP7ouejEAnp832S/7AQIgwQQApg5Nm63tH5DQkbN+zPzMO9Ygoj3ukxfFTyTBPYSXYKMiTjEbESegaU40uN8jnz2vprcIQWcgZfzO4+opEJMcI35aPwzEk0vKOp0S/PrBLUY2rJfnDVkX5XgJFZa2Q7LLe826UEBzTVYW924utiCCe8oOaOEWVNpg1mqdknu3M9o==kz5D
des.c iQCVAwUAQCN2oDEAnp832S/7AQL/jwP6Auoq6nZCDBjpgc9tDzuIRwa9DqyuM3gX94uvgEpUwdHszb2bG43dz03kVmcYxtj1MzXbyCeCZOwox0b2SKmLgxIbrNP6yGbzVdTj6592gDYuf/ZXmc1ZNJ1DDldcPQ0n9fXUipUPwyPaNWo3mSZaNcMKSWWzdK0J6ciG6nk7SWI==9k/t
dsa.c iQCVAwUAP9XZHDEAnp832S/7AQLBRgP/XrBzTEYx5ccMj1MMb6sg37liEHdIyyy49zjvt6jUqxj4RuwVEN8S6v3u4q/QyJkHAi1E0EkREgENlyHW6PKWhYbcrd0vPIAN15yjnl2yqtrCrJImexUCoqJJewK0E4JOicGbabTil8MZjk+mbhEPnjJBqOkyP1w0i31pEDgE/8M==pC8s
elgamal.c iQCVAwUAP9XbYzEAnp832S/7AQLXagQA3HrvspZfbTGgmUH0IqLQTJ0exUPxJv5DET2TvoIy62trDmMN6lTAj5P+a7jQ8udcu0w+mR2vXUHcxUpNA2PxLaMwGzNSY4zRDNe9r3SFTDrFm6m4y9Ko2e8XtEA+WF6P/XLpck4Jn7vMEDmVGPwkNd22kXFFE8dBGwG6i5Hk1Mk==oBUs
md4.c iQCVAwUAP9h50DEAnp832S/7AQJhHgQAzNA/B6MWFDlCtPkIVaW8RpP1Eg0ZNMsy0s7SJkopOCBlu6CwXUOKe+8ppcSxhjYKh4i4uQr/QtfipYlBjzKJGnrafoF/NugXNCOHSTGT11TvK7mCiBuUMVgvZGAlOJImk6eTTfUjRrMfaXM/SWl8bdJ4ZpzdjEyVh89r7I5JrGk==x2UD
md5.c iQCVAwUAP9h7LzEAnp832S/7AQJUGQP/c0cbf6WZXCzmjufHxiE9FAQBzTsA0WtaNqdFcHl7fhmikGtknlaED8n5a7eYd/C481UQW6Wgq/oZdsvgoPWPhG3fOCy2CFP9cZVXITuMSf0ucyZTFUJNO15fnZ+nDfsUv+JPdv1aSeRinAUtfAcSKfkSyR9BCPZvkx+tgU6cphU==Zv+h
rijndael.c iQCVAwUAP9h9cTEAnp832S/7AQKF1AP+P2L/tPqDJRDg+/fwbOk8Ts0MNxnvvYEm3gE73TKuLt1S+B2+jkrZcKNvM5VGPnVMJbnS0lmIK04nmedHCOftGTOwhGulZAHHIaKGystT3Jql4iPws/JMgAjE7Fyxh5WZMtB9yEljKBpJ5XNqhrMvvxcHpnyP3+YzIXNwzk34V+c==dJ5k
rmd160.c iQCVAwUAP9h+bTEAnp832S/7AQK1OgP+PNKF6Nzi6X93easVlksdLqKEsArCAw2QjGWDGyxTnbiJM55qAl9JxR1mn3V+oOL7izLLwTt6EYK9evhzfcxY5N5Mni85RAcsLPsuAfQDEzjI6GUWHtQUKPbM+BaorzfhQjYFSZyvum/dZYJ/WfiwwwhqqIKyVU2ZFSqA38YGC/c==9jdA
rsa.c iQCVAwUAP9iHIzEAnp832S/7AQKAYwQAuWtnMte54QHN+Hij9t4sGuypXogajOb1vQQwGgS0fKsaBZsuSP2amze4o5diIvsQTsFQ4CzjvqoCVuBDoHM3xkSD8wGDizgvtCamAxkdbF7wmzldKFn8SpJqlVwWQMP6kk1IjXHEuYb4IDWGTbVMhfEu+eOlU8+PSK4IhZqNvt4==/3hp
serpent.c iQCVAwUAP9h/VzEAnp832S/7AQLyCwP/d1zbmb7l/PriZNa9/Z7mo01XFe5MnAqCfIwhl9GjeaMszcoS37jECNq5nLvrTTFIIJpm3rvBePwiCG4Wwx1I18HCxaP198pcSaR+BLOJ3Aj52EZPrxtqlDKuFr38ZOP5giyUqUYVYGVdrz4kRMNWAZQK53GeJnGhXCnhxojLEgA==ck46
sha1.c iQCVAwUAP9iATTEAnp832S/7AQKcSwQAwAs/HnNqho3lU1ZUgCPNt5P2/Brm6W21+wWWGKJkSrra/c4NYVKJGDDwlsFE0b9ln1uZt7bHReFkKXK3JnrKTmNVcx/Cy64iCMRNMhaM72Mqy7wWx5yHBAmMBxzFGnNQKbmeY52zeGih5HsNLSibc2pPuOViWo2JPJ5Ci/wIwl8==/wtO
sha256.c iQCVAwUAP9iAtzEAnp832S/7AQJD2QP/UqvL0hhjG1wEFbGrdkV9tba1sMDXdnnK6X7HdLuRpVAgNiQiFf8JDmntd/dZ2Q71p4Uae2ctqve4WoEijPUZPjACnpuZfx0SEQL0lQBkwxzJp7lz9ujVtwQ2cM/aYexJkXcWgGcloJNLM3JbWPGIJnuYbr/IwJ6RQF9vgj0357o==UWO1
sha512.c iQCVAwUAP9iBTDEAnp832S/7AQIPBAQA28CJSUQLiW0s2x9u8/OH2eKnxPjA4sZmb50WP7920Lem66P31C3BrOqwfBot4RLhjL+zh/+Uc4s3HPwApZuj9E4BxNMlqLv+Tqk++DAbdaOeYT4jeUt+mlhQQ6mH/RDsy32rZsNsGQ2bUGxazZmfG++PL3JyhawqCy00SUDr/o0==H+0X
tiger.c iQCVAwUAP9iCfjEAnp832S/7AQKufwP/fryv3MqSOYY+90325DH7X3/CtekxeooN0scGsHX0fxBakWSMecTNrj33KPddLS46gU/S89zIc2N/Bw/7EVIAXVFA3/3Ip+OrFOuIMO4Py1sCdB8o2Y+5ygv8iXLcsXIq1O0av79i9g774V3uaXa2qN9ZnXe0AEhcy8FHJ2i/wro==5XVB
twofish.c iQCVAwUAP9iD6TEAnp832S/7AQKUnQP/Rq8FaYeHTG7HbZuqAs9pbPitzjDbkdZddmInWR7NmevBkKvhsJALjVooc0KGQfo2lAAmy3Xi/4QQN8VPn51DVjDIgf7x+DQh/9TFJHMccxI9asUgi4+TNnmMqLU1k3N8S2PjyZ1sjeC8B79fKPpwCzj72WkqPkzZw3l2jArr+dU==NdJT
rfc2268.c iQCVAwUAQCN+3jEAnp832S/7AQLv1gQA1hJh29hAjKi4uLSGxXvJ6cyYmPdmevdKrbLnuHZWtHe4xvCgy/nTdEojEpxgLp/hL/ogasuWRC1W16Wiz9ryxf7YR0uhZWayO/bQNagpfU5MIkJTLuKqqgpwYumCSQfOugXVAqcgEzj+13eeyJaFVrzwrNa67sh84nmbjOjNjvE==0zBq
# Random number related
random.c iQCVAwUAP7nsITEAnp832S/7AQK4SAQAtvfUgrtGOQ2PlxGMla0qJLPHjJacMwgq0ecusiI79elPdDsFfCCk6dK1Ug2kFbNm22nCGHNcUquqbX7noi7ZVQnmPBQXzyLNZd7GmrawRZfdlRerTUDBpSnR8V8ui/5+YYp627E7kKGC0hPSgqXFql6oBMIfno0LZwFJTjIevRY==L419
random.h iQCVAwUAP7ovKDEAnp832S/7AQJ3bQQAjnPebnyTC7sphAv2I7uIz+yPgw1ZfbVhLv+OiWDlO9ish+fRyyMpy+HELBOgZjJdgRegqhlZC6qyns5arM/VglYi+PzvdLO3hIqHE/YFfpIFPz8wBrcmlqrYyd3CsGqcYsfjocXNttCBLeSWmoJ09ltKQH8yzJf3oAgN6X1yuc4==eNoU
rand-internal.h iQCVAwUAP7ouvDEAnp832S/7AQLYnAQAhdI7ERoJVCkV8GiV7MjaUxv1WIL7iZ+jIOvVhv4fNyhCGCGoEtTjkyput/lj7Nsh3FXEqRhypGGrCLf47x/gua5n+BwffogxVyUDqiOyyGhNTPpe3fQcNBvbPCtco8yMK4GJO5G3BqzlPyN+BMeogLymyV6Sm1mvh5LZDyAFbfQ==tZSE
rndlinux.c iQCVAwUAP9iPYTEAnp832S/7AQL6/AP/ZDrbOkVuB9qJ7sKeX1MImZEsz3mi0xPovJzaBtBU7a0idcUKrWYOvQFWRlLUeq0iCT6+h2l5bniP7q7hepzlKa+VPY9VWaQthqeJm2l5LN6QQ5PyMfBq04QuBncw9BJnCGmEyTLt3RxIXBAPdxmiVxtcRIFUqCBtQvoUXGLvemw==t37k
rndegd.c iQCVAwUAP9iPRDEAnp832S/7AQImBQP/WHKg+hKXcm1pQvilzML0jZpwK5PAMM4uBnnPJNIXWOYBO6I/Xg9d/tPLg8NlmmtyQCo2Eu0ybDSt+8mu+dWveAys+0LTi0MIqeP9BMzCKz8dnWH6+S8huLXwTF3m0IrqM0JLb6b71GK9SOq6sWQ22yW5vf61hXP8kH9dhIaoMZs==FaHV
rndunix.c iQCVAwUAP9iQlzEAnp832S/7AQL/KgQA29GnvcD4Xb5qjDMBgW9THEE4+4lfex/6k+Fh0IT61OLJsWVLJ7bJpRntburw4uQm4Tf7CO8vaiDFDYhKKrzXeOF1fmdpcL8hA+fNp9I/MUOc4e9kN9+YJ9wikVa0SZj1OBfhzgcFLd1xOtulkr3ii52HLF9vhrxzkgVwvD10Bi8==2cML
rndw32.c iQCVAwUAP9iRKDEAnp832S/7AQIuaAQA3AJr3WqnxNDsWCIdvehf8Suotthj+laX8nJsvDfFhXPKcXDpsg0wTTXSnnKgyED53+uYiMDnVRsxeWAyhKwvx1MjjlaSMMjzbH6isWTH8FaWpLgrxEkXoPeNqYf5FXpdUkcUxGX2RkQeuX/cIfiHLNE9CV0usaF2jysjBX2iERY==EEnO
# Helper
bithelp.h iQCVAwUAP7ouPTEAnp832S/7AQKXggQAqjcgvihIF3WclOgw1JV2rbARw4ISIDRMFqdaNCqBRx6BwEz3UGsEIlz6+iR1sS/reqN61WvtjLb+D0+tujAkGrgQJhFLG85WtG2tB5UVoI3am1fpkwiRm+bR4rv0rGk0BYk81bC7+l4KrK9o5lVp4lCsrorlUKsd48lNmBHyAXM==mDDN
rmd.h iQCVAwUAP7oumjEAnp832S/7AQJiJQP/V4bJwjZaYndJzV+KRnIDbl1koHuw+ZK5heMYVu8Qk4ylqv//BGyeRa3jZCcfPHI35q6HilCs2VBm8hiBMjHSqY/VPn2ZQ0yg/lt6qEvl7YjsLmyMICvjG+ncszHoq9pRvnF3vTnM18sPIioXLk8fskuM0XOCNBs0ARBAQjY9UGI==olUN
# Configuration
Makefile.am iQCVAwUAQCN33TEAnp832S/7AQKFJAQAz7BDkC814q+QiuE/jnutJHR5qlgbrm3ikGbQwdRzYUscst4bCCWy3uKL/sIPGLg+JQXtF5FnsQy3s4D9BOYhp72cA9ktYK65hhi4pNm/JQ0lXkZMNfk8Go5lNzKezlWwHvkMwRXR0Fep0wPdyeaKW5BfaW2ABvgep6Bp+hHEbyg==zSyi
$names$ iQCVAwUAQCN3EDEAnp832S/7AQJXLAP8DvHTpm5DkTF35EmzeKpi9ie59AZcZanD19ir/e/7+PaQxr2riuLHDGwFKTju+dcvvBsqrygXOC378GXVWzIF2OZwS4EdDcJ+pgojo9UpsqpKsJHouY4Ugx5cQialxba462kUn8hcihSBnMyc4LzbJ5WQ4puQuqy544d2x94+2ms==G4Ls

View file

@ -2499,7 +2499,7 @@ typedef enum dencode_action
dencode_action_t; dencode_action_t;
/* Encode or decode a message according to the the encoding method /* Encode or decode a message according to the the encoding method
METHOD; ACTION specifies wether the message that is contained in METHOD; ACTION specifies whether the message that is contained in
BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded. BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded.
The resulting message will be stored in a newly allocated buffer in The resulting message will be stored in a newly allocated buffer in
BUFFER_OUT and BUFFER_OUT_N. */ BUFFER_OUT and BUFFER_OUT_N. */

File diff suppressed because it is too large Load diff

View file

@ -25,7 +25,6 @@
#include <string.h> #include <string.h>
#include "g10lib.h" #include "g10lib.h"
#include "memory.h"
#include "cipher.h" #include "cipher.h"
#include "bithelp.h" #include "bithelp.h"

View file

@ -106,7 +106,7 @@
* *
* if ( (error_msg = selftest()) ) * if ( (error_msg = selftest()) )
* { * {
* fprintf(stderr, "An error in the DES/Tripple-DES implementation occured: %s\n", error_msg); * fprintf(stderr, "An error in the DES/Triple-DES implementation occurred: %s\n", error_msg);
* abort(); * abort();
* } * }
*/ */

View file

@ -907,6 +907,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
gcry_mpi_release ((*retfactors)[i]); gcry_mpi_release ((*retfactors)[i]);
(*retfactors)[i] = NULL; (*retfactors)[i] = NULL;
} }
gcry_free (*retfactors);
*retfactors = NULL; *retfactors = NULL;
if (ec) if (ec)
{ {

View file

@ -1,5 +1,5 @@
/* ecc.c - Elliptic Curve Cryptography /* ecc.c - Elliptic Curve Cryptography
Copyright (C) 2007, 2008 Free Software Foundation, Inc. Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc.
This file is part of Libgcrypt. This file is part of Libgcrypt.
@ -504,6 +504,7 @@ generate_curve (unsigned int nbits, const char *name,
*/ */
static gpg_err_code_t static gpg_err_code_t
generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name, generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
int transient_key,
gcry_mpi_t g_x, gcry_mpi_t g_y, gcry_mpi_t g_x, gcry_mpi_t g_y,
gcry_mpi_t q_x, gcry_mpi_t q_y) gcry_mpi_t q_x, gcry_mpi_t q_y)
{ {
@ -512,6 +513,7 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
gcry_mpi_t d; gcry_mpi_t d;
mpi_point_t Q; mpi_point_t Q;
mpi_ec_t ctx; mpi_ec_t ctx;
gcry_random_level_t random_level;
err = generate_curve (nbits, name, &E, &nbits); err = generate_curve (nbits, name, &E, &nbits);
if (err) if (err)
@ -528,9 +530,11 @@ generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
log_mpidump ("ecc generation Gz", E.G.z); log_mpidump ("ecc generation Gz", E.G.z);
} }
random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
if (DBG_CIPHER) if (DBG_CIPHER)
log_debug ("choosing a random x of size %u\n", nbits); log_debug ("choosing a random x of size %u%s\n", nbits,
d = gen_k (E.n, GCRY_VERY_STRONG_RANDOM); transient_key? " (transient-key)":"");
d = gen_k (E.n, random_level);
/* Compute Q. */ /* Compute Q. */
point_init (&Q); point_init (&Q);
@ -962,6 +966,7 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
gcry_mpi_t g_x, g_y, q_x, q_y; gcry_mpi_t g_x, g_y, q_x, q_y;
char *curve_name = NULL; char *curve_name = NULL;
gcry_sexp_t l1; gcry_sexp_t l1;
int transient_key = 0;
(void)algo; (void)algo;
(void)evalue; (void)evalue;
@ -978,6 +983,14 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
if (!curve_name) if (!curve_name)
return GPG_ERR_INV_OBJ; /* No curve name or value too large. */ return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
} }
/* Parse the optional transient-key flag. */
l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
if (l1)
{
transient_key = 1;
gcry_sexp_release (l1);
}
} }
/* NBITS is required if no curve name has been given. */ /* NBITS is required if no curve name has been given. */
@ -988,7 +1001,7 @@ ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
g_y = mpi_new (0); g_y = mpi_new (0);
q_x = mpi_new (0); q_x = mpi_new (0);
q_y = mpi_new (0); q_y = mpi_new (0);
ec = generate_key (&sk, nbits, curve_name, g_x, g_y, q_x, q_y); ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y);
gcry_free (curve_name); gcry_free (curve_name);
if (ec) if (ec)
return ec; return ec;
@ -1266,7 +1279,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
} }
/* Check that all parameters are known and normalize all MPIs (that /* Check that all parameters are known and normalize all MPIs (that
should not be required but we use an internal fucntion later and should not be required but we use an internal function later and
thus we better make 100% sure that they are normalized). */ thus we better make 100% sure that they are normalized). */
for (idx = 0; idx < 6; idx++) for (idx = 0; idx < 6; idx++)
if (!values[idx]) if (!values[idx])

View file

@ -87,6 +87,10 @@ static struct digest_table_entry
#if USE_TIGER #if USE_TIGER
{ &_gcry_digest_spec_tiger, { &_gcry_digest_spec_tiger,
&dummy_extra_spec, GCRY_MD_TIGER }, &dummy_extra_spec, GCRY_MD_TIGER },
{ &_gcry_digest_spec_tiger1,
&dummy_extra_spec, GCRY_MD_TIGER1 },
{ &_gcry_digest_spec_tiger2,
&dummy_extra_spec, GCRY_MD_TIGER2 },
#endif #endif
#if USE_WHIRLPOOL #if USE_WHIRLPOOL
{ &_gcry_digest_spec_whirlpool, { &_gcry_digest_spec_whirlpool,
@ -101,7 +105,7 @@ static gcry_module_t digests_registered;
/* This is the lock protecting DIGESTS_REGISTERED. */ /* This is the lock protecting DIGESTS_REGISTERED. */
static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER; static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;
/* Flag to check wether the default ciphers have already been /* Flag to check whether the default ciphers have already been
registered. */ registered. */
static int default_digests_registered; static int default_digests_registered;
@ -948,10 +952,13 @@ md_read( gcry_md_hd_t a, int algo )
if (! algo) if (! algo)
{ {
/* return the first algorithm */ /* Return the first algorithm */
if (r && r->next) if (r)
log_debug ("more than one algorithm in md_read(0)\n"); {
return r->digest->read( &r->context.c ); if (r->next)
log_debug ("more than one algorithm in md_read(0)\n");
return r->digest->read (&r->context.c);
}
} }
else else
{ {
@ -1135,7 +1142,7 @@ md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
* Note: Because this function is in most cases used to return an * Note: Because this function is in most cases used to return an
* integer value, we can make it easier for the caller to just look at * integer value, we can make it easier for the caller to just look at
* the return value. The caller will in all cases consult the value * the return value. The caller will in all cases consult the value
* and thereby detecting whether a error occured or not (i.e. while checking * and thereby detecting whether a error occurred or not (i.e. while checking
* the block size) * the block size)
*/ */
gcry_error_t gcry_error_t

View file

@ -53,7 +53,6 @@
#include <string.h> #include <string.h>
#include "g10lib.h" #include "g10lib.h"
#include "memory.h"
#include "cipher.h" #include "cipher.h"
#include "bithelp.h" #include "bithelp.h"

View file

@ -37,7 +37,6 @@
#include <string.h> #include <string.h>
#include "g10lib.h" #include "g10lib.h"
#include "memory.h"
#include "cipher.h" #include "cipher.h"
#include "bithelp.h" #include "bithelp.h"

View file

@ -988,7 +988,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count)
/* Given ARRAY of size N with M elements set to true produce a /* Given ARRAY of size N with M elements set to true produce a
modified array with the next permutation of M elements. Note, that modified array with the next permutation of M elements. Note, that
ARRAY is used in a one-bit-per-byte approach. To detected the last ARRAY is used in a one-bit-per-byte approach. To detected the last
permutation it is useful to intialize the array with the first M permutation it is useful to initialize the array with the first M
element set to true and use this test: element set to true and use this test:
m_out_of_n (array, m, n); m_out_of_n (array, m, n);
for (i = j = 0; i < n && j < m; i++) for (i = j = 0; i < n && j < m; i++)
@ -1170,7 +1170,7 @@ gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
return gcry_error (err); return gcry_error (err);
} }
/* Check wether the number X is prime. */ /* Check whether the number X is prime. */
gcry_error_t gcry_error_t
gcry_prime_check (gcry_mpi_t x, unsigned int flags) gcry_prime_check (gcry_mpi_t x, unsigned int flags)
{ {

View file

@ -85,7 +85,7 @@ static gcry_module_t pubkeys_registered;
/* This is the lock protecting PUBKEYS_REGISTERED. */ /* This is the lock protecting PUBKEYS_REGISTERED. */
static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;; static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
/* Flag to check wether the default pubkeys have already been /* Flag to check whether the default pubkeys have already been
registered. */ registered. */
static int default_pubkeys_registered; static int default_pubkeys_registered;
@ -1567,7 +1567,7 @@ sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
Do a PK encrypt operation Do a PK encrypt operation
Caller has to provide a public key as the SEXP pkey and data as a Caller has to provide a public key as the SEXP pkey and data as a
SEXP with just one MPI in it. Alternativly S_DATA might be a SEXP with just one MPI in it. Alternatively S_DATA might be a
complex S-Expression, similar to the one used for signature complex S-Expression, similar to the one used for signature
verification. This provides a flag which allows to handle PKCS#1 verification. This provides a flag which allows to handle PKCS#1
block type 2 padding. The function returns a a sexp which may be block type 2 padding. The function returns a a sexp which may be
@ -2357,7 +2357,7 @@ gcry_pk_get_nbits (gcry_sexp_t key)
/* Return the so called KEYGRIP which is the SHA-1 hash of the public /* Return the so called KEYGRIP which is the SHA-1 hash of the public
key parameters expressed in a way depended on the algorithm. key parameters expressed in a way depending on the algorithm.
ARRAY must either be 20 bytes long or NULL; in the latter case a ARRAY must either be 20 bytes long or NULL; in the latter case a
newly allocated array of that size is returned, otherwise ARRAY or newly allocated array of that size is returned, otherwise ARRAY or
@ -2503,15 +2503,15 @@ gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
care or a combination of the GCRY_PK_USAGE_xxx flags; care or a combination of the GCRY_PK_USAGE_xxx flags;
GCRYCTL_GET_ALGO_USAGE: GCRYCTL_GET_ALGO_USAGE:
Return the usage glafs for the give algo. An invalid alog Return the usage flags for the given algo. An invalid algo
does return 0. Disabled algos are ignored here becuase we returns 0. Disabled algos are ignored here because we
only want to know whether the algo is at all capable of only want to know whether the algo is at all capable of
the usage. the usage.
Note: Because this function is in most cases used to return an Note: Because this function is in most cases used to return an
integer value, we can make it easier for the caller to just look at integer value, we can make it easier for the caller to just look at
the return value. The caller will in all cases consult the value the return value. The caller will in all cases consult the value
and thereby detecting whether a error occured or not (i.e. while and thereby detecting whether a error occurred or not (i.e. while
checking the block size) */ checking the block size) */
gcry_error_t gcry_error_t
gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes) gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)

View file

@ -22,7 +22,7 @@
/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS /* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
* as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
* direct use by Libgcrypt by Werner Koch. This implementation is * direct use by Libgcrypt by Werner Koch. This implementation is
* only useful for pkcs#12 descryption. * only useful for pkcs#12 decryption.
* *
* The implementation here is based on Peter Gutmann's RRC.2 paper. * The implementation here is based on Peter Gutmann's RRC.2 paper.
*/ */

View file

@ -24,7 +24,6 @@
#include <string.h> #include <string.h>
#include "g10lib.h" #include "g10lib.h"
#include "memory.h"
#include "rmd.h" #include "rmd.h"
#include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */ #include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */

View file

@ -444,18 +444,28 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
else else
{ {
/* Parameters to derive the key are given. */ /* Parameters to derive the key are given. */
/* Note that we explicitly need to setup the values of tbl
because some compilers (e.g. OpenWatcom, IRIX) don't allow
to initialize a structure with automatic variables. */
struct { const char *name; gcry_mpi_t *value; } tbl[] = { struct { const char *name; gcry_mpi_t *value; } tbl[] = {
{ "Xp1", &xp1 }, { "Xp1" },
{ "Xp2", &xp2 }, { "Xp2" },
{ "Xp", &xp }, { "Xp" },
{ "Xq1", &xq1 }, { "Xq1" },
{ "Xq2", &xq2 }, { "Xq2" },
{ "Xq", &xq }, { "Xq" },
{ NULL, NULL } { NULL }
}; };
int idx; int idx;
gcry_sexp_t oneparm; gcry_sexp_t oneparm;
tbl[0].value = &xp1;
tbl[1].value = &xp2;
tbl[2].value = &xp;
tbl[3].value = &xq1;
tbl[4].value = &xq2;
tbl[5].value = &xq;
for (idx=0; tbl[idx].name; idx++) for (idx=0; tbl[idx].name; idx++)
{ {
oneparm = gcry_sexp_find_token (deriveparms, tbl[idx].name, 0); oneparm = gcry_sexp_find_token (deriveparms, tbl[idx].name, 0);
@ -572,7 +582,7 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
/**************** /****************
* Test wether the secret key is valid. * Test whether the secret key is valid.
* Returns: true if this is a valid key. * Returns: true if this is a valid key.
*/ */
static int static int
@ -876,7 +886,7 @@ rsa_check_secret_key (int algo, gcry_mpi_t *skey)
err = GPG_ERR_NO_OBJ; /* To check the key we need the optional err = GPG_ERR_NO_OBJ; /* To check the key we need the optional
parameters. */ parameters. */
else if (!check_secret_key (&sk)) else if (!check_secret_key (&sk))
err = GPG_ERR_PUBKEY_ALGO; err = GPG_ERR_BAD_SECKEY;
return err; return err;
} }
@ -942,7 +952,7 @@ rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
gcry_mpi_mod (r, r, sk.n); gcry_mpi_mod (r, r, sk.n);
/* Calculate inverse of r. It practically impossible that the /* Calculate inverse of r. It practically impossible that the
follwing test fails, thus we do not add code to release following test fails, thus we do not add code to release
allocated resources. */ allocated resources. */
if (!gcry_mpi_invm (ri, r, sk.n)) if (!gcry_mpi_invm (ri, r, sk.n))
return GPG_ERR_INTERNAL; return GPG_ERR_INTERNAL;
@ -1053,7 +1063,7 @@ rsa_get_nbits (int algo, gcry_mpi_t *pkey)
(e #010001#)) (e #010001#))
PKCS-15 says that for RSA only the modulus should be hashed - PKCS-15 says that for RSA only the modulus should be hashed -
however, it is not clear wether this is meant to use the raw bytes however, it is not clear whether this is meant to use the raw bytes
(assuming this is an unsigned integer) or whether the DER required (assuming this is an unsigned integer) or whether the DER required
0 should be prefixed. We hash the raw bytes. */ 0 should be prefixed. We hash the raw bytes. */
static gpg_err_code_t static gpg_err_code_t

View file

@ -37,7 +37,6 @@
#endif #endif
#include "g10lib.h" #include "g10lib.h"
#include "memory.h"
#include "bithelp.h" #include "bithelp.h"
#include "cipher.h" #include "cipher.h"
#include "hash-common.h" #include "hash-common.h"

View file

@ -1,5 +1,5 @@
/* sha256.c - SHA256 hash function /* sha256.c - SHA256 hash function
* Copyright (C) 2003, 2006, 2008 Free Software Foundation, Inc. * Copyright (C) 2003, 2006, 2008, 2009 Free Software Foundation, Inc.
* *
* This file is part of Libgcrypt. * This file is part of Libgcrypt.
* *
@ -41,7 +41,6 @@
#include <string.h> #include <string.h>
#include "g10lib.h" #include "g10lib.h"
#include "memory.h"
#include "bithelp.h" #include "bithelp.h"
#include "cipher.h" #include "cipher.h"
#include "hash-common.h" #include "hash-common.h"
@ -95,10 +94,6 @@ sha224_init (void *context)
/* /*
Transform the message X which consists of 16 32-bit-words. See FIPS Transform the message X which consists of 16 32-bit-words. See FIPS
180-2 for details. */ 180-2 for details. */
#define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */
#define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */
#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */
#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */
#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */ #define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */ #define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
#define R(a,b,c,d,e,f,g,h,k,w) do \ #define R(a,b,c,d,e,f,g,h,k,w) do \
@ -114,6 +109,35 @@ sha224_init (void *context)
b = a; \ b = a; \
a = t1 + t2; \ a = t1 + t2; \
} while (0) } while (0)
/* (4.2) same as SHA-1's F1. */
static inline u32
Cho (u32 x, u32 y, u32 z)
{
return (z ^ (x & (y ^ z)));
}
/* (4.3) same as SHA-1's F3 */
static inline u32
Maj (u32 x, u32 y, u32 z)
{
return ((x & y) | (z & (x|y)));
}
/* (4.4) */
static inline u32
Sum0 (u32 x)
{
return (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22));
}
/* (4.5) */
static inline u32
Sum1 (u32 x)
{
return (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25));
}
static void static void
transform (SHA256_CONTEXT *hd, const unsigned char *data) transform (SHA256_CONTEXT *hd, const unsigned char *data)
@ -172,8 +196,55 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data)
for (; i < 64; i++) for (; i < 64; i++)
w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16]; w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
for (i=0; i < 64; i++) for (i=0; i < 64;)
R(a,b,c,d,e,f,g,h,K[i],w[i]); {
#if 0
R(a,b,c,d,e,f,g,h,K[i],w[i]);
i++;
#else
t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i];
t2 = Sum0 (a) + Maj (a, b, c);
d += t1;
h = t1 + t2;
t1 = g + Sum1 (d) + Cho (d, e, f) + K[i+1] + w[i+1];
t2 = Sum0 (h) + Maj (h, a, b);
c += t1;
g = t1 + t2;
t1 = f + Sum1 (c) + Cho (c, d, e) + K[i+2] + w[i+2];
t2 = Sum0 (g) + Maj (g, h, a);
b += t1;
f = t1 + t2;
t1 = e + Sum1 (b) + Cho (b, c, d) + K[i+3] + w[i+3];
t2 = Sum0 (f) + Maj (f, g, h);
a += t1;
e = t1 + t2;
t1 = d + Sum1 (a) + Cho (a, b, c) + K[i+4] + w[i+4];
t2 = Sum0 (e) + Maj (e, f, g);
h += t1;
d = t1 + t2;
t1 = c + Sum1 (h) + Cho (h, a, b) + K[i+5] + w[i+5];
t2 = Sum0 (d) + Maj (d, e, f);
g += t1;
c = t1 + t2;
t1 = b + Sum1 (g) + Cho (g, h, a) + K[i+6] + w[i+6];
t2 = Sum0 (c) + Maj (c, d, e);
f += t1;
b = t1 + t2;
t1 = a + Sum1 (f) + Cho (f, g, h) + K[i+7] + w[i+7];
t2 = Sum0 (b) + Maj (b, c, d);
e += t1;
a = t1 + t2;
i += 8;
#endif
}
hd->h0 += a; hd->h0 += a;
hd->h1 += b; hd->h1 += b;
@ -184,10 +255,6 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data)
hd->h6 += g; hd->h6 += g;
hd->h7 += h; hd->h7 += h;
} }
#undef Cho
#undef Maj
#undef Sum0
#undef Sum1
#undef S0 #undef S0
#undef S1 #undef S1
#undef R #undef R

View file

@ -1,5 +1,5 @@
/* sha512.c - SHA384 and SHA512 hash functions /* sha512.c - SHA384 and SHA512 hash functions
* Copyright (C) 2003, 2008 Free Software Foundation, Inc. * Copyright (C) 2003, 2008, 2009 Free Software Foundation, Inc.
* *
* This file is part of Libgcrypt. * This file is part of Libgcrypt.
* *
@ -98,6 +98,36 @@ sha384_init (void *context)
} }
static inline u64
ROTR (u64 x, u64 n)
{
return ((x >> n) | (x << (64 - n)));
}
static inline u64
Ch (u64 x, u64 y, u64 z)
{
return ((x & y) ^ ( ~x & z));
}
static inline u64
Maj (u64 x, u64 y, u64 z)
{
return ((x & y) ^ (x & z) ^ (y & z));
}
static inline u64
Sum0 (u64 x)
{
return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39));
}
static inline u64
Sum1 (u64 x)
{
return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41));
}
/**************** /****************
* Transform the message W which consists of 16 64-bit-words * Transform the message W which consists of 16 64-bit-words
*/ */
@ -182,21 +212,26 @@ transform (SHA512_CONTEXT *hd, const unsigned char *data)
} }
#endif #endif
#define ROTR(x,n) (((x)>>(n)) | ((x)<<(64-(n))))
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define Sum0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
#define Sum1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41))
#define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
#define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
for (t = 16; t < 80; t++) for (t = 16; t < 80; t++)
w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16]; w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16];
for (t = 0; t < 80; t++)
for (t = 0; t < 80; )
{ {
u64 t1, t2; u64 t1, t2;
/* Performance on a AMD Athlon(tm) Dual Core Processor 4050e
with gcc 4.3.3 using gcry_md_hash_buffer of each 10000 bytes
initialized to 0,1,2,3...255,0,... and 1000 iterations:
Not unrolled with macros: 440ms
Unrolled with macros: 350ms
Unrolled with inline: 330ms
*/
#if 0 /* Not unrolled. */
t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
t2 = Sum0 (a) + Maj (a, b, c); t2 = Sum0 (a) + Maj (a, b, c);
h = g; h = g;
@ -207,12 +242,53 @@ transform (SHA512_CONTEXT *hd, const unsigned char *data)
c = b; c = b;
b = a; b = a;
a = t1 + t2; a = t1 + t2;
t++;
#else /* Unrolled to interweave the chain variables. */
t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
t2 = Sum0 (a) + Maj (a, b, c);
d += t1;
h = t1 + t2;
/* printf("t=%d a=%016llX b=%016llX c=%016llX d=%016llX " t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[t+1];
"e=%016llX f=%016llX g=%016llX h=%016llX\n",t,a,b,c,d,e,f,g,h); */ t2 = Sum0 (h) + Maj (h, a, b);
c += t1;
g = t1 + t2;
t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[t+2];
t2 = Sum0 (g) + Maj (g, h, a);
b += t1;
f = t1 + t2;
t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[t+3];
t2 = Sum0 (f) + Maj (f, g, h);
a += t1;
e = t1 + t2;
t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[t+4];
t2 = Sum0 (e) + Maj (e, f, g);
h += t1;
d = t1 + t2;
t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[t+5];
t2 = Sum0 (d) + Maj (d, e, f);
g += t1;
c = t1 + t2;
t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[t+6];
t2 = Sum0 (c) + Maj (c, d, e);
f += t1;
b = t1 + t2;
t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[t+7];
t2 = Sum0 (b) + Maj (b, c, d);
e += t1;
a = t1 + t2;
t += 8;
#endif
} }
/* update chaining vars */ /* Update chaining vars. */
hd->h0 += a; hd->h0 += a;
hd->h1 += b; hd->h1 += b;
hd->h2 += c; hd->h2 += c;

View file

@ -0,0 +1,105 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>
int
main (int argc, char **argv)
{
struct rusage buf;
if (argc > 1)
{
system (argv[1]);
if (getrusage (RUSAGE_CHILDREN, &buf ))
{
perror ("getrusage");
return 1;
}
}
else
{
if (getrusage (RUSAGE_SELF, &buf ))
{
perror ("getrusage");
return 1;
}
}
printf ("ru_utime = %ld.%06ld\n",
buf.ru_utime.tv_sec, buf.ru_utime.tv_usec);
printf ("ru_stime = %ld.%06ld\n",
buf.ru_stime.tv_sec, buf.ru_stime.tv_usec);
printf ("ru_maxrss = %ld\n", buf.ru_maxrss );
printf ("ru_ixrss = %ld\n", buf.ru_ixrss );
printf ("ru_idrss = %ld\n", buf.ru_idrss );
printf ("ru_isrss = %ld\n", buf.ru_isrss );
printf ("ru_minflt = %ld\n", buf.ru_minflt );
printf ("ru_majflt = %ld\n", buf.ru_majflt );
printf ("ru_nswap = %ld\n", buf.ru_nswap );
printf ("ru_inblock = %ld\n", buf.ru_inblock );
printf ("ru_oublock = %ld\n", buf.ru_oublock );
printf ("ru_msgsnd = %ld\n", buf.ru_msgsnd );
printf ("ru_msgrcv = %ld\n", buf.ru_msgrcv );
printf ("ru_nsignals= %ld\n", buf.ru_nsignals );
printf ("ru_nvcsw = %ld\n", buf.ru_nvcsw );
printf ("ru_nivcsw = %ld\n", buf.ru_nivcsw );
fprintf (stderr, "ru_utime ru_stime ru_minflt ru_nccsw ru_nivcsw\n");
fprintf (stderr, "%ld.%06ld %ld.%06ld %5ld %5ld %5ld\n");
return 0;
}
/* Codesnippet for debugging in random.c. */
#if 0
static void
collect_rusage_stats (struct rusage *rb)
{
static int idx;
static struct rusage buf[100];
if (!rb)
{
int i;
fprintf (stderr, "ru_utime ru_stime ru_minflt ru_nvcsw ru_nivcsw\n");
for (i=0; i < idx; i++)
fprintf (stderr, "%ld.%06ld %ld.%06ld %5ld %5ld %5ld\n",
buf[i].ru_utime.tv_sec, buf[i].ru_utime.tv_usec,
buf[i].ru_stime.tv_sec, buf[i].ru_stime.tv_usec,
buf[i].ru_minflt,
buf[i].ru_nvcsw,
buf[i].ru_nivcsw);
}
else if (idx < DIM(buf))
{
buf[idx++] = *rb;
}
}
#endif
/*
void
_gcry_random_dump_stats()
{
@@ -233,8 +261,11 @@
rndstats.naddbytes, rndstats.addbytes,
rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1,
rndstats.ngetbytes2, rndstats.getbytes2 );
+
+ collect_rusage_stats (NULL);
}
========
getrusage (RUSAGE_SELF, &buf );
+ collect_rusage_stats (&buf);
add_randomness( &buf, sizeof buf, 1 );
memset( &buf, 0, sizeof buf );
}
*/

View file

@ -1,5 +1,5 @@
/* tiger.c - The TIGER hash function /* tiger.c - The TIGER hash function
* Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc. * Copyright (C) 1998, 2001, 2002, 2003, 2010 Free Software Foundation, Inc.
* *
* This file is part of Libgcrypt. * This file is part of Libgcrypt.
* *
@ -18,25 +18,26 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/ */
/* See http://www.cs.technion.ac.il/~biham/Reports/Tiger/ */
#include <config.h> #include <config.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "g10lib.h" #include "g10lib.h"
#include "memory.h"
#include "cipher.h" #include "cipher.h"
/* We really need a 64 bit type for this code. */
#ifdef HAVE_U64_TYPEDEF #ifdef HAVE_U64_TYPEDEF
/* we really need it here, but as this is only experiment we typedef struct
* can live without Tiger */ {
u64 a, b, c;
typedef struct { byte buf[64];
u64 a, b, c; int count;
byte buf[64]; u32 nblocks;
int count; int variant; /* 0 = old code, 1 = fixed code, 2 - TIGER2. */
u32 nblocks;
} TIGER_CONTEXT; } TIGER_CONTEXT;
@ -588,7 +589,7 @@ static u64 sbox4[256] = {
}; };
static void static void
tiger_init( void *context ) do_init (void *context, int variant)
{ {
TIGER_CONTEXT *hd = context; TIGER_CONTEXT *hd = context;
@ -597,6 +598,25 @@ tiger_init( void *context )
hd->c = 0xf096a5b4c3b2e187LL; hd->c = 0xf096a5b4c3b2e187LL;
hd->nblocks = 0; hd->nblocks = 0;
hd->count = 0; hd->count = 0;
hd->variant = variant;
}
static void
tiger_init (void *context)
{
do_init (context, 0);
}
static void
tiger1_init (void *context)
{
do_init (context, 1);
}
static void
tiger2_init (void *context)
{
do_init (context, 2);
} }
static void static void
@ -763,6 +783,7 @@ tiger_final( void *context )
TIGER_CONTEXT *hd = context; TIGER_CONTEXT *hd = context;
u32 t, msb, lsb; u32 t, msb, lsb;
byte *p; byte *p;
byte pad = hd->variant == 2? 0x80 : 0x01;
tiger_write(hd, NULL, 0); /* flush */; tiger_write(hd, NULL, 0); /* flush */;
@ -782,13 +803,13 @@ tiger_final( void *context )
if( hd->count < 56 ) /* enough room */ if( hd->count < 56 ) /* enough room */
{ {
hd->buf[hd->count++] = 0x01; /* pad */ hd->buf[hd->count++] = pad;
while( hd->count < 56 ) while( hd->count < 56 )
hd->buf[hd->count++] = 0; /* pad */ hd->buf[hd->count++] = 0; /* pad */
} }
else /* need one extra block */ else /* need one extra block */
{ {
hd->buf[hd->count++] = 0x01; /* pad character */ hd->buf[hd->count++] = pad; /* pad character */
while( hd->count < 64 ) while( hd->count < 64 )
hd->buf[hd->count++] = 0; hd->buf[hd->count++] = 0;
tiger_write(hd, NULL, 0); /* flush */; tiger_write(hd, NULL, 0); /* flush */;
@ -815,10 +836,24 @@ tiger_final( void *context )
*p++ = hd->a >> 24; *p++ = hd->a >> 16; \ *p++ = hd->a >> 24; *p++ = hd->a >> 16; \
*p++ = hd->a >> 8; *p++ = hd->a; } while(0) *p++ = hd->a >> 8; *p++ = hd->a; } while(0)
#endif #endif
X(a); #define Y(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
X(b); *p++ = hd->a >> 16; *p++ = hd->a >> 24; \
X(c); *p++ = hd->a >> 32; *p++ = hd->a >> 40; \
*p++ = hd->a >> 48; *p++ = hd->a >> 56; } while(0)
if (hd->variant == 0)
{
X(a);
X(b);
X(c);
}
else
{
Y(a);
Y(b);
Y(c);
}
#undef X #undef X
#undef Y
} }
static byte * static byte *
@ -829,22 +864,47 @@ tiger_read( void *context )
return hd->buf; return hd->buf;
} }
static byte asn[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
/* This is the old TIGER variant based on the unfixed reference
implementation. IT was used in GnupG up to 1.3.2. We don't provide
an OID anymore because that would not be correct. */
gcry_md_spec_t _gcry_digest_spec_tiger =
{
"TIGER192", NULL, 0, NULL, 24,
tiger_init, tiger_write, tiger_final, tiger_read,
sizeof (TIGER_CONTEXT)
};
/* This is the fixed TIGER implementation. */
static byte asn1[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
{ 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06, { 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06,
0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02,
0x05, 0x00, 0x04, 0x18 }; 0x05, 0x00, 0x04, 0x18 };
static gcry_md_oid_spec_t oid_spec_tiger[] = static gcry_md_oid_spec_t oid_spec_tiger1[] =
{ {
/* GNU.digestAlgorithm TIGER */ /* GNU.digestAlgorithm TIGER */
{ "1.3.6.1.4.1.11591.12.2" }, { "1.3.6.1.4.1.11591.12.2" },
{ NULL } { NULL }
}; };
gcry_md_spec_t _gcry_digest_spec_tiger = gcry_md_spec_t _gcry_digest_spec_tiger1 =
{ {
"TIGER192", asn, DIM (asn), oid_spec_tiger, 24, "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24,
tiger_init, tiger_write, tiger_final, tiger_read, tiger1_init, tiger_write, tiger_final, tiger_read,
sizeof (TIGER_CONTEXT)
};
/* This is TIGER2 which usues a changed padding algorithm. */
gcry_md_spec_t _gcry_digest_spec_tiger2 =
{
"TIGER2", NULL, 0, NULL, 24,
tiger2_init, tiger_write, tiger_final, tiger_read,
sizeof (TIGER_CONTEXT) sizeof (TIGER_CONTEXT)
}; };

View file

@ -522,7 +522,7 @@ static byte calc_sb_tbl[512] = {
* preprocessed through q0 and q1 respectively; for longer keys they are the * preprocessed through q0 and q1 respectively; for longer keys they are the
* output of previous stages. j is the index of the first key byte to use. * output of previous stages. j is the index of the first key byte to use.
* CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2 * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
* twice, doing the Psuedo-Hadamard Transform, and doing the necessary * twice, doing the Pseudo-Hadamard Transform, and doing the necessary
* rotations. Its parameters are: a, the array to write the results into, * rotations. Its parameters are: a, the array to write the results into,
* j, the index of the first output entry, k and l, the preprocessed indices * j, the index of the first output entry, k and l, the preprocessed indices
* for index 2i, and m and n, the preprocessed indices for index 2i+1. * for index 2i, and m and n, the preprocessed indices for index 2i+1.

View file

@ -36,7 +36,6 @@
#include "types.h" #include "types.h"
#include "g10lib.h" #include "g10lib.h"
#include "memory.h"
#include "cipher.h" #include "cipher.h"
#include "bithelp.h" #include "bithelp.h"

View file

@ -0,0 +1,831 @@
2011-12-01 Werner Koch <wk@g10code.com>
NB: ChangeLog files are no longer manually maintained. Starting
on December 1st, 2011 we put change information only in the GIT
commit log, and generate a top-level ChangeLog file from logs at
"make dist". See doc/HACKING for details.
2011-07-04 Werner Koch <wk@g10code.com>
* longlong.h (add_ssaaaa) [__arm__]: Do no use asm if thumb code
generation is enabled. This is bug#1202. Reported for gpg 1.4.
2011-03-28 Werner Koch <wk@g10code.com>
* mpi-pow.c (gcry_mpi_powm): Remove unused var RSEC.
2011-02-01 Werner Koch <wk@g10code.com>
* mpi-cmp.c (gcry_mpi_cmp): Allow comparing of opaque MPIs.
2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
Spelling fixes.
2010-02-22 Aurelien Jarno <aurel32@debian.org> (wk)
* longlong.h (umul_ppmm) <mips> [__GNUC__ >= 4.4]: Patch according
to recommended gcc 4.4 changes.
2009-12-09 Werner Koch <wk@g10code.com>
* config.links: Remove asm modules for all sparc64. This is
debian#560028.
2009-05-26 Werner Koch <wk@g10code.com>
* mpicoder.c (mpi_read_from_buffer): Allow zero-sized MPIs (i.e a
zero).
2009-02-16 Werner Koch <wk@g10code.com>
* mpiutil.c: Remove memory.h.
2008-12-05 Werner Koch <wk@g10code.com>
* mpicoder.c (mpi_read_from_buffer): Do not bail out if the mpi is
larger than the buffer (potential problem). Do not print error
messages.
(mpi_fromstr): Return an error instead of hitting an assert.
(gcry_mpi_scan) <PGP>: Fix potential double free problem.
(gcry_mpi_scan) <HEX>: Fix potential memory leak.
(do_get_buffer): Return NULL on memory allocation failure.
(gcry_mpi_print): Check result of do_get_buffer.
(gcry_mpi_aprint): Return error on a memory allocation failure.
* mpicoder.c: Re-indent.
2008-12-03 Werner Koch <wk@g10code.com>
* mpi-pow.c (gcry_mpi_powm): Fix last change. Asserts are really
useful!
2008-12-02 Werner Koch <wk@g10code.com>
* mpi-pow.c (gcry_mpi_powm): Re-indent.
(gcry_mpi_powm): Simplified allocation of the result to fix a
double free bug. This is bug#977. Reported by Haakon Ringberg.
2008-08-20 Werner Koch <wk@g10code.com>
* mpi-bit.c (gcry_mpi_lshift): Actually implement.
2008-08-19 Werner Koch <wk@g10code.com>
* mpi-bit.c (gcry_mpi_lshift): New.
2007-10-31 Werner Koch <wk@g10code.com>
* mpi-mod.c (gcry_mpi_mod): Remove
* mpi-inv.c (_gcry_mpi_invm): Remove _ prefix.
* mpiutil.c (_gcry_mpi_swap): Remove.
(_gcry_mpi_new): Remove.
(_gcry_mpi_snew): Remove.
(gcry_mpi_invm): Remove.
(gcry_mpi_copy): Remove and rename _version to this.
(gcry_mpi_set, gcry_mpi_set_ui): Merge with _ version.
* mpi-inv.c (gcry_mpi_invm): Remove _ prefix and return 1.
* mpi-mul.c (gcry_mpi_mul_2exp): Remove and rename _ version to this.
2007-10-29 Werner Koch <wk@g10code.com>
* config.links: No Candadian Cross here, thus use $host instead of
$target.
2007-10-26 Werner Koch <wk@g10code.com>
* config.links (mpi_optional_modules): Special rules for Apple
Darwin on ia32 from Gregor Riepl.
2007-05-09 Marcus Brinkmann <marcus@g10code.de>
* config.links: Rename assembler file links by suffixing "-asm".
* Makefile.am (CCASCOMPILE, LTCCASCOMPILE, CLEANFILES,
libmpi_la_LIBADD, libmpi_la_DEPENDENCIES, SUFFIXES, .S.o, .S.obj,
.S.lo): Removed variables and targets.
(mpih_add1, mpih_sub1, mpih_mul1, mpih_mul2, mpih_mul3,
mpih_lshift, mpih_rshift, mpih_udiv, mpih_udiv_qrnnd,
nodist_libmpi_la_SOURCES): New variables.
(DISTCLEANFILES): Rename assembler file links by suffixing "-asm".
Add variants for C file links.
2007-05-04 Werner Koch <wk@g10code.com>
* config.links (path): Allowthe sue of colons as delimiters.
2007-05-03 Werner Koch <wk@g10code.com>
* pentium4/distfiles: Fixed.
2007-04-30 Werner Koch <wk@g10code.com>
* config.links: Create a file mod-source-info.h.
* Makefile.am (DISTCLEANFILES): Add that file.
* mpiutil.c (_gcry_mpi_get_hw_config): New.
2007-04-28 Marcus Brinkmann <marcus@g10code.de>
* config.links: Add additional assembler search directories.
2007-03-28 Werner Koch <wk@g10code.com>
* ec.c: New.
2007-03-23 Werner Koch <wk@g10code.com>
* mpi-bit.c (_gcry_mpi_lshift_limbs): Assign AP after the resize.
* mpi-div.c (gcry_mpi_mod, _gcry_mpi_mod): Moved to ..
* mpi-mod.c: .. new file.
(_gcry_mpi_barrett_init, _gcry_mpi_barrett_free): New.
(_gcry_mpi_mod_barrett): New.
(_gcry_mpi_mul_barrett): New.
2007-03-22 Werner Koch <wk@g10code.com>
* mpi-div.c (_gcry_mpi_mod): New.
* mpiutil.c (_gcry_mpi_new, _gcry_mpi_snew): New.
2007-03-13 Werner Dittmann <Werner.Dittmann@t-online.de> (wk)
* amd64/mpih-add1.S, amd64/mpih-add1.S, amd64/mpih-lshift.S
* amd64/mpih-mul1.S, amd64/mpih-mul2.S, amd64/mpih-mul3.S
* amd64/mpih-rshift.S, amd64/mpih-sub1.S: New.
* config.links: Add case for x86_64.
2007-02-23 Werner Koch <wk@g10code.com>
* mpi-pow.c (gcry_mpi_powm): Remove unused var ESIGN.
* mpiutil.c (gcry_mpi_get_flag): Let it return a value to silent
MIPSpro cc warning.
2007-02-21 Werner Koch <wk@g10code.com>
* mpicoder.c (_gcry_mpi_set_buffer): Made BUFFER a void*.
2006-11-15 Werner Koch <wk@g10code.com>
* Makefile.am (.S.o): Check for srcdir also in in CPP pass.
(INCLUDES): Removed.
(AM_CPPFLAGS, AM_CFLAGS): New, modified. Merged with Moritz'
changes.
2006-11-05 Moritz Schulte <moritz@g10code.com>
* Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the
new gcrypt.h is used, not the one installed in the system.
2006-10-23 Werner Koch <wk@g10code.com>
* config.links (mpi_optional_modules): Make sure that powerpc64 is
matched before a generic powerpc. Reported by Andreas Metzler.
Should fix Debian bug 284609.
2006-08-25 Werner Koch <wk@g10code.com>
* mpi-bit.c (gcry_mpi_rshift): Don't shift if N == 0 but do a
plain copy.
2006-08-04 Werner Koch <wk@g10code.com>
* mpi-bit.c (gcry_mpi_rshift): Rewritten to remove the limitation
on N (which used to be less than BITS_PER_MPI_LIMB).
2006-08-03 Werner Koch <wk@g10code.com>
* mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit): Fixed
allocation. Reported by bpgcrypt at itaparica.org.
* mpiutil.c (_gcry_mpi_resize): Clear the new part of the resized
limb space.
2006-07-26 Werner Koch <wk@g10code.com>
* mpiutil.c (gcry_mpi_randomize): Changed P to unsigned char*.
* mpicoder.c (gcry_mpi_scan): Changed arg BUFFER to void*.
(mpi_read_from_buffer): Made BUFFER arg const.
(gcry_mpi_scan): Removed now needless cast. Add cast for arg to
mpi_fromstr.
(gcry_mpi_print): Made TMP unsigned.
* Makefile.am (AM_CCASFLAGS): New.
2005-10-09 Moritz Schulte <moritz@g10code.com>
* mpi-cmp.c (gcry_mpi_cmp_ui): Rewritten; correctly handle case of
zero limbs in U.
2005-04-27 Moritz Schulte <moritz@g10code.com>
* mpiutil.c (gcry_mpi_randomize): Store random data in secure
memory if the given MPI is secure - not the other way around (argl).
2005-04-23 Moritz Schulte <moritz@g10code.com>
* Makefile.am: Don't assume the compiler will pre-process the .S
files. Some compilers, like those from HP and IBM, don't do
this. So, we use the same solution gnupg-1.4.0 does. Preprocess
first and then compile.
* hppa1.1/mpih-mul3.S: Add "level 1.1" directive to disable
warning about using PA-RISC1.1 opcodes.
* hppa1.1/mpih-mul2.S: Likewise.
* hppa1.1/mpih-mul1.S: Likewise.
* hppa1.1/udiv-qrnnd.S: Likewise.
2005-02-16 Moritz Schulte <moritz@g10code.com>
* mpiutil.c (_gcry_mpi_alloc_limb_space): Rewritten, fixed memory
corruption.
2005-02-06 Moritz Schulte <moritz@g10code.com>
* mpiutil.c (_gcry_mpi_get_ui, gcry_mpi_get_ui): New functions.
2005-01-05 Werner Koch <wk@g10code.com>
* hppa1.1/udiv-qrnnd.S: Reverted change of 2004-03-02 but kept the
.align directive.
2004-12-16 Werner Koch <wk@g10code.com>
* config.links (mpi_optional_modules): Move entry for powerpc64
before generic powerpc. Suggested by Rafael Ávila de Espíndola.
2004-03-02 Werner Koch <wk@gnupg.org>
* hppa1.1/udiv-qrnnd.S: Alignment fix from Lamont Jones for
Debian. Taken from gnupg-1.3.
* longlong.h: Added PowerPC 64 bit code from GPM-4.1.2 but didn't
enable it yet. Some whitespace changes in HPPA to fix assembler
problems on HP-UX. From gnupg 1.3
* mpiutil.c (_gcry_mpi_alloc_limb_space): Better allocate
something even if NLIMBS is passed as 0.
* config.links: Updated system list to match gnupg 1.3.
2003-12-19 Werner Koch <wk@gnupg.org>
* mpi-internal.h [M_DEBUG]: Removed this unused code.
(struct karatsuba_ctx): Added TSPACE_NLIMBS and TP_NLIMBS.
* mpiutil.c (_gcry_mpi_free_limb_space): Add arg NLIMBS and wipe
out the memory. Changed all callers.
* mpih-mul.c (_gcry_mpih_mul_karatsuba_case): Keep track of
allocated limbs.
* mpi-div.c (_gcry_mpi_tdiv_qr): Keep track of allocated limbs.
* mpi-mul.c (gcry_mpi_mul): Ditto.
* mpi-pow.c (gcry_mpi_powm): Ditto.
* Manifest: Empty new file. Also add Manifest files to all CPU
specific directories.
* Makefile.am: Added.
* mpiutil.c (gcry_mpi_randomize): Use gcry_create_nonce if WEAK
random has been requested.
2003-10-31 Werner Koch <wk@gnupg.org>
* i386/mpih-rshift.S, i386/mpih-lshift.S: Use %dl and not %edx for
testb; this avoids an assembler warning.
* mpi-pow.c (gcry_mpi_powm): s/exp/expo/ to avoid shadowing warning.
2003-08-19 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (SUFFIXES): New variable.
(.S.o, .S.lo, .S.obj): Rewritten.
2003-07-30 Moritz Schulte <moritz@g10code.com>
* longlong.h (__clz_tab): Renamed to _gcry_clz_tab.
* mpi-bit.c (__clz_tab): Likewise.
2003-07-27 Werner Koch <wk@gnupg.org>
* mpicoder.c (gcry_mpi_scan): New argument BUFLEN to replace the
use of the intial value of NBYTES. Changed BUFFER to unsigned.
(gcry_mpi_print): Likewise.
(gcry_mpi_dump): New.
(_gcry_log_mpidump): Make use of gcry_mpi_dump.
(mpi_print): Removed.
(gcry_mpi_scan): Allocated mpi in secure memory when required.
(gcry_mpi_aprint): Changed BUFFER to unsigned char*.
2003-07-14 Moritz Schulte <moritz@g10code.com>
* mpicoder.c: Used gcry_err* wrappers for libgpg-error symbols.
2003-06-16 Moritz Schulte <moritz@g10code.com>
* mpi-add.c: Replace last occurences of old type names with newer
names (i.e. replace MPI with gcry_mpi_t).
* mpi-bit.c: Likewise.
* mpi-cmp.c: Likewise.
* mpi-div.c: Likewise.
* mpi-gcd.c: Likewise.
* mpi-internal.h: Likewise.
* mpi-inv.c: Likewise.
* mpi-mpow.c: Likewise.
* mpi-mul.c: Likewise.
* mpi-pow.c: Likewise.
* mpi-scan.c: Likewise.
* mpicoder.c: Likewise.
* mpiutil.c: Likewise.
2003-06-09 Moritz Schulte <moritz@g10code.com>
* mpicoder.c (gcry_mpi_scan): Adjust for libgpg-error.
(gcry_mpi_print): Likewise.
(gcry_mpi_aprint): Likewise.
2003-06-07 Moritz Schulte <moritz@g10code.com>
* longlong.h, mpi-add.c, mpi-bit.c, mpi-cmp.c, mpi-div.c,
mpi-gcd.c, mpi-inline.c, mpi-inline.h, mpi-internal.h, mpi-inv.c,
mpi-mpow.c, mpi-mul.c, mpi-pow.c, mpi-scan.c, mpicoder.c,
mpih-div.c, mpih-mul.c, mpiutil.c, generic/mpi-asm-defs.h,
generic/mpih-add1.c, generic/mpih-lshift.c, generic/mpih-mul1.c,
generic/mpih-mul2.c, generic/mpih-mul3.c, generic/mpih-rshift.c,
generic/mpih-sub1.c, generic/udiv-w-sdiv.c, i386/syntax.h,
m68k/syntax.h, mips3/mpi-asm-defs.h, powerpc32/syntax.h: Edited
all preprocessor instructions to remove whitespace before the '#'.
This is not required by C89, but there are some compilers out
there that don't like it. Replaced any occurence of the now
deprecated type names with the new ones.
2003-05-21 Moritz Schulte <moritz@g10code.com>
* mpiutil.c (_gcry_mpi_alloc_limb_space): Only try to allocate
memory in case the amount of bytes to allocate is non-zero.
2003-04-27 Moritz Schulte <moritz@g10code.com>
* mpiutil.c (_gcry_mpi_resize): Allocate secure memory, in case
bit zero of `flags' is set.
* mpi-add.c (gcry_mpi_sub): Simplify function; always use a
temporary variable now.
2003-04-15 Werner Koch <wk@gnupg.org>
* longlong.h (umul_ppmm): Support SH3 and SH4. Thanks to
kazuya.s@jp.yokogawa.com.
2003-04-02 Werner Koch <wk@gnupg.org>
* mpicoder.c (gcry_mpi_print): Fixed testing against possible
uninitialized LEN. Valgrinded by Nikos Mavroyanopoulos.
2003-01-15 Werner Koch <wk@gnupg.org>
* longlong.h: Removed some spaces between backslashes and newlines.
2002-09-20 Werner Koch <wk@gnupg.org>
* mpi-mul.c (gcry_mpi_mul_2exp): New. This was declared in
gcrypt.h but only implemented as internal function. Noted by Timo
but a few minutes to late for today's release.
* Makefile.am (DISTCLEANFILES): Include mpi-asm-defs.h
2002-09-18 Werner Koch <wk@gnupg.org>
* Makefile.am (.S.lo): Pass -DPIC. i386, PPC and Sparc code
require it. It worked for me because I am using the i586 code.
2002-08-23 Werner Koch <wk@gnupg.org>
* Makefile.am (.S.lo): Fixed for libtool build with --disable-shared.
2002-07-24 Werner Koch <wk@gnupg.org>
* longlong.h: Replaced all K&R multiline strings by ISO ones for
the sake of modern compilers. Suggested by Marco Parrone.
2002-06-24 Werner Koch <wk@gnupg.org>
* mpiutil.c (gcry_mpi_swap): New.
* mpi-div.c (gcry_mpi_div): New.
(gcry_mpi_mod): New.
* mpi-inv.c (gcry_mpi_invm): New.
* mpicoder.c (do_get_buffer): Make sure that we allocate at least
one byte.
2002-06-12 Werner Koch <wk@gnupg.org>
* hppa1.1/udiv-qrnnd.S: Changes for PIC by Randolph Chung.
2002-05-15 Werner Koch <wk@gnupg.org>
* config.links: Chnage the way the mpi modules are determined.
* Makefile.am: Revamped to better handle modules
2002-05-14 Werner Koch <wk@gnupg.org>
Changed license of all files to the LGPL.
2002-04-18 Werner Koch <wk@gnupg.org>
* mpicoder.c (gcry_mpi_scan): Don't use normalize on a NULL MPI.
2002-03-20 Werner Koch <wk@gnupg.org>
* mpicoder.c (mpi_read_from_buffer): Bail out on a zero length
buffer because we can't eventually do an malloc of this size.
Reported by Timo.
2002-01-14 Werner Koch <wk@gnupg.org>
* mpi-inv.c (_gcry_mpi_invm): Typo fixes, noted by Carlo Perassi.
2001-11-01 Werner Koch <wk@gnupg.org>
* mpicoder.c (gcry_mpi_scan): Allow to pass a nbytes as NULL or
with value 0 for format GCRY_FMT_SSH, so that the length is not
used for any checks, only the length stored in the bufer is used.
This is a nice format becuase we can just pass a buffer around and
don't need to care about its length.
2001-08-03 Werner Koch <wk@gnupg.org>
* config.links: Changed the way the list of files to be
symlinked is returned.
2001-05-31 Werner Koch <wk@gnupg.org>
* mpih-cmp.c: Removed and moved mpihelp_cmp to ..
* mpi-inline.h: .. here.
Major function renaming. All global functions are now prefixed
with _gcry_ or gcry_. Renamed also all mpihelp_ to just mpih_ so
that functions names are not getting to long an unreadable and for
better matching with the filenames.
2001-05-28 Werner Koch <wk@gnupg.org>
* mpicoder.c (mpi_fromstr): Made static and assume that all input
is in hexformat.
Updated all CPU specific code with the one from GnuPG-1.0.5. This
is just a change of text formatting and the use of .label
instead of labels for hppa and pa7100.
* longlong.h: Fixes for ARM by Phil Blundell.
2001-03-29 Werner Koch <wk@gnupg.org>
* mpi-mul.c (mpi_mul): Make sure that secret temporary results are
not stored in w. Suggested by Florian Weimer.
* config.links: Use i386 code for i386. According to tests by
Kevin Ryde the i586 code runs slow on i386 CPUs. Ditto for i786.
2001-01-11 Werner Koch <wk@gnupg.org>
* Makefile.am: Removed mpi.h.
2000-12-19 Werner Koch <wk@gnupg.org>
* mpi-internal.h: Put limb_t definition in an ifdef.
Major change:
Removed all GnuPG stuff and renamed this piece of software
to gcrypt.
2000-11-14 Werner Koch <wk@gnupg.org>
* mpi-internal.h, mpi.h: Changed the way they are called and
introduced DID_MPI_LIMP_TYPEDEF hack. Very ugly, should all be
revamped.
* Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
problems.
2000-10-11 Werner Koch <wk@gnupg.org>
* generic/mpi-asm-defs.h: New.
* mips3/mpi-asm-defs.h: New.
* config.links: Create a link to one of the above files.
Fri Jul 28 18:19:11 CEST 2000 Werner Koch <wk@openit.de>
* mpicoder.c (gcry_mpi_scan): Normalize the returned MPI.
Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
* config.links: Support for powerpc--netbsd by Gabriel Rosenkoetter.
Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
* power/: Add all files from GMP for this CPU. Converted comments to
CPP comments because some ASes complain about ' in comments.
* config.links: Support for BSDI 4.x; by Wayne Chapeskie. Add support
for FreeBSD 5 and made the case stmt looking nicer; by Jun Kuriyama.
Add support for NetBSD.
(sparc8): Made the search path the same as sparc9
(sparc64-unknown-linux-gnu): use udiv module; by Adam Mitchell.
* Makefile.am: c/SFLAGS/ASFLAGS/. This has only been used by the
powerpc and actually never passed the -Wa,foo to the cc.
* mpih-div.c (mpihelp_divrem): The MPN_COPY_DECR copied one element
too many. This is a gmp2.0.2p9.txt patch.
* longlong.h (umul_ppmm): Fixes for ARM-4. By Sean MacLennan.
* mpi-internal.h (karatsuba_ctx): New.
* mpih-mul.c (mpihelp_release_karatsuba_ctx): New.
(mpihelp_mul_karatsuba_case): New.
(mpihelp_mul): Splitted to make use of the new functions.
* mpi-pow.c (mpi_powm): Make use of the new splitted function to avoid
multiple allocation of temporary memory during the karatsuba operations.
* mpi_mpow.c: Removed the unused Barrett code.
2000-03-21 16:17:30 Werner Koch (wk@habibti.openit.de)
* config.links: Add support for FreeBSD 5.
Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
* mpicoder.c (gcry_mpi_aprint): Now really returns the length.
Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
* mpiutil.c: Removed all memory debugging code.
* mpicoder.c (gcry_mpi_aprint): New.
* Replaced all m_ memory functions by g10_ ones.
Fri Dec 31 14:06:56 CET 1999 Werner Koch <wk@gnupg.de>
* mpi-bit.c (gcry_mpi_get_nbits): New.
* mpiutil.c (mpi_set_secure): made static.
(gcry_mpi_get_flag): New.
(gcry_mpi_set_flag): New.
(gcry_mpi_clear_flag): New.
(mpi_set_opaque): renamed to gcry_mpi_set_opaque.
(mpi_get_opaque): renamed to gcry_mpi_get_opaque.
Fri Dec 31 12:48:31 CET 1999 Werner Koch <wk@gnupg.de>
* mpicoder.c (mpi_read_from_buffer): Made static.
(gcry_mpi_print): A buffer of NULL is now allowed to get the required
length back.
(mpi_get_keyid): Removed.
(mpi_print): Made static - should be removed.
Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
* Makefile.am (INCLUDES): Add ../gcrypt.
* g10m.c : Removed.
* mpicoder.c (mpi_write): Removed.
(mpi_read): Removed.
(gcry_mpi_scan): New. Taken from ../gcrypt/mpiapi.c.
(gcry_mpi_print): Ditto.
* mpi-pow.c (mpi_powm): Renamed to ...
(gcry_mpi_powm): ... this.
* mpiutil.c (gcry_mpi_new): New as a wrapper around the old function.
Taken from ../gcrypt/mpiapi.c.
(gcry_mpi_snew): Ditto.
(gcry_mpi_release): Ditto.
(gcry_mpi_copy): Ditto.
(gcry_mpi_set): Ditto.
(gcry_mpi_set_ui): Ditto.
(gcry_mpi_cmp): Ditto.
(gcry_mpi_cmp_ui): Ditto.
(gcry_mpi_randomize): Ditto.
* mpicoder.c (mpi_print): Removed the nbit_info kludge.
* mpi-bits.c (mpi_get_nbits): Replaced the is_protected stuff by
checking whether it is an opaque mpi and then returns it's length
in bits.
* mpiutil.c (mpi_set_opaque): Changed the interface to take a number
of bits for the length. Adjusted all users.
(mpi_get_opaque): Ditto.
Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
* mpicoder.c (g10_log_mpidump): Add a temporary workaround
* mpih-mul.c (mpihelp_mul_n): s/m_is_ecure/g10_is_secure/
* mpiutil.c (mpi_alloc): Remved the debug mode because it has turned
out, that this feature was not very useful in the past. Use the
new alloc functions.
(mpi_alloc_secure): Ditto.
(mpi_alloc_limb_space): Ditto.
(mpi_free_limb_space): Ditto.
(mpi_resize): Ditto.
(mpi_free): Ditto.
(mpi_set_secure): Removed the debug stuff.
(mpi_set_opaque): Ditto.
(mpi_copy): Ditto.
(mpi_alloc_set_ui): Ditto.
(mpi_m_check): Use g10_ wrapper.
Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* config.links: Add case label for DJGPP
Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am: Use .s files as temporaries, disabled other .S rules.
Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* mpicoder.c (g10_log_mpidump): New.
* Makefile.am: Support for libtool.
Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* mpi-bit.c (mpi_lshift_limbs,mpi_rshift_limbs): New.
* mpi-mpow.c (barrett_mulm): New but diabled.
Tue Jun 1 16:01:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* config.links (i[56]86*-*-freebsdelf*): New.
Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* config.links (sysdep.h): Not any more conditionally created.
Tue May 4 15:47:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* mpiutil.c (mpi_alloc_like): New.
Mon Apr 26 17:48:15 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* mpih-add.c, mpih-sub.c: Removed
* mpi-inline.c: New.
* mpi-inline.h: Make it usable by mpi-inline.c.
Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* mpih-mul.c (mpihelp_mul_n): Fixed use of memory region.
(mpihelp_mul): Ditto.
Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am: Explicit rules to invoke cpp on *.S
Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* config.links: Take advantage of the with_symbol_underscore macro.
Add support for freebsd 4.
Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* mips3/mpih-sub1.S: Removed left over junk in last line. (Should I
blame me or my editor?).
Sat Feb 13 12:04:43 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am: Removed the +=. Add MPI_OPT_FLAGS.
Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* mpi-cmp.c (mpi_cmp_ui): Normalized the arg.
Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* mpi-bit.c (mpi_normalize): New.
(mpi_get_nbits): Normalize the MPI.
* mpi-bit.c (mpi_cmp): Normalize the MPI before the compare.
Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* config.links: Moved the case for powerpc*linux
* powerpcp32/*.S: Removed some underscores.
Thu Nov 26 07:27:52 1998 Werner Koch <werner.koch@guug.de>
* config.links: Support for ppc with ELF
* powerpc32/syntax.h: New.
* powerpc32/*.S: Applied ELF patches (glibc patches)
Tue Nov 10 19:31:37 1998 Werner Koch (wk@isil.d.shuttle.de)
* power*/ : Started with stuff for PPC
* config.links: Some stuff for PPC.
* generic/udiv-w-sdiv.c: New but disabled.
Tue Oct 27 12:37:46 1998 Werner Koch (wk@isil.d.shuttle.de)
* config.links (freebsd): Fixes for FreeBSD 3.0
Wed Oct 14 09:59:30 1998 Werner Koch (wk@isil.d.shuttle.de)
* config.links (freebsd): ELF patches from Jun Kuriyama.
Thu Oct 8 13:28:17 1998 Werner Koch (wk@isil.d.shuttle.de)
* mpi-mpow.c (mpi_mulpowm): Fixed mem leak (m_free/mpi_free).
Thu Sep 17 18:08:50 1998 Werner Koch (wk@(none))
* hppa1.1/udiv-qrnnd.S: Fix from Steffen Zahn for HPUX 10.20
Thu Aug 6 16:39:28 1998 Werner Koch,mobil,,, (wk@tobold)
* mpi-bit.c (mpi_set_bytes): Removed.
Wed Aug 5 15:11:12 1998 Werner Koch (wk@(none))
* mpicoder.c (mpi_read_from_buffer): New.
* mpiutil.c (mpi_set_opaque): New.
(mpi_get_opaque): New.
(mpi_copy): Changed to support opauqe flag
(mpi_free): Ditto.
Sat Jul 4 10:11:11 1998 Werner Koch (wk@isil.d.shuttle.de)
* mpiutil.c (mpi_clear): Reset flags.
(mpi_set): Ditto.
(mpi_alloc_secure): Set flag to 1 and not ored the 1 in, tsss..
Fri Jun 26 11:19:06 1998 Werner Koch (wk@isil.d.shuttle.de)
* mpiutil.c (mpi_alloc): set nbits to 0.
(mpi_alloc_secure): Ditto.
(mpi_clear): Ditto.
Thu Jun 25 11:50:01 1998 Werner Koch (wk@isil.d.shuttle.de)
* mips3/*.S: New
Mon May 18 13:47:06 1998 Werner Koch (wk@isil.d.shuttle.de)
* config.links: split mpih-shift into mpih-[lr]shift and
changed all implementations.
* mpi/alpha: add some new assembler stuff.
Wed May 13 11:04:29 1998 Werner Koch (wk@isil.d.shuttle.de)
* config.links: Add support for MIPS
Thu Apr 9 11:31:36 1998 Werner Koch (wk@isil.d.shuttle.de)
* mpicoder.c (mpi_get_secure_buffer): New.
Wed Apr 8 09:44:33 1998 Werner Koch (wk@isil.d.shuttle.de)
* config.links: Applied small fix from Ulf Möller.
Mon Apr 6 12:38:52 1998 Werner Koch (wk@isil.d.shuttle.de)
* mpicoder.c (mpi_get_buffer): Removed returned leading zeroes
and changed all callers.
Tue Mar 10 13:40:34 1998 Werner Koch (wk@isil.d.shuttle.de)
* mpi-bit.c (mpi_clear_highbit): New.
Mon Mar 2 19:29:00 1998 Werner Koch (wk@isil.d.shuttle.de)
* Makefile.am (DISTCLEANFILES): New
Thu Feb 26 06:48:54 1998 Werner Koch (wk@isil.d.shuttle.de)
* config.links (X86_BROKEN_ALIGN): Added for some systems.
Mon Feb 23 12:21:40 1998 Werner Koch (wk@isil.d.shuttle.de)
* mpi/m68k/mpih-shift.S (Lspecial): Changed duplicate symbol.
Mon Feb 16 13:00:27 1998 Werner Koch (wk@isil.d.shuttle.de)
* config.links : Add detection of m68k cpus
Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
This file is free software; as a special exception the author gives
unlimited permission to copy and/or distribute it, with or without
modifications, as long as this notice is preserved.
This file is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Local Variables:
buffer-read-only: t
End:

View file

@ -0,0 +1,177 @@
## Process this file with automake to produce Makefile.in
# Copyright (C) 1992, 1999, 2000, 2002 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# Libgcrypt is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Libgcrypt 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser 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
# 1.5 leads to a combinatorial explosion due to all the conditionals
# I was not able to build it with 64Megs - 1.6 fixes this.
# not anymore required: AUTOMAKE_OPTIONS = 1.6
# Need to include ../src in addition to top_srcdir because gcrypt.h is
# a built header.
AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
AM_CFLAGS = $(GPG_ERROR_CFLAGS)
AM_ASFLAGS = $(MPI_SFLAGS)
AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
EXTRA_DIST = Manifest config.links
DISTCLEANFILES = mpi-asm-defs.h \
mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S \
mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \
mpih-add1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c \
mpih-lshift.c mpih-rshift.c mpih-sub1.c \
sysdep.h mod-source-info.h
# Beware: The following list is not a comment but grepped by
# config.links to get the list of symlinked modules
# Optional modules are marked with an O in the second column.
#BEGIN_ASM_LIST
# mpih-add1 C
# mpih-sub1 C
# mpih-mul1 C
# mpih-mul2 C
# mpih-mul3 C
# mpih-lshift C
# mpih-rshift C
# udiv O
# udiv-qrnnd O
#END_ASM_LIST
# Note: This function has not yet been implemented. There is only a dummy in
# generic/
# udiv-w-sdiv O
# And we need to have conditionals for all modules because
# we don't know whether they are .c or .S. Very ugly; I know.
# Remember to define them all in configure.ac
if MPI_MOD_ASM_MPIH_ADD1
mpih_add1 = mpih-add1-asm.S
else
if MPI_MOD_C_MPIH_ADD1
mpih_add1 = mpih-add1.c
else
mpih_add1 =
endif
endif
if MPI_MOD_ASM_MPIH_SUB1
mpih_sub1 = mpih-sub1-asm.S
else
if MPI_MOD_C_MPIH_SUB1
mpih_sub1 = mpih-sub1.c
else
mpih_sub1 =
endif
endif
if MPI_MOD_ASM_MPIH_MUL1
mpih_mul1 = mpih-mul1-asm.S
else
if MPI_MOD_C_MPIH_MUL1
mpih_mul1 = mpih-mul1.c
else
mpih_mul1 =
endif
endif
if MPI_MOD_ASM_MPIH_MUL2
mpih_mul2 = mpih-mul2-asm.S
else
if MPI_MOD_C_MPIH_MUL2
mpih_mul2 = mpih-mul2.c
else
mpih_mul2 =
endif
endif
if MPI_MOD_ASM_MPIH_MUL3
mpih_mul3 = mpih-mul3-asm.S
else
if MPI_MOD_C_MPIH_MUL3
mpih_mul3 = mpih-mul3.c
else
mpih_mul3 =
endif
endif
if MPI_MOD_ASM_MPIH_LSHIFT
mpih_lshift = mpih-lshift-asm.S
else
if MPI_MOD_C_MPIH_LSHIFT
mpih_lshift = mpih-lshift.c
else
mpih_lshift =
endif
endif
if MPI_MOD_ASM_MPIH_RSHIFT
mpih_rshift = mpih-rshift-asm.S
else
if MPI_MOD_C_MPIH_RSHIFT
mpih_rshift = mpih-rshift.c
else
mpih_rshift =
endif
endif
if MPI_MOD_ASM_UDIV
udiv = udiv-asm.S
else
if MPI_MOD_C_UDIV
udiv = udiv.c
else
udiv =
endif
endif
if MPI_MOD_ASM_UDIV_QRNND
udiv_qrnnd = udiv-qrnnd-asm.S
else
if MPI_MOD_C_UDIV_QRNND
udiv_qrnnd = udiv-qrnnd.c
else
udiv_qrnnd =
endif
endif
noinst_LTLIBRARIES = libmpi.la
libmpi_la_LDFLAGS =
nodist_libmpi_la_SOURCES = $(mpih_add1) $(mpih_sub1) $(mpih_mul1) \
$(mpih_mul2) $(mpih_mul3) $(mpih_lshift) $(mpih_rshift) \
$(udiv) $(udiv_qrnnd)
libmpi_la_SOURCES = longlong.h \
mpi-add.c \
mpi-bit.c \
mpi-cmp.c \
mpi-div.c \
mpi-gcd.c \
mpi-internal.h \
mpi-inline.h \
mpi-inline.c \
mpi-inv.c \
mpi-mul.c \
mpi-mod.c \
mpi-pow.c \
mpi-mpow.c \
mpi-scan.c \
mpicoder.c \
mpih-div.c \
mpih-mul.c \
mpiutil.c \
ec.c

View file

@ -0,0 +1,41 @@
# Manifest - checksums of the mpi directory
# Copyright 2003 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# Libgcrypt is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser general Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Libgcrypt 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser 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
Makefile.am
config.links
longlong.h
mpi-add.c
mpi-bit.c
mpi-cmp.c
mpi-div.c
mpi-gcd.c
mpi-inline.c
mpi-inline.h
mpi-internal.h
mpi-inv.c
mpi-mpow.c
mpi-mul.c
mpi-pow.c
mpi-scan.c
mpicoder.c
mpih-div.c
mpih-mul.c
mpiutil.c
$names$ iQCVAwUAP+LmfDEAnp832S/7AQKZJQQAkR/gQITUM+6Ygy9WAOAO17btyKAlCtGTXp5XSZ+J3X0o/rYneRdSCW89IJvwFRJjAOcFJd52MXs6ZVFF/RQBC8MvJzuQChbEzvihK8o2VgK34YWjU+6XH9sFgRMIgzkHs/51ZZxeQUOPy1XF7TyKB0WE7YBUVisFiRaqB1qGIOs==Z3qB

View file

@ -0,0 +1,53 @@
This directory contains mpn functions optimized for DEC Alpha processors.
RELEVANT OPTIMIZATION ISSUES
EV4
1. This chip has very limited store bandwidth. The on-chip L1 cache is
write-through, and a cache line is transfered from the store buffer to the
off-chip L2 in as much 15 cycles on most systems. This delay hurts
mpn_add_n, mpn_sub_n, mpn_lshift, and mpn_rshift.
2. Pairing is possible between memory instructions and integer arithmetic
instructions.
3. mulq and umulh is documented to have a latency of 23 cycles, but 2 of
these cycles are pipelined. Thus, multiply instructions can be issued at a
rate of one each 21nd cycle.
EV5
1. The memory bandwidth of this chip seems excellent, both for loads and
stores. Even when the working set is larger than the on-chip L1 and L2
caches, the perfromance remain almost unaffected.
2. mulq has a measured latency of 13 cycles and an issue rate of 1 each 8th
cycle. umulh has a measured latency of 15 cycles and an issue rate of 1
each 10th cycle. But the exact timing is somewhat confusing.
3. mpn_add_n. With 4-fold unrolling, we need 37 instructions, whereof 12
are memory operations. This will take at least
ceil(37/2) [dual issue] + 1 [taken branch] = 20 cycles
We have 12 memory cycles, plus 4 after-store conflict cycles, or 16 data
cache cycles, which should be completely hidden in the 20 issue cycles.
The computation is inherently serial, with these dependencies:
addq
/ \
addq cmpult
| |
cmpult |
\ /
or
I.e., there is a 4 cycle path for each limb, making 16 cycles the absolute
minimum. We could replace the `or' with a cmoveq/cmovne, which would save
a cycle on EV5, but that might waste a cycle on EV4. Also, cmov takes 2
cycles.
addq
/ \
addq cmpult
| \
cmpult -> cmovne
STATUS

View file

@ -0,0 +1,11 @@
README
mpih-add1.S
mpih-sub1.S
mpih-mul1.S
mpih-mul2.S
mpih-mul3.S
mpih-lshift.S
mpih-rshift.S
udiv-qrnnd.S

View file

@ -0,0 +1,124 @@
/* alpha add_n -- Add two limb vectors of the same length > 0 and store
* sum in a third limb vector.
* Copyright (C) 1995, 1998, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*/
/*******************
* mpi_limb_t
* _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($16)
* mpi_ptr_t s1_ptr, ($17)
* mpi_ptr_t s2_ptr, ($18)
* mpi_size_t size) ($19)
*/
.set noreorder
.set noat
.text
.align 3
.globl _gcry_mpih_add_n
.ent _gcry_mpih_add_n
_gcry_mpih_add_n:
.frame $30,0,$26,0
ldq $3,0($17)
ldq $4,0($18)
subq $19,1,$19
and $19,4-1,$2 # number of limbs in first loop
bis $31,$31,$0
beq $2,.L0 # if multiple of 4 limbs, skip first loop
subq $19,$2,$19
.Loop0: subq $2,1,$2
ldq $5,8($17)
addq $4,$0,$4
ldq $6,8($18)
cmpult $4,$0,$1
addq $3,$4,$4
cmpult $4,$3,$0
stq $4,0($16)
or $0,$1,$0
addq $17,8,$17
addq $18,8,$18
bis $5,$5,$3
bis $6,$6,$4
addq $16,8,$16
bne $2,.Loop0
.L0: beq $19,.Lend
.align 3
.Loop: subq $19,4,$19
ldq $5,8($17)
addq $4,$0,$4
ldq $6,8($18)
cmpult $4,$0,$1
addq $3,$4,$4
cmpult $4,$3,$0
stq $4,0($16)
or $0,$1,$0
ldq $3,16($17)
addq $6,$0,$6
ldq $4,16($18)
cmpult $6,$0,$1
addq $5,$6,$6
cmpult $6,$5,$0
stq $6,8($16)
or $0,$1,$0
ldq $5,24($17)
addq $4,$0,$4
ldq $6,24($18)
cmpult $4,$0,$1
addq $3,$4,$4
cmpult $4,$3,$0
stq $4,16($16)
or $0,$1,$0
ldq $3,32($17)
addq $6,$0,$6
ldq $4,32($18)
cmpult $6,$0,$1
addq $5,$6,$6
cmpult $6,$5,$0
stq $6,24($16)
or $0,$1,$0
addq $17,32,$17
addq $18,32,$18
addq $16,32,$16
bne $19,.Loop
.Lend: addq $4,$0,$4
cmpult $4,$0,$1
addq $3,$4,$4
cmpult $4,$3,$0
stq $4,0($16)
or $0,$1,$0
ret $31,($26),1
.end _gcry_mpih_add_n

View file

@ -0,0 +1,122 @@
/* alpha - left shift
*
* Copyright (C) 1994, 1995, 1998, 2001,
* 2002 Free Software Foundation, Inc.
*
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
/*******************
* mpi_limb_t
* _gcry_mpih_lshift( mpi_ptr_t wp, (r16)
* mpi_ptr_t up, (r17)
* mpi_size_t usize, (r18)
* unsigned cnt) (r19)
*
* This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling,
* it would take 4 cycles/limb. It should be possible to get down to 3
* cycles/limb since both ldq and stq can be paired with the other used
* instructions. But there are many restrictions in the 21064 pipeline that
* makes it hard, if not impossible, to get down to 3 cycles/limb:
*
* 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay.
* 2. Only aligned instruction pairs can be paired.
* 3. The store buffer or silo might not be able to deal with the bandwidth.
*/
.set noreorder
.set noat
.text
.align 3
.globl _gcry_mpih_lshift
.ent _gcry_mpih_lshift
_gcry_mpih_lshift:
.frame $30,0,$26,0
s8addq $18,$17,$17 # make r17 point at end of s1
ldq $4,-8($17) # load first limb
subq $17,8,$17
subq $31,$19,$7
s8addq $18,$16,$16 # make r16 point at end of RES
subq $18,1,$18
and $18,4-1,$20 # number of limbs in first loop
srl $4,$7,$0 # compute function result
beq $20,.L0
subq $18,$20,$18
.align 3
.Loop0:
ldq $3,-8($17)
subq $16,8,$16
subq $17,8,$17
subq $20,1,$20
sll $4,$19,$5
srl $3,$7,$6
bis $3,$3,$4
bis $5,$6,$8
stq $8,0($16)
bne $20,.Loop0
.L0: beq $18,.Lend
.align 3
.Loop: ldq $3,-8($17)
subq $16,32,$16
subq $18,4,$18
sll $4,$19,$5
srl $3,$7,$6
ldq $4,-16($17)
sll $3,$19,$1
bis $5,$6,$8
stq $8,24($16)
srl $4,$7,$2
ldq $3,-24($17)
sll $4,$19,$5
bis $1,$2,$8
stq $8,16($16)
srl $3,$7,$6
ldq $4,-32($17)
sll $3,$19,$1
bis $5,$6,$8
stq $8,8($16)
srl $4,$7,$2
subq $17,32,$17
bis $1,$2,$8
stq $8,0($16)
bgt $18,.Loop
.Lend: sll $4,$19,$8
stq $8,-8($16)
ret $31,($26),1
.end _gcry_mpih_lshift

View file

@ -0,0 +1,90 @@
/* Alpha 21064 mpih-mul1.S -- Multiply a limb vector with a limb and store
* the result in a second limb vector.
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*/
/*******************
* mpi_limb_t
* _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r16)
* mpi_ptr_t s1_ptr, (r17)
* mpi_size_t s1_size, (r18)
* mpi_limb_t s2_limb) (r19)
*
* This code runs at 42 cycles/limb on the EV4 and 18 cycles/limb on the EV5.
*
* To improve performance for long multiplications, we would use
* 'fetch' for S1 and 'fetch_m' for RES. It's not obvious how to use
* these instructions without slowing down the general code: 1. We can
* only have two prefetches in operation at any time in the Alpha
* architecture. 2. There will seldom be any special alignment
* between RES_PTR and S1_PTR. Maybe we can simply divide the current
* loop into an inner and outer loop, having the inner loop handle
* exactly one prefetch block?
*/
.set noreorder
.set noat
.text
.align 3
.globl _gcry_mpih_mul_1
.ent _gcry_mpih_mul_1 2
_gcry_mpih_mul_1:
.frame $30,0,$26
ldq $2,0($17) # $2 = s1_limb
subq $18,1,$18 # size--
mulq $2,$19,$3 # $3 = prod_low
bic $31,$31,$4 # clear cy_limb
umulh $2,$19,$0 # $0 = prod_high
beq $18,Lend1 # jump if size was == 1
ldq $2,8($17) # $2 = s1_limb
subq $18,1,$18 # size--
stq $3,0($16)
beq $18,Lend2 # jump if size was == 2
.align 3
Loop: mulq $2,$19,$3 # $3 = prod_low
addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
subq $18,1,$18 # size--
umulh $2,$19,$4 # $4 = cy_limb
ldq $2,16($17) # $2 = s1_limb
addq $17,8,$17 # s1_ptr++
addq $3,$0,$3 # $3 = cy_limb + prod_low
stq $3,8($16)
cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
addq $16,8,$16 # res_ptr++
bne $18,Loop
Lend2: mulq $2,$19,$3 # $3 = prod_low
addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
umulh $2,$19,$4 # $4 = cy_limb
addq $3,$0,$3 # $3 = cy_limb + prod_low
cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
stq $3,8($16)
addq $4,$0,$0 # cy_limb = prod_high + cy
ret $31,($26),1
Lend1: stq $3,0($16)
ret $31,($26),1
.end _gcry_mpih_mul_1

View file

@ -0,0 +1,97 @@
/* Alpha 21064 addmul_1 -- Multiply a limb vector with a limb and add
* the result to a second limb vector.
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*/
/*******************
* mpi_limb_t
* _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r16)
* mpi_ptr_t s1_ptr, (r17)
* mpi_size_t s1_size, (r18)
* mpi_limb_t s2_limb) (r19)
*
* This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5.
*/
.set noreorder
.set noat
.text
.align 3
.globl _gcry_mpih_addmul_1
.ent _gcry_mpih_addmul_1 2
_gcry_mpih_addmul_1:
.frame $30,0,$26
ldq $2,0($17) # $2 = s1_limb
addq $17,8,$17 # s1_ptr++
subq $18,1,$18 # size--
mulq $2,$19,$3 # $3 = prod_low
ldq $5,0($16) # $5 = *res_ptr
umulh $2,$19,$0 # $0 = prod_high
beq $18,.Lend1 # jump if size was == 1
ldq $2,0($17) # $2 = s1_limb
addq $17,8,$17 # s1_ptr++
subq $18,1,$18 # size--
addq $5,$3,$3
cmpult $3,$5,$4
stq $3,0($16)
addq $16,8,$16 # res_ptr++
beq $18,.Lend2 # jump if size was == 2
.align 3
.Loop: mulq $2,$19,$3 # $3 = prod_low
ldq $5,0($16) # $5 = *res_ptr
addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
subq $18,1,$18 # size--
umulh $2,$19,$4 # $4 = cy_limb
ldq $2,0($17) # $2 = s1_limb
addq $17,8,$17 # s1_ptr++
addq $3,$0,$3 # $3 = cy_limb + prod_low
cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
addq $5,$3,$3
cmpult $3,$5,$5
stq $3,0($16)
addq $16,8,$16 # res_ptr++
addq $5,$0,$0 # combine carries
bne $18,.Loop
.Lend2: mulq $2,$19,$3 # $3 = prod_low
ldq $5,0($16) # $5 = *res_ptr
addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
umulh $2,$19,$4 # $4 = cy_limb
addq $3,$0,$3 # $3 = cy_limb + prod_low
cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
addq $5,$3,$3
cmpult $3,$5,$5
stq $3,0($16)
addq $5,$0,$0 # combine carries
addq $4,$0,$0 # cy_limb = prod_high + cy
ret $31,($26),1
.Lend1: addq $5,$3,$3
cmpult $3,$5,$5
stq $3,0($16)
addq $0,$5,$0
ret $31,($26),1
.end _gcry_mpih_addmul_1

View file

@ -0,0 +1,95 @@
/* Alpha 21064 submul_1 -- Multiply a limb vector with a limb and
* subtract the result from a second limb vector.
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*/
/*******************
* mpi_limb_t
* _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r16 )
* mpi_ptr_t s1_ptr, (r17 )
* mpi_size_t s1_size, (r18 )
* mpi_limb_t s2_limb) (r19 )
*
* This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5.
*/
.set noreorder
.set noat
.text
.align 3
.globl _gcry_mpih_submul_1
.ent _gcry_mpih_submul_1 2
_gcry_mpih_submul_1:
.frame $30,0,$26
ldq $2,0($17) # $2 = s1_limb
addq $17,8,$17 # s1_ptr++
subq $18,1,$18 # size--
mulq $2,$19,$3 # $3 = prod_low
ldq $5,0($16) # $5 = *res_ptr
umulh $2,$19,$0 # $0 = prod_high
beq $18,.Lend1 # jump if size was == 1
ldq $2,0($17) # $2 = s1_limb
addq $17,8,$17 # s1_ptr++
subq $18,1,$18 # size--
subq $5,$3,$3
cmpult $5,$3,$4
stq $3,0($16)
addq $16,8,$16 # res_ptr++
beq $18,.Lend2 # jump if size was == 2
.align 3
.Loop: mulq $2,$19,$3 # $3 = prod_low
ldq $5,0($16) # $5 = *res_ptr
addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
subq $18,1,$18 # size--
umulh $2,$19,$4 # $4 = cy_limb
ldq $2,0($17) # $2 = s1_limb
addq $17,8,$17 # s1_ptr++
addq $3,$0,$3 # $3 = cy_limb + prod_low
cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
subq $5,$3,$3
cmpult $5,$3,$5
stq $3,0($16)
addq $16,8,$16 # res_ptr++
addq $5,$0,$0 # combine carries
bne $18,.Loop
.Lend2: mulq $2,$19,$3 # $3 = prod_low
ldq $5,0($16) # $5 = *res_ptr
addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
umulh $2,$19,$4 # $4 = cy_limb
addq $3,$0,$3 # $3 = cy_limb + prod_low
cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
subq $5,$3,$3
cmpult $5,$3,$5
stq $3,0($16)
addq $5,$0,$0 # combine carries
addq $4,$0,$0 # cy_limb = prod_high + cy
ret $31,($26),1
.Lend1: subq $5,$3,$3
cmpult $5,$3,$5
stq $3,0($16)
addq $0,$5,$0
ret $31,($26),1
.end _gcry_mpih_submul_1

View file

@ -0,0 +1,118 @@
/* alpha rshift
* Copyright (C) 1994, 1995, 1998, 1999,
* 2000, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
/*******************
* mpi_limb_t
* _gcry_mpih_rshift( mpi_ptr_t wp, (r16)
* mpi_ptr_t up, (r17)
* mpi_size_t usize, (r18)
* unsigned cnt) (r19)
*
* This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling,
* it would take 4 cycles/limb. It should be possible to get down to 3
* cycles/limb since both ldq and stq can be paired with the other used
* instructions. But there are many restrictions in the 21064 pipeline that
* makes it hard, if not impossible, to get down to 3 cycles/limb:
*
* 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay.
* 2. Only aligned instruction pairs can be paired.
* 3. The store buffer or silo might not be able to deal with the bandwidth.
*/
.set noreorder
.set noat
.text
.align 3
.globl _gcry_mpih_rshift
.ent _gcry_mpih_rshift
_gcry_mpih_rshift:
.frame $30,0,$26,0
ldq $4,0($17) # load first limb
addq $17,8,$17
subq $31,$19,$7
subq $18,1,$18
and $18,4-1,$20 # number of limbs in first loop
sll $4,$7,$0 # compute function result
beq $20,.R0
subq $18,$20,$18
.align 3
.Roop0:
ldq $3,0($17)
addq $16,8,$16
addq $17,8,$17
subq $20,1,$20
srl $4,$19,$5
sll $3,$7,$6
bis $3,$3,$4
bis $5,$6,$8
stq $8,-8($16)
bne $20,.Roop0
.R0: beq $18,.Rend
.align 3
.Roop: ldq $3,0($17)
addq $16,32,$16
subq $18,4,$18
srl $4,$19,$5
sll $3,$7,$6
ldq $4,8($17)
srl $3,$19,$1
bis $5,$6,$8
stq $8,-32($16)
sll $4,$7,$2
ldq $3,16($17)
srl $4,$19,$5
bis $1,$2,$8
stq $8,-24($16)
sll $3,$7,$6
ldq $4,24($17)
srl $3,$19,$1
bis $5,$6,$8
stq $8,-16($16)
sll $4,$7,$2
addq $17,32,$17
bis $1,$2,$8
stq $8,-8($16)
bgt $18,.Roop
.Rend: srl $4,$19,$8
stq $8,0($16)
ret $31,($26),1
.end _gcry_mpih_rshift

View file

@ -0,0 +1,124 @@
/* Alpha sub_n -- Subtract two limb vectors of the same length > 0 and
* store difference in a third limb vector.
* Copyright (C) 1995, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*/
/*******************
* mpi_limb_t
* _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r16)
* mpi_ptr_t s1_ptr, (r17)
* mpi_ptr_t s2_ptr, (r18)
* mpi_size_t size) (r19)
*/
.set noreorder
.set noat
.text
.align 3
.globl _gcry_mpih_sub_n
.ent _gcry_mpih_sub_n
_gcry_mpih_sub_n:
.frame $30,0,$26,0
ldq $3,0($17)
ldq $4,0($18)
subq $19,1,$19
and $19,4-1,$2 # number of limbs in first loop
bis $31,$31,$0
beq $2,.L0 # if multiple of 4 limbs, skip first loop
subq $19,$2,$19
.Loop0: subq $2,1,$2
ldq $5,8($17)
addq $4,$0,$4
ldq $6,8($18)
cmpult $4,$0,$1
subq $3,$4,$4
cmpult $3,$4,$0
stq $4,0($16)
or $0,$1,$0
addq $17,8,$17
addq $18,8,$18
bis $5,$5,$3
bis $6,$6,$4
addq $16,8,$16
bne $2,.Loop0
.L0: beq $19,.Lend
.align 3
.Loop: subq $19,4,$19
ldq $5,8($17)
addq $4,$0,$4
ldq $6,8($18)
cmpult $4,$0,$1
subq $3,$4,$4
cmpult $3,$4,$0
stq $4,0($16)
or $0,$1,$0
ldq $3,16($17)
addq $6,$0,$6
ldq $4,16($18)
cmpult $6,$0,$1
subq $5,$6,$6
cmpult $5,$6,$0
stq $6,8($16)
or $0,$1,$0
ldq $5,24($17)
addq $4,$0,$4
ldq $6,24($18)
cmpult $4,$0,$1
subq $3,$4,$4
cmpult $3,$4,$0
stq $4,16($16)
or $0,$1,$0
ldq $3,32($17)
addq $6,$0,$6
ldq $4,32($18)
cmpult $6,$0,$1
subq $5,$6,$6
cmpult $5,$6,$0
stq $6,24($16)
or $0,$1,$0
addq $17,32,$17
addq $18,32,$18
addq $16,32,$16
bne $19,.Loop
.Lend: addq $4,$0,$4
cmpult $4,$0,$1
subq $3,$4,$4
cmpult $3,$4,$0
stq $4,0($16)
or $0,$1,$0
ret $31,($26),1
.end _gcry_mpih_sub_n

View file

@ -0,0 +1,159 @@
/* Alpha 21064 __udiv_qrnnd
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
.set noreorder
.set noat
.text
.align 3
.globl __udiv_qrnnd
.ent __udiv_qrnnd
__udiv_qrnnd:
.frame $30,0,$26,0
.prologue 0
#define cnt $2
#define tmp $3
#define rem_ptr $16
#define n1 $17
#define n0 $18
#define d $19
#define qb $20
ldiq cnt,16
blt d,.Largedivisor
.Loop1: cmplt n0,0,tmp
addq n1,n1,n1
bis n1,tmp,n1
addq n0,n0,n0
cmpule d,n1,qb
subq n1,d,tmp
cmovne qb,tmp,n1
bis n0,qb,n0
cmplt n0,0,tmp
addq n1,n1,n1
bis n1,tmp,n1
addq n0,n0,n0
cmpule d,n1,qb
subq n1,d,tmp
cmovne qb,tmp,n1
bis n0,qb,n0
cmplt n0,0,tmp
addq n1,n1,n1
bis n1,tmp,n1
addq n0,n0,n0
cmpule d,n1,qb
subq n1,d,tmp
cmovne qb,tmp,n1
bis n0,qb,n0
cmplt n0,0,tmp
addq n1,n1,n1
bis n1,tmp,n1
addq n0,n0,n0
cmpule d,n1,qb
subq n1,d,tmp
cmovne qb,tmp,n1
bis n0,qb,n0
subq cnt,1,cnt
bgt cnt,.Loop1
stq n1,0(rem_ptr)
bis $31,n0,$0
ret $31,($26),1
.Largedivisor:
and n0,1,$4
srl n0,1,n0
sll n1,63,tmp
or tmp,n0,n0
srl n1,1,n1
and d,1,$6
srl d,1,$5
addq $5,$6,$5
.Loop2: cmplt n0,0,tmp
addq n1,n1,n1
bis n1,tmp,n1
addq n0,n0,n0
cmpule $5,n1,qb
subq n1,$5,tmp
cmovne qb,tmp,n1
bis n0,qb,n0
cmplt n0,0,tmp
addq n1,n1,n1
bis n1,tmp,n1
addq n0,n0,n0
cmpule $5,n1,qb
subq n1,$5,tmp
cmovne qb,tmp,n1
bis n0,qb,n0
cmplt n0,0,tmp
addq n1,n1,n1
bis n1,tmp,n1
addq n0,n0,n0
cmpule $5,n1,qb
subq n1,$5,tmp
cmovne qb,tmp,n1
bis n0,qb,n0
cmplt n0,0,tmp
addq n1,n1,n1
bis n1,tmp,n1
addq n0,n0,n0
cmpule $5,n1,qb
subq n1,$5,tmp
cmovne qb,tmp,n1
bis n0,qb,n0
subq cnt,1,cnt
bgt cnt,.Loop2
addq n1,n1,n1
addq $4,n1,n1
bne $6,.LOdd
stq n1,0(rem_ptr)
bis $31,n0,$0
ret $31,($26),1
.LOdd:
/* q' in n0. r' in n1 */
addq n1,n0,n1
cmpult n1,n0,tmp # tmp := carry from addq
beq tmp,.LLp6
addq n0,1,n0
subq n1,d,n1
.LLp6: cmpult n1,d,tmp
bne tmp,.LLp7
addq n0,1,n0
subq n1,d,n1
.LLp7:
stq n1,0(rem_ptr)
bis $31,n0,$0
ret $31,($26),1
.end __udiv_qrnnd

View file

@ -0,0 +1,7 @@
mpih-add1.S
mpih-lshift.S
mpih-mul1.S
mpih-mul2.S
mpih-mul3.S
mpih-rshift.S
mpih-sub1.S

View file

@ -0,0 +1,63 @@
/* AMD64 (x86_64) add_n -- Add two limb vectors of the same length > 0 and store
* sum in a third limb vector.
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002, 2006 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_add_n( mpi_ptr_t res_ptr, rdi
* mpi_ptr_t s1_ptr, rsi
* mpi_ptr_t s2_ptr, rdx
* mpi_size_t size) rcx
*/
.text
.globl C_SYMBOL_NAME(_gcry_mpih_add_n)
C_SYMBOL_NAME(_gcry_mpih_add_n:)
leaq (%rsi,%rcx,8), %rsi
leaq (%rdi,%rcx,8), %rdi
leaq (%rdx,%rcx,8), %rdx
negq %rcx
xorl %eax, %eax /* clear cy */
ALIGN(4) /* minimal alignment for claimed speed */
.Loop: movq (%rsi,%rcx,8), %rax
movq (%rdx,%rcx,8), %r10
adcq %r10, %rax
movq %rax, (%rdi,%rcx,8)
incq %rcx
jne .Loop
movq %rcx, %rax /* zero %rax */
adcq %rax, %rax
ret

View file

@ -0,0 +1,77 @@
/* AMD64 (x86_64) lshift -- Left shift a limb vector and store
* result in a second limb vector.
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002, 2006 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_lshift( mpi_ptr_t wp, rdi
* mpi_ptr_t up, rsi
* mpi_size_t usize, rdx
* unsigned cnt) rcx
*/
.text
.globl C_SYMBOL_NAME(_gcry_mpih_lshift)
C_SYMBOL_NAME(_gcry_mpih_lshift:)
movq -8(%rsi,%rdx,8), %mm7
movd %ecx, %mm1
movl $64, %eax
subl %ecx, %eax
movd %eax, %mm0
movq %mm7, %mm3
psrlq %mm0, %mm7
movd %mm7, %rax
subq $2, %rdx
jl .Lendo
ALIGN(4) /* minimal alignment for claimed speed */
.Loop: movq (%rsi,%rdx,8), %mm6
movq %mm6, %mm2
psrlq %mm0, %mm6
psllq %mm1, %mm3
por %mm6, %mm3
movq %mm3, 8(%rdi,%rdx,8)
je .Lende
movq -8(%rsi,%rdx,8), %mm7
movq %mm7, %mm3
psrlq %mm0, %mm7
psllq %mm1, %mm2
por %mm7, %mm2
movq %mm2, (%rdi,%rdx,8)
subq $2, %rdx
jge .Loop
.Lendo: movq %mm3, %mm2
.Lende: psllq %mm1, %mm2
movq %mm2, (%rdi)
emms
ret

View file

@ -0,0 +1,65 @@
/* AMD64 mul_1 -- Multiply a limb vector with a limb and store
* the result in a second limb vector.
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002, 2006 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (rdi)
* mpi_ptr_t s1_ptr, (rsi)
* mpi_size_t s1_size, (rdx)
* mpi_limb_t s2_limb) (rcx)
*/
TEXT
ALIGN(5)
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
C_SYMBOL_NAME(_gcry_mpih_mul_1:)
movq %rdx, %r11
leaq (%rsi,%rdx,8), %rsi
leaq (%rdi,%rdx,8), %rdi
negq %r11
xorl %r8d, %r8d
.Loop: movq (%rsi,%r11,8), %rax
mulq %rcx
addq %r8, %rax
movl $0, %r8d
adcq %rdx, %r8
movq %rax, (%rdi,%r11,8)
incq %r11
jne .Loop
movq %r8, %rax
ret

View file

@ -0,0 +1,107 @@
/* AMD64 addmul2 -- Multiply a limb vector with a limb and add
* the result to a second limb vector.
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002, 2006 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_addmul_2( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_size_t s1_size, (sp + 12)
* mpi_limb_t s2_limb) (sp + 16)
*/
/* i80386 addmul_1 -- Multiply a limb vector with a limb and add
* the result to a second limb vector.
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (rdi)
* mpi_ptr_t s1_ptr, (rsi)
* mpi_size_t s1_size, (rdx)
* mpi_limb_t s2_limb) (rcx)
*/
TEXT
GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
movq %rdx, %r11
leaq (%rsi,%rdx,8), %rsi
leaq (%rdi,%rdx,8), %rdi
negq %r11
xorl %r8d, %r8d
xorl %r10d, %r10d
ALIGN(3) /* minimal alignment for claimed speed */
.Loop: movq (%rsi,%r11,8), %rax
mulq %rcx
addq (%rdi,%r11,8), %rax
adcq %r10, %rdx
addq %r8, %rax
movq %r10, %r8
movq %rax, (%rdi,%r11,8)
adcq %rdx, %r8
incq %r11
jne .Loop
movq %r8, %rax
ret

View file

@ -0,0 +1,66 @@
/* AMD64 submul_1 -- Multiply a limb vector with a limb and add
* the result to a second limb vector.
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002, 2006 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (rdi)
* mpi_ptr_t s1_ptr, (rsi)
* mpi_size_t s1_size, (rdx)
* mpi_limb_t s2_limb) (rcx)
*/
TEXT
GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
C_SYMBOL_NAME(_gcry_mpih_submul_1:)
movq %rdx, %r11
leaq (%rsi,%r11,8), %rsi
leaq (%rdi,%r11,8), %rdi
negq %r11
xorl %r8d, %r8d
ALIGN(3) /* minimal alignment for claimed speed */
.Loop: movq (%rsi,%r11,8), %rax
movq (%rdi,%r11,8), %r10
mulq %rcx
subq %r8, %r10
movl $0, %r8d
adcl %r8d, %r8d
subq %rax, %r10
adcq %rdx, %r8
movq %r10, (%rdi,%r11,8)
incq %r11
jne .Loop
movq %r8, %rax
ret

View file

@ -0,0 +1,80 @@
/* AMD64 (x86_64) rshift -- Right shift a limb vector and store
* result in a second limb vector.
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002, 2006 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_rshift( mpi_ptr_t wp, rdi
* mpi_ptr_t up, rsi
* mpi_size_t usize, rdx
* unsigned cnt) rcx
*/
.text
.globl C_SYMBOL_NAME(_gcry_mpih_rshift)
C_SYMBOL_NAME(_gcry_mpih_rshift:)
movq (%rsi), %mm7
movd %ecx, %mm1
movl $64, %eax
subl %ecx, %eax
movd %eax, %mm0
movq %mm7, %mm3
psllq %mm0, %mm7
movd %mm7, %rax
leaq (%rsi,%rdx,8), %rsi
leaq (%rdi,%rdx,8), %rdi
negq %rdx
addq $2, %rdx
jg .Lendo
ALIGN(8) /* minimal alignment for claimed speed */
.Loop: movq -8(%rsi,%rdx,8), %mm6
movq %mm6, %mm2
psllq %mm0, %mm6
psrlq %mm1, %mm3
por %mm6, %mm3
movq %mm3, -16(%rdi,%rdx,8)
je .Lende
movq (%rsi,%rdx,8), %mm7
movq %mm7, %mm3
psllq %mm0, %mm7
psrlq %mm1, %mm2
por %mm7, %mm2
movq %mm2, -8(%rdi,%rdx,8)
addq $2, %rdx
jle .Loop
.Lendo: movq %mm3, %mm2
.Lende: psrlq %mm1, %mm2
movq %mm2, -8(%rdi)
emms
ret

View file

@ -0,0 +1,61 @@
/* AMD64 (x86_64) sub_n -- Subtract two limb vectors of the same length > 0 and store
* sum in a third limb vector.
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002, 2006 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_sub_n( mpi_ptr_t res_ptr, rdi
* mpi_ptr_t s1_ptr, rsi
* mpi_ptr_t s2_ptr, rdx
* mpi_size_t size) rcx
*/
.text
.globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
C_SYMBOL_NAME(_gcry_mpih_sub_n:)
leaq (%rsi,%rcx,8), %rsi
leaq (%rdi,%rcx,8), %rdi
leaq (%rdx,%rcx,8), %rdx
negq %rcx
xorl %eax, %eax /* clear cy */
ALIGN(4) /* minimal alignment for claimed speed */
.Loop: movq (%rsi,%rcx,8), %rax
movq (%rdx,%rcx,8), %r10
sbbq %r10, %rax
movq %rax, (%rdi,%rcx,8)
incq %rcx
jne .Loop
movq %rcx, %rax /* zero %rax */
adcq %rax, %rax
ret

View file

@ -0,0 +1,360 @@
# config.links - helper for ../configure -*- mode: sh -*-
# Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# Libgcrypt is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Libgcrypt 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser 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
#
# sourced by ../configure to get the list of files to link
# this should set $mpi_ln_list.
# Note: this is called from the above directory.
mpi_sflags=
mpi_extra_modules=
test -d ./mpi || mkdir ./mpi
# We grep the list of modules from the Makefile so that
# we don't need to maintain them here.
mpi_standard_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ {
if( $3 != "O" ) print $2 }' $srcdir/mpi/Makefile.am`
mpi_optional_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ {
if( $3 == "O" ) print $2 }' $srcdir/mpi/Makefile.am`
echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
echo "/* Host: ${host} */" >>./mpi/asm-syntax.h
if test "$try_asm_modules" = "yes" ; then
case "${host}" in
powerpc-apple-darwin* | \
i[34567]86*-*-openbsd[12]* | \
i[34567]86*-*-openbsd3.[0123]*)
echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
path=""
;;
i[3467]86*-*-openbsd* | \
i[3467]86*-*-freebsd*-elf | \
i[3467]86*-*-freebsd[3-9]* | \
i[3467]86*-*-freebsdelf* | \
i[3467]86*-*-netbsd* | \
i[3467]86*-*-k*bsd*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
;;
i586*-*-openbsd* | \
i586*-*-freebsd*-elf | \
i586*-*-freebsd[3-9]* | \
i586*-*-freebsdelf* | \
i586*-*-netbsd* | \
i586*-*-k*bsd* | \
pentium-*-netbsd* | \
pentiumpro-*-netbsd*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i586 i386"
;;
i[34]86*-*-bsdi4*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
;;
i[3467]86*-*-linuxaout* | \
i[3467]86*-*-linuxoldld* | \
i[3467]86*-*-*bsd*)
echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
;;
i586*-*-linuxaout* | \
i586*-*-linuxoldld* | \
i586*-*-*bsd*)
echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i586 i386"
;;
i[3467]86*-msdosdjgpp* | \
i[34]86*-apple-darwin*)
echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
;;
i586*-msdosdjgpp* | \
i[567]86*-apple-darwin*)
echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i586 i386"
;;
i[3467]86*-*-*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
;;
i586*-*-* | \
pentium-*-* | \
pentiumpro-*-*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i586 i386"
;;
x86_64-*-*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="amd64"
;;
alpha*-*-*)
echo '/* configured for alpha */' >>./mpi/asm-syntax.h
path="alpha"
mpi_extra_modules="udiv-qrnnd"
;;
hppa7000*-*-*)
echo '/* configured for HPPA (pa7000) */' >>./mpi/asm-syntax.h
path="hppa1.1 hppa"
mpi_extra_modules="udiv-qrnnd"
;;
hppa1.0*-*-*)
echo '/* configured for HPPA 1.0 */' >>./mpi/asm-syntax.h
path="hppa"
mpi_extra_modules="udiv-qrnnd"
;;
hppa*-*-*) # assume pa7100
echo '/* configured for HPPA (pa7100) */' >>./mpi/asm-syntax.h
path="pa7100 hppa1.1 hppa"
mpi_extra_modules="udiv-qrnnd"
;;
sparc64-*-linux-gnu)
echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
path=""
;;
sparc64-sun-solaris2*)
echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
path=""
;;
sparc64-*-netbsd* | sparc64-*-freebsd* | sparc64-*-openbsd*)
# There are no sparc64 assembler modules that work on the
# *BSDs, so use the generic C functions.
echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
path=""
;;
sparc64*-*-*)
echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
path=""
;;
sparc9*-*-* | \
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 sparc32"
;;
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"
;;
mips[34]*-*-* | \
mips*-*-irix6*)
echo '/* configured for MIPS3 */' >>./mpi/asm-syntax.h
path="mips3"
;;
mips*-*-*)
echo '/* configured for MIPS2 */' >>./mpi/asm-syntax.h
path="mips2"
;;
# Motorola 68k configurations. Let m68k mean 68020-68040.
# mc68000 or mc68060 configurations need to be specified explicitly
m680[234]0*-*-linuxaout* | \
m68k*-*-linuxaout*)
echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k/mc68020 m68k"
;;
m68060*-*-linuxaout*)
echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k"
;;
m680[234]0*-*-linux* | \
m68k*-*-linux*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
;;
m68060*-*-linux*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k"
;;
m68k-atari-mint)
echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k/mc68020 m68k"
;;
m68000*-*-* | \
m68060*-*-*)
echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k/mc68000"
;;
m680[234]0*-*-* | \
m68k*-*-*)
echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
path="m68k/mc68020 m68k"
;;
powerpc*-*-netbsd* | powerpc*-*-openbsd*)
echo '/* configured {Open,Net}BSD on powerpc */' >>./mpi/asm-syntax.h
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
mpi_sflags="-Wa,-mppc"
path="powerpc32"
;;
ppc620-*-* | \
powerpc64*-*-*)
mpi_sflags="-Wa,-mppc"
path="powerpc64"
;;
powerpc*-*-linux*)
echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
path="powerpc32"
;;
rs6000-*-aix[456789]* | \
rs6000-*-aix3.2.[456789])
mpi_sflags="-Wa,-mpwr"
path="power"
mpi_extra_modules="udiv-w-sdiv"
;;
rs6000-*-* | \
power-*-* | \
power2-*-*)
mpi_sflags="-Wa,-mppc"
path="power"
mpi_extra_modules="udiv-w-sdiv"
;;
powerpc-ibm-aix4.2.* )
# I am not sure about this one but a machine identified by
# powerpc-ibm-aix4.2.1.0 cannot use the powerpc32 code.
mpi_sflags="-Wa,-mpwr"
path="power"
mpi_extra_modules="udiv-w-sdiv"
;;
ppc601-*-*)
mpi_sflags="-Wa,-mppc"
path="power powerpc32"
;;
ppc60[234]*-*-*)
mpi_sflags="-Wa,-mppc"
path="powerpc32"
;;
powerpc*-*-*)
mpi_sflags="-Wa,-mppc"
path="powerpc32"
;;
*)
echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
path=""
;;
esac
else
echo '/* Assembler modules disabled on request */' >>./mpi/asm-syntax.h
path=""
fi
# Make sysdep.h
echo '/* created by config.links - do not edit */' >./mpi/sysdep.h
if test x$ac_cv_sys_symbol_underscore = xyes; then
cat <<EOF >>./mpi/sysdep.h
#if __STDC__
#define C_SYMBOL_NAME(name) _##name
#else
#define C_SYMBOL_NAME(name) _/**/name
#endif
EOF
else
cat <<EOF >>./mpi/sysdep.h
#define C_SYMBOL_NAME(name) name
EOF
fi
# Figure the required modules out
mpi_required_modules=$mpi_standard_modules
if test "$mpi_extra_modules" != ""; then
for fn in $mpi_extra_modules; do
for i in $mpi_optional_modules; do
if test "$fn" = "$i" ; then
mpi_required_modules="$mpi_required_modules $fn"
fi
done
done
fi
# Try to get file to link from the assembler subdirectory and
# if this fails get it from the generic subdirectory.
mpi_ln_list=
mpi_mod_list=
path=`echo "$mpi_extra_path $path generic" | tr ':' ' '`
echo '/* Created by config.links - do not edit */' >./mpi/mod-source-info.h
echo "/* Host: ${host} */" >>./mpi/mod-source-info.h
echo "static char mod_source_info[] =" >>./mpi/mod-source-info.h
for fn in $mpi_required_modules ; do
fnu=`echo $fn | sed 's/-/_/g'`
eval mpi_mod_c_${fnu}=no
eval mpi_mod_asm_${fnu}=no
for dir in $path ; do
rm -f $srcdir/mpi/$fn.[Sc]
if test -f $srcdir/mpi/$dir/$fn.S ; then
echo " \":$dir/$fn.S\"" >>./mpi/mod-source-info.h
mpi_ln_list="$mpi_ln_list mpi/$fn-asm.S:mpi/$dir/$fn.S"
eval mpi_mod_asm_${fnu}=yes
mpi_mod_list="$mpi_mod_list $fn"
break;
elif test -f $srcdir/mpi/$dir/$fn.c ; then
echo " \":$dir/$fn.c\"" >>./mpi/mod-source-info.h
mpi_ln_list="$mpi_ln_list mpi/$fn.c:mpi/$dir/$fn.c"
eval mpi_mod_c_${fnu}=yes
mpi_mod_list="$mpi_mod_list $fn"
break;
fi
done
done
echo " ;" >>./mpi/mod-source-info.h
# Same thing for the file which defines the limb size
path=`echo "$path generic" | tr ':' ' '`
for dir in $path ; do
rm -f $srcdir/mpi/mpi-asm-defs.h
if test -f $srcdir/mpi/$dir/mpi-asm-defs.h ; then
mpi_ln_list="$mpi_ln_list mpi/mpi-asm-defs.h:mpi/$dir/mpi-asm-defs.h"
break;
fi
done

View file

@ -0,0 +1,708 @@
/* ec.c - Elliptic Curve functions
Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of Libgcrypt.
Libgcrypt is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.
Libgcrypt 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
USA. */
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "mpi-internal.h"
#include "longlong.h"
#include "g10lib.h"
#define point_init(a) _gcry_mpi_ec_point_init ((a))
#define point_free(a) _gcry_mpi_ec_point_free ((a))
/* Object to represent a point in projective coordinates. */
/* Currently defined in mpi.h */
/* This context is used with all our EC functions. */
struct mpi_ec_ctx_s
{
/* Domain parameters. */
gcry_mpi_t p; /* Prime specifying the field GF(p). */
gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */
int a_is_pminus3; /* True if A = P - 3. */
/* Some often used constants. */
gcry_mpi_t one;
gcry_mpi_t two;
gcry_mpi_t three;
gcry_mpi_t four;
gcry_mpi_t eight;
gcry_mpi_t two_inv_p;
/* Scratch variables. */
gcry_mpi_t scratch[11];
/* Helper for fast reduction. */
/* int nist_nbits; /\* If this is a NIST curve, the number of bits. *\/ */
/* gcry_mpi_t s[10]; */
/* gcry_mpi_t c; */
};
/* Initialized a point object. gcry_mpi_ec_point_free shall be used
to release this object. */
void
_gcry_mpi_ec_point_init (mpi_point_t *p)
{
p->x = mpi_new (0);
p->y = mpi_new (0);
p->z = mpi_new (0);
}
/* Release a point object. */
void
_gcry_mpi_ec_point_free (mpi_point_t *p)
{
mpi_free (p->x); p->x = NULL;
mpi_free (p->y); p->y = NULL;
mpi_free (p->z); p->z = NULL;
}
/* Set the value from S into D. */
static void
point_set (mpi_point_t *d, mpi_point_t *s)
{
mpi_set (d->x, s->x);
mpi_set (d->y, s->y);
mpi_set (d->z, s->z);
}
static void
ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
{
mpi_addm (w, u, v, ctx->p);
}
static void
ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
{
mpi_subm (w, u, v, ctx->p);
}
static void
ec_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
{
#if 0
/* NOTE: This code works only for limb sizes of 32 bit. */
mpi_limb_t *wp, *sp;
if (ctx->nist_nbits == 192)
{
mpi_mul (w, u, v);
mpi_resize (w, 12);
wp = w->d;
sp = ctx->s[0]->d;
sp[0*2+0] = wp[0*2+0];
sp[0*2+1] = wp[0*2+1];
sp[1*2+0] = wp[1*2+0];
sp[1*2+1] = wp[1*2+1];
sp[2*2+0] = wp[2*2+0];
sp[2*2+1] = wp[2*2+1];
sp = ctx->s[1]->d;
sp[0*2+0] = wp[3*2+0];
sp[0*2+1] = wp[3*2+1];
sp[1*2+0] = wp[3*2+0];
sp[1*2+1] = wp[3*2+1];
sp[2*2+0] = 0;
sp[2*2+1] = 0;
sp = ctx->s[2]->d;
sp[0*2+0] = 0;
sp[0*2+1] = 0;
sp[1*2+0] = wp[4*2+0];
sp[1*2+1] = wp[4*2+1];
sp[2*2+0] = wp[4*2+0];
sp[2*2+1] = wp[4*2+1];
sp = ctx->s[3]->d;
sp[0*2+0] = wp[5*2+0];
sp[0*2+1] = wp[5*2+1];
sp[1*2+0] = wp[5*2+0];
sp[1*2+1] = wp[5*2+1];
sp[2*2+0] = wp[5*2+0];
sp[2*2+1] = wp[5*2+1];
ctx->s[0]->nlimbs = 6;
ctx->s[1]->nlimbs = 6;
ctx->s[2]->nlimbs = 6;
ctx->s[3]->nlimbs = 6;
mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
mpi_add (ctx->c, ctx->c, ctx->s[2]);
mpi_add (ctx->c, ctx->c, ctx->s[3]);
while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
mpi_sub ( ctx->c, ctx->c, ctx->p );
mpi_set (w, ctx->c);
}
else if (ctx->nist_nbits == 384)
{
int i;
mpi_mul (w, u, v);
mpi_resize (w, 24);
wp = w->d;
#define NEXT(a) do { ctx->s[(a)]->nlimbs = 12; \
sp = ctx->s[(a)]->d; \
i = 0; } while (0)
#define X(a) do { sp[i++] = wp[(a)];} while (0)
#define X0(a) do { sp[i++] = 0; } while (0)
NEXT(0);
X(0);X(1);X(2);X(3);X(4);X(5);X(6);X(7);X(8);X(9);X(10);X(11);
NEXT(1);
X0();X0();X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();
NEXT(2);
X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);X(23);
NEXT(3);
X(21);X(22);X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);
NEXT(4);
X0();X(23);X0();X(20);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);
NEXT(5);
X0();X0();X0();X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();
NEXT(6);
X(20);X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();
NEXT(7);
X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);
NEXT(8);
X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();X0();
NEXT(9);
X0();X0();X0();X(23);X(23);X0();X0();X0();X0();X0();X0();X0();
#undef X0
#undef X
#undef NEXT
mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
mpi_add (ctx->c, ctx->c, ctx->s[1]);
mpi_add (ctx->c, ctx->c, ctx->s[2]);
mpi_add (ctx->c, ctx->c, ctx->s[3]);
mpi_add (ctx->c, ctx->c, ctx->s[4]);
mpi_add (ctx->c, ctx->c, ctx->s[5]);
mpi_add (ctx->c, ctx->c, ctx->s[6]);
mpi_sub (ctx->c, ctx->c, ctx->s[7]);
mpi_sub (ctx->c, ctx->c, ctx->s[8]);
mpi_sub (ctx->c, ctx->c, ctx->s[9]);
while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
mpi_sub ( ctx->c, ctx->c, ctx->p );
while ( ctx->c->sign )
mpi_add ( ctx->c, ctx->c, ctx->p );
mpi_set (w, ctx->c);
}
else
#endif /*0*/
mpi_mulm (w, u, v, ctx->p);
}
static void
ec_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e,
mpi_ec_t ctx)
{
mpi_powm (w, b, e, ctx->p);
}
static void
ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx)
{
mpi_invm (x, a, ctx->p);
}
/* This function returns a new context for elliptic curve based on the
field GF(p). P is the prime specifying thuis field, A is the first
coefficient.
This context needs to be released using _gcry_mpi_ec_free. */
mpi_ec_t
_gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a)
{
int i;
mpi_ec_t ctx;
gcry_mpi_t tmp;
mpi_normalize (p);
mpi_normalize (a);
/* Fixme: Do we want to check some constraints? e.g.
a < p
*/
ctx = gcry_xcalloc (1, sizeof *ctx);
ctx->p = mpi_copy (p);
ctx->a = mpi_copy (a);
tmp = mpi_alloc_like (ctx->p);
mpi_sub_ui (tmp, ctx->p, 3);
ctx->a_is_pminus3 = !mpi_cmp (ctx->a, tmp);
mpi_free (tmp);
/* Allocate constants. */
ctx->one = mpi_alloc_set_ui (1);
ctx->two = mpi_alloc_set_ui (2);
ctx->three = mpi_alloc_set_ui (3);
ctx->four = mpi_alloc_set_ui (4);
ctx->eight = mpi_alloc_set_ui (8);
ctx->two_inv_p = mpi_alloc (0);
ec_invm (ctx->two_inv_p, ctx->two, ctx);
/* Allocate scratch variables. */
for (i=0; i< DIM(ctx->scratch); i++)
ctx->scratch[i] = mpi_alloc_like (ctx->p);
/* Prepare for fast reduction. */
/* FIXME: need a test for NIST values. However it does not gain us
any real advantage, for 384 bits it is actually slower than using
mpi_mulm. */
/* ctx->nist_nbits = mpi_get_nbits (ctx->p); */
/* if (ctx->nist_nbits == 192) */
/* { */
/* for (i=0; i < 4; i++) */
/* ctx->s[i] = mpi_new (192); */
/* ctx->c = mpi_new (192*2); */
/* } */
/* else if (ctx->nist_nbits == 384) */
/* { */
/* for (i=0; i < 10; i++) */
/* ctx->s[i] = mpi_new (384); */
/* ctx->c = mpi_new (384*2); */
/* } */
return ctx;
}
void
_gcry_mpi_ec_free (mpi_ec_t ctx)
{
int i;
if (!ctx)
return;
mpi_free (ctx->p);
mpi_free (ctx->a);
mpi_free (ctx->one);
mpi_free (ctx->two);
mpi_free (ctx->three);
mpi_free (ctx->four);
mpi_free (ctx->eight);
mpi_free (ctx->two_inv_p);
for (i=0; i< DIM(ctx->scratch); i++)
mpi_free (ctx->scratch[i]);
/* if (ctx->nist_nbits == 192) */
/* { */
/* for (i=0; i < 4; i++) */
/* mpi_free (ctx->s[i]); */
/* mpi_free (ctx->c); */
/* } */
/* else if (ctx->nist_nbits == 384) */
/* { */
/* for (i=0; i < 10; i++) */
/* mpi_free (ctx->s[i]); */
/* mpi_free (ctx->c); */
/* } */
gcry_free (ctx);
}
/* Compute the affine coordinates from the projective coordinates in
POINT. Set them into X and Y. If one coordinate is not required,
X or Y may be passed as NULL. CTX is the usual context. Returns: 0
on success or !0 if POINT is at infinity. */
int
_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
mpi_ec_t ctx)
{
gcry_mpi_t z1, z2, z3;
if (!mpi_cmp_ui (point->z, 0))
return -1;
z1 = mpi_new (0);
z2 = mpi_new (0);
ec_invm (z1, point->z, ctx); /* z1 = z^(-1) mod p */
ec_mulm (z2, z1, z1, ctx); /* z2 = z^(-2) mod p */
if (x)
ec_mulm (x, point->x, z2, ctx);
if (y)
{
z3 = mpi_new (0);
ec_mulm (z3, z2, z1, ctx); /* z3 = z^(-3) mod p */
ec_mulm (y, point->y, z3, ctx);
mpi_free (z3);
}
mpi_free (z2);
mpi_free (z1);
return 0;
}
/* RESULT = 2 * POINT */
void
_gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx)
{
#define x3 (result->x)
#define y3 (result->y)
#define z3 (result->z)
#define t1 (ctx->scratch[0])
#define t2 (ctx->scratch[1])
#define t3 (ctx->scratch[2])
#define l1 (ctx->scratch[3])
#define l2 (ctx->scratch[4])
#define l3 (ctx->scratch[5])
if (!mpi_cmp_ui (point->y, 0) || !mpi_cmp_ui (point->z, 0))
{
/* P_y == 0 || P_z == 0 => [1:1:0] */
mpi_set_ui (x3, 1);
mpi_set_ui (y3, 1);
mpi_set_ui (z3, 0);
}
else
{
if (ctx->a_is_pminus3) /* Use the faster case. */
{
/* L1 = 3(X - Z^2)(X + Z^2) */
/* T1: used for Z^2. */
/* T2: used for the right term. */
ec_powm (t1, point->z, ctx->two, ctx);
ec_subm (l1, point->x, t1, ctx);
ec_mulm (l1, l1, ctx->three, ctx);
ec_addm (t2, point->x, t1, ctx);
ec_mulm (l1, l1, t2, ctx);
}
else /* Standard case. */
{
/* L1 = 3X^2 + aZ^4 */
/* T1: used for aZ^4. */
ec_powm (l1, point->x, ctx->two, ctx);
ec_mulm (l1, l1, ctx->three, ctx);
ec_powm (t1, point->z, ctx->four, ctx);
ec_mulm (t1, t1, ctx->a, ctx);
ec_addm (l1, l1, t1, ctx);
}
/* Z3 = 2YZ */
ec_mulm (z3, point->y, point->z, ctx);
ec_mulm (z3, z3, ctx->two, ctx);
/* L2 = 4XY^2 */
/* T2: used for Y2; required later. */
ec_powm (t2, point->y, ctx->two, ctx);
ec_mulm (l2, t2, point->x, ctx);
ec_mulm (l2, l2, ctx->four, ctx);
/* X3 = L1^2 - 2L2 */
/* T1: used for L2^2. */
ec_powm (x3, l1, ctx->two, ctx);
ec_mulm (t1, l2, ctx->two, ctx);
ec_subm (x3, x3, t1, ctx);
/* L3 = 8Y^4 */
/* T2: taken from above. */
ec_powm (t2, t2, ctx->two, ctx);
ec_mulm (l3, t2, ctx->eight, ctx);
/* Y3 = L1(L2 - X3) - L3 */
ec_subm (y3, l2, x3, ctx);
ec_mulm (y3, y3, l1, ctx);
ec_subm (y3, y3, l3, ctx);
}
#undef x3
#undef y3
#undef z3
#undef t1
#undef t2
#undef t3
#undef l1
#undef l2
#undef l3
}
/* RESULT = P1 + P2 */
void
_gcry_mpi_ec_add_points (mpi_point_t *result,
mpi_point_t *p1, mpi_point_t *p2,
mpi_ec_t ctx)
{
#define x1 (p1->x )
#define y1 (p1->y )
#define z1 (p1->z )
#define x2 (p2->x )
#define y2 (p2->y )
#define z2 (p2->z )
#define x3 (result->x)
#define y3 (result->y)
#define z3 (result->z)
#define l1 (ctx->scratch[0])
#define l2 (ctx->scratch[1])
#define l3 (ctx->scratch[2])
#define l4 (ctx->scratch[3])
#define l5 (ctx->scratch[4])
#define l6 (ctx->scratch[5])
#define l7 (ctx->scratch[6])
#define l8 (ctx->scratch[7])
#define l9 (ctx->scratch[8])
#define t1 (ctx->scratch[9])
#define t2 (ctx->scratch[10])
if ( (!mpi_cmp (x1, x2)) && (!mpi_cmp (y1, y2)) && (!mpi_cmp (z1, z2)) )
{
/* Same point; need to call the duplicate function. */
_gcry_mpi_ec_dup_point (result, p1, ctx);
}
else if (!mpi_cmp_ui (z1, 0))
{
/* P1 is at infinity. */
mpi_set (x3, p2->x);
mpi_set (y3, p2->y);
mpi_set (z3, p2->z);
}
else if (!mpi_cmp_ui (z2, 0))
{
/* P2 is at infinity. */
mpi_set (x3, p1->x);
mpi_set (y3, p1->y);
mpi_set (z3, p1->z);
}
else
{
int z1_is_one = !mpi_cmp_ui (z1, 1);
int z2_is_one = !mpi_cmp_ui (z2, 1);
/* l1 = x1 z2^2 */
/* l2 = x2 z1^2 */
if (z2_is_one)
mpi_set (l1, x1);
else
{
ec_powm (l1, z2, ctx->two, ctx);
ec_mulm (l1, l1, x1, ctx);
}
if (z1_is_one)
mpi_set (l2, x1);
else
{
ec_powm (l2, z1, ctx->two, ctx);
ec_mulm (l2, l2, x2, ctx);
}
/* l3 = l1 - l2 */
ec_subm (l3, l1, l2, ctx);
/* l4 = y1 z2^3 */
ec_powm (l4, z2, ctx->three, ctx);
ec_mulm (l4, l4, y1, ctx);
/* l5 = y2 z1^3 */
ec_powm (l5, z1, ctx->three, ctx);
ec_mulm (l5, l5, y2, ctx);
/* l6 = l4 - l5 */
ec_subm (l6, l4, l5, ctx);
if (!mpi_cmp_ui (l3, 0))
{
if (!mpi_cmp_ui (l6, 0))
{
/* P1 and P2 are the same - use duplicate function. */
_gcry_mpi_ec_dup_point (result, p1, ctx);
}
else
{
/* P1 is the inverse of P2. */
mpi_set_ui (x3, 1);
mpi_set_ui (y3, 1);
mpi_set_ui (z3, 0);
}
}
else
{
/* l7 = l1 + l2 */
ec_addm (l7, l1, l2, ctx);
/* l8 = l4 + l5 */
ec_addm (l8, l4, l5, ctx);
/* z3 = z1 z2 l3 */
ec_mulm (z3, z1, z2, ctx);
ec_mulm (z3, z3, l3, ctx);
/* x3 = l6^2 - l7 l3^2 */
ec_powm (t1, l6, ctx->two, ctx);
ec_powm (t2, l3, ctx->two, ctx);
ec_mulm (t2, t2, l7, ctx);
ec_subm (x3, t1, t2, ctx);
/* l9 = l7 l3^2 - 2 x3 */
ec_mulm (t1, x3, ctx->two, ctx);
ec_subm (l9, t2, t1, ctx);
/* y3 = (l9 l6 - l8 l3^3)/2 */
ec_mulm (l9, l9, l6, ctx);
ec_powm (t1, l3, ctx->three, ctx); /* fixme: Use saved value*/
ec_mulm (t1, t1, l8, ctx);
ec_subm (y3, l9, t1, ctx);
ec_mulm (y3, y3, ctx->two_inv_p, ctx);
}
}
#undef x1
#undef y1
#undef z1
#undef x2
#undef y2
#undef z2
#undef x3
#undef y3
#undef z3
#undef l1
#undef l2
#undef l3
#undef l4
#undef l5
#undef l6
#undef l7
#undef l8
#undef l9
#undef t1
#undef t2
}
/* Scalar point multiplication - the main function for ECC. If takes
an integer SCALAR and a POINT as well as the usual context CTX.
RESULT will be set to the resulting point. */
void
_gcry_mpi_ec_mul_point (mpi_point_t *result,
gcry_mpi_t scalar, mpi_point_t *point,
mpi_ec_t ctx)
{
#if 0
/* Simple left to right binary method. GECC Algorithm 3.27 */
unsigned int nbits;
int i;
nbits = mpi_get_nbits (scalar);
mpi_set_ui (result->x, 1);
mpi_set_ui (result->y, 1);
mpi_set_ui (result->z, 0);
for (i=nbits-1; i >= 0; i--)
{
_gcry_mpi_ec_dup_point (result, result, ctx);
if (mpi_test_bit (scalar, i) == 1)
_gcry_mpi_ec_add_points (result, result, point, ctx);
}
#else
gcry_mpi_t x1, y1, z1, k, h, yy;
unsigned int i, loops;
mpi_point_t p1, p2, p1inv;
x1 = mpi_alloc_like (ctx->p);
y1 = mpi_alloc_like (ctx->p);
h = mpi_alloc_like (ctx->p);
k = mpi_copy (scalar);
yy = mpi_copy (point->y);
if ( mpi_is_neg (k) )
{
k->sign = 0;
ec_invm (yy, yy, ctx);
}
if (!mpi_cmp_ui (point->z, 1))
{
mpi_set (x1, point->x);
mpi_set (y1, yy);
}
else
{
gcry_mpi_t z2, z3;
z2 = mpi_alloc_like (ctx->p);
z3 = mpi_alloc_like (ctx->p);
ec_mulm (z2, point->z, point->z, ctx);
ec_mulm (z3, point->z, z2, ctx);
ec_invm (z2, z2, ctx);
ec_mulm (x1, point->x, z2, ctx);
ec_invm (z3, z3, ctx);
ec_mulm (y1, yy, z3, ctx);
mpi_free (z2);
mpi_free (z3);
}
z1 = mpi_copy (ctx->one);
mpi_mul (h, k, ctx->three); /* h = 3k */
loops = mpi_get_nbits (h);
mpi_set (result->x, point->x);
mpi_set (result->y, yy); mpi_free (yy); yy = NULL;
mpi_set (result->z, point->z);
p1.x = x1; x1 = NULL;
p1.y = y1; y1 = NULL;
p1.z = z1; z1 = NULL;
point_init (&p2);
point_init (&p1inv);
for (i=loops-2; i > 0; i--)
{
_gcry_mpi_ec_dup_point (result, result, ctx);
if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0)
{
point_set (&p2, result);
_gcry_mpi_ec_add_points (result, &p2, &p1, ctx);
}
if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1)
{
point_set (&p2, result);
/* Invert point: y = p - y mod p */
point_set (&p1inv, &p1);
ec_subm (p1inv.y, ctx->p, p1inv.y, ctx);
_gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx);
}
}
point_free (&p1);
point_free (&p2);
point_free (&p1inv);
mpi_free (h);
mpi_free (k);
#endif
}

View file

@ -0,0 +1,29 @@
# Manifest - checksums
# Copyright 2003 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# Libgcrypt is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser general Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Libgcrypt 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser 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
mpih-add1.c iQCVAwUAP+Lj2DEAnp832S/7AQKn/AQAwQLWggl6zNQ5EZ+lE+jKV8W3FsogW3/6tp9T5rrSR5JnlWyoHQ9/Pu4knOcLjS6nIfVOiAEifu3nuIysQr9jDSSSJA2LylSUBSXKLKDamPsOCwXOLxiZODslJT3CCGAUtLvXJrWDbTZQrkEuwnLnjQFDzuA7iY9JLrG9kAoXD6Q==WoWm
mpih-mul1.c iQCVAwUAP+LkCTEAnp832S/7AQKFVQP+MhBNjcY73JtnsHZfnaVZq3TiKwN151cWV51nDc1RnTaMhSIFeuNlj3vNML2W0Gn8n+GnyiWE2XXdQEaik6BL02eekUn9aq7I/rdpnTHuOjQPK1uwjuNl8RuJ9YrERBAxq4oB71f+iwMab8dsMSUlVC+NdeAocRqLLgnR/efkdLc==2Tkb
mpih-mul2.c iQCVAwUAP+LkMjEAnp832S/7AQLPeAQAqmRzxFe/mDqTdZr/pTXT8RVyB1vKB0Ei2THV05BxmI4OPv39uysfFpLMt/INsX7AGqdOlj4jOZ/qNaFXR1ceMrlSXvo8u/epk6rCXFp82kM7Qs983LjoP//PrMCkYkXwblaVrgUGiBUCbuPMliWTK6qKkxxXtEfqZ7nVbEWdBx8==Kwhl
mpih-mul3.c iQCVAwUAP+LkVDEAnp832S/7AQL91gP/Qd5iZWxRiN5DdEIVHAedoNvl23NPrT2UUdXvnSK49DpplTxkLiMBj0WqCayG/YIET2NpMRCeLvAZNcSt6lOm0bSZDYo1Hv/N+UoqD3V1McjY16REBv/nnPaMWMZcx7rl5yKTVZiX2PgV6oQOL7Yfrt5ZIOlrHBRs9S2/zcCaVz0==9BQe
mpih-lshift.c iQCVAwUAP+LlATEAnp832S/7AQIACAQAhMrpx0SRXE/LN1NkjMO9n74nMrvmzYJyru0gw2O4BYrUPvD/LWGju2FZaggKV0IBjmi0cDoCrNeK9EGjKOO1lfgODbX2IZ1LUhr9jDuMj0QRqj6T9YkAFYTNUk4GfpwIf7T6Ybo7c78Jx93PidCJt7d39eMMEalooC7LZ4IU3NM==nZ4k
mpih-rshift.c iQCVAwUAP+LlIjEAnp832S/7AQKiuAP/eYC2ZScd+taBx/kNzRvGjA0eAXvORMkMLV6Ot+OXVzVUi04eoP2yXdxSNFKwUj12p8GWXkdoMG3aOGBKg2a7bY5Q5RUho3hUWb9UsVYVUfXLf7IOTt/3a6MLh2CmV5dFPWJmSlbCyQRcn6n/fLDeJ3A2bWTS/BhqGfpOXUIU1ws==jCf8
mpih-sub1.c iQCVAwUAP+LlZzEAnp832S/7AQIEPgP/dLHTDRbPrYJhsLp9SjGstU1M8/IC5XytcDtO3NQeu4mx6vaXjpujtsTvKIbX4QL5IahNntVVKv1xFLEm2yFg7L2ns0uD/mfwGgOhCG1j2o/SaTAWP5KxP7ae5UDcZl2w6NWvEuMj9t32zmziAZjP8W73A37FUspeRDYiL9sQzkI==QQzk
udiv-w-sdiv.c iQCVAwUAP+Lk0TEAnp832S/7AQICXAQAsxe1SQD4+xZaZTqBC0V9Cyuo0mrdccnRFzthOtm0ARwKFXU2cuLW/ZBOkmeWOVmOFhBp22/I8dEGYnMA3gcfmOMCpNu9i9zk/XHfptdunA1MnOe3GsoWgfHL0rhpAyPhp/X043ICB41NElnnuxADuQQlD4Z1fca5ygYxMr2crJg==EI/6
mpi-asm-defs.h iQCVAwUAP+LkgDEAnp832S/7AQK0FgQAxJZ7xvXhoZa33GWe23LRb3asrno/loZSyAIXrntqtVH8M3pEsCY0OyW4ry4hX2RnxpuhRCM/PdRNLG3xXyMSVIhkHU8WVRLqzF2LLjEkyU3cAmHnnTQ9aO/XpUWtJGTZ8q2bv7ZsAEi4aPl0p6KhPXcPgM9vQ2XcyOPn3Dl0d6Q==xpjI
$names$ iQCVAwUAP+LmNDEAnp832S/7AQJa+gP+KQNJpbNOgc+s2UX+Ya2gDaOFcAROImIllhg3ej8EaBF8xxdHmWT1zaKwTwi3moEEleykMR104YAGWyQeMbFYiuPPBW+ohrT6KxRBVJpIA9auOOqqJMyglZyoR3Hv7gduVYUW1h/DebnqiKXKEfzQDFqYuT0ayuteoOR4B5NICbE==nLSh

View file

@ -0,0 +1,11 @@
Manifest
mpih-add1.c
mpih-mul1.c
mpih-mul2.c
mpih-mul3.c
mpih-lshift.c
mpih-rshift.c
mpih-sub1.c
udiv-w-sdiv.c
mpi-asm-defs.h

View file

@ -0,0 +1,10 @@
/* This file defines some basic constants for the MPI machinery. We
* need to define the types on a per-CPU basis, so it is done with
* this file here. */
#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)

View file

@ -0,0 +1,65 @@
/* mpihelp-add_1.c - MPI helper functions
* Copyright (C) 1994, 1996, 1997, 1998,
* 2000, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "mpi-internal.h"
#include "longlong.h"
mpi_limb_t
_gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
mpi_ptr_t s2_ptr, mpi_size_t size)
{
mpi_limb_t x, y, cy;
mpi_size_t j;
/* The loop counter and index J goes from -SIZE to -1. This way
the loop becomes faster. */
j = -size;
/* Offset the base pointers to compensate for the negative indices. */
s1_ptr -= j;
s2_ptr -= j;
res_ptr -= j;
cy = 0;
do
{
y = s2_ptr[j];
x = s1_ptr[j];
y += cy; /* add previous carry to one addend */
cy = y < cy; /* get out carry from that addition */
y += x; /* add other addend */
cy += y < x; /* get out carry from that add, combine */
res_ptr[j] = y;
}
while ( ++j );
return cy;
}

View file

@ -0,0 +1,68 @@
/* mpi-lshift.c - MPI helper functions
* Copyright (C) 1994, 1996, 1998, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "mpi-internal.h"
/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
* and store the USIZE least significant digits of the result at WP.
* Return the bits shifted out from the most significant digit.
*
* Argument constraints:
* 1. 0 < CNT < BITS_PER_MP_LIMB
* 2. If the result is to be written over the input, WP must be >= UP.
*/
mpi_limb_t
_gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
unsigned int cnt)
{
mpi_limb_t high_limb, low_limb;
unsigned sh_1, sh_2;
mpi_size_t i;
mpi_limb_t retval;
sh_1 = cnt;
wp += 1;
sh_2 = BITS_PER_MPI_LIMB - sh_1;
i = usize - 1;
low_limb = up[i];
retval = low_limb >> sh_2;
high_limb = low_limb;
while ( --i >= 0 )
{
low_limb = up[i];
wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
high_limb = low_limb;
}
wp[i] = high_limb << sh_1;
return retval;
}

View file

@ -0,0 +1,62 @@
/* mpihelp-mul_1.c - MPI helper functions
* Copyright (C) 1994, 1996, 1997, 1998, 2001,
* 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "mpi-internal.h"
#include "longlong.h"
mpi_limb_t
_gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
mpi_limb_t s2_limb)
{
mpi_limb_t cy_limb;
mpi_size_t j;
mpi_limb_t prod_high, prod_low;
/* The loop counter and index J goes from -S1_SIZE to -1. This way
* the loop becomes faster. */
j = -s1_size;
/* Offset the base pointers to compensate for the negative indices. */
s1_ptr -= j;
res_ptr -= j;
cy_limb = 0;
do
{
umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
prod_low += cy_limb;
cy_limb = (prod_low < cy_limb?1:0) + prod_high;
res_ptr[j] = prod_low;
}
while( ++j );
return cy_limb;
}

View file

@ -0,0 +1,68 @@
/* mpih-mul2.c - MPI helper functions
* Copyright (C) 1994, 1996, 1997, 1998, 2001,
* 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "mpi-internal.h"
#include "longlong.h"
mpi_limb_t
_gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
mpi_size_t s1_size, mpi_limb_t s2_limb)
{
mpi_limb_t cy_limb;
mpi_size_t j;
mpi_limb_t prod_high, prod_low;
mpi_limb_t x;
/* The loop counter and index J goes from -SIZE to -1. This way
* the loop becomes faster. */
j = -s1_size;
res_ptr -= j;
s1_ptr -= j;
cy_limb = 0;
do
{
umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
prod_low += cy_limb;
cy_limb = (prod_low < cy_limb?1:0) + prod_high;
x = res_ptr[j];
prod_low = x + prod_low;
cy_limb += prod_low < x?1:0;
res_ptr[j] = prod_low;
}
while ( ++j );
return cy_limb;
}

View file

@ -0,0 +1,68 @@
/* mpih-mul3.c - MPI helper functions
* Copyright (C) 1994, 1996, 1997, 1998, 2001,
* 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "mpi-internal.h"
#include "longlong.h"
mpi_limb_t
_gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
mpi_size_t s1_size, mpi_limb_t s2_limb)
{
mpi_limb_t cy_limb;
mpi_size_t j;
mpi_limb_t prod_high, prod_low;
mpi_limb_t x;
/* The loop counter and index J goes from -SIZE to -1. This way
* the loop becomes faster. */
j = -s1_size;
res_ptr -= j;
s1_ptr -= j;
cy_limb = 0;
do
{
umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb);
prod_low += cy_limb;
cy_limb = (prod_low < cy_limb?1:0) + prod_high;
x = res_ptr[j];
prod_low = x - prod_low;
cy_limb += prod_low > x?1:0;
res_ptr[j] = prod_low;
}
while( ++j );
return cy_limb;
}

View file

@ -0,0 +1,67 @@
/* mpih-rshift.c - MPI helper functions
* Copyright (C) 1994, 1996, 1998, 1999,
* 2000, 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "mpi-internal.h"
/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
* and store the USIZE least significant limbs of the result at WP.
* The bits shifted out to the right are returned.
*
* Argument constraints:
* 1. 0 < CNT < BITS_PER_MP_LIMB
* 2. If the result is to be written over the input, WP must be <= UP.
*/
mpi_limb_t
_gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt)
{
mpi_limb_t high_limb, low_limb;
unsigned sh_1, sh_2;
mpi_size_t i;
mpi_limb_t retval;
sh_1 = cnt;
wp -= 1;
sh_2 = BITS_PER_MPI_LIMB - sh_1;
high_limb = up[0];
retval = high_limb << sh_2;
low_limb = high_limb;
for (i=1; i < usize; i++)
{
high_limb = up[i];
wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
low_limb = high_limb;
}
wp[i] = low_limb >> sh_1;
return retval;
}

View file

@ -0,0 +1,66 @@
/* mpihelp-add_2.c - MPI helper functions
* Copyright (C) 1994, 1996, 1997, 1998, 2001,
* 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "mpi-internal.h"
#include "longlong.h"
mpi_limb_t
_gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
mpi_ptr_t s2_ptr, mpi_size_t size)
{
mpi_limb_t x, y, cy;
mpi_size_t j;
/* The loop counter and index J goes from -SIZE to -1. This way
the loop becomes faster. */
j = -size;
/* Offset the base pointers to compensate for the negative indices. */
s1_ptr -= j;
s2_ptr -= j;
res_ptr -= j;
cy = 0;
do
{
y = s2_ptr[j];
x = s1_ptr[j];
y += cy; /* add previous carry to subtrahend */
cy = y < cy; /* get out carry from that addition */
y = x - y; /* main subtract */
cy += y > x; /* get out carry from the subtract, combine */
res_ptr[j] = y;
}
while( ++j );
return cy;
}

View file

@ -0,0 +1,133 @@
/* mpih-w-sdiv -- implement udiv_qrnnd on machines with only signed
* division.
* Copyright (C) 1992, 1994, 1996, 1998, 2002 Free Software Foundation, Inc.
* Contributed by Peter L. Montgomery.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include "mpi-internal.h"
#include "longlong.h"
#if 0 /* not yet ported to MPI */
mpi_limb_t
mpihelp_udiv_w_sdiv( mpi_limp_t *rp,
mpi_limp_t *a1,
mpi_limp_t *a0,
mpi_limp_t *d )
{
mp_limb_t q, r;
mp_limb_t c0, c1, b1;
if ((mpi_limb_signed_t) d >= 0)
{
if (a1 < d - a1 - (a0 >> (BITS_PER_MP_LIMB - 1)))
{
/* dividend, divisor, and quotient are nonnegative */
sdiv_qrnnd (q, r, a1, a0, d);
}
else
{
/* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (BITS_PER_MP_LIMB - 1));
/* Divide (c1*2^32 + c0) by d */
sdiv_qrnnd (q, r, c1, c0, d);
/* Add 2^31 to quotient */
q += (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
}
}
else
{
b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
c1 = a1 >> 1; /* A/2 */
c0 = (a1 << (BITS_PER_MP_LIMB - 1)) + (a0 >> 1);
if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
{
sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
if ((d & 1) != 0)
{
if (r >= q)
r = r - q;
else if (q - r <= d)
{
r = r - q + d;
q--;
}
else
{
r = r - q + 2*d;
q -= 2;
}
}
}
else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
{
c1 = (b1 - 1) - c1;
c0 = ~c0; /* logical NOT */
sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
q = ~q; /* (A/2)/b1 */
r = (b1 - 1) - r;
r = 2*r + (a0 & 1); /* A/(2*b1) */
if ((d & 1) != 0)
{
if (r >= q)
r = r - q;
else if (q - r <= d)
{
r = r - q + d;
q--;
}
else
{
r = r - q + 2*d;
q -= 2;
}
}
}
else /* Implies c1 = b1 */
{ /* Hence a1 = d - 1 = 2*b1 - 1 */
if (a0 >= -d)
{
q = -1;
r = a0 + d;
}
else
{
q = -2;
r = a0 + 2*d;
}
}
}
*rp = r;
return q;
}
#endif

View file

@ -0,0 +1,84 @@
This directory contains mpn functions for various HP PA-RISC chips. Code
that runs faster on the PA7100 and later implementations, is in the pa7100
directory.
RELEVANT OPTIMIZATION ISSUES
Load and Store timing
On the PA7000 no memory instructions can issue the two cycles after a store.
For the PA7100, this is reduced to one cycle.
The PA7100 has a lookup-free cache, so it helps to schedule loads and the
dependent instruction really far from each other.
STATUS
1. mpn_mul_1 could be improved to 6.5 cycles/limb on the PA7100, using the
instructions bwlow (but some sw pipelining is needed to avoid the
xmpyu-fstds delay):
fldds s1_ptr
xmpyu
fstds N(%r30)
xmpyu
fstds N(%r30)
ldws N(%r30)
ldws N(%r30)
ldws N(%r30)
ldws N(%r30)
addc
stws res_ptr
addc
stws res_ptr
addib Loop
2. mpn_addmul_1 could be improved from the current 10 to 7.5 cycles/limb
(asymptotically) on the PA7100, using the instructions below. With proper
sw pipelining and the unrolling level below, the speed becomes 8
cycles/limb.
fldds s1_ptr
fldds s1_ptr
xmpyu
fstds N(%r30)
xmpyu
fstds N(%r30)
xmpyu
fstds N(%r30)
xmpyu
fstds N(%r30)
ldws N(%r30)
ldws N(%r30)
ldws N(%r30)
ldws N(%r30)
ldws N(%r30)
ldws N(%r30)
ldws N(%r30)
ldws N(%r30)
addc
addc
addc
addc
addc %r0,%r0,cy-limb
ldws res_ptr
ldws res_ptr
ldws res_ptr
ldws res_ptr
add
stws res_ptr
addc
stws res_ptr
addc
stws res_ptr
addc
stws res_ptr
addib

View file

@ -0,0 +1,7 @@
README
udiv-qrnnd.S
mpih-add1.S
mpih-sub1.S
mpih-lshift.S
mpih-rshift.S

View file

@ -0,0 +1,70 @@
/* hppa add_n -- Add two limb vectors of the same length > 0 and store
* sum in a third limb vector.
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Fee Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
/*******************
* mpi_limb_t
* _gcry_mpih_add_n( mpi_ptr_t res_ptr, (gr26)
* mpi_ptr_t s1_ptr, (gr25)
* mpi_ptr_t s2_ptr, (gr24)
* mpi_size_t size) (gr23)
*
* One might want to unroll this as for other processors, but it turns
* out that the data cache contention after a store makes such
* unrolling useless. We can't come under 5 cycles/limb anyway.
*/
.code
.export _gcry_mpih_add_n
.label _gcry_mpih_add_n
.proc
.callinfo frame=0,no_calls
.entry
ldws,ma 4(0,%r25),%r20
ldws,ma 4(0,%r24),%r19
addib,= -1,%r23,L$end ; check for (SIZE == 1)
add %r20,%r19,%r28 ; add first limbs ignoring cy
.label L$loop
ldws,ma 4(0,%r25),%r20
ldws,ma 4(0,%r24),%r19
stws,ma %r28,4(0,%r26)
addib,<> -1,%r23,L$loop
addc %r20,%r19,%r28
.label L$end
stws %r28,0(0,%r26)
bv 0(%r2)
addc %r0,%r0,%r28
.exit
.procend

View file

@ -0,0 +1,77 @@
/* hppa lshift
*
* Copyright (C) 1992, 1994, 1998
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*/
/*******************
* mpi_limb_t
* _gcry_mpih_lshift( mpi_ptr_t wp, (gr26)
* mpi_ptr_t up, (gr25)
* mpi_size_t usize, (gr24)
* unsigned cnt) (gr23)
*/
.code
.export _gcry_mpih_lshift
.label _gcry_mpih_lshift
.proc
.callinfo frame=64,no_calls
.entry
sh2add %r24,%r25,%r25
sh2add %r24,%r26,%r26
ldws,mb -4(0,%r25),%r22
subi 32,%r23,%r1
mtsar %r1
addib,= -1,%r24,L$0004
vshd %r0,%r22,%r28 ; compute carry out limb
ldws,mb -4(0,%r25),%r29
addib,= -1,%r24,L$0002
vshd %r22,%r29,%r20
.label L$loop
ldws,mb -4(0,%r25),%r22
stws,mb %r20,-4(0,%r26)
addib,= -1,%r24,L$0003
vshd %r29,%r22,%r20
ldws,mb -4(0,%r25),%r29
stws,mb %r20,-4(0,%r26)
addib,<> -1,%r24,L$loop
vshd %r22,%r29,%r20
.label L$0002
stws,mb %r20,-4(0,%r26)
vshd %r29,%r0,%r20
bv 0(%r2)
stw %r20,-4(0,%r26)
.label L$0003
stws,mb %r20,-4(0,%r26)
.label L$0004
vshd %r22,%r0,%r20
bv 0(%r2)
stw %r20,-4(0,%r26)
.exit
.procend

View file

@ -0,0 +1,73 @@
/* hppa rshift
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*/
/*******************
* mpi_limb_t
* _gcry_mpih_rshift( mpi_ptr_t wp, (gr26)
* mpi_ptr_t up, (gr25)
* mpi_size_t usize, (gr24)
* unsigned cnt) (gr23)
*/
.code
.export _gcry_mpih_rshift
.label _gcry_mpih_rshift
.proc
.callinfo frame=64,no_calls
.entry
ldws,ma 4(0,%r25),%r22
mtsar %r23
addib,= -1,%r24,L$r004
vshd %r22,%r0,%r28 ; compute carry out limb
ldws,ma 4(0,%r25),%r29
addib,= -1,%r24,L$r002
vshd %r29,%r22,%r20
.label L$roop
ldws,ma 4(0,%r25),%r22
stws,ma %r20,4(0,%r26)
addib,= -1,%r24,L$r003
vshd %r22,%r29,%r20
ldws,ma 4(0,%r25),%r29
stws,ma %r20,4(0,%r26)
addib,<> -1,%r24,L$roop
vshd %r29,%r22,%r20
.label L$r002
stws,ma %r20,4(0,%r26)
vshd %r0,%r29,%r20
bv 0(%r2)
stw %r20,0(0,%r26)
.label L$r003
stws,ma %r20,4(0,%r26)
.label L$r004
vshd %r0,%r22,%r20
bv 0(%r2)
stw %r20,0(0,%r26)
.exit
.procend

View file

@ -0,0 +1,78 @@
/* hppa sub_n -- Sub two limb vectors of the same length > 0 and store
* sum in a third limb vector.
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (gr26)
* mpi_ptr_t s1_ptr, (gr25)
* mpi_ptr_t s2_ptr, (gr24)
* mpi_size_t size) (gr23)
*
* One might want to unroll this as for other processors, but it turns
* out that the data cache contention after a store makes such
* unrolling useless. We can't come under 5 cycles/limb anyway.
*/
.code
.export _gcry_mpih_sub_n
.label _gcry_mpih_sub_n
.proc
.callinfo frame=0,no_calls
.entry
ldws,ma 4(0,%r25),%r20
ldws,ma 4(0,%r24),%r19
addib,= -1,%r23,L$end ; check for (SIZE == 1)
sub %r20,%r19,%r28 ; subtract first limbs ignoring cy
.label L$loop
ldws,ma 4(0,%r25),%r20
ldws,ma 4(0,%r24),%r19
stws,ma %r28,4(0,%r26)
addib,<> -1,%r23,L$loop
subb %r20,%r19,%r28
.label L$end
stws %r28,0(0,%r26)
addc %r0,%r0,%r28
bv 0(%r2)
subi 1,%r28,%r28
.exit
.procend

View file

@ -0,0 +1,297 @@
/* HP-PA __udiv_qrnnd division support, used from longlong.h.
* This version runs fast on pre-PA7000 CPUs.
*
* Copyright (C) 1993, 1994, 1998, 2001,
* 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
/* INPUT PARAMETERS
* rem_ptr gr26
* n1 gr25
* n0 gr24
* d gr23
*
* The code size is a bit excessive. We could merge the last two ds;addc
* sequences by simply moving the "bb,< Odd" instruction down. The only
* trouble is the FFFFFFFF code that would need some hacking.
*/
.code
.export __udiv_qrnnd
.label __udiv_qrnnd
.proc
.callinfo frame=0,no_calls
.entry
comb,< %r23,0,L$largedivisor
sub %r0,%r23,%r1 ; clear cy as side-effect
ds %r0,%r1,%r0
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r24
ds %r25,%r23,%r25
addc %r24,%r24,%r28
ds %r25,%r23,%r25
comclr,>= %r25,%r0,%r0
addl %r25,%r23,%r25
stws %r25,0(0,%r26)
bv 0(%r2)
addc %r28,%r28,%r28
.label L$largedivisor
extru %r24,31,1,%r19 ; r19 = n0 & 1
bb,< %r23,31,L$odd
extru %r23,30,31,%r22 ; r22 = d >> 1
shd %r25,%r24,1,%r24 ; r24 = new n0
extru %r25,30,31,%r25 ; r25 = new n1
sub %r0,%r22,%r21
ds %r0,%r21,%r0
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
comclr,>= %r25,%r0,%r0
addl %r25,%r22,%r25
sh1addl %r25,%r19,%r25
stws %r25,0(0,%r26)
bv 0(%r2)
addc %r24,%r24,%r28
.label L$odd
addib,sv,n 1,%r22,L$FF.. ; r22 = (d / 2 + 1)
shd %r25,%r24,1,%r24 ; r24 = new n0
extru %r25,30,31,%r25 ; r25 = new n1
sub %r0,%r22,%r21
ds %r0,%r21,%r0
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r24
ds %r25,%r22,%r25
addc %r24,%r24,%r28
comclr,>= %r25,%r0,%r0
addl %r25,%r22,%r25
sh1addl %r25,%r19,%r25
; We have computed (n1,,n0) / (d + 1), q' = r28, r' = r25
add,nuv %r28,%r25,%r25
addl %r25,%r1,%r25
addc %r0,%r28,%r28
sub,<< %r25,%r23,%r0
addl %r25,%r1,%r25
stws %r25,0(0,%r26)
bv 0(%r2)
addc %r0,%r28,%r28
; This is just a special case of the code above.
; We come here when d == 0xFFFFFFFF
.label L$FF..
add,uv %r25,%r24,%r24
sub,<< %r24,%r23,%r0
ldo 1(%r24),%r24
stws %r24,0(0,%r26)
bv 0(%r2)
addc %r0,%r25,%r28
.exit
.procend

View file

@ -0,0 +1,28 @@
# Manifest - checksums
# Copyright 2003 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# Libgcrypt is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser general Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Libgcrypt 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser 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
mpih-add1.S
mpih-mul1.S
mpih-mul2.S
mpih-mul3.S
mpih-lshift.S
mpih-rshift.S
mpih-sub1.S
syntax.h
$names$ iQCVAwUAP+LmOTEAnp832S/7AQJZmgQA1+GIl7rXiEY00y5xD2kG5Lm2QD6c9aBME8hTl812OEcj0ul/QSpdv8E2NEKooifr4SiLVhEVfLNaLqAgN3cIsttn3rRX3/pMC5JwSKHDJPsUbpN9tzb5dr2YC9GG9m8xngAQrN11IQPnGfvFLJK+oDnEMIAeHDpOnX9NeQPDAQA==bnOy

View file

@ -0,0 +1,10 @@
Manifest
mpih-add1.S
mpih-mul1.S
mpih-mul2.S
mpih-mul3.S
mpih-lshift.S
mpih-rshift.S
mpih-sub1.S
syntax.h

View file

@ -0,0 +1,116 @@
/* i80386 add_n -- Add two limb vectors of the same length > 0 and store
* sum in a third limb vector.
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_ptr_t s2_ptr, (sp + 12)
* mpi_size_t size) (sp + 16)
*/
.text
ALIGN (3)
.globl C_SYMBOL_NAME(_gcry_mpih_add_n)
C_SYMBOL_NAME(_gcry_mpih_add_n:)
pushl %edi
pushl %esi
movl 12(%esp),%edi /* res_ptr */
movl 16(%esp),%esi /* s1_ptr */
movl 20(%esp),%edx /* s2_ptr */
movl 24(%esp),%ecx /* size */
movl %ecx,%eax
shrl $3,%ecx /* compute count for unrolled loop */
negl %eax
andl $7,%eax /* get index where to start loop */
jz Loop /* necessary special case for 0 */
incl %ecx /* adjust loop count */
shll $2,%eax /* adjustment for pointers... */
subl %eax,%edi /* ... since they are offset ... */
subl %eax,%esi /* ... by a constant when we ... */
subl %eax,%edx /* ... enter the loop */
shrl $2,%eax /* restore previous value */
#ifdef PIC
/* Calculate start address in loop for PIC. Due to limitations in some
assemblers, Loop-L0-3 cannot be put into the leal */
call L0
L0: leal (%eax,%eax,8),%eax
addl (%esp),%eax
addl $(Loop-L0-3),%eax
addl $4,%esp
#else
/* Calculate start address in loop for non-PIC. */
leal (Loop - 3)(%eax,%eax,8),%eax
#endif
jmp *%eax /* jump into loop */
ALIGN (3)
Loop: movl (%esi),%eax
adcl (%edx),%eax
movl %eax,(%edi)
movl 4(%esi),%eax
adcl 4(%edx),%eax
movl %eax,4(%edi)
movl 8(%esi),%eax
adcl 8(%edx),%eax
movl %eax,8(%edi)
movl 12(%esi),%eax
adcl 12(%edx),%eax
movl %eax,12(%edi)
movl 16(%esi),%eax
adcl 16(%edx),%eax
movl %eax,16(%edi)
movl 20(%esi),%eax
adcl 20(%edx),%eax
movl %eax,20(%edi)
movl 24(%esi),%eax
adcl 24(%edx),%eax
movl %eax,24(%edi)
movl 28(%esi),%eax
adcl 28(%edx),%eax
movl %eax,28(%edi)
leal 32(%edi),%edi
leal 32(%esi),%esi
leal 32(%edx),%edx
decl %ecx
jnz Loop
sbbl %eax,%eax
negl %eax
popl %esi
popl %edi
ret

View file

@ -0,0 +1,94 @@
/* i80386 lshift
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
* mpi_ptr_t up, (sp + 8)
* mpi_size_t usize, (sp + 12)
* unsigned cnt) (sp + 16)
*/
.text
ALIGN (3)
.globl C_SYMBOL_NAME(_gcry_mpih_lshift)
C_SYMBOL_NAME(_gcry_mpih_lshift:)
pushl %edi
pushl %esi
pushl %ebx
movl 16(%esp),%edi /* res_ptr */
movl 20(%esp),%esi /* s_ptr */
movl 24(%esp),%edx /* size */
movl 28(%esp),%ecx /* cnt */
subl $4,%esi /* adjust s_ptr */
movl (%esi,%edx,4),%ebx /* read most significant limb */
xorl %eax,%eax
shldl %cl,%ebx,%eax /* compute carry limb */
decl %edx
jz Lend
pushl %eax /* push carry limb onto stack */
testb $1,%dl
jnz L1 /* enter loop in the middle */
movl %ebx,%eax
ALIGN (3)
Loop: movl (%esi,%edx,4),%ebx /* load next lower limb */
shldl %cl,%ebx,%eax /* compute result limb */
movl %eax,(%edi,%edx,4) /* store it */
decl %edx
L1: movl (%esi,%edx,4),%eax
shldl %cl,%eax,%ebx
movl %ebx,(%edi,%edx,4)
decl %edx
jnz Loop
shll %cl,%eax /* compute least significant limb */
movl %eax,(%edi) /* store it */
popl %eax /* pop carry limb */
popl %ebx
popl %esi
popl %edi
ret
Lend: shll %cl,%ebx /* compute least significant limb */
movl %ebx,(%edi) /* store it */
popl %ebx
popl %esi
popl %edi
ret

View file

@ -0,0 +1,84 @@
/* i80386 mul_1 -- Multiply a limb vector with a limb and store
* the result in a second limb vector.
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_size_t s1_size, (sp + 12)
* mpi_limb_t s2_limb) (sp + 16)
*/
#define res_ptr edi
#define s1_ptr esi
#define size ecx
#define s2_limb ebp
TEXT
ALIGN (3)
GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
C_SYMBOL_NAME(_gcry_mpih_mul_1:)
INSN1(push,l ,R(edi))
INSN1(push,l ,R(esi))
INSN1(push,l ,R(ebx))
INSN1(push,l ,R(ebp))
INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
INSN2(mov,l ,R(size),MEM_DISP(esp,28))
INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
INSN1(neg,l ,R(size))
INSN2(xor,l ,R(ebx),R(ebx))
ALIGN (3)
Loop:
INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
INSN1(mul,l ,R(s2_limb))
INSN2(add,l ,R(eax),R(ebx))
INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(eax))
INSN2(adc,l ,R(edx),$0)
INSN2(mov,l ,R(ebx),R(edx))
INSN1(inc,l ,R(size))
INSN1(jnz, ,Loop)
INSN2(mov,l ,R(eax),R(ebx))
INSN1(pop,l ,R(ebp))
INSN1(pop,l ,R(ebx))
INSN1(pop,l ,R(esi))
INSN1(pop,l ,R(edi))
ret

View file

@ -0,0 +1,86 @@
/* i80386 addmul_1 -- Multiply a limb vector with a limb and add
* the result to a second limb vector.
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_size_t s1_size, (sp + 12)
* mpi_limb_t s2_limb) (sp + 16)
*/
#define res_ptr edi
#define s1_ptr esi
#define size ecx
#define s2_limb ebp
TEXT
ALIGN (3)
GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
INSN1(push,l ,R(edi))
INSN1(push,l ,R(esi))
INSN1(push,l ,R(ebx))
INSN1(push,l ,R(ebp))
INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
INSN2(mov,l ,R(size),MEM_DISP(esp,28))
INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
INSN1(neg,l ,R(size))
INSN2(xor,l ,R(ebx),R(ebx))
ALIGN (3)
Loop:
INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
INSN1(mul,l ,R(s2_limb))
INSN2(add,l ,R(eax),R(ebx))
INSN2(adc,l ,R(edx),$0)
INSN2(add,l ,MEM_INDEX(res_ptr,size,4),R(eax))
INSN2(adc,l ,R(edx),$0)
INSN2(mov,l ,R(ebx),R(edx))
INSN1(inc,l ,R(size))
INSN1(jnz, ,Loop)
INSN2(mov,l ,R(eax),R(ebx))
INSN1(pop,l ,R(ebp))
INSN1(pop,l ,R(ebx))
INSN1(pop,l ,R(esi))
INSN1(pop,l ,R(edi))
ret

View file

@ -0,0 +1,86 @@
/* i80386 submul_1 -- Multiply a limb vector with a limb and add
* the result to a second limb vector.
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_size_t s1_size, (sp + 12)
* mpi_limb_t s2_limb) (sp + 16)
*/
#define res_ptr edi
#define s1_ptr esi
#define size ecx
#define s2_limb ebp
TEXT
ALIGN (3)
GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
C_SYMBOL_NAME(_gcry_mpih_submul_1:)
INSN1(push,l ,R(edi))
INSN1(push,l ,R(esi))
INSN1(push,l ,R(ebx))
INSN1(push,l ,R(ebp))
INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
INSN2(mov,l ,R(size),MEM_DISP(esp,28))
INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
INSN1(neg,l ,R(size))
INSN2(xor,l ,R(ebx),R(ebx))
ALIGN (3)
Loop:
INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
INSN1(mul,l ,R(s2_limb))
INSN2(add,l ,R(eax),R(ebx))
INSN2(adc,l ,R(edx),$0)
INSN2(sub,l ,MEM_INDEX(res_ptr,size,4),R(eax))
INSN2(adc,l ,R(edx),$0)
INSN2(mov,l ,R(ebx),R(edx))
INSN1(inc,l ,R(size))
INSN1(jnz, ,Loop)
INSN2(mov,l ,R(eax),R(ebx))
INSN1(pop,l ,R(ebp))
INSN1(pop,l ,R(ebx))
INSN1(pop,l ,R(esi))
INSN1(pop,l ,R(edi))
ret

View file

@ -0,0 +1,97 @@
/* i80386 rshift
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
* mpi_ptr_t up, (sp + 8)
* mpi_size_t usize, (sp + 12)
* unsigned cnt) (sp + 16)
*/
.text
ALIGN (3)
.globl C_SYMBOL_NAME(_gcry_mpih_rshift)
C_SYMBOL_NAME(_gcry_mpih_rshift:)
pushl %edi
pushl %esi
pushl %ebx
movl 16(%esp),%edi /* wp */
movl 20(%esp),%esi /* up */
movl 24(%esp),%edx /* usize */
movl 28(%esp),%ecx /* cnt */
leal -4(%edi,%edx,4),%edi
leal (%esi,%edx,4),%esi
negl %edx
movl (%esi,%edx,4),%ebx /* read least significant limb */
xorl %eax,%eax
shrdl %cl,%ebx,%eax /* compute carry limb */
incl %edx
jz Lend2
pushl %eax /* push carry limb onto stack */
testb $1,%dl
jnz L2 /* enter loop in the middle */
movl %ebx,%eax
ALIGN (3)
Loop2: movl (%esi,%edx,4),%ebx /* load next higher limb */
shrdl %cl,%ebx,%eax /* compute result limb */
movl %eax,(%edi,%edx,4) /* store it */
incl %edx
L2: movl (%esi,%edx,4),%eax
shrdl %cl,%eax,%ebx
movl %ebx,(%edi,%edx,4)
incl %edx
jnz Loop2
shrl %cl,%eax /* compute most significant limb */
movl %eax,(%edi) /* store it */
popl %eax /* pop carry limb */
popl %ebx
popl %esi
popl %edi
ret
Lend2: shrl %cl,%ebx /* compute most significant limb */
movl %ebx,(%edi) /* store it */
popl %ebx
popl %esi
popl %edi
ret

View file

@ -0,0 +1,117 @@
/* i80386 sub_n -- Sub two limb vectors of the same length > 0 and store
* sum in a third limb vector.
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_ptr_t s2_ptr, (sp + 12)
* mpi_size_t size) (sp + 16)
*/
.text
ALIGN (3)
.globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
C_SYMBOL_NAME(_gcry_mpih_sub_n:)
pushl %edi
pushl %esi
movl 12(%esp),%edi /* res_ptr */
movl 16(%esp),%esi /* s1_ptr */
movl 20(%esp),%edx /* s2_ptr */
movl 24(%esp),%ecx /* size */
movl %ecx,%eax
shrl $3,%ecx /* compute count for unrolled loop */
negl %eax
andl $7,%eax /* get index where to start loop */
jz Loop /* necessary special case for 0 */
incl %ecx /* adjust loop count */
shll $2,%eax /* adjustment for pointers... */
subl %eax,%edi /* ... since they are offset ... */
subl %eax,%esi /* ... by a constant when we ... */
subl %eax,%edx /* ... enter the loop */
shrl $2,%eax /* restore previous value */
#ifdef PIC
/* Calculate start address in loop for PIC. Due to limitations in some
assemblers, Loop-L0-3 cannot be put into the leal */
call L0
L0: leal (%eax,%eax,8),%eax
addl (%esp),%eax
addl $(Loop-L0-3),%eax
addl $4,%esp
#else
/* Calculate start address in loop for non-PIC. */
leal (Loop - 3)(%eax,%eax,8),%eax
#endif
jmp *%eax /* jump into loop */
ALIGN (3)
Loop: movl (%esi),%eax
sbbl (%edx),%eax
movl %eax,(%edi)
movl 4(%esi),%eax
sbbl 4(%edx),%eax
movl %eax,4(%edi)
movl 8(%esi),%eax
sbbl 8(%edx),%eax
movl %eax,8(%edi)
movl 12(%esi),%eax
sbbl 12(%edx),%eax
movl %eax,12(%edi)
movl 16(%esi),%eax
sbbl 16(%edx),%eax
movl %eax,16(%edi)
movl 20(%esi),%eax
sbbl 20(%edx),%eax
movl %eax,20(%edi)
movl 24(%esi),%eax
sbbl 24(%edx),%eax
movl %eax,24(%edi)
movl 28(%esi),%eax
sbbl 28(%edx),%eax
movl %eax,28(%edi)
leal 32(%edi),%edi
leal 32(%esi),%esi
leal 32(%edx),%edx
decl %ecx
jnz Loop
sbbl %eax,%eax
negl %eax
popl %esi
popl %edi
ret

View file

@ -0,0 +1,68 @@
/* syntax.h -- Definitions for x86 syntax variations.
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#undef ALIGN
#if defined (BSD_SYNTAX) || defined (ELF_SYNTAX)
#define R(r) %r
#define MEM(base)(base)
#define MEM_DISP(base,displacement)displacement(R(base))
#define MEM_INDEX(base,index,size)(R(base),R(index),size)
#ifdef __STDC__
#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst
#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst
#else
#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst
#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst
#endif
#define TEXT .text
#if defined (BSD_SYNTAX)
#define ALIGN(log) .align log
#endif
#if defined (ELF_SYNTAX)
#define ALIGN(log) .align 1<<(log)
#endif
#define GLOBL .globl
#endif
#ifdef INTEL_SYNTAX
#define R(r) r
#define MEM(base)[base]
#define MEM_DISP(base,displacement)[base+(displacement)]
#define MEM_INDEX(base,index,size)[base+index*size]
#define INSN1(mnemonic,size_suffix,dst)mnemonic dst
#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src
#define TEXT .text
#define ALIGN(log) .align log
#define GLOBL .globl
#endif
#ifdef X86_BROKEN_ALIGN
#undef ALIGN
#define ALIGN(log) .align log,0x90
#endif

View file

@ -0,0 +1,27 @@
# Manifest - checksums
# Copyright 2003 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# Libgcrypt is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser general Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Libgcrypt 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser 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
mpih-add1.S
mpih-mul1.S
mpih-mul2.S
mpih-mul3.S
mpih-lshift.S
mpih-rshift.S
mpih-sub1.S
$names$ iQCVAwUAP+LmQDEAnp832S/7AQKCmgQAhG+E7X0KB4qdVf3sMb6Qr+Iv5Jlehzoub/5vxTRgePKzRuOHidCnTzSSoyzA++UcHrOjHQQDMsXnO6PqpS1d/TKkxjnGN7rE8mvMYlFAT8RsawTozSfh14mCzI0HTDbaKL9Z8pcMJtadB3XqAuqWJNO8kyECJFwurt3DRWXSWS8==Rug5

View file

@ -0,0 +1,26 @@
This directory contains mpn functions optimized for Intel Pentium
processors.
RELEVANT OPTIMIZATION ISSUES
1. Pentium doesn't allocate cache lines on writes, unlike most other modern
processors. Since the functions in the mpn class do array writes, we have to
handle allocating the destination cache lines by reading a word from it in the
loops, to achieve the best performance.
2. Pairing of memory operations requires that the two issued operations refer
to different cache banks. The simplest way to insure this is to read/write
two words from the same object. If we make operations on different objects,
they might or might not be to the same cache bank.
STATUS
1. mpn_lshift and mpn_rshift run at about 6 cycles/limb, but the Pentium
documentation indicates that they should take only 43/8 = 5.375 cycles/limb,
or 5 cycles/limb asymptotically.
2. mpn_add_n and mpn_sub_n run at asymptotically 2 cycles/limb. Due to loop
overhead and other delays (cache refill?), they run at or near 2.5 cycles/limb.
3. mpn_mul_1, mpn_addmul_1, mpn_submul_1 all run 1 cycle faster than they
should...

View file

@ -0,0 +1,10 @@
Manifest
mpih-add1.S
mpih-mul1.S
mpih-mul2.S
mpih-mul3.S
mpih-lshift.S
mpih-rshift.S
mpih-sub1.S
README

View file

@ -0,0 +1,135 @@
/* i80586 add_n -- Add two limb vectors of the same length > 0 and store
* sum in a third limb vector.
*
* Copyright (C) 1992, 1994, 1995, 1996, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser 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
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_ptr_t s2_ptr, (sp + 12)
* mpi_size_t size) (sp + 16)
*/
.text
ALIGN (3)
.globl C_SYMBOL_NAME(_gcry_mpih_add_n)
C_SYMBOL_NAME(_gcry_mpih_add_n:)
pushl %edi
pushl %esi
pushl %ebx
pushl %ebp
movl 20(%esp),%edi /* res_ptr */
movl 24(%esp),%esi /* s1_ptr */
movl 28(%esp),%ebp /* s2_ptr */
movl 32(%esp),%ecx /* size */
movl (%ebp),%ebx
decl %ecx
movl %ecx,%edx
shrl $3,%ecx
andl $7,%edx
testl %ecx,%ecx /* zero carry flag */
jz Lend
pushl %edx
ALIGN (3)
Loop: movl 28(%edi),%eax /* fetch destination cache line */
leal 32(%edi),%edi
L1: movl (%esi),%eax
movl 4(%esi),%edx
adcl %ebx,%eax
movl 4(%ebp),%ebx
adcl %ebx,%edx
movl 8(%ebp),%ebx
movl %eax,-32(%edi)
movl %edx,-28(%edi)
L2: movl 8(%esi),%eax
movl 12(%esi),%edx
adcl %ebx,%eax
movl 12(%ebp),%ebx
adcl %ebx,%edx
movl 16(%ebp),%ebx
movl %eax,-24(%edi)
movl %edx,-20(%edi)
L3: movl 16(%esi),%eax
movl 20(%esi),%edx
adcl %ebx,%eax
movl 20(%ebp),%ebx
adcl %ebx,%edx
movl 24(%ebp),%ebx
movl %eax,-16(%edi)
movl %edx,-12(%edi)
L4: movl 24(%esi),%eax
movl 28(%esi),%edx
adcl %ebx,%eax
movl 28(%ebp),%ebx
adcl %ebx,%edx
movl 32(%ebp),%ebx
movl %eax,-8(%edi)
movl %edx,-4(%edi)
leal 32(%esi),%esi
leal 32(%ebp),%ebp
decl %ecx
jnz Loop
popl %edx
Lend:
decl %edx /* test %edx w/o clobbering carry */
js Lend2
incl %edx
Loop2:
leal 4(%edi),%edi
movl (%esi),%eax
adcl %ebx,%eax
movl 4(%ebp),%ebx
movl %eax,-4(%edi)
leal 4(%esi),%esi
leal 4(%ebp),%ebp
decl %edx
jnz Loop2
Lend2:
movl (%esi),%eax
adcl %ebx,%eax
movl %eax,(%edi)
sbbl %eax,%eax
negl %eax
popl %ebp
popl %ebx
popl %esi
popl %edi
ret

View file

@ -0,0 +1,229 @@
/* i80586 lshift
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
* mpi_ptr_t up, (sp + 8)
* mpi_size_t usize, (sp + 12)
* unsigned cnt) (sp + 16)
*/
.text
ALIGN (3)
.globl C_SYMBOL_NAME(_gcry_mpih_lshift)
C_SYMBOL_NAME(_gcry_mpih_lshift:)
pushl %edi
pushl %esi
pushl %ebx
pushl %ebp
movl 20(%esp),%edi /* res_ptr */
movl 24(%esp),%esi /* s_ptr */
movl 28(%esp),%ebp /* size */
movl 32(%esp),%ecx /* cnt */
/* We can use faster code for shift-by-1 under certain conditions. */
cmp $1,%ecx
jne Lnormal
leal 4(%esi),%eax
cmpl %edi,%eax
jnc Lspecial /* jump if s_ptr + 1 >= res_ptr */
leal (%esi,%ebp,4),%eax
cmpl %eax,%edi
jnc Lspecial /* jump if res_ptr >= s_ptr + size */
Lnormal:
leal -4(%edi,%ebp,4),%edi
leal -4(%esi,%ebp,4),%esi
movl (%esi),%edx
subl $4,%esi
xorl %eax,%eax
shldl %cl,%edx,%eax /* compute carry limb */
pushl %eax /* push carry limb onto stack */
decl %ebp
pushl %ebp
shrl $3,%ebp
jz Lend
movl (%edi),%eax /* fetch destination cache line */
ALIGN (2)
Loop: movl -28(%edi),%eax /* fetch destination cache line */
movl %edx,%ebx
movl (%esi),%eax
movl -4(%esi),%edx
shldl %cl,%eax,%ebx
shldl %cl,%edx,%eax
movl %ebx,(%edi)
movl %eax,-4(%edi)
movl -8(%esi),%ebx
movl -12(%esi),%eax
shldl %cl,%ebx,%edx
shldl %cl,%eax,%ebx
movl %edx,-8(%edi)
movl %ebx,-12(%edi)
movl -16(%esi),%edx
movl -20(%esi),%ebx
shldl %cl,%edx,%eax
shldl %cl,%ebx,%edx
movl %eax,-16(%edi)
movl %edx,-20(%edi)
movl -24(%esi),%eax
movl -28(%esi),%edx
shldl %cl,%eax,%ebx
shldl %cl,%edx,%eax
movl %ebx,-24(%edi)
movl %eax,-28(%edi)
subl $32,%esi
subl $32,%edi
decl %ebp
jnz Loop
Lend: popl %ebp
andl $7,%ebp
jz Lend2
Loop2: movl (%esi),%eax
shldl %cl,%eax,%edx
movl %edx,(%edi)
movl %eax,%edx
subl $4,%esi
subl $4,%edi
decl %ebp
jnz Loop2
Lend2: shll %cl,%edx /* compute least significant limb */
movl %edx,(%edi) /* store it */
popl %eax /* pop carry limb */
popl %ebp
popl %ebx
popl %esi
popl %edi
ret
/* We loop from least significant end of the arrays, which is only
permissable if the source and destination don't overlap, since the
function is documented to work for overlapping source and destination.
*/
Lspecial:
movl (%esi),%edx
addl $4,%esi
decl %ebp
pushl %ebp
shrl $3,%ebp
addl %edx,%edx
incl %ebp
decl %ebp
jz LLend
movl (%edi),%eax /* fetch destination cache line */
ALIGN (2)
LLoop: movl 28(%edi),%eax /* fetch destination cache line */
movl %edx,%ebx
movl (%esi),%eax
movl 4(%esi),%edx
adcl %eax,%eax
movl %ebx,(%edi)
adcl %edx,%edx
movl %eax,4(%edi)
movl 8(%esi),%ebx
movl 12(%esi),%eax
adcl %ebx,%ebx
movl %edx,8(%edi)
adcl %eax,%eax
movl %ebx,12(%edi)
movl 16(%esi),%edx
movl 20(%esi),%ebx
adcl %edx,%edx
movl %eax,16(%edi)
adcl %ebx,%ebx
movl %edx,20(%edi)
movl 24(%esi),%eax
movl 28(%esi),%edx
adcl %eax,%eax
movl %ebx,24(%edi)
adcl %edx,%edx
movl %eax,28(%edi)
leal 32(%esi),%esi /* use leal not to clobber carry */
leal 32(%edi),%edi
decl %ebp
jnz LLoop
LLend: popl %ebp
sbbl %eax,%eax /* save carry in %eax */
andl $7,%ebp
jz LLend2
addl %eax,%eax /* restore carry from eax */
LLoop2: movl %edx,%ebx
movl (%esi),%edx
adcl %edx,%edx
movl %ebx,(%edi)
leal 4(%esi),%esi /* use leal not to clobber carry */
leal 4(%edi),%edi
decl %ebp
jnz LLoop2
jmp LL1
LLend2: addl %eax,%eax /* restore carry from eax */
LL1: movl %edx,(%edi) /* store last limb */
sbbl %eax,%eax
negl %eax
popl %ebp
popl %ebx
popl %esi
popl %edi
ret

View file

@ -0,0 +1,89 @@
/* i80586 mul_1 -- Multiply a limb vector with a limb and store
* the result in a second limb vector.
*
* Copyright (C) 1992, 1994, 1996, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_size_t s1_size, (sp + 12)
* mpi_limb_t s2_limb) (sp + 16)
*/
#define res_ptr edi
#define s1_ptr esi
#define size ecx
#define s2_limb ebp
TEXT
ALIGN (3)
GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
C_SYMBOL_NAME(_gcry_mpih_mul_1:)
INSN1(push,l ,R(edi))
INSN1(push,l ,R(esi))
INSN1(push,l ,R(ebx))
INSN1(push,l ,R(ebp))
INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
INSN2(mov,l ,R(size),MEM_DISP(esp,28))
INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
INSN1(neg,l ,R(size))
INSN2(xor,l ,R(ebx),R(ebx))
ALIGN (3)
Loop: INSN2(adc,l ,R(ebx),$0)
INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
INSN1(mul,l ,R(s2_limb))
INSN2(add,l ,R(ebx),R(eax))
INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
INSN1(inc,l ,R(size))
INSN2(mov,l ,R(ebx),R(edx))
INSN1(jnz, ,Loop)
INSN2(adc,l ,R(ebx),$0)
INSN2(mov,l ,R(eax),R(ebx))
INSN1(pop,l ,R(ebp))
INSN1(pop,l ,R(ebx))
INSN1(pop,l ,R(esi))
INSN1(pop,l ,R(edi))
ret

View file

@ -0,0 +1,93 @@
/* i80586 addmul_1 -- Multiply a limb vector with a limb and add
* the result to a second limb vector.
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_size_t s1_size, (sp + 12)
* mpi_limb_t s2_limb) (sp + 16)
*/
#define res_ptr edi
#define s1_ptr esi
#define size ecx
#define s2_limb ebp
TEXT
ALIGN (3)
GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
INSN1(push,l ,R(edi))
INSN1(push,l ,R(esi))
INSN1(push,l ,R(ebx))
INSN1(push,l ,R(ebp))
INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
INSN2(mov,l ,R(size),MEM_DISP(esp,28))
INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
INSN1(neg,l ,R(size))
INSN2(xor,l ,R(ebx),R(ebx))
ALIGN (3)
Loop: INSN2(adc,l ,R(ebx),$0)
INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
INSN1(mul,l ,R(s2_limb))
INSN2(add,l ,R(eax),R(ebx))
INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4))
INSN2(adc,l ,R(edx),$0)
INSN2(add,l ,R(ebx),R(eax))
INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
INSN1(inc,l ,R(size))
INSN2(mov,l ,R(ebx),R(edx))
INSN1(jnz, ,Loop)
INSN2(adc,l ,R(ebx),$0)
INSN2(mov,l ,R(eax),R(ebx))
INSN1(pop,l ,R(ebp))
INSN1(pop,l ,R(ebx))
INSN1(pop,l ,R(esi))
INSN1(pop,l ,R(edi))
ret

View file

@ -0,0 +1,93 @@
/* i80586 submul_1 -- Multiply a limb vector with a limb and add
* the result to a second limb vector.
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_size_t s1_size, (sp + 12)
* mpi_limb_t s2_limb) (sp + 16)
*/
#define res_ptr edi
#define s1_ptr esi
#define size ecx
#define s2_limb ebp
TEXT
ALIGN (3)
GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
C_SYMBOL_NAME(_gcry_mpih_submul_1:)
INSN1(push,l ,R(edi))
INSN1(push,l ,R(esi))
INSN1(push,l ,R(ebx))
INSN1(push,l ,R(ebp))
INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
INSN2(mov,l ,R(size),MEM_DISP(esp,28))
INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
INSN1(neg,l ,R(size))
INSN2(xor,l ,R(ebx),R(ebx))
ALIGN (3)
Loop: INSN2(adc,l ,R(ebx),$0)
INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
INSN1(mul,l ,R(s2_limb))
INSN2(add,l ,R(eax),R(ebx))
INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4))
INSN2(adc,l ,R(edx),$0)
INSN2(sub,l ,R(ebx),R(eax))
INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
INSN1(inc,l ,R(size))
INSN2(mov,l ,R(ebx),R(edx))
INSN1(jnz, ,Loop)
INSN2(adc,l ,R(ebx),$0)
INSN2(mov,l ,R(eax),R(ebx))
INSN1(pop,l ,R(ebp))
INSN1(pop,l ,R(ebx))
INSN1(pop,l ,R(esi))
INSN1(pop,l ,R(edi))
ret

View file

@ -0,0 +1,228 @@
/* i80586 rshift
*
* Copyright (C) 1992, 1994, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
* mpi_ptr_t up, (sp + 8)
* mpi_size_t usize, (sp + 12)
* unsigned cnt) (sp + 16)
*/
.text
ALIGN (3)
.globl C_SYMBOL_NAME(_gcry_mpih_rshift)
C_SYMBOL_NAME(_gcry_mpih_rshift:)
pushl %edi
pushl %esi
pushl %ebx
pushl %ebp
movl 20(%esp),%edi /* res_ptr */
movl 24(%esp),%esi /* s_ptr */
movl 28(%esp),%ebp /* size */
movl 32(%esp),%ecx /* cnt */
/* We can use faster code for shift-by-1 under certain conditions. */
cmp $1,%ecx
jne Rnormal
leal 4(%edi),%eax
cmpl %esi,%eax
jnc Rspecial /* jump if res_ptr + 1 >= s_ptr */
leal (%edi,%ebp,4),%eax
cmpl %eax,%esi
jnc Rspecial /* jump if s_ptr >= res_ptr + size */
Rnormal:
movl (%esi),%edx
addl $4,%esi
xorl %eax,%eax
shrdl %cl,%edx,%eax /* compute carry limb */
pushl %eax /* push carry limb onto stack */
decl %ebp
pushl %ebp
shrl $3,%ebp
jz Rend
movl (%edi),%eax /* fetch destination cache line */
ALIGN (2)
Roop: movl 28(%edi),%eax /* fetch destination cache line */
movl %edx,%ebx
movl (%esi),%eax
movl 4(%esi),%edx
shrdl %cl,%eax,%ebx
shrdl %cl,%edx,%eax
movl %ebx,(%edi)
movl %eax,4(%edi)
movl 8(%esi),%ebx
movl 12(%esi),%eax
shrdl %cl,%ebx,%edx
shrdl %cl,%eax,%ebx
movl %edx,8(%edi)
movl %ebx,12(%edi)
movl 16(%esi),%edx
movl 20(%esi),%ebx
shrdl %cl,%edx,%eax
shrdl %cl,%ebx,%edx
movl %eax,16(%edi)
movl %edx,20(%edi)
movl 24(%esi),%eax
movl 28(%esi),%edx
shrdl %cl,%eax,%ebx
shrdl %cl,%edx,%eax
movl %ebx,24(%edi)
movl %eax,28(%edi)
addl $32,%esi
addl $32,%edi
decl %ebp
jnz Roop
Rend: popl %ebp
andl $7,%ebp
jz Rend2
Roop2: movl (%esi),%eax
shrdl %cl,%eax,%edx /* compute result limb */
movl %edx,(%edi)
movl %eax,%edx
addl $4,%esi
addl $4,%edi
decl %ebp
jnz Roop2
Rend2: shrl %cl,%edx /* compute most significant limb */
movl %edx,(%edi) /* store it */
popl %eax /* pop carry limb */
popl %ebp
popl %ebx
popl %esi
popl %edi
ret
/* We loop from least significant end of the arrays, which is only
permissable if the source and destination don't overlap, since the
function is documented to work for overlapping source and destination.
*/
Rspecial:
leal -4(%edi,%ebp,4),%edi
leal -4(%esi,%ebp,4),%esi
movl (%esi),%edx
subl $4,%esi
decl %ebp
pushl %ebp
shrl $3,%ebp
shrl $1,%edx
incl %ebp
decl %ebp
jz RLend
movl (%edi),%eax /* fetch destination cache line */
ALIGN (2)
RLoop: movl -28(%edi),%eax /* fetch destination cache line */
movl %edx,%ebx
movl (%esi),%eax
movl -4(%esi),%edx
rcrl $1,%eax
movl %ebx,(%edi)
rcrl $1,%edx
movl %eax,-4(%edi)
movl -8(%esi),%ebx
movl -12(%esi),%eax
rcrl $1,%ebx
movl %edx,-8(%edi)
rcrl $1,%eax
movl %ebx,-12(%edi)
movl -16(%esi),%edx
movl -20(%esi),%ebx
rcrl $1,%edx
movl %eax,-16(%edi)
rcrl $1,%ebx
movl %edx,-20(%edi)
movl -24(%esi),%eax
movl -28(%esi),%edx
rcrl $1,%eax
movl %ebx,-24(%edi)
rcrl $1,%edx
movl %eax,-28(%edi)
leal -32(%esi),%esi /* use leal not to clobber carry */
leal -32(%edi),%edi
decl %ebp
jnz RLoop
RLend: popl %ebp
sbbl %eax,%eax /* save carry in %eax */
andl $7,%ebp
jz RLend2
addl %eax,%eax /* restore carry from eax */
RLoop2: movl %edx,%ebx
movl (%esi),%edx
rcrl $1,%edx
movl %ebx,(%edi)
leal -4(%esi),%esi /* use leal not to clobber carry */
leal -4(%edi),%edi
decl %ebp
jnz RLoop2
jmp RL1
RLend2: addl %eax,%eax /* restore carry from eax */
RL1: movl %edx,(%edi) /* store last limb */
movl $0,%eax
rcrl $1,%eax
popl %ebp
popl %ebx
popl %esi
popl %edi
ret

View file

@ -0,0 +1,142 @@
/* i80586 sub_n -- Sub two limb vectors of the same length > 0 and store
* sum in a third limb vector.
*
* Copyright (C) 1992, 1994, 1995, 1998,
* 2001, 2002 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#include "sysdep.h"
#include "asm-syntax.h"
/*******************
* mpi_limb_t
* _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
* mpi_ptr_t s1_ptr, (sp + 8)
* mpi_ptr_t s2_ptr, (sp + 12)
* mpi_size_t size) (sp + 16)
*/
.text
ALIGN (3)
.globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
C_SYMBOL_NAME(_gcry_mpih_sub_n:)
pushl %edi
pushl %esi
pushl %ebx
pushl %ebp
movl 20(%esp),%edi /* res_ptr */
movl 24(%esp),%esi /* s1_ptr */
movl 28(%esp),%ebp /* s2_ptr */
movl 32(%esp),%ecx /* size */
movl (%ebp),%ebx
decl %ecx
movl %ecx,%edx
shrl $3,%ecx
andl $7,%edx
testl %ecx,%ecx /* zero carry flag */
jz Lend
pushl %edx
ALIGN (3)
Loop: movl 28(%edi),%eax /* fetch destination cache line */
leal 32(%edi),%edi
L1: movl (%esi),%eax
movl 4(%esi),%edx
sbbl %ebx,%eax
movl 4(%ebp),%ebx
sbbl %ebx,%edx
movl 8(%ebp),%ebx
movl %eax,-32(%edi)
movl %edx,-28(%edi)
L2: movl 8(%esi),%eax
movl 12(%esi),%edx
sbbl %ebx,%eax
movl 12(%ebp),%ebx
sbbl %ebx,%edx
movl 16(%ebp),%ebx
movl %eax,-24(%edi)
movl %edx,-20(%edi)
L3: movl 16(%esi),%eax
movl 20(%esi),%edx
sbbl %ebx,%eax
movl 20(%ebp),%ebx
sbbl %ebx,%edx
movl 24(%ebp),%ebx
movl %eax,-16(%edi)
movl %edx,-12(%edi)
L4: movl 24(%esi),%eax
movl 28(%esi),%edx
sbbl %ebx,%eax
movl 28(%ebp),%ebx
sbbl %ebx,%edx
movl 32(%ebp),%ebx
movl %eax,-8(%edi)
movl %edx,-4(%edi)
leal 32(%esi),%esi
leal 32(%ebp),%ebp
decl %ecx
jnz Loop
popl %edx
Lend:
decl %edx /* test %edx w/o clobbering carry */
js Lend2
incl %edx
Loop2:
leal 4(%edi),%edi
movl (%esi),%eax
sbbl %ebx,%eax
movl 4(%ebp),%ebx
movl %eax,-4(%edi)
leal 4(%esi),%esi
leal 4(%ebp),%ebp
decl %edx
jnz Loop2
Lend2:
movl (%esi),%eax
sbbl %ebx,%eax
movl %eax,(%edi)
sbbl %eax,%eax
negl %eax
popl %ebp
popl %ebx
popl %esi
popl %edi
ret

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,25 @@
# Manifest - checksums
# Copyright 2003 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# Libgcrypt is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser general Public License as
# published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# Libgcrypt 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser 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
syntax.h
mpih-lshift.S
mpih-rshift.S
mpih-add1.S
mpih-sub1.S
$names$ iQCVAwUAP+LmTDEAnp832S/7AQJHUAP/dxfq2U0pDc5ZLoEizoqgjjcnHIyb9EjMG3YjvgK6jQ62yoAOCuo/jFYlJS+Mdve6bgfdTzYMrnKV7BG2SEcwb263pVnIntS7ZhKQPiMCbFgXWR2VjN3+a1v8yjQDZtgqEgm8OlQ+u7jKBY13Oryiuq5nPNxsXZqJpelG6Zkdg9M==PIee

View file

@ -0,0 +1,9 @@
Manifest
syntax.h
mpih-lshift.S
mpih-rshift.S
mpih-add1.S
mpih-sub1.S

Some files were not shown because too many files have changed in this diff Show more