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