1 /*
2  * Butchered version of sshblowf.c from putty-0.59.
3  *
4  * contrib/pgcrypto/blf.c
5  */
6 
7 /*
8  * PuTTY is copyright 1997-2007 Simon Tatham.
9  *
10  * Portions copyright Robert de Bath, Joris van Rantwijk, Delian
11  * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
12  * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
13  * Kuhn, and CORE SDI S.A.
14  *
15  * Permission is hereby granted, free of charge, to any person
16  * obtaining a copy of this software and associated documentation files
17  * (the "Software"), to deal in the Software without restriction,
18  * including without limitation the rights to use, copy, modify, merge,
19  * publish, distribute, sublicense, and/or sell copies of the Software,
20  * and to permit persons to whom the Software is furnished to do so,
21  * subject to the following conditions:
22  *
23  * The above copyright notice and this permission notice shall be
24  * included in all copies or substantial portions of the Software.
25  *
26  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29  * NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
30  * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
31  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33  */
34 
35 /*
36  * Blowfish implementation for PuTTY.
37  *
38  * Coded from scratch from the algorithm description.
39  */
40 
41 #include "postgres.h"
42 #include "blf.h"
43 
44 #define GET_32BIT_MSB_FIRST(p) ( \
45 	((p)[0] << 24) | ((p)[1] << 16) | ((p)[2] << 8) | ((p)[3]) )
46 
47 #define PUT_32BIT_MSB_FIRST(p, v) do { \
48 	(p)[0] = v >> 24; \
49 	(p)[1] = v >> 16; \
50 	(p)[2] = v >> 8; \
51 	(p)[3] = v; \
52 } while (0)
53 
54 /*
55  * The Blowfish init data: hex digits of the fractional part of pi.
56  * (ie pi as a hex fraction is 3.243F6A8885A308D3...)
57  */
58 static const uint32 parray[] = {
59 	0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
60 	0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
61 	0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B,
62 };
63 
64 static const uint32 sbox0[] = {
65 	0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96,
66 	0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
67 	0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658,
68 	0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
69 	0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E,
70 	0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
71 	0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6,
72 	0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
73 	0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C,
74 	0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
75 	0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1,
76 	0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
77 	0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A,
78 	0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
79 	0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176,
80 	0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
81 	0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706,
82 	0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
83 	0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B,
84 	0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
85 	0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C,
86 	0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
87 	0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A,
88 	0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
89 	0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760,
90 	0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
91 	0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8,
92 	0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
93 	0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33,
94 	0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
95 	0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0,
96 	0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
97 	0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777,
98 	0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
99 	0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705,
100 	0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
101 	0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E,
102 	0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
103 	0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9,
104 	0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
105 	0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F,
106 	0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
107 	0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A,
108 };
109 
110 static const uint32 sbox1[] = {
111 	0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D,
112 	0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
113 	0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65,
114 	0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
115 	0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9,
116 	0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
117 	0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D,
118 	0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
119 	0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC,
120 	0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
121 	0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908,
122 	0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
123 	0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124,
124 	0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
125 	0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908,
126 	0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
127 	0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B,
128 	0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
129 	0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA,
130 	0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
131 	0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D,
132 	0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
133 	0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5,
134 	0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
135 	0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96,
136 	0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
137 	0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA,
138 	0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
139 	0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77,
140 	0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
141 	0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054,
142 	0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
143 	0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA,
144 	0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
145 	0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646,
146 	0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
147 	0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA,
148 	0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
149 	0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E,
150 	0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
151 	0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD,
152 	0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
153 	0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7,
154 };
155 
156 static const uint32 sbox2[] = {
157 	0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7,
158 	0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
159 	0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF,
160 	0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
161 	0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4,
162 	0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
163 	0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC,
164 	0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
165 	0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332,
166 	0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
167 	0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58,
168 	0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
169 	0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22,
170 	0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
171 	0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60,
172 	0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
173 	0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99,
174 	0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
175 	0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74,
176 	0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
177 	0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3,
178 	0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
179 	0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979,
180 	0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
181 	0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA,
182 	0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
183 	0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086,
184 	0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
185 	0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24,
186 	0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
187 	0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84,
188 	0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
189 	0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09,
190 	0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
191 	0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE,
192 	0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
193 	0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0,
194 	0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
195 	0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188,
196 	0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
197 	0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8,
198 	0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
199 	0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0,
200 };
201 
202 static const uint32 sbox3[] = {
203 	0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742,
204 	0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
205 	0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79,
206 	0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
207 	0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A,
208 	0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
209 	0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1,
210 	0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
211 	0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797,
212 	0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
213 	0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6,
214 	0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
215 	0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA,
216 	0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
217 	0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5,
218 	0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
219 	0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE,
220 	0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
221 	0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD,
222 	0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
223 	0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB,
224 	0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
225 	0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC,
226 	0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
227 	0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC,
228 	0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
229 	0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A,
230 	0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
231 	0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A,
232 	0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
233 	0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B,
234 	0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
235 	0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E,
236 	0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
237 	0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623,
238 	0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
239 	0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A,
240 	0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
241 	0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3,
242 	0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
243 	0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C,
244 	0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
245 	0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6,
246 };
247 
248 #define Fprime(a,b,c,d) ( ( (S0[a] + S1[b]) ^ S2[c] ) + S3[d] )
249 #define F(x) Fprime( ((x>>24)&0xFF), ((x>>16)&0xFF), ((x>>8)&0xFF), (x&0xFF) )
250 #define ROUND(n) ( xL ^= P[n], t = xL, xL = F(xL) ^ xR, xR = t )
251 
252 static void
blowfish_encrypt(uint32 xL,uint32 xR,uint32 * output,BlowfishContext * ctx)253 blowfish_encrypt(uint32 xL, uint32 xR, uint32 *output,
254 				 BlowfishContext *ctx)
255 {
256 	uint32	   *S0 = ctx->S0;
257 	uint32	   *S1 = ctx->S1;
258 	uint32	   *S2 = ctx->S2;
259 	uint32	   *S3 = ctx->S3;
260 	uint32	   *P = ctx->P;
261 	uint32		t;
262 
263 	ROUND(0);
264 	ROUND(1);
265 	ROUND(2);
266 	ROUND(3);
267 	ROUND(4);
268 	ROUND(5);
269 	ROUND(6);
270 	ROUND(7);
271 	ROUND(8);
272 	ROUND(9);
273 	ROUND(10);
274 	ROUND(11);
275 	ROUND(12);
276 	ROUND(13);
277 	ROUND(14);
278 	ROUND(15);
279 	xL ^= P[16];
280 	xR ^= P[17];
281 
282 	output[0] = xR;
283 	output[1] = xL;
284 }
285 
286 static void
blowfish_decrypt(uint32 xL,uint32 xR,uint32 * output,BlowfishContext * ctx)287 blowfish_decrypt(uint32 xL, uint32 xR, uint32 *output,
288 				 BlowfishContext *ctx)
289 {
290 	uint32	   *S0 = ctx->S0;
291 	uint32	   *S1 = ctx->S1;
292 	uint32	   *S2 = ctx->S2;
293 	uint32	   *S3 = ctx->S3;
294 	uint32	   *P = ctx->P;
295 	uint32		t;
296 
297 	ROUND(17);
298 	ROUND(16);
299 	ROUND(15);
300 	ROUND(14);
301 	ROUND(13);
302 	ROUND(12);
303 	ROUND(11);
304 	ROUND(10);
305 	ROUND(9);
306 	ROUND(8);
307 	ROUND(7);
308 	ROUND(6);
309 	ROUND(5);
310 	ROUND(4);
311 	ROUND(3);
312 	ROUND(2);
313 	xL ^= P[1];
314 	xR ^= P[0];
315 
316 	output[0] = xR;
317 	output[1] = xL;
318 }
319 
320 void
blowfish_encrypt_cbc(uint8 * blk,int len,BlowfishContext * ctx)321 blowfish_encrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx)
322 {
323 	uint32		xL,
324 				xR,
325 				out[2],
326 				iv0,
327 				iv1;
328 
329 	Assert((len & 7) == 0);
330 
331 	iv0 = ctx->iv0;
332 	iv1 = ctx->iv1;
333 
334 	while (len > 0)
335 	{
336 		xL = GET_32BIT_MSB_FIRST(blk);
337 		xR = GET_32BIT_MSB_FIRST(blk + 4);
338 		iv0 ^= xL;
339 		iv1 ^= xR;
340 		blowfish_encrypt(iv0, iv1, out, ctx);
341 		iv0 = out[0];
342 		iv1 = out[1];
343 		PUT_32BIT_MSB_FIRST(blk, iv0);
344 		PUT_32BIT_MSB_FIRST(blk + 4, iv1);
345 		blk += 8;
346 		len -= 8;
347 	}
348 
349 	ctx->iv0 = iv0;
350 	ctx->iv1 = iv1;
351 }
352 
353 void
blowfish_decrypt_cbc(uint8 * blk,int len,BlowfishContext * ctx)354 blowfish_decrypt_cbc(uint8 *blk, int len, BlowfishContext *ctx)
355 {
356 	uint32		xL,
357 				xR,
358 				out[2],
359 				iv0,
360 				iv1;
361 
362 	Assert((len & 7) == 0);
363 
364 	iv0 = ctx->iv0;
365 	iv1 = ctx->iv1;
366 
367 	while (len > 0)
368 	{
369 		xL = GET_32BIT_MSB_FIRST(blk);
370 		xR = GET_32BIT_MSB_FIRST(blk + 4);
371 		blowfish_decrypt(xL, xR, out, ctx);
372 		iv0 ^= out[0];
373 		iv1 ^= out[1];
374 		PUT_32BIT_MSB_FIRST(blk, iv0);
375 		PUT_32BIT_MSB_FIRST(blk + 4, iv1);
376 		iv0 = xL;
377 		iv1 = xR;
378 		blk += 8;
379 		len -= 8;
380 	}
381 
382 	ctx->iv0 = iv0;
383 	ctx->iv1 = iv1;
384 }
385 
386 void
blowfish_encrypt_ecb(uint8 * blk,int len,BlowfishContext * ctx)387 blowfish_encrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx)
388 {
389 	uint32		xL,
390 				xR,
391 				out[2];
392 
393 	Assert((len & 7) == 0);
394 
395 	while (len > 0)
396 	{
397 		xL = GET_32BIT_MSB_FIRST(blk);
398 		xR = GET_32BIT_MSB_FIRST(blk + 4);
399 		blowfish_encrypt(xL, xR, out, ctx);
400 		PUT_32BIT_MSB_FIRST(blk, out[0]);
401 		PUT_32BIT_MSB_FIRST(blk + 4, out[1]);
402 		blk += 8;
403 		len -= 8;
404 	}
405 }
406 
407 void
blowfish_decrypt_ecb(uint8 * blk,int len,BlowfishContext * ctx)408 blowfish_decrypt_ecb(uint8 *blk, int len, BlowfishContext *ctx)
409 {
410 	uint32		xL,
411 				xR,
412 				out[2];
413 
414 	Assert((len & 7) == 0);
415 
416 	while (len > 0)
417 	{
418 		xL = GET_32BIT_MSB_FIRST(blk);
419 		xR = GET_32BIT_MSB_FIRST(blk + 4);
420 		blowfish_decrypt(xL, xR, out, ctx);
421 		PUT_32BIT_MSB_FIRST(blk, out[0]);
422 		PUT_32BIT_MSB_FIRST(blk + 4, out[1]);
423 		blk += 8;
424 		len -= 8;
425 	}
426 }
427 
428 void
blowfish_setkey(BlowfishContext * ctx,const uint8 * key,short keybytes)429 blowfish_setkey(BlowfishContext *ctx,
430 				const uint8 *key, short keybytes)
431 {
432 	uint32	   *S0 = ctx->S0;
433 	uint32	   *S1 = ctx->S1;
434 	uint32	   *S2 = ctx->S2;
435 	uint32	   *S3 = ctx->S3;
436 	uint32	   *P = ctx->P;
437 	uint32		str[2];
438 	int			i;
439 
440 	Assert(keybytes > 0 && keybytes <= (448 / 8));
441 
442 	for (i = 0; i < 18; i++)
443 	{
444 		P[i] = parray[i];
445 		P[i] ^= ((uint32) key[(i * 4 + 0) % keybytes]) << 24;
446 		P[i] ^= ((uint32) key[(i * 4 + 1) % keybytes]) << 16;
447 		P[i] ^= ((uint32) key[(i * 4 + 2) % keybytes]) << 8;
448 		P[i] ^= ((uint32) key[(i * 4 + 3) % keybytes]);
449 	}
450 
451 	for (i = 0; i < 256; i++)
452 	{
453 		S0[i] = sbox0[i];
454 		S1[i] = sbox1[i];
455 		S2[i] = sbox2[i];
456 		S3[i] = sbox3[i];
457 	}
458 
459 	str[0] = str[1] = 0;
460 
461 	for (i = 0; i < 18; i += 2)
462 	{
463 		blowfish_encrypt(str[0], str[1], str, ctx);
464 		P[i] = str[0];
465 		P[i + 1] = str[1];
466 	}
467 
468 	for (i = 0; i < 256; i += 2)
469 	{
470 		blowfish_encrypt(str[0], str[1], str, ctx);
471 		S0[i] = str[0];
472 		S0[i + 1] = str[1];
473 	}
474 	for (i = 0; i < 256; i += 2)
475 	{
476 		blowfish_encrypt(str[0], str[1], str, ctx);
477 		S1[i] = str[0];
478 		S1[i + 1] = str[1];
479 	}
480 	for (i = 0; i < 256; i += 2)
481 	{
482 		blowfish_encrypt(str[0], str[1], str, ctx);
483 		S2[i] = str[0];
484 		S2[i + 1] = str[1];
485 	}
486 	for (i = 0; i < 256; i += 2)
487 	{
488 		blowfish_encrypt(str[0], str[1], str, ctx);
489 		S3[i] = str[0];
490 		S3[i + 1] = str[1];
491 	}
492 }
493 
494 void
blowfish_setiv(BlowfishContext * ctx,const uint8 * iv)495 blowfish_setiv(BlowfishContext *ctx, const uint8 *iv)
496 {
497 	ctx->iv0 = GET_32BIT_MSB_FIRST(iv);
498 	ctx->iv1 = GET_32BIT_MSB_FIRST(iv + 4);
499 }
500