mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
cipher reorganisiert
This commit is contained in:
parent
53a578711f
commit
86f261dbc5
36 changed files with 760 additions and 939 deletions
|
@ -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.
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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*/
|
||||
|
|
217
cipher/cast5.c
217
cipher/cast5.c
|
@ -43,7 +43,6 @@
|
|||
#include "util.h"
|
||||
#include "types.h"
|
||||
#include "cast5.h"
|
||||
#include "random.h"
|
||||
|
||||
static const u32 s1[256] = {
|
||||
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
|
||||
|
@ -339,8 +338,8 @@ rol(int n, u32 x)
|
|||
#define F3(D,m,r) ( (I = ((m) - (D))), (I=rol((r),I)), \
|
||||
(((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
|
||||
|
||||
static void
|
||||
encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
|
||||
void
|
||||
cast5_encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
|
||||
{
|
||||
u32 l, r, t;
|
||||
u32 I; /* used by the Fx macros */
|
||||
|
@ -393,8 +392,8 @@ encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
|
|||
outbuf[7] = l & 0xff;
|
||||
}
|
||||
|
||||
static void
|
||||
decrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
|
||||
void
|
||||
cast5_decrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
|
||||
{
|
||||
u32 l, r, t;
|
||||
u32 I;
|
||||
|
@ -447,10 +446,10 @@ selftest()
|
|||
byte buffer[8];
|
||||
|
||||
cast5_setkey( &c, key, 16 );
|
||||
encrypt_block( &c, buffer, plain );
|
||||
cast5_encrypt_block( &c, buffer, plain );
|
||||
if( memcmp( buffer, cipher, 8 ) )
|
||||
log_error("wrong cast5-128 encryption\n");
|
||||
decrypt_block( &c, buffer, buffer );
|
||||
cast5_decrypt_block( &c, buffer, buffer );
|
||||
if( memcmp( buffer, plain, 8 ) )
|
||||
log_bug("cast5-128 failed\n");
|
||||
|
||||
|
@ -468,11 +467,11 @@ selftest()
|
|||
|
||||
for(i=0; i < 1000000; i++ ) {
|
||||
cast5_setkey( &c, b0, 16 );
|
||||
encrypt_block( &c, a0, a0 );
|
||||
encrypt_block( &c, a0+8, a0+8 );
|
||||
cast5_encrypt_block( &c, a0, a0 );
|
||||
cast5_encrypt_block( &c, a0+8, a0+8 );
|
||||
cast5_setkey( &c, a0, 16 );
|
||||
encrypt_block( &c, b0, b0 );
|
||||
encrypt_block( &c, b0+8, b0+8 );
|
||||
cast5_encrypt_block( &c, b0, b0 );
|
||||
cast5_encrypt_block( &c, b0+8, b0+8 );
|
||||
}
|
||||
if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) )
|
||||
log_bug("cast5-128 maintenance test failed\n");
|
||||
|
@ -543,7 +542,6 @@ cast5_setkey( CAST5_context *c, byte *key, unsigned keylen )
|
|||
initialized = 1;
|
||||
selftest();
|
||||
}
|
||||
fast_random_poll();
|
||||
|
||||
assert(keylen==16);
|
||||
x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3];
|
||||
|
@ -567,198 +565,3 @@ cast5_setkey( CAST5_context *c, byte *key, unsigned keylen )
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
cast5_setiv( CAST5_context *c, byte *iv )
|
||||
{
|
||||
if( iv )
|
||||
memcpy( c->iv, iv, CAST5_BLOCKSIZE );
|
||||
else
|
||||
memset( c->iv, 0, CAST5_BLOCKSIZE );
|
||||
c->count = 0;
|
||||
encrypt_block( c, c->eniv, c->iv );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cast5_encode( CAST5_context *c, byte *outbuf, byte *inbuf,
|
||||
unsigned nblocks )
|
||||
{
|
||||
unsigned n;
|
||||
|
||||
for(n=0; n < nblocks; n++ ) {
|
||||
encrypt_block( c, outbuf, inbuf );
|
||||
inbuf += CAST5_BLOCKSIZE;;
|
||||
outbuf += CAST5_BLOCKSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cast5_decode( CAST5_context *c, byte *outbuf, byte *inbuf,
|
||||
unsigned nblocks )
|
||||
{
|
||||
unsigned n;
|
||||
|
||||
for(n=0; n < nblocks; n++ ) {
|
||||
decrypt_block( c, outbuf, inbuf );
|
||||
inbuf += CAST5_BLOCKSIZE;;
|
||||
outbuf += CAST5_BLOCKSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* FIXME: Make use of bigger chunks
|
||||
* (out may overlap with a or b)
|
||||
*/
|
||||
static void
|
||||
xorblock( byte *out, byte *a, byte *b, unsigned count )
|
||||
{
|
||||
for( ; count ; count--, a++, b++ )
|
||||
*out++ = *a ^ *b ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Encode buffer in CFB mode. nbytes can be an arbitrary value.
|
||||
*/
|
||||
void
|
||||
cast5_encode_cfb( CAST5_context *c, byte *outbuf,
|
||||
byte *inbuf, unsigned nbytes)
|
||||
{
|
||||
unsigned n;
|
||||
int is_aligned;
|
||||
|
||||
if( c->count ) { /* must make a full block first */
|
||||
assert( c->count < CAST5_BLOCKSIZE );
|
||||
n = CAST5_BLOCKSIZE - c->count;
|
||||
if( n > nbytes )
|
||||
n = nbytes;
|
||||
xorblock( outbuf, c->eniv+c->count, inbuf, n);
|
||||
memcpy( c->iv+c->count, outbuf, n);
|
||||
c->count += n;
|
||||
nbytes -= n;
|
||||
inbuf += n;
|
||||
outbuf += n;
|
||||
assert( c->count <= CAST5_BLOCKSIZE);
|
||||
if( c->count == CAST5_BLOCKSIZE ) {
|
||||
encrypt_block( c, c->eniv, c->iv );
|
||||
c->count = 0;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
assert(!c->count);
|
||||
is_aligned = !((ulong)inbuf % SIZEOF_UNSIGNED_LONG);
|
||||
while( nbytes >= CAST5_BLOCKSIZE ) {
|
||||
if( is_aligned ) {
|
||||
#if SIZEOF_UNSIGNED_LONG == CAST5_BLOCKSIZE
|
||||
*(ulong*)outbuf = *(ulong*)c->eniv ^ *(ulong*)inbuf;
|
||||
#elif (2*SIZEOF_UNSIGNED_LONG) == CAST5_BLOCKSIZE
|
||||
((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0];
|
||||
((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1];
|
||||
#elif (4*SIZEOF_UNSIGNED_LONG) == CAST5_BLOCKSIZE
|
||||
((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0];
|
||||
((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1];
|
||||
((ulong*)outbuf)[2] = ((ulong*)c->eniv)[2] ^ ((ulong*)inbuf)[2];
|
||||
((ulong*)outbuf)[3] = ((ulong*)c->eniv)[3] ^ ((ulong*)inbuf)[3];
|
||||
#else
|
||||
#error Please remove this info line.
|
||||
xorblock( outbuf, c->eniv, inbuf, CAST5_BLOCKSIZE);
|
||||
#endif
|
||||
}
|
||||
else /* not aligned */
|
||||
xorblock( outbuf, c->eniv, inbuf, CAST5_BLOCKSIZE);
|
||||
memcpy( c->iv, outbuf, CAST5_BLOCKSIZE);
|
||||
encrypt_block( c, c->eniv, c->iv );
|
||||
nbytes -= CAST5_BLOCKSIZE;
|
||||
inbuf += CAST5_BLOCKSIZE;
|
||||
outbuf += CAST5_BLOCKSIZE;
|
||||
}
|
||||
|
||||
if( nbytes ) {
|
||||
xorblock( outbuf, c->eniv, inbuf, nbytes );
|
||||
memcpy( c->iv, outbuf, nbytes );
|
||||
c->count = nbytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cast5_decode_cfb( CAST5_context *c, byte *outbuf,
|
||||
byte *inbuf, unsigned nbytes)
|
||||
{
|
||||
unsigned n;
|
||||
int is_aligned;
|
||||
|
||||
if( c->count ) { /* must make a full block first */
|
||||
assert( c->count < CAST5_BLOCKSIZE );
|
||||
n = CAST5_BLOCKSIZE - c->count;
|
||||
if( n > nbytes )
|
||||
n = nbytes;
|
||||
memcpy( c->iv+c->count, inbuf, n);
|
||||
xorblock( outbuf, c->eniv+c->count, inbuf, n);
|
||||
c->count += n;
|
||||
nbytes -= n;
|
||||
inbuf += n;
|
||||
outbuf += n;
|
||||
assert( c->count <= CAST5_BLOCKSIZE);
|
||||
if( c->count == CAST5_BLOCKSIZE ) {
|
||||
encrypt_block( c, c->eniv, c->iv );
|
||||
c->count = 0;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!c->count);
|
||||
is_aligned = !((ulong)inbuf % SIZEOF_UNSIGNED_LONG);
|
||||
while( nbytes >= CAST5_BLOCKSIZE ) {
|
||||
memcpy( c->iv, inbuf, CAST5_BLOCKSIZE);
|
||||
if( is_aligned ) {
|
||||
#if SIZEOF_UNSIGNED_LONG == CAST5_BLOCKSIZE
|
||||
*(ulong*)outbuf = *(ulong*)c->eniv ^ *(ulong*)inbuf;
|
||||
#elif (2*SIZEOF_UNSIGNED_LONG) == CAST5_BLOCKSIZE
|
||||
((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0];
|
||||
((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1];
|
||||
#elif (4*SIZEOF_UNSIGNED_LONG) == CAST5_BLOCKSIZE
|
||||
((ulong*)outbuf)[0] = ((ulong*)c->eniv)[0] ^ ((ulong*)inbuf)[0];
|
||||
((ulong*)outbuf)[1] = ((ulong*)c->eniv)[1] ^ ((ulong*)inbuf)[1];
|
||||
((ulong*)outbuf)[2] = ((ulong*)c->eniv)[2] ^ ((ulong*)inbuf)[2];
|
||||
((ulong*)outbuf)[3] = ((ulong*)c->eniv)[3] ^ ((ulong*)inbuf)[3];
|
||||
#else
|
||||
#error Please remove this info line.
|
||||
xorblock( outbuf, c->eniv, inbuf, CAST5_BLOCKSIZE);
|
||||
#endif
|
||||
}
|
||||
else /* not aligned */
|
||||
xorblock( outbuf, c->eniv, inbuf, CAST5_BLOCKSIZE);
|
||||
encrypt_block( c, c->eniv, c->iv );
|
||||
nbytes -= CAST5_BLOCKSIZE;
|
||||
inbuf += CAST5_BLOCKSIZE;
|
||||
outbuf += CAST5_BLOCKSIZE;
|
||||
}
|
||||
|
||||
if( nbytes ) {
|
||||
memcpy( c->iv, inbuf, nbytes );
|
||||
xorblock( outbuf, c->eniv, inbuf, nbytes );
|
||||
c->count = nbytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
cast5_sync_cfb( CAST5_context *c )
|
||||
{
|
||||
if( c->count ) {
|
||||
memmove(c->iv + c->count, c->iv, CAST5_BLOCKSIZE - c->count );
|
||||
memcpy(c->iv, c->eniv + CAST5_BLOCKSIZE - c->count, c->count);
|
||||
c->count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,22 +27,11 @@
|
|||
typedef struct {
|
||||
u32 Km[16];
|
||||
byte Kr[16];
|
||||
byte iv[CAST5_BLOCKSIZE];
|
||||
byte eniv[CAST5_BLOCKSIZE];
|
||||
int count;
|
||||
} CAST5_context;
|
||||
|
||||
void cast5_setkey( CAST5_context *c, byte *key, unsigned keylen );
|
||||
void cast5_setiv( CAST5_context *c, byte *iv );
|
||||
void cast5_encode( CAST5_context *c, byte *outbuf, byte *inbuf,
|
||||
unsigned nblocks );
|
||||
void cast5_decode( CAST5_context *c, byte *outbuf, byte *inbuf,
|
||||
unsigned nblocks );
|
||||
void cast5_encode_cfb( CAST5_context *c, byte *outbuf,
|
||||
byte *inbuf, unsigned nbytes);
|
||||
void cast5_decode_cfb( CAST5_context *c, byte *outbuf,
|
||||
byte *inbuf, unsigned nbytes);
|
||||
void cast5_sync_cfb( CAST5_context *c );
|
||||
void cast5_encrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf );
|
||||
void cast5_decrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf );
|
||||
|
||||
|
||||
#endif /*G10_CAST5_H*/
|
||||
|
|
425
cipher/cipher.c
Normal file
425
cipher/cipher.c
Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -27,17 +27,6 @@
|
|||
#include "cipher.h"
|
||||
|
||||
|
||||
static struct { const char *name; int algo;} cipher_names[] = {
|
||||
{ "IDEA", CIPHER_ALGO_IDEA },
|
||||
{ "3DES", CIPHER_ALGO_3DES },
|
||||
{ "CAST", CIPHER_ALGO_CAST },
|
||||
{ "BLOWFISH128", CIPHER_ALGO_BLOWFISH128 },
|
||||
{ "ROT_N", CIPHER_ALGO_ROT_N },
|
||||
{ "SAFER_SK128", CIPHER_ALGO_SAFER_SK128 },
|
||||
{ "DES_SK", CIPHER_ALGO_DES_SK },
|
||||
{ "BLOWFISH", CIPHER_ALGO_BLOWFISH },
|
||||
{NULL} };
|
||||
|
||||
static struct { const char *name; int algo;} pubkey_names[] = {
|
||||
{ "RSA", PUBKEY_ALGO_RSA },
|
||||
{ "RSA-E", PUBKEY_ALGO_RSA_E },
|
||||
|
@ -57,35 +46,7 @@ static struct { const char *name; int algo;} digest_names[] = {
|
|||
{NULL} };
|
||||
|
||||
|
||||
/****************
|
||||
* Map a string to the cipher algo
|
||||
*/
|
||||
int
|
||||
string_to_cipher_algo( const char *string )
|
||||
{
|
||||
int i;
|
||||
const char *s;
|
||||
|
||||
for(i=0; (s=cipher_names[i].name); i++ )
|
||||
if( !stricmp( s, string ) )
|
||||
return cipher_names[i].algo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Map a cipher algo to a string
|
||||
*/
|
||||
const char *
|
||||
cipher_algo_to_string( int algo )
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; cipher_names[i].name; i++ )
|
||||
if( cipher_names[i].algo == algo )
|
||||
return cipher_names[i].name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
|
@ -153,21 +114,6 @@ digest_algo_to_string( int algo )
|
|||
|
||||
|
||||
|
||||
/****************
|
||||
* Return 0 if the cipher algo is available
|
||||
*/
|
||||
int
|
||||
check_cipher_algo( int algo )
|
||||
{
|
||||
switch( algo ) {
|
||||
case CIPHER_ALGO_BLOWFISH128:
|
||||
case CIPHER_ALGO_BLOWFISH:
|
||||
case CIPHER_ALGO_CAST:
|
||||
return 0;
|
||||
default:
|
||||
return G10ERR_CIPHER_ALGO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue