1 /*
2 * Blowfish implementation for PuTTY.
3 *
4 * Coded from scratch from the algorithm description.
5 */
6
7 #include <assert.h>
8 #include <stdio.h>
9 #include "ssh.h"
10 #include "sshblowf.h"
11
12 struct BlowfishContext {
13 uint32_t S0[256], S1[256], S2[256], S3[256], P[18];
14 uint32_t iv0, iv1; /* for CBC mode */
15 };
16
17 /*
18 * The Blowfish init data: hex digits of the fractional part of pi.
19 * (ie pi as a hex fraction is 3.243F6A8885A308D3...)
20 *
21 * If you have Simon Tatham's 'spigot' exact real calculator
22 * available, or any other method of generating 8336 fractional hex
23 * digits of pi on standard output, you can regenerate these tables
24 * exactly as below using the following Perl script (adjusting the
25 * first line or two if your pi-generator is not spigot).
26
27 open my $spig, "spigot -n -B16 -d8336 pi |";
28 read $spig, $ignore, 2; # throw away the leading "3."
29 for my $name ("parray", "sbox0".."sbox3") {
30 print "static const uint32_t ${name}[] = {\n";
31 my $len = $name eq "parray" ? 18 : 256;
32 for my $i (1..$len) {
33 read $spig, $word, 8;
34 printf "%s0x%s,", ($i%6==1 ? " " : " "), uc $word;
35 print "\n" if ($i == $len || $i%6 == 0);
36 }
37 print "};\n\n";
38 }
39 close $spig;
40
41 */
42 static const uint32_t parray[] = {
43 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0,
44 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
45 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B,
46 };
47
48 static const uint32_t sbox0[] = {
49 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96,
50 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
51 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658,
52 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
53 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E,
54 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
55 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6,
56 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
57 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C,
58 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
59 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1,
60 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
61 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A,
62 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
63 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176,
64 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
65 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706,
66 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
67 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B,
68 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
69 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C,
70 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
71 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A,
72 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
73 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760,
74 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
75 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8,
76 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
77 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33,
78 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
79 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0,
80 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
81 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777,
82 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
83 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705,
84 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
85 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E,
86 0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
87 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9,
88 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
89 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F,
90 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
91 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A,
92 };
93
94 static const uint32_t sbox1[] = {
95 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D,
96 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
97 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65,
98 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
99 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9,
100 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
101 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D,
102 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
103 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC,
104 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
105 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908,
106 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
107 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124,
108 0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
109 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908,
110 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
111 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B,
112 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
113 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA,
114 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
115 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D,
116 0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
117 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5,
118 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
119 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96,
120 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
121 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA,
122 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
123 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77,
124 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
125 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054,
126 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
127 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA,
128 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
129 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646,
130 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
131 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA,
132 0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
133 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E,
134 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
135 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD,
136 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
137 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7,
138 };
139
140 static const uint32_t sbox2[] = {
141 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7,
142 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
143 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF,
144 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
145 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4,
146 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
147 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC,
148 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
149 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332,
150 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
151 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58,
152 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
153 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22,
154 0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
155 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60,
156 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
157 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99,
158 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
159 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74,
160 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
161 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3,
162 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
163 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979,
164 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
165 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA,
166 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
167 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086,
168 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
169 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24,
170 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
171 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84,
172 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
173 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09,
174 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
175 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE,
176 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
177 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0,
178 0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
179 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188,
180 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
181 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8,
182 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
183 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0,
184 };
185
186 static const uint32_t sbox3[] = {
187 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742,
188 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
189 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79,
190 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
191 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A,
192 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
193 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1,
194 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
195 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797,
196 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
197 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6,
198 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
199 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA,
200 0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
201 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5,
202 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
203 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE,
204 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
205 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD,
206 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
207 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB,
208 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
209 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC,
210 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
211 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC,
212 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
213 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A,
214 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
215 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A,
216 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
217 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B,
218 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
219 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E,
220 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
221 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623,
222 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
223 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A,
224 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
225 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3,
226 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
227 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C,
228 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
229 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6,
230 };
231
232 #define Fprime(a,b,c,d) ( ( (S0[a] + S1[b]) ^ S2[c] ) + S3[d] )
233 #define F(x) Fprime( ((x>>24)&0xFF), ((x>>16)&0xFF), ((x>>8)&0xFF), (x&0xFF) )
234 #define ROUND(n) ( xL ^= P[n], t = xL, xL = F(xL) ^ xR, xR = t )
235
blowfish_encrypt(uint32_t xL,uint32_t xR,uint32_t * output,BlowfishContext * ctx)236 static void blowfish_encrypt(uint32_t xL, uint32_t xR, uint32_t *output,
237 BlowfishContext * ctx)
238 {
239 uint32_t *S0 = ctx->S0;
240 uint32_t *S1 = ctx->S1;
241 uint32_t *S2 = ctx->S2;
242 uint32_t *S3 = ctx->S3;
243 uint32_t *P = ctx->P;
244 uint32_t t;
245
246 ROUND(0);
247 ROUND(1);
248 ROUND(2);
249 ROUND(3);
250 ROUND(4);
251 ROUND(5);
252 ROUND(6);
253 ROUND(7);
254 ROUND(8);
255 ROUND(9);
256 ROUND(10);
257 ROUND(11);
258 ROUND(12);
259 ROUND(13);
260 ROUND(14);
261 ROUND(15);
262 xL ^= P[16];
263 xR ^= P[17];
264
265 output[0] = xR;
266 output[1] = xL;
267 }
268
blowfish_decrypt(uint32_t xL,uint32_t xR,uint32_t * output,BlowfishContext * ctx)269 static void blowfish_decrypt(uint32_t xL, uint32_t xR, uint32_t *output,
270 BlowfishContext * ctx)
271 {
272 uint32_t *S0 = ctx->S0;
273 uint32_t *S1 = ctx->S1;
274 uint32_t *S2 = ctx->S2;
275 uint32_t *S3 = ctx->S3;
276 uint32_t *P = ctx->P;
277 uint32_t t;
278
279 ROUND(17);
280 ROUND(16);
281 ROUND(15);
282 ROUND(14);
283 ROUND(13);
284 ROUND(12);
285 ROUND(11);
286 ROUND(10);
287 ROUND(9);
288 ROUND(8);
289 ROUND(7);
290 ROUND(6);
291 ROUND(5);
292 ROUND(4);
293 ROUND(3);
294 ROUND(2);
295 xL ^= P[1];
296 xR ^= P[0];
297
298 output[0] = xR;
299 output[1] = xL;
300 }
301
blowfish_lsb_encrypt_cbc(unsigned char * blk,int len,BlowfishContext * ctx)302 static void blowfish_lsb_encrypt_cbc(unsigned char *blk, int len,
303 BlowfishContext * ctx)
304 {
305 uint32_t xL, xR, out[2], iv0, iv1;
306
307 assert((len & 7) == 0);
308
309 iv0 = ctx->iv0;
310 iv1 = ctx->iv1;
311
312 while (len > 0) {
313 xL = GET_32BIT_LSB_FIRST(blk);
314 xR = GET_32BIT_LSB_FIRST(blk + 4);
315 iv0 ^= xL;
316 iv1 ^= xR;
317 blowfish_encrypt(iv0, iv1, out, ctx);
318 iv0 = out[0];
319 iv1 = out[1];
320 PUT_32BIT_LSB_FIRST(blk, iv0);
321 PUT_32BIT_LSB_FIRST(blk + 4, iv1);
322 blk += 8;
323 len -= 8;
324 }
325
326 ctx->iv0 = iv0;
327 ctx->iv1 = iv1;
328 }
329
blowfish_lsb_encrypt_ecb(void * vblk,int len,BlowfishContext * ctx)330 void blowfish_lsb_encrypt_ecb(void *vblk, int len, BlowfishContext * ctx)
331 {
332 unsigned char *blk = (unsigned char *)vblk;
333 uint32_t xL, xR, out[2];
334
335 assert((len & 7) == 0);
336
337 while (len > 0) {
338 xL = GET_32BIT_LSB_FIRST(blk);
339 xR = GET_32BIT_LSB_FIRST(blk + 4);
340 blowfish_encrypt(xL, xR, out, ctx);
341 PUT_32BIT_LSB_FIRST(blk, out[0]);
342 PUT_32BIT_LSB_FIRST(blk + 4, out[1]);
343 blk += 8;
344 len -= 8;
345 }
346 }
347
blowfish_lsb_decrypt_cbc(unsigned char * blk,int len,BlowfishContext * ctx)348 static void blowfish_lsb_decrypt_cbc(unsigned char *blk, int len,
349 BlowfishContext * ctx)
350 {
351 uint32_t xL, xR, out[2], iv0, iv1;
352
353 assert((len & 7) == 0);
354
355 iv0 = ctx->iv0;
356 iv1 = ctx->iv1;
357
358 while (len > 0) {
359 xL = GET_32BIT_LSB_FIRST(blk);
360 xR = GET_32BIT_LSB_FIRST(blk + 4);
361 blowfish_decrypt(xL, xR, out, ctx);
362 iv0 ^= out[0];
363 iv1 ^= out[1];
364 PUT_32BIT_LSB_FIRST(blk, iv0);
365 PUT_32BIT_LSB_FIRST(blk + 4, iv1);
366 iv0 = xL;
367 iv1 = xR;
368 blk += 8;
369 len -= 8;
370 }
371
372 ctx->iv0 = iv0;
373 ctx->iv1 = iv1;
374 }
375
blowfish_msb_encrypt_cbc(unsigned char * blk,int len,BlowfishContext * ctx)376 static void blowfish_msb_encrypt_cbc(unsigned char *blk, int len,
377 BlowfishContext * ctx)
378 {
379 uint32_t xL, xR, out[2], iv0, iv1;
380
381 assert((len & 7) == 0);
382
383 iv0 = ctx->iv0;
384 iv1 = ctx->iv1;
385
386 while (len > 0) {
387 xL = GET_32BIT_MSB_FIRST(blk);
388 xR = GET_32BIT_MSB_FIRST(blk + 4);
389 iv0 ^= xL;
390 iv1 ^= xR;
391 blowfish_encrypt(iv0, iv1, out, ctx);
392 iv0 = out[0];
393 iv1 = out[1];
394 PUT_32BIT_MSB_FIRST(blk, iv0);
395 PUT_32BIT_MSB_FIRST(blk + 4, iv1);
396 blk += 8;
397 len -= 8;
398 }
399
400 ctx->iv0 = iv0;
401 ctx->iv1 = iv1;
402 }
403
blowfish_msb_decrypt_cbc(unsigned char * blk,int len,BlowfishContext * ctx)404 static void blowfish_msb_decrypt_cbc(unsigned char *blk, int len,
405 BlowfishContext * ctx)
406 {
407 uint32_t xL, xR, out[2], iv0, iv1;
408
409 assert((len & 7) == 0);
410
411 iv0 = ctx->iv0;
412 iv1 = ctx->iv1;
413
414 while (len > 0) {
415 xL = GET_32BIT_MSB_FIRST(blk);
416 xR = GET_32BIT_MSB_FIRST(blk + 4);
417 blowfish_decrypt(xL, xR, out, ctx);
418 iv0 ^= out[0];
419 iv1 ^= out[1];
420 PUT_32BIT_MSB_FIRST(blk, iv0);
421 PUT_32BIT_MSB_FIRST(blk + 4, iv1);
422 iv0 = xL;
423 iv1 = xR;
424 blk += 8;
425 len -= 8;
426 }
427
428 ctx->iv0 = iv0;
429 ctx->iv1 = iv1;
430 }
431
blowfish_msb_sdctr(unsigned char * blk,int len,BlowfishContext * ctx)432 static void blowfish_msb_sdctr(unsigned char *blk, int len,
433 BlowfishContext * ctx)
434 {
435 uint32_t b[2], iv0, iv1, tmp;
436
437 assert((len & 7) == 0);
438
439 iv0 = ctx->iv0;
440 iv1 = ctx->iv1;
441
442 while (len > 0) {
443 blowfish_encrypt(iv0, iv1, b, ctx);
444 tmp = GET_32BIT_MSB_FIRST(blk);
445 PUT_32BIT_MSB_FIRST(blk, tmp ^ b[0]);
446 tmp = GET_32BIT_MSB_FIRST(blk + 4);
447 PUT_32BIT_MSB_FIRST(blk + 4, tmp ^ b[1]);
448 if ((iv1 = (iv1 + 1) & 0xffffffff) == 0)
449 iv0 = (iv0 + 1) & 0xffffffff;
450 blk += 8;
451 len -= 8;
452 }
453
454 ctx->iv0 = iv0;
455 ctx->iv1 = iv1;
456 }
457
blowfish_initkey(BlowfishContext * ctx)458 void blowfish_initkey(BlowfishContext *ctx)
459 {
460 int i;
461
462 for (i = 0; i < 18; i++) {
463 ctx->P[i] = parray[i];
464 }
465
466 for (i = 0; i < 256; i++) {
467 ctx->S0[i] = sbox0[i];
468 ctx->S1[i] = sbox1[i];
469 ctx->S2[i] = sbox2[i];
470 ctx->S3[i] = sbox3[i];
471 }
472 }
473
blowfish_expandkey(BlowfishContext * ctx,const void * vkey,short keybytes,const void * vsalt,short saltbytes)474 void blowfish_expandkey(BlowfishContext * ctx,
475 const void *vkey, short keybytes,
476 const void *vsalt, short saltbytes)
477 {
478 const unsigned char *key = (const unsigned char *)vkey;
479 const unsigned char *salt = (const unsigned char *)vsalt;
480 uint32_t *S0 = ctx->S0;
481 uint32_t *S1 = ctx->S1;
482 uint32_t *S2 = ctx->S2;
483 uint32_t *S3 = ctx->S3;
484 uint32_t *P = ctx->P;
485 uint32_t str[2];
486 int i, j;
487 int saltpos;
488 unsigned char dummysalt[1];
489
490 saltpos = 0;
491 if (!salt) {
492 saltbytes = 1;
493 salt = dummysalt;
494 dummysalt[0] = 0;
495 }
496
497 for (i = 0; i < 18; i++) {
498 P[i] ^=
499 ((uint32_t) (unsigned char) (key[(i * 4 + 0) % keybytes])) << 24;
500 P[i] ^=
501 ((uint32_t) (unsigned char) (key[(i * 4 + 1) % keybytes])) << 16;
502 P[i] ^=
503 ((uint32_t) (unsigned char) (key[(i * 4 + 2) % keybytes])) << 8;
504 P[i] ^= ((uint32_t) (unsigned char) (key[(i * 4 + 3) % keybytes]));
505 }
506
507 str[0] = str[1] = 0;
508
509 for (i = 0; i < 18; i += 2) {
510 for (j = 0; j < 8; j++)
511 str[j/4] ^= ((uint32_t)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
512
513 blowfish_encrypt(str[0], str[1], str, ctx);
514 P[i] = str[0];
515 P[i + 1] = str[1];
516 }
517
518 for (i = 0; i < 256; i += 2) {
519 for (j = 0; j < 8; j++)
520 str[j/4] ^= ((uint32_t)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
521 blowfish_encrypt(str[0], str[1], str, ctx);
522 S0[i] = str[0];
523 S0[i + 1] = str[1];
524 }
525 for (i = 0; i < 256; i += 2) {
526 for (j = 0; j < 8; j++)
527 str[j/4] ^= ((uint32_t)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
528 blowfish_encrypt(str[0], str[1], str, ctx);
529 S1[i] = str[0];
530 S1[i + 1] = str[1];
531 }
532 for (i = 0; i < 256; i += 2) {
533 for (j = 0; j < 8; j++)
534 str[j/4] ^= ((uint32_t)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
535 blowfish_encrypt(str[0], str[1], str, ctx);
536 S2[i] = str[0];
537 S2[i + 1] = str[1];
538 }
539 for (i = 0; i < 256; i += 2) {
540 for (j = 0; j < 8; j++)
541 str[j/4] ^= ((uint32_t)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
542 blowfish_encrypt(str[0], str[1], str, ctx);
543 S3[i] = str[0];
544 S3[i + 1] = str[1];
545 }
546 }
547
blowfish_setkey(BlowfishContext * ctx,const unsigned char * key,short keybytes)548 static void blowfish_setkey(BlowfishContext *ctx,
549 const unsigned char *key, short keybytes)
550 {
551 blowfish_initkey(ctx);
552 blowfish_expandkey(ctx, key, keybytes, NULL, 0);
553 }
554
555 /* -- Interface with PuTTY -- */
556
557 #define SSH1_SESSION_KEY_LENGTH 32
558
blowfish_make_context(void)559 BlowfishContext *blowfish_make_context(void)
560 {
561 return snew(BlowfishContext);
562 }
563
blowfish_free_context(BlowfishContext * ctx)564 void blowfish_free_context(BlowfishContext *ctx)
565 {
566 sfree(ctx);
567 }
568
blowfish_iv_be(BlowfishContext * ctx,const void * viv)569 static void blowfish_iv_be(BlowfishContext *ctx, const void *viv)
570 {
571 const unsigned char *iv = (const unsigned char *)viv;
572 ctx->iv0 = GET_32BIT_MSB_FIRST(iv);
573 ctx->iv1 = GET_32BIT_MSB_FIRST(iv + 4);
574 }
575
blowfish_iv_le(BlowfishContext * ctx,const void * viv)576 static void blowfish_iv_le(BlowfishContext *ctx, const void *viv)
577 {
578 const unsigned char *iv = (const unsigned char *)viv;
579 ctx->iv0 = GET_32BIT_LSB_FIRST(iv);
580 ctx->iv1 = GET_32BIT_LSB_FIRST(iv + 4);
581 }
582
583 struct blowfish_ctx {
584 BlowfishContext context;
585 ssh_cipher ciph;
586 };
587
blowfish_new(const ssh_cipheralg * alg)588 static ssh_cipher *blowfish_new(const ssh_cipheralg *alg)
589 {
590 struct blowfish_ctx *ctx = snew(struct blowfish_ctx);
591 ctx->ciph.vt = alg;
592 return &ctx->ciph;
593 }
594
blowfish_free(ssh_cipher * cipher)595 static void blowfish_free(ssh_cipher *cipher)
596 {
597 struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
598 smemclr(ctx, sizeof(*ctx));
599 sfree(ctx);
600 }
601
blowfish_ssh_setkey(ssh_cipher * cipher,const void * key)602 static void blowfish_ssh_setkey(ssh_cipher *cipher, const void *key)
603 {
604 struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
605 blowfish_setkey(&ctx->context, key, ctx->ciph.vt->padded_keybytes);
606 }
607
blowfish_ssh1_setiv(ssh_cipher * cipher,const void * iv)608 static void blowfish_ssh1_setiv(ssh_cipher *cipher, const void *iv)
609 {
610 struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
611 blowfish_iv_le(&ctx->context, iv);
612 }
613
blowfish_ssh2_setiv(ssh_cipher * cipher,const void * iv)614 static void blowfish_ssh2_setiv(ssh_cipher *cipher, const void *iv)
615 {
616 struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
617 blowfish_iv_be(&ctx->context, iv);
618 }
619
blowfish_ssh1_encrypt_blk(ssh_cipher * cipher,void * blk,int len)620 static void blowfish_ssh1_encrypt_blk(ssh_cipher *cipher, void *blk, int len)
621 {
622 struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
623 blowfish_lsb_encrypt_cbc(blk, len, &ctx->context);
624 }
625
blowfish_ssh1_decrypt_blk(ssh_cipher * cipher,void * blk,int len)626 static void blowfish_ssh1_decrypt_blk(ssh_cipher *cipher, void *blk, int len)
627 {
628 struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
629 blowfish_lsb_decrypt_cbc(blk, len, &ctx->context);
630 }
631
blowfish_ssh2_encrypt_blk(ssh_cipher * cipher,void * blk,int len)632 static void blowfish_ssh2_encrypt_blk(ssh_cipher *cipher, void *blk, int len)
633 {
634 struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
635 blowfish_msb_encrypt_cbc(blk, len, &ctx->context);
636 }
637
blowfish_ssh2_decrypt_blk(ssh_cipher * cipher,void * blk,int len)638 static void blowfish_ssh2_decrypt_blk(ssh_cipher *cipher, void *blk, int len)
639 {
640 struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
641 blowfish_msb_decrypt_cbc(blk, len, &ctx->context);
642 }
643
blowfish_ssh2_sdctr(ssh_cipher * cipher,void * blk,int len)644 static void blowfish_ssh2_sdctr(ssh_cipher *cipher, void *blk, int len)
645 {
646 struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
647 blowfish_msb_sdctr(blk, len, &ctx->context);
648 }
649
650 const ssh_cipheralg ssh_blowfish_ssh1 = {
651 .new = blowfish_new,
652 .free = blowfish_free,
653 .setiv = blowfish_ssh1_setiv,
654 .setkey = blowfish_ssh_setkey,
655 .encrypt = blowfish_ssh1_encrypt_blk,
656 .decrypt = blowfish_ssh1_decrypt_blk,
657 .blksize = 8,
658 .real_keybits = 128,
659 .padded_keybytes = SSH1_SESSION_KEY_LENGTH,
660 .flags = SSH_CIPHER_IS_CBC,
661 .text_name = "Blowfish-256 CBC",
662 };
663
664 const ssh_cipheralg ssh_blowfish_ssh2 = {
665 .new = blowfish_new,
666 .free = blowfish_free,
667 .setiv = blowfish_ssh2_setiv,
668 .setkey = blowfish_ssh_setkey,
669 .encrypt = blowfish_ssh2_encrypt_blk,
670 .decrypt = blowfish_ssh2_decrypt_blk,
671 .ssh2_id = "blowfish-cbc",
672 .blksize = 8,
673 .real_keybits = 128,
674 .padded_keybytes = 16,
675 .flags = SSH_CIPHER_IS_CBC,
676 .text_name = "Blowfish-128 CBC",
677 };
678
679 const ssh_cipheralg ssh_blowfish_ssh2_ctr = {
680 .new = blowfish_new,
681 .free = blowfish_free,
682 .setiv = blowfish_ssh2_setiv,
683 .setkey = blowfish_ssh_setkey,
684 .encrypt = blowfish_ssh2_sdctr,
685 .decrypt = blowfish_ssh2_sdctr,
686 .ssh2_id = "blowfish-ctr",
687 .blksize = 8,
688 .real_keybits = 256,
689 .padded_keybytes = 32,
690 .flags = 0,
691 .text_name = "Blowfish-256 SDCTR",
692 };
693
694 static const ssh_cipheralg *const blowfish_list[] = {
695 &ssh_blowfish_ssh2_ctr,
696 &ssh_blowfish_ssh2
697 };
698
699 const ssh2_ciphers ssh2_blowfish = { lenof(blowfish_list), blowfish_list };
700