]> git.ipfire.org Git - people/ms/putty.git/blame - sshblowf.c
Add search to connection list box.
[people/ms/putty.git] / sshblowf.c
CommitLineData
1c1af145 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
11typedef 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 */
20static 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
26static 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
72static 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
118static 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
164static 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
214static 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
247static 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
280static 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
308static 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
336static 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
364static 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
392static void blowfish_msb_sdctr(unsigned char *blk, int len,
393 BlowfishContext * ctx)
394{
395 word32 b[2], iv0, iv1, tmp;
396
397 assert((len & 7) == 0);
398
399 iv0 = ctx->iv0;
400 iv1 = ctx->iv1;
401
402 while (len > 0) {
403 blowfish_encrypt(iv0, iv1, b, ctx);
404 tmp = GET_32BIT_MSB_FIRST(blk);
405 PUT_32BIT_MSB_FIRST(blk, tmp ^ b[0]);
406 tmp = GET_32BIT_MSB_FIRST(blk + 4);
407 PUT_32BIT_MSB_FIRST(blk + 4, tmp ^ b[1]);
408 if ((iv1 = (iv1 + 1) & 0xffffffff) == 0)
409 iv0 = (iv0 + 1) & 0xffffffff;
410 blk += 8;
411 len -= 8;
412 }
413
414 ctx->iv0 = iv0;
415 ctx->iv1 = iv1;
416}
417
418static void blowfish_setkey(BlowfishContext * ctx,
419 const unsigned char *key, short keybytes)
420{
421 word32 *S0 = ctx->S0;
422 word32 *S1 = ctx->S1;
423 word32 *S2 = ctx->S2;
424 word32 *S3 = ctx->S3;
425 word32 *P = ctx->P;
426 word32 str[2];
427 int i;
428
429 for (i = 0; i < 18; i++) {
430 P[i] = parray[i];
431 P[i] ^=
432 ((word32) (unsigned char) (key[(i * 4 + 0) % keybytes])) << 24;
433 P[i] ^=
434 ((word32) (unsigned char) (key[(i * 4 + 1) % keybytes])) << 16;
435 P[i] ^=
436 ((word32) (unsigned char) (key[(i * 4 + 2) % keybytes])) << 8;
437 P[i] ^= ((word32) (unsigned char) (key[(i * 4 + 3) % keybytes]));
438 }
439
440 for (i = 0; i < 256; i++) {
441 S0[i] = sbox0[i];
442 S1[i] = sbox1[i];
443 S2[i] = sbox2[i];
444 S3[i] = sbox3[i];
445 }
446
447 str[0] = str[1] = 0;
448
449 for (i = 0; i < 18; i += 2) {
450 blowfish_encrypt(str[0], str[1], str, ctx);
451 P[i] = str[0];
452 P[i + 1] = str[1];
453 }
454
455 for (i = 0; i < 256; i += 2) {
456 blowfish_encrypt(str[0], str[1], str, ctx);
457 S0[i] = str[0];
458 S0[i + 1] = str[1];
459 }
460 for (i = 0; i < 256; i += 2) {
461 blowfish_encrypt(str[0], str[1], str, ctx);
462 S1[i] = str[0];
463 S1[i + 1] = str[1];
464 }
465 for (i = 0; i < 256; i += 2) {
466 blowfish_encrypt(str[0], str[1], str, ctx);
467 S2[i] = str[0];
468 S2[i + 1] = str[1];
469 }
470 for (i = 0; i < 256; i += 2) {
471 blowfish_encrypt(str[0], str[1], str, ctx);
472 S3[i] = str[0];
473 S3[i + 1] = str[1];
474 }
475}
476
477/* -- Interface with PuTTY -- */
478
479#define SSH_SESSION_KEY_LENGTH 32
480
481static void *blowfish_make_context(void)
482{
483 return snew(BlowfishContext);
484}
485
486static void *blowfish_ssh1_make_context(void)
487{
488 /* In SSH-1, need one key for each direction */
489 return snewn(2, BlowfishContext);
490}
491
492static void blowfish_free_context(void *handle)
493{
494 sfree(handle);
495}
496
497static void blowfish_key(void *handle, unsigned char *key)
498{
499 BlowfishContext *ctx = (BlowfishContext *)handle;
500 blowfish_setkey(ctx, key, 16);
501}
502
503static void blowfish256_key(void *handle, unsigned char *key)
504{
505 BlowfishContext *ctx = (BlowfishContext *)handle;
506 blowfish_setkey(ctx, key, 32);
507}
508
509static void blowfish_iv(void *handle, unsigned char *key)
510{
511 BlowfishContext *ctx = (BlowfishContext *)handle;
512 ctx->iv0 = GET_32BIT_MSB_FIRST(key);
513 ctx->iv1 = GET_32BIT_MSB_FIRST(key + 4);
514}
515
516static void blowfish_sesskey(void *handle, unsigned char *key)
517{
518 BlowfishContext *ctx = (BlowfishContext *)handle;
519 blowfish_setkey(ctx, key, SSH_SESSION_KEY_LENGTH);
520 ctx->iv0 = 0;
521 ctx->iv1 = 0;
522 ctx[1] = ctx[0]; /* structure copy */
523}
524
525static void blowfish_ssh1_encrypt_blk(void *handle, unsigned char *blk,
526 int len)
527{
528 BlowfishContext *ctx = (BlowfishContext *)handle;
529 blowfish_lsb_encrypt_cbc(blk, len, ctx);
530}
531
532static void blowfish_ssh1_decrypt_blk(void *handle, unsigned char *blk,
533 int len)
534{
535 BlowfishContext *ctx = (BlowfishContext *)handle;
536 blowfish_lsb_decrypt_cbc(blk, len, ctx+1);
537}
538
539static void blowfish_ssh2_encrypt_blk(void *handle, unsigned char *blk,
540 int len)
541{
542 BlowfishContext *ctx = (BlowfishContext *)handle;
543 blowfish_msb_encrypt_cbc(blk, len, ctx);
544}
545
546static void blowfish_ssh2_decrypt_blk(void *handle, unsigned char *blk,
547 int len)
548{
549 BlowfishContext *ctx = (BlowfishContext *)handle;
550 blowfish_msb_decrypt_cbc(blk, len, ctx);
551}
552
553static void blowfish_ssh2_sdctr(void *handle, unsigned char *blk,
554 int len)
555{
556 BlowfishContext *ctx = (BlowfishContext *)handle;
557 blowfish_msb_sdctr(blk, len, ctx);
558}
559
560const struct ssh_cipher ssh_blowfish_ssh1 = {
561 blowfish_ssh1_make_context, blowfish_free_context, blowfish_sesskey,
562 blowfish_ssh1_encrypt_blk, blowfish_ssh1_decrypt_blk,
563 8, "Blowfish-128 CBC"
564};
565
566static const struct ssh2_cipher ssh_blowfish_ssh2 = {
567 blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish_key,
568 blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk,
569 "blowfish-cbc",
570 8, 128, SSH_CIPHER_IS_CBC, "Blowfish-128 CBC"
571};
572
573static const struct ssh2_cipher ssh_blowfish_ssh2_ctr = {
574 blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish256_key,
575 blowfish_ssh2_sdctr, blowfish_ssh2_sdctr,
576 "blowfish-ctr",
577 8, 256, 0, "Blowfish-256 SDCTR"
578};
579
580static const struct ssh2_cipher *const blowfish_list[] = {
581 &ssh_blowfish_ssh2_ctr,
582 &ssh_blowfish_ssh2
583};
584
585const struct ssh2_ciphers ssh2_blowfish = {
586 sizeof(blowfish_list) / sizeof(*blowfish_list),
587 blowfish_list
588};