📄 bf.c
字号:
/* Bruce Schneier's Blowfish. Author: Olaf Titz <olaf@bigred.inka.de> This code is in the public domain. $Id: linux-2.4.0-cipe-1.4.5.patch,v 1.6 2001/04/17 18:50:11 arjanv Exp $*/#include "bf.h"#ifdef __KERNEL__#include <linux/types.h>#include <linux/string.h>#else#include <string.h>#endif#ifndef ASM_BF_Crypt/* The generic big/little endian routines use the following imported from <asm/byteorder.h> under Linux: __u32 __be32_to_cpup(__u32 *p); __u32 __cpu_to_be32(__u32 x); __u32 __le32_to_cpup(__u32 *p); __u32 __cpu_to_le32(__u32 x); These are macros. We provide replacements if necessary (non-Linux). XXX the pointer types are wrong, but else a cast would be necessary.*/#ifdef __GNUC__#define INLINE static inline#else#define INLINE static#endif#ifndef __be32_to_cpupINLINE __u32 __be32_to_cpup(unsigned char *p){ return (p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3];}#endif#ifndef __cpu_to_be32INLINE __u32 __cpu_to_be32(__u32 x){ register unsigned char *p=(unsigned char *)&x; return (p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3];}#endif#ifndef __le32_to_cpupINLINE __u32 __le32_to_cpup(unsigned char *p){ return (p[3]<<24)+(p[2]<<16)+(p[1]<<8)+p[0];}#endif#ifndef __cpu_to_le32INLINE __u32 __cpu_to_le32(__u32 x){ register unsigned char *p=(unsigned char *)&x; return (p[3]<<24)+(p[2]<<16)+(p[1]<<8)+p[0];}#endif/* Macros to implement the round function. *//* access the P and S boxes in key array */#define P(n) (key[(n)])#define S0(n) (key[(n)+18])#define S1(n) (key[(n)+274])#define S2(n) (key[(n)+530])#define S3(n) (key[(n)+786])/* access byte in word */#define B0(x) (((x)>>24)&255)#define B1(x) (((x)>>16)&255)#define B2(x) (((x)>>8)&255)#define B3(x) (((x))&255)/* one raw round sans swap. p is running ptr into P box array */#define F(x) (((S0(B0(x))+S1(B1(x)))^S2(B2(x)))+S3(B3(x)))#define RoundP(a,b) (a)^=(*p++)^F(b)#define RoundN(a,b) (a)^=(*p--)^F(b)/* 16 rounds with running pointer and word swapping */#define RoundsP \ RoundP(r, l); RoundP(l, r); \ RoundP(r, l); RoundP(l, r); \ RoundP(r, l); RoundP(l, r); \ RoundP(r, l); RoundP(l, r); \ RoundP(r, l); RoundP(l, r); \ RoundP(r, l); RoundP(l, r); \ RoundP(r, l); RoundP(l, r); \ RoundP(r, l); RoundP(l, r)#define RoundsN \ RoundN(r, l); RoundN(l, r); \ RoundN(r, l); RoundN(l, r); \ RoundN(r, l); RoundN(l, r); \ RoundN(r, l); RoundN(l, r); \ RoundN(r, l); RoundN(l, r); \ RoundN(r, l); RoundN(l, r); \ RoundN(r, l); RoundN(l, r); \ RoundN(r, l); RoundN(l, r)/* Native byte order routines */void _N_Blowfish_Encrypt(void *dataIn, void *dataOut, const Blowfish_Key key){ register const __u32 *p=(const __u32 *)key; register unsigned long l=((__u32 *)dataIn)[0]^(*p++), r=((__u32 *)dataIn)[1]; RoundsP; ((__u32 *)dataOut)[0]=r^(*p); ((__u32 *)dataOut)[1]=l;}void _N_Blowfish_Decrypt(void *dataIn, void *dataOut, const Blowfish_Key key){ register const __u32 *p=((const __u32 *)key)+17; register unsigned long l=((__u32 *)dataIn)[0]^(*p--), r=((__u32 *)dataIn)[1]; RoundsN; ((__u32 *)dataOut)[0]=r^(*p); ((__u32 *)dataOut)[1]=l;}/* Big-endian routines (i.e. real Blowfish) */#ifndef BF_DONTNEED_BE#ifndef BF_NATIVE_BEvoid B_Blowfish_Encrypt(void *dataIn, void *dataOut, const Blowfish_Key key){ register const __u32 *p=(const __u32 *)key; register unsigned long l=__be32_to_cpup(dataIn)^(*p++), r=__be32_to_cpup(dataIn+4); RoundsP; ((__u32 *)dataOut)[0]=__cpu_to_be32(r^(*p)); ((__u32 *)dataOut)[1]=__cpu_to_be32(l);}void B_Blowfish_Decrypt(void *dataIn, void *dataOut, const Blowfish_Key key){ register const __u32 *p=((const __u32 *)key)+17; register unsigned long l=__be32_to_cpup(dataIn)^(*p--), r=__be32_to_cpup(dataIn+4); RoundsN; ((__u32 *)dataOut)[0]=__cpu_to_be32(r^(*p)); ((__u32 *)dataOut)[1]=__cpu_to_be32(l);}#endif#endif/* Little-endian routines */#ifndef BF_DONTNEED_LE#ifndef BF_NATIVE_LEvoid L_Blowfish_Encrypt(void *dataIn, void *dataOut, const Blowfish_Key key){ register const __u32 *p=key; register unsigned long l=__le32_to_cpup(dataIn)^(*p++), r=__le32_to_cpup(dataIn+4); RoundsP; ((__u32 *)dataOut)[0]=__cpu_to_le32(r^(*p)); ((__u32 *)dataOut)[1]=__cpu_to_le32(l);}void L_Blowfish_Decrypt(void *dataIn, void *dataOut, const Blowfish_Key key){ register const __u32 *p=key+17; register unsigned long l=__le32_to_cpup(dataIn)^(*p--), r=__le32_to_cpup(dataIn+4); RoundsN; ((__u32 *)dataOut)[0]=__cpu_to_le32(r^(*p)); ((__u32 *)dataOut)[1]=__cpu_to_le32(l);}#endif#endif/* Key setup */void Blowfish_ExpandUserKey(const char *userKey, int userKeyLen, Blowfish_Key key){ char d[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int i, j; __u32 u; #define UK (userKey[j]&255) #define UKI if (++j>=userKeyLen) j=0 for (i=j=0; i<18; ++i) { u=UK; UKI; u=(u<<8)+UK; UKI; u=(u<<8)+UK; UKI; u=(u<<8)+UK; UKI; key[i]=Blowfish_Init_Key[i]^u; } memcpy(key+18, Blowfish_Init_Key+18, 4096); for (i=0; i<1042; i+=2) { _N_Blowfish_Encrypt(d, d, key); key[i]=((__u32 *)d)[0]; key[i+1]=((__u32 *)d)[1]; }}#endif/* The initialization key. According to Schneier, this is not a magic pattern but simply the first 33344 (after point) bits of "pi". */const Blowfish_Key Blowfish_Init_Key = { /* The eighteen P boxes @ 1 word */ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b, /* The four S boxes @ 256 words */ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -