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