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