summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2001-08-03 10:57:34 +0000
committerWerner Koch <wk@gnupg.org>2001-08-03 10:57:34 +0000
commit0c667cbdebcd34dfa556b6b8d786b0677f09f5a5 (patch)
treed31d08dfe51104bc4e26c6c69b87c8dd4b545047
parent442e7215fb0b7455d31587bd6ad9ccb5d5a64dd7 (diff)
downloadlibgcrypt-0c667cbdebcd34dfa556b6b8d786b0677f09f5a5.tar.gz
Applied changes from GnuPG stable.
Add a first tes program
-rw-r--r--ChangeLog8
-rw-r--r--Makefile.am2
-rw-r--r--NEWS18
-rw-r--r--THANKS2
-rw-r--r--cipher/ChangeLog38
-rw-r--r--cipher/Makefile.am18
-rw-r--r--cipher/arcfour.c33
-rw-r--r--cipher/blowfish.c42
-rw-r--r--cipher/cast5.c46
-rw-r--r--cipher/cipher.c75
-rw-r--r--cipher/des.c23
-rw-r--r--cipher/md5.c13
-rw-r--r--cipher/primegen.c7
-rw-r--r--cipher/random.c25
-rw-r--r--cipher/rijndael.c45
-rw-r--r--cipher/rmd160.c15
-rw-r--r--cipher/rndlinux.c3
-rw-r--r--cipher/rndunix.c1
-rw-r--r--cipher/sha1.c13
-rw-r--r--cipher/tiger.c53
-rw-r--r--cipher/twofish.c45
-rw-r--r--configure.in12
-rw-r--r--libgcrypt.txt93
-rw-r--r--src/ChangeLog8
-rw-r--r--src/gcrypt.h4
-rw-r--r--src/global.c31
-rw-r--r--tests/ChangeLog0
-rw-r--r--tests/Makefile.am38
-rw-r--r--tests/basic.c166
29 files changed, 762 insertions, 115 deletions
diff --git a/ChangeLog b/ChangeLog
index bed5f6ff..df1a6842 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * tests/: New.
+ * Makefile.am: Included tests directory
+
+ * configure.in (DYNLINK_MOD_CFLAGS): Use -shared with dec-osf.
+ Reported by Chris Adams. Merged some cases.
+
2001-05-31 Werner Koch <wk@gnupg.org>
Release 1.1.3.
diff --git a/Makefile.am b/Makefile.am
index 80672089..86e2813c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
-SUBDIRS = jnlib mpi cipher src doc
+SUBDIRS = jnlib mpi cipher src doc tests
EXTRA_DIST = README-alpha BUGS
DISTCLEANFILES = gcrypt-defs.h
diff --git a/NEWS b/NEWS
index e815ed0d..dc41db23 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,19 @@
+ * Arcfour does now work.
-GnuPG has been spitted into libgcrypt and GnuPG.
+Noteworthy changes in version 1.1.3 (2001-05-31)
+------------------------------------------------
+
+ * First release of Libgcrypt which is a result of splitting GnuPG
+ into into libgcrypt and GnuPG.
+
+
+Copyright 2001 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.
diff --git a/THANKS b/THANKS
index 4eeb8d98..fc47e6f7 100644
--- a/THANKS
+++ b/THANKS
@@ -78,6 +78,7 @@ Philippe Laliberte arsphl@oeil.qc.ca
Peter Gutmann pgut001@cs.auckland.ac.nz
QingLong qinglong@bolizm.ihep.su
Ralph Gillen gillen@theochem.uni-duesseldorf.de
+Rami Lehti Rami.Lehti@finland.sun.com
Rat ratinox@peorth.gweep.net
Reinhard Wobst R.Wobst@ifw-dresden.de
Rémi Guyomarch rguyom@mail.dotcom.fr
@@ -99,6 +100,7 @@ Thomas Roessler roessler@guug.de
Tom Spindler dogcow@home.merit.edu
Tom Zerucha tzeruch@ceddec.com
Tomas Fasth tomas.fasth@twinspot.net
+Tommi Komulainen Tommi.Komulainen@iki.fi
Thomas Mikkelsen tbm@image.dk
Ulf Möller 3umoelle@informatik.uni-hamburg.de
Urko Lusa ulusa@euskalnet.net
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index e96ce481..ee015638 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -1,5 +1,43 @@
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (cipher_encrypt, cipher_decrypt): Prepare to return
+ errors. We have to change the interface to all ciphers to make
+ this really work but we should do so to prepare for hardware
+ encryption modules.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Return the error and
+ set lasterr.
+ (gcry_cipher_ctl): Make sure that errors from setkey are returned.
+
2001-08-02 Werner Koch <wk@gnupg.org>
+ * rndlinux.c (gather_random): casted a size_t arg to int so that
+ the format string is correct. Casting is okay here and avoids
+ translation changes.
+
+ * random.c (fast_random_poll): Do not check the return code of
+ getrusage.
+
+ * rndunix.c: Add a signal.h header to avoid warnings on Solaris 7
+ and 8.
+
+ * tiger.c (print_abc,print_data): Removed.
+
+ * rijndael.c, des.c, blowfish.c, twofish.c, cast5.c, arcfour.c
+ (burn_stack): New. Add wrappers for most functions to be able to
+ call burn_stack after the function invocation. This methods seems
+ to be the most portable way to zeroise the stack used. It does
+ only work on stack frame based machines but it is highly portable
+ and has no side effects. Just setting the automatic variables at
+ the end of a function to zero does not work well because the
+ compiler will optimize them away - marking them as volatile would
+ be bad for performance.
+ * md5.c, sha1.c, rmd160.c, tiger.c (burn_stack): Likewise.
+ * random.c (burn_stack): New.
+ (mix_pool): Use it here to burn the stack of the mixblock function.
+
+ * primegen.c (_gcry_generate_elg_prime): Freed q at 3 places.
+ Thanks to Tommi Komulainen.
+
* arcfour.c (arcfour_setkey): Check the minimim keylength against
bytes and not bits.
(selftest): Must reset the key before decryption.
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 0d78e93d..217aa35e 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -1,3 +1,21 @@
+# Copyright (C) 1998, 1999, 2000, 2001 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 General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
# Process this file with automake to produce Makefile.in
diff --git a/cipher/arcfour.c b/cipher/arcfour.c
index c19d282d..e9db410b 100644
--- a/cipher/arcfour.c
+++ b/cipher/arcfour.c
@@ -41,7 +41,19 @@ typedef struct {
static void
-encrypt_stream( ARCFOUR_context *ctx,
+burn_stack (int bytes)
+{
+ char buf[64];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
+
+
+static void
+do_encrypt_stream( ARCFOUR_context *ctx,
byte *outbuf, const byte *inbuf, unsigned int length )
{
int t;
@@ -60,9 +72,18 @@ encrypt_stream( ARCFOUR_context *ctx,
ctx->idx_j = j;
}
+static void
+encrypt_stream( ARCFOUR_context *ctx,
+ byte *outbuf, const byte *inbuf, unsigned int length )
+{
+
+ do_encrypt_stream (ctx, outbuf, inbuf, length );
+ burn_stack (64);
+}
+
static int
-arcfour_setkey( ARCFOUR_context *ctx, const byte *key, unsigned int keylen )
+do_arcfour_setkey( ARCFOUR_context *ctx, const byte *key, unsigned int keylen )
{
static int initialized;
static const char* selftest_failed;
@@ -98,6 +119,14 @@ arcfour_setkey( ARCFOUR_context *ctx, const byte *key, unsigned int keylen )
return 0;
}
+static int
+arcfour_setkey ( ARCFOUR_context *ctx, const byte *key, unsigned int keylen )
+{
+ int rc = do_arcfour_setkey (ctx, key, keylen );
+ burn_stack (300);
+ return rc;
+}
+
static const char*
selftest(void)
diff --git a/cipher/blowfish.c b/cipher/blowfish.c
index 0847de38..dc8e3feb 100644
--- a/cipher/blowfish.c
+++ b/cipher/blowfish.c
@@ -1,5 +1,5 @@
/* blowfish.c - Blowfish encryption
- * Copyright (C) 1998 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2001 Free Software Foundation, Inc.
*
* For a description of the algorithm, see:
* Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
@@ -281,6 +281,17 @@ function_F( BLOWFISH_context *bc, u32 x )
#endif
#define R(l,r,i) do { l ^= p[i]; r ^= F(l); } while(0)
+static void
+burn_stack (int bytes)
+{
+ char buf[64];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
+
static void
do_encrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
@@ -416,7 +427,7 @@ decrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
#undef R
static void
-encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
+do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
{
u32 d1, d2;
@@ -433,9 +444,16 @@ encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
outbuf[7] = d2 & 0xff;
}
+static void
+encrypt_block ( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
+{
+ do_encrypt_block (bc, outbuf, inbuf);
+ burn_stack (64);
+}
+
static void
-decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
+do_decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
{
u32 d1, d2;
@@ -452,6 +470,13 @@ decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
outbuf[7] = d2 & 0xff;
}
+static void
+decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
+{
+ do_decrypt_block (bc, outbuf, inbuf);
+ burn_stack (64);
+}
+
static const char*
selftest(void)
@@ -484,7 +509,7 @@ selftest(void)
static int
-bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
+do_bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
{
int i, j;
u32 data, datal, datar;
@@ -567,6 +592,15 @@ bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
}
+static int
+bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
+{
+ int rc = do_bf_setkey (c, key, keylen);
+ burn_stack (64);
+ return rc;
+}
+
+
/****************
* Return some information about the algorithm. We need algo here to
* distinguish different flavors of the algorithm.
diff --git a/cipher/cast5.c b/cipher/cast5.c
index 9811c455..e5ffaa97 100644
--- a/cipher/cast5.c
+++ b/cipher/cast5.c
@@ -1,5 +1,5 @@
/* cast5.c - CAST5 cipher (RFC2144)
- * Copyright (C) 1998 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2001 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -358,7 +358,19 @@ rol(int n, u32 x)
(((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
static void
-encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
+burn_stack (int bytes)
+{
+ char buf[64];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
+
+
+static void
+do_encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
{
u32 l, r, t;
u32 I; /* used by the Fx macros */
@@ -412,7 +424,16 @@ encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
}
static void
-decrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
+encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
+{
+ do_encrypt_block (c, outbuf, inbuf);
+ burn_stack (20+4*sizeof(void*));
+}
+
+
+
+static void
+do_decrypt_block (CAST5_context *c, byte *outbuf, byte *inbuf )
{
u32 l, r, t;
u32 I;
@@ -452,7 +473,13 @@ decrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
outbuf[7] = l & 0xff;
}
-
+static void
+decrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
+{
+ do_decrypt_block (c, outbuf, inbuf);
+ burn_stack (20+4*sizeof(void*));
+}
+
static const char*
selftest(void)
@@ -500,6 +527,7 @@ selftest(void)
return NULL;
}
+
static void
key_schedule( u32 *x, u32 *z, u32 *k )
@@ -550,7 +578,7 @@ key_schedule( u32 *x, u32 *z, u32 *k )
static int
-cast_setkey( CAST5_context *c, byte *key, unsigned keylen )
+do_cast_setkey( CAST5_context *c, byte *key, unsigned keylen )
{
static int initialized;
static const char* selftest_failed;
@@ -592,6 +620,14 @@ cast_setkey( CAST5_context *c, byte *key, unsigned keylen )
return 0;
}
+static int
+cast_setkey( CAST5_context *c, byte *key, unsigned keylen )
+{
+ int rc = do_cast_setkey (c, key, keylen);
+ burn_stack (96+7*sizeof(void*));
+ return rc;
+}
+
/****************
* Return some information about the algorithm. We need algo here to
diff --git a/cipher/cipher.c b/cipher/cipher.c
index 0dfe8661..a5afdc01 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -701,18 +701,24 @@ do_cfb_decrypt( GCRY_CIPHER_HD c,
* inbuf and outbuf may overlap or be the same.
* Depending on the mode some contraints apply to NBYTES.
*/
-static void
+static int
cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf,
const byte *inbuf, unsigned int nbytes )
{
+ int rc = 0;
+
switch( c->mode ) {
case GCRY_CIPHER_MODE_ECB:
- assert(!(nbytes%c->blocksize));
- do_ecb_encrypt(c, outbuf, inbuf, nbytes/c->blocksize );
+ if (!(nbytes%c->blocksize))
+ do_ecb_encrypt(c, outbuf, inbuf, nbytes/c->blocksize );
+ else
+ rc = GCRYERR_INV_ARG;
break;
case GCRY_CIPHER_MODE_CBC:
- assert(!(nbytes%c->blocksize));
- do_cbc_encrypt(c, outbuf, inbuf, nbytes/c->blocksize );
+ if (!(nbytes%c->blocksize))
+ do_cbc_encrypt(c, outbuf, inbuf, nbytes/c->blocksize );
+ else
+ rc = GCRYERR_INV_ARG;
break;
case GCRY_CIPHER_MODE_CFB:
do_cfb_encrypt(c, outbuf, inbuf, nbytes );
@@ -725,8 +731,12 @@ cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf,
if( inbuf != outbuf )
memmove( outbuf, inbuf, nbytes );
break;
- default: log_fatal("cipher_encrypt: invalid mode %d\n", c->mode );
+ default:
+ log_fatal("cipher_encrypt: invalid mode %d\n", c->mode );
+ rc = GCRYERR_INV_CIPHER_MODE;
+ break;
}
+ return rc;
}
@@ -738,21 +748,24 @@ int
gcry_cipher_encrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
const byte *in, size_t inlen )
{
- if( !in ) {
+ int rc;
+
+ if ( !in ) {
/* caller requested in-place encryption */
/* actullay cipher_encrypt() does not need to know about it, but
* we may chnage this to get better performace */
- cipher_encrypt( h, out, out, outsize );
+ rc = cipher_encrypt ( h, out, out, outsize );
}
else {
- if( outsize < inlen )
- return set_lasterr( GCRYERR_TOO_SHORT );
+ if ( outsize < inlen )
+ return set_lasterr ( GCRYERR_TOO_SHORT );
/* fixme: check that the inlength is a multipe of the blocksize
* if a blockoriented mode is used, or modify cipher_encrypt to
* return an error in this case */
- cipher_encrypt( h, out, in, inlen );
+ rc = cipher_encrypt ( h, out, in, inlen );
}
- return 0;
+
+ return rc? set_lasterr (rc):0;
}
@@ -762,18 +775,24 @@ gcry_cipher_encrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
* inbuf and outbuf may overlap or be the same.
* Depending on the mode some some contraints apply to NBYTES.
*/
-static void
+static int
cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf,
unsigned nbytes )
{
+ int rc = 0;
+
switch( c->mode ) {
case GCRY_CIPHER_MODE_ECB:
- assert(!(nbytes%c->blocksize));
- do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->blocksize );
+ if (!(nbytes%c->blocksize))
+ do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->blocksize );
+ else
+ rc = GCRYERR_INV_ARG;
break;
case GCRY_CIPHER_MODE_CBC:
- assert(!(nbytes%c->blocksize));
- do_cbc_decrypt(c, outbuf, inbuf, nbytes/c->blocksize );
+ if (!(nbytes%c->blocksize))
+ do_cbc_decrypt(c, outbuf, inbuf, nbytes/c->blocksize );
+ else
+ rc = GCRYERR_INV_ARG;
break;
case GCRY_CIPHER_MODE_CFB:
do_cfb_decrypt(c, outbuf, inbuf, nbytes );
@@ -786,8 +805,12 @@ cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf,
if( inbuf != outbuf )
memmove( outbuf, inbuf, nbytes );
break;
- default: log_fatal("cipher_decrypt: invalid mode %d\n", c->mode );
+ default:
+ log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode );
+ rc = GCRYERR_INV_CIPHER_MODE;
+ break;
}
+ return rc;
}
@@ -795,11 +818,13 @@ int
gcry_cipher_decrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
const byte *in, size_t inlen )
{
+ int rc;
+
if( !in ) {
/* caller requested in-place encryption */
/* actullay cipher_encrypt() does not need to know about it, but
* we may chnage this to get better performace */
- cipher_decrypt( h, out, out, outsize );
+ rc = cipher_decrypt( h, out, out, outsize );
}
else {
if( outsize < inlen )
@@ -807,9 +832,9 @@ gcry_cipher_decrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
/* fixme: check that the inlength is a multipe of the blocksize
* if a blockoriented mode is used, or modify cipher_encrypt to
* return an error in this case */
- cipher_decrypt( h, out, in, inlen );
+ rc = cipher_decrypt( h, out, in, inlen );
}
- return 0;
+ return rc? set_lasterr (rc):0;
}
@@ -832,9 +857,11 @@ cipher_sync( GCRY_CIPHER_HD c )
int
gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen)
{
+ int rc = 0;
+
switch( cmd ) {
case GCRYCTL_SET_KEY:
- cipher_setkey( h, buffer, buflen );
+ rc = cipher_setkey( h, buffer, buflen );
break;
case GCRYCTL_SET_IV:
cipher_setiv( h, buffer, buflen );
@@ -853,9 +880,9 @@ gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen)
break;
default:
- return set_lasterr( GCRYERR_INV_OP );
+ rc = GCRYERR_INV_OP;
}
- return 0;
+ return set_lasterr (rc);
}
diff --git a/cipher/des.c b/cipher/des.c
index f421f395..7d089c58 100644
--- a/cipher/des.c
+++ b/cipher/des.c
@@ -1,5 +1,5 @@
/* des.c - DES and Triple-DES encryption/decryption Algorithm
- * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
*
* Please see below for more legal information!
*
@@ -136,6 +136,17 @@ working_memcmp( const char *a, const char *b, size_t n )
}
#endif
+static void
+burn_stack (int bytes)
+{
+ char buf[64];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
+
/* Some defines/checks to support standalone modules */
@@ -561,6 +572,7 @@ des_setkey (struct _des_ctx *ctx, const byte * key)
return GCRYERR_SELFTEST;
des_key_schedule (key, ctx->encrypt_subkeys);
+ burn_stack (32);
for(i=0; i<32; i+=2)
{
@@ -619,6 +631,7 @@ tripledes_set2keys (struct _tripledes_ctx *ctx,
des_key_schedule (key1, ctx->encrypt_subkeys);
des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
+ burn_stack (32);
for(i=0; i<32; i+=2)
{
@@ -656,6 +669,7 @@ tripledes_set3keys (struct _tripledes_ctx *ctx,
des_key_schedule (key1, ctx->encrypt_subkeys);
des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
des_key_schedule (key3, &(ctx->encrypt_subkeys[64]));
+ burn_stack (32);
for(i=0; i<32; i+=2)
{
@@ -950,8 +964,11 @@ do_tripledes_setkey ( struct _tripledes_ctx *ctx, byte *key, unsigned keylen )
tripledes_set3keys ( ctx, key, key+8, key+16);
- if( is_weak_key( key ) || is_weak_key( key+8 ) || is_weak_key( key+16 ) )
+ if( is_weak_key( key ) || is_weak_key( key+8 ) || is_weak_key( key+16 ) ) {
+ burn_stack (64);
return GCRYERR_WEAK_KEY;
+ }
+ burn_stack (64);
return 0;
}
@@ -961,12 +978,14 @@ static void
do_tripledes_encrypt( struct _tripledes_ctx *ctx, byte *outbuf, byte *inbuf )
{
tripledes_ecb_encrypt ( ctx, inbuf, outbuf );
+ burn_stack (32);
}
static void
do_tripledes_decrypt( struct _tripledes_ctx *ctx, byte *outbuf, byte *inbuf )
{
tripledes_ecb_decrypt ( ctx, inbuf, outbuf );
+ burn_stack (32);
}
diff --git a/cipher/md5.c b/cipher/md5.c
index 60b12270..62584305 100644
--- a/cipher/md5.c
+++ b/cipher/md5.c
@@ -60,6 +60,16 @@ md5_init( MD5_CONTEXT *ctx )
ctx->count = 0;
}
+static void
+burn_stack (int bytes)
+{
+ char buf[128];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
@@ -217,6 +227,7 @@ md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen)
{
if( hd->count == 64 ) { /* flush the buffer */
transform( hd, hd->buf );
+ burn_stack (80+6*sizeof(void*));
hd->count = 0;
hd->nblocks++;
}
@@ -229,6 +240,7 @@ md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen)
if( !inlen )
return;
}
+ burn_stack (80+6*sizeof(void*));
while( inlen >= 64 ) {
transform( hd, inbuf );
@@ -294,6 +306,7 @@ md5_final( MD5_CONTEXT *hd )
hd->buf[62] = msb >> 16;
hd->buf[63] = msb >> 24;
transform( hd, hd->buf );
+ burn_stack (80+6*sizeof(void*));
p = hd->buf;
#ifdef BIG_ENDIAN_HOST
diff --git a/cipher/primegen.c b/cipher/primegen.c
index da8b01f5..9489f0e8 100644
--- a/cipher/primegen.c
+++ b/cipher/primegen.c
@@ -190,6 +190,7 @@ _gcry_generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
count1 = 0;
qbits++;
progress('>');
+ mpi_free (q);
q = gen_prime( qbits, 0, 0 );
goto next_try;
}
@@ -201,6 +202,7 @@ _gcry_generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
count2 = 0;
qbits--;
progress('<');
+ mpi_free (q);
q = gen_prime( qbits, 0, 0 );
goto next_try;
}
@@ -227,14 +229,14 @@ _gcry_generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
if( ret_factors ) { /* caller wants the factors */
*ret_factors = gcry_xcalloc( n+2 , sizeof **ret_factors);
+ i = 0;
if( mode == 1 ) {
- i = 0;
(*ret_factors)[i++] = mpi_copy( q_factor );
for(; i <= n; i++ )
(*ret_factors)[i] = mpi_copy( factors[i] );
}
else {
- for(i=0; i < n; i++ )
+ for(; i < n; i++ )
(*ret_factors)[i] = mpi_copy( factors[i] );
}
}
@@ -284,6 +286,7 @@ _gcry_generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
gcry_free( pool );
gcry_free(perms);
mpi_free(val_2);
+ mpi_free (q);
return prime;
}
diff --git a/cipher/random.c b/cipher/random.c
index f6eec21b..91c80829 100644
--- a/cipher/random.c
+++ b/cipher/random.c
@@ -1,5 +1,5 @@
/* random.c - random number generator
- * Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -138,6 +138,17 @@ initialize(void)
_gcry_cipher_modules_constructor();
}
+static void
+burn_stack (int bytes)
+{
+ char buf[128];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
+
void
_gcry_random_dump_stats()
@@ -280,6 +291,7 @@ mix_pool(byte *pool)
_gcry_rmd160_mixblock( &md, hashbuf);
memcpy(p, hashbuf, 20 );
}
+ burn_stack (200); /* for the rmd160_mixblock() */
}
void
@@ -601,11 +613,14 @@ _gcry_fast_random_poll()
#warning There is no RUSAGE_SELF on this system
#endif
#else
- { struct rusage buf;
+ {
+ struct rusage buf;
/* QNX/Neutrino does return ENOSYS - so we just ignore it and
- * add whatever is in buf */
- if( getrusage( RUSAGE_SELF, &buf ) && errno != ENOSYS )
- BUG();
+ * add whatever is in buf. In a chroot environment it might not
+ * work at all (i.e. because /proc/ is not accessible), so we better
+ * ugnore all error codes and hope for the best
+ */
+ getrusage (RUSAGE_SELF, &buf );
add_randomness( &buf, sizeof buf, 1 );
memset( &buf, 0, sizeof buf );
}
diff --git a/cipher/rijndael.c b/cipher/rijndael.c
index ec110dc5..fa43adbd 100644
--- a/cipher/rijndael.c
+++ b/cipher/rijndael.c
@@ -1706,10 +1706,23 @@ static const u32 rcon[30] = {
};
+
+static void
+burn_stack (int bytes)
+{
+ char buf[64];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
+
+
/* Perform the key setup.
*/
static int
-rijndael_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
+do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
{
static int initialized = 0;
static const char *selftest_failed=0;
@@ -1808,6 +1821,15 @@ rijndael_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
return 0;
}
+static int
+rijndael_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
+{
+ int rc = do_setkey (ctx, key, keylen);
+ burn_stack ( 100 + 16*sizeof(int));
+ return rc;
+}
+
+
/* make a decryption key from an encryption key */
static void
prepare_decryption( RIJNDAEL_context *ctx )
@@ -1846,7 +1868,7 @@ prepare_decryption( RIJNDAEL_context *ctx )
/* Encrypt one block. A and B may be the same. */
static void
-rijndael_encrypt (const RIJNDAEL_context *ctx, byte *b, const byte *a)
+do_encrypt (const RIJNDAEL_context *ctx, byte *b, const byte *a)
{
int r;
byte temp[4][4];
@@ -1923,10 +1945,19 @@ rijndael_encrypt (const RIJNDAEL_context *ctx, byte *b, const byte *a)
*((u32*)(b+12)) ^= *((u32*)rk[ROUNDS][3]);
#undef rk
}
+
+static void
+rijndael_encrypt (const RIJNDAEL_context *ctx, byte *b, const byte *a)
+{
+ do_encrypt (ctx, b, a);
+ burn_stack (16 + 2*sizeof(int));
+}
+
+
/* Decrypt one block. a and b may be the same. */
static void
-rijndael_decrypt (RIJNDAEL_context *ctx, byte *b, const byte *a)
+do_decrypt (RIJNDAEL_context *ctx, byte *b, const byte *a)
{
#define rk (ctx->keySched2)
int ROUNDS = ctx->ROUNDS;
@@ -1935,6 +1966,7 @@ rijndael_decrypt (RIJNDAEL_context *ctx, byte *b, const byte *a)
if ( !ctx->decryption_prepared ) {
prepare_decryption ( ctx );
+ burn_stack (64);
ctx->decryption_prepared = 1;
}
@@ -2008,6 +2040,13 @@ rijndael_decrypt (RIJNDAEL_context *ctx, byte *b, const byte *a)
*((u32*)(b+12)) ^= *((u32*)rk[0][3]);
#undef rk
}
+
+static void
+rijndael_decrypt (RIJNDAEL_context *ctx, byte *b, const byte *a)
+{
+ do_decrypt (ctx, b, a);
+ burn_stack (16+2*sizeof(int));
+}
/* Test a single encryption and decryption with each key size. */
diff --git a/cipher/rmd160.c b/cipher/rmd160.c
index cce9d3c5..d3f00f2e 100644
--- a/cipher/rmd160.c
+++ b/cipher/rmd160.c
@@ -141,6 +141,18 @@
* 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528
*/
+static void
+burn_stack (int bytes)
+{
+ char buf[150];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
+
+
void
_gcry_rmd160_init( RMD160_CONTEXT *hd )
@@ -405,6 +417,7 @@ rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
{
if( hd->count == 64 ) { /* flush the buffer */
transform( hd, hd->buf );
+ burn_stack (108+5*sizeof(void*));
hd->count = 0;
hd->nblocks++;
}
@@ -425,6 +438,7 @@ rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
inlen -= 64;
inbuf += 64;
}
+ burn_stack (108+5*sizeof(void*));
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
}
@@ -497,6 +511,7 @@ rmd160_final( RMD160_CONTEXT *hd )
hd->buf[62] = msb >> 16;
hd->buf[63] = msb >> 24;
transform( hd, hd->buf );
+ burn_stack (108+5*sizeof(void*));
p = hd->buf;
#ifdef BIG_ENDIAN_HOST
diff --git a/cipher/rndlinux.c b/cipher/rndlinux.c
index cf3df66b..e0442407 100644
--- a/cipher/rndlinux.c
+++ b/cipher/rndlinux.c
@@ -125,7 +125,8 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
fprintf(stderr,
_("\n"
"Not enough random bytes available. Please do some other work to give\n"
-"the OS a chance to collect more entropy! (Need %d more bytes)\n"), length );
+"the OS a chance to collect more entropy! (Need %d more bytes)\n"),
+ (int)length );
warn = 1;
continue;
}
diff --git a/cipher/rndunix.c b/cipher/rndunix.c
index 8ef1caed..bcb1f3fd 100644
--- a/cipher/rndunix.c
+++ b/cipher/rndunix.c
@@ -82,6 +82,7 @@
#endif /* _AIX */
#ifndef __QNX__
#include <sys/shm.h>
+#include <signal.h>
#include <sys/signal.h>
#endif /* __QNX__ */
#include <sys/stat.h>
diff --git a/cipher/sha1.c b/cipher/sha1.c
index 39583208..8f0cfc19 100644
--- a/cipher/sha1.c
+++ b/cipher/sha1.c
@@ -50,6 +50,16 @@ typedef struct {
} SHA1_CONTEXT;
+static void
+burn_stack (int bytes)
+{
+ char buf[128];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
static void
@@ -214,6 +224,7 @@ sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen)
{
if( hd->count == 64 ) { /* flush the buffer */
transform( hd, hd->buf );
+ burn_stack (88+4*sizeof(void*));
hd->count = 0;
hd->nblocks++;
}
@@ -234,6 +245,7 @@ sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen)
inlen -= 64;
inbuf += 64;
}
+ burn_stack (88+4*sizeof(void*));
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
}
@@ -290,6 +302,7 @@ sha1_final(SHA1_CONTEXT *hd)
hd->buf[62] = lsb >> 8;
hd->buf[63] = lsb ;
transform( hd, hd->buf );
+ burn_stack (88+4*sizeof(void*));
p = hd->buf;
#ifdef BIG_ENDIAN_HOST
diff --git a/cipher/tiger.c b/cipher/tiger.c
index 7152492e..c4b107da 100644
--- a/cipher/tiger.c
+++ b/cipher/tiger.c
@@ -1,5 +1,5 @@
/* tiger.c - The TIGER hash function
- * Copyright (C) 1998 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2001 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -590,44 +590,16 @@ static u64 sbox4[256] = {
static void
-print_abc( const char *text, u64 a, u64 b, u64 c )
+burn_stack (int bytes)
{
-/*printf("%s: %08X%08X %08X%08X %08X%08X\n",
- text,
- (u32)(a>>32),
- (u32)(a),
- (u32)(b>>32),
- (u32)(b),
- (u32)(c>>32),
- (u32)(c) );*/
+ char buf[256];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
}
-static void
-print_data( const char *text, u64 a, u64 b, u64 c,
- u64 d, u64 e, u64 f,
- u64 g, u64 h )
-{
-/*printf("%s: %08X%08X %08X%08X %08X%08X %08X%08X\n"
- "%s %08X%08X %08X%08X %08X%08X %08X%08X\n",
- text,
- (u32)(a>>32),
- (u32)(a),
- (u32)(b>>32),
- (u32)(b),
- (u32)(c>>32),
- (u32)(c),
- (u32)(d>>32),
- (u32)(d),
- text,
- (u32)(e>>32),
- (u32)(e),
- (u32)(f>>32),
- (u32)(f),
- (u32)(g>>32),
- (u32)(g),
- (u32)(h>>32),
- (u32)(h) );*/
-}
static void
@@ -736,17 +708,11 @@ transform( TIGER_CONTEXT *hd, byte *data )
b = bb = hd->b;
c = cc = hd->c;
- print_data(" key0", x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7] );
- print_abc(" init", a, b, c );
pass( &a, &b, &c, x, 5);
- print_abc("pass1", a, b, c );
key_schedule( x );
pass( &c, &a, &b, x, 7);
- print_abc("pass2", a, b, c );
key_schedule( x );
pass( &b, &c, &a, x, 9);
- print_abc("pass3", a, b, c );
-
/* feedforward */
a ^= aa;
@@ -768,6 +734,7 @@ tiger_write( TIGER_CONTEXT *hd, byte *inbuf, size_t inlen)
{
if( hd->count == 64 ) { /* flush the buffer */
transform( hd, hd->buf );
+ burn_stack (21*8+11*sizeof(void*));
hd->count = 0;
hd->nblocks++;
}
@@ -788,6 +755,7 @@ tiger_write( TIGER_CONTEXT *hd, byte *inbuf, size_t inlen)
inlen -= 64;
inbuf += 64;
}
+ burn_stack (21*8+11*sizeof(void*));
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
}
@@ -841,6 +809,7 @@ tiger_final( TIGER_CONTEXT *hd )
hd->buf[62] = msb >> 16;
hd->buf[63] = msb >> 24;
transform( hd, hd->buf );
+ burn_stack (21*8+11*sizeof(void*));
p = hd->buf;
#ifdef BIG_ENDIAN_HOST
diff --git a/cipher/twofish.c b/cipher/twofish.c
index a7cbb309..eb41d872 100644
--- a/cipher/twofish.c
+++ b/cipher/twofish.c
@@ -544,11 +544,24 @@ static byte calc_sb_tbl[512] = {
x += y; y += x; ctx->a[j] = x; \
ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+static void
+burn_stack (int bytes)
+{
+ char buf[64];
+
+ memset (buf, 0, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ burn_stack (bytes);
+}
+
+
/* Perform the key setup. Note that this works only with 128- and 256-bit
* keys, despite the API that looks like it might support other sizes. */
static int
-twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
+do_twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
{
int i, j, k;
@@ -681,6 +694,16 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
return 0;
}
+
+static int
+twofish_setkey (TWOFISH_context *ctx, const byte *key, unsigned int keylen)
+{
+ int rc = do_twofish_setkey (ctx, key, keylen);
+ burn_stack (23+6*sizeof(void*));
+ return rc;
+}
+
+
/* Macros to compute the g() function in the encryption and decryption
* rounds. G1 is the straight g() function; G2 includes the 8-bit
@@ -743,7 +766,7 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
/* Encrypt one block. in and out may be the same. */
static void
-twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
{
/* The four 32-bit chunks of the text. */
u32 a, b, c, d;
@@ -773,11 +796,19 @@ twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
OUTUNPACK (2, a, 6);
OUTUNPACK (3, b, 7);
}
+
+static void
+twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+{
+ do_twofish_encrypt (ctx, out, in);
+ burn_stack (24+3*sizeof (void*));
+}
+
/* Decrypt one block. in and out may be the same. */
static void
-twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
{
/* The four 32-bit chunks of the text. */
u32 a, b, c, d;
@@ -807,6 +838,14 @@ twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
OUTUNPACK (2, c, 2);
OUTUNPACK (3, d, 3);
}
+
+static void
+twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+{
+ do_twofish_decrypt (ctx, out, in);
+ burn_stack (24+3*sizeof (void*));
+}
+
/* Test a single encryption and decryption with each key size. */
diff --git a/configure.in b/configure.in
index a1ff1da9..c4526d18 100644
--- a/configure.in
+++ b/configure.in
@@ -258,21 +258,14 @@ esac
AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME")
dnl Fixme: Are these the best flags for OpenBSD????
-dnl (I have removed the -lc from * ...CFLAGS for test purposes.)
case "${target}" in
- *-openbsd*)
+ *-openbsd* | *-netbsd*)
NAME_OF_DEV_RANDOM="/dev/srandom"
NAME_OF_DEV_URANDOM="/dev/urandom"
DYNLINK_MOD_CFLAGS="-shared -rdynamic $CFLAGS_PIC -Wl,-Bshareable -Wl,-x"
;;
- *-netbsd*)
- NAME_OF_DEV_RANDOM="/dev/random"
- NAME_OF_DEV_URANDOM="/dev/urandom"
- DYNLINK_MOD_CFLAGS="-shared -rdynamic $CFLAGS_PIC -Wl,-Bshareable -Wl,-x"
- ;;
-
- *-solaris*)
+ *-solaris* | *-irix* | *-dec-osf* )
NAME_OF_DEV_RANDOM="/dev/random"
NAME_OF_DEV_URANDOM="/dev/random"
DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
@@ -725,5 +718,6 @@ doc/Makefile
doc/version.sgml
src/Makefile
src/libgcrypt-config
+tests/Makefile
])
diff --git a/libgcrypt.txt b/libgcrypt.txt
new file mode 100644
index 00000000..1367761b
--- /dev/null
+++ b/libgcrypt.txt
@@ -0,0 +1,93 @@
+%%comments:
+Copyright (C) 2001 Free Software Foundation, Inc.
+
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.1 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
+Texts. A copy of the license is included in the file COPYING.
+
+%%name: Libgcrypt
+
+%%short-description: Cryptographic library
+
+%%full-description: This is a general purpose cryptographic library
+based on the code from GnuPG. It provides functions for all
+cryptograhic building blocks: symmetric ciphers
+(AES,DES,Blowfish,CAST5,Twofish,Arcfour), hash algorithms (MD5,
+RIPE-MD160, SHA-1, TIGER-192), MACs (HMAC for all hash algorithms),
+public key algorithms (RSA, ElGamal, DSA), large integer functions,
+random numbers and a lot of supporting functions.
+
+%%category: security, libraries
+
+%%license: GPL
+%%license verified by:
+%%license verified on:
+
+%%maintainer: g10 Code GmbH <libgcrypt@g10code.com>
+
+%%updated: 2001-06-01
+
+%%keywords: encryption, public key, digital signature, hash
+
+%%interface:
+
+%%programs:
+
+%%GNU: (I am not sure - it is a spring-off from GnuPG)
+
+%%web-page: http://www.gnupg.org
+
+%%support: paid extension/consulting from http://www.g10code.com
+
+%%doc: English programmer reference in Texinfo, Postscript, HTML included
+
+%%developers: Matthew Skala, Michael Roth, Niklas Hernaeus, Remi
+Guyomarch, Werner Koch <wk@gnupg.org>.
+
+%%contributors:
+
+%%sponsors:
+
+%%source: ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/
+
+%%debian:
+
+%%redhat:
+
+%%repository: See http://www.gnupg.org/cvs-access.html
+
+%%related:
+
+%%source-language: C
+
+%%supported-languages: C, C++
+
+%%use-requirements:
+
+%%build-prerequisites:
+
+%%weak-prerequisites:
+
+%%source-prerequisites:
+
+%%version: 1.1.3 alpha released on 2001-05-31
+
+%%announce-list: announce@gnupg.org announce-request@gnupg.org
+
+%%announce-news:
+
+%%help-list:
+
+%%help-news:
+
+%%dev-list: gcrypt-devel@gnupg.org gcrypt-devel-request@gnupg.org
+
+%%dev-news:
+
+%%bug-list:
+
+%%bug-database:
+
+%%entry written by: Werner Koch <wk@gnupg.org> \ No newline at end of file
diff --git a/src/ChangeLog b/src/ChangeLog
index 2ba366d9..fbc03f4b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_strerror): Updated list of error codes.
+
+2001-07-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Replaced the last ulong. Noted by Rami Lehti.
+
2001-05-31 Werner Koch <wk@gnupg.org>
* gcrypt.h, mpi.h: Made some mpi functions public.
diff --git a/src/gcrypt.h b/src/gcrypt.h
index 63f121d3..b13e3875 100644
--- a/src/gcrypt.h
+++ b/src/gcrypt.h
@@ -1,5 +1,5 @@
/* gcrypt.h - GNU digital encryption library interface
- * Copyright (C) 1998 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -224,7 +224,7 @@ void gcry_mpi_add(GCRY_MPI w, GCRY_MPI u, GCRY_MPI v);
void gcry_mpi_add_ui(GCRY_MPI w, GCRY_MPI u, unsigned long v );
void gcry_mpi_addm(GCRY_MPI w, GCRY_MPI u, GCRY_MPI v, GCRY_MPI m);
void gcry_mpi_sub( GCRY_MPI w, GCRY_MPI u, GCRY_MPI v);
-void gcry_mpi_sub_ui(GCRY_MPI w, GCRY_MPI u, ulong v );
+void gcry_mpi_sub_ui(GCRY_MPI w, GCRY_MPI u, unsigned long v );
void gcry_mpi_subm( GCRY_MPI w, GCRY_MPI u, GCRY_MPI v, GCRY_MPI m);
void gcry_mpi_mul_ui(GCRY_MPI w, GCRY_MPI u, unsigned long v );
void gcry_mpi_mul_2exp( GCRY_MPI w, GCRY_MPI u, unsigned long cnt);
diff --git a/src/global.c b/src/global.c
index 8466dace..f78b6f78 100644
--- a/src/global.c
+++ b/src/global.c
@@ -211,23 +211,36 @@ gcry_strerror( int ec )
ec = gcry_errno();
#define X(n,a) case GCRYERR_##n : s = a; break;
switch( ec ) {
- X(SUCCESS, N_("no error"))
- X(GENERAL, N_("general error"))
+ X(SUCCESS, N_("no error"))
+ X(GENERAL, N_("general error"))
+
+ X(INV_PK_ALGO, N_("invalid public key algorithm"))
+ X(INV_MD_ALGO, N_("invalid hash algorithm"))
+ X(BAD_PUBLIC_KEY ,N_("bad public key"))
+ X(BAD_SECRET_KEY ,N_("bad secret key"))
+ X(BAD_SIGNATURE , N_("bad signature"))
+
+ X(INV_CIPHER_ALGO,N_("invalid cipher algorithm"))
+ X(BAD_MPI, N_("bad big integer"))
+ X(WRONG_PK_ALGO, N_("unusable public key algorithm"))
+ X(WEAK_KEY, N_("weak encryption key"))
+ X(INV_KEYLEN, N_("invalid key length"))
+ X(INV_ARG, N_("invalid argument"))
+ X(SELFTEST, N_("selftest failed"))
+
X(INV_OP, N_("invalid operation code or ctl command"))
X(NO_MEM, N_("out of core"))
- X(INV_ARG, N_("invalid argument"))
X(INTERNAL, N_("internal error"))
X(EOF, N_("EOF"))
+ X(INV_OBJ, N_("an object is not valid"))
X(TOO_SHORT, N_("provided buffer too short"))
X(TOO_LARGE, N_("object is too large"))
- X(INV_OBJ, N_("an object is not valid"))
- X(WEAK_KEY, N_("weak encryption key"))
- X(INV_PK_ALGO, N_("invalid public key algorithm"))
- X(INV_CIPHER_ALGO,N_("invalid cipher algorithm"))
- X(INV_MD_ALGO, N_("invalid hash algorithm"))
- X(WRONG_PK_ALGO, N_("unusable public key algorithm"))
+ X(NO_OBJ, N_("no object"))
+ X(NOT_IMPL, N_("not implemented"))
X(CONFLICT, N_("conflict"))
X(INV_CIPHER_MODE,N_("invalid cipher mode"))
+
+
default:
sprintf( buf, "ec=%d", ec );
s = buf;
diff --git a/tests/ChangeLog b/tests/ChangeLog
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/ChangeLog
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 00000000..9875feb9
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,38 @@
+# Copyright (C) 2001 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 General Public License as published by
+# the Free Software Foundation; either version 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+## Process this file with automake to produce Makefile.in
+
+
+# TESTS_ENVIRONMENT =
+
+TESTS = basic
+
+EXTRA_DIST =
+
+INCLUDES =
+LDADD = ../src/libgcrypt.la
+
+noinst_PROGRAMS = $(TESTS)
+
+
+
+
+
+
+
diff --git a/tests/basic.c b/tests/basic.c
new file mode 100644
index 00000000..c850ca69
--- /dev/null
+++ b/tests/basic.c
@@ -0,0 +1,166 @@
+/* basic.c - basic regression tests
+ * Copyright (C) 2001 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "../src/gcrypt.h"
+
+static int error_count;
+
+static void
+fail ( const char *format, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ error_count++;
+}
+
+static void
+die ( const char *format, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ exit (1);
+}
+
+
+static void
+check_one_cipher (int algo, int mode)
+{
+ GCRY_CIPHER_HD hd;
+ char key[32], plain[16], in[16], out[16];
+ int keylen;
+
+ memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32);
+ memcpy (plain, "foobar42FOOBAR17", 16);
+
+ keylen = gcry_cipher_get_algo_keylen (algo);
+ if (keylen < 40/8 || keylen > 32 ) {
+ fail ("algo %d, mode %d, keylength problem (%d)\n",
+ algo, mode, keylen );
+ return;
+ }
+
+ hd = gcry_cipher_open (algo, mode, 0);
+ if (!hd) {
+ fail ("algo %d, mode %d, grcy_open_cipher failed: %s\n",
+ algo, mode, gcry_strerror (-1) );
+ return;
+ }
+
+
+ if (gcry_cipher_setkey (hd, key, keylen)) {
+ fail ("algo %d, mode %d, gcry_cipher_setkey failed: %s\n",
+ algo, mode, gcry_strerror (-1) );
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if ( gcry_cipher_encrypt (hd, out, 16, plain, 16)) {
+ fail ("algo %d, mode %d, gcry_cipher_encrypt failed: %s\n",
+ algo, mode, gcry_strerror (-1) );
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ gcry_cipher_close (hd);
+ hd = gcry_cipher_open (algo, mode, 0);
+ if (!hd) {
+ fail ("algo %d, mode %d, grcy_open_cipher failed: %s\n",
+ algo, mode, gcry_strerror (-1) );
+ return;
+ }
+
+ if (gcry_cipher_setkey (hd, key, keylen)) {
+ fail ("algo %d, mode %d, gcry_cipher_setkey[2] failed: %s\n",
+ algo, mode, gcry_strerror (-1) );
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if ( gcry_cipher_decrypt (hd, in, 16, out, 16)) {
+ fail ("algo %d, mode %d, gcry_cipher_decrypt failed: %s\n",
+ algo, mode, gcry_strerror (-1) );
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ gcry_cipher_close (hd);
+
+ if ( memcmp (plain, in, 16) )
+ fail ("algo %d, mode %d, encrypt-decrypt mismatch\n", algo, mode);
+}
+
+
+static void
+check_ciphers (void)
+{
+ static int algos[] = {
+ GCRY_CIPHER_3DES,
+ GCRY_CIPHER_CAST5,
+ GCRY_CIPHER_BLOWFISH,
+ GCRY_CIPHER_RIJNDAEL,
+ GCRY_CIPHER_RIJNDAEL192,
+ GCRY_CIPHER_RIJNDAEL256,
+ GCRY_CIPHER_TWOFISH,
+ 0
+ };
+ int i;
+
+ for (i=0; algos[i]; i++ ) {
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_ECB);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC);
+ }
+
+ check_one_cipher (GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM);
+ /* we have now run all cipher's selftests */
+ /* TODO: add some extra encryption to test the higher level functions */
+
+}
+
+
+static void
+check_digests ()
+{
+ /* TODO */
+}
+
+
+int
+main (int argc, char **argv)
+{
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("Version mismatch\n");
+ check_ciphers ();
+ check_digests ();
+
+ return error_count? 1:0;
+}
+
+