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