More portable blowfish macros.
Submitted by: Andy Polyakov <appro@fy.chalmers.se>
This commit is contained in:
parent
67a4728511
commit
8cd8a7b7a2
@ -71,6 +71,7 @@ to modify the code.
|
|||||||
|
|
||||||
void BF_encrypt(BF_LONG *data, BF_KEY *key)
|
void BF_encrypt(BF_LONG *data, BF_KEY *key)
|
||||||
{
|
{
|
||||||
|
#ifndef BF_PTR2
|
||||||
register BF_LONG l,r,*p,*s;
|
register BF_LONG l,r,*p,*s;
|
||||||
|
|
||||||
p=key->P;
|
p=key->P;
|
||||||
@ -105,12 +106,48 @@ void BF_encrypt(BF_LONG *data, BF_KEY *key)
|
|||||||
|
|
||||||
data[1]=l&0xffffffffL;
|
data[1]=l&0xffffffffL;
|
||||||
data[0]=r&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
|
#ifndef BF_DEFAULT_OPTIONS
|
||||||
|
|
||||||
void BF_decrypt(BF_LONG *data, BF_KEY *key)
|
void BF_decrypt(BF_LONG *data, BF_KEY *key)
|
||||||
{
|
{
|
||||||
|
#ifndef BF_PTR2
|
||||||
register BF_LONG l,r,*p,*s;
|
register BF_LONG l,r,*p,*s;
|
||||||
|
|
||||||
p=key->P;
|
p=key->P;
|
||||||
@ -145,6 +182,41 @@ void BF_decrypt(BF_LONG *data, BF_KEY *key)
|
|||||||
|
|
||||||
data[1]=l&0xffffffffL;
|
data[1]=l&0xffffffffL;
|
||||||
data[0]=r&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,
|
void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
|
||||||
|
@ -151,56 +151,69 @@
|
|||||||
/* This is actually a big endian algorithm, the most significate byte
|
/* This is actually a big endian algorithm, the most significate byte
|
||||||
* is used to lookup array 0 */
|
* 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)
|
#if defined(BF_PTR2)
|
||||||
|
|
||||||
/* This is basically a special pentium verson */
|
/*
|
||||||
#define BF_ENC(LL,R,S,P) \
|
* This is basically a special Intel version. Point is that Intel
|
||||||
{ \
|
* doesn't have many registers, but offers a reach choice of addressing
|
||||||
BF_LONG t,u,v; \
|
* modes. So we spare some registers by directly traversing BF_KEY
|
||||||
u=R>>BF_0; \
|
* structure and hiring the most decorated addressing mode. The code
|
||||||
v=R>>BF_1; \
|
* generated by EGCS is *perfectly* competitive with assembler
|
||||||
u&=BF_M; \
|
* implementation!
|
||||||
v&=BF_M; \
|
*/
|
||||||
t= *(BF_LONG *)((unsigned char *)&(S[ 0])+u); \
|
#define BF_ENC(LL,R,KEY,Pi) (\
|
||||||
u=R>>BF_2; \
|
LL^=KEY[Pi], \
|
||||||
t+= *(BF_LONG *)((unsigned char *)&(S[256])+v); \
|
t= KEY[BF_ROUNDS+2 + 0 + ((R>>24)&0xFF)], \
|
||||||
v=R<<BF_3; \
|
t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \
|
||||||
u&=BF_M; \
|
t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \
|
||||||
v&=BF_M; \
|
t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \
|
||||||
t^= *(BF_LONG *)((unsigned char *)&(S[512])+u); \
|
LL^=t \
|
||||||
LL^=P; \
|
)
|
||||||
t+= *(BF_LONG *)((unsigned char *)&(S[768])+v); \
|
|
||||||
LL^=t; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(BF_PTR)
|
#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_LONG_LOG2)
|
||||||
|
#define BF_0 (24-BF_LONG_LOG2)
|
||||||
|
#define BF_1 (16-BF_LONG_LOG2)
|
||||||
|
#define BF_2 ( 8-BF_LONG_LOG2)
|
||||||
|
#define BF_3 BF_LONG_LOG2 /* left shift */
|
||||||
|
|
||||||
#define BF_ENC(LL,R,S,P) \
|
/*
|
||||||
LL^=P; \
|
* This is normally very good on RISC platforms where normally you
|
||||||
|
* have to explicitely "multiplicate" array index by sizeof(BF_LONG)
|
||||||
|
* in order to caclulate the effective address. This implementation
|
||||||
|
* excuses CPU from this extra work. Power[PC] uses should have most
|
||||||
|
* fun as (R>>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, \
|
||||||
LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \
|
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[256])+((R>>BF_1)&BF_M)))^ \
|
||||||
*(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \
|
*(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \
|
||||||
*(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M)));
|
*(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M))) \
|
||||||
|
)
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* This will always work, even on 64 bit machines and strangly enough,
|
/*
|
||||||
* on the Alpha it is faster than the pointer versions (both 32 and 64
|
* This is a *generic* version. Seem to perform best on platforms that
|
||||||
* versions of BF_LONG) */
|
* offer explicit support for extraction of 8-bit nibbles preferably
|
||||||
|
* complemented with "multiplying" of array index by sizeof(BF_LONG).
|
||||||
|
* For the moment of this writing the list comprises Alpha CPU featuring
|
||||||
|
* extbl and s[48]addq instructions.
|
||||||
|
*/
|
||||||
|
|
||||||
#define BF_ENC(LL,R,S,P) \
|
#define BF_ENC(LL,R,S,P) ( \
|
||||||
LL^=P; \
|
LL^=P, \
|
||||||
LL^=((( S[ (int)(R>>24L) ] + \
|
LL^=((( S[ ((int)(R>>24)&0xff)] + \
|
||||||
S[0x0100+((int)(R>>16L)&0xff)])^ \
|
S[0x0100+((int)(R>>16)&0xff)])^ \
|
||||||
S[0x0200+((int)(R>> 8L)&0xff)])+ \
|
S[0x0200+((int)(R>> 8)&0xff)])+ \
|
||||||
S[0x0300+((int)(R )&0xff)])&0xffffffffL;
|
S[0x0300+((int)(R )&0xff)])&0xffffffffL \
|
||||||
|
)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -70,8 +70,25 @@ extern "C" {
|
|||||||
#define BF_ENCRYPT 1
|
#define BF_ENCRYPT 1
|
||||||
#define BF_DECRYPT 0
|
#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
|
#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...
|
||||||
|
* <appro@fy.chalmers.se>
|
||||||
|
*/
|
||||||
#else
|
#else
|
||||||
#define BF_LONG unsigned int
|
#define BF_LONG unsigned int
|
||||||
#endif
|
#endif
|
||||||
|
@ -58,27 +58,7 @@
|
|||||||
|
|
||||||
#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
|
#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
|
||||||
#define CONFIG_HEADER_BF_LOCL_H
|
#define CONFIG_HEADER_BF_LOCL_H
|
||||||
/* Special defines which change the way the code is built depending on the
|
#undef BF_PTR
|
||||||
CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
|
|
||||||
even newer MIPS CPU's, but at the moment one size fits all for
|
|
||||||
optimization options. Older Sparc's work better with only UNROLL, but
|
|
||||||
there's no way to tell at compile time what it is you're running on */
|
|
||||||
|
|
||||||
#if defined( sun ) /* Newer Sparc's */
|
|
||||||
# define BF_PTR
|
|
||||||
#elif defined( __ultrix ) /* Older MIPS */
|
|
||||||
# define BF_PTR
|
|
||||||
#elif defined( __sgi ) /* Newer MIPS */
|
|
||||||
# define BF_PTR
|
|
||||||
#endif /* Systems-specific speed defines */
|
|
||||||
|
|
||||||
/* use BF_PTR2 for intel boxes,
|
|
||||||
* BF_PTR for sparc and MIPS/SGI
|
|
||||||
* use nothing for Alpha and HP.
|
|
||||||
*/
|
|
||||||
#if !defined(BF_PTR) && !defined(BF_PTR2)
|
|
||||||
#define BF_PTR2
|
|
||||||
#endif
|
|
||||||
#endif /* HEADER_BF_LOCL_H */
|
#endif /* HEADER_BF_LOCL_H */
|
||||||
|
|
||||||
#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
|
#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user