Sebastian Kuschel reports that pfd_closing can be called for a socket
[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
840de66d 16/*
54eb0b3e 17 * The Blowfish init data: hex digits of the fractional part of pi.
18 * (ie pi as a hex fraction is 3.243F6A8885A308D3...)
840de66d 19 */
54eb0b3e 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};
840de66d 25
54eb0b3e 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};
840de66d 71
54eb0b3e 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};
840de66d 117
54eb0b3e 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};
840de66d 163
54eb0b3e 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};
840de66d 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
32874aea 214static void blowfish_encrypt(word32 xL, word32 xR, word32 * output,
215 BlowfishContext * ctx)
216{
840de66d 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
32874aea 247static void blowfish_decrypt(word32 xL, word32 xR, word32 * output,
248 BlowfishContext * ctx)
249{
840de66d 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
5e8358ad 280static void blowfish_lsb_encrypt_cbc(unsigned char *blk, int len,
32874aea 281 BlowfishContext * ctx)
282{
840de66d 283 word32 xL, xR, out[2], iv0, iv1;
284
285 assert((len & 7) == 0);
286
32874aea 287 iv0 = ctx->iv0;
288 iv1 = ctx->iv1;
840de66d 289
290 while (len > 0) {
32874aea 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;
840de66d 302 }
303
32874aea 304 ctx->iv0 = iv0;
305 ctx->iv1 = iv1;
840de66d 306}
307
5e8358ad 308static void blowfish_lsb_decrypt_cbc(unsigned char *blk, int len,
32874aea 309 BlowfishContext * ctx)
310{
840de66d 311 word32 xL, xR, out[2], iv0, iv1;
312
313 assert((len & 7) == 0);
314
32874aea 315 iv0 = ctx->iv0;
316 iv1 = ctx->iv1;
840de66d 317
318 while (len > 0) {
32874aea 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;
840de66d 330 }
331
32874aea 332 ctx->iv0 = iv0;
333 ctx->iv1 = iv1;
840de66d 334}
335
5e8358ad 336static void blowfish_msb_encrypt_cbc(unsigned char *blk, int len,
32874aea 337 BlowfishContext * ctx)
338{
5e8358ad 339 word32 xL, xR, out[2], iv0, iv1;
340
341 assert((len & 7) == 0);
342
32874aea 343 iv0 = ctx->iv0;
344 iv1 = ctx->iv1;
5e8358ad 345
346 while (len > 0) {
32874aea 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;
5e8358ad 358 }
359
32874aea 360 ctx->iv0 = iv0;
361 ctx->iv1 = iv1;
5e8358ad 362}
363
364static void blowfish_msb_decrypt_cbc(unsigned char *blk, int len,
32874aea 365 BlowfishContext * ctx)
366{
5e8358ad 367 word32 xL, xR, out[2], iv0, iv1;
368
369 assert((len & 7) == 0);
370
32874aea 371 iv0 = ctx->iv0;
372 iv1 = ctx->iv1;
5e8358ad 373
374 while (len > 0) {
32874aea 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;
5e8358ad 386 }
387
32874aea 388 ctx->iv0 = iv0;
389 ctx->iv1 = iv1;
5e8358ad 390}
391
c2e3a6c9 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]);
be47bb50 408 if ((iv1 = (iv1 + 1) & 0xffffffff) == 0)
409 iv0 = (iv0 + 1) & 0xffffffff;
c2e3a6c9 410 blk += 8;
411 len -= 8;
412 }
413
414 ctx->iv0 = iv0;
415 ctx->iv1 = iv1;
416}
417
32874aea 418static void blowfish_setkey(BlowfishContext * ctx,
419 const unsigned char *key, short keybytes)
420{
840de66d 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++) {
32874aea 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]));
840de66d 438 }
439
440 for (i = 0; i < 256; i++) {
32874aea 441 S0[i] = sbox0[i];
442 S1[i] = sbox1[i];
443 S2[i] = sbox2[i];
444 S3[i] = sbox3[i];
840de66d 445 }
446
447 str[0] = str[1] = 0;
448
449 for (i = 0; i < 18; i += 2) {
32874aea 450 blowfish_encrypt(str[0], str[1], str, ctx);
451 P[i] = str[0];
452 P[i + 1] = str[1];
840de66d 453 }
454
455 for (i = 0; i < 256; i += 2) {
32874aea 456 blowfish_encrypt(str[0], str[1], str, ctx);
457 S0[i] = str[0];
458 S0[i + 1] = str[1];
840de66d 459 }
460 for (i = 0; i < 256; i += 2) {
32874aea 461 blowfish_encrypt(str[0], str[1], str, ctx);
462 S1[i] = str[0];
463 S1[i + 1] = str[1];
840de66d 464 }
465 for (i = 0; i < 256; i += 2) {
32874aea 466 blowfish_encrypt(str[0], str[1], str, ctx);
467 S2[i] = str[0];
468 S2[i + 1] = str[1];
840de66d 469 }
470 for (i = 0; i < 256; i += 2) {
32874aea 471 blowfish_encrypt(str[0], str[1], str, ctx);
472 S3[i] = str[0];
473 S3[i + 1] = str[1];
840de66d 474 }
475}
476
477/* -- Interface with PuTTY -- */
478
479#define SSH_SESSION_KEY_LENGTH 32
840de66d 480
371e569c 481static void *blowfish_make_context(void)
d39f364a 482{
3d88e64d 483 return snew(BlowfishContext);
d39f364a 484}
485
371e569c 486static void *blowfish_ssh1_make_context(void)
d39f364a 487{
2e85c969 488 /* In SSH-1, need one key for each direction */
3d88e64d 489 return snewn(2, BlowfishContext);
d39f364a 490}
491
371e569c 492static void blowfish_free_context(void *handle)
d39f364a 493{
371e569c 494 sfree(handle);
d39f364a 495}
496
371e569c 497static void blowfish_key(void *handle, unsigned char *key)
d39f364a 498{
371e569c 499 BlowfishContext *ctx = (BlowfishContext *)handle;
500 blowfish_setkey(ctx, key, 16);
d39f364a 501}
502
c2e3a6c9 503static void blowfish256_key(void *handle, unsigned char *key)
504{
505 BlowfishContext *ctx = (BlowfishContext *)handle;
506 blowfish_setkey(ctx, key, 32);
507}
508
371e569c 509static void blowfish_iv(void *handle, unsigned char *key)
840de66d 510{
371e569c 511 BlowfishContext *ctx = (BlowfishContext *)handle;
512 ctx->iv0 = GET_32BIT_MSB_FIRST(key);
513 ctx->iv1 = GET_32BIT_MSB_FIRST(key + 4);
840de66d 514}
515
371e569c 516static void blowfish_sesskey(void *handle, unsigned char *key)
840de66d 517{
371e569c 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 */
840de66d 523}
524
371e569c 525static void blowfish_ssh1_encrypt_blk(void *handle, unsigned char *blk,
526 int len)
840de66d 527{
371e569c 528 BlowfishContext *ctx = (BlowfishContext *)handle;
529 blowfish_lsb_encrypt_cbc(blk, len, ctx);
840de66d 530}
531
371e569c 532static void blowfish_ssh1_decrypt_blk(void *handle, unsigned char *blk,
533 int len)
5e8358ad 534{
371e569c 535 BlowfishContext *ctx = (BlowfishContext *)handle;
536 blowfish_lsb_decrypt_cbc(blk, len, ctx+1);
5e8358ad 537}
538
371e569c 539static void blowfish_ssh2_encrypt_blk(void *handle, unsigned char *blk,
540 int len)
5e8358ad 541{
371e569c 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);
5e8358ad 551}
552
c2e3a6c9 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
65a22376 560const struct ssh_cipher ssh_blowfish_ssh1 = {
371e569c 561 blowfish_ssh1_make_context, blowfish_free_context, blowfish_sesskey,
562 blowfish_ssh1_encrypt_blk, blowfish_ssh1_decrypt_blk,
c2e3a6c9 563 8, "Blowfish-128 CBC"
5e8358ad 564};
565
65a22376 566static const struct ssh2_cipher ssh_blowfish_ssh2 = {
371e569c 567 blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish_key,
568 blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk,
e5574168 569 "blowfish-cbc",
97ab28d7 570 8, 128, SSH_CIPHER_IS_CBC, "Blowfish-128 CBC"
840de66d 571};
0a3f1d48 572
c2e3a6c9 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",
97ab28d7 577 8, 256, 0, "Blowfish-256 SDCTR"
c2e3a6c9 578};
579
65a22376 580static const struct ssh2_cipher *const blowfish_list[] = {
8d49ffb3 581 &ssh_blowfish_ssh2_ctr,
0a3f1d48 582 &ssh_blowfish_ssh2
583};
584
65a22376 585const struct ssh2_ciphers ssh2_blowfish = {
0a3f1d48 586 sizeof(blowfish_list) / sizeof(*blowfish_list),
587 blowfish_list
588};