cipher reorganisiert

This commit is contained in:
Werner Koch 1998-04-07 18:16:10 +00:00
parent 53a578711f
commit 86f261dbc5
36 changed files with 760 additions and 939 deletions

8
NEWS
View File

@ -1,11 +1,15 @@
Noteworthy changes in version 0.2.15 Noteworthy changes in version 0.2.15
------------------------------------ ------------------------------------
* Fixed a bug with the old checksum calculation for secret keys.
If you run the program without --batch, a warning does inform
you if your secret key needs to be converted; simply use
--change-passphrase to recalculate the checksum. Please do this
soon, as the compatible mode will be removed sometime in the future.
* CAST5 works (using the PGP's special CFB mode). * CAST5 works (using the PGP's special CFB mode).
Noteworthy changes in version 0.2.14 Noteworthy changes in version 0.2.14
------------------------------------ ------------------------------------

9
TODO
View File

@ -49,3 +49,12 @@
* fix the problems with "\v" in gettext * fix the problems with "\v" in gettext
* calculation of cechksums for secret keys is wrong. We used a
the complete chunk length instead of the real number of bits.
The problme ist that it is how to stay compatible to old
keys? - Do wee need a kludge to calculate both versions of
checksums???? (keygen.c, seckey-cert.c)

View File

@ -5,6 +5,6 @@
#info Checking encryption with a pipe #info Checking encryption with a pipe
for i in $plain_files $data_files ; do for i in $plain_files $data_files ; do
run_gpg -e --yes -r "$usrname2" < $i | run_gpg --yes > y run_gpg -e --yes -r "$usrname2" < $i | run_gpg --yes > y
cmp $i y || error "$i: mismatch" cmp $i y || fatal "$i: mismatch"
done done

View 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) Sat Apr 4 19:52:08 1998 Werner Koch (wk@isil.d.shuttle.de)
* cast5.c: Implemented and tested. * cast5.c: Implemented and tested.

View File

@ -6,7 +6,8 @@ EXTRA_DIST = @CIPHER_EXTRA_DIST@
noinst_LIBRARIES = libcipher.a noinst_LIBRARIES = libcipher.a
libcipher_a_SOURCES = blowfish.c \ libcipher_a_SOURCES = cipher.c \
blowfish.c \
blowfish.h \ blowfish.h \
cast5.c \ cast5.c \
cast5.h \ cast5.h \

View File

@ -97,7 +97,8 @@ EXTRA_DIST = @CIPHER_EXTRA_DIST@
noinst_LIBRARIES = libcipher.a noinst_LIBRARIES = libcipher.a
libcipher_a_SOURCES = blowfish.c \ libcipher_a_SOURCES = cipher.c \
blowfish.c \
blowfish.h \ blowfish.h \
cast5.c \ cast5.c \
cast5.h \ cast5.h \
@ -131,8 +132,8 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I..
CPPFLAGS = @CPPFLAGS@ CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
LIBS = @LIBS@ LIBS = @LIBS@
libcipher_a_OBJECTS = blowfish.o cast5.o elgamal.o md5.o primegen.o \ libcipher_a_OBJECTS = cipher.o blowfish.o cast5.o elgamal.o md5.o \
random.o rmd160.o sha1.o dsa.o md.o misc.o smallprime.o primegen.o random.o rmd160.o sha1.o dsa.o md.o misc.o smallprime.o
AR = ar AR = ar
CFLAGS = @CFLAGS@ CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
@ -144,9 +145,9 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar TAR = tar
GZIP = --best GZIP = --best
DEP_FILES = .deps/blowfish.P .deps/cast5.P .deps/dsa.P .deps/elgamal.P \ DEP_FILES = .deps/blowfish.P .deps/cast5.P .deps/cipher.P .deps/dsa.P \
.deps/md.P .deps/md5.P .deps/misc.P .deps/primegen.P .deps/random.P \ .deps/elgamal.P .deps/md.P .deps/md5.P .deps/misc.P .deps/primegen.P \
.deps/rmd160.P .deps/sha1.P .deps/smallprime.P .deps/random.P .deps/rmd160.P .deps/sha1.P .deps/smallprime.P
SOURCES = $(libcipher_a_SOURCES) SOURCES = $(libcipher_a_SOURCES)
OBJECTS = $(libcipher_a_OBJECTS) OBJECTS = $(libcipher_a_OBJECTS)

View File

@ -37,7 +37,6 @@
#include "util.h" #include "util.h"
#include "types.h" #include "types.h"
#include "blowfish.h" #include "blowfish.h"
#include "random.h"
/* precomputed S boxes */ /* precomputed S boxes */
static const u32 ks0[256] = { static const u32 ks0[256] = {
@ -392,8 +391,8 @@ decrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
#undef F #undef F
#undef R #undef R
static void void
encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) blowfish_encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
{ {
u32 d1, d2; u32 d1, d2;
@ -429,8 +428,8 @@ encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
} }
static void void
decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) blowfish_decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
{ {
u32 d1, d2; u32 d1, d2;
@ -477,18 +476,18 @@ selftest()
byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 }; byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
blowfish_setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 ); 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 ) ) if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) )
log_error("wrong blowfish encryption\n"); log_error("wrong blowfish encryption\n");
decrypt_block( &c, buffer, buffer ); blowfish_decrypt_block( &c, buffer, buffer );
if( memcmp( buffer, plain, 8 ) ) if( memcmp( buffer, plain, 8 ) )
log_bug("blowfish failed\n"); log_bug("blowfish failed\n");
blowfish_setkey( &c, key3, 8 ); blowfish_setkey( &c, key3, 8 );
encrypt_block( &c, buffer, plain3 ); blowfish_encrypt_block( &c, buffer, plain3 );
if( memcmp( buffer, cipher3, 8 ) ) if( memcmp( buffer, cipher3, 8 ) )
log_error("wrong blowfish encryption (3)\n"); log_error("wrong blowfish encryption (3)\n");
decrypt_block( &c, buffer, buffer ); blowfish_decrypt_block( &c, buffer, buffer );
if( memcmp( buffer, plain3, 8 ) ) if( memcmp( buffer, plain3, 8 ) )
log_bug("blowfish failed (3)\n"); log_bug("blowfish failed (3)\n");
} }
@ -507,8 +506,6 @@ blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
selftest(); selftest();
} }
fast_random_poll();
for(i=0; i < BLOWFISH_ROUNDS+2; i++ ) for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
c->p[i] = ps[i]; c->p[i] = ps[i];
for(i=0; i < 256; 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;
}
}

View File

@ -31,21 +31,10 @@ typedef struct {
u32 s2[256]; u32 s2[256];
u32 s3[256]; u32 s3[256];
u32 p[BLOWFISH_ROUNDS+2]; u32 p[BLOWFISH_ROUNDS+2];
byte iv[BLOWFISH_BLOCKSIZE];
byte eniv[BLOWFISH_BLOCKSIZE];
int count;
} BLOWFISH_context; } BLOWFISH_context;
void blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen ); void blowfish_setkey( BLOWFISH_context *c, byte *key, unsigned keylen );
void blowfish_setiv( BLOWFISH_context *c, byte *iv ); void blowfish_encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf );
void blowfish_encode( BLOWFISH_context *c, byte *outbuf, byte *inbuf, void blowfish_decrypt_block( BLOWFISH_context *bc, 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);
#endif /*G10_BLOWFISH_H*/ #endif /*G10_BLOWFISH_H*/

View File

@ -43,7 +43,6 @@
#include "util.h" #include "util.h"
#include "types.h" #include "types.h"
#include "cast5.h" #include "cast5.h"
#include "random.h"
static const u32 s1[256] = { static const u32 s1[256] = {
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, 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)), \ #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]) ) (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
static void void
encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf ) cast5_encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
{ {
u32 l, r, t; u32 l, r, t;
u32 I; /* used by the Fx macros */ u32 I; /* used by the Fx macros */
@ -393,8 +392,8 @@ encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
outbuf[7] = l & 0xff; outbuf[7] = l & 0xff;
} }
static void void
decrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf ) cast5_decrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
{ {
u32 l, r, t; u32 l, r, t;
u32 I; u32 I;
@ -447,10 +446,10 @@ selftest()
byte buffer[8]; byte buffer[8];
cast5_setkey( &c, key, 16 ); cast5_setkey( &c, key, 16 );
encrypt_block( &c, buffer, plain ); cast5_encrypt_block( &c, buffer, plain );
if( memcmp( buffer, cipher, 8 ) ) if( memcmp( buffer, cipher, 8 ) )
log_error("wrong cast5-128 encryption\n"); log_error("wrong cast5-128 encryption\n");
decrypt_block( &c, buffer, buffer ); cast5_decrypt_block( &c, buffer, buffer );
if( memcmp( buffer, plain, 8 ) ) if( memcmp( buffer, plain, 8 ) )
log_bug("cast5-128 failed\n"); log_bug("cast5-128 failed\n");
@ -468,11 +467,11 @@ selftest()
for(i=0; i < 1000000; i++ ) { for(i=0; i < 1000000; i++ ) {
cast5_setkey( &c, b0, 16 ); cast5_setkey( &c, b0, 16 );
encrypt_block( &c, a0, a0 ); cast5_encrypt_block( &c, a0, a0 );
encrypt_block( &c, a0+8, a0+8 ); cast5_encrypt_block( &c, a0+8, a0+8 );
cast5_setkey( &c, a0, 16 ); cast5_setkey( &c, a0, 16 );
encrypt_block( &c, b0, b0 ); cast5_encrypt_block( &c, b0, b0 );
encrypt_block( &c, b0+8, b0+8 ); cast5_encrypt_block( &c, b0+8, b0+8 );
} }
if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) ) if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) )
log_bug("cast5-128 maintenance test failed\n"); log_bug("cast5-128 maintenance test failed\n");
@ -543,7 +542,6 @@ cast5_setkey( CAST5_context *c, byte *key, unsigned keylen )
initialized = 1; initialized = 1;
selftest(); selftest();
} }
fast_random_poll();
assert(keylen==16); assert(keylen==16);
x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]; 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;
}
}

