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