diff options
author | Werner Koch <wk@gnupg.org> | 2001-08-03 10:57:34 +0000 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2001-08-03 10:57:34 +0000 |
commit | 0c667cbdebcd34dfa556b6b8d786b0677f09f5a5 (patch) | |
tree | d31d08dfe51104bc4e26c6c69b87c8dd4b545047 | |
parent | 442e7215fb0b7455d31587bd6ad9ccb5d5a64dd7 (diff) | |
download | libgcrypt-0c667cbdebcd34dfa556b6b8d786b0677f09f5a5.tar.gz |
Applied changes from GnuPG stable.
Add a first tes program
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | NEWS | 18 | ||||
-rw-r--r-- | THANKS | 2 | ||||
-rw-r--r-- | cipher/ChangeLog | 38 | ||||
-rw-r--r-- | cipher/Makefile.am | 18 | ||||
-rw-r--r-- | cipher/arcfour.c | 33 | ||||
-rw-r--r-- | cipher/blowfish.c | 42 | ||||
-rw-r--r-- | cipher/cast5.c | 46 | ||||
-rw-r--r-- | cipher/cipher.c | 75 | ||||
-rw-r--r-- | cipher/des.c | 23 | ||||
-rw-r--r-- | cipher/md5.c | 13 | ||||
-rw-r--r-- | cipher/primegen.c | 7 | ||||
-rw-r--r-- | cipher/random.c | 25 | ||||
-rw-r--r-- | cipher/rijndael.c | 45 | ||||
-rw-r--r-- | cipher/rmd160.c | 15 | ||||
-rw-r--r-- | cipher/rndlinux.c | 3 | ||||
-rw-r--r-- | cipher/rndunix.c | 1 | ||||
-rw-r--r-- | cipher/sha1.c | 13 | ||||
-rw-r--r-- | cipher/tiger.c | 53 | ||||
-rw-r--r-- | cipher/twofish.c | 45 | ||||
-rw-r--r-- | configure.in | 12 | ||||
-rw-r--r-- | libgcrypt.txt | 93 | ||||
-rw-r--r-- | src/ChangeLog | 8 | ||||
-rw-r--r-- | src/gcrypt.h | 4 | ||||
-rw-r--r-- | src/global.c | 31 | ||||
-rw-r--r-- | tests/ChangeLog | 0 | ||||
-rw-r--r-- | tests/Makefile.am | 38 | ||||
-rw-r--r-- | tests/basic.c | 166 |
29 files changed, 762 insertions, 115 deletions
@@ -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 @@ -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. @@ -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; +} + + |