From d49fc3aeac4daa65416751f94943b6611ad247d3 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 10 Apr 2012 08:32:23 +0000 Subject: Rearranged the Cipher system, and added four modes of operation. It's pretty slick, really, and we actually support four of the most common modes. Blowfish is still a template, but it doesn't really need to be anymore... --- src/experimental/blowfish.h | 415 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 408 insertions(+), 7 deletions(-) (limited to 'src/experimental/blowfish.h') diff --git a/src/experimental/blowfish.h b/src/experimental/blowfish.h index c043b12..855ce2b 100644 --- a/src/experimental/blowfish.h +++ b/src/experimental/blowfish.h @@ -3,22 +3,78 @@ #include "bu/cipher.h" +#include "bu/ciphermodeecb.h" +#include "bu/ciphermodecfb.h" +#include "bu/ciphermodecbc.h" +#include "bu/ciphermodeofb.h" + #define NUM_SUBKEYS 18 #define NUM_S_BOXES 4 #define NUM_ENTRIES 256 #define MAX_STRING 256 #define MAX_PASSWD 56 // 448bits +#define F(x) \ + (((SB[0][x.byte.zero] + SB[1][x.byte.one]) ^ SB[2][x.byte.two]) + \ + SB[3][x.byte.three]) +#define revBytes( x ) x = (((x&0xff)<<24)|((x&0xff00)<<8)|((x&0xff0000)>>8)|((x&0xff000000)>>24)) namespace Bu { + template class Blowfish : public Bu::Cipher<8> { public: - Blowfish( Bu::Stream &rNext ); - virtual ~Blowfish(); + Blowfish( Bu::Stream &rNext ) : + Bu::Cipher<8>( rNext ) + { + } + + virtual ~Blowfish() + { + reset(); + } + + void setPassword( const Bu::String &sPass ) + { + reset(); + + uint32_t i,j,len=sPass.getSize(); + Word Work,null0,null1; + + if (len > 0) + { + j = 0; + for (i=0;iword0, &w2 = dwWork->word1; + + w1.word = be32toh( w1.word ); + w2.word = be32toh( w2.word ); + + keyEncipher( w1, w2 ); + + revBytes( w1.word ); + revBytes( w2.word ); + } + + virtual void decipher( void *pData ) + { + DWord *dwWork = (DWord *)pData; + Word &w1 = dwWork->word0, &w2 = dwWork->word1; + + revBytes( w1.word ); + revBytes( w2.word ); + + w1.word ^= PA[17]; + w2.word ^= F(w1)^PA[16]; w1.word ^= F(w2)^PA[15]; + w2.word ^= F(w1)^PA[14]; w1.word ^= F(w2)^PA[13]; + w2.word ^= F(w1)^PA[12]; w1.word ^= F(w2)^PA[11]; + w2.word ^= F(w1)^PA[10]; w1.word ^= F(w2)^PA[9]; + w2.word ^= F(w1)^PA[8]; w1.word ^= F(w2)^PA[7]; + w2.word ^= F(w1)^PA[6]; w1.word ^= F(w2)^PA[5]; + w2.word ^= F(w1)^PA[4]; w1.word ^= F(w2)^PA[3]; + w2.word ^= F(w1)^PA[2]; w1.word ^= F(w2)^PA[1]; + w2.word ^= PA[0]; + + Bu::swap( w1, w2 ); + + w1.word = htobe32( w1.word ); + w2.word = htobe32( w2.word ); + } + + inline void keyEncipher( Word &w1, Word &w2 ) + { + w1.word ^= PA[0]; + w2.word ^= F(w1)^PA[1]; w1.word ^= F(w2)^PA[2]; + w2.word ^= F(w1)^PA[3]; w1.word ^= F(w2)^PA[4]; + w2.word ^= F(w1)^PA[5]; w1.word ^= F(w2)^PA[6]; + w2.word ^= F(w1)^PA[7]; w1.word ^= F(w2)^PA[8]; + w2.word ^= F(w1)^PA[9]; w1.word ^= F(w2)^PA[10]; + w2.word ^= F(w1)^PA[11]; w1.word ^= F(w2)^PA[12]; + w2.word ^= F(w1)^PA[13]; w1.word ^= F(w2)^PA[14]; + w2.word ^= F(w1)^PA[15]; w1.word ^= F(w2)^PA[16]; + w2.word ^= PA[17]; + + Bu::swap( w1, w2 ); + } }; + + typedef CipherModeEcb<8, Blowfish<1> > BlowfishEcb; + typedef CipherModeCfb<8, Blowfish<1> > BlowfishCfb; + typedef CipherModeCbc<8, Blowfish<1> > BlowfishCbc; + typedef CipherModeOfb<8, Blowfish<1> > BlowfishOfb; }; #endif -- cgit v1.2.3