1 /* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
2 /*
3 * Blowfish block cipher for OpenBSD
4 * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
5 * All rights reserved.
6 *
7 * Implementation advice by David Mazieres <dm@lcs.mit.edu>.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by Niels Provos.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /*
36 * This code is derived from section 14.3 and the given source
37 * in section V of Applied Cryptography, second edition.
38 * Blowfish is an unpatented fast block cipher designed by
39 * Bruce Schneier.
40 */
41
42
43 #if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \
44 !defined(HAVE_BLOWFISH_EXPAND0STATE) || \
45 !defined(HAVE_BLF_ENC))
46
47 #if 0
48 #include <stdio.h> /* used for debugging */
49 #include <string.h>
50 #endif
51
52 #include <sys/types.h>
53
54 #include "libssh2.h"
55 #include "blf.h"
56
57 #undef inline
58 #ifdef __GNUC__
59 #define inline __inline
60 #else /* !__GNUC__ */
61 #define inline
62 #endif /* !__GNUC__ */
63
64 /* Function for Feistel Networks */
65
66 #define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \
67 + (s)[0x100 + (((x)>>16)&0xFF)]) \
68 ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
69 + (s)[0x300 + ( (x) &0xFF)])
70
71 #define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
72
73 void
Blowfish_encipher(blf_ctx * c,uint32_t * xl,uint32_t * xr)74 Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
75 {
76 uint32_t Xl;
77 uint32_t Xr;
78 uint32_t *s = c->S[0];
79 uint32_t *p = c->P;
80
81 Xl = *xl;
82 Xr = *xr;
83
84 Xl ^= p[0];
85 BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
86 BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
87 BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
88 BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
89 BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
90 BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
91 BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
92 BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
93
94 *xl = Xr ^ p[17];
95 *xr = Xl;
96 }
97
98 void
Blowfish_decipher(blf_ctx * c,uint32_t * xl,uint32_t * xr)99 Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
100 {
101 uint32_t Xl;
102 uint32_t Xr;
103 uint32_t *s = c->S[0];
104 uint32_t *p = c->P;
105
106 Xl = *xl;
107 Xr = *xr;
108
109 Xl ^= p[17];
110 BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
111 BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
112 BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
113 BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
114 BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
115 BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
116 BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
117 BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
118
119 *xl = Xr ^ p[0];
120 *xr = Xl;
121 }
122
123 void
Blowfish_initstate(blf_ctx * c)124 Blowfish_initstate(blf_ctx *c)
125 {
126 /* P-box and S-box tables initialized with digits of Pi */
127
128 static const blf_ctx initstate =
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 uint32_t
Blowfish_stream2word(const uint8_t * data,uint16_t databytes,uint16_t * current)403 Blowfish_stream2word(const uint8_t *data, uint16_t databytes,
404 uint16_t *current)
405 {
406 uint8_t i;
407 uint16_t j;
408 uint32_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
Blowfish_expand0state(blf_ctx * c,const uint8_t * key,uint16_t keybytes)424 Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes)
425 {
426 uint16_t i;
427 uint16_t j;
428 uint16_t k;
429 uint32_t temp;
430 uint32_t datal;
431 uint32_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
Blowfish_expandstate(blf_ctx * c,const uint8_t * data,uint16_t databytes,const uint8_t * key,uint16_t keybytes)462 Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes,
463 const uint8_t *key, uint16_t keybytes)
464 {
465 uint16_t i;
466 uint16_t j;
467 uint16_t k;
468 uint32_t temp;
469 uint32_t datal;
470 uint32_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
blf_key(blf_ctx * c,const uint8_t * k,uint16_t len)505 blf_key(blf_ctx *c, const uint8_t *k, uint16_t len)
506 {
507 /* Initialize 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
blf_enc(blf_ctx * c,uint32_t * data,uint16_t blocks)515 blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks)
516 {
517 uint32_t *d;
518 uint16_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
blf_dec(blf_ctx * c,uint32_t * data,uint16_t blocks)528 blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks)
529 {
530 uint32_t *d;
531 uint16_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
blf_ecb_encrypt(blf_ctx * c,uint8_t * data,uint32_t len)541 blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
542 {
543 uint32_t l, r;
544 uint32_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
blf_ecb_decrypt(blf_ctx * c,uint8_t * data,uint32_t len)563 blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
564 {
565 uint32_t l, r;
566 uint32_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
blf_cbc_encrypt(blf_ctx * c,uint8_t * iv,uint8_t * data,uint32_t len)585 blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
586 {
587 uint32_t l, r;
588 uint32_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
blf_cbc_decrypt(blf_ctx * c,uint8_t * iva,uint8_t * data,uint32_t len)610 blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
611 {
612 uint32_t l, r;
613 uint8_t *iv;
614 uint32_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(uint32_t data[], uint16_t len)
653 {
654 uint16_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 uint32_t data[10];
668 uint32_t data2[] =
669 {0x424c4f57l, 0x46495348l};
670
671 uint16_t i;
672
673 /* First test */
674 for(i = 0; i < 10; i++)
675 data[i] = i;
676
677 blf_key(&c, (uint8_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, (uint8_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
693
694 #endif /* !defined(HAVE_BCRYPT_PBKDF) && \
695 (!defined(HAVE_BLOWFISH_INITSTATE) || \
696 !defined(HAVE_BLOWFISH_EXPAND0STATE) || \
697 '!defined(HAVE_BLF_ENC)) */
698