xref: /dragonfly/lib/libcrypt/blowfish.c (revision 2ae2c6ed)
10fe46dc6SMatthew Dillon /*
20fe46dc6SMatthew Dillon  * Blowfish block cipher
30fe46dc6SMatthew Dillon  * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
40fe46dc6SMatthew Dillon  * All rights reserved.
50fe46dc6SMatthew Dillon  *
60fe46dc6SMatthew Dillon  * Implementation advice by David Mazieres <dm@lcs.mit.edu>.
70fe46dc6SMatthew Dillon  *
80fe46dc6SMatthew Dillon  * Redistribution and use in source and binary forms, with or without
90fe46dc6SMatthew Dillon  * modification, are permitted provided that the following conditions
100fe46dc6SMatthew Dillon  * are met:
110fe46dc6SMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
120fe46dc6SMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
130fe46dc6SMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
140fe46dc6SMatthew Dillon  *    notice, this list of conditions and the following disclaimer in the
150fe46dc6SMatthew Dillon  *    documentation and/or other materials provided with the distribution.
160fe46dc6SMatthew Dillon  * 3. All advertising materials mentioning features or use of this software
170fe46dc6SMatthew Dillon  *    must display the following acknowledgement:
180fe46dc6SMatthew Dillon  *      This product includes software developed by Niels Provos.
190fe46dc6SMatthew Dillon  * 4. The name of the author may not be used to endorse or promote products
200fe46dc6SMatthew Dillon  *    derived from this software without specific prior written permission.
210fe46dc6SMatthew Dillon  *
220fe46dc6SMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
230fe46dc6SMatthew Dillon  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
240fe46dc6SMatthew Dillon  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
250fe46dc6SMatthew Dillon  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
260fe46dc6SMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
270fe46dc6SMatthew Dillon  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
280fe46dc6SMatthew Dillon  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
290fe46dc6SMatthew Dillon  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
300fe46dc6SMatthew Dillon  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
310fe46dc6SMatthew Dillon  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
320fe46dc6SMatthew Dillon  *
330fe46dc6SMatthew Dillon  * $FreeBSD: src/secure/lib/libcrypt/blowfish.c,v 1.1.2.1 2001/05/24 12:20:03 markm Exp $
340fe46dc6SMatthew Dillon  */
350fe46dc6SMatthew Dillon 
360fe46dc6SMatthew Dillon /*
370fe46dc6SMatthew Dillon  * This code is derived from section 14.3 and the given source
380fe46dc6SMatthew Dillon  * in section V of Applied Cryptography, second edition.
390fe46dc6SMatthew Dillon  * Blowfish is an unpatented fast block cipher designed by
400fe46dc6SMatthew Dillon  * Bruce Schneier.
410fe46dc6SMatthew Dillon  */
420fe46dc6SMatthew Dillon 
430fe46dc6SMatthew Dillon /*
440fe46dc6SMatthew Dillon  * FreeBSD implementation by Paul Herman <pherman@frenchfries.net>
450fe46dc6SMatthew Dillon  */
460fe46dc6SMatthew Dillon 
470fe46dc6SMatthew Dillon #if 0
480fe46dc6SMatthew Dillon #include <stdio.h>		/* used for debugging */
490fe46dc6SMatthew Dillon #include <string.h>
500fe46dc6SMatthew Dillon #endif
510fe46dc6SMatthew Dillon 
520fe46dc6SMatthew Dillon #include <sys/types.h>
530fe46dc6SMatthew Dillon #include "blowfish.h"
540fe46dc6SMatthew Dillon 
550fe46dc6SMatthew Dillon #undef inline
560fe46dc6SMatthew Dillon #ifdef __GNUC__
570fe46dc6SMatthew Dillon #define inline __inline
580fe46dc6SMatthew Dillon #else				/* !__GNUC__ */
590fe46dc6SMatthew Dillon #define inline
600fe46dc6SMatthew Dillon #endif				/* !__GNUC__ */
610fe46dc6SMatthew Dillon 
620fe46dc6SMatthew Dillon /* Function for Feistel Networks */
630fe46dc6SMatthew Dillon 
640fe46dc6SMatthew Dillon #define F(s, x) ((((s)[        (((x)>>24)&0xFF)]  \
650fe46dc6SMatthew Dillon 		 + (s)[0x100 + (((x)>>16)&0xFF)]) \
660fe46dc6SMatthew Dillon 		 ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
670fe46dc6SMatthew Dillon 		 + (s)[0x300 + ( (x)     &0xFF)])
680fe46dc6SMatthew Dillon 
690fe46dc6SMatthew Dillon #define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
700fe46dc6SMatthew Dillon 
710fe46dc6SMatthew Dillon void
Blowfish_encipher(blf_ctx * c,u_int32_t * xl,u_int32_t * xr)72*2ae2c6edSSascha Wildner Blowfish_encipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr)
730fe46dc6SMatthew Dillon {
740fe46dc6SMatthew Dillon 	u_int32_t Xl;
750fe46dc6SMatthew Dillon 	u_int32_t Xr;
760fe46dc6SMatthew Dillon 	u_int32_t *s = c->S[0];
770fe46dc6SMatthew Dillon 	u_int32_t *p = c->P;
780fe46dc6SMatthew Dillon 
790fe46dc6SMatthew Dillon 	Xl = *xl;
800fe46dc6SMatthew Dillon 	Xr = *xr;
810fe46dc6SMatthew Dillon 
820fe46dc6SMatthew Dillon 	Xl ^= p[0];
830fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
840fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
850fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
860fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
870fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
880fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
890fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
900fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
910fe46dc6SMatthew Dillon 
920fe46dc6SMatthew Dillon 	*xl = Xr ^ p[17];
930fe46dc6SMatthew Dillon 	*xr = Xl;
940fe46dc6SMatthew Dillon }
950fe46dc6SMatthew Dillon 
960fe46dc6SMatthew Dillon void
Blowfish_decipher(blf_ctx * c,u_int32_t * xl,u_int32_t * xr)97*2ae2c6edSSascha Wildner Blowfish_decipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr)
980fe46dc6SMatthew Dillon {
990fe46dc6SMatthew Dillon 	u_int32_t Xl;
1000fe46dc6SMatthew Dillon 	u_int32_t Xr;
1010fe46dc6SMatthew Dillon 	u_int32_t *s = c->S[0];
1020fe46dc6SMatthew Dillon 	u_int32_t *p = c->P;
1030fe46dc6SMatthew Dillon 
1040fe46dc6SMatthew Dillon 	Xl = *xl;
1050fe46dc6SMatthew Dillon 	Xr = *xr;
1060fe46dc6SMatthew Dillon 
1070fe46dc6SMatthew Dillon 	Xl ^= p[17];
1080fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
1090fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
1100fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
1110fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
1120fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
1130fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
1140fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
1150fe46dc6SMatthew Dillon 	BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
1160fe46dc6SMatthew Dillon 
1170fe46dc6SMatthew Dillon 	*xl = Xr ^ p[0];
1180fe46dc6SMatthew Dillon 	*xr = Xl;
1190fe46dc6SMatthew Dillon }
1200fe46dc6SMatthew Dillon 
1210fe46dc6SMatthew Dillon void
Blowfish_initstate(blf_ctx * c)122*2ae2c6edSSascha Wildner Blowfish_initstate(blf_ctx *c)
1230fe46dc6SMatthew Dillon {
1240fe46dc6SMatthew Dillon 
1250fe46dc6SMatthew Dillon /* P-box and S-box tables initialized with digits of Pi */
1260fe46dc6SMatthew Dillon 
1270fe46dc6SMatthew Dillon 	const blf_ctx initstate =
1280fe46dc6SMatthew Dillon 
1290fe46dc6SMatthew Dillon 	{ {
1300fe46dc6SMatthew Dillon 		{
1310fe46dc6SMatthew Dillon 			0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1320fe46dc6SMatthew Dillon 			0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1330fe46dc6SMatthew Dillon 			0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1340fe46dc6SMatthew Dillon 			0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1350fe46dc6SMatthew Dillon 			0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1360fe46dc6SMatthew Dillon 			0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1370fe46dc6SMatthew Dillon 			0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1380fe46dc6SMatthew Dillon 			0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1390fe46dc6SMatthew Dillon 			0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1400fe46dc6SMatthew Dillon 			0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1410fe46dc6SMatthew Dillon 			0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1420fe46dc6SMatthew Dillon 			0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1430fe46dc6SMatthew Dillon 			0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1440fe46dc6SMatthew Dillon 			0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1450fe46dc6SMatthew Dillon 			0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1460fe46dc6SMatthew Dillon 			0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1470fe46dc6SMatthew Dillon 			0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1480fe46dc6SMatthew Dillon 			0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1490fe46dc6SMatthew Dillon 			0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1500fe46dc6SMatthew Dillon 			0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1510fe46dc6SMatthew Dillon 			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1520fe46dc6SMatthew Dillon 			0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1530fe46dc6SMatthew Dillon 			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1540fe46dc6SMatthew Dillon 			0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1550fe46dc6SMatthew Dillon 			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1560fe46dc6SMatthew Dillon 			0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1570fe46dc6SMatthew Dillon 			0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1580fe46dc6SMatthew Dillon 			0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1590fe46dc6SMatthew Dillon 			0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1600fe46dc6SMatthew Dillon 			0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1610fe46dc6SMatthew Dillon 			0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1620fe46dc6SMatthew Dillon 			0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1630fe46dc6SMatthew Dillon 			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1640fe46dc6SMatthew Dillon 			0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1650fe46dc6SMatthew Dillon 			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1660fe46dc6SMatthew Dillon 			0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1670fe46dc6SMatthew Dillon 			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1680fe46dc6SMatthew Dillon 			0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1690fe46dc6SMatthew Dillon 			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1700fe46dc6SMatthew Dillon 			0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1710fe46dc6SMatthew Dillon 			0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1720fe46dc6SMatthew Dillon 			0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1730fe46dc6SMatthew Dillon 			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1740fe46dc6SMatthew Dillon 			0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1750fe46dc6SMatthew Dillon 			0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1760fe46dc6SMatthew Dillon 			0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1770fe46dc6SMatthew Dillon 			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1780fe46dc6SMatthew Dillon 			0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1790fe46dc6SMatthew Dillon 			0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1800fe46dc6SMatthew Dillon 			0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1810fe46dc6SMatthew Dillon 			0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1820fe46dc6SMatthew Dillon 			0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1830fe46dc6SMatthew Dillon 			0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1840fe46dc6SMatthew Dillon 			0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1850fe46dc6SMatthew Dillon 			0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1860fe46dc6SMatthew Dillon 			0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1870fe46dc6SMatthew Dillon 			0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1880fe46dc6SMatthew Dillon 			0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1890fe46dc6SMatthew Dillon 			0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1900fe46dc6SMatthew Dillon 			0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1910fe46dc6SMatthew Dillon 			0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1920fe46dc6SMatthew Dillon 			0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1930fe46dc6SMatthew Dillon 			0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1940fe46dc6SMatthew Dillon 		0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
1950fe46dc6SMatthew Dillon 		{
1960fe46dc6SMatthew Dillon 			0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1970fe46dc6SMatthew Dillon 			0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1980fe46dc6SMatthew Dillon 			0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1990fe46dc6SMatthew Dillon 			0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
2000fe46dc6SMatthew Dillon 			0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
2010fe46dc6SMatthew Dillon 			0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
2020fe46dc6SMatthew Dillon 			0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
2030fe46dc6SMatthew Dillon 			0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
2040fe46dc6SMatthew Dillon 			0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
2050fe46dc6SMatthew Dillon 			0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
2060fe46dc6SMatthew Dillon 			0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
2070fe46dc6SMatthew Dillon 			0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
2080fe46dc6SMatthew Dillon 			0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
2090fe46dc6SMatthew Dillon 			0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
2100fe46dc6SMatthew Dillon 			0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
2110fe46dc6SMatthew Dillon 			0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
2120fe46dc6SMatthew Dillon 			0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
2130fe46dc6SMatthew Dillon 			0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
2140fe46dc6SMatthew Dillon 			0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
2150fe46dc6SMatthew Dillon 			0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
2160fe46dc6SMatthew Dillon 			0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
2170fe46dc6SMatthew Dillon 			0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
2180fe46dc6SMatthew Dillon 			0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
2190fe46dc6SMatthew Dillon 			0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
2200fe46dc6SMatthew Dillon 			0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
2210fe46dc6SMatthew Dillon 			0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
2220fe46dc6SMatthew Dillon 			0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
2230fe46dc6SMatthew Dillon 			0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
2240fe46dc6SMatthew Dillon 			0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
2250fe46dc6SMatthew Dillon 			0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
2260fe46dc6SMatthew Dillon 			0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
2270fe46dc6SMatthew Dillon 			0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
2280fe46dc6SMatthew Dillon 			0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
2290fe46dc6SMatthew Dillon 			0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
2300fe46dc6SMatthew Dillon 			0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
2310fe46dc6SMatthew Dillon 			0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
2320fe46dc6SMatthew Dillon 			0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
2330fe46dc6SMatthew Dillon 			0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
2340fe46dc6SMatthew Dillon 			0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
2350fe46dc6SMatthew Dillon 			0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
2360fe46dc6SMatthew Dillon 			0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
2370fe46dc6SMatthew Dillon 			0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
2380fe46dc6SMatthew Dillon 			0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
2390fe46dc6SMatthew Dillon 			0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
2400fe46dc6SMatthew Dillon 			0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
2410fe46dc6SMatthew Dillon 			0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
2420fe46dc6SMatthew Dillon 			0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
2430fe46dc6SMatthew Dillon 			0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
2440fe46dc6SMatthew Dillon 			0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
2450fe46dc6SMatthew Dillon 			0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
2460fe46dc6SMatthew Dillon 			0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
2470fe46dc6SMatthew Dillon 			0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
2480fe46dc6SMatthew Dillon 			0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
2490fe46dc6SMatthew Dillon 			0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
2500fe46dc6SMatthew Dillon 			0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
2510fe46dc6SMatthew Dillon 			0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
2520fe46dc6SMatthew Dillon 			0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
2530fe46dc6SMatthew Dillon 			0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
2540fe46dc6SMatthew Dillon 			0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
2550fe46dc6SMatthew Dillon 			0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
2560fe46dc6SMatthew Dillon 			0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
2570fe46dc6SMatthew Dillon 			0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
2580fe46dc6SMatthew Dillon 			0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
2590fe46dc6SMatthew Dillon 		0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
2600fe46dc6SMatthew Dillon 		{
2610fe46dc6SMatthew Dillon 			0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
2620fe46dc6SMatthew Dillon 			0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
2630fe46dc6SMatthew Dillon 			0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
2640fe46dc6SMatthew Dillon 			0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
2650fe46dc6SMatthew Dillon 			0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
2660fe46dc6SMatthew Dillon 			0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
2670fe46dc6SMatthew Dillon 			0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
2680fe46dc6SMatthew Dillon 			0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
2690fe46dc6SMatthew Dillon 			0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
2700fe46dc6SMatthew Dillon 			0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
2710fe46dc6SMatthew Dillon 			0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
2720fe46dc6SMatthew Dillon 			0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
2730fe46dc6SMatthew Dillon 			0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
2740fe46dc6SMatthew Dillon 			0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
2750fe46dc6SMatthew Dillon 			0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
2760fe46dc6SMatthew Dillon 			0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
2770fe46dc6SMatthew Dillon 			0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
2780fe46dc6SMatthew Dillon 			0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
2790fe46dc6SMatthew Dillon 			0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
2800fe46dc6SMatthew Dillon 			0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
2810fe46dc6SMatthew Dillon 			0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
2820fe46dc6SMatthew Dillon 			0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
2830fe46dc6SMatthew Dillon 			0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
2840fe46dc6SMatthew Dillon 			0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
2850fe46dc6SMatthew Dillon 			0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
2860fe46dc6SMatthew Dillon 			0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
2870fe46dc6SMatthew Dillon 			0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
2880fe46dc6SMatthew Dillon 			0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
2890fe46dc6SMatthew Dillon 			0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
2900fe46dc6SMatthew Dillon 			0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
2910fe46dc6SMatthew Dillon 			0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
2920fe46dc6SMatthew Dillon 			0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
2930fe46dc6SMatthew Dillon 			0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
2940fe46dc6SMatthew Dillon 			0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
2950fe46dc6SMatthew Dillon 			0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
2960fe46dc6SMatthew Dillon 			0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
2970fe46dc6SMatthew Dillon 			0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
2980fe46dc6SMatthew Dillon 			0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
2990fe46dc6SMatthew Dillon 			0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
3000fe46dc6SMatthew Dillon 			0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
3010fe46dc6SMatthew Dillon 			0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
3020fe46dc6SMatthew Dillon 			0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
3030fe46dc6SMatthew Dillon 			0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
3040fe46dc6SMatthew Dillon 			0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
3050fe46dc6SMatthew Dillon 			0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
3060fe46dc6SMatthew Dillon 			0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
3070fe46dc6SMatthew Dillon 			0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
3080fe46dc6SMatthew Dillon 			0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
3090fe46dc6SMatthew Dillon 			0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
3100fe46dc6SMatthew Dillon 			0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
3110fe46dc6SMatthew Dillon 			0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
3120fe46dc6SMatthew Dillon 			0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
3130fe46dc6SMatthew Dillon 			0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
3140fe46dc6SMatthew Dillon 			0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
3150fe46dc6SMatthew Dillon 			0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
3160fe46dc6SMatthew Dillon 			0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
3170fe46dc6SMatthew Dillon 			0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
3180fe46dc6SMatthew Dillon 			0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
3190fe46dc6SMatthew Dillon 			0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
3200fe46dc6SMatthew Dillon 			0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
3210fe46dc6SMatthew Dillon 			0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
3220fe46dc6SMatthew Dillon 			0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
3230fe46dc6SMatthew Dillon 			0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
3240fe46dc6SMatthew Dillon 		0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
3250fe46dc6SMatthew Dillon 		{
3260fe46dc6SMatthew Dillon 			0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
3270fe46dc6SMatthew Dillon 			0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
3280fe46dc6SMatthew Dillon 			0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
3290fe46dc6SMatthew Dillon 			0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
3300fe46dc6SMatthew Dillon 			0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
3310fe46dc6SMatthew Dillon 			0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
3320fe46dc6SMatthew Dillon 			0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
3330fe46dc6SMatthew Dillon 			0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
3340fe46dc6SMatthew Dillon 			0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
3350fe46dc6SMatthew Dillon 			0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
3360fe46dc6SMatthew Dillon 			0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
3370fe46dc6SMatthew Dillon 			0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
3380fe46dc6SMatthew Dillon 			0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
3390fe46dc6SMatthew Dillon 			0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
3400fe46dc6SMatthew Dillon 			0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
3410fe46dc6SMatthew Dillon 			0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
3420fe46dc6SMatthew Dillon 			0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
3430fe46dc6SMatthew Dillon 			0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
3440fe46dc6SMatthew Dillon 			0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
3450fe46dc6SMatthew Dillon 			0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
3460fe46dc6SMatthew Dillon 			0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
3470fe46dc6SMatthew Dillon 			0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
3480fe46dc6SMatthew Dillon 			0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
3490fe46dc6SMatthew Dillon 			0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
3500fe46dc6SMatthew Dillon 			0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
3510fe46dc6SMatthew Dillon 			0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
3520fe46dc6SMatthew Dillon 			0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
3530fe46dc6SMatthew Dillon 			0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
3540fe46dc6SMatthew Dillon 			0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
3550fe46dc6SMatthew Dillon 			0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
3560fe46dc6SMatthew Dillon 			0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
3570fe46dc6SMatthew Dillon 			0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
3580fe46dc6SMatthew Dillon 			0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
3590fe46dc6SMatthew Dillon 			0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
3600fe46dc6SMatthew Dillon 			0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
3610fe46dc6SMatthew Dillon 			0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
3620fe46dc6SMatthew Dillon 			0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
3630fe46dc6SMatthew Dillon 			0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
3640fe46dc6SMatthew Dillon 			0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
3650fe46dc6SMatthew Dillon 			0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
3660fe46dc6SMatthew Dillon 			0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
3670fe46dc6SMatthew Dillon 			0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
3680fe46dc6SMatthew Dillon 			0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
3690fe46dc6SMatthew Dillon 			0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
3700fe46dc6SMatthew Dillon 			0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
3710fe46dc6SMatthew Dillon 			0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
3720fe46dc6SMatthew Dillon 			0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
3730fe46dc6SMatthew Dillon 			0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
3740fe46dc6SMatthew Dillon 			0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
3750fe46dc6SMatthew Dillon 			0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
3760fe46dc6SMatthew Dillon 			0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
3770fe46dc6SMatthew Dillon 			0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
3780fe46dc6SMatthew Dillon 			0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
3790fe46dc6SMatthew Dillon 			0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
3800fe46dc6SMatthew Dillon 			0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
3810fe46dc6SMatthew Dillon 			0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
3820fe46dc6SMatthew Dillon 			0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
3830fe46dc6SMatthew Dillon 			0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
3840fe46dc6SMatthew Dillon 			0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
3850fe46dc6SMatthew Dillon 			0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
3860fe46dc6SMatthew Dillon 			0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
3870fe46dc6SMatthew Dillon 			0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
3880fe46dc6SMatthew Dillon 			0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
3890fe46dc6SMatthew Dillon 		0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
3900fe46dc6SMatthew Dillon 	},
3910fe46dc6SMatthew Dillon 	{
3920fe46dc6SMatthew Dillon 		0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
3930fe46dc6SMatthew Dillon 		0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
3940fe46dc6SMatthew Dillon 		0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
3950fe46dc6SMatthew Dillon 		0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
3960fe46dc6SMatthew Dillon 		0x9216d5d9, 0x8979fb1b
3970fe46dc6SMatthew Dillon 	} };
3980fe46dc6SMatthew Dillon 
3990fe46dc6SMatthew Dillon 	*c = initstate;
4000fe46dc6SMatthew Dillon 
4010fe46dc6SMatthew Dillon }
4020fe46dc6SMatthew Dillon 
4030fe46dc6SMatthew Dillon u_int32_t
Blowfish_stream2word(const u_int8_t * data,u_int16_t databytes,u_int16_t * current)4040fe46dc6SMatthew Dillon Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes, u_int16_t *current)
4050fe46dc6SMatthew Dillon {
4060fe46dc6SMatthew Dillon 	u_int8_t i;
4070fe46dc6SMatthew Dillon 	u_int16_t j;
4080fe46dc6SMatthew Dillon 	u_int32_t temp;
4090fe46dc6SMatthew Dillon 
4100fe46dc6SMatthew Dillon 	temp = 0x00000000;
4110fe46dc6SMatthew Dillon 	j = *current;
4120fe46dc6SMatthew Dillon 
4130fe46dc6SMatthew Dillon 	for (i = 0; i < 4; i++, j++) {
4140fe46dc6SMatthew Dillon 		if (j >= databytes)
4150fe46dc6SMatthew Dillon 			j = 0;
4160fe46dc6SMatthew Dillon 		temp = (temp << 8) | data[j];
4170fe46dc6SMatthew Dillon 	}
4180fe46dc6SMatthew Dillon 
4190fe46dc6SMatthew Dillon 	*current = j;
4200fe46dc6SMatthew Dillon 	return temp;
4210fe46dc6SMatthew Dillon }
4220fe46dc6SMatthew Dillon 
4230fe46dc6SMatthew Dillon void
Blowfish_expand0state(blf_ctx * c,const u_int8_t * key,u_int16_t keybytes)4240fe46dc6SMatthew Dillon Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes)
4250fe46dc6SMatthew Dillon {
4260fe46dc6SMatthew Dillon 	u_int16_t i;
4270fe46dc6SMatthew Dillon 	u_int16_t j;
4280fe46dc6SMatthew Dillon 	u_int16_t k;
4290fe46dc6SMatthew Dillon 	u_int32_t temp;
4300fe46dc6SMatthew Dillon 	u_int32_t datal;
4310fe46dc6SMatthew Dillon 	u_int32_t datar;
4320fe46dc6SMatthew Dillon 
4330fe46dc6SMatthew Dillon 	j = 0;
4340fe46dc6SMatthew Dillon 	for (i = 0; i < BLF_N + 2; i++) {
4350fe46dc6SMatthew Dillon 		/* Extract 4 int8 to 1 int32 from keystream */
4360fe46dc6SMatthew Dillon 		temp = Blowfish_stream2word(key, keybytes, &j);
4370fe46dc6SMatthew Dillon 		c->P[i] = c->P[i] ^ temp;
4380fe46dc6SMatthew Dillon 	}
4390fe46dc6SMatthew Dillon 
4400fe46dc6SMatthew Dillon 	j = 0;
4410fe46dc6SMatthew Dillon 	datal = 0x00000000;
4420fe46dc6SMatthew Dillon 	datar = 0x00000000;
4430fe46dc6SMatthew Dillon 	for (i = 0; i < BLF_N + 2; i += 2) {
4440fe46dc6SMatthew Dillon 		Blowfish_encipher(c, &datal, &datar);
4450fe46dc6SMatthew Dillon 
4460fe46dc6SMatthew Dillon 		c->P[i] = datal;
4470fe46dc6SMatthew Dillon 		c->P[i + 1] = datar;
4480fe46dc6SMatthew Dillon 	}
4490fe46dc6SMatthew Dillon 
4500fe46dc6SMatthew Dillon 	for (i = 0; i < 4; i++) {
4510fe46dc6SMatthew Dillon 		for (k = 0; k < 256; k += 2) {
4520fe46dc6SMatthew Dillon 			Blowfish_encipher(c, &datal, &datar);
4530fe46dc6SMatthew Dillon 
4540fe46dc6SMatthew Dillon 			c->S[i][k] = datal;
4550fe46dc6SMatthew Dillon 			c->S[i][k + 1] = datar;
4560fe46dc6SMatthew Dillon 		}
4570fe46dc6SMatthew Dillon 	}
4580fe46dc6SMatthew Dillon }
4590fe46dc6SMatthew Dillon 
4600fe46dc6SMatthew Dillon 
4610fe46dc6SMatthew Dillon void
Blowfish_expandstate(blf_ctx * c,const u_int8_t * data,u_int16_t databytes,const u_int8_t * key,u_int16_t keybytes)4620fe46dc6SMatthew Dillon Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes,
4630fe46dc6SMatthew Dillon 		     const u_int8_t *key, u_int16_t keybytes)
4640fe46dc6SMatthew Dillon {
4650fe46dc6SMatthew Dillon 	u_int16_t i;
4660fe46dc6SMatthew Dillon 	u_int16_t j;
4670fe46dc6SMatthew Dillon 	u_int16_t k;
4680fe46dc6SMatthew Dillon 	u_int32_t temp;
4690fe46dc6SMatthew Dillon 	u_int32_t datal;
4700fe46dc6SMatthew Dillon 	u_int32_t datar;
4710fe46dc6SMatthew Dillon 
4720fe46dc6SMatthew Dillon 	j = 0;
4730fe46dc6SMatthew Dillon 	for (i = 0; i < BLF_N + 2; i++) {
4740fe46dc6SMatthew Dillon 		/* Extract 4 int8 to 1 int32 from keystream */
4750fe46dc6SMatthew Dillon 		temp = Blowfish_stream2word(key, keybytes, &j);
4760fe46dc6SMatthew Dillon 		c->P[i] = c->P[i] ^ temp;
4770fe46dc6SMatthew Dillon 	}
4780fe46dc6SMatthew Dillon 
4790fe46dc6SMatthew Dillon 	j = 0;
4800fe46dc6SMatthew Dillon 	datal = 0x00000000;
4810fe46dc6SMatthew Dillon 	datar = 0x00000000;
4820fe46dc6SMatthew Dillon 	for (i = 0; i < BLF_N + 2; i += 2) {
4830fe46dc6SMatthew Dillon 		datal ^= Blowfish_stream2word(data, databytes, &j);
4840fe46dc6SMatthew Dillon 		datar ^= Blowfish_stream2word(data, databytes, &j);
4850fe46dc6SMatthew Dillon 		Blowfish_encipher(c, &datal, &datar);
4860fe46dc6SMatthew Dillon 
4870fe46dc6SMatthew Dillon 		c->P[i] = datal;
4880fe46dc6SMatthew Dillon 		c->P[i + 1] = datar;
4890fe46dc6SMatthew Dillon 	}
4900fe46dc6SMatthew Dillon 
4910fe46dc6SMatthew Dillon 	for (i = 0; i < 4; i++) {
4920fe46dc6SMatthew Dillon 		for (k = 0; k < 256; k += 2) {
4930fe46dc6SMatthew Dillon 			datal ^= Blowfish_stream2word(data, databytes, &j);
4940fe46dc6SMatthew Dillon 			datar ^= Blowfish_stream2word(data, databytes, &j);
4950fe46dc6SMatthew Dillon 			Blowfish_encipher(c, &datal, &datar);
4960fe46dc6SMatthew Dillon 
4970fe46dc6SMatthew Dillon 			c->S[i][k] = datal;
4980fe46dc6SMatthew Dillon 			c->S[i][k + 1] = datar;
4990fe46dc6SMatthew Dillon 		}
5000fe46dc6SMatthew Dillon 	}
5010fe46dc6SMatthew Dillon 
5020fe46dc6SMatthew Dillon }
5030fe46dc6SMatthew Dillon 
5040fe46dc6SMatthew Dillon void
blf_key(blf_ctx * c,const u_int8_t * k,u_int16_t len)5050fe46dc6SMatthew Dillon blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len)
5060fe46dc6SMatthew Dillon {
5070fe46dc6SMatthew Dillon 	/* Initalize S-boxes and subkeys with Pi */
5080fe46dc6SMatthew Dillon 	Blowfish_initstate(c);
5090fe46dc6SMatthew Dillon 
5100fe46dc6SMatthew Dillon 	/* Transform S-boxes and subkeys with key */
5110fe46dc6SMatthew Dillon 	Blowfish_expand0state(c, k, len);
5120fe46dc6SMatthew Dillon }
5130fe46dc6SMatthew Dillon 
5140fe46dc6SMatthew Dillon void
blf_enc(blf_ctx * c,u_int32_t * data,u_int16_t blocks)5150fe46dc6SMatthew Dillon blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
5160fe46dc6SMatthew Dillon {
5170fe46dc6SMatthew Dillon 	u_int32_t *d;
5180fe46dc6SMatthew Dillon 	u_int16_t i;
5190fe46dc6SMatthew Dillon 
5200fe46dc6SMatthew Dillon 	d = data;
5210fe46dc6SMatthew Dillon 	for (i = 0; i < blocks; i++) {
5220fe46dc6SMatthew Dillon 		Blowfish_encipher(c, d, d + 1);
5230fe46dc6SMatthew Dillon 		d += 2;
5240fe46dc6SMatthew Dillon 	}
5250fe46dc6SMatthew Dillon }
5260fe46dc6SMatthew Dillon 
5270fe46dc6SMatthew Dillon void
blf_dec(blf_ctx * c,u_int32_t * data,u_int16_t blocks)5280fe46dc6SMatthew Dillon blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
5290fe46dc6SMatthew Dillon {
5300fe46dc6SMatthew Dillon 	u_int32_t *d;
5310fe46dc6SMatthew Dillon 	u_int16_t i;
5320fe46dc6SMatthew Dillon 
5330fe46dc6SMatthew Dillon 	d = data;
5340fe46dc6SMatthew Dillon 	for (i = 0; i < blocks; i++) {
5350fe46dc6SMatthew Dillon 		Blowfish_decipher(c, d, d + 1);
5360fe46dc6SMatthew Dillon 		d += 2;
5370fe46dc6SMatthew Dillon 	}
5380fe46dc6SMatthew Dillon }
5390fe46dc6SMatthew Dillon 
5400fe46dc6SMatthew Dillon void
blf_ecb_encrypt(blf_ctx * c,u_int8_t * data,u_int32_t len)5410fe46dc6SMatthew Dillon blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
5420fe46dc6SMatthew Dillon {
5430fe46dc6SMatthew Dillon 	u_int32_t l, r;
5440fe46dc6SMatthew Dillon 	u_int32_t i;
5450fe46dc6SMatthew Dillon 
5460fe46dc6SMatthew Dillon 	for (i = 0; i < len; i += 8) {
5470fe46dc6SMatthew Dillon 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
5480fe46dc6SMatthew Dillon 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
5490fe46dc6SMatthew Dillon 		Blowfish_encipher(c, &l, &r);
5500fe46dc6SMatthew Dillon 		data[0] = l >> 24 & 0xff;
5510fe46dc6SMatthew Dillon 		data[1] = l >> 16 & 0xff;
5520fe46dc6SMatthew Dillon 		data[2] = l >> 8 & 0xff;
5530fe46dc6SMatthew Dillon 		data[3] = l & 0xff;
5540fe46dc6SMatthew Dillon 		data[4] = r >> 24 & 0xff;
5550fe46dc6SMatthew Dillon 		data[5] = r >> 16 & 0xff;
5560fe46dc6SMatthew Dillon 		data[6] = r >> 8 & 0xff;
5570fe46dc6SMatthew Dillon 		data[7] = r & 0xff;
5580fe46dc6SMatthew Dillon 		data += 8;
5590fe46dc6SMatthew Dillon 	}
5600fe46dc6SMatthew Dillon }
5610fe46dc6SMatthew Dillon 
5620fe46dc6SMatthew Dillon void
blf_ecb_decrypt(blf_ctx * c,u_int8_t * data,u_int32_t len)5630fe46dc6SMatthew Dillon blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
5640fe46dc6SMatthew Dillon {
5650fe46dc6SMatthew Dillon 	u_int32_t l, r;
5660fe46dc6SMatthew Dillon 	u_int32_t i;
5670fe46dc6SMatthew Dillon 
5680fe46dc6SMatthew Dillon 	for (i = 0; i < len; i += 8) {
5690fe46dc6SMatthew Dillon 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
5700fe46dc6SMatthew Dillon 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
5710fe46dc6SMatthew Dillon 		Blowfish_decipher(c, &l, &r);
5720fe46dc6SMatthew Dillon 		data[0] = l >> 24 & 0xff;
5730fe46dc6SMatthew Dillon 		data[1] = l >> 16 & 0xff;
5740fe46dc6SMatthew Dillon 		data[2] = l >> 8 & 0xff;
5750fe46dc6SMatthew Dillon 		data[3] = l & 0xff;
5760fe46dc6SMatthew Dillon 		data[4] = r >> 24 & 0xff;
5770fe46dc6SMatthew Dillon 		data[5] = r >> 16 & 0xff;
5780fe46dc6SMatthew Dillon 		data[6] = r >> 8 & 0xff;
5790fe46dc6SMatthew Dillon 		data[7] = r & 0xff;
5800fe46dc6SMatthew Dillon 		data += 8;
5810fe46dc6SMatthew Dillon 	}
5820fe46dc6SMatthew Dillon }
5830fe46dc6SMatthew Dillon 
5840fe46dc6SMatthew Dillon void
blf_cbc_encrypt(blf_ctx * c,u_int8_t * iv,u_int8_t * data,u_int32_t len)5850fe46dc6SMatthew Dillon blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len)
5860fe46dc6SMatthew Dillon {
5870fe46dc6SMatthew Dillon 	u_int32_t l, r;
5880fe46dc6SMatthew Dillon 	u_int32_t i, j;
5890fe46dc6SMatthew Dillon 
5900fe46dc6SMatthew Dillon 	for (i = 0; i < len; i += 8) {
5910fe46dc6SMatthew Dillon 		for (j = 0; j < 8; j++)
5920fe46dc6SMatthew Dillon 			data[j] ^= iv[j];
5930fe46dc6SMatthew Dillon 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
5940fe46dc6SMatthew Dillon 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
5950fe46dc6SMatthew Dillon 		Blowfish_encipher(c, &l, &r);
5960fe46dc6SMatthew Dillon 		data[0] = l >> 24 & 0xff;
5970fe46dc6SMatthew Dillon 		data[1] = l >> 16 & 0xff;
5980fe46dc6SMatthew Dillon 		data[2] = l >> 8 & 0xff;
5990fe46dc6SMatthew Dillon 		data[3] = l & 0xff;
6000fe46dc6SMatthew Dillon 		data[4] = r >> 24 & 0xff;
6010fe46dc6SMatthew Dillon 		data[5] = r >> 16 & 0xff;
6020fe46dc6SMatthew Dillon 		data[6] = r >> 8 & 0xff;
6030fe46dc6SMatthew Dillon 		data[7] = r & 0xff;
6040fe46dc6SMatthew Dillon 		iv = data;
6050fe46dc6SMatthew Dillon 		data += 8;
6060fe46dc6SMatthew Dillon 	}
6070fe46dc6SMatthew Dillon }
6080fe46dc6SMatthew Dillon 
6090fe46dc6SMatthew Dillon void
blf_cbc_decrypt(blf_ctx * c,u_int8_t * iva,u_int8_t * data,u_int32_t len)6100fe46dc6SMatthew Dillon blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len)
6110fe46dc6SMatthew Dillon {
6120fe46dc6SMatthew Dillon 	u_int32_t l, r;
6130fe46dc6SMatthew Dillon 	u_int8_t *iv;
6140fe46dc6SMatthew Dillon 	u_int32_t i, j;
6150fe46dc6SMatthew Dillon 
6160fe46dc6SMatthew Dillon 	iv = data + len - 16;
6170fe46dc6SMatthew Dillon 	data = data + len - 8;
6180fe46dc6SMatthew Dillon 	for (i = len - 8; i >= 8; i -= 8) {
6190fe46dc6SMatthew Dillon 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
6200fe46dc6SMatthew Dillon 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
6210fe46dc6SMatthew Dillon 		Blowfish_decipher(c, &l, &r);
6220fe46dc6SMatthew Dillon 		data[0] = l >> 24 & 0xff;
6230fe46dc6SMatthew Dillon 		data[1] = l >> 16 & 0xff;
6240fe46dc6SMatthew Dillon 		data[2] = l >> 8 & 0xff;
6250fe46dc6SMatthew Dillon 		data[3] = l & 0xff;
6260fe46dc6SMatthew Dillon 		data[4] = r >> 24 & 0xff;
6270fe46dc6SMatthew Dillon 		data[5] = r >> 16 & 0xff;
6280fe46dc6SMatthew Dillon 		data[6] = r >> 8 & 0xff;
6290fe46dc6SMatthew Dillon 		data[7] = r & 0xff;
6300fe46dc6SMatthew Dillon 		for (j = 0; j < 8; j++)
6310fe46dc6SMatthew Dillon 			data[j] ^= iv[j];
6320fe46dc6SMatthew Dillon 		iv -= 8;
6330fe46dc6SMatthew Dillon 		data -= 8;
6340fe46dc6SMatthew Dillon 	}
6350fe46dc6SMatthew Dillon 	l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
6360fe46dc6SMatthew Dillon 	r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
6370fe46dc6SMatthew Dillon 	Blowfish_decipher(c, &l, &r);
6380fe46dc6SMatthew Dillon 	data[0] = l >> 24 & 0xff;
6390fe46dc6SMatthew Dillon 	data[1] = l >> 16 & 0xff;
6400fe46dc6SMatthew Dillon 	data[2] = l >> 8 & 0xff;
6410fe46dc6SMatthew Dillon 	data[3] = l & 0xff;
6420fe46dc6SMatthew Dillon 	data[4] = r >> 24 & 0xff;
6430fe46dc6SMatthew Dillon 	data[5] = r >> 16 & 0xff;
6440fe46dc6SMatthew Dillon 	data[6] = r >> 8 & 0xff;
6450fe46dc6SMatthew Dillon 	data[7] = r & 0xff;
6460fe46dc6SMatthew Dillon 	for (j = 0; j < 8; j++)
6470fe46dc6SMatthew Dillon 		data[j] ^= iva[j];
6480fe46dc6SMatthew Dillon }
6490fe46dc6SMatthew Dillon 
6500fe46dc6SMatthew Dillon #if 0
6510fe46dc6SMatthew Dillon void
6520fe46dc6SMatthew Dillon report(u_int32_t data[], u_int16_t len)
6530fe46dc6SMatthew Dillon {
6540fe46dc6SMatthew Dillon 	u_int16_t i;
6550fe46dc6SMatthew Dillon 	for (i = 0; i < len; i += 2)
6560fe46dc6SMatthew Dillon 		printf("Block %0hd: %08lx %08lx.\n",
6570fe46dc6SMatthew Dillon 		    i / 2, data[i], data[i + 1]);
6580fe46dc6SMatthew Dillon }
6590fe46dc6SMatthew Dillon void
6600fe46dc6SMatthew Dillon main(void)
6610fe46dc6SMatthew Dillon {
6620fe46dc6SMatthew Dillon 
6630fe46dc6SMatthew Dillon 	blf_ctx c;
6640fe46dc6SMatthew Dillon 	char    key[] = "AAAAA";
6650fe46dc6SMatthew Dillon 	char    key2[] = "abcdefghijklmnopqrstuvwxyz";
6660fe46dc6SMatthew Dillon 
6670fe46dc6SMatthew Dillon 	u_int32_t data[10];
6680fe46dc6SMatthew Dillon 	u_int32_t data2[] =
6690fe46dc6SMatthew Dillon 	{0x424c4f57l, 0x46495348l};
6700fe46dc6SMatthew Dillon 
6710fe46dc6SMatthew Dillon 	u_int16_t i;
6720fe46dc6SMatthew Dillon 
6730fe46dc6SMatthew Dillon 	/* First test */
6740fe46dc6SMatthew Dillon 	for (i = 0; i < 10; i++)
6750fe46dc6SMatthew Dillon 		data[i] = i;
6760fe46dc6SMatthew Dillon 
6770fe46dc6SMatthew Dillon 	blf_key(&c, (u_int8_t *) key, 5);
6780fe46dc6SMatthew Dillon 	blf_enc(&c, data, 5);
6790fe46dc6SMatthew Dillon 	blf_dec(&c, data, 1);
6800fe46dc6SMatthew Dillon 	blf_dec(&c, data + 2, 4);
6810fe46dc6SMatthew Dillon 	printf("Should read as 0 - 9.\n");
6820fe46dc6SMatthew Dillon 	report(data, 10);
6830fe46dc6SMatthew Dillon 
6840fe46dc6SMatthew Dillon 	/* Second test */
6850fe46dc6SMatthew Dillon 	blf_key(&c, (u_int8_t *) key2, strlen(key2));
6860fe46dc6SMatthew Dillon 	blf_enc(&c, data2, 1);
6870fe46dc6SMatthew Dillon 	printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
6880fe46dc6SMatthew Dillon 	report(data2, 2);
6890fe46dc6SMatthew Dillon 	blf_dec(&c, data2, 1);
6900fe46dc6SMatthew Dillon 	report(data2, 2);
6910fe46dc6SMatthew Dillon }
6920fe46dc6SMatthew Dillon #endif
693