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