OSDN Git Service

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