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