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