1/* blowfish.c */
2
3#include "BlowFish.h"
4#include "BlowFishTable.h"
5
6#define N               16
7#define noErr            0
8#define DATAERROR         -1
9#define KEYBYTES         8
10
11unsigned long F(blf_ctx *bc, unsigned long x)
12{
13   unsigned long a;
14   unsigned long b;
15   unsigned long c;
16   unsigned long d;
17   unsigned long y;
18
19   d = x & 0x00FF;
20   x >>= 8;
21   c = x & 0x00FF;
22   x >>= 8;
23   b = x & 0x00FF;
24   x >>= 8;
25   a = x & 0x00FF;
26   y = bc->S[0][a] + bc->S[1][b];
27   y = y ^ bc->S[2][c];
28   y = y + bc->S[3][d];
29
30   return y;
31}
32
33void Blowfish_encipher(blf_ctx *bc, unsigned long *xl, unsigned long *xr)
34{
35   unsigned long  Xl;
36   unsigned long  Xr;
37   unsigned long  temp;
38   short          i;
39
40   Xl = *xl;
41   Xr = *xr;
42
43   for (i = 0; i < N; ++i)
44   {
45      Xl = Xl ^ bc->P[i];
46      Xr = F(bc, Xl) ^ Xr;
47
48      temp = Xl;
49      Xl = Xr;
50      Xr = temp;
51   }
52
53   temp = Xl;
54   Xl = Xr;
55   Xr = temp;
56
57   Xr = Xr ^ bc->P[N];
58   Xl = Xl ^ bc->P[N + 1];
59
60   *xl = Xl;
61   *xr = Xr;
62}
63
64void Blowfish_decipher(blf_ctx *bc, unsigned long *xl, unsigned long *xr)
65{
66   unsigned long  Xl;
67   unsigned long  Xr;
68   unsigned long  temp;
69   short          i;
70
71   Xl = *xl;
72   Xr = *xr;
73
74   for (i = N + 1; i > 1; --i)
75   {
76      Xl = Xl ^ bc->P[i];
77      Xr = F(bc, Xl) ^ Xr;
78
79      /* Exchange Xl and Xr */
80      temp = Xl;
81      Xl = Xr;
82      Xr = temp;
83   }
84
85   /* Exchange Xl and Xr */
86   temp = Xl;
87   Xl = Xr;
88   Xr = temp;
89
90   Xr = Xr ^ bc->P[1];
91   Xl = Xl ^ bc->P[0];
92
93   *xl = Xl;
94   *xr = Xr;
95}
96
97short InitializeBlowfish(blf_ctx *bc, unsigned char key[], int keybytes)
98{
99	 short          i;
100	 short          j;
101	 short          k;
102	 unsigned long  data;
103	 unsigned long  datal;
104	 unsigned long  datar;
105
106	/* initialise p & s-boxes without file read */
107	for (i = 0; i < N+2; i++)
108	{
109		bc->P[i] = bfp[i];
110	}
111	for (i = 0; i < 256; i++)
112	{
113		bc->S[0][i] = ks0[i];
114		bc->S[1][i] = ks1[i];
115		bc->S[2][i] = ks2[i];
116		bc->S[3][i] = ks3[i];
117	}
118
119	j = 0;
120	for (i = 0; i < N + 2; ++i)
121	{
122		data = 0x00000000;
123		for (k = 0; k < 4; ++k)
124		{
125			data = (data << 8) | key[j];
126			j = j + 1;
127			if (j >= keybytes)
128			{
129	  			j = 0;
130			}
131		}
132		bc->P[i] = bc->P[i] ^ data;
133	}
134
135	datal = 0x00000000;
136	datar = 0x00000000;
137
138	for (i = 0; i < N + 2; i += 2)
139	{
140		Blowfish_encipher(bc, &datal, &datar);
141
142		bc->P[i] = datal;
143		bc->P[i + 1] = datar;
144	}
145
146	for (i = 0; i < 4; ++i)
147	{
148		for (j = 0; j < 256; j += 2)
149		{
150
151			Blowfish_encipher(bc, &datal, &datar);
152
153			bc->S[i][j] = datal;
154			bc->S[i][j + 1] = datar;
155		}
156	}
157	return 0;
158}
159
160void blf_key (blf_ctx *c, unsigned char *k, int len)
161{
162	InitializeBlowfish(c, k, len);
163}
164
165void blf_enc(blf_ctx *c, unsigned long *data, int blocks)
166{
167	unsigned long *d;
168	int i;
169
170	d = data;
171	for (i = 0; i < blocks; i++)
172	{
173		Blowfish_encipher(c, d, d+1);
174		d += 2;
175	}
176}
177
178void blf_dec(blf_ctx *c, unsigned long *data, int blocks)
179{
180	unsigned long *d;
181	int i;
182
183	d = data;
184	for (i = 0; i < blocks; i++)
185	{
186		Blowfish_decipher(c, d, d+1);
187		d += 2;
188	}
189}
190