Initial commit
[keepassx] / src / crypto / blowfish.h
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, 2004 by Michael Buesch <mbuesch@freenet.de>       *
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 #ifndef BLOWFISH_H
25 #define BLOWFISH_H
26
27 #include <qglobal.h>
28 //#include <stdint.h>
29 #include <string>
30 using std::string;
31
32 #define BLOWFISH_BLOCKSIZE      8
33 #define BLOWFISH_ROUNDS         16
34 #define CIPHER_ALGO_BLOWFISH    4       /* blowfish 128 bit key */
35
36 #define uint8_t quint8
37 #define uint16_t quint16
38 #define uint32_t quint32
39 #ifndef byte
40 #define byte quint8
41 #endif
42
43 /** blowfish encryption algorithm.
44   * Derived from libgcrypt-1.1.12
45   */
46
47 class Blowfish
48 {
49         struct BLOWFISH_context
50         {
51                 uint32_t s0[256];
52                 uint32_t s1[256];
53                 uint32_t s2[256];
54                 uint32_t s3[256];
55                 uint32_t p[BLOWFISH_ROUNDS+2];
56         };
57
58 public:
59         Blowfish();
60
61         /** set key to encrypt. if return == 1, it is a weak key. */
62         int bf_setkey( byte *key, unsigned int keylen );
63         /** encrypt inbuf and return it in outbuf.
64           * inbuf and outbuf have to be: buf % 8 == 0
65           * You may check this with getPaddedLen() and pad with NULL.
66           */
67         int bf_encrypt( byte *outbuf, byte *inbuf, unsigned int inbuf_len );
68         /** decrypt inbuf and return it in outbuf.
69           * inbuf and outbuf have to be: buf % 8 == 0
70           * You may check this with getPaddedLen() and pad with NULL.
71           */
72         int bf_decrypt( byte *outbuf, byte *inbuf, unsigned int inbuf_len );
73         /** returns the length, the sting has to be padded to */
74         static unsigned int getPaddedLen(unsigned int inLen)
75                         { return ((8 - (inLen % 8)) + inLen); }
76         /** pad up to 8 bytes. */
77         static void padNull(string *buf);
78         /** remove padded data */
79         static bool unpadNull(string *buf);
80
81 protected:
82 #if BLOWFISH_ROUNDS != 16
83         uint32_t function_F( uint32_t x)
84         {
85                 uint16_t a, b, c, d;
86         #ifdef KEEPASS_BIG_ENDIAN
87                 a = ((byte *) & x)[0];
88                 b = ((byte *) & x)[1];
89                 c = ((byte *) & x)[2];
90                 d = ((byte *) & x)[3];
91         #else
92                 a = ((byte *) & x)[3];
93                 b = ((byte *) & x)[2];
94                 c = ((byte *) & x)[1];
95                 d = ((byte *) & x)[0];
96         #endif
97                 return ((bc.s0[a] + bc.s1[b]) ^ bc.s2[c]) + bc.s3[d];
98         }
99 #endif
100         void R(uint32_t &l, uint32_t &r, uint32_t i, uint32_t *p,
101                uint32_t *s0, uint32_t *s1, uint32_t *s2, uint32_t *s3)
102         {
103                 l ^= p[i];
104         #ifdef KEEPASS_BIG_ENDIAN
105                 r ^= (( s0[((byte*)&l)[0]] + s1[((byte*)&l)[1]])
106                         ^ s2[((byte*)&l)[2]]) + s3[((byte*)&l)[3]];
107         #else
108                 r ^= (( s0[((byte*)&l)[3]] + s1[((byte*)&l)[2]])
109                         ^ s2[((byte*)&l)[1]]) + s3[((byte*)&l)[0]];
110         #endif
111         }
112         void encrypt_block(byte *outbuf, byte *inbuf);
113         void decrypt_block(byte *outbuf, byte *inbuf);
114         void burn_stack(int bytes);
115         void do_encrypt(uint32_t *ret_xl, uint32_t *ret_xr);
116         void do_decrypt(uint32_t *ret_xl, uint32_t *ret_xr);
117         void do_encrypt_block(byte *outbuf, byte *inbuf);
118         void do_decrypt_block(byte *outbuf, byte *inbuf);
119         int do_bf_setkey(byte *key, unsigned int keylen);
120
121 protected:
122         struct BLOWFISH_context bc;
123 };
124
125 #endif