View File

@ -27,22 +27,11 @@
typedef struct { typedef struct {
u32 Km[16]; u32 Km[16];
byte Kr[16]; byte Kr[16];
byte iv[CAST5_BLOCKSIZE];
byte eniv[CAST5_BLOCKSIZE];
int count;
} CAST5_context; } CAST5_context;
void cast5_setkey( CAST5_context *c, byte *key, unsigned keylen ); void cast5_setkey( CAST5_context *c, byte *key, unsigned keylen );
void cast5_setiv( CAST5_context *c, byte *iv ); void cast5_encrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf );
void cast5_encode( CAST5_context *c, byte *outbuf, byte *inbuf, void cast5_decrypt_block( CAST5_context *bc, 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 );
#endif /*G10_CAST5_H*/ #endif /*G10_CAST5_H*/

425
cipher/cipher.c Normal file
View File

@ -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;
}
}

View File

@ -27,17 +27,6 @@
#include "cipher.h" #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[] = { static struct { const char *name; int algo;} pubkey_names[] = {
{ "RSA", PUBKEY_ALGO_RSA }, { "RSA", PUBKEY_ALGO_RSA },
{ "RSA-E", PUBKEY_ALGO_RSA_E }, { "RSA-E", PUBKEY_ALGO_RSA_E },
@ -57,35 +46,7 @@ static struct { const char *name; int algo;} digest_names[] = {
{NULL} }; {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 int

View File

@ -1,3 +1,18 @@
Tue Apr 7 19:28:07 1998 Werner Koch (wk@isil.d.shuttle.de)
* cipher.c, encr-data.c, seckey-cert.c: Now uses cipher_xxxx
functions instead of blowfish_xxx or cast_xxx
Tue Apr 7 11:04:02 1998 Werner Koch (wk@isil.d.shuttle.de)
* Makefile.am (g10maint.o): Changed the way it is created.
Mon Apr 6 11:17:08 1998 Werner Koch (wk@isil.d.shuttle.de)
* misc.c: New.
* keygen.c (checksum,checksum_u16,checksum_mpi): Moved to misc.c
* seckey-cert.c: Kludge for wrong ELG checksum implementation.
Sat Apr 4 20:07:01 1998 Werner Koch (wk@isil.d.shuttle.de) Sat Apr 4 20:07:01 1998 Werner Koch (wk@isil.d.shuttle.de)
* cipher.c (cipher_filter): Support for CAST5 * cipher.c (cipher_filter): Support for CAST5

View File

@ -3,7 +3,6 @@
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
EXTRA_DIST = OPTIONS pubring.asc EXTRA_DIST = OPTIONS pubring.asc
OMIT_DEPENDENCIES = zlib.h zconf.h OMIT_DEPENDENCIES = zlib.h zconf.h
BUILT_SOURCES = g10maint.c
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
bin_PROGRAMS = gpg gpgm gpgd bin_PROGRAMS = gpg gpgm gpgd
@ -28,6 +27,7 @@ common_source = \
elg.c \ elg.c \
dsa.c \ dsa.c \
rsa.c \ rsa.c \
misc.c \
options.h \ options.h \
openfile.c \ openfile.c \
keyid.c \ keyid.c \
@ -60,8 +60,7 @@ gpg_SOURCES = g10.c \
keygen.c keygen.c
gpgm_SOURCES = g10maint.c \ gpgm_SOURCES = dearmor.c \
dearmor.c \
$(common_source) $(common_source)
gpgd_SOURCES = gpgd.c \ gpgd_SOURCES = gpgd.c \
@ -70,8 +69,11 @@ gpgd_SOURCES = gpgd.c \
LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@ LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@
g10maint.c : g10.c gpgm_LDADD = g10maint.o $(LDADD)
$(CPP) $(CFLAGS) $(DEFS) $(INCLUDES) -DIS_G10MAINT $< > $@ || rm $@
g10maint.o: g10.c
$(COMPILE) -DIS_G10MAINT -o g10maint.o -c g10.c
$(PROGRAMS): $(needed_libs) $(PROGRAMS): $(needed_libs)

View File

@ -95,7 +95,6 @@ l = @l@
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
EXTRA_DIST = OPTIONS pubring.asc EXTRA_DIST = OPTIONS pubring.asc
OMIT_DEPENDENCIES = zlib.h zconf.h OMIT_DEPENDENCIES = zlib.h zconf.h
BUILT_SOURCES = g10maint.c
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
bin_PROGRAMS = gpg gpgm gpgd bin_PROGRAMS = gpg gpgm gpgd
@ -120,6 +119,7 @@ common_source = \
elg.c \ elg.c \
dsa.c \ dsa.c \
rsa.c \ rsa.c \
misc.c \
options.h \ options.h \
openfile.c \ openfile.c \
keyid.c \ keyid.c \
@ -151,14 +151,15 @@ gpg_SOURCES = g10.c \
decrypt.c \ decrypt.c \
keygen.c keygen.c
gpgm_SOURCES = g10maint.c \ gpgm_SOURCES = dearmor.c \
dearmor.c \
$(common_source) $(common_source)
gpgd_SOURCES = gpgd.c \ gpgd_SOURCES = gpgd.c \
$(common_source) $(common_source)
LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@ LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@
gpgm_LDADD = g10maint.o $(LDADD)
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ../config.h CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
@ -171,32 +172,31 @@ LDFLAGS = @LDFLAGS@
LIBS = @LIBS@ LIBS = @LIBS@
gpg_OBJECTS = g10.o build-packet.o compress.o free-packet.o getkey.o \ gpg_OBJECTS = g10.o build-packet.o compress.o free-packet.o getkey.o \
pkclist.o skclist.o ringedit.o kbnode.o mainproc.o armor.o mdfilter.o \ pkclist.o skclist.o ringedit.o kbnode.o mainproc.o armor.o mdfilter.o \
textfilter.o cipher.o elg.o dsa.o rsa.o openfile.o keyid.o trustdb.o \ textfilter.o cipher.o elg.o dsa.o rsa.o misc.o openfile.o keyid.o \
parse-packet.o passphrase.o pubkey-enc.o seckey-cert.o seskey.o \ trustdb.o parse-packet.o passphrase.o pubkey-enc.o seckey-cert.o \
import.o export.o comment.o status.o sign.o plaintext.o encr-data.o \ seskey.o import.o export.o comment.o status.o sign.o plaintext.o \
encode.o revoke.o keylist.o sig-check.o signal.o verify.o decrypt.o \ encr-data.o encode.o revoke.o keylist.o sig-check.o signal.o verify.o \
keygen.o decrypt.o keygen.o
gpg_LDADD = $(LDADD) gpg_LDADD = $(LDADD)
gpg_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \ gpg_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \
../util/libutil.a ../util/libutil.a
gpg_LDFLAGS = gpg_LDFLAGS =
gpgm_OBJECTS = g10maint.o dearmor.o build-packet.o compress.o \ gpgm_OBJECTS = dearmor.o build-packet.o compress.o free-packet.o \
free-packet.o getkey.o pkclist.o skclist.o ringedit.o kbnode.o \ getkey.o pkclist.o skclist.o ringedit.o kbnode.o mainproc.o armor.o \
mainproc.o armor.o mdfilter.o textfilter.o cipher.o elg.o dsa.o rsa.o \ mdfilter.o textfilter.o cipher.o elg.o dsa.o rsa.o misc.o openfile.o \
openfile.o keyid.o trustdb.o parse-packet.o passphrase.o pubkey-enc.o \ keyid.o trustdb.o parse-packet.o passphrase.o pubkey-enc.o \
seckey-cert.o seskey.o import.o export.o comment.o status.o sign.o \ seckey-cert.o seskey.o import.o export.o comment.o status.o sign.o \
plaintext.o encr-data.o encode.o revoke.o keylist.o sig-check.o \ plaintext.o encr-data.o encode.o revoke.o keylist.o sig-check.o \
signal.o signal.o
gpgm_LDADD = $(LDADD) gpgm_DEPENDENCIES = g10maint.o ../cipher/libcipher.a ../mpi/libmpi.a \
gpgm_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \
../util/libutil.a ../util/libutil.a
gpgm_LDFLAGS = gpgm_LDFLAGS =
gpgd_OBJECTS = gpgd.o build-packet.o compress.o free-packet.o getkey.o \ gpgd_OBJECTS = gpgd.o build-packet.o compress.o free-packet.o getkey.o \
pkclist.o skclist.o ringedit.o kbnode.o mainproc.o armor.o mdfilter.o \ pkclist.o skclist.o ringedit.o kbnode.o mainproc.o armor.o mdfilter.o \
textfilter.o cipher.o elg.o dsa.o rsa.o openfile.o keyid.o trustdb.o \ textfilter.o cipher.o elg.o dsa.o rsa.o misc.o openfile.o keyid.o \
parse-packet.o passphrase.o pubkey-enc.o seckey-cert.o seskey.o \ trustdb.o parse-packet.o passphrase.o pubkey-enc.o seckey-cert.o \
import.o export.o comment.o status.o sign.o plaintext.o encr-data.o \ seskey.o import.o export.o comment.o status.o sign.o plaintext.o \
encode.o revoke.o keylist.o sig-check.o signal.o encr-data.o encode.o revoke.o keylist.o sig-check.o signal.o
gpgd_LDADD = $(LDADD) gpgd_LDADD = $(LDADD)
gpgd_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \ gpgd_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \
../util/libutil.a ../util/libutil.a
@ -214,15 +214,14 @@ GZIP = --best
DEP_FILES = .deps/armor.P .deps/build-packet.P .deps/cipher.P \ DEP_FILES = .deps/armor.P .deps/build-packet.P .deps/cipher.P \
.deps/comment.P .deps/compress.P .deps/dearmor.P .deps/decrypt.P \ .deps/comment.P .deps/compress.P .deps/dearmor.P .deps/decrypt.P \
.deps/dsa.P .deps/elg.P .deps/encode.P .deps/encr-data.P .deps/export.P \ .deps/dsa.P .deps/elg.P .deps/encode.P .deps/encr-data.P .deps/export.P \
.deps/free-packet.P .deps/g10.P .deps/g10maint .deps/g10maint.P \ .deps/free-packet.P .deps/g10.P .deps/getkey.P .deps/gpgd.P \
.deps/getkey.P .deps/gpgd.P .deps/import.P .deps/kbnode.P \ .deps/import.P .deps/kbnode.P .deps/keygen.P .deps/keyid.P \
.deps/keygen.P .deps/keyid.P .deps/keylist.P .deps/mainproc.P \ .deps/keylist.P .deps/mainproc.P .deps/mdfilter.P .deps/misc.P \
.deps/mdfilter.P .deps/openfile.P .deps/parse-packet.P \ .deps/openfile.P .deps/parse-packet.P .deps/passphrase.P \
.deps/passphrase.P .deps/pkclist.P .deps/plaintext.P .deps/pubkey-enc.P \ .deps/pkclist.P .deps/plaintext.P .deps/pubkey-enc.P .deps/revoke.P \
.deps/revoke.P .deps/ringedit.P .deps/rsa.P .deps/seckey-cert.P \ .deps/ringedit.P .deps/rsa.P .deps/seckey-cert.P .deps/seskey.P \
.deps/seskey.P .deps/sig-check.P .deps/sign.P .deps/signal.P \ .deps/sig-check.P .deps/sign.P .deps/signal.P .deps/skclist.P \
.deps/skclist.P .deps/status.P .deps/textfilter.P .deps/trustdb.P \ .deps/status.P .deps/textfilter.P .deps/trustdb.P .deps/verify.P
.deps/verify.P
SOURCES = $(gpg_SOURCES) $(gpgm_SOURCES) $(gpgd_SOURCES) SOURCES = $(gpg_SOURCES) $(gpgm_SOURCES) $(gpgd_SOURCES)
OBJECTS = $(gpg_OBJECTS) $(gpgm_OBJECTS) $(gpgd_OBJECTS) OBJECTS = $(gpg_OBJECTS) $(gpgm_OBJECTS) $(gpgd_OBJECTS)
@ -421,8 +420,8 @@ installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean maintainer-clean-generic clean mostlyclean distclean maintainer-clean
g10maint.c : g10.c g10maint.o: g10.c
$(CPP) $(CFLAGS) $(DEFS) $(INCLUDES) -DIS_G10MAINT $< > $@ || rm $@ $(COMPILE) -DIS_G10MAINT -o g10maint.o -c g10.c
$(PROGRAMS): $(needed_libs) $(PROGRAMS): $(needed_libs)

View File

@ -67,42 +67,21 @@ cipher_filter( void *opaque, int control,
randomize_buffer( temp, 8, 1 ); randomize_buffer( temp, 8, 1 );
temp[8] = temp[6]; temp[8] = temp[6];
temp[9] = temp[7]; temp[9] = temp[7];
if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH cfx->cipher_hd = cipher_open( cfx->dek->algo,
|| cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 ) { CIPHER_MODE_AUTO_CFB, 1 );
cfx->bf_ctx = m_alloc_secure( sizeof *cfx->bf_ctx ); cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen );
blowfish_setkey( cfx->bf_ctx, cfx->dek->key, cfx->dek->keylen ); cipher_setiv( cfx->cipher_hd, NULL );
blowfish_setiv( cfx->bf_ctx, NULL ); cipher_encrypt( cfx->cipher_hd, temp, temp, 10);
blowfish_encode_cfb( cfx->bf_ctx, temp, temp, 10); cipher_sync( cfx->cipher_hd );
}
else if( cfx->dek->algo == CIPHER_ALGO_CAST ) {
cfx->cast5_ctx = m_alloc_secure( sizeof *cfx->cast5_ctx );
cast5_setkey( cfx->cast5_ctx, cfx->dek->key, cfx->dek->keylen );
cast5_setiv( cfx->cast5_ctx, NULL );
cast5_encode_cfb( cfx->cast5_ctx, temp, temp, 10);
cast5_sync_cfb( cfx->cast5_ctx );
}
else
log_bug("no cipher algo %d\n", cfx->dek->algo);
iobuf_write(a, temp, 10); iobuf_write(a, temp, 10);
cfx->header=1; cfx->header=1;
} }
cipher_encrypt( cfx->cipher_hd, buf, buf, size);
if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH
|| cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 )
blowfish_encode_cfb( cfx->bf_ctx, buf, buf, size);
else if( cfx->dek->algo == CIPHER_ALGO_CAST )
cast5_encode_cfb( cfx->cast5_ctx, buf, buf, size);
if( iobuf_write( a, buf, size ) ) if( iobuf_write( a, buf, size ) )
rc = G10ERR_WRITE_FILE; rc = G10ERR_WRITE_FILE;
} }
else if( control == IOBUFCTRL_FREE ) { else if( control == IOBUFCTRL_FREE ) {
if( cfx->dek->algo == CIPHER_ALGO_BLOWFISH cipher_close(cfx->cipher_hd);
|| cfx->dek->algo == CIPHER_ALGO_BLOWFISH128 )
m_free(cfx->bf_ctx);
else if( cfx->dek->algo == CIPHER_ALGO_CAST )
m_free(cfx->cast5_ctx);
} }
else if( control == IOBUFCTRL_DESC ) { else if( control == IOBUFCTRL_DESC ) {
*(char**)buf = "cipher_filter"; *(char**)buf = "cipher_filter";

View File

@ -79,9 +79,6 @@ make_mpi_comment_node( const char *s, MPI a )
nb1 = mpi_get_nbits( a ); nb1 = mpi_get_nbits( a );
p = buf = mpi_get_buffer( a, &n1, NULL ); p = buf = mpi_get_buffer( a, &n1, NULL );
for( ; !*p && n1; p++, n1-- ) /* skip leading null bytes */
;
pkt = m_alloc_clear( sizeof *pkt ); pkt = m_alloc_clear( sizeof *pkt );
pkt->pkttype = PKT_COMMENT; pkt->pkttype = PKT_COMMENT;
pkt->pkt.comment = m_alloc( sizeof *pkt->pkt.comment + n + 2 + n1 ); pkt->pkt.comment = m_alloc( sizeof *pkt->pkt.comment + n + 2 + n1 );

View File

@ -35,9 +35,7 @@ static int decode_filter( void *opaque, int control, IOBUF a,
byte *buf, size_t *ret_len); byte *buf, size_t *ret_len);
typedef struct { typedef struct {
int is_cast5; CIPHER_HANDLE cipher_hd;
BLOWFISH_context *bf_ctx;
CAST5_context *cast5_ctx;
} decode_filter_ctx_t; } decode_filter_ctx_t;
@ -50,7 +48,7 @@ decrypt_data( PKT_encrypted *ed, DEK *dek )
{ {
decode_filter_ctx_t dfx; decode_filter_ctx_t dfx;
byte *p; byte *p;
int c, i; int rc, c, i;
byte temp[16]; byte temp[16];
if( opt.verbose ) { if( opt.verbose ) {
@ -60,25 +58,14 @@ decrypt_data( PKT_encrypted *ed, DEK *dek )
else else
log_info("encrypted with unknown algorithm %d\n", dek->algo ); log_info("encrypted with unknown algorithm %d\n", dek->algo );
} }
if( dek->algo != CIPHER_ALGO_BLOWFISH if( (rc=check_cipher_algo(dek->algo)) )
&& dek->algo != CIPHER_ALGO_BLOWFISH128 return rc;
&& dek->algo != CIPHER_ALGO_CAST )
return G10ERR_CIPHER_ALGO;
if( ed->len && ed->len < 10 ) if( ed->len && ed->len < 10 )
log_bug("Nanu\n"); /* oops: found a bug */ log_bug("Nanu\n"); /* oops: found a bug */
if( dek->algo == CIPHER_ALGO_CAST ) { dfx.cipher_hd = cipher_open( dek->algo, CIPHER_MODE_AUTO_CFB, 1 );
dfx.is_cast5 = 1; cipher_setkey( dfx.cipher_hd, dek->key, dek->keylen );
dfx.cast5_ctx = m_alloc_secure( sizeof *dfx.cast5_ctx ); cipher_setiv( dfx.cipher_hd, NULL );
cast5_setkey( dfx.cast5_ctx, dek->key, dek->keylen );
cast5_setiv( dfx.cast5_ctx, NULL );
}
else {
dfx.is_cast5 = 0;
dfx.bf_ctx = m_alloc_secure( sizeof *dfx.bf_ctx );
blowfish_setkey( dfx.bf_ctx, dek->key, dek->keylen );
blowfish_setiv( dfx.bf_ctx, NULL );
}
if( ed->len ) { if( ed->len ) {
iobuf_set_limit( ed->buf, ed->len ); iobuf_set_limit( ed->buf, ed->len );
@ -93,15 +80,11 @@ decrypt_data( PKT_encrypted *ed, DEK *dek )
else else
temp[i] = c; temp[i] = c;
} }
if( dfx.is_cast5 ) { cipher_decrypt( dfx.cipher_hd, temp, temp, 10);
cast5_decode_cfb( dfx.cast5_ctx, temp, temp, 10); cipher_sync( dfx.cipher_hd );
cast5_sync_cfb( dfx.cast5_ctx );
}
else
blowfish_decode_cfb( dfx.bf_ctx, temp, temp, 10);
p = temp; p = temp;
if( p[6] != p[8] || p[7] != p[9] ) { if( p[6] != p[8] || p[7] != p[9] ) {
m_free(dfx.bf_ctx); cipher_close(dfx.cipher_hd);
return G10ERR_BAD_KEY; return G10ERR_BAD_KEY;
} }
iobuf_push_filter( ed->buf, decode_filter, &dfx ); iobuf_push_filter( ed->buf, decode_filter, &dfx );
@ -112,7 +95,7 @@ decrypt_data( PKT_encrypted *ed, DEK *dek )
else else
iobuf_clear_eof( ed->buf ); iobuf_clear_eof( ed->buf );
ed->buf = NULL; ed->buf = NULL;
m_free(dfx.bf_ctx); cipher_close(dfx.cipher_hd);
return 0; return 0;
} }
@ -132,12 +115,8 @@ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len)
buf[n] = c; buf[n] = c;
} }
if( n ) { if( n )
if( fc->is_cast5 ) cipher_decrypt( fc->cipher_hd, buf, buf, n);
cast5_decode_cfb( fc->cast5_ctx, buf, buf, n);
else
blowfish_decode_cfb( fc->bf_ctx, buf, buf, n);
}
else else
rc = -1; /* eof */ rc = -1; /* eof */
*ret_len = n; *ret_len = n;

View File

@ -60,8 +60,7 @@ typedef struct {
typedef struct { typedef struct {
DEK *dek; DEK *dek;
u32 datalen; u32 datalen;
BLOWFISH_context *bf_ctx; CIPHER_HANDLE cipher_hd;
CAST5_context *cast5_ctx;
int header; int header;
} cipher_filter_context_t; } cipher_filter_context_t;

View File

@ -554,6 +554,7 @@ lookup( PKT_public_cert *pkc, int mode, u32 *keyid, const char *name )
int rc; int rc;
KBNODE keyblock = NULL; KBNODE keyblock = NULL;
KBPOS kbpos; KBPOS kbpos;
int oldmode = set_packet_list_mode(0);
rc = enum_keyblocks( 0, &kbpos, &keyblock ); rc = enum_keyblocks( 0, &kbpos, &keyblock );
if( rc ) { if( rc ) {
@ -655,6 +656,7 @@ lookup( PKT_public_cert *pkc, int mode, u32 *keyid, const char *name )
leave: leave:
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */ enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
release_kbnode( keyblock ); release_kbnode( keyblock );
set_packet_list_mode(oldmode);
return rc; return rc;
} }
@ -667,11 +669,12 @@ lookup_skc( PKT_secret_cert *skc, int mode, u32 *keyid, const char *name )
int rc; int rc;
KBNODE keyblock = NULL; KBNODE keyblock = NULL;
KBPOS kbpos; KBPOS kbpos;
int oldmode = set_packet_list_mode(0);
rc = enum_keyblocks( 5 /* open secret */, &kbpos, &keyblock ); rc = enum_keyblocks( 5 /* open secret */, &kbpos, &keyblock );
if( rc ) { if( rc ) {
if( rc == -1 ) if( rc == -1 )
rc = G10ERR_NO_PUBKEY; rc = G10ERR_NO_SECKEY;
else if( rc ) else if( rc )
log_error("enum_keyblocks(open secret) failed: %s\n", g10_errstr(rc) ); log_error("enum_keyblocks(open secret) failed: %s\n", g10_errstr(rc) );
goto leave; goto leave;
@ -761,13 +764,14 @@ lookup_skc( PKT_secret_cert *skc, int mode, u32 *keyid, const char *name )
keyblock = NULL; keyblock = NULL;
} }
if( rc == -1 ) if( rc == -1 )
rc = G10ERR_NO_PUBKEY; rc = G10ERR_NO_SECKEY;
else if( rc ) else if( rc )
log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc)); log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
leave: leave:
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */ enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
release_kbnode( keyblock ); release_kbnode( keyblock );
set_packet_list_mode(oldmode);
return rc; return rc;
} }

View File

@ -40,42 +40,6 @@
#endif #endif
static u16
checksum_u16( unsigned n )
{
u16 a;
a = (n >> 8) & 0xff;
a |= n & 0xff;
return a;
}
static u16
checksum( byte *p, unsigned n )
{
u16 a;
for(a=0; n; n-- )
a += *p++;
return a;
}
static u16
checksum_mpi( MPI a )
{
u16 csum;
byte *buffer;
unsigned nbytes;
buffer = mpi_get_buffer( a, &nbytes, NULL );
csum = checksum_u16( nbytes*8 );
csum += checksum( buffer, nbytes );
m_free( buffer );
return csum;
}
static void static void
write_uid( KBNODE root, const char *s ) write_uid( KBNODE root, const char *s )
{ {

View File

@ -64,16 +64,10 @@ v3_elg_fingerprint_md( PKT_public_cert *pkc )
nb1 = mpi_get_nbits(pkc->d.elg.p); nb1 = mpi_get_nbits(pkc->d.elg.p);
p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL ); p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL );
for( ; !*p1 && n1; p1++, n1-- ) /* skip leading null bytes */
;
nb2 = mpi_get_nbits(pkc->d.elg.g); nb2 = mpi_get_nbits(pkc->d.elg.g);
p2 = buf2 = mpi_get_buffer( pkc->d.elg.g, &n2, NULL ); p2 = buf2 = mpi_get_buffer( pkc->d.elg.g, &n2, NULL );
for( ; !*p2 && n2; p2++, n2-- ) /* skip leading null bytes */
;
nb3 = mpi_get_nbits(pkc->d.elg.y); nb3 = mpi_get_nbits(pkc->d.elg.y);
p3 = buf3 = mpi_get_buffer( pkc->d.elg.y, &n3, NULL ); p3 = buf3 = mpi_get_buffer( pkc->d.elg.y, &n3, NULL );
for( ; !*p3 && n3; p3++, n3-- ) /* skip leading null bytes */
;
/* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */ /* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */
n = 14 + n1 + n2 + n3; n = 14 + n1 + n2 + n3;
@ -117,16 +111,10 @@ elg_fingerprint_md( PKT_public_cert *pkc )
nb1 = mpi_get_nbits(pkc->d.elg.p); nb1 = mpi_get_nbits(pkc->d.elg.p);
p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL ); p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL );
for( ; !*p1 && n1; p1++, n1-- ) /* skip leading null bytes */
;
nb3 = mpi_get_nbits(pkc->d.elg.g); nb3 = mpi_get_nbits(pkc->d.elg.g);
p3 = buf3 = mpi_get_buffer( pkc->d.elg.g, &n3, NULL ); p3 = buf3 = mpi_get_buffer( pkc->d.elg.g, &n3, NULL );
for( ; !*p3 && n3; p3++, n3-- )
;
nb4 = mpi_get_nbits(pkc->d.elg.y); nb4 = mpi_get_nbits(pkc->d.elg.y);
p4 = buf4 = mpi_get_buffer( pkc->d.elg.y, &n4, NULL ); p4 = buf4 = mpi_get_buffer( pkc->d.elg.y, &n4, NULL );
for( ; !*p4 && n4; p4++, n4-- )
;
/* calculate length of packet */ /* calculate length of packet */
n = 12 + n1 + n3 +n4 ; n = 12 + n1 + n3 +n4 ;
@ -167,20 +155,12 @@ dsa_fingerprint_md( PKT_public_cert *pkc )
nb1 = mpi_get_nbits(pkc->d.dsa.p); nb1 = mpi_get_nbits(pkc->d.dsa.p);
p1 = buf1 = mpi_get_buffer( pkc->d.dsa.p, &n1, NULL ); p1 = buf1 = mpi_get_buffer( pkc->d.dsa.p, &n1, NULL );
for( ; !*p1 && n1; p1++, n1-- ) /* skip leading null bytes */
;
nb2 = mpi_get_nbits(pkc->d.dsa.q); nb2 = mpi_get_nbits(pkc->d.dsa.q);
p2 = buf2 = mpi_get_buffer( pkc->d.dsa.q, &n2, NULL ); p2 = buf2 = mpi_get_buffer( pkc->d.dsa.q, &n2, NULL );
for( ; !*p2 && n2; p2++, n2-- )
;
nb3 = mpi_get_nbits(pkc->d.dsa.g); nb3 = mpi_get_nbits(pkc->d.dsa.g);
p3 = buf3 = mpi_get_buffer( pkc->d.dsa.g, &n3, NULL ); p3 = buf3 = mpi_get_buffer( pkc->d.dsa.g, &n3, NULL );
for( ; !*p3 && n3; p3++, n3-- )
;
nb4 = mpi_get_nbits(pkc->d.dsa.y); nb4 = mpi_get_nbits(pkc->d.dsa.y);
p4 = buf4 = mpi_get_buffer( pkc->d.dsa.y, &n4, NULL ); p4 = buf4 = mpi_get_buffer( pkc->d.dsa.y, &n4, NULL );
for( ; !*p4 && n4; p4++, n4-- )
;
/* calculate length of packet */ /* calculate length of packet */
n = 14 + n1 + n2 + n3 +n4 ; n = 14 + n1 + n2 + n3 +n4 ;
@ -510,13 +490,9 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
md = md_open( DIGEST_ALGO_MD5, 0); md = md_open( DIGEST_ALGO_MD5, 0);
p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL ); p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL );
for( ; !*p && n; p++, n-- )
;
md_write( md, p, n ); md_write( md, p, n );
m_free(buf); m_free(buf);
p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL ); p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL );
for( ; !*p && n; p++, n-- )
;
md_write( md, p, n ); md_write( md, p, n );
m_free(buf); m_free(buf);
md_final(md); md_final(md);

View File

@ -21,6 +21,7 @@
#define G10_MAIN_H #define G10_MAIN_H
#include "types.h" #include "types.h"
#include "iobuf.h" #include "iobuf.h"
#include "mpi.h"
#include "cipher.h" #include "cipher.h"
#include "keydb.h" #include "keydb.h"
@ -39,6 +40,11 @@ typedef struct {
void g10_exit(int rc); void g10_exit(int rc);
#endif #endif
/*-- misc.c --*/
u16 checksum_u16( unsigned n );
u16 checksum( byte *p, unsigned n );
u16 checksum_mpi( MPI a );
/*-- encode.c --*/ /*-- encode.c --*/
int encode_symmetric( const char *filename ); int encode_symmetric( const char *filename );
int encode_store( const char *filename ); int encode_store( const char *filename );

63
g10/misc.c Normal file
View File

@ -0,0 +1,63 @@
/* misc.c - miscellaneous functions
* 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "main.h"
u16
checksum_u16( unsigned n )
{
u16 a;
a = (n >> 8) & 0xff;
a |= n & 0xff;
return a;
}
u16
checksum( byte *p, unsigned n )
{
u16 a;
for(a=0; n; n-- )
a += *p++;
return a;
}
u16
checksum_mpi( MPI a )
{
u16 csum;
byte *buffer;
unsigned nbytes;
buffer = mpi_get_buffer( a, &nbytes, NULL );
csum = checksum_u16( mpi_get_nbits(a) );
csum += checksum( buffer, nbytes );
m_free( buffer );
return csum;
}

View File

@ -61,19 +61,6 @@ static int parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet ); PACKET *packet );
static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet ); PACKET *packet );
#if 0
static u16
checksum( byte *p )
{
u16 n, a;
n = *p++ << 8;
n |= *p++;
for(a=0; n; n-- )
a += *p++;
return a;
}
#endif
static unsigned short static unsigned short
read_16(IOBUF inp) read_16(IOBUF inp)
@ -944,6 +931,9 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
cert->csum = read_16(inp); pktlen -= 2; cert->csum = read_16(inp); pktlen -= 2;
if( list_mode ) { if( list_mode ) {
printf("\telg x: ");
mpi_print(stdout, cert->d.elg.x, mpi_print_mode );
putchar('\n');
printf("\t[secret value x is not shown]\n" printf("\t[secret value x is not shown]\n"
"\tchecksum: %04hx\n", cert->csum); "\tchecksum: %04hx\n", cert->csum);
} }

View File

@ -100,6 +100,8 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
* *
* 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
* *
* (mpi_get_buffer already removed the leading zero).
*
* RND are non-zero randow bytes. * RND are non-zero randow bytes.
* A is the cipher algorithm * A is the cipher algorithm
* DEK is the encryption key (session key) with length k * DEK is the encryption key (session key) with length k
@ -107,8 +109,7 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
*/ */
if( DBG_CIPHER ) if( DBG_CIPHER )
log_hexdump("DEK frame:", frame, nframe ); log_hexdump("DEK frame:", frame, nframe );
for(n=0; n < nframe && !frame[n]; n++ ) /* skip leading zeroes */ n=0;
;
if( n + 7 > nframe ) if( n + 7 > nframe )
{ rc = G10ERR_WRONG_SECKEY; goto leave; } { rc = G10ERR_WRONG_SECKEY; goto leave; }
if( frame[n] == 1 && frame[nframe-1] == 2 ) { if( frame[n] == 1 && frame[nframe-1] == 2 ) {

View File

@ -29,34 +29,8 @@
#include "mpi.h" #include "mpi.h"
#include "keydb.h" #include "keydb.h"
#include "cipher.h" #include "cipher.h"
#include "main.h"
#if BLOWFISH_BLOCKSIZE != 8 #include "options.h"
#error unsupported blocksize
#endif
#if CAST5_BLOCKSIZE != 8
#error unsupported blocksize
#endif
static u16
checksum_u16( unsigned n )
{
u16 a;
a = (n >> 8) & 0xff;
a |= n & 0xff;
return a;
}
static u16
checksum( byte *p, unsigned n )
{
u16 a;
for(a=0; n; n-- )
a += *p++;
return a;
}
static int static int
@ -73,8 +47,7 @@ check_elg( PKT_secret_cert *cert )
if( cert->is_protected ) { /* remove the protection */ if( cert->is_protected ) { /* remove the protection */
DEK *dek = NULL; DEK *dek = NULL;
MPI test_x; MPI test_x;
BLOWFISH_context *blowfish_ctx=NULL; CIPHER_HANDLE cipher_hd=NULL;
CAST5_context *cast5_ctx=NULL;
switch( cert->protect.algo ) { switch( cert->protect.algo ) {
case CIPHER_ALGO_NONE: BUG(); break; case CIPHER_ALGO_NONE: BUG(); break;
@ -87,47 +60,37 @@ check_elg( PKT_secret_cert *cert )
else else
dek = get_passphrase_hash( keyid, NULL, NULL ); dek = get_passphrase_hash( keyid, NULL, NULL );
if( cert->protect.algo == CIPHER_ALGO_CAST ) cipher_hd = cipher_open( cert->protect.algo,
cast5_ctx = m_alloc_secure( sizeof *cast5_ctx ); CIPHER_MODE_AUTO_CFB, 1);
else cipher_setkey( cipher_hd, dek->key, dek->keylen );
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx ); cipher_setiv( cipher_hd, NULL );
if( blowfish_ctx ) {
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
blowfish_setiv( blowfish_ctx, NULL );
}
else {
cast5_setkey( cast5_ctx, dek->key, dek->keylen );
cast5_setiv( cast5_ctx, NULL );
}
m_free(dek); /* pw is in secure memory, so m_free() burns it */ m_free(dek); /* pw is in secure memory, so m_free() burns it */
memcpy(save_iv, cert->protect.iv, 8 ); memcpy(save_iv, cert->protect.iv, 8 );
if( blowfish_ctx ) cipher_decrypt( cipher_hd, cert->protect.iv, cert->protect.iv, 8 );
blowfish_decode_cfb( blowfish_ctx, cert->protect.iv,
cert->protect.iv, 8 );
else
cast5_decode_cfb( cast5_ctx, cert->protect.iv,
cert->protect.iv, 8 );
mpi_set_secure(cert->d.elg.x ); mpi_set_secure(cert->d.elg.x );
/*fixme: maybe it is better to set the buffer secure with a /*fixme: maybe it is better to set the buffer secure with a
* new get_buffer_secure() function */ * new get_buffer_secure() function */
buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL ); buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL );
csum = checksum_u16( nbytes*8 ); cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
if( blowfish_ctx )
blowfish_decode_cfb( blowfish_ctx, buffer, buffer, nbytes );
else
cast5_decode_cfb( cast5_ctx, buffer, buffer, nbytes );
csum += checksum( buffer, nbytes );
test_x = mpi_alloc_secure( mpi_get_nlimbs(cert->d.elg.x) ); test_x = mpi_alloc_secure( mpi_get_nlimbs(cert->d.elg.x) );
mpi_set_buffer( test_x, buffer, nbytes, 0 ); mpi_set_buffer( test_x, buffer, nbytes, 0 );
csum = checksum_mpi( test_x );
m_free( buffer ); m_free( buffer );
m_free( cast5_ctx ); cipher_close( cipher_hd );
m_free( blowfish_ctx );
/* now let's see wether we have used the right passphrase */ /* now let's see wether we have used the right passphrase */
if( csum != cert->csum ) { if( csum != cert->csum ) {
mpi_free(test_x); /* very bad kludge to work around an early bug */
memcpy( cert->protect.iv, save_iv, 8 ); csum -= checksum_u16( mpi_get_nbits(test_x) );
return G10ERR_BAD_PASS; nbytes = mpi_get_nlimbs(test_x) * 4;
csum += checksum_u16( nbytes*8 );
if( csum != cert->csum ) {
mpi_free(test_x);
memcpy( cert->protect.iv, save_iv, 8 );
return G10ERR_BAD_PASS;
}
if( !opt.batch )
log_info("Probably you have an old key - use "
"\"--change-passphrase\" to convert.\n");
} }
skey.p = cert->d.elg.p; skey.p = cert->d.elg.p;
@ -151,12 +114,18 @@ check_elg( PKT_secret_cert *cert )
} }
} }
else { /* not protected */ else { /* not protected */
buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL ); csum = checksum_mpi( cert->d.elg.x );
csum = checksum_u16( nbytes*8 ); if( csum != cert->csum ) {
csum += checksum( buffer, nbytes ); /* very bad kludge to work around an early bug */
m_free( buffer ); csum -= checksum_u16( mpi_get_nbits(cert->d.elg.x) );
if( csum != cert->csum ) nbytes = mpi_get_nlimbs(cert->d.elg.x) * 4;
return G10ERR_CHECKSUM; csum += checksum_u16( nbytes*8 );
if( csum != cert->csum )
return G10ERR_CHECKSUM;
if( !opt.batch )
log_info("Probably you have an old key - use "
"\"--change-passphrase\" to convert.\n");
}
} }
return 0; return 0;
@ -177,8 +146,7 @@ check_dsa( PKT_secret_cert *cert )
if( cert->is_protected ) { /* remove the protection */ if( cert->is_protected ) { /* remove the protection */
DEK *dek = NULL; DEK *dek = NULL;
MPI test_x; MPI test_x;
BLOWFISH_context *blowfish_ctx=NULL; CIPHER_HANDLE cipher_hd=NULL;
CAST5_context *cast5_ctx=NULL;
switch( cert->protect.algo ) { switch( cert->protect.algo ) {
case CIPHER_ALGO_NONE: BUG(); break; case CIPHER_ALGO_NONE: BUG(); break;
@ -191,39 +159,23 @@ check_dsa( PKT_secret_cert *cert )
else else
dek = get_passphrase_hash( keyid, NULL, NULL ); dek = get_passphrase_hash( keyid, NULL, NULL );
if( cert->protect.algo == CIPHER_ALGO_CAST ) { cipher_hd = cipher_open( cert->protect.algo,
cast5_ctx = m_alloc_secure( sizeof *cast5_ctx ); CIPHER_MODE_AUTO_CFB, 1);
cast5_setkey( cast5_ctx, dek->key, dek->keylen ); cipher_setkey( cipher_hd, dek->key, dek->keylen );
cast5_setiv( cast5_ctx, NULL ); cipher_setiv( cipher_hd, NULL );
}
else {
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
blowfish_setiv( blowfish_ctx, NULL );
}
m_free(dek); /* pw is in secure memory, so m_free() burns it */ m_free(dek); /* pw is in secure memory, so m_free() burns it */
memcpy(save_iv, cert->protect.iv, 8 ); memcpy(save_iv, cert->protect.iv, 8 );
if( blowfish_ctx ) cipher_decrypt( cipher_hd, cert->protect.iv, cert->protect.iv, 8 );
blowfish_decode_cfb( blowfish_ctx, cert->protect.iv,
cert->protect.iv, 8 );
else
cast5_decode_cfb( cast5_ctx, cert->protect.iv,
cert->protect.iv, 8 );
mpi_set_secure(cert->d.dsa.x ); mpi_set_secure(cert->d.dsa.x );
/*fixme: maybe it is better to set the buffer secure with a /*fixme: maybe it is better to set the buffer secure with a
* new get_buffer_secure() function */ * new get_buffer_secure() function */
buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL ); buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL );
csum = checksum_u16( nbytes*8 ); cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
if( blowfish_ctx )
blowfish_decode_cfb( blowfish_ctx, buffer, buffer, nbytes );
else
cast5_decode_cfb( cast5_ctx, buffer, buffer, nbytes );
csum += checksum( buffer, nbytes );
test_x = mpi_alloc_secure( mpi_get_nlimbs(cert->d.dsa.x) ); test_x = mpi_alloc_secure( mpi_get_nlimbs(cert->d.dsa.x) );
mpi_set_buffer( test_x, buffer, nbytes, 0 ); mpi_set_buffer( test_x, buffer, nbytes, 0 );
csum = checksum_mpi( test_x );
m_free( buffer ); m_free( buffer );
m_free( cast5_ctx ); cipher_close( cipher_hd );
m_free( blowfish_ctx );
/* now let's see wether we have used the right passphrase */ /* now let's see wether we have used the right passphrase */
if( csum != cert->csum ) { if( csum != cert->csum ) {
mpi_free(test_x); mpi_free(test_x);
@ -253,10 +205,7 @@ check_dsa( PKT_secret_cert *cert )
} }
} }
else { /* not protected */ else { /* not protected */
buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL ); csum = checksum_mpi( cert->d.dsa.x );
csum = checksum_u16( nbytes*8 );
csum += checksum( buffer, nbytes );
m_free( buffer );
if( csum != cert->csum ) if( csum != cert->csum )
return G10ERR_CHECKSUM; return G10ERR_CHECKSUM;
} }
@ -267,6 +216,9 @@ check_dsa( PKT_secret_cert *cert )
#ifdef HAVE_RSA_CIPHER #ifdef HAVE_RSA_CIPHER
/****************
* FIXME: fix checksum stuff
*/
static int static int
check_rsa( PKT_secret_cert *cert ) check_rsa( PKT_secret_cert *cert )
{ {
@ -398,23 +350,29 @@ is_secret_key_protected( PKT_secret_cert *cert )
static int static int
do_protect( void (*fnc)(void *, byte *, byte *, unsigned), do_protect( void (*fnc)(CIPHER_HANDLE, byte *, byte *, unsigned),
void *fncctx, PKT_secret_cert *cert ) CIPHER_HANDLE fnc_hd, PKT_secret_cert *cert )
{ {
byte *buffer; byte *buffer;
unsigned nbytes; unsigned nbytes;
switch( cert->pubkey_algo ) { switch( cert->pubkey_algo ) {
case PUBKEY_ALGO_ELGAMAL: case PUBKEY_ALGO_ELGAMAL:
/* recalculate the checksum, so that --change-passphrase
* can be used to convert from the faulty to the correct one
* wk 06.04.98:
* fixme: remove this some time in the future.
*/
cert->csum = checksum_mpi( cert->d.elg.x );
buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL ); buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL );
(*fnc)( fncctx, buffer, buffer, nbytes ); (*fnc)( fnc_hd, buffer, buffer, nbytes );
mpi_set_buffer( cert->d.elg.x, buffer, nbytes, 0 ); mpi_set_buffer( cert->d.elg.x, buffer, nbytes, 0 );
m_free( buffer ); m_free( buffer );
break; break;
case PUBKEY_ALGO_DSA: case PUBKEY_ALGO_DSA:
buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL ); buffer = mpi_get_buffer( cert->d.dsa.x, &nbytes, NULL );
(*fnc)( fncctx, buffer, buffer, nbytes ); (*fnc)( fnc_hd, buffer, buffer, nbytes );
mpi_set_buffer( cert->d.dsa.x, buffer, nbytes, 0 ); mpi_set_buffer( cert->d.dsa.x, buffer, nbytes, 0 );
m_free( buffer ); m_free( buffer );
break; break;
@ -437,33 +395,20 @@ protect_secret_key( PKT_secret_cert *cert, DEK *dek )
return 0; return 0;
if( !cert->is_protected ) { /* okay, apply the protection */ if( !cert->is_protected ) { /* okay, apply the protection */
BLOWFISH_context *blowfish_ctx=NULL; CIPHER_HANDLE cipher_hd=NULL;
CAST5_context *cast5_ctx=NULL;
switch( cert->protect.algo ) { switch( cert->protect.algo ) {
case CIPHER_ALGO_NONE: BUG(); break; case CIPHER_ALGO_NONE: BUG(); break;
case CIPHER_ALGO_BLOWFISH: case CIPHER_ALGO_BLOWFISH:
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
blowfish_setiv( blowfish_ctx, NULL );
blowfish_encode_cfb( blowfish_ctx, cert->protect.iv,
cert->protect.iv, 8 );
if( !do_protect( (void (*)(void*,byte*,byte*,unsigned))
&blowfish_encode_cfb, blowfish_ctx, cert ) )
cert->is_protected = 1;
m_free( blowfish_ctx );
break;
case CIPHER_ALGO_CAST: case CIPHER_ALGO_CAST:
cast5_ctx = m_alloc_secure( sizeof *cast5_ctx ); cipher_hd = cipher_open( cert->protect.algo,
cast5_setkey( cast5_ctx, dek->key, dek->keylen ); CIPHER_MODE_AUTO_CFB, 1 );
cast5_setiv( cast5_ctx, NULL ); cipher_setkey( cipher_hd, dek->key, dek->keylen );
cast5_encode_cfb( cast5_ctx, cert->protect.iv, cipher_setiv( cipher_hd, NULL );
cert->protect.iv, 8 ); cipher_encrypt( cipher_hd, cert->protect.iv, cert->protect.iv, 8 );
if( !do_protect( (void (*)(void*,byte*,byte*,unsigned)) if( !do_protect( &cipher_encrypt, cipher_hd, cert ) )
&cast5_encode_cfb, cast5_ctx, cert ) )
cert->is_protected = 1; cert->is_protected = 1;
m_free( cast5_ctx ); cipher_close( cipher_hd );
break; break;
default: default:

View File

@ -78,6 +78,9 @@ encode_session_key( DEK *dek, unsigned nbits )
* *
* 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
* *
* (But how can we store the leading 0 - the external representaion
* of MPIs don't allow leading zeroes =:-)
*
* RND are non-zero random bytes. * RND are non-zero random bytes.
* A is the cipher algorithm * A is the cipher algorithm
* DEK is the encryption key (session key) length k depends on the * DEK is the encryption key (session key) length k depends on the

View File

@ -32,8 +32,6 @@
#ifdef HAVE_RSA_CIPHER #ifdef HAVE_RSA_CIPHER
#include "../cipher/rsa.h" #include "../cipher/rsa.h"
#endif #endif
#include "../cipher/blowfish.h"
#include "../cipher/cast5.h"
#include "../cipher/elgamal.h" #include "../cipher/elgamal.h"
#include "../cipher/dsa.h" #include "../cipher/dsa.h"
#include "../cipher/random.h" #include "../cipher/random.h"
@ -66,22 +64,41 @@ typedef struct {
byte key[20]; /* this is the largest used keylen */ byte key[20]; /* this is the largest used keylen */
} DEK; } DEK;
typedef struct cipher_handle_s *CIPHER_HANDLE;
#ifndef DEFINES_CIPHER_HANDLE
struct cipher_handle_s { char does_not_matter[1]; };
#endif
#define CIPHER_MODE_ECB 1
#define CIPHER_MODE_CFB 2
#define CIPHER_MODE_PHILS_CFB 3
#define CIPHER_MODE_AUTO_CFB 4
int cipher_debug_mode; int cipher_debug_mode;
/*-- cipher.c --*/
int string_to_cipher_algo( const char *string );
const char * cipher_algo_to_string( int algo );
int check_cipher_algo( int algo );
CIPHER_HANDLE cipher_open( int algo, int mode, int secure );
void cipher_close( CIPHER_HANDLE c );
void cipher_setkey( CIPHER_HANDLE c, byte *key, unsigned keylen );
void cipher_setiv( CIPHER_HANDLE c, const byte *iv );
void cipher_encrypt( CIPHER_HANDLE c, byte *out, byte *in, unsigned nbytes );
void cipher_decrypt( CIPHER_HANDLE c, byte *out, byte *in, unsigned nbytes );
void cipher_sync( CIPHER_HANDLE c );
/*-- misc.c --*/ /*-- misc.c --*/
int string_to_cipher_algo( const char *string );
int string_to_pubkey_algo( const char *string ); int string_to_pubkey_algo( const char *string );
int string_to_digest_algo( const char *string ); int string_to_digest_algo( const char *string );
const char * cipher_algo_to_string( int algo );
const char * pubkey_algo_to_string( int algo ); const char * pubkey_algo_to_string( int algo );
const char * digest_algo_to_string( int algo ); const char * digest_algo_to_string( int algo );
int check_cipher_algo( int algo );
int check_pubkey_algo( int algo ); int check_pubkey_algo( int algo );
int check_digest_algo( int algo ); int check_digest_algo( int algo );
/*-- smallprime.c --*/ /*-- smallprime.c --*/
extern ushort small_prime_numbers[]; extern ushort small_prime_numbers[];

View 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) Tue Mar 10 13:40:34 1998 Werner Koch (wk@isil.d.shuttle.de)
* mpi-bit.c (mpi_clear_highbit): New. * mpi-bit.c (mpi_clear_highbit): New.

View File

@ -54,8 +54,6 @@ mpi_write( IOBUF out, MPI a )
iobuf_put(out, (nbits) ); iobuf_put(out, (nbits) );
p = buf = mpi_get_buffer( a, &n, NULL ); p = buf = mpi_get_buffer( a, &n, NULL );
for( ; !*p && n; p++, n-- )
;
rc = iobuf_write( out, p, n ); rc = iobuf_write( out, p, n );
m_free(buf); m_free(buf);
return rc; return rc;
@ -302,6 +300,13 @@ mpi_get_buffer( MPI a, unsigned *nbytes, int *sign )
#error please implement for this limb size. #error please implement for this limb size.
#endif #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; return buffer;
} }

View File

@ -0,0 +1,5 @@
Tue Apr 7 19:50:41 1998 Werner Koch (wk@isil.d.shuttle.de)
* bftest.c: Now supports all availabe ciphers.

View File

@ -4,20 +4,17 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
needed_libs = ../cipher/libcipher.a ../util/libutil.a \ needed_libs = ../cipher/libcipher.a ../util/libutil.a \
../mpi/libmpi.a ../util/libutil.a ../mpi/libmpi.a ../util/libutil.a
noinst_PROGRAMS = mpicalc bftest cast5test clean-sat noinst_PROGRAMS = mpicalc bftest clean-sat
mpicalc_SOURCES = mpicalc.c mpicalc_SOURCES = mpicalc.c
bftest_SOURCES = bftest.c bftest_SOURCES = bftest.c
cast5test_SOURCES = cast5test.c
clean_sat_SOURCES = clean-sat.c clean_sat_SOURCES = clean-sat.c
mpicalc_LDADD = @INTLLIBS@ $(needed_libs) mpicalc_LDADD = @INTLLIBS@ $(needed_libs)
bftest_LDADD = @INTLLIBS@ $(needed_libs) bftest_LDADD = @INTLLIBS@ $(needed_libs)
cast5test_LDADD = @INTLLIBS@ $(needed_libs)
mpicalc bftest cast5test: $(needed_libs) mpicalc bftest: $(needed_libs)

View File

@ -96,19 +96,16 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
needed_libs = ../cipher/libcipher.a ../util/libutil.a \ needed_libs = ../cipher/libcipher.a ../util/libutil.a \
../mpi/libmpi.a ../util/libutil.a ../mpi/libmpi.a ../util/libutil.a
noinst_PROGRAMS = mpicalc bftest cast5test clean-sat noinst_PROGRAMS = mpicalc bftest clean-sat
mpicalc_SOURCES = mpicalc.c mpicalc_SOURCES = mpicalc.c
bftest_SOURCES = bftest.c bftest_SOURCES = bftest.c
cast5test_SOURCES = cast5test.c
clean_sat_SOURCES = clean-sat.c clean_sat_SOURCES = clean-sat.c
mpicalc_LDADD = @INTLLIBS@ $(needed_libs) mpicalc_LDADD = @INTLLIBS@ $(needed_libs)
bftest_LDADD = @INTLLIBS@ $(needed_libs) bftest_LDADD = @INTLLIBS@ $(needed_libs)
cast5test_LDADD = @INTLLIBS@ $(needed_libs)
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
CONFIG_HEADER = ../config.h CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES = CONFIG_CLEAN_FILES =
@ -127,10 +124,6 @@ bftest_OBJECTS = bftest.o
bftest_DEPENDENCIES = ../cipher/libcipher.a ../util/libutil.a \ bftest_DEPENDENCIES = ../cipher/libcipher.a ../util/libutil.a \
../mpi/libmpi.a ../util/libutil.a ../mpi/libmpi.a ../util/libutil.a
bftest_LDFLAGS = bftest_LDFLAGS =
cast5test_OBJECTS = cast5test.o
cast5test_DEPENDENCIES = ../cipher/libcipher.a ../util/libutil.a \
../mpi/libmpi.a ../util/libutil.a
cast5test_LDFLAGS =
clean_sat_OBJECTS = clean-sat.o clean_sat_OBJECTS = clean-sat.o
clean_sat_LDADD = $(LDADD) clean_sat_LDADD = $(LDADD)
clean_sat_DEPENDENCIES = clean_sat_DEPENDENCIES =
@ -145,10 +138,9 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar TAR = tar
GZIP = --best GZIP = --best
DEP_FILES = .deps/bftest.P .deps/cast5test.P .deps/clean-sat.P \ DEP_FILES = .deps/bftest.P .deps/clean-sat.P .deps/mpicalc.P
.deps/mpicalc.P SOURCES = $(mpicalc_SOURCES) $(bftest_SOURCES) $(clean_sat_SOURCES)
SOURCES = $(mpicalc_SOURCES) $(bftest_SOURCES) $(cast5test_SOURCES) $(clean_sat_SOURCES) OBJECTS = $(mpicalc_OBJECTS) $(bftest_OBJECTS) $(clean_sat_OBJECTS)
OBJECTS = $(mpicalc_OBJECTS) $(bftest_OBJECTS) $(cast5test_OBJECTS) $(clean_sat_OBJECTS)
default: all default: all
@ -195,10 +187,6 @@ bftest: $(bftest_OBJECTS) $(bftest_DEPENDENCIES)
@rm -f bftest @rm -f bftest
$(LINK) $(bftest_LDFLAGS) $(bftest_OBJECTS) $(bftest_LDADD) $(LIBS) $(LINK) $(bftest_LDFLAGS) $(bftest_OBJECTS) $(bftest_LDADD) $(LIBS)
cast5test: $(cast5test_OBJECTS) $(cast5test_DEPENDENCIES)
@rm -f cast5test
$(LINK) $(cast5test_LDFLAGS) $(cast5test_OBJECTS) $(cast5test_LDADD) $(LIBS)
clean-sat: $(clean_sat_OBJECTS) $(clean_sat_DEPENDENCIES) clean-sat: $(clean_sat_OBJECTS) $(clean_sat_DEPENDENCIES)
@rm -f clean-sat @rm -f clean-sat
$(LINK) $(clean_sat_LDFLAGS) $(clean_sat_OBJECTS) $(clean_sat_LDADD) $(LIBS) $(LINK) $(clean_sat_LDFLAGS) $(clean_sat_OBJECTS) $(clean_sat_LDADD) $(LIBS)
@ -333,7 +321,7 @@ installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean maintainer-clean-generic clean mostlyclean distclean maintainer-clean
mpicalc bftest cast5test: $(needed_libs) mpicalc bftest: $(needed_libs)
# Tell versions [3.59,3.63) of GNU make to not export all variables. # Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded. # Otherwise a system limit (for SysV at least) may be exceeded.

View File

@ -34,7 +34,7 @@
static void static void
my_usage(void) my_usage(void)
{ {
fprintf(stderr, "usage: bftest [-e][-d] key\n"); fprintf(stderr, "usage: bftest [-e][-d] algo key\n");
exit(1); exit(1);
} }
@ -62,10 +62,10 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
int encode=0; int encode=0;
BLOWFISH_context ctx; CIPHER_HANDLE hd;
char buf[100]; char buf[100];
char iv[BLOWFISH_BLOCKSIZE];
int n, size=8; int n, size=8;
int algo;
#ifdef __MINGW32__ #ifdef __MINGW32__
setmode( fileno(stdin), O_BINARY ); setmode( fileno(stdin), O_BINARY );
@ -89,22 +89,24 @@ main(int argc, char **argv)
argc--; argv++; argc--; argv++;
size = 10; size = 10;
} }
if( argc != 2 ) if( argc != 3 )
my_usage(); my_usage();
argc--; argv++; argc--; argv++;
algo = string_to_cipher_algo( *argv );
argc--; argv++;
blowfish_setkey( &ctx, *argv, strlen(*argv) ); hd = cipher_open( algo, CIPHER_MODE_CFB, 0 );
memset(iv,0, BLOWFISH_BLOCKSIZE); cipher_setkey( hd, *argv, strlen(*argv) );
blowfish_setiv( &ctx, iv ); cipher_setiv( hd, NULL );
while( (n = fread( buf, 1, size, stdin )) > 0 ) { while( (n = fread( buf, 1, size, stdin )) > 0 ) {
if( encode ) if( encode )
blowfish_encode_cfb( &ctx, buf, buf, n ); cipher_encrypt( hd, buf, buf, n );
else else
blowfish_decode_cfb( &ctx, buf, buf, n ); cipher_decrypt( hd, buf, buf, n );
if( fwrite( buf, 1, n, stdout) != n ) if( fwrite( buf, 1, n, stdout) != n )
log_fatal("write error\n"); log_fatal("write error\n");
} }
cipher_close(hd);
return 0; return 0;
} }

View File

@ -1,108 +0,0 @@
/* cast5test.c - CAST5 test program
* 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __MINGW32__
#include <io.h>
#include <fcntl.h>
#endif
#include "util.h"
#include "cipher.h"
#include "i18n.h"
static void
my_usage(void)
{
fprintf(stderr, "usage: cast5test [-e][-d] key\n");
exit(1);
}
const char *
strusage( int level )
{
return default_strusage(level);
}
static void
i18n_init(void)
{
#ifdef ENABLE_NLS
#ifdef HAVE_LC_MESSAGES
setlocale( LC_MESSAGES, "" );
#else
setlocale( LC_ALL, "" );
#endif
bindtextdomain( PACKAGE, G10_LOCALEDIR );
textdomain( PACKAGE );
#endif
}
int
main(int argc, char **argv)
{
int encode=0;
CAST5_context ctx;
char buf[100];
int n, size=100;
#ifdef __MINGW32__
setmode( fileno(stdin), O_BINARY );
setmode( fileno(stdout), O_BINARY );
#endif
i18n_init();
if( argc > 1 && !strcmp(argv[1], "-e") ) {
encode++;
argc--; argv++;
}
else if( argc > 1 && !strcmp(argv[1], "-E") ) {
encode++;
argc--; argv++;
size = 10;
}
else if( argc > 1 && !strcmp(argv[1], "-d") ) {
argc--; argv++;
}
else if( argc > 1 && !strcmp(argv[1], "-D") ) {
argc--; argv++;
size = 10;
}
if( argc != 2 )
my_usage();
argc--; argv++;
cast5_setkey( &ctx, *argv, strlen(*argv) );
cast5_setiv( &ctx, NULL );
while( (n = fread( buf, 1, size, stdin )) > 0 ) {
if( encode )
cast5_encode_cfb( &ctx, buf, buf, n );
else
cast5_decode_cfb( &ctx, buf, buf, n );
if( fwrite( buf, 1, n, stdout) != n )
log_fatal("write error\n");
}
return 0;
}