cipher reorganisiert
authorWerner Koch <wk@gnupg.org>
Tue, 7 Apr 1998 18:16:08 +0000 (18:16 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 7 Apr 1998 18:16:08 +0000 (18:16 +0000)
cipher/ChangeLog
cipher/Makefile.am
cipher/Makefile.in
cipher/blowfish.c
cipher/blowfish.h
cipher/cast5.c
cipher/cast5.h
cipher/cipher.c [new file with mode: 0644]
cipher/misc.c
mpi/ChangeLog
mpi/mpicoder.c

index d768465..e1bc0b8 100644 (file)
@@ -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.
index ff2e9f3..945ae3d 100644 (file)
@@ -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        \
index 91ed0a9..d6bfab3 100644 (file)
@@ -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)
 
index 09b1576..9e3c2bd 100644 (file)
@@ -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;
-    }
-
-}
-
-
index 998bc0c..db96d37 100644 (file)
@@ -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*/
index a14abaa..99791e0 100644 (file)
@@ -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;
-    }
-}
-
-
index 4afaf2a..6d943c2 100644 (file)
 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 (file)
index 0000000..6e2bcce
--- /dev/null
@@ -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;
+    }
+}
+
index d251955..35761e4 100644 (file)
 #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
index 5a2f039..ca01cb4 100644 (file)
@@ -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.
index 4d3f454..9362aff 100644 (file)
@@ -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;
 }