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