xref: /freebsd/secure/lib/libcrypt/blowfish.c (revision 6990ffd8a95caaba6858ad44ff1b3157d1efba8f)
1 /*
2  * Blowfish block cipher
3  * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
4  * All rights reserved.
5  *
6  * Implementation advice by David Mazieres <dm@lcs.mit.edu>.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by Niels Provos.
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * $FreeBSD$
34  */
35 
36 /*
37  * This code is derived from section 14.3 and the given source
38  * in section V of Applied Cryptography, second edition.
39  * Blowfish is an unpatented fast block cipher designed by
40  * Bruce Schneier.
41  */
42 
43 /*
44  * FreeBSD implementation by Paul Herman <pherman@frenchfries.net>
45  */
46 
47 #if 0
48 #include <stdio.h>		/* used for debugging */
49 #include <string.h>
50 #endif
51 
52 #include <sys/types.h>
53 #include "blowfish.h"
54 
55 #undef inline
56 #ifdef __GNUC__
57 #define inline __inline
58 #else				/* !__GNUC__ */
59 #define inline
60 #endif				/* !__GNUC__ */
61 
62 /* Function for Feistel Networks */
63 
64 #define F(s, x) ((((s)[        (((x)>>24)&0xFF)]  \
65 		 + (s)[0x100 + (((x)>>16)&0xFF)]) \
66 		 ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
67 		 + (s)[0x300 + ( (x)     &0xFF)])
68 
69 #define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
70 
71 void
72 Blowfish_encipher(c, xl, xr)
73 	blf_ctx *c;
74 	u_int32_t *xl;
75 	u_int32_t *xr;
76 {
77 	u_int32_t Xl;
78 	u_int32_t Xr;
79 	u_int32_t *s = c->S[0];
80 	u_int32_t *p = c->P;
81 
82 	Xl = *xl;
83 	Xr = *xr;
84 
85 	Xl ^= p[0];
86 	BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
87 	BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
88 	BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
89 	BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
90 	BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
91 	BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
92 	BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
93 	BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
94 
95 	*xl = Xr ^ p[17];
96 	*xr = Xl;
97 }
98 
99 void
100 Blowfish_decipher(c, xl, xr)
101 	blf_ctx *c;
102 	u_int32_t *xl;
103 	u_int32_t *xr;
104 {
105 	u_int32_t Xl;
106 	u_int32_t Xr;
107 	u_int32_t *s = c->S[0];
108 	u_int32_t *p = c->P;
109 
110 	Xl = *xl;
111 	Xr = *xr;
112 
113 	Xl ^= p[17];
114 	BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
115 	BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
116 	BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
117 	BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
118 	BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
119 	BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
120 	BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
121 	BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
122 
123 	*xl = Xr ^ p[0];
124 	*xr = Xl;
125 }
126 
127 void
128 Blowfish_initstate(c)
129 	blf_ctx *c;
130 {
131 
132 /* P-box and S-box tables initialized with digits of Pi */
133 
134 	const blf_ctx initstate =
135 
136 	{ {
137 		{
138 			0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
139 			0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
140 			0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
141 			0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
142 			0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
143 			0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
144 			0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
145 			0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
146 			0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
147 			0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
148 			0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
149 			0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
150 			0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
151 			0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
152 			0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
153 			0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
154 			0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
155 			0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
156 			0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
157 			0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
158 			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
159 			0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
160 			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
161 			0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
162 			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
163 			0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
164 			0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
165 			0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
166 			0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
167 			0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
168 			0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
169 			0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
170 			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
171 			0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
172 			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
173 			0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
174 			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
175 			0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
176 			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
177 			0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
178 			0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
179 			0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
180 			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
181 			0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
182 			0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
183 			0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
184 			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
185 			0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
186 			0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
187 			0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
188 			0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
189 			0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
190 			0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
191 			0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
192 			0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
193 			0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
194 			0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
195 			0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
196 			0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
197 			0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
198 			0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
199 			0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
200 			0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
201 		0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
202 		{
203 			0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
204 			0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
205 			0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
206 			0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
207 			0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
208 			0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
209 			0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
210 			0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
211 			0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
212 			0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
213 			0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
214 			0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
215 			0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
216 			0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
217 			0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
218 			0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
219 			0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
220 			0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
221 			0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
222 			0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
223 			0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
224 			0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
225 			0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
226 			0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
227 			0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
228 			0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
229 			0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
230 			0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
231 			0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
232 			0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
233 			0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
234 			0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
235 			0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
236 			0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
237 			0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
238 			0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
239 			0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
240 			0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
241 			0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
242 			0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
243 			0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
244 			0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
245 			0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
246 			0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
247 			0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
248 			0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
249 			0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
250 			0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
251 			0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
252 			0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
253 			0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
254 			0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
255 			0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
256 			0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
257 			0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
258 			0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
259 			0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
260 			0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
261 			0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
262 			0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
263 			0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
264 			0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
265 			0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
266 		0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
267 		{
268 			0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
269 			0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
270 			0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
271 			0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
272 			0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
273 			0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
274 			0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
275 			0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
276 			0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
277 			0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
278 			0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
279 			0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
280 			0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
281 			0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
282 			0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
283 			0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
284 			0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
285 			0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
286 			0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
287 			0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
288 			0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
289 			0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
290 			0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
291 			0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
292 			0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
293 			0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
294 			0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
295 			0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
296 			0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
297 			0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
298 			0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
299 			0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
300 			0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
301 			0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
302 			0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
303 			0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
304 			0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
305 			0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
306 			0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
307 			0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
308 			0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
309 			0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
310 			0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
311 			0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
312 			0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
313 			0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
314 			0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
315 			0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
316 			0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
317 			0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
318 			0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
319 			0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
320 			0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
321 			0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
322 			0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
323 			0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
324 			0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
325 			0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
326 			0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
327 			0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
328 			0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
329 			0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
330 			0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
331 		0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
332 		{
333 			0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
334 			0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
335 			0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
336 			0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
337 			0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
338 			0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
339 			0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
340 			0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
341 			0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
342 			0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
343 			0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
344 			0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
345 			0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
346 			0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
347 			0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
348 			0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
349 			0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
350 			0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
351 			0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
352 			0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
353 			0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
354 			0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
355 			0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
356 			0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
357 			0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
358 			0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
359 			0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
360 			0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
361 			0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
362 			0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
363 			0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
364 			0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
365 			0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
366 			0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
367 			0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
368 			0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
369 			0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
370 			0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
371 			0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
372 			0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
373 			0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
374 			0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
375 			0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
376 			0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
377 			0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
378 			0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
379 			0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
380 			0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
381 			0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
382 			0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
383 			0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
384 			0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
385 			0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
386 			0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
387 			0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
388 			0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
389 			0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
390 			0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
391 			0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
392 			0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
393 			0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
394 			0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
395 			0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
396 		0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
397 	},
398 	{
399 		0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
400 		0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
401 		0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
402 		0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
403 		0x9216d5d9, 0x8979fb1b
404 	} };
405 
406 	*c = initstate;
407 
408 }
409 
410 #ifdef __STDC__
411 u_int32_t
412 Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, u_int16_t *current)
413 #else
414 u_int32_t
415 Blowfish_stream2word(data, databytes, current)
416 	const u_int8_t *data;
417 	u_int16_t databytes;
418 	u_int16_t *current;
419 #endif
420 {
421 	u_int8_t i;
422 	u_int16_t j;
423 	u_int32_t temp;
424 
425 	temp = 0x00000000;
426 	j = *current;
427 
428 	for (i = 0; i < 4; i++, j++) {
429 		if (j >= databytes)
430 			j = 0;
431 		temp = (temp << 8) | data[j];
432 	}
433 
434 	*current = j;
435 	return temp;
436 }
437 
438 #if __STDC__
439 void
440 Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes)
441 #else
442 void
443 Blowfish_expand0state(c, key, keybytes)
444 	blf_ctx *c;
445 	const u_int8_t *key;
446 	u_int16_t keybytes;
447 #endif
448 {
449 	u_int16_t i;
450 	u_int16_t j;
451 	u_int16_t k;
452 	u_int32_t temp;
453 	u_int32_t datal;
454 	u_int32_t datar;
455 
456 	j = 0;
457 	for (i = 0; i < BLF_N + 2; i++) {
458 		/* Extract 4 int8 to 1 int32 from keystream */
459 		temp = Blowfish_stream2word(key, keybytes, &j);
460 		c->P[i] = c->P[i] ^ temp;
461 	}
462 
463 	j = 0;
464 	datal = 0x00000000;
465 	datar = 0x00000000;
466 	for (i = 0; i < BLF_N + 2; i += 2) {
467 		Blowfish_encipher(c, &datal, &datar);
468 
469 		c->P[i] = datal;
470 		c->P[i + 1] = datar;
471 	}
472 
473 	for (i = 0; i < 4; i++) {
474 		for (k = 0; k < 256; k += 2) {
475 			Blowfish_encipher(c, &datal, &datar);
476 
477 			c->S[i][k] = datal;
478 			c->S[i][k + 1] = datar;
479 		}
480 	}
481 }
482 
483 
484 #if __STDC__
485 void
486 Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes,
487 		     const u_int8_t *key, u_int16_t keybytes)
488 #else
489 void
490 Blowfish_expandstate(c, data, databytes, key, keybytes)
491 	blf_ctx *c;
492 	const u_int8_t *data;
493 	u_int16_t databytes;
494 	const u_int8_t *key;
495 	u_int16_t keybytes;
496 #endif
497 {
498 	u_int16_t i;
499 	u_int16_t j;
500 	u_int16_t k;
501 	u_int32_t temp;
502 	u_int32_t datal;
503 	u_int32_t datar;
504 
505 	j = 0;
506 	for (i = 0; i < BLF_N + 2; i++) {
507 		/* Extract 4 int8 to 1 int32 from keystream */
508 		temp = Blowfish_stream2word(key, keybytes, &j);
509 		c->P[i] = c->P[i] ^ temp;
510 	}
511 
512 	j = 0;
513 	datal = 0x00000000;
514 	datar = 0x00000000;
515 	for (i = 0; i < BLF_N + 2; i += 2) {
516 		datal ^= Blowfish_stream2word(data, databytes, &j);
517 		datar ^= Blowfish_stream2word(data, databytes, &j);
518 		Blowfish_encipher(c, &datal, &datar);
519 
520 		c->P[i] = datal;
521 		c->P[i + 1] = datar;
522 	}
523 
524 	for (i = 0; i < 4; i++) {
525 		for (k = 0; k < 256; k += 2) {
526 			datal ^= Blowfish_stream2word(data, databytes, &j);
527 			datar ^= Blowfish_stream2word(data, databytes, &j);
528 			Blowfish_encipher(c, &datal, &datar);
529 
530 			c->S[i][k] = datal;
531 			c->S[i][k + 1] = datar;
532 		}
533 	}
534 
535 }
536 
537 #if __STDC__
538 void
539 blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len)
540 #else
541 void
542 blf_key(c, k, len)
543 	blf_ctx *c;
544 	const u_int8_t *k;
545 	u_int16_t len;
546 #endif
547 {
548 	/* Initalize S-boxes and subkeys with Pi */
549 	Blowfish_initstate(c);
550 
551 	/* Transform S-boxes and subkeys with key */
552 	Blowfish_expand0state(c, k, len);
553 }
554 
555 #if __STDC__
556 void
557 blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
558 #else
559 void
560 blf_enc(c, data, blocks)
561 	blf_ctx *c;
562 	u_int32_t *data;
563 	u_int16_t blocks;
564 #endif
565 {
566 	u_int32_t *d;
567 	u_int16_t i;
568 
569 	d = data;
570 	for (i = 0; i < blocks; i++) {
571 		Blowfish_encipher(c, d, d + 1);
572 		d += 2;
573 	}
574 }
575 
576 #if __STDC__
577 void
578 blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
579 #else
580 void
581 blf_dec(c, data, blocks)
582 	blf_ctx *c;
583 	u_int32_t *data;
584 	u_int16_t blocks;
585 #endif
586 {
587 	u_int32_t *d;
588 	u_int16_t i;
589 
590 	d = data;
591 	for (i = 0; i < blocks; i++) {
592 		Blowfish_decipher(c, d, d + 1);
593 		d += 2;
594 	}
595 }
596 
597 #if __STDC__
598 void
599 blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
600 #else
601 void
602 blf_ecb_encrypt(c, data, len)
603      blf_ctx *c;
604      u_int8_t *data;
605      u_int32_t len;
606 #endif
607 {
608 	u_int32_t l, r;
609 	u_int32_t i;
610 
611 	for (i = 0; i < len; i += 8) {
612 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
613 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
614 		Blowfish_encipher(c, &l, &r);
615 		data[0] = l >> 24 & 0xff;
616 		data[1] = l >> 16 & 0xff;
617 		data[2] = l >> 8 & 0xff;
618 		data[3] = l & 0xff;
619 		data[4] = r >> 24 & 0xff;
620 		data[5] = r >> 16 & 0xff;
621 		data[6] = r >> 8 & 0xff;
622 		data[7] = r & 0xff;
623 		data += 8;
624 	}
625 }
626 
627 #if __STDC__
628 void
629 blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
630 #else
631 void
632 blf_ecb_decrypt(c, data, len)
633      blf_ctx *c;
634      u_int8_t *data;
635      u_int32_t len;
636 #endif
637 {
638 	u_int32_t l, r;
639 	u_int32_t i;
640 
641 	for (i = 0; i < len; i += 8) {
642 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
643 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
644 		Blowfish_decipher(c, &l, &r);
645 		data[0] = l >> 24 & 0xff;
646 		data[1] = l >> 16 & 0xff;
647 		data[2] = l >> 8 & 0xff;
648 		data[3] = l & 0xff;
649 		data[4] = r >> 24 & 0xff;
650 		data[5] = r >> 16 & 0xff;
651 		data[6] = r >> 8 & 0xff;
652 		data[7] = r & 0xff;
653 		data += 8;
654 	}
655 }
656 
657 #if __STDC__
658 void
659 blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len)
660 #else
661 void
662 blf_cbc_encrypt(c, iv, data, len)
663      blf_ctx *c;
664      u_int8_t *iv;
665      u_int8_t *data;
666      u_int32_t len;
667 #endif
668 {
669 	u_int32_t l, r;
670 	u_int32_t i, j;
671 
672 	for (i = 0; i < len; i += 8) {
673 		for (j = 0; j < 8; j++)
674 			data[j] ^= iv[j];
675 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
676 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
677 		Blowfish_encipher(c, &l, &r);
678 		data[0] = l >> 24 & 0xff;
679 		data[1] = l >> 16 & 0xff;
680 		data[2] = l >> 8 & 0xff;
681 		data[3] = l & 0xff;
682 		data[4] = r >> 24 & 0xff;
683 		data[5] = r >> 16 & 0xff;
684 		data[6] = r >> 8 & 0xff;
685 		data[7] = r & 0xff;
686 		iv = data;
687 		data += 8;
688 	}
689 }
690 
691 #if __STDC__
692 void
693 blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len)
694 #else
695 void
696 blf_cbc_decrypt(c, iva, data, len)
697      blf_ctx *c;
698      u_int8_t *iva;
699      u_int8_t *data;
700      u_int32_t len;
701 #endif
702 {
703 	u_int32_t l, r;
704 	u_int8_t *iv;
705 	u_int32_t i, j;
706 
707 	iv = data + len - 16;
708 	data = data + len - 8;
709 	for (i = len - 8; i >= 8; i -= 8) {
710 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
711 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
712 		Blowfish_decipher(c, &l, &r);
713 		data[0] = l >> 24 & 0xff;
714 		data[1] = l >> 16 & 0xff;
715 		data[2] = l >> 8 & 0xff;
716 		data[3] = l & 0xff;
717 		data[4] = r >> 24 & 0xff;
718 		data[5] = r >> 16 & 0xff;
719 		data[6] = r >> 8 & 0xff;
720 		data[7] = r & 0xff;
721 		for (j = 0; j < 8; j++)
722 			data[j] ^= iv[j];
723 		iv -= 8;
724 		data -= 8;
725 	}
726 	l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
727 	r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
728 	Blowfish_decipher(c, &l, &r);
729 	data[0] = l >> 24 & 0xff;
730 	data[1] = l >> 16 & 0xff;
731 	data[2] = l >> 8 & 0xff;
732 	data[3] = l & 0xff;
733 	data[4] = r >> 24 & 0xff;
734 	data[5] = r >> 16 & 0xff;
735 	data[6] = r >> 8 & 0xff;
736 	data[7] = r & 0xff;
737 	for (j = 0; j < 8; j++)
738 		data[j] ^= iva[j];
739 }
740 
741 #if 0
742 void
743 report(u_int32_t data[], u_int16_t len)
744 {
745 	u_int16_t i;
746 	for (i = 0; i < len; i += 2)
747 		printf("Block %0hd: %08lx %08lx.\n",
748 		    i / 2, data[i], data[i + 1]);
749 }
750 void
751 main(void)
752 {
753 
754 	blf_ctx c;
755 	char    key[] = "AAAAA";
756 	char    key2[] = "abcdefghijklmnopqrstuvwxyz";
757 
758 	u_int32_t data[10];
759 	u_int32_t data2[] =
760 	{0x424c4f57l, 0x46495348l};
761 
762 	u_int16_t i;
763 
764 	/* First test */
765 	for (i = 0; i < 10; i++)
766 		data[i] = i;
767 
768 	blf_key(&c, (u_int8_t *) key, 5);
769 	blf_enc(&c, data, 5);
770 	blf_dec(&c, data, 1);
771 	blf_dec(&c, data + 2, 4);
772 	printf("Should read as 0 - 9.\n");
773 	report(data, 10);
774 
775 	/* Second test */
776 	blf_key(&c, (u_int8_t *) key2, strlen(key2));
777 	blf_enc(&c, data2, 1);
778 	printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
779 	report(data2, 2);
780 	blf_dec(&c, data2, 1);
781 	report(data2, 2);
782 }
783 #endif
784