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