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