]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - sshblowf.c
first pass
[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 #include "sshblowf.h"
11
12 struct BlowfishContext {
13     word32 S0[256], S1[256], S2[256], S3[256], P[18];
14     word32 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 word32 ${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 word32 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 word32 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 word32 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 word32 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 word32 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
236 static void blowfish_encrypt(word32 xL, word32 xR, word32 * output,
237                              BlowfishContext * ctx)
238 {
239     word32 *S0 = ctx->S0;
240     word32 *S1 = ctx->S1;
241     word32 *S2 = ctx->S2;
242     word32 *S3 = ctx->S3;
243     word32 *P = ctx->P;
244     word32 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
269 static void blowfish_decrypt(word32 xL, word32 xR, word32 * output,
270                              BlowfishContext * ctx)
271 {
272     word32 *S0 = ctx->S0;
273     word32 *S1 = ctx->S1;
274     word32 *S2 = ctx->S2;
275     word32 *S3 = ctx->S3;
276     word32 *P = ctx->P;
277     word32 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
302 static void blowfish_lsb_encrypt_cbc(unsigned char *blk, int len,
303                                      BlowfishContext * ctx)
304 {
305     word32 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
330 void blowfish_lsb_encrypt_ecb(unsigned char *blk, int len,
331                               BlowfishContext * ctx)
332 {
333     word32 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
348 static void blowfish_lsb_decrypt_cbc(unsigned char *blk, int len,
349                                      BlowfishContext * ctx)
350 {
351     word32 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
376 static void blowfish_msb_encrypt_cbc(unsigned char *blk, int len,
377                                      BlowfishContext * ctx)
378 {
379     word32 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
404 static void blowfish_msb_decrypt_cbc(unsigned char *blk, int len,
405                                      BlowfishContext * ctx)
406 {
407     word32 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
432 static void blowfish_msb_sdctr(unsigned char *blk, int len,
433                                      BlowfishContext * ctx)
434 {
435     word32 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
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
474 void blowfish_expandkey(BlowfishContext * ctx,
475                         const unsigned char *key, short keybytes,
476                         const unsigned char *salt, short saltbytes)
477 {
478     word32 *S0 = ctx->S0;
479     word32 *S1 = ctx->S1;
480     word32 *S2 = ctx->S2;
481     word32 *S3 = ctx->S3;
482     word32 *P = ctx->P;
483     word32 str[2];
484     int i, j;
485     int saltpos;
486     unsigned char dummysalt[1];
487
488     saltpos = 0;
489     if (!salt) {
490         saltbytes = 1;
491         salt = dummysalt;
492         dummysalt[0] = 0;
493     }
494
495     for (i = 0; i < 18; i++) {
496         P[i] ^=
497             ((word32) (unsigned char) (key[(i * 4 + 0) % keybytes])) << 24;
498         P[i] ^=
499             ((word32) (unsigned char) (key[(i * 4 + 1) % keybytes])) << 16;
500         P[i] ^=
501             ((word32) (unsigned char) (key[(i * 4 + 2) % keybytes])) << 8;
502         P[i] ^= ((word32) (unsigned char) (key[(i * 4 + 3) % keybytes]));
503     }
504
505     str[0] = str[1] = 0;
506
507     for (i = 0; i < 18; i += 2) {
508         for (j = 0; j < 8; j++)
509             str[j/4] ^= ((word32)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
510
511         blowfish_encrypt(str[0], str[1], str, ctx);
512         P[i] = str[0];
513         P[i + 1] = str[1];
514     }
515
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);
520         S0[i] = str[0];
521         S0[i + 1] = str[1];
522     }
523     for (i = 0; i < 256; i += 2) {
524         for (j = 0; j < 8; j++)
525             str[j/4] ^= ((word32)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
526         blowfish_encrypt(str[0], str[1], str, ctx);
527         S1[i] = str[0];
528         S1[i + 1] = str[1];
529     }
530     for (i = 0; i < 256; i += 2) {
531         for (j = 0; j < 8; j++)
532             str[j/4] ^= ((word32)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
533         blowfish_encrypt(str[0], str[1], str, ctx);
534         S2[i] = str[0];
535         S2[i + 1] = str[1];
536     }
537     for (i = 0; i < 256; i += 2) {
538         for (j = 0; j < 8; j++)
539             str[j/4] ^= ((word32)salt[saltpos++ % saltbytes]) << (24-8*(j%4));
540         blowfish_encrypt(str[0], str[1], str, ctx);
541         S3[i] = str[0];
542         S3[i + 1] = str[1];
543     }
544 }
545
546 static void blowfish_setkey(BlowfishContext *ctx,
547                             const unsigned char *key, short keybytes)
548 {
549     blowfish_initkey(ctx);
550     blowfish_expandkey(ctx, key, keybytes, NULL, 0);
551 }
552
553 /* -- Interface with PuTTY -- */
554
555 #define SSH_SESSION_KEY_LENGTH  32
556
557 void *blowfish_make_context(void)
558 {
559     return snew(BlowfishContext);
560 }
561
562 static void *blowfish_ssh1_make_context(void)
563 {
564     /* In SSH-1, need one key for each direction */
565     return snewn(2, BlowfishContext);
566 }
567
568 void blowfish_free_context(void *handle)
569 {
570     sfree(handle);
571 }
572
573 static void blowfish_key(void *handle, unsigned char *key)
574 {
575     BlowfishContext *ctx = (BlowfishContext *)handle;
576     blowfish_setkey(ctx, key, 16);
577 }
578
579 static void blowfish256_key(void *handle, unsigned char *key)
580 {
581     BlowfishContext *ctx = (BlowfishContext *)handle;
582     blowfish_setkey(ctx, key, 32);
583 }
584
585 static void blowfish_iv(void *handle, unsigned char *key)
586 {
587     BlowfishContext *ctx = (BlowfishContext *)handle;
588     ctx->iv0 = GET_32BIT_MSB_FIRST(key);
589     ctx->iv1 = GET_32BIT_MSB_FIRST(key + 4);
590 }
591
592 static void blowfish_sesskey(void *handle, unsigned char *key)
593 {
594     BlowfishContext *ctx = (BlowfishContext *)handle;
595     blowfish_setkey(ctx, key, SSH_SESSION_KEY_LENGTH);
596     ctx->iv0 = 0;
597     ctx->iv1 = 0;
598     ctx[1] = ctx[0];                   /* structure copy */
599 }
600
601 static void blowfish_ssh1_encrypt_blk(void *handle, unsigned char *blk,
602                                       int len)
603 {
604     BlowfishContext *ctx = (BlowfishContext *)handle;
605     blowfish_lsb_encrypt_cbc(blk, len, ctx);
606 }
607
608 static void blowfish_ssh1_decrypt_blk(void *handle, unsigned char *blk,
609                                       int len)
610 {
611     BlowfishContext *ctx = (BlowfishContext *)handle;
612     blowfish_lsb_decrypt_cbc(blk, len, ctx+1);
613 }
614
615 static void blowfish_ssh2_encrypt_blk(void *handle, unsigned char *blk,
616                                       int len)
617 {
618     BlowfishContext *ctx = (BlowfishContext *)handle;
619     blowfish_msb_encrypt_cbc(blk, len, ctx);
620 }
621
622 static void blowfish_ssh2_decrypt_blk(void *handle, unsigned char *blk,
623                                       int len)
624 {
625     BlowfishContext *ctx = (BlowfishContext *)handle;
626     blowfish_msb_decrypt_cbc(blk, len, ctx);
627 }
628
629 static void blowfish_ssh2_sdctr(void *handle, unsigned char *blk,
630                                       int len)
631 {
632     BlowfishContext *ctx = (BlowfishContext *)handle;
633     blowfish_msb_sdctr(blk, len, ctx);
634 }
635
636 const struct ssh_cipher ssh_blowfish_ssh1 = {
637     blowfish_ssh1_make_context, blowfish_free_context, blowfish_sesskey,
638     blowfish_ssh1_encrypt_blk, blowfish_ssh1_decrypt_blk,
639     8, "Blowfish-128 CBC"
640 };
641
642 static const struct ssh2_cipher ssh_blowfish_ssh2 = {
643     blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish_key,
644     blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk, NULL, NULL,
645     "blowfish-cbc",
646     8, 128, 16, SSH_CIPHER_IS_CBC, "Blowfish-128 CBC",
647     NULL
648 };
649
650 static const struct ssh2_cipher ssh_blowfish_ssh2_ctr = {
651     blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish256_key,
652     blowfish_ssh2_sdctr, blowfish_ssh2_sdctr, NULL, NULL,
653     "blowfish-ctr",
654     8, 256, 32, 0, "Blowfish-256 SDCTR",
655     NULL
656 };
657
658 static const struct ssh2_cipher *const blowfish_list[] = {
659     &ssh_blowfish_ssh2_ctr,
660     &ssh_blowfish_ssh2
661 };
662
663 const struct ssh2_ciphers ssh2_blowfish = {
664     sizeof(blowfish_list) / sizeof(*blowfish_list),
665     blowfish_list
666 };