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