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