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