2 * Blowfish implementation for PuTTY.
4 * Coded from scratch from the algorithm description.
12 struct BlowfishContext {
13 word32 S0[256], S1[256], S2[256], S3[256], P[18];
14 word32 iv0, iv1; /* for CBC mode */
18 * The Blowfish init data: hex digits of the fractional part of pi.
19 * (ie pi as a hex fraction is 3.243F6A8885A308D3...)
21 static const word32 parray[] = {
22 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
23 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
24 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B,
27 static const word32 sbox0[] = {
28 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96,
29 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
30 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658,
31 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
32 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E,
33 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
34 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6,
35 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
36 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C,
37 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
38 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1,
39 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
40 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A,
41 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
42 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176,
43 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
44 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706,
45 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
46 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B,
47 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
48 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C,
49 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
50 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A,
51 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
52 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760,
53 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
54 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8,
55 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
56 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33,
57 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
58 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0,
59 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
60 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777,
61 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
62 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705,
63 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
64 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E,
65 0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
66 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9,
67 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
68 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F,
69 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
70 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A,
73 static const word32 sbox1[] = {
74 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D,
75 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
76 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65,
77 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
78 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9,
79 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
80 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D,
81 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
82 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC,
83 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
84 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908,
85 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
86 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124,
87 0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
88 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908,
89 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
90 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B,
91 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
92 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA,
93 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
94 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D,
95 0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
96 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5,
97 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
98 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96,
99 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
100 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA,
101 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
102 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77,
103 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
104 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054,
105 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
106 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA,
107 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
108 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646,
109 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
110 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA,
111 0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
112 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E,
113 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
114 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD,
115 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
116 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7,
119 static const word32 sbox2[] = {
120 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7,
121 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
122 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF,
123 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
124 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4,
125 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
126 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC,
127 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
128 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332,
129 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
130 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58,
131 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
132 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22,
133 0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
134 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60,
135 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
136 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99,
137 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
138 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74,
139 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
140 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3,
141 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
142 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979,
143 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
144 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA,
145 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
146 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086,
147 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
148 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24,
149 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
150 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84,
151 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
152 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09,
153 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
154 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE,
155 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
156 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0,
157 0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
158 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188,
159 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
160 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8,
161 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
162 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0,
165 static const word32 sbox3[] = {
166 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742,
167 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
168 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79,
169 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
170 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A,
171 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
172 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1,
173 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
174 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797,
175 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
176 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6,
177 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
178 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA,
179 0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
180 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5,
181 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
182 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE,
183 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
184 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD,
185 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
186 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB,
187 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
188 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC,
189 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
190 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC,
191 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
192 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A,
193 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
194 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A,
195 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
196 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B,
197 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
198 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E,
199 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
200 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623,
201 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
202 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A,
203 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
204 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3,
205 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
206 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C,
207 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
208 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6,
211 #define Fprime(a,b,c,d) ( ( (S0[a] + S1[b]) ^ S2[c] ) + S3[d] )
212 #define F(x) Fprime( ((x>>24)&0xFF), ((x>>16)&0xFF), ((x>>8)&0xFF), (x&0xFF) )
213 #define ROUND(n) ( xL ^= P[n], t = xL, xL = F(xL) ^ xR, xR = t )
215 static void blowfish_encrypt(word32 xL, word32 xR, word32 * output,
216 BlowfishContext * ctx)
218 word32 *S0 = ctx->S0;
219 word32 *S1 = ctx->S1;
220 word32 *S2 = ctx->S2;
221 word32 *S3 = ctx->S3;
248 static void blowfish_decrypt(word32 xL, word32 xR, word32 * output,
249 BlowfishContext * ctx)
251 word32 *S0 = ctx->S0;
252 word32 *S1 = ctx->S1;
253 word32 *S2 = ctx->S2;
254 word32 *S3 = ctx->S3;
281 static void blowfish_lsb_encrypt_cbc(unsigned char *blk, int len,
282 BlowfishContext * ctx)
284 word32 xL, xR, out[2], iv0, iv1;
286 assert((len & 7) == 0);
292 xL = GET_32BIT_LSB_FIRST(blk);
293 xR = GET_32BIT_LSB_FIRST(blk + 4);
296 blowfish_encrypt(iv0, iv1, out, ctx);
299 PUT_32BIT_LSB_FIRST(blk, iv0);
300 PUT_32BIT_LSB_FIRST(blk + 4, iv1);
309 void blowfish_lsb_encrypt_ecb(unsigned char *blk, int len,
310 BlowfishContext * ctx)
312 word32 xL, xR, out[2];
314 assert((len & 7) == 0);
317 xL = GET_32BIT_LSB_FIRST(blk);
318 xR = GET_32BIT_LSB_FIRST(blk + 4);
319 blowfish_encrypt(xL, xR, out, ctx);
320 PUT_32BIT_LSB_FIRST(blk, out[0]);
321 PUT_32BIT_LSB_FIRST(blk + 4, out[1]);
327 static void blowfish_lsb_decrypt_cbc(unsigned char *blk, int len,
328 BlowfishContext * ctx)
330 word32 xL, xR, out[2], iv0, iv1;
332 assert((len & 7) == 0);
338 xL = GET_32BIT_LSB_FIRST(blk);
339 xR = GET_32BIT_LSB_FIRST(blk + 4);
340 blowfish_decrypt(xL, xR, out, ctx);
343 PUT_32BIT_LSB_FIRST(blk, iv0);
344 PUT_32BIT_LSB_FIRST(blk + 4, iv1);
355 static void blowfish_msb_encrypt_cbc(unsigned char *blk, int len,
356 BlowfishContext * ctx)
358 word32 xL, xR, out[2], iv0, iv1;
360 assert((len & 7) == 0);
366 xL = GET_32BIT_MSB_FIRST(blk);
367 xR = GET_32BIT_MSB_FIRST(blk + 4);
370 blowfish_encrypt(iv0, iv1, out, ctx);
373 PUT_32BIT_MSB_FIRST(blk, iv0);
374 PUT_32BIT_MSB_FIRST(blk + 4, iv1);
383 static void blowfish_msb_decrypt_cbc(unsigned char *blk, int len,
384 BlowfishContext * ctx)
386 word32 xL, xR, out[2], iv0, iv1;
388 assert((len & 7) == 0);
394 xL = GET_32BIT_MSB_FIRST(blk);
395 xR = GET_32BIT_MSB_FIRST(blk + 4);
396 blowfish_decrypt(xL, xR, out, ctx);
399 PUT_32BIT_MSB_FIRST(blk, iv0);
400 PUT_32BIT_MSB_FIRST(blk + 4, iv1);
411 static void blowfish_msb_sdctr(unsigned char *blk, int len,
412 BlowfishContext * ctx)
414 word32 b[2], iv0, iv1, tmp;
416 assert((len & 7) == 0);
422 blowfish_encrypt(iv0, iv1, b, ctx);
423 tmp = GET_32BIT_MSB_FIRST(blk);
424 PUT_32BIT_MSB_FIRST(blk, tmp ^ b[0]);
425 tmp = GET_32BIT_MSB_FIRST(blk + 4);
426 PUT_32BIT_MSB_FIRST(blk + 4, tmp ^ b[1]);
427 if ((iv1 = (iv1 + 1) & 0xffffffff) == 0)
428 iv0 = (iv0 + 1) & 0xffffffff;
437 void blowfish_initkey(BlowfishContext *ctx)
441 for (i = 0; i < 18; i++) {
442 ctx->P[i] = parray[i];
445 for (i = 0; i < 256; i++) {
446 ctx->S0[i] = sbox0[i];
447 ctx->S1[i] = sbox1[i];
448 ctx->S2[i] = sbox2[i];
449 ctx->S3[i] = sbox3[i];
453 void blowfish_expandkey(BlowfishContext * ctx,
454 const unsigned char *key, short keybytes,
455 const unsigned char *salt, short saltbytes)
457 word32 *S0 = ctx->S0;
458 word32 *S1 = ctx->S1;
459 word32 *S2 = ctx->S2;
460 word32 *S3 = ctx->S3;
465 unsigned char dummysalt[1];
474 for (i = 0; i < 18; i++) {
476 ((word32) (unsigned char) (key[(i * 4 + 0) % keybytes])) << 24;
478 ((word32) (unsigned char) (key[(i * 4 + 1) % keybytes])) << 16;
480 ((word32) (unsigned char) (key[(i * 4 + 2) % keybytes])) << 8;
481 P[i] ^= ((word32) (unsigned char) (key[(i * 4 + 3) % keybytes]));
486 for (i = 0; i < 18; i += 2) {
487 for (j = 0; j < 8; j++)
488 str[j/4] ^= ((word32)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
490 blowfish_encrypt(str[0], str[1], str, ctx);
495 for (i = 0; i < 256; i += 2) {
496 for (j = 0; j < 8; j++)
497 str[j/4] ^= ((word32)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
498 blowfish_encrypt(str[0], str[1], str, ctx);
502 for (i = 0; i < 256; i += 2) {
503 for (j = 0; j < 8; j++)
504 str[j/4] ^= ((word32)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
505 blowfish_encrypt(str[0], str[1], str, ctx);
509 for (i = 0; i < 256; i += 2) {
510 for (j = 0; j < 8; j++)
511 str[j/4] ^= ((word32)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
512 blowfish_encrypt(str[0], str[1], str, ctx);
516 for (i = 0; i < 256; i += 2) {
517 for (j = 0; j < 8; j++)
518 str[j/4] ^= ((word32)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
519 blowfish_encrypt(str[0], str[1], str, ctx);
525 static void blowfish_setkey(BlowfishContext *ctx,
526 const unsigned char *key, short keybytes)
528 blowfish_initkey(ctx);
529 blowfish_expandkey(ctx, key, keybytes, NULL, 0);
532 /* -- Interface with PuTTY -- */
534 #define SSH_SESSION_KEY_LENGTH 32
536 void *blowfish_make_context(void)
538 return snew(BlowfishContext);
541 static void *blowfish_ssh1_make_context(void)
543 /* In SSH-1, need one key for each direction */
544 return snewn(2, BlowfishContext);
547 void blowfish_free_context(void *handle)
552 static void blowfish_key(void *handle, unsigned char *key)
554 BlowfishContext *ctx = (BlowfishContext *)handle;
555 blowfish_setkey(ctx, key, 16);
558 static void blowfish256_key(void *handle, unsigned char *key)
560 BlowfishContext *ctx = (BlowfishContext *)handle;
561 blowfish_setkey(ctx, key, 32);
564 static void blowfish_iv(void *handle, unsigned char *key)
566 BlowfishContext *ctx = (BlowfishContext *)handle;
567 ctx->iv0 = GET_32BIT_MSB_FIRST(key);
568 ctx->iv1 = GET_32BIT_MSB_FIRST(key + 4);
571 static void blowfish_sesskey(void *handle, unsigned char *key)
573 BlowfishContext *ctx = (BlowfishContext *)handle;
574 blowfish_setkey(ctx, key, SSH_SESSION_KEY_LENGTH);
577 ctx[1] = ctx[0]; /* structure copy */
580 static void blowfish_ssh1_encrypt_blk(void *handle, unsigned char *blk,
583 BlowfishContext *ctx = (BlowfishContext *)handle;
584 blowfish_lsb_encrypt_cbc(blk, len, ctx);
587 static void blowfish_ssh1_decrypt_blk(void *handle, unsigned char *blk,
590 BlowfishContext *ctx = (BlowfishContext *)handle;
591 blowfish_lsb_decrypt_cbc(blk, len, ctx+1);
594 static void blowfish_ssh2_encrypt_blk(void *handle, unsigned char *blk,
597 BlowfishContext *ctx = (BlowfishContext *)handle;
598 blowfish_msb_encrypt_cbc(blk, len, ctx);
601 static void blowfish_ssh2_decrypt_blk(void *handle, unsigned char *blk,
604 BlowfishContext *ctx = (BlowfishContext *)handle;
605 blowfish_msb_decrypt_cbc(blk, len, ctx);
608 static void blowfish_ssh2_sdctr(void *handle, unsigned char *blk,
611 BlowfishContext *ctx = (BlowfishContext *)handle;
612 blowfish_msb_sdctr(blk, len, ctx);
615 const struct ssh_cipher ssh_blowfish_ssh1 = {
616 blowfish_ssh1_make_context, blowfish_free_context, blowfish_sesskey,
617 blowfish_ssh1_encrypt_blk, blowfish_ssh1_decrypt_blk,
618 8, "Blowfish-128 CBC"
621 static const struct ssh2_cipher ssh_blowfish_ssh2 = {
622 blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish_key,
623 blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk,
625 8, 128, SSH_CIPHER_IS_CBC, "Blowfish-128 CBC"
628 static const struct ssh2_cipher ssh_blowfish_ssh2_ctr = {
629 blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish256_key,
630 blowfish_ssh2_sdctr, blowfish_ssh2_sdctr,
632 8, 256, 0, "Blowfish-256 SDCTR"
635 static const struct ssh2_cipher *const blowfish_list[] = {
636 &ssh_blowfish_ssh2_ctr,
640 const struct ssh2_ciphers ssh2_blowfish = {
641 sizeof(blowfish_list) / sizeof(*blowfish_list),