Fix two more stupid bugs in 3des-ctr:
[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
e94b1ec4 392#ifdef ENABLE_BLOWFISH_SSH2_CTR
c2e3a6c9 393static void blowfish_msb_sdctr(unsigned char *blk, int len,
394 BlowfishContext * ctx)
395{
396 word32 b[2], iv0, iv1, tmp;
397
398 assert((len & 7) == 0);
399
400 iv0 = ctx->iv0;
401 iv1 = ctx->iv1;
402
403 while (len > 0) {
404 blowfish_encrypt(iv0, iv1, b, ctx);
405 tmp = GET_32BIT_MSB_FIRST(blk);
406 PUT_32BIT_MSB_FIRST(blk, tmp ^ b[0]);
407 tmp = GET_32BIT_MSB_FIRST(blk + 4);
408 PUT_32BIT_MSB_FIRST(blk + 4, tmp ^ b[1]);
409 if ((iv0 = (iv0 + 1) & 0xffffffff) == 0)
410 iv1 = (iv1 + 1) & 0xffffffff;
411 blk += 8;
412 len -= 8;
413 }
414
415 ctx->iv0 = iv0;
416 ctx->iv1 = iv1;
417}
e94b1ec4 418#endif
c2e3a6c9 419
32874aea 420static void blowfish_setkey(BlowfishContext * ctx,
421 const unsigned char *key, short keybytes)
422{
840de66d 423 word32 *S0 = ctx->S0;
424 word32 *S1 = ctx->S1;
425 word32 *S2 = ctx->S2;
426 word32 *S3 = ctx->S3;
427 word32 *P = ctx->P;
428 word32 str[2];
429 int i;
430
431 for (i = 0; i < 18; i++) {
32874aea 432 P[i] = parray[i];
433 P[i] ^=
434 ((word32) (unsigned char) (key[(i * 4 + 0) % keybytes])) << 24;
435 P[i] ^=
436 ((word32) (unsigned char) (key[(i * 4 + 1) % keybytes])) << 16;
437 P[i] ^=
438 ((word32) (unsigned char) (key[(i * 4 + 2) % keybytes])) << 8;
439 P[i] ^= ((word32) (unsigned char) (key[(i * 4 + 3) % keybytes]));
840de66d 440 }
441
442 for (i = 0; i < 256; i++) {
32874aea 443 S0[i] = sbox0[i];
444 S1[i] = sbox1[i];
445 S2[i] = sbox2[i];
446 S3[i] = sbox3[i];
840de66d 447 }
448
449 str[0] = str[1] = 0;
450
451 for (i = 0; i < 18; i += 2) {
32874aea 452 blowfish_encrypt(str[0], str[1], str, ctx);
453 P[i] = str[0];
454 P[i + 1] = str[1];
840de66d 455 }
456
457 for (i = 0; i < 256; i += 2) {
32874aea 458 blowfish_encrypt(str[0], str[1], str, ctx);
459 S0[i] = str[0];
460 S0[i + 1] = str[1];
840de66d 461 }
462 for (i = 0; i < 256; i += 2) {
32874aea 463 blowfish_encrypt(str[0], str[1], str, ctx);
464 S1[i] = str[0];
465 S1[i + 1] = str[1];
840de66d 466 }
467 for (i = 0; i < 256; i += 2) {
32874aea 468 blowfish_encrypt(str[0], str[1], str, ctx);
469 S2[i] = str[0];
470 S2[i + 1] = str[1];
840de66d 471 }
472 for (i = 0; i < 256; i += 2) {
32874aea 473 blowfish_encrypt(str[0], str[1], str, ctx);
474 S3[i] = str[0];
475 S3[i + 1] = str[1];
840de66d 476 }
477}
478
479/* -- Interface with PuTTY -- */
480
481#define SSH_SESSION_KEY_LENGTH 32
840de66d 482
371e569c 483static void *blowfish_make_context(void)
d39f364a 484{
3d88e64d 485 return snew(BlowfishContext);
d39f364a 486}
487
371e569c 488static void *blowfish_ssh1_make_context(void)
d39f364a 489{
2e85c969 490 /* In SSH-1, need one key for each direction */
3d88e64d 491 return snewn(2, BlowfishContext);
d39f364a 492}
493
371e569c 494static void blowfish_free_context(void *handle)
d39f364a 495{
371e569c 496 sfree(handle);
d39f364a 497}
498
371e569c 499static void blowfish_key(void *handle, unsigned char *key)
d39f364a 500{
371e569c 501 BlowfishContext *ctx = (BlowfishContext *)handle;
502 blowfish_setkey(ctx, key, 16);
d39f364a 503}
504
d4480d78 505#ifdef ENABLE_BLOWFISH_SSH2_CTR
c2e3a6c9 506static void blowfish256_key(void *handle, unsigned char *key)
507{
508 BlowfishContext *ctx = (BlowfishContext *)handle;
509 blowfish_setkey(ctx, key, 32);
510}
8d49ffb3 511#endif
c2e3a6c9 512
371e569c 513static void blowfish_iv(void *handle, unsigned char *key)
840de66d 514{
371e569c 515 BlowfishContext *ctx = (BlowfishContext *)handle;
516 ctx->iv0 = GET_32BIT_MSB_FIRST(key);
517 ctx->iv1 = GET_32BIT_MSB_FIRST(key + 4);
840de66d 518}
519
371e569c 520static void blowfish_sesskey(void *handle, unsigned char *key)
840de66d 521{
371e569c 522 BlowfishContext *ctx = (BlowfishContext *)handle;
523 blowfish_setkey(ctx, key, SSH_SESSION_KEY_LENGTH);
524 ctx->iv0 = 0;
525 ctx->iv1 = 0;
526 ctx[1] = ctx[0]; /* structure copy */
840de66d 527}
528
371e569c 529static void blowfish_ssh1_encrypt_blk(void *handle, unsigned char *blk,
530 int len)
840de66d 531{
371e569c 532 BlowfishContext *ctx = (BlowfishContext *)handle;
533 blowfish_lsb_encrypt_cbc(blk, len, ctx);
840de66d 534}
535
371e569c 536static void blowfish_ssh1_decrypt_blk(void *handle, unsigned char *blk,
537 int len)
5e8358ad 538{
371e569c 539 BlowfishContext *ctx = (BlowfishContext *)handle;
540 blowfish_lsb_decrypt_cbc(blk, len, ctx+1);
5e8358ad 541}
542
371e569c 543static void blowfish_ssh2_encrypt_blk(void *handle, unsigned char *blk,
544 int len)
5e8358ad 545{
371e569c 546 BlowfishContext *ctx = (BlowfishContext *)handle;
547 blowfish_msb_encrypt_cbc(blk, len, ctx);
548}
549
550static void blowfish_ssh2_decrypt_blk(void *handle, unsigned char *blk,
551 int len)
552{
553 BlowfishContext *ctx = (BlowfishContext *)handle;
554 blowfish_msb_decrypt_cbc(blk, len, ctx);
5e8358ad 555}
556
d4480d78 557#ifdef ENABLE_BLOWFISH_SSH2_CTR
c2e3a6c9 558static void blowfish_ssh2_sdctr(void *handle, unsigned char *blk,
559 int len)
560{
561 BlowfishContext *ctx = (BlowfishContext *)handle;
562 blowfish_msb_sdctr(blk, len, ctx);
563}
8d49ffb3 564#endif
c2e3a6c9 565
65a22376 566const struct ssh_cipher ssh_blowfish_ssh1 = {
371e569c 567 blowfish_ssh1_make_context, blowfish_free_context, blowfish_sesskey,
568 blowfish_ssh1_encrypt_blk, blowfish_ssh1_decrypt_blk,
c2e3a6c9 569 8, "Blowfish-128 CBC"
5e8358ad 570};
571
65a22376 572static const struct ssh2_cipher ssh_blowfish_ssh2 = {
371e569c 573 blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish_key,
574 blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk,
e5574168 575 "blowfish-cbc",
97ab28d7 576 8, 128, SSH_CIPHER_IS_CBC, "Blowfish-128 CBC"
840de66d 577};
0a3f1d48 578
d4480d78 579#ifdef ENABLE_BLOWFISH_SSH2_CTR
c2e3a6c9 580static const struct ssh2_cipher ssh_blowfish_ssh2_ctr = {
581 blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish256_key,
582 blowfish_ssh2_sdctr, blowfish_ssh2_sdctr,
583 "blowfish-ctr",
97ab28d7 584 8, 256, 0, "Blowfish-256 SDCTR"
c2e3a6c9 585};
8d49ffb3 586#endif
c2e3a6c9 587
588/*
589 * "blowfish-ctr" is disabled because it hasn't had any interoperability
590 * testing, which is in turn because I couldn't find another implementation
591 * to test against. Once it's been tested, it can be enabled in standard
592 * builds.
593 */
65a22376 594static const struct ssh2_cipher *const blowfish_list[] = {
d4480d78 595#ifdef ENABLE_BLOWFISH_SSH2_CTR
8d49ffb3 596 &ssh_blowfish_ssh2_ctr,
597#endif
0a3f1d48 598 &ssh_blowfish_ssh2
599};
600
65a22376 601const struct ssh2_ciphers ssh2_blowfish = {
0a3f1d48 602 sizeof(blowfish_list) / sizeof(*blowfish_list),
603 blowfish_list
604};