diff options
author | Werner Koch <wk@gnupg.org> | 1998-04-07 18:16:08 +0000 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 1998-04-07 18:16:08 +0000 |
commit | ec42def828299fdb906da477fcf444ce6bb866f9 (patch) | |
tree | eadad240c42d34b6c3857479fda9ae15eeae8fa8 | |
parent | 309bdcc428ef09caad953fe880b244ae1d28dd89 (diff) | |
download | libgcrypt-ec42def828299fdb906da477fcf444ce6bb866f9.tar.gz |
cipher reorganisiert
-rw-r--r-- | cipher/ChangeLog | 7 | ||||
-rw-r--r-- | cipher/Makefile.am | 3 | ||||
-rw-r--r-- | cipher/Makefile.in | 13 | ||||
-rw-r--r-- | cipher/blowfish.c | 202 | ||||
-rw-r--r-- | cipher/blowfish.h | 15 | ||||
-rw-r--r-- | cipher/cast5.c | 217 | ||||
-rw-r--r-- | cipher/cast5.h | 15 | ||||
-rw-r--r-- | cipher/cipher.c | 425 | ||||
-rw-r--r-- | cipher/misc.c | 54 | ||||
-rw-r--r-- | mpi/ChangeLog | 5 | ||||
-rw-r--r-- | mpi/mpicoder.c | 9 |
11 files changed, 475 insertions, 490 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog index d7684659..e1bc0b8e 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,10 @@ +Tue Apr 7 18:46:49 1998 Werner Koch (wk@isil.d.shuttle.de) + + * cipher.c: New + * misc.c (check_cipher_algo): Moved to cipher.c + * cast5.c: Moved many functions to cipher.c + * blowfish.c: Likewise. + Sat Apr 4 19:52:08 1998 Werner Koch (wk@isil.d.shuttle.de) * cast5.c: Implemented and tested. diff --git a/cipher/Makefile.am b/cipher/Makefile.am index ff2e9f37..945ae3db 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -6,7 +6,8 @@ EXTRA_DIST = @CIPHER_EXTRA_DIST@ noinst_LIBRARIES = libcipher.a -libcipher_a_SOURCES = blowfish.c \ +libcipher_a_SOURCES = cipher.c \ + blowfish.c \ blowfish.h \ cast5.c \ cast5.h \ diff --git a/cipher/Makefile.in b/cipher/Makefile.in index 91ed0a95..d6bfab33 100644 --- a/cipher/Makefile.in +++ b/cipher/Makefile.in @@ -97,7 +97,8 @@ EXTRA_DIST = @CIPHER_EXTRA_DIST@ noinst_LIBRARIES = libcipher.a -libcipher_a_SOURCES = blowfish.c \ +libcipher_a_SOURCES = cipher.c \ + blowfish.c \ blowfish.h \ cast5.c \ cast5.h \ @@ -131,8 +132,8 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ -libcipher_a_OBJECTS = blowfish.o cast5.o elgamal.o md5.o primegen.o \ -random.o rmd160.o sha1.o dsa.o md.o misc.o smallprime.o +libcipher_a_OBJECTS = cipher.o blowfish.o cast5.o elgamal.o md5.o \ +primegen.o random.o rmd160.o sha1.o dsa.o md.o misc.o smallprime.o AR = ar CFLAGS = @CFLAGS@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @@ -144,9 +145,9 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP = --best -DEP_FILES = .deps/blowfish.P .deps/cast5.P .deps/dsa.P .deps/elgamal.P \ -.deps/md.P .deps/md5.P .deps/misc.P .deps/primegen.P .deps/random.P \ -.deps/rmd160.P .deps/sha1.P .deps/smallprime.P +DEP_FILES = .deps/blowfish.P .deps/cast5.P .deps/cipher.P .deps/dsa.P \ +.deps/elgamal.P .deps/md.P .deps/md5.P .deps/misc.P .deps/primegen.P \ +.deps/random.P .deps/rmd160.P .deps/sha1.P .deps/smallprime.P SOURCES = $(libcipher_a_SOURCES) OBJECTS = $(libcipher_a_OBJECTS) diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 09b15767..9e3c2bdc 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -37,7 +37,6 @@ #include "util.h" #include "types.h" #include "blowfish.h" -#include "random.h" /* precomputed S boxes */ static const u32 ks0[256] = { @@ -392,8 +391,8 @@ decrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr ) #undef F #undef R -static void -encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) +void +blowfish_encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) { u32 d1, d2; @@ -429,8 +428,8 @@ encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) } -static void -decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) +void +blowfish_decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) { u32 d1, d2; @@ -477,18 +476,18 @@ selftest() byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 }; blowfish_setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 ); - encrypt_block( &c, buffer, plain ); + blowfish_encrypt_block( &c, buffer, plain ); if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) ) log_error("wrong blowfish encryption\n"); - decrypt_block( &c, buffer, buffer ); + blowfish_decrypt_block( &c, buffer, buffer ); if( memcmp( buffer, plain, 8 ) ) log_bug("blowfish failed\n"); blowfish_setkey( &c, key3, 8 ); - encrypt_block( &c, buffer, plain3 ); + blowfish_encrypt_block( &c, buffer, plain3 ); if( memcmp( buffer, cipher3, 8 ) ) log_error("wrong blowfish encryption (3)\n"); - decrypt_block( &c, buffer, buffer ); + blowfish_decrypt_block( &c, buffer, buffer ); if( memcmp( buffer, plain3, 8 ) ) log_bug("blowfish failed (3)\n"); } @@ -507,8 +506,6 @@ blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen ) selftest(); } - fast_random_poll(); - for(i=0; i < BLOWFISH_ROUNDS+2; i++ ) c->p[i] = ps[i]; for(i=0; i < 256; i++ ) { @@ -563,186 +560,3 @@ blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen ) } -void -blowfish_setiv( BLOWFISH_context *c, byte *iv ) -{ - if( iv ) - memcpy( c->iv, iv, BLOWFISH_BLOCKSIZE ); - else - memset( c->iv, 0, BLOWFISH_BLOCKSIZE ); - c->count = 0; - encrypt_block( c, c->eniv, c->iv ); -} - - -void -blowfish_encode( BLOWFISH_context *c, byte *outbuf, byte *inbuf, - unsigned nblocks ) -{ - unsigned n; - - for(n=0; n < nblocks; n++ ) { - encrypt_block( c, outbuf, inbuf ); - inbuf += BLOWFISH_BLOCKSIZE;; - outbuf += BLOWFISH_BLOCKSIZE; - } -} - -void -blowfish_decode( BLOWFISH_context *c, byte *outbuf, byte *inbuf, - unsigned nblocks ) -{ - unsigned n; - - for(n=0; n < nblocks; n++ ) { - decrypt_block( c, outbuf, inbuf ); - inbuf += BLOWFISH_BLOCKSIZE;; - outbuf += BLOWFISH_BLOCKSIZE; - } -} - - - -/**************** - * FIXME: Make use of bigger chunks - * (out may overlap with a or b) - */ -static void -xorblock( byte *out, byte *a, byte *b, unsigned count ) -{ - for( ; count ; count--, a++, b++ ) - *out++ = *a ^ *b ; -} - - - -/**************** - * Encode buffer in CFB mode. nbytes can be an arbitrary value. - */ -void -blowfish_encode_cfb( BLOWFISH_context *c, byte *outbuf, - byte *inbuf, unsigned nbytes) -{ - unsigned n; - int is_aligned; - - if( c->count ) { /* must make a full block first */ - assert( c->count < BLOWFISH_BLOCKSIZE ); - n = BLOWFISH_BLOCKSIZE - c->count; - if( n > nbytes ) - n = nbytes; - xorblock( outbuf, c->eniv+c->count, inbuf, n); - memcpy( c->iv+c->count, outbuf, n); - c->count += n; - nbytes -= n; - inbuf += n; - outbuf += n; - assert( c->count <= BLOWFISH_BLOCKSIZE); - if( c->count == BLOWFISH_BLOCKSIZE ) { - encrypt_block( c, c->eniv, c->iv ); - c->count = 0; - } - else - return; - } - assert(!c->count); - is_aligned = !((ulong)inbuf % SIZEOF_UNSIGNED_LONG); - while( nbytes >= BLOWFISH_BLOCKSIZE ) { - if( is_aligned ) { - #if SIZEOF_UNSIGNED_LONG == BLOWFISH_BLOCKSIZE - *(ulong*)outbuf = *(ulong*)c->eniv ^ *(ulong*)inbuf; - #elif (2*SIZEOF_UNSIGNED_LONG) == BLOWFISH_BLOCKSIZE - ((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0]; - ((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1]; - #elif (4*SIZEOF_UNSIGNED_LONG) == BLOWFISH_BLOCKSIZE - ((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0]; - ((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1]; - ((ulong*)outbuf)[2] = ((ulong*)c->eniv)[2] ^ ((ulong*)inbuf)[2]; - ((ulong*)outbuf)[3] = ((ulong*)c->eniv)[3] ^ ((ulong*)inbuf)[3]; - #else - #error Please remove this info line. - xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE); - #endif - } - else /* not aligned */ - xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE); - memcpy( c->iv, outbuf, BLOWFISH_BLOCKSIZE); - encrypt_block( c, c->eniv, c->iv ); - nbytes -= BLOWFISH_BLOCKSIZE; - inbuf += BLOWFISH_BLOCKSIZE; - outbuf += BLOWFISH_BLOCKSIZE; - } - - if( nbytes ) { - xorblock( outbuf, c->eniv, inbuf, nbytes ); - memcpy( c->iv, outbuf, nbytes ); - c->count = nbytes; - } - -} - - -void -blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf, - byte *inbuf, unsigned nbytes) -{ - unsigned n; - int is_aligned; - - if( c->count ) { /* must make a full block first */ - assert( c->count < BLOWFISH_BLOCKSIZE ); - n = BLOWFISH_BLOCKSIZE - c->count; - if( n > nbytes ) - n = nbytes; - memcpy( c->iv+c->count, inbuf, n); - xorblock( outbuf, c->eniv+c->count, inbuf, n); - c->count += n; - nbytes -= n; - inbuf += n; - outbuf += n; - assert( c->count <= BLOWFISH_BLOCKSIZE); - if( c->count == BLOWFISH_BLOCKSIZE ) { - encrypt_block( c, c->eniv, c->iv ); - c->count = 0; - } - else - return; - } - - assert(!c->count); - is_aligned = !((ulong)inbuf % SIZEOF_UNSIGNED_LONG); - while( nbytes >= BLOWFISH_BLOCKSIZE ) { - memcpy( c->iv, inbuf, BLOWFISH_BLOCKSIZE); - if( is_aligned ) { - #if SIZEOF_UNSIGNED_LONG == BLOWFISH_BLOCKSIZE - *(ulong*)outbuf = *(ulong*)c->eniv ^ *(ulong*)inbuf; - #elif (2*SIZEOF_UNSIGNED_LONG) == BLOWFISH_BLOCKSIZE - ((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0]; - ((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1]; - #elif (4*SIZEOF_UNSIGNED_LONG) == BLOWFISH_BLOCKSIZE - ((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0]; - ((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1]; - ((ulong*)outbuf)[2] = ((ulong*)c->eniv)[2] ^ ((ulong*)inbuf)[2]; - ((ulong*)outbuf)[3] = ((ulong*)c->eniv)[3] ^ ((ulong*)inbuf)[3]; - #else - #error Please remove this info line. - xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE); - #endif - } - else /* not aligned */ - xorblock( outbuf, c->eniv, inbuf, BLOWFISH_BLOCKSIZE); - encrypt_block( c, c->eniv, c->iv ); - nbytes -= BLOWFISH_BLOCKSIZE; - inbuf += BLOWFISH_BLOCKSIZE; - outbuf += BLOWFISH_BLOCKSIZE; - } - - if( nbytes ) { - memcpy( c->iv, inbuf, nbytes ); - xorblock( outbuf, c->eniv, inbuf, nbytes ); - c->count = nbytes; - } - -} - - diff --git a/cipher/blowfish.h b/cipher/blowfish.h index 998bc0c0..db96d372 100644 --- a/cipher/blowfish.h +++ b/cipher/blowfish.h @@ -31,21 +31,10 @@ typedef struct { u32 s2[256]; u32 s3[256]; u32 p[BLOWFISH_ROUNDS+2]; - byte iv[BLOWFISH_BLOCKSIZE]; - byte eniv[BLOWFISH_BLOCKSIZE]; - int count; } BLOWFISH_context; void blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen ); -void blowfish_setiv( BLOWFISH_context *c, byte *iv ); -void blowfish_encode( BLOWFISH_context *c, byte *outbuf, byte *inbuf, - unsigned nblocks ); -void blowfish_decode( BLOWFISH_context *c, byte *outbuf, byte *inbuf, - unsigned nblocks ); -void blowfish_encode_cfb( BLOWFISH_context *c, byte *outbuf, - byte *inbuf, unsigned nbytes); -void blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf, - byte *inbuf, unsigned nbytes); - +void blowfish_encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ); +void blowfish_decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ); #endif /*G10_BLOWFISH_H*/ diff --git a/cipher/cast5.c b/cipher/cast5.c index a14abaa3..99791e05 100644 --- a/cipher/cast5.c +++ b/cipher/cast5.c @@ -43,7 +43,6 @@ #include "util.h" #include "types.h" #include "cast5.h" -#include "random.h" static const u32 s1[256] = { 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, @@ -339,8 +338,8 @@ rol(int n, u32 x) #define F3(D,m,r) ( (I = ((m) - (D))), (I=rol((r),I)), \ (((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 ) +void +cast5_encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf ) { u32 l, r, t; u32 I; /* used by the Fx macros */ @@ -393,8 +392,8 @@ encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf ) outbuf[7] = l & 0xff; } -static void -decrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf ) +void +cast5_decrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf ) { u32 l, r, t; u32 I; @@ -447,10 +446,10 @@ selftest() byte buffer[8]; cast5_setkey( &c, key, 16 ); - encrypt_block( &c, buffer, plain ); + cast5_encrypt_block( &c, buffer, plain ); if( memcmp( buffer, cipher, 8 ) ) log_error("wrong cast5-128 encryption\n"); - decrypt_block( &c, buffer, buffer ); + cast5_decrypt_block( &c, buffer, buffer ); if( memcmp( buffer, plain, 8 ) ) log_bug("cast5-128 failed\n"); @@ -468,11 +467,11 @@ selftest() for(i=0; i < 1000000; i++ ) { cast5_setkey( &c, b0, 16 ); - encrypt_block( &c, a0, a0 ); - encrypt_block( &c, a0+8, a0+8 ); + cast5_encrypt_block( &c, a0, a0 ); + cast5_encrypt_block( &c, a0+8, a0+8 ); cast5_setkey( &c, a0, 16 ); - encrypt_block( &c, b0, b0 ); - encrypt_block( &c, b0+8, b0+8 ); + cast5_encrypt_block( &c, b0, b0 ); + cast5_encrypt_block( &c, b0+8, b0+8 ); } if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) ) log_bug("cast5-128 maintenance test failed\n"); @@ -543,7 +542,6 @@ cast5_setkey( CAST5_context *c, byte *key, unsigned keylen ) initialized = 1; selftest(); } - fast_random_poll(); assert(keylen==16); x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]; @@ -567,198 +565,3 @@ cast5_setkey( CAST5_context *c, byte *key, unsigned keylen ) } -void -cast5_setiv( CAST5_context *c, byte *iv ) -{ - if( iv ) - memcpy( c->iv, iv, CAST5_BLOCKSIZE ); - else - memset( c->iv, 0, CAST5_BLOCKSIZE ); - c->count = 0; - encrypt_block( c, c->eniv, c->iv ); -} - - -void -cast5_encode( CAST5_context *c, byte *outbuf, byte *inbuf, - unsigned nblocks ) -{ - unsigned n; - - for(n=0; n < nblocks; n++ ) { - encrypt_block( c, outbuf, inbuf ); - inbuf += CAST5_BLOCKSIZE;; - outbuf += CAST5_BLOCKSIZE; - } -} - -void -cast5_decode( CAST5_context *c, byte *outbuf, byte *inbuf, - unsigned nblocks ) -{ - unsigned n; - - for(n=0; n < nblocks; n++ ) { - decrypt_block( c, outbuf, inbuf ); - inbuf += CAST5_BLOCKSIZE;; - outbuf += CAST5_BLOCKSIZE; - } -} - - - -/**************** - * FIXME: Make use of bigger chunks - * (out may overlap with a or b) - */ -static void -xorblock( byte *out, byte *a, byte *b, unsigned count ) -{ - for( ; count ; count--, a++, b++ ) - *out++ = *a ^ *b ; -} - - - -/**************** - * Encode buffer in CFB mode. nbytes can be an arbitrary value. - */ -void -cast5_encode_cfb( CAST5_context *c, byte *outbuf, - byte *inbuf, unsigned nbytes) -{ - unsigned n; - int is_aligned; - - if( c->count ) { /* must make a full block first */ - assert( c->count < CAST5_BLOCKSIZE ); - n = CAST5_BLOCKSIZE - c->count; - if( n > nbytes ) - n = nbytes; - xorblock( outbuf, c->eniv+c->count, inbuf, n); - memcpy( c->iv+c->count, outbuf, n); - c->count += n; - nbytes -= n; - inbuf += n; - outbuf += n; - assert( c->count <= CAST5_BLOCKSIZE); - if( c->count == CAST5_BLOCKSIZE ) { - encrypt_block( c, c->eniv, c->iv ); - c->count = 0; - } - else - return; - } - assert(!c->count); - is_aligned = !((ulong)inbuf % SIZEOF_UNSIGNED_LONG); - while( nbytes >= CAST5_BLOCKSIZE ) { - if( is_aligned ) { - #if SIZEOF_UNSIGNED_LONG == CAST5_BLOCKSIZE - *(ulong*)outbuf = *(ulong*)c->eniv ^ *(ulong*)inbuf; - #elif (2*SIZEOF_UNSIGNED_LONG) == CAST5_BLOCKSIZE - ((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0]; - ((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1]; - #elif (4*SIZEOF_UNSIGNED_LONG) == CAST5_BLOCKSIZE - ((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0]; - ((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1]; - ((ulong*)outbuf)[2] = ((ulong*)c->eniv)[2] ^ ((ulong*)inbuf)[2]; - ((ulong*)outbuf)[3] = ((ulong*)c->eniv)[3] ^ ((ulong*)inbuf)[3]; - #else - #error Please remove this info line. - xorblock( outbuf, c->eniv, inbuf, CAST5_BLOCKSIZE); - #endif - } - else /* not aligned */ - xorblock( outbuf, c->eniv, inbuf, CAST5_BLOCKSIZE); - memcpy( c->iv, outbuf, CAST5_BLOCKSIZE); - encrypt_block( c, c->eniv, c->iv ); - nbytes -= CAST5_BLOCKSIZE; - inbuf += CAST5_BLOCKSIZE; - outbuf += CAST5_BLOCKSIZE; - } - - if( nbytes ) { - xorblock( outbuf, c->eniv, inbuf, nbytes ); - memcpy( c->iv, outbuf, nbytes ); - c->count = nbytes; - } - -} - - -void -cast5_decode_cfb( CAST5_context *c, byte *outbuf, - byte *inbuf, unsigned nbytes) -{ - unsigned n; - int is_aligned; - - if( c->count ) { /* must make a full block first */ - assert( c->count < CAST5_BLOCKSIZE ); - n = CAST5_BLOCKSIZE - c->count; - if( n > nbytes ) - n = nbytes; - memcpy( c->iv+c->count, inbuf, n); - xorblock( outbuf, c->eniv+c->count, inbuf, n); - c->count += n; - nbytes -= n; - inbuf += n; - outbuf += n; - assert( c->count <= CAST5_BLOCKSIZE); - if( c->count == CAST5_BLOCKSIZE ) { - encrypt_block( c, c->eniv, c->iv ); - c->count = 0; - } - else - return; - } - - assert(!c->count); - is_aligned = !((ulong)inbuf % SIZEOF_UNSIGNED_LONG); - while( nbytes >= CAST5_BLOCKSIZE ) { - memcpy( c->iv, inbuf, CAST5_BLOCKSIZE); - if( is_aligned ) { - #if SIZEOF_UNSIGNED_LONG == CAST5_BLOCKSIZE - *(ulong*)outbuf = *(ulong*)c->eniv ^ *(ulong*)inbuf; - #elif (2*SIZEOF_UNSIGNED_LONG) == CAST5_BLOCKSIZE - ((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0]; - ((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1]; - #elif (4*SIZEOF_UNSIGNED_LONG) == CAST5_BLOCKSIZE - ((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0]; - ((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1]; - ((ulong*)outbuf)[2] = ((ulong*)c->eniv)[2] ^ ((ulong*)inbuf)[2]; - ((ulong*)outbuf)[3] = ((ulong*)c->eniv)[3] ^ ((ulong*)inbuf)[3]; - #else - #error Please remove this info line. - xorblock( outbuf, c->eniv, inbuf, CAST5_BLOCKSIZE); - #endif - } - else /* not aligned */ - xorblock( outbuf, c->eniv, inbuf, CAST5_BLOCKSIZE); - encrypt_block( c, c->eniv, c->iv ); - nbytes -= CAST5_BLOCKSIZE; - inbuf += CAST5_BLOCKSIZE; - outbuf += CAST5_BLOCKSIZE; - } - - if( nbytes ) { - memcpy( c->iv, inbuf, nbytes ); - xorblock( outbuf, c->eniv, inbuf, nbytes ); - c->count = nbytes; - } - -} - - - -void -cast5_sync_cfb( CAST5_context *c ) -{ - if( c->count ) { - memmove(c->iv + c->count, c->iv, CAST5_BLOCKSIZE - c->count ); - memcpy(c->iv, c->eniv + CAST5_BLOCKSIZE - c->count, c->count); - c->count = 0; - } -} - - diff --git a/cipher/cast5.h b/cipher/cast5.h index 4afaf2a8..6d943c25 100644 --- a/cipher/cast5.h +++ b/cipher/cast5.h @@ -27,22 +27,11 @@ typedef struct { u32 Km[16]; byte Kr[16]; - byte iv[CAST5_BLOCKSIZE]; - byte eniv[CAST5_BLOCKSIZE]; - int count; } CAST5_context; void cast5_setkey( CAST5_context *c, byte *key, unsigned keylen ); -void cast5_setiv( CAST5_context *c, byte *iv ); -void cast5_encode( CAST5_context *c, byte *outbuf, byte *inbuf, - unsigned nblocks ); -void cast5_decode( CAST5_context *c, byte *outbuf, byte *inbuf, - unsigned nblocks ); -void cast5_encode_cfb( CAST5_context *c, byte *outbuf, - byte *inbuf, unsigned nbytes); -void cast5_decode_cfb( CAST5_context *c, byte *outbuf, - byte *inbuf, unsigned nbytes); -void cast5_sync_cfb( CAST5_context *c ); +void cast5_encrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf ); +void cast5_decrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf ); #endif /*G10_CAST5_H*/ diff --git a/cipher/cipher.c b/cipher/cipher.c new file mode 100644 index 00000000..6e2bcce0 --- /dev/null +++ b/cipher/cipher.c @@ -0,0 +1,425 @@ +/* cipher.c - cipher dispatcher + * Copyright (C) 1998 Free Software Foundation, Inc. + * + * This file is part of GNUPG. + * + * GNUPG 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. + * + * GNUPG 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 + */ + +#define DEFINES_CIPHER_HANDLE 1 + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include "util.h" +#include "errors.h" +#include "cipher.h" +#include "blowfish.h" +#include "cast5.h" + +#define STD_BLOCKSIZE 8 + +#if BLOWFISH_BLOCKSIZE != STD_BLOCKSIZE + #error Invalid BLOWFISH blocksize +#elif CAST5_BLOCKSIZE != STD_BLOCKSIZE + #error Invalid CAST blocksize +#endif + + +static struct { const char *name; int algo;} cipher_names[] = { + { "IDEA", CIPHER_ALGO_IDEA }, + { "3DES", CIPHER_ALGO_3DES }, + { "CAST", CIPHER_ALGO_CAST }, + { "BLOWFISH128", CIPHER_ALGO_BLOWFISH128 }, + { "ROT_N", CIPHER_ALGO_ROT_N }, + { "SAFER_SK128", CIPHER_ALGO_SAFER_SK128 }, + { "DES_SK", CIPHER_ALGO_DES_SK }, + { "BLOWFISH", CIPHER_ALGO_BLOWFISH }, + {NULL} }; + + +/* Hmmm, no way for a void arg in function pointer? */ +#define FNCCAST_SETKEY(f) (void(*)(void*, byte*, unsigned))(f) +#define FNCCAST_CRYPT(f) (void(*)(void*, byte*, byte*))(f) + + +struct cipher_handle_s { + int algo; + int mode; + byte iv[STD_BLOCKSIZE]; /* (this should be ulong aligned) */ + byte lastiv[STD_BLOCKSIZE]; + int unused; /* in IV */ + void (*setkey)( void *c, byte *key, unsigned keylen ); + void (*encrypt)( void *c, byte *outbuf, byte *inbuf ); + void (*decrypt)( void *c, byte *outbuf, byte *inbuf ); + void (*sync_cfb)( void *c ); + union { + int context; + BLOWFISH_context blowfish; + CAST5_context cast5; + } c; +}; + + +/**************** + * Map a string to the cipher algo + */ +int +string_to_cipher_algo( const char *string ) +{ + int i; + const char *s; + + for(i=0; (s=cipher_names[i].name); i++ ) + if( !stricmp( s, string ) ) + return cipher_names[i].algo; + return 0; +} + +/**************** + * Map a cipher algo to a string + */ +const char * +cipher_algo_to_string( int algo ) +{ + int i; + + for(i=0; cipher_names[i].name; i++ ) + if( cipher_names[i].algo == algo ) + return cipher_names[i].name; + return NULL; +} + +/**************** + * Return 0 if the cipher algo is available + */ +int +check_cipher_algo( int algo ) +{ + switch( algo ) { + case CIPHER_ALGO_BLOWFISH128: + case CIPHER_ALGO_BLOWFISH: + case CIPHER_ALGO_CAST: + return 0; + default: + return G10ERR_CIPHER_ALGO; + } +} + + +/**************** + * Open a cipher handle for use with algorithm ALGO, in mode MODE + * and put it into secure memory if SECURE is true. + */ +CIPHER_HANDLE +cipher_open( int algo, int mode, int secure ) +{ + CIPHER_HANDLE hd; + + fast_random_poll(); + /* performance hint: + * It is possible to allocate less memory depending on the cipher */ + hd = secure ? m_alloc_secure_clear( sizeof *hd ) + : m_alloc_clear( sizeof *hd ); + hd->algo = algo; + if( mode == CIPHER_MODE_AUTO_CFB ) { + if( algo == CIPHER_ALGO_CAST ) + hd->mode = CIPHER_MODE_PHILS_CFB; + else + hd->mode = CIPHER_MODE_CFB; + } + else + hd->mode = mode; + switch( algo ) { + case CIPHER_ALGO_BLOWFISH: + case CIPHER_ALGO_BLOWFISH128: + hd->setkey = FNCCAST_SETKEY(blowfish_setkey); + hd->encrypt = FNCCAST_CRYPT(blowfish_encrypt_block); + hd->decrypt = FNCCAST_CRYPT(blowfish_decrypt_block); + break; + + case CIPHER_ALGO_CAST: + hd->setkey = FNCCAST_SETKEY(cast5_setkey); + hd->encrypt = FNCCAST_CRYPT(cast5_encrypt_block); + hd->decrypt = FNCCAST_CRYPT(cast5_decrypt_block); + break; + + default: log_fatal("cipher_open: invalid algo %d\n", algo ); + } + + return hd; +} + + +void +cipher_close( CIPHER_HANDLE c ) +{ + m_free(c); +} + + +void +cipher_setkey( CIPHER_HANDLE c, byte *key, unsigned keylen ) +{ + (*c->setkey)( &c->c.context, key, keylen ); +} + + +void +cipher_setiv( CIPHER_HANDLE c, const byte *iv ) +{ + if( iv ) + memcpy( c->iv, iv, STD_BLOCKSIZE ); + else + memset( c->iv, 0, STD_BLOCKSIZE ); + c->unused = 0; +} + + + +static void +do_ecb_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nblocks ) +{ + unsigned n; + + for(n=0; n < nblocks; n++ ) { + (*c->encrypt)( &c->c.context, outbuf, inbuf ); + inbuf += CAST5_BLOCKSIZE;; + outbuf += CAST5_BLOCKSIZE; + } +} + +static void +do_ecb_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nblocks ) +{ + unsigned n; + + for(n=0; n < nblocks; n++ ) { + (*c->decrypt)( &c->c.context, outbuf, inbuf ); + inbuf += CAST5_BLOCKSIZE;; + outbuf += CAST5_BLOCKSIZE; + } +} + + +static void +do_cfb_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) +{ + byte *ivp; + + if( nbytes <= c->unused ) { + /* short enough to be encoded by the remaining XOR mask */ + /* XOR the input with the IV and store input into IV */ + c->unused -= nbytes; + for(ivp=c->iv+STD_BLOCKSIZE - c->unused; nbytes; nbytes-- ) + *outbuf++ = (*ivp++ ^= *inbuf++); + return; + } + + if( c->unused ) { + /* XOR the input with the IV and store input into IV */ + nbytes -= c->unused; + for(ivp=c->iv+STD_BLOCKSIZE - c->unused; c->unused; c->unused-- ) + *outbuf++ = (*ivp++ ^= *inbuf++); + } + + /* now we can process complete blocks */ + while( nbytes >= STD_BLOCKSIZE ) { + int i; + /* encrypt the IV (and save the current one) */ + memcpy( c->lastiv, c->iv, STD_BLOCKSIZE ); + (*c->encrypt)( &c->c.context, c->iv, c->iv ); + /* XOR the input with the IV and store input into IV */ + for(ivp=c->iv,i=0; i < STD_BLOCKSIZE; i++ ) + *outbuf++ = (*ivp++ ^= *inbuf++); + nbytes -= STD_BLOCKSIZE; + } + if( nbytes ) { /* process the remaining bytes */ + /* encrypt the IV (and save the current one) */ + memcpy( c->lastiv, c->iv, STD_BLOCKSIZE ); + (*c->encrypt)( &c->c.context, c->iv, c->iv ); + c->unused = STD_BLOCKSIZE; + /* and apply the xor */ + c->unused -= nbytes; + for(ivp=c->iv; nbytes; nbytes-- ) + *outbuf++ = (*ivp++ ^= *inbuf++); + } +} + + +static void +do_cfb_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) +{ + byte *ivp; + ulong temp; + + if( nbytes <= c->unused ) { + /* short enough to be encoded by the remaining XOR mask */ + /* XOR the input with the IV and store input into IV */ + c->unused -= nbytes; + for(ivp=c->iv+STD_BLOCKSIZE - c->unused; nbytes; nbytes-- ) { + temp = *inbuf++; + *outbuf++ = *ivp ^ temp; + *ivp++ = temp; + } + return; + } + + if( c->unused ) { + /* XOR the input with the IV and store input into IV */ + nbytes -= c->unused; + for(ivp=c->iv+STD_BLOCKSIZE - c->unused; c->unused; c->unused-- ) { + temp = *inbuf++; + *outbuf++ = *ivp ^ temp; + *ivp++ = temp; + } + } + + /* now we can process complete blocks */ + #ifdef BIG_ENDIAN_HOST + /* This does only make sense for big endian hosts, due to ... ivp = temp*/ + if( !((ulong)inbuf % SIZEOF_UNSIGNED_LONG) ) { + while( nbytes >= STD_BLOCKSIZE ) { + /* encrypt the IV (and save the current one) */ + memcpy( c->lastiv, c->iv, STD_BLOCKSIZE ); + (*c->encrypt)( &c->c.context, c->iv, c->iv ); + ivp = c->iv; + /* XOR the input with the IV and store input into IV */ + #if SIZEOF_UNSIGNED_LONG == STD_BLOCKSIZE + temp = *(ulong*)inbuf; + *(ulong*)outbuf = *(ulong*)c->iv ^ temp; + *(ulong*)ivp = temp; + #elif (2*SIZEOF_UNSIGNED_LONG) == STD_BLOCKSIZE + temp = ((ulong*)inbuf)[0]; + ((ulong*)outbuf)[0] = ((ulong*)c->iv)[0] ^ temp; + ((ulong*)ivp)[0] = temp; + temp = ((ulong*)inbuf)[1]; + ((ulong*)outbuf)[1] = ((ulong*)c->iv)[1] ^ temp; + ((ulong*)ivp)[1] = temp; + #elif (4*SIZEOF_UNSIGNED_LONG) == STD_BLOCKSIZE + temp = ((ulong*)inbuf)[0]; + ((ulong*)outbuf)[0] = ((ulong*)c->iv)[0] ^ temp; + ((ulong*)ivp)[0] = temp; + temp = ((ulong*)inbuf)[1]; + ((ulong*)outbuf)[1] = ((ulong*)c->iv)[1] ^ temp; + ((ulong*)ivp)[1] = temp; + temp = ((ulong*)inbuf)[2]; + ((ulong*)outbuf)[2] = ((ulong*)c->iv)[2] ^ temp; + ((ulong*)ivp)[2] = temp; + temp = ((ulong*)inbuf)[3]; + ((ulong*)outbuf)[3] = ((ulong*)c->iv)[3] ^ temp; + ((ulong*)ivp)[3] = temp; + #else + #error Please disable the align test. + #endif + nbytes -= STD_BLOCKSIZE; + } + } + else { /* non aligned version */ + #endif /* BIG_ENDIAN_HOST */ + while( nbytes >= STD_BLOCKSIZE ) { + int i; + /* encrypt the IV (and save the current one) */ + memcpy( c->lastiv, c->iv, STD_BLOCKSIZE ); + (*c->encrypt)( &c->c.context, c->iv, c->iv ); + /* XOR the input with the IV and store input into IV */ + for(ivp=c->iv,i=0; i < STD_BLOCKSIZE; i++ ) { + temp = *inbuf++; + *outbuf++ = *ivp ^ temp; + *ivp++ = temp; + } + nbytes -= STD_BLOCKSIZE; + } + #ifdef BIG_ENDIAN_HOST + } + #endif + if( nbytes ) { /* process the remaining bytes */ + /* encrypt the IV (and save the current one) */ + memcpy( c->lastiv, c->iv, STD_BLOCKSIZE ); + (*c->encrypt)( &c->c.context, c->iv, c->iv ); + c->unused = STD_BLOCKSIZE; + /* and apply the xor */ + c->unused -= nbytes; + for(ivp=c->iv; nbytes; nbytes-- ) { + temp = *inbuf++; + *outbuf++ = *ivp ^ temp; + *ivp++ = temp; + } + } +} + + +/**************** + * Encrypt INBUF to OUTBUF with the mode selected at open. + * inbuf and outbuf may overlap or be the same. + * Depending on the mode some some contraints apply to NBYTES. + */ +void +cipher_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) +{ + switch( c->mode ) { + case CIPHER_MODE_ECB: + assert(!(nbytes%8)); + do_ecb_encrypt(c, outbuf, inbuf, nbytes/8 ); + break; + case CIPHER_MODE_CFB: + case CIPHER_MODE_PHILS_CFB: + do_cfb_encrypt(c, outbuf, inbuf, nbytes ); + break; + default: log_fatal("cipher_encrypt: invalid mode %d\n", c->mode ); + } +} + + +/**************** + * Decrypt INBUF to OUTBUF with the mode selected at open. + * inbuf and outbuf may overlap or be the same. + * Depending on the mode some some contraints apply to NBYTES. + */ +void +cipher_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) +{ + switch( c->mode ) { + case CIPHER_MODE_ECB: + assert(!(nbytes%8)); + do_ecb_decrypt(c, outbuf, inbuf, nbytes/8 ); + break; + case CIPHER_MODE_CFB: + case CIPHER_MODE_PHILS_CFB: + do_cfb_decrypt(c, outbuf, inbuf, nbytes ); + break; + default: log_fatal("cipher_decrypt: invalid mode %d\n", c->mode ); + } +} + + + +/**************** + * Used for PGP's somewhat strange CFB mode. Does only work if + * the handle is in PHILS_CFB mode + */ +void +cipher_sync( CIPHER_HANDLE c ) +{ + if( c->mode == CIPHER_MODE_PHILS_CFB && c->unused ) { + memmove(c->iv + c->unused, c->iv, CAST5_BLOCKSIZE - c->unused ); + memcpy(c->iv, c->lastiv + CAST5_BLOCKSIZE - c->unused, c->unused); + c->unused = 0; + } +} + diff --git a/cipher/misc.c b/cipher/misc.c index d251955e..35761e4f 100644 --- a/cipher/misc.c +++ b/cipher/misc.c @@ -27,17 +27,6 @@ #include "cipher.h" -static struct { const char *name; int algo;} cipher_names[] = { - { "IDEA", CIPHER_ALGO_IDEA }, - { "3DES", CIPHER_ALGO_3DES }, - { "CAST", CIPHER_ALGO_CAST }, - { "BLOWFISH128", CIPHER_ALGO_BLOWFISH128 }, - { "ROT_N", CIPHER_ALGO_ROT_N }, - { "SAFER_SK128", CIPHER_ALGO_SAFER_SK128 }, - { "DES_SK", CIPHER_ALGO_DES_SK }, - { "BLOWFISH", CIPHER_ALGO_BLOWFISH }, - {NULL} }; - static struct { const char *name; int algo;} pubkey_names[] = { { "RSA", PUBKEY_ALGO_RSA }, { "RSA-E", PUBKEY_ALGO_RSA_E }, @@ -57,35 +46,7 @@ static struct { const char *name; int algo;} digest_names[] = { {NULL} }; -/**************** - * Map a string to the cipher algo - */ -int -string_to_cipher_algo( const char *string ) -{ - int i; - const char *s; - - for(i=0; (s=cipher_names[i].name); i++ ) - if( !stricmp( s, string ) ) - return cipher_names[i].algo; - return 0; -} - - -/**************** - * Map a cipher algo to a string - */ -const char * -cipher_algo_to_string( int algo ) -{ - int i; - for(i=0; cipher_names[i].name; i++ ) - if( cipher_names[i].algo == algo ) - return cipher_names[i].name; - return NULL; -} /**************** @@ -153,21 +114,6 @@ digest_algo_to_string( int algo ) -/**************** - * Return 0 if the cipher algo is available - */ -int -check_cipher_algo( int algo ) -{ - switch( algo ) { - case CIPHER_ALGO_BLOWFISH128: - case CIPHER_ALGO_BLOWFISH: - case CIPHER_ALGO_CAST: - return 0; - default: - return G10ERR_CIPHER_ALGO; - } -} int diff --git a/mpi/ChangeLog b/mpi/ChangeLog index 5a2f0399..ca01cb4d 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -1,3 +1,8 @@ +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. diff --git a/mpi/mpicoder.c b/mpi/mpicoder.c index 4d3f454a..9362aff6 100644 --- a/mpi/mpicoder.c +++ b/mpi/mpicoder.c @@ -54,8 +54,6 @@ mpi_write( IOBUF out, MPI a ) iobuf_put(out, (nbits) ); p = buf = mpi_get_buffer( a, &n, NULL ); - for( ; !*p && n; p++, n-- ) - ; rc = iobuf_write( out, p, n ); m_free(buf); return rc; @@ -302,6 +300,13 @@ mpi_get_buffer( MPI a, unsigned *nbytes, int *sign ) #error please implement for this limb size. #endif } + + /* this is sub-optimal but we need to do the shift oepration because + * the caller has to free the returned buffer */ + for(p=buffer; !*p && *nbytes; p++, --*nbytes ) + ; + if( p != buffer ) + memmove(buffer,p, *nbytes); return buffer; } |