1 /* This file is part of the KDE project
2 Copyright (C) 2001 George Staikos <staikos@kde.org>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
21 // FIXME: should we unroll some loops? Optimization can be done here.
24 /* Implementation of 16 rounds blowfish as described in:
25 * _Applied_Cryptography_ (c) Bruce Schneier, 1996.
33 #include <QtCore/QBool>
35 #include "blowfishtables.h"
38 BlowFish::BlowFish() {
46 bool BlowFish::init() {
47 // Initialize the sboxes
48 for (int i
= 0; i
< 256; i
++) {
61 // Update the sboxes and pbox.
62 for (int i
= 0; i
< 18; i
++) {
64 for (int k
= 0; k
< 4; ++k
) {
65 data
= (data
<< 8) | ((unsigned char *)_key
)[j
++];
66 if (j
>= _keylen
/ 8) {
73 for (int i
= 0; i
< 18; i
+= 2) {
74 encipher(&datal
, &datar
);
79 for (int j
= 0; j
< 4; j
++) {
80 for (int i
= 0; i
< 256; i
+= 2) {
81 encipher(&datal
, &datar
);
87 // Nice code from gpg's implementation...
88 // check to see if the key is weak and return error if so
89 for (int i
= 0; i
< 255; i
++) {
90 for (int j
= i
+ 1; j
< 256; j
++) {
91 if ((_S
[0][i
] == _S
[0][j
]) || (_S
[1][i
] == _S
[1][j
]) ||
92 (_S
[2][i
] == _S
[2][j
]) || (_S
[3][i
] == _S
[3][j
])) {
104 BlowFish::~BlowFish() {
105 delete[] (unsigned char *)_key
;
110 int BlowFish::keyLen() const {
115 bool BlowFish::variableKeyLen() const {
120 bool BlowFish::readyToGo() const {
125 bool BlowFish::setKey(void *key
, int bitlength
) {
126 if (bitlength
<= 0 || bitlength
> 448 || bitlength
% 8 != 0) {
130 delete[] (unsigned char *)_key
;
132 _key
= new unsigned char[bitlength
/ 8];
133 memcpy(_key
, key
, bitlength
/ 8);
140 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
141 #define shuffle(x) do { \
143 x = (r & 0xff000000) >> 24; \
144 x |= (r & 0x00ff0000) >> 8; \
145 x |= (r & 0x0000ff00) << 8; \
146 x |= (r & 0x000000ff) << 24; \
150 int BlowFish::encrypt(void *block
, int len
) {
151 uint32_t *d
= (uint32_t *)block
;
153 if (!_init
|| len
% _blksz
!= 0) {
157 for (int i
= 0; i
< len
/ _blksz
; i
++) {
158 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
163 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
174 int BlowFish::decrypt(void *block
, int len
) {
175 uint32_t *d
= (uint32_t *)block
;
177 if (!_init
|| len
% _blksz
!= 0) {
181 for (int i
= 0; i
< len
/ _blksz
; i
++) {
182 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
187 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
198 uint32_t BlowFish::F(uint32_t x
) {
199 unsigned short a
, b
, c
, d
;
210 y
= _S
[0][a
] + _S
[1][b
];
218 void BlowFish::encipher(uint32_t *xl
, uint32_t *xr
) {
219 uint32_t Xl
= *xl
, Xr
= *xr
, temp
;
221 for (int i
= 0; i
< 16; ++i
) {
225 temp
= Xl
; Xl
= Xr
; Xr
= temp
;
229 temp
= Xl
; Xl
= Xr
; Xr
= temp
;
239 void BlowFish::decipher(uint32_t *xl
, uint32_t *xr
) {
240 uint32_t Xl
= *xl
, Xr
= *xr
, temp
;
242 for (int i
= 17; i
> 1; --i
) {
246 temp
= Xl
; Xl
= Xr
; Xr
= temp
;
250 temp
= Xl
; Xl
= Xr
; Xr
= temp
;