From 8cd8a7b7a2cb2b69cd1ede5c525e3dbbee138a0c Mon Sep 17 00:00:00 2001 From: Ulf Möller Date: Tue, 27 Apr 1999 21:17:18 +0000 Subject: More portable blowfish macros. Submitted by: Andy Polyakov --- crypto/bf/bf_enc.c | 72 ++++++++++++++++++++++++++++++++++++++++++ crypto/bf/bf_locl.h | 89 ++++++++++++++++++++++++++++++---------------------- crypto/bf/blowfish.h | 19 ++++++++++- 3 files changed, 141 insertions(+), 39 deletions(-) (limited to 'crypto/bf') diff --git a/crypto/bf/bf_enc.c b/crypto/bf/bf_enc.c index f8a95e2142..ee01834561 100644 --- a/crypto/bf/bf_enc.c +++ b/crypto/bf/bf_enc.c @@ -71,6 +71,7 @@ to modify the code. void BF_encrypt(BF_LONG *data, BF_KEY *key) { +#ifndef BF_PTR2 register BF_LONG l,r,*p,*s; p=key->P; @@ -105,12 +106,48 @@ void BF_encrypt(BF_LONG *data, BF_KEY *key) data[1]=l&0xffffffffL; data[0]=r&0xffffffffL; +#else + register BF_LONG l,r,t,*k; + + l=data[0]; + r=data[1]; + k=(BF_LONG*)key; + + l^=k[0]; + BF_ENC(r,l,k, 1); + BF_ENC(l,r,k, 2); + BF_ENC(r,l,k, 3); + BF_ENC(l,r,k, 4); + BF_ENC(r,l,k, 5); + BF_ENC(l,r,k, 6); + BF_ENC(r,l,k, 7); + BF_ENC(l,r,k, 8); + BF_ENC(r,l,k, 9); + BF_ENC(l,r,k,10); + BF_ENC(r,l,k,11); + BF_ENC(l,r,k,12); + BF_ENC(r,l,k,13); + BF_ENC(l,r,k,14); + BF_ENC(r,l,k,15); + BF_ENC(l,r,k,16); +#if BF_ROUNDS == 20 + BF_ENC(r,l,k,17); + BF_ENC(l,r,k,18); + BF_ENC(r,l,k,19); + BF_ENC(l,r,k,20); +#endif + r^=k[BF_ROUNDS+1]; + + data[1]=l&0xffffffffL; + data[0]=r&0xffffffffL; +#endif } #ifndef BF_DEFAULT_OPTIONS void BF_decrypt(BF_LONG *data, BF_KEY *key) { +#ifndef BF_PTR2 register BF_LONG l,r,*p,*s; p=key->P; @@ -145,6 +182,41 @@ void BF_decrypt(BF_LONG *data, BF_KEY *key) data[1]=l&0xffffffffL; data[0]=r&0xffffffffL; +#else + register BF_LONG l,r,t,*k; + + l=data[0]; + r=data[1]; + k=(BF_LONG *)key; + + l^=k[BF_ROUNDS+1]; +#if BF_ROUNDS == 20 + BF_ENC(r,l,k,20); + BF_ENC(l,r,k,19); + BF_ENC(r,l,k,18); + BF_ENC(l,r,k,17); +#endif + BF_ENC(r,l,k,16); + BF_ENC(l,r,k,15); + BF_ENC(r,l,k,14); + BF_ENC(l,r,k,13); + BF_ENC(r,l,k,12); + BF_ENC(l,r,k,11); + BF_ENC(r,l,k,10); + BF_ENC(l,r,k, 9); + BF_ENC(r,l,k, 8); + BF_ENC(l,r,k, 7); + BF_ENC(r,l,k, 6); + BF_ENC(l,r,k, 5); + BF_ENC(r,l,k, 4); + BF_ENC(l,r,k, 3); + BF_ENC(r,l,k, 2); + BF_ENC(l,r,k, 1); + r^=k[0]; + + data[1]=l&0xffffffffL; + data[0]=r&0xffffffffL; +#endif } void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length, diff --git a/crypto/bf/bf_locl.h b/crypto/bf/bf_locl.h index 7936e6c56a..3ebb145f88 100644 --- a/crypto/bf/bf_locl.h +++ b/crypto/bf/bf_locl.h @@ -151,56 +151,69 @@ /* This is actually a big endian algorithm, the most significate byte * is used to lookup array 0 */ -#define BF_M 0x3fc -#define BF_0 22L -#define BF_1 14L -#define BF_2 6L -#define BF_3 2L /* left shift */ - #if defined(BF_PTR2) -/* This is basically a special pentium verson */ -#define BF_ENC(LL,R,S,P) \ - { \ - BF_LONG t,u,v; \ - u=R>>BF_0; \ - v=R>>BF_1; \ - u&=BF_M; \ - v&=BF_M; \ - t= *(BF_LONG *)((unsigned char *)&(S[ 0])+u); \ - u=R>>BF_2; \ - t+= *(BF_LONG *)((unsigned char *)&(S[256])+v); \ - v=R<>24)&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \ + t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \ + LL^=t \ + ) #elif defined(BF_PTR) -/* This is normally very good */ +#ifndef BF_LONG_LOG2 +#define BF_LONG_LOG2 2 /* default to BF_LONG being 32 bits */ +#endif +#define BF_M (0xFF<>BF_i)&BF_M gets folded into a single instruction, namely + * rlwinm. So let'em double-check if their compiler does it. + */ -#define BF_ENC(LL,R,S,P) \ - LL^=P; \ +#define BF_ENC(LL,R,S,P) ( \ + LL^=P, \ LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \ *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \ *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \ - *(BF_LONG *)((unsigned char *)&(S[768])+((R<>24L) ] + \ - S[0x0100+((int)(R>>16L)&0xff)])^ \ - S[0x0200+((int)(R>> 8L)&0xff)])+ \ - S[0x0300+((int)(R )&0xff)])&0xffffffffL; +#define BF_ENC(LL,R,S,P) ( \ + LL^=P, \ + LL^=((( S[ ((int)(R>>24)&0xff)] + \ + S[0x0100+((int)(R>>16)&0xff)])^ \ + S[0x0200+((int)(R>> 8)&0xff)])+ \ + S[0x0300+((int)(R )&0xff)])&0xffffffffL \ + ) #endif #endif diff --git a/crypto/bf/blowfish.h b/crypto/bf/blowfish.h index a18dfee1a4..02f73b2f30 100644 --- a/crypto/bf/blowfish.h +++ b/crypto/bf/blowfish.h @@ -70,8 +70,25 @@ extern "C" { #define BF_ENCRYPT 1 #define BF_DECRYPT 0 -#ifdef WIN16 +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! BF_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#if defined(WIN16) || defined(__LP32__) #define BF_LONG unsigned long +#elif defined(_CRAY) || defined(__ILP64__) +#define BF_LONG unsigned long +#define BF_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ #else #define BF_LONG unsigned int #endif -- cgit v1.2.3