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