summaryrefslogtreecommitdiff
path: root/cipher/blowfish.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>1998-03-19 15:27:26 +0000
committerWerner Koch <wk@gnupg.org>1998-03-19 15:27:26 +0000
commitfa3731d01d66ad6fcd9faf1383611e55e11a3f5a (patch)
treed46eeb9ee4859e591922182ee325da7e4c95e5e7 /cipher/blowfish.c
parent198d5240d567568480862afae628a4639617815f (diff)
downloadlibgcrypt-fa3731d01d66ad6fcd9faf1383611e55e11a3f5a.tar.gz
some cleanups
Diffstat (limited to 'cipher/blowfish.c')
-rw-r--r--cipher/blowfish.c150
1 files changed, 137 insertions, 13 deletions
diff --git a/cipher/blowfish.c b/cipher/blowfish.c
index 55b99025..09b15767 100644
--- a/cipher/blowfish.c
+++ b/cipher/blowfish.c
@@ -227,8 +227,7 @@ static const u32 ps[BLOWFISH_ROUNDS+2] = {
-
-
+#if BLOWFISH_ROUNDS != 16
static inline u32
function_F( BLOWFISH_context *bc, u32 x )
{
@@ -248,48 +247,130 @@ function_F( BLOWFISH_context *bc, u32 x )
return ((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d];
}
+#endif
+
+#ifdef BIG_ENDIAN_HOST
+ #define F(x) ((( s0[((byte*)&x)[0]] + s1[((byte*)&x)[1]]) \
+ ^ s2[((byte*)&x)[2]]) + s3[((byte*)&x)[3]] )
+#else
+ #define F(x) ((( s0[((byte*)&x)[3]] + s1[((byte*)&x)[2]]) \
+ ^ s2[((byte*)&x)[1]]) + s3[((byte*)&x)[0]] )
+#endif
+#define R(l,r,i) do { l ^= p[i]; r ^= F(l); } while(0)
static void
encrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
{
- u32 xl, xr, temp;
+ #if BLOWFISH_ROUNDS == 16
+ u32 xl, xr, *s0, *s1, *s2, *s3, *p;
+
+ xl = *ret_xl;
+ xr = *ret_xr;
+ p = bc->p;
+ s0 = bc->s0;
+ s1 = bc->s1;
+ s2 = bc->s2;
+ s3 = bc->s3;
+
+ R( xl, xr, 0);
+ R( xr, xl, 1);
+ R( xl, xr, 2);
+ R( xr, xl, 3);
+ R( xl, xr, 4);
+ R( xr, xl, 5);
+ R( xl, xr, 6);
+ R( xr, xl, 7);
+ R( xl, xr, 8);
+ R( xr, xl, 9);
+ R( xl, xr, 10);
+ R( xr, xl, 11);
+ R( xl, xr, 12);
+ R( xr, xl, 13);
+ R( xl, xr, 14);
+ R( xr, xl, 15);
+
+ xl ^= p[BLOWFISH_ROUNDS];
+ xr ^= p[BLOWFISH_ROUNDS+1];
+
+ *ret_xl = xr;
+ *ret_xr = xl;
+
+ #else
+ u32 xl, xr, temp, *p;
int i;
xl = *ret_xl;
xr = *ret_xr;
+ p = bc->p;
for(i=0; i < BLOWFISH_ROUNDS; i++ ) {
- xl ^= bc->p[i];
+ xl ^= p[i];
xr ^= function_F(bc, xl);
temp = xl;
xl = xr;
xr = temp;
}
-
temp = xl;
xl = xr;
xr = temp;
- xr ^= bc->p[BLOWFISH_ROUNDS];
- xl ^= bc->p[BLOWFISH_ROUNDS+1];
+ xr ^= p[BLOWFISH_ROUNDS];
+ xl ^= p[BLOWFISH_ROUNDS+1];
*ret_xl = xl;
*ret_xr = xr;
+ #endif
}
static void
decrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
{
- u32 xl, xr, temp;
+ #if BLOWFISH_ROUNDS == 16
+ u32 xl, xr, *s0, *s1, *s2, *s3, *p;
+
+ xl = *ret_xl;
+ xr = *ret_xr;
+ p = bc->p;
+ s0 = bc->s0;
+ s1 = bc->s1;
+ s2 = bc->s2;
+ s3 = bc->s3;
+
+ R( xl, xr, 17);
+ R( xr, xl, 16);
+ R( xl, xr, 15);
+ R( xr, xl, 14);
+ R( xl, xr, 13);
+ R( xr, xl, 12);
+ R( xl, xr, 11);
+ R( xr, xl, 10);
+ R( xl, xr, 9);
+ R( xr, xl, 8);
+ R( xl, xr, 7);
+ R( xr, xl, 6);
+ R( xl, xr, 5);
+ R( xr, xl, 4);
+ R( xl, xr, 3);
+ R( xr, xl, 2);
+
+ xl ^= p[1];
+ xr ^= p[0];
+
+ *ret_xl = xr;
+ *ret_xr = xl;
+
+ #else
+ u32 xl, xr, temp, *p;
int i;
xl = *ret_xl;
xr = *ret_xr;
+ p = bc->p;
for(i=BLOWFISH_ROUNDS+1; i > 1; i-- ) {
- xl ^= bc->p[i];
+ xl ^= p[i];
xr ^= function_F(bc, xl);
temp = xl;
xl = xr;
@@ -300,13 +381,17 @@ decrypt( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
xl = xr;
xr = temp;
- xr ^= bc->p[1];
- xl ^= bc->p[0];
+ xr ^= p[1];
+ xl ^= p[0];
*ret_xl = xl;
*ret_xr = xr;
+ #endif
}
+#undef F
+#undef R
+
static void
encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
{
@@ -539,6 +624,7 @@ 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 );
@@ -560,8 +646,26 @@ blowfish_encode_cfb( BLOWFISH_context *c, byte *outbuf,
return;
}
assert(!c->count);
+ is_aligned = !((ulong)inbuf % SIZEOF_UNSIGNED_LONG);
while( nbytes >= BLOWFISH_BLOCKSIZE ) {
- xorblock( outbuf, c->eniv, 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);
memcpy( c->iv, outbuf, BLOWFISH_BLOCKSIZE);
encrypt_block( c, c->eniv, c->iv );
nbytes -= BLOWFISH_BLOCKSIZE;
@@ -583,6 +687,7 @@ 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 );
@@ -605,9 +710,27 @@ blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf,
}
assert(!c->count);
+ is_aligned = !((ulong)inbuf % SIZEOF_UNSIGNED_LONG);
while( nbytes >= BLOWFISH_BLOCKSIZE ) {
memcpy( c->iv, inbuf, BLOWFISH_BLOCKSIZE);
- xorblock( outbuf, c->eniv, 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;
@@ -622,3 +745,4 @@ blowfish_decode_cfb( BLOWFISH_context *c, byte *outbuf,
}
+