Implement SDCTR modes, as defined in the newmodes draft. This adds
[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
32874aea 238static void blowfish_encrypt(word32 xL, word32 xR, word32 * output,
239 BlowfishContext * ctx)
240{
840de66d 241 word32 *S0 = ctx->S0;
242 word32 *S1 = ctx->S1;
243 word32 *S2 = ctx->S2;
244 word32 *S3 = ctx->S3;
245 word32 *P = ctx->P;
246 word32 t;
247
248 ROUND(0);
249 ROUND(1);
250 ROUND(2);
251 ROUND(3);
252 ROUND(4);
253 ROUND(5);
254 ROUND(6);
255 ROUND(7);
256 ROUND(8);
257 ROUND(9);
258 ROUND(10);
259 ROUND(11);
260 ROUND(12);
261 ROUND(13);
262 ROUND(14);
263 ROUND(15);
264 xL ^= P[16];
265 xR ^= P[17];
266
267 output[0] = xR;
268 output[1] = xL;
269}
270
32874aea 271static void blowfish_decrypt(word32 xL, word32 xR, word32 * output,
272 BlowfishContext * ctx)
273{
840de66d 274 word32 *S0 = ctx->S0;
275 word32 *S1 = ctx->S1;
276 word32 *S2 = ctx->S2;
277 word32 *S3 = ctx->S3;
278 word32 *P = ctx->P;
279 word32 t;
280
281 ROUND(17);
282 ROUND(16);
283 ROUND(15);
284 ROUND(14);
285 ROUND(13);
286 ROUND(12);
287 ROUND(11);
288 ROUND(10);
289 ROUND(9);
290 ROUND(8);
291 ROUND(7);
292 ROUND(6);
293 ROUND(5);
294 ROUND(4);
295 ROUND(3);
296 ROUND(2);
297 xL ^= P[1];
298 xR ^= P[0];
299
300 output[0] = xR;
301 output[1] = xL;
302}
303
5e8358ad 304static void blowfish_lsb_encrypt_cbc(unsigned char *blk, int len,
32874aea 305 BlowfishContext * ctx)
306{
840de66d 307 word32 xL, xR, out[2], iv0, iv1;
308
309 assert((len & 7) == 0);
310
32874aea 311 iv0 = ctx->iv0;
312 iv1 = ctx->iv1;
840de66d 313
314 while (len > 0) {
32874aea 315 xL = GET_32BIT_LSB_FIRST(blk);
316 xR = GET_32BIT_LSB_FIRST(blk + 4);
317 iv0 ^= xL;
318 iv1 ^= xR;
319 blowfish_encrypt(iv0, iv1, out, ctx);
320 iv0 = out[0];
321 iv1 = out[1];
322 PUT_32BIT_LSB_FIRST(blk, iv0);
323 PUT_32BIT_LSB_FIRST(blk + 4, iv1);
324 blk += 8;
325 len -= 8;
840de66d 326 }
327
32874aea 328 ctx->iv0 = iv0;
329 ctx->iv1 = iv1;
840de66d 330}
331
5e8358ad 332static void blowfish_lsb_decrypt_cbc(unsigned char *blk, int len,
32874aea 333 BlowfishContext * ctx)
334{
840de66d 335 word32 xL, xR, out[2], iv0, iv1;
336
337 assert((len & 7) == 0);
338
32874aea 339 iv0 = ctx->iv0;
340 iv1 = ctx->iv1;
840de66d 341
342 while (len > 0) {
32874aea 343 xL = GET_32BIT_LSB_FIRST(blk);
344 xR = GET_32BIT_LSB_FIRST(blk + 4);
345 blowfish_decrypt(xL, xR, out, ctx);
346 iv0 ^= out[0];
347 iv1 ^= out[1];
348 PUT_32BIT_LSB_FIRST(blk, iv0);
349 PUT_32BIT_LSB_FIRST(blk + 4, iv1);
350 iv0 = xL;
351 iv1 = xR;
352 blk += 8;
353 len -= 8;
840de66d 354 }
355
32874aea 356 ctx->iv0 = iv0;
357 ctx->iv1 = iv1;
840de66d 358}
359
5e8358ad 360static void blowfish_msb_encrypt_cbc(unsigned char *blk, int len,
32874aea 361 BlowfishContext * ctx)
362{
5e8358ad 363 word32 xL, xR, out[2], iv0, iv1;
364
365 assert((len & 7) == 0);
366
32874aea 367 iv0 = ctx->iv0;
368 iv1 = ctx->iv1;
5e8358ad 369
370 while (len > 0) {
32874aea 371 xL = GET_32BIT_MSB_FIRST(blk);
372 xR = GET_32BIT_MSB_FIRST(blk + 4);
373 iv0 ^= xL;
374 iv1 ^= xR;
375 blowfish_encrypt(iv0, iv1, out, ctx);
376 iv0 = out[0];
377 iv1 = out[1];
378 PUT_32BIT_MSB_FIRST(blk, iv0);
379 PUT_32BIT_MSB_FIRST(blk + 4, iv1);
380 blk += 8;
381 len -= 8;
5e8358ad 382 }
383
32874aea 384 ctx->iv0 = iv0;
385 ctx->iv1 = iv1;
5e8358ad 386}
387
388static void blowfish_msb_decrypt_cbc(unsigned char *blk, int len,
32874aea 389 BlowfishContext * ctx)
390{
5e8358ad 391 word32 xL, xR, out[2], iv0, iv1;
392
393 assert((len & 7) == 0);
394
32874aea 395 iv0 = ctx->iv0;
396 iv1 = ctx->iv1;
5e8358ad 397
398 while (len > 0) {
32874aea 399 xL = GET_32BIT_MSB_FIRST(blk);
400 xR = GET_32BIT_MSB_FIRST(blk + 4);
401 blowfish_decrypt(xL, xR, out, ctx);
402 iv0 ^= out[0];
403 iv1 ^= out[1];
404 PUT_32BIT_MSB_FIRST(blk, iv0);
405 PUT_32BIT_MSB_FIRST(blk + 4, iv1);
406 iv0 = xL;
407 iv1 = xR;
408 blk += 8;
409 len -= 8;
5e8358ad 410 }
411
32874aea 412 ctx->iv0 = iv0;
413 ctx->iv1 = iv1;
5e8358ad 414}
415
c2e3a6c9 416static void blowfish_msb_sdctr(unsigned char *blk, int len,
417 BlowfishContext * ctx)
418{
419 word32 b[2], iv0, iv1, tmp;
420
421 assert((len & 7) == 0);
422
423 iv0 = ctx->iv0;
424 iv1 = ctx->iv1;
425
426 while (len > 0) {
427 blowfish_encrypt(iv0, iv1, b, ctx);
428 tmp = GET_32BIT_MSB_FIRST(blk);
429 PUT_32BIT_MSB_FIRST(blk, tmp ^ b[0]);
430 tmp = GET_32BIT_MSB_FIRST(blk + 4);
431 PUT_32BIT_MSB_FIRST(blk + 4, tmp ^ b[1]);
432 if ((iv0 = (iv0 + 1) & 0xffffffff) == 0)
433 iv1 = (iv1 + 1) & 0xffffffff;
434 blk += 8;
435 len -= 8;
436 }
437
438 ctx->iv0 = iv0;
439 ctx->iv1 = iv1;
440}
441
32874aea 442static void blowfish_setkey(BlowfishContext * ctx,
443 const unsigned char *key, short keybytes)
444{
840de66d 445 word32 *S0 = ctx->S0;
446 word32 *S1 = ctx->S1;
447 word32 *S2 = ctx->S2;
448 word32 *S3 = ctx->S3;
449 word32 *P = ctx->P;
450 word32 str[2];
451 int i;
452
453 for (i = 0; i < 18; i++) {
32874aea 454 P[i] = parray[i];
455 P[i] ^=
456 ((word32) (unsigned char) (key[(i * 4 + 0) % keybytes])) << 24;
457 P[i] ^=
458 ((word32) (unsigned char) (key[(i * 4 + 1) % keybytes])) << 16;
459 P[i] ^=
460 ((word32) (unsigned char) (key[(i * 4 + 2) % keybytes])) << 8;
461 P[i] ^= ((word32) (unsigned char) (key[(i * 4 + 3) % keybytes]));
840de66d 462 }
463
464 for (i = 0; i < 256; i++) {
32874aea 465 S0[i] = sbox0[i];
466 S1[i] = sbox1[i];
467 S2[i] = sbox2[i];
468 S3[i] = sbox3[i];
840de66d 469 }
470
471 str[0] = str[1] = 0;
472
473 for (i = 0; i < 18; i += 2) {
32874aea 474 blowfish_encrypt(str[0], str[1], str, ctx);
475 P[i] = str[0];
476 P[i + 1] = str[1];
840de66d 477 }
478
479 for (i = 0; i < 256; i += 2) {
32874aea 480 blowfish_encrypt(str[0], str[1], str, ctx);
481 S0[i] = str[0];
482 S0[i + 1] = str[1];
840de66d 483 }
484 for (i = 0; i < 256; i += 2) {
32874aea 485 blowfish_encrypt(str[0], str[1], str, ctx);
486 S1[i] = str[0];
487 S1[i + 1] = str[1];
840de66d 488 }
489 for (i = 0; i < 256; i += 2) {
32874aea 490 blowfish_encrypt(str[0], str[1], str, ctx);
491 S2[i] = str[0];
492 S2[i + 1] = str[1];
840de66d 493 }
494 for (i = 0; i < 256; i += 2) {
32874aea 495 blowfish_encrypt(str[0], str[1], str, ctx);
496 S3[i] = str[0];
497 S3[i + 1] = str[1];
840de66d 498 }
499}
500
501/* -- Interface with PuTTY -- */
502
503#define SSH_SESSION_KEY_LENGTH 32
840de66d 504
371e569c 505static void *blowfish_make_context(void)
d39f364a 506{
3d88e64d 507 return snew(BlowfishContext);
d39f364a 508}
509
371e569c 510static void *blowfish_ssh1_make_context(void)
d39f364a 511{
2e85c969 512 /* In SSH-1, need one key for each direction */
3d88e64d 513 return snewn(2, BlowfishContext);
d39f364a 514}
515
371e569c 516static void blowfish_free_context(void *handle)
d39f364a 517{
371e569c 518 sfree(handle);
d39f364a 519}
520
371e569c 521static void blowfish_key(void *handle, unsigned char *key)
d39f364a 522{
371e569c 523 BlowfishContext *ctx = (BlowfishContext *)handle;
524 blowfish_setkey(ctx, key, 16);
d39f364a 525}
526
c2e3a6c9 527static void blowfish256_key(void *handle, unsigned char *key)
528{
529 BlowfishContext *ctx = (BlowfishContext *)handle;
530 blowfish_setkey(ctx, key, 32);
531}
532
371e569c 533static void blowfish_iv(void *handle, unsigned char *key)
840de66d 534{
371e569c 535 BlowfishContext *ctx = (BlowfishContext *)handle;
536 ctx->iv0 = GET_32BIT_MSB_FIRST(key);
537 ctx->iv1 = GET_32BIT_MSB_FIRST(key + 4);
840de66d 538}
539
371e569c 540static void blowfish_sesskey(void *handle, unsigned char *key)
840de66d 541{
371e569c 542 BlowfishContext *ctx = (BlowfishContext *)handle;
543 blowfish_setkey(ctx, key, SSH_SESSION_KEY_LENGTH);
544 ctx->iv0 = 0;
545 ctx->iv1 = 0;
546 ctx[1] = ctx[0]; /* structure copy */
840de66d 547}
548
371e569c 549static void blowfish_ssh1_encrypt_blk(void *handle, unsigned char *blk,
550 int len)
840de66d 551{
371e569c 552 BlowfishContext *ctx = (BlowfishContext *)handle;
553 blowfish_lsb_encrypt_cbc(blk, len, ctx);
840de66d 554}
555
371e569c 556static void blowfish_ssh1_decrypt_blk(void *handle, unsigned char *blk,
557 int len)
5e8358ad 558{
371e569c 559 BlowfishContext *ctx = (BlowfishContext *)handle;
560 blowfish_lsb_decrypt_cbc(blk, len, ctx+1);
5e8358ad 561}
562
371e569c 563static void blowfish_ssh2_encrypt_blk(void *handle, unsigned char *blk,
564 int len)
5e8358ad 565{
371e569c 566 BlowfishContext *ctx = (BlowfishContext *)handle;
567 blowfish_msb_encrypt_cbc(blk, len, ctx);
568}
569
570static void blowfish_ssh2_decrypt_blk(void *handle, unsigned char *blk,
571 int len)
572{
573 BlowfishContext *ctx = (BlowfishContext *)handle;
574 blowfish_msb_decrypt_cbc(blk, len, ctx);
5e8358ad 575}
576
c2e3a6c9 577static void blowfish_ssh2_sdctr(void *handle, unsigned char *blk,
578 int len)
579{
580 BlowfishContext *ctx = (BlowfishContext *)handle;
581 blowfish_msb_sdctr(blk, len, ctx);
582}
583
65a22376 584const struct ssh_cipher ssh_blowfish_ssh1 = {
371e569c 585 blowfish_ssh1_make_context, blowfish_free_context, blowfish_sesskey,
586 blowfish_ssh1_encrypt_blk, blowfish_ssh1_decrypt_blk,
c2e3a6c9 587 8, "Blowfish-128 CBC"
5e8358ad 588};
589
65a22376 590static const struct ssh2_cipher ssh_blowfish_ssh2 = {
371e569c 591 blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish_key,
592 blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk,
e5574168 593 "blowfish-cbc",
c2e3a6c9 594 8, 128, "Blowfish-128 CBC"
840de66d 595};
0a3f1d48 596
c2e3a6c9 597static const struct ssh2_cipher ssh_blowfish_ssh2_ctr = {
598 blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish256_key,
599 blowfish_ssh2_sdctr, blowfish_ssh2_sdctr,
600 "blowfish-ctr",
601 8, 256, "Blowfish-256 SDCTR"
602};
603
604/*
605 * "blowfish-ctr" is disabled because it hasn't had any interoperability
606 * testing, which is in turn because I couldn't find another implementation
607 * to test against. Once it's been tested, it can be enabled in standard
608 * builds.
609 */
65a22376 610static const struct ssh2_cipher *const blowfish_list[] = {
c2e3a6c9 611/* &ssh_blowfish_ssh2_ctr, */
0a3f1d48 612 &ssh_blowfish_ssh2
613};
614
65a22376 615const struct ssh2_ciphers ssh2_blowfish = {
0a3f1d48 616 sizeof(blowfish_list) / sizeof(*blowfish_list),
617 blowfish_list
618};