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