11ff130daSDamien Miller /* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
21ff130daSDamien Miller /*
31ff130daSDamien Miller  * Blowfish block cipher for OpenBSD
41ff130daSDamien Miller  * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
51ff130daSDamien Miller  * All rights reserved.
61ff130daSDamien Miller  *
71ff130daSDamien Miller  * Implementation advice by David Mazieres <dm@lcs.mit.edu>.
81ff130daSDamien Miller  *
91ff130daSDamien Miller  * Redistribution and use in source and binary forms, with or without
101ff130daSDamien Miller  * modification, are permitted provided that the following conditions
111ff130daSDamien Miller  * are met:
121ff130daSDamien Miller  * 1. Redistributions of source code must retain the above copyright
131ff130daSDamien Miller  *    notice, this list of conditions and the following disclaimer.
141ff130daSDamien Miller  * 2. Redistributions in binary form must reproduce the above copyright
151ff130daSDamien Miller  *    notice, this list of conditions and the following disclaimer in the
161ff130daSDamien Miller  *    documentation and/or other materials provided with the distribution.
171ff130daSDamien Miller  * 3. All advertising materials mentioning features or use of this software
181ff130daSDamien Miller  *    must display the following acknowledgement:
191ff130daSDamien Miller  *      This product includes software developed by Niels Provos.
201ff130daSDamien Miller  * 4. The name of the author may not be used to endorse or promote products
211ff130daSDamien Miller  *    derived from this software without specific prior written permission.
221ff130daSDamien Miller  *
331ff130daSDamien Miller  */
341ff130daSDamien Miller 
351ff130daSDamien Miller /*
361ff130daSDamien Miller  * This code is derived from section 14.3 and the given source
371ff130daSDamien Miller  * in section V of Applied Cryptography, second edition.
381ff130daSDamien Miller  * Blowfish is an unpatented fast block cipher designed by
391ff130daSDamien Miller  * Bruce Schneier.
401ff130daSDamien Miller  */
411ff130daSDamien Miller 
421ff130daSDamien Miller #include "includes.h"
431ff130daSDamien Miller 
441ff130daSDamien Miller #if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \
451ff130daSDamien Miller     !defined(HAVE_BLOWFISH_EXPAND0STATE) || !defined(HAVE_BLF_ENC))
461ff130daSDamien Miller 
471ff130daSDamien Miller #if 0
481ff130daSDamien Miller #include <stdio.h>		/* used for debugging */
491ff130daSDamien Miller #include <string.h>
501ff130daSDamien Miller #endif
511ff130daSDamien Miller 
521ff130daSDamien Miller #include <sys/types.h>
53*bb99844aSDarren Tucker #ifdef HAVE_BLF_H
541ff130daSDamien Miller #include <blf.h>
55*bb99844aSDarren Tucker #endif
561ff130daSDamien Miller 
571ff130daSDamien Miller #undef inline
581ff130daSDamien Miller #ifdef __GNUC__
591ff130daSDamien Miller #define inline __inline
601ff130daSDamien Miller #else				/* !__GNUC__ */
611ff130daSDamien Miller #define inline
621ff130daSDamien Miller #endif				/* !__GNUC__ */
631ff130daSDamien Miller 
641ff130daSDamien Miller /* Function for Feistel Networks */
651ff130daSDamien Miller 
661ff130daSDamien Miller #define F(s, x) ((((s)[        (((x)>>24)&0xFF)]  \
671ff130daSDamien Miller 		 + (s)[0x100 + (((x)>>16)&0xFF)]) \
681ff130daSDamien Miller 		 ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
691ff130daSDamien Miller 		 + (s)[0x300 + ( (x)     &0xFF)])
701ff130daSDamien Miller 
711ff130daSDamien Miller #define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
721ff130daSDamien Miller 
731ff130daSDamien Miller void
Blowfish_encipher(blf_ctx * c,u_int32_t * xl,u_int32_t * xr)741ff130daSDamien Miller Blowfish_encipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr)
751ff130daSDamien Miller {
761ff130daSDamien Miller 	u_int32_t Xl;
771ff130daSDamien Miller 	u_int32_t Xr;
781ff130daSDamien Miller 	u_int32_t *s = c->S[0];
791ff130daSDamien Miller 	u_int32_t *p = c->P;
801ff130daSDamien Miller 
811ff130daSDamien Miller 	Xl = *xl;
821ff130daSDamien Miller 	Xr = *xr;
831ff130daSDamien Miller 
841ff130daSDamien Miller 	Xl ^= p[0];
851ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
861ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
871ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
881ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
891ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
901ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
911ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
921ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
931ff130daSDamien Miller 
941ff130daSDamien Miller 	*xl = Xr ^ p[17];
951ff130daSDamien Miller 	*xr = Xl;
961ff130daSDamien Miller }
971ff130daSDamien Miller 
981ff130daSDamien Miller void
Blowfish_decipher(blf_ctx * c,u_int32_t * xl,u_int32_t * xr)991ff130daSDamien Miller Blowfish_decipher(blf_ctx *c, u_int32_t *xl, u_int32_t *xr)
1001ff130daSDamien Miller {
1011ff130daSDamien Miller 	u_int32_t Xl;
1021ff130daSDamien Miller 	u_int32_t Xr;
1031ff130daSDamien Miller 	u_int32_t *s = c->S[0];
1041ff130daSDamien Miller 	u_int32_t *p = c->P;
1051ff130daSDamien Miller 
1061ff130daSDamien Miller 	Xl = *xl;
1071ff130daSDamien Miller 	Xr = *xr;
1081ff130daSDamien Miller 
1091ff130daSDamien Miller 	Xl ^= p[17];
1101ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
1111ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
1121ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
1131ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
1141ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
1151ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
1161ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
1171ff130daSDamien Miller 	BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
1181ff130daSDamien Miller 
1191ff130daSDamien Miller 	*xl = Xr ^ p[0];
1201ff130daSDamien Miller 	*xr = Xl;
1211ff130daSDamien Miller }
1221ff130daSDamien Miller 
1231ff130daSDamien Miller void
Blowfish_initstate(blf_ctx * c)1241ff130daSDamien Miller Blowfish_initstate(blf_ctx *c)
1251ff130daSDamien Miller {
1261ff130daSDamien Miller 	/* P-box and S-box tables initialized with digits of Pi */
1271ff130daSDamien Miller 
1281ff130daSDamien Miller 	static const blf_ctx initstate =
1291ff130daSDamien Miller 	{ {
1301ff130daSDamien Miller 		{
1311ff130daSDamien Miller 			0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
1321ff130daSDamien Miller 			0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
1331ff130daSDamien Miller 			0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
1341ff130daSDamien Miller 			0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
1351ff130daSDamien Miller 			0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
1361ff130daSDamien Miller 			0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
1371ff130daSDamien Miller 			0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
1381ff130daSDamien Miller 			0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
1391ff130daSDamien Miller 			0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
1401ff130daSDamien Miller 			0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
1411ff130daSDamien Miller 			0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
1421ff130daSDamien Miller 			0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
1431ff130daSDamien Miller 			0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
1441ff130daSDamien Miller 			0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
1451ff130daSDamien Miller 			0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
1461ff130daSDamien Miller 			0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
1471ff130daSDamien Miller 			0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
1481ff130daSDamien Miller 			0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
1491ff130daSDamien Miller 			0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
1501ff130daSDamien Miller 			0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
1511ff130daSDamien Miller 			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
1521ff130daSDamien Miller 			0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
1531ff130daSDamien Miller 			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
1541ff130daSDamien Miller 			0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
1551ff130daSDamien Miller 			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
1561ff130daSDamien Miller 			0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
1571ff130daSDamien Miller 			0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
1581ff130daSDamien Miller 			0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
1591ff130daSDamien Miller 			0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
1601ff130daSDamien Miller 			0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
1611ff130daSDamien Miller 			0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
1621ff130daSDamien Miller 			0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
1631ff130daSDamien Miller 			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
1641ff130daSDamien Miller 			0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
1651ff130daSDamien Miller 			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
1661ff130daSDamien Miller 			0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
1671ff130daSDamien Miller 			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
1681ff130daSDamien Miller 			0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
1691ff130daSDamien Miller 			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
1701ff130daSDamien Miller 			0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
1711ff130daSDamien Miller 			0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
1721ff130daSDamien Miller 			0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
1731ff130daSDamien Miller 			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
1741ff130daSDamien Miller 			0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
1751ff130daSDamien Miller 			0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
1761ff130daSDamien Miller 			0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
1771ff130daSDamien Miller 			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
1781ff130daSDamien Miller 			0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
1791ff130daSDamien Miller 			0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
1801ff130daSDamien Miller 			0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
1811ff130daSDamien Miller 			0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
1821ff130daSDamien Miller 			0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
1831ff130daSDamien Miller 			0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
1841ff130daSDamien Miller 			0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
1851ff130daSDamien Miller 			0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
1861ff130daSDamien Miller 			0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
1871ff130daSDamien Miller 			0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
1881ff130daSDamien Miller 			0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
1891ff130daSDamien Miller 			0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
1901ff130daSDamien Miller 			0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
1911ff130daSDamien Miller 			0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
1921ff130daSDamien Miller 			0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
1931ff130daSDamien Miller 			0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
1941ff130daSDamien Miller 		0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
1951ff130daSDamien Miller 		{
1961ff130daSDamien Miller 			0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
1971ff130daSDamien Miller 			0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
1981ff130daSDamien Miller 			0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
1991ff130daSDamien Miller 			0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
2001ff130daSDamien Miller 			0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
2011ff130daSDamien Miller 			0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
2021ff130daSDamien Miller 			0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
2031ff130daSDamien Miller 			0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
2041ff130daSDamien Miller 			0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
2051ff130daSDamien Miller 			0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
2061ff130daSDamien Miller 			0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
2071ff130daSDamien Miller 			0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
2081ff130daSDamien Miller 			0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
2091ff130daSDamien Miller 			0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
2101ff130daSDamien Miller 			0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
2111ff130daSDamien Miller 			0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
2121ff130daSDamien Miller 			0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
2131ff130daSDamien Miller 			0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
2141ff130daSDamien Miller 			0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
2151ff130daSDamien Miller 			0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
2161ff130daSDamien Miller 			0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
2171ff130daSDamien Miller 			0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
2181ff130daSDamien Miller 			0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
2191ff130daSDamien Miller 			0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
2201ff130daSDamien Miller 			0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
2211ff130daSDamien Miller 			0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
2221ff130daSDamien Miller 			0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
2231ff130daSDamien Miller 			0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
2241ff130daSDamien Miller 			0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
2251ff130daSDamien Miller 			0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
2261ff130daSDamien Miller 			0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
2271ff130daSDamien Miller 			0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
2281ff130daSDamien Miller 			0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
2291ff130daSDamien Miller 			0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
2301ff130daSDamien Miller 			0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
2311ff130daSDamien Miller 			0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
2321ff130daSDamien Miller 			0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
2331ff130daSDamien Miller 			0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
2341ff130daSDamien Miller 			0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
2351ff130daSDamien Miller 			0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
2361ff130daSDamien Miller 			0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
2371ff130daSDamien Miller 			0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
2381ff130daSDamien Miller 			0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
2391ff130daSDamien Miller 			0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
2401ff130daSDamien Miller 			0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
2411ff130daSDamien Miller 			0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
2421ff130daSDamien Miller 			0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
2431ff130daSDamien Miller 			0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
2441ff130daSDamien Miller 			0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
2451ff130daSDamien Miller 			0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
2461ff130daSDamien Miller 			0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
2471ff130daSDamien Miller 			0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
2481ff130daSDamien Miller 			0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
2491ff130daSDamien Miller 			0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
2501ff130daSDamien Miller 			0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
2511ff130daSDamien Miller 			0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
2521ff130daSDamien Miller 			0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
2531ff130daSDamien Miller 			0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
2541ff130daSDamien Miller 			0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
2551ff130daSDamien Miller 			0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
2561ff130daSDamien Miller 			0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
2571ff130daSDamien Miller 			0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
2581ff130daSDamien Miller 			0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
2591ff130daSDamien Miller 		0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
2601ff130daSDamien Miller 		{
2611ff130daSDamien Miller 			0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
2621ff130daSDamien Miller 			0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
2631ff130daSDamien Miller 			0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
2641ff130daSDamien Miller 			0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
2651ff130daSDamien Miller 			0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
2661ff130daSDamien Miller 			0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
2671ff130daSDamien Miller 			0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
2681ff130daSDamien Miller 			0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
2691ff130daSDamien Miller 			0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
2701ff130daSDamien Miller 			0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
2711ff130daSDamien Miller 			0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
2721ff130daSDamien Miller 			0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
2731ff130daSDamien Miller 			0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
2741ff130daSDamien Miller 			0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
2751ff130daSDamien Miller 			0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
2761ff130daSDamien Miller 			0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
2771ff130daSDamien Miller 			0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
2781ff130daSDamien Miller 			0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
2791ff130daSDamien Miller 			0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
2801ff130daSDamien Miller 			0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
2811ff130daSDamien Miller 			0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
2821ff130daSDamien Miller 			0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
2831ff130daSDamien Miller 			0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
2841ff130daSDamien Miller 			0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
2851ff130daSDamien Miller 			0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
2861ff130daSDamien Miller 			0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
2871ff130daSDamien Miller 			0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
2881ff130daSDamien Miller 			0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
2891ff130daSDamien Miller 			0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
2901ff130daSDamien Miller 			0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
2911ff130daSDamien Miller 			0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
2921ff130daSDamien Miller 			0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
2931ff130daSDamien Miller 			0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
2941ff130daSDamien Miller 			0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
2951ff130daSDamien Miller 			0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
2961ff130daSDamien Miller 			0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
2971ff130daSDamien Miller 			0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
2981ff130daSDamien Miller 			0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
2991ff130daSDamien Miller 			0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
3001ff130daSDamien Miller 			0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
3011ff130daSDamien Miller 			0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
3021ff130daSDamien Miller 			0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
3031ff130daSDamien Miller 			0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
3041ff130daSDamien Miller 			0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
3051ff130daSDamien Miller 			0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
3061ff130daSDamien Miller 			0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
3071ff130daSDamien Miller 			0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
3081ff130daSDamien Miller 			0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
3091ff130daSDamien Miller 			0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
3101ff130daSDamien Miller 			0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
3111ff130daSDamien Miller 			0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
3121ff130daSDamien Miller 			0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
3131ff130daSDamien Miller 			0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
3141ff130daSDamien Miller 			0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
3151ff130daSDamien Miller 			0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
3161ff130daSDamien Miller 			0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
3171ff130daSDamien Miller 			0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
3181ff130daSDamien Miller 			0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
3191ff130daSDamien Miller 			0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
3201ff130daSDamien Miller 			0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
3211ff130daSDamien Miller 			0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
3221ff130daSDamien Miller 			0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
3231ff130daSDamien Miller 			0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
3241ff130daSDamien Miller 		0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
3251ff130daSDamien Miller 		{
3261ff130daSDamien Miller 			0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
3271ff130daSDamien Miller 			0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
3281ff130daSDamien Miller 			0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
3291ff130daSDamien Miller 			0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
3301ff130daSDamien Miller 			0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
3311ff130daSDamien Miller 			0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
3321ff130daSDamien Miller 			0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
3331ff130daSDamien Miller 			0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
3341ff130daSDamien Miller 			0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
3351ff130daSDamien Miller 			0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
3361ff130daSDamien Miller 			0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
3371ff130daSDamien Miller 			0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
3381ff130daSDamien Miller 			0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
3391ff130daSDamien Miller 			0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
3401ff130daSDamien Miller 			0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
3411ff130daSDamien Miller 			0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
3421ff130daSDamien Miller 			0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
3431ff130daSDamien Miller 			0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
3441ff130daSDamien Miller 			0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
3451ff130daSDamien Miller 			0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
3461ff130daSDamien Miller 			0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
3471ff130daSDamien Miller 			0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
3481ff130daSDamien Miller 			0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
3491ff130daSDamien Miller 			0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
3501ff130daSDamien Miller 			0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
3511ff130daSDamien Miller 			0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
3521ff130daSDamien Miller 			0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
3531ff130daSDamien Miller 			0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
3541ff130daSDamien Miller 			0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
3551ff130daSDamien Miller 			0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
3561ff130daSDamien Miller 			0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
3571ff130daSDamien Miller 			0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
3581ff130daSDamien Miller 			0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
3591ff130daSDamien Miller 			0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
3601ff130daSDamien Miller 			0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
3611ff130daSDamien Miller 			0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
3621ff130daSDamien Miller 			0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
3631ff130daSDamien Miller 			0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
3641ff130daSDamien Miller 			0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
3651ff130daSDamien Miller 			0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
3661ff130daSDamien Miller 			0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
3671ff130daSDamien Miller 			0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
3681ff130daSDamien Miller 			0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
3691ff130daSDamien Miller 			0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
3701ff130daSDamien Miller 			0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
3711ff130daSDamien Miller 			0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
3721ff130daSDamien Miller 			0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
3731ff130daSDamien Miller 			0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
3741ff130daSDamien Miller 			0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
3751ff130daSDamien Miller 			0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
3761ff130daSDamien Miller 			0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
3771ff130daSDamien Miller 			0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
3781ff130daSDamien Miller 			0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
3791ff130daSDamien Miller 			0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
3801ff130daSDamien Miller 			0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
3811ff130daSDamien Miller 			0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
3821ff130daSDamien Miller 			0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
3831ff130daSDamien Miller 			0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
3841ff130daSDamien Miller 			0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
3851ff130daSDamien Miller 			0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
3861ff130daSDamien Miller 			0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
3871ff130daSDamien Miller 			0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
3881ff130daSDamien Miller 			0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
3891ff130daSDamien Miller 		0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
3901ff130daSDamien Miller 	},
3911ff130daSDamien Miller 	{
3921ff130daSDamien Miller 		0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
3931ff130daSDamien Miller 		0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
3941ff130daSDamien Miller 		0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
3951ff130daSDamien Miller 		0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
3961ff130daSDamien Miller 		0x9216d5d9, 0x8979fb1b
3971ff130daSDamien Miller 	} };
3981ff130daSDamien Miller 
3991ff130daSDamien Miller 	*c = initstate;
4001ff130daSDamien Miller }
4011ff130daSDamien Miller 
4021ff130daSDamien Miller u_int32_t
Blowfish_stream2word(const u_int8_t * data,u_int16_t databytes,u_int16_t * current)4031ff130daSDamien Miller Blowfish_stream2word(const u_int8_t *data, u_int16_t databytes,
4041ff130daSDamien Miller     u_int16_t *current)
4051ff130daSDamien Miller {
4061ff130daSDamien Miller 	u_int8_t i;
4071ff130daSDamien Miller 	u_int16_t j;
4081ff130daSDamien Miller 	u_int32_t temp;
4091ff130daSDamien Miller 
4101ff130daSDamien Miller 	temp = 0x00000000;
4111ff130daSDamien Miller 	j = *current;
4121ff130daSDamien Miller 
4131ff130daSDamien Miller 	for (i = 0; i < 4; i++, j++) {
4141ff130daSDamien Miller 		if (j >= databytes)
4151ff130daSDamien Miller 			j = 0;
4161ff130daSDamien Miller 		temp = (temp << 8) | data[j];
4171ff130daSDamien Miller 	}
4181ff130daSDamien Miller 
4191ff130daSDamien Miller 	*current = j;
4201ff130daSDamien Miller 	return temp;
4211ff130daSDamien Miller }
4221ff130daSDamien Miller 
4231ff130daSDamien Miller void
Blowfish_expand0state(blf_ctx * c,const u_int8_t * key,u_int16_t keybytes)4241ff130daSDamien Miller Blowfish_expand0state(blf_ctx *c, const u_int8_t *key, u_int16_t keybytes)
4251ff130daSDamien Miller {
4261ff130daSDamien Miller 	u_int16_t i;
4271ff130daSDamien Miller 	u_int16_t j;
4281ff130daSDamien Miller 	u_int16_t k;
4291ff130daSDamien Miller 	u_int32_t temp;
4301ff130daSDamien Miller 	u_int32_t datal;
4311ff130daSDamien Miller 	u_int32_t datar;
4321ff130daSDamien Miller 
4331ff130daSDamien Miller 	j = 0;
4341ff130daSDamien Miller 	for (i = 0; i < BLF_N + 2; i++) {
4351ff130daSDamien Miller 		/* Extract 4 int8 to 1 int32 from keystream */
4361ff130daSDamien Miller 		temp = Blowfish_stream2word(key, keybytes, &j);
4371ff130daSDamien Miller 		c->P[i] = c->P[i] ^ temp;
4381ff130daSDamien Miller 	}
4391ff130daSDamien Miller 
4401ff130daSDamien Miller 	j = 0;
4411ff130daSDamien Miller 	datal = 0x00000000;
4421ff130daSDamien Miller 	datar = 0x00000000;
4431ff130daSDamien Miller 	for (i = 0; i < BLF_N + 2; i += 2) {
4441ff130daSDamien Miller 		Blowfish_encipher(c, &datal, &datar);
4451ff130daSDamien Miller 
4461ff130daSDamien Miller 		c->P[i] = datal;
4471ff130daSDamien Miller 		c->P[i + 1] = datar;
4481ff130daSDamien Miller 	}
4491ff130daSDamien Miller 
4501ff130daSDamien Miller 	for (i = 0; i < 4; i++) {
4511ff130daSDamien Miller 		for (k = 0; k < 256; k += 2) {
4521ff130daSDamien Miller 			Blowfish_encipher(c, &datal, &datar);
4531ff130daSDamien Miller 
4541ff130daSDamien Miller 			c->S[i][k] = datal;
4551ff130daSDamien Miller 			c->S[i][k + 1] = datar;
4561ff130daSDamien Miller 		}
4571ff130daSDamien Miller 	}
4581ff130daSDamien Miller }
4591ff130daSDamien Miller 
4601ff130daSDamien Miller 
4611ff130daSDamien Miller void
Blowfish_expandstate(blf_ctx * c,const u_int8_t * data,u_int16_t databytes,const u_int8_t * key,u_int16_t keybytes)4621ff130daSDamien Miller Blowfish_expandstate(blf_ctx *c, const u_int8_t *data, u_int16_t databytes,
4631ff130daSDamien Miller     const u_int8_t *key, u_int16_t keybytes)
4641ff130daSDamien Miller {
4651ff130daSDamien Miller 	u_int16_t i;
4661ff130daSDamien Miller 	u_int16_t j;
4671ff130daSDamien Miller 	u_int16_t k;
4681ff130daSDamien Miller 	u_int32_t temp;
4691ff130daSDamien Miller 	u_int32_t datal;
4701ff130daSDamien Miller 	u_int32_t datar;
4711ff130daSDamien Miller 
4721ff130daSDamien Miller 	j = 0;
4731ff130daSDamien Miller 	for (i = 0; i < BLF_N + 2; i++) {
4741ff130daSDamien Miller 		/* Extract 4 int8 to 1 int32 from keystream */
4751ff130daSDamien Miller 		temp = Blowfish_stream2word(key, keybytes, &j);
4761ff130daSDamien Miller 		c->P[i] = c->P[i] ^ temp;
4771ff130daSDamien Miller 	}
4781ff130daSDamien Miller 
4791ff130daSDamien Miller 	j = 0;
4801ff130daSDamien Miller 	datal = 0x00000000;
4811ff130daSDamien Miller 	datar = 0x00000000;
4821ff130daSDamien Miller 	for (i = 0; i < BLF_N + 2; i += 2) {
4831ff130daSDamien Miller 		datal ^= Blowfish_stream2word(data, databytes, &j);
4841ff130daSDamien Miller 		datar ^= Blowfish_stream2word(data, databytes, &j);
4851ff130daSDamien Miller 		Blowfish_encipher(c, &datal, &datar);
4861ff130daSDamien Miller 
4871ff130daSDamien Miller 		c->P[i] = datal;
4881ff130daSDamien Miller 		c->P[i + 1] = datar;
4891ff130daSDamien Miller 	}
4901ff130daSDamien Miller 
4911ff130daSDamien Miller 	for (i = 0; i < 4; i++) {
4921ff130daSDamien Miller 		for (k = 0; k < 256; k += 2) {
4931ff130daSDamien Miller 			datal ^= Blowfish_stream2word(data, databytes, &j);
4941ff130daSDamien Miller 			datar ^= Blowfish_stream2word(data, databytes, &j);
4951ff130daSDamien Miller 			Blowfish_encipher(c, &datal, &datar);
4961ff130daSDamien Miller 
4971ff130daSDamien Miller 			c->S[i][k] = datal;
4981ff130daSDamien Miller 			c->S[i][k + 1] = datar;
4991ff130daSDamien Miller 		}
5001ff130daSDamien Miller 	}
5011ff130daSDamien Miller 
5021ff130daSDamien Miller }
5031ff130daSDamien Miller 
5041ff130daSDamien Miller void
blf_key(blf_ctx * c,const u_int8_t * k,u_int16_t len)5051ff130daSDamien Miller blf_key(blf_ctx *c, const u_int8_t *k, u_int16_t len)
5061ff130daSDamien Miller {
5071ff130daSDamien Miller 	/* Initialize S-boxes and subkeys with Pi */
5081ff130daSDamien Miller 	Blowfish_initstate(c);
5091ff130daSDamien Miller 
5101ff130daSDamien Miller 	/* Transform S-boxes and subkeys with key */
5111ff130daSDamien Miller 	Blowfish_expand0state(c, k, len);
5121ff130daSDamien Miller }
5131ff130daSDamien Miller 
5141ff130daSDamien Miller void
blf_enc(blf_ctx * c,u_int32_t * data,u_int16_t blocks)5151ff130daSDamien Miller blf_enc(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
5161ff130daSDamien Miller {
5171ff130daSDamien Miller 	u_int32_t *d;
5181ff130daSDamien Miller 	u_int16_t i;
5191ff130daSDamien Miller 
5201ff130daSDamien Miller 	d = data;
5211ff130daSDamien Miller 	for (i = 0; i < blocks; i++) {
5221ff130daSDamien Miller 		Blowfish_encipher(c, d, d + 1);
5231ff130daSDamien Miller 		d += 2;
5241ff130daSDamien Miller 	}
5251ff130daSDamien Miller }
5261ff130daSDamien Miller 
5271ff130daSDamien Miller void
blf_dec(blf_ctx * c,u_int32_t * data,u_int16_t blocks)5281ff130daSDamien Miller blf_dec(blf_ctx *c, u_int32_t *data, u_int16_t blocks)
5291ff130daSDamien Miller {
5301ff130daSDamien Miller 	u_int32_t *d;
5311ff130daSDamien Miller 	u_int16_t i;
5321ff130daSDamien Miller 
5331ff130daSDamien Miller 	d = data;
5341ff130daSDamien Miller 	for (i = 0; i < blocks; i++) {
5351ff130daSDamien Miller 		Blowfish_decipher(c, d, d + 1);
5361ff130daSDamien Miller 		d += 2;
5371ff130daSDamien Miller 	}
5381ff130daSDamien Miller }
5391ff130daSDamien Miller 
5401ff130daSDamien Miller void
blf_ecb_encrypt(blf_ctx * c,u_int8_t * data,u_int32_t len)5411ff130daSDamien Miller blf_ecb_encrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
5421ff130daSDamien Miller {
5431ff130daSDamien Miller 	u_int32_t l, r;
5441ff130daSDamien Miller 	u_int32_t i;
5451ff130daSDamien Miller 
5461ff130daSDamien Miller 	for (i = 0; i < len; i += 8) {
5471ff130daSDamien Miller 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
5481ff130daSDamien Miller 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
5491ff130daSDamien Miller 		Blowfish_encipher(c, &l, &r);
5501ff130daSDamien Miller 		data[0] = l >> 24 & 0xff;
5511ff130daSDamien Miller 		data[1] = l >> 16 & 0xff;
5521ff130daSDamien Miller 		data[2] = l >> 8 & 0xff;
5531ff130daSDamien Miller 		data[3] = l & 0xff;
5541ff130daSDamien Miller 		data[4] = r >> 24 & 0xff;
5551ff130daSDamien Miller 		data[5] = r >> 16 & 0xff;
5561ff130daSDamien Miller 		data[6] = r >> 8 & 0xff;
5571ff130daSDamien Miller 		data[7] = r & 0xff;
5581ff130daSDamien Miller 		data += 8;
5591ff130daSDamien Miller 	}
5601ff130daSDamien Miller }
5611ff130daSDamien Miller 
5621ff130daSDamien Miller void
blf_ecb_decrypt(blf_ctx * c,u_int8_t * data,u_int32_t len)5631ff130daSDamien Miller blf_ecb_decrypt(blf_ctx *c, u_int8_t *data, u_int32_t len)
5641ff130daSDamien Miller {
5651ff130daSDamien Miller 	u_int32_t l, r;
5661ff130daSDamien Miller 	u_int32_t i;
5671ff130daSDamien Miller 
5681ff130daSDamien Miller 	for (i = 0; i < len; i += 8) {
5691ff130daSDamien Miller 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
5701ff130daSDamien Miller 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
5711ff130daSDamien Miller 		Blowfish_decipher(c, &l, &r);
5721ff130daSDamien Miller 		data[0] = l >> 24 & 0xff;
5731ff130daSDamien Miller 		data[1] = l >> 16 & 0xff;
5741ff130daSDamien Miller 		data[2] = l >> 8 & 0xff;
5751ff130daSDamien Miller 		data[3] = l & 0xff;
5761ff130daSDamien Miller 		data[4] = r >> 24 & 0xff;
5771ff130daSDamien Miller 		data[5] = r >> 16 & 0xff;
5781ff130daSDamien Miller 		data[6] = r >> 8 & 0xff;
5791ff130daSDamien Miller 		data[7] = r & 0xff;
5801ff130daSDamien Miller 		data += 8;
5811ff130daSDamien Miller 	}
5821ff130daSDamien Miller }
5831ff130daSDamien Miller 
5841ff130daSDamien Miller void
blf_cbc_encrypt(blf_ctx * c,u_int8_t * iv,u_int8_t * data,u_int32_t len)5851ff130daSDamien Miller blf_cbc_encrypt(blf_ctx *c, u_int8_t *iv, u_int8_t *data, u_int32_t len)
5861ff130daSDamien Miller {
5871ff130daSDamien Miller 	u_int32_t l, r;
5881ff130daSDamien Miller 	u_int32_t i, j;
5891ff130daSDamien Miller 
5901ff130daSDamien Miller 	for (i = 0; i < len; i += 8) {
5911ff130daSDamien Miller 		for (j = 0; j < 8; j++)
5921ff130daSDamien Miller 			data[j] ^= iv[j];
5931ff130daSDamien Miller 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
5941ff130daSDamien Miller 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
5951ff130daSDamien Miller 		Blowfish_encipher(c, &l, &r);
5961ff130daSDamien Miller 		data[0] = l >> 24 & 0xff;
5971ff130daSDamien Miller 		data[1] = l >> 16 & 0xff;
5981ff130daSDamien Miller 		data[2] = l >> 8 & 0xff;
5991ff130daSDamien Miller 		data[3] = l & 0xff;
6001ff130daSDamien Miller 		data[4] = r >> 24 & 0xff;
6011ff130daSDamien Miller 		data[5] = r >> 16 & 0xff;
6021ff130daSDamien Miller 		data[6] = r >> 8 & 0xff;
6031ff130daSDamien Miller 		data[7] = r & 0xff;
6041ff130daSDamien Miller 		iv = data;
6051ff130daSDamien Miller 		data += 8;
6061ff130daSDamien Miller 	}
6071ff130daSDamien Miller }
6081ff130daSDamien Miller 
6091ff130daSDamien Miller void
blf_cbc_decrypt(blf_ctx * c,u_int8_t * iva,u_int8_t * data,u_int32_t len)6101ff130daSDamien Miller blf_cbc_decrypt(blf_ctx *c, u_int8_t *iva, u_int8_t *data, u_int32_t len)
6111ff130daSDamien Miller {
6121ff130daSDamien Miller 	u_int32_t l, r;
6131ff130daSDamien Miller 	u_int8_t *iv;
6141ff130daSDamien Miller 	u_int32_t i, j;
6151ff130daSDamien Miller 
6161ff130daSDamien Miller 	iv = data + len - 16;
6171ff130daSDamien Miller 	data = data + len - 8;
6181ff130daSDamien Miller 	for (i = len - 8; i >= 8; i -= 8) {
6191ff130daSDamien Miller 		l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
6201ff130daSDamien Miller 		r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
6211ff130daSDamien Miller 		Blowfish_decipher(c, &l, &r);
6221ff130daSDamien Miller 		data[0] = l >> 24 & 0xff;
6231ff130daSDamien Miller 		data[1] = l >> 16 & 0xff;
6241ff130daSDamien Miller 		data[2] = l >> 8 & 0xff;
6251ff130daSDamien Miller 		data[3] = l & 0xff;
6261ff130daSDamien Miller 		data[4] = r >> 24 & 0xff;
6271ff130daSDamien Miller 		data[5] = r >> 16 & 0xff;
6281ff130daSDamien Miller 		data[6] = r >> 8 & 0xff;
6291ff130daSDamien Miller 		data[7] = r & 0xff;
6301ff130daSDamien Miller 		for (j = 0; j < 8; j++)
6311ff130daSDamien Miller 			data[j] ^= iv[j];
6321ff130daSDamien Miller 		iv -= 8;
6331ff130daSDamien Miller 		data -= 8;
6341ff130daSDamien Miller 	}
6351ff130daSDamien Miller 	l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
6361ff130daSDamien Miller 	r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
6371ff130daSDamien Miller 	Blowfish_decipher(c, &l, &r);
6381ff130daSDamien Miller 	data[0] = l >> 24 & 0xff;
6391ff130daSDamien Miller 	data[1] = l >> 16 & 0xff;
6401ff130daSDamien Miller 	data[2] = l >> 8 & 0xff;
6411ff130daSDamien Miller 	data[3] = l & 0xff;
6421ff130daSDamien Miller 	data[4] = r >> 24 & 0xff;
6431ff130daSDamien Miller 	data[5] = r >> 16 & 0xff;
6441ff130daSDamien Miller 	data[6] = r >> 8 & 0xff;
6451ff130daSDamien Miller 	data[7] = r & 0xff;
6461ff130daSDamien Miller 	for (j = 0; j < 8; j++)
6471ff130daSDamien Miller 		data[j] ^= iva[j];
6481ff130daSDamien Miller }
6491ff130daSDamien Miller 
6501ff130daSDamien Miller #if 0
6511ff130daSDamien Miller void
6521ff130daSDamien Miller report(u_int32_t data[], u_int16_t len)
6531ff130daSDamien Miller {
6541ff130daSDamien Miller 	u_int16_t i;
6551ff130daSDamien Miller 	for (i = 0; i < len; i += 2)
6561ff130daSDamien Miller 		printf("Block %0hd: %08lx %08lx.\n",
6571ff130daSDamien Miller 		    i / 2, data[i], data[i + 1]);
6581ff130daSDamien Miller }
6591ff130daSDamien Miller void
6601ff130daSDamien Miller main(void)
6611ff130daSDamien Miller {
6621ff130daSDamien Miller 
6631ff130daSDamien Miller 	blf_ctx c;
6641ff130daSDamien Miller 	char    key[] = "AAAAA";
6651ff130daSDamien Miller 	char    key2[] = "abcdefghijklmnopqrstuvwxyz";
6661ff130daSDamien Miller 
6671ff130daSDamien Miller 	u_int32_t data[10];
6681ff130daSDamien Miller 	u_int32_t data2[] =
6691ff130daSDamien Miller 	{0x424c4f57l, 0x46495348l};
6701ff130daSDamien Miller 
6711ff130daSDamien Miller 	u_int16_t i;
6721ff130daSDamien Miller 
6731ff130daSDamien Miller 	/* First test */
6741ff130daSDamien Miller 	for (i = 0; i < 10; i++)
6751ff130daSDamien Miller 		data[i] = i;
6761ff130daSDamien Miller 
6771ff130daSDamien Miller 	blf_key(&c, (u_int8_t *) key, 5);
6781ff130daSDamien Miller 	blf_enc(&c, data, 5);
6791ff130daSDamien Miller 	blf_dec(&c, data, 1);
6801ff130daSDamien Miller 	blf_dec(&c, data + 2, 4);
6811ff130daSDamien Miller 	printf("Should read as 0 - 9.\n");
6821ff130daSDamien Miller 	report(data, 10);
6831ff130daSDamien Miller 
6841ff130daSDamien Miller 	/* Second test */
6851ff130daSDamien Miller 	blf_key(&c, (u_int8_t *) key2, strlen(key2));
6861ff130daSDamien Miller 	blf_enc(&c, data2, 1);
6871ff130daSDamien Miller 	printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
6881ff130daSDamien Miller 	report(data2, 2);
6891ff130daSDamien Miller 	blf_dec(&c, data2, 1);
6901ff130daSDamien Miller 	report(data2, 2);
6911ff130daSDamien Miller }
6921ff130daSDamien Miller #endif
6931ff130daSDamien Miller 
6941ff130daSDamien Miller #endif /* !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \
6951ff130daSDamien Miller     !defined(HAVE_BLOWFISH_EXPAND0STATE) || !defined(HAVE_BLF_ENC)) */
6961ff130daSDamien Miller