Revert BlowfishCompat changes (PR #877)

This commit is contained in:
Jeffrey Walton 2019-10-12 09:40:34 -04:00
parent dd005c4bc3
commit b91ce07bfb
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
6 changed files with 41 additions and 142 deletions

View File

@ -3,18 +3,16 @@
NAMESPACE_BEGIN(CryptoPP)
template<class Info, class ByteOrder>
const word32 Blowfish_Base<Info, ByteOrder>::p_init[Info::ROUNDS+2] =
const word32 Blowfish::Base::p_init[Blowfish::ROUNDS+2] =
{
608135816U, 2242054355U, 320440878U, 57701188U,
2752067618U, 698298832U, 137296536U, 3964562569U,
1160258022U, 953160567U, 3193202383U, 887688300U,
3232508343U, 3380367581U, 1065670069U, 3041331479U,
2450970073U, 2306472731U
};
} ;
template<class Info, class ByteOrder>
const word32 Blowfish_Base<Info, ByteOrder>::s_init[4*256] = {
const word32 Blowfish::Base::s_init[4*256] = {
3509652390U, 2564797868U, 805139163U, 3491422135U,
3101798381U, 1780907670U, 3128725573U, 4046225305U,
614570311U, 3012652279U, 134345442U, 2240740374U,
@ -276,10 +274,4 @@ const word32 Blowfish_Base<Info, ByteOrder>::s_init[4*256] = {
3075367218U, 3463963227U, 1469046755U, 985887462U
};
template const word32 Blowfish_Base<Blowfish_Info, BigEndian>::p_init[Blowfish_Info::ROUNDS+2];
template const word32 Blowfish_Base<Blowfish_Info, BigEndian>::s_init[4*256];
template const word32 Blowfish_Base<BlowfishCompat_Info, LittleEndian>::p_init[BlowfishCompat_Info::ROUNDS+2];
template const word32 Blowfish_Base<BlowfishCompat_Info, LittleEndian>::s_init[4*256];
NAMESPACE_END

View File

@ -6,16 +6,9 @@
NAMESPACE_BEGIN(CryptoPP)
extern template const word32 Blowfish_Base<Blowfish_Info, BigEndian>::p_init[Blowfish_Info::ROUNDS+2];
extern template const word32 Blowfish_Base<Blowfish_Info, BigEndian>::s_init[4*256];
extern template const word32 Blowfish_Base<BlowfishCompat_Info, LittleEndian>::p_init[BlowfishCompat_Info::ROUNDS+2];
extern template const word32 Blowfish_Base<BlowfishCompat_Info, LittleEndian>::s_init[4*256];
template<class Info, class ByteOrder>
void Blowfish_Base<Info, ByteOrder>::UncheckedSetKey(const byte *key_string, unsigned int keylength, const NameValuePairs &)
void Blowfish::Base::UncheckedSetKey(const byte *key_string, unsigned int keylength, const NameValuePairs &)
{
this->AssertValidKeyLength(keylength);
AssertValidKeyLength(keylength);
unsigned i, j=0, k;
word32 data, dspace[2] = {0, 0};
@ -24,7 +17,7 @@ void Blowfish_Base<Info, ByteOrder>::UncheckedSetKey(const byte *key_string, uns
memcpy(sbox, s_init, sizeof(s_init));
// Xor key string into encryption key vector
for (i=0 ; i<Info::ROUNDS+2 ; ++i)
for (i=0 ; i<ROUNDS+2 ; ++i)
{
data = 0 ;
for (k=0 ; k<4 ; ++k )
@ -34,22 +27,21 @@ void Blowfish_Base<Info, ByteOrder>::UncheckedSetKey(const byte *key_string, uns
crypt_block(dspace, pbox);
for (i=0; i<Info::ROUNDS; i+=2)
for (i=0; i<ROUNDS; i+=2)
crypt_block(pbox+i, pbox+i+2);
crypt_block(pbox+Info::ROUNDS, sbox);
crypt_block(pbox+ROUNDS, sbox);
for (i=0; i<4*256-2; i+=2)
crypt_block(sbox+i, sbox+i+2);
if (!this->IsForwardTransformation())
for (i=0; i<(Info::ROUNDS+2)/2; i++)
std::swap(pbox[i], pbox[Info::ROUNDS+1-i]);
if (!IsForwardTransformation())
for (i=0; i<(ROUNDS+2)/2; i++)
std::swap(pbox[i], pbox[ROUNDS+1-i]);
}
// this version is only used to make pbox and sbox
template<class Info, class ByteOrder>
void Blowfish_Base<Info, ByteOrder>::crypt_block(const word32 in[2], word32 out[2]) const
void Blowfish::Base::crypt_block(const word32 in[2], word32 out[2]) const
{
word32 left = in[0];
word32 right = in[1];
@ -59,7 +51,7 @@ void Blowfish_Base<Info, ByteOrder>::crypt_block(const word32 in[2], word32 out[
left ^= p[0];
for (unsigned i=0; i<Info::ROUNDS/2; i++)
for (unsigned i=0; i<ROUNDS/2; i++)
{
right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)])
^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)])
@ -70,16 +62,15 @@ void Blowfish_Base<Info, ByteOrder>::crypt_block(const word32 in[2], word32 out[
^ p[2*i+2];
}
right ^= p[Info::ROUNDS+1];
right ^= p[ROUNDS+1];
out[0] = right;
out[1] = left;
}
template<class Info, class ByteOrder>
void Blowfish_Base<Info, ByteOrder>::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
void Blowfish::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
typedef BlockGetAndPut<word32, ByteOrder> Block;
typedef BlockGetAndPut<word32, BigEndian> Block;
word32 left, right;
Block::Get(inBlock)(left)(right);
@ -89,7 +80,7 @@ void Blowfish_Base<Info, ByteOrder>::ProcessAndXorBlock(const byte *inBlock, con
left ^= p[0];
for (unsigned i=0; i<Info::ROUNDS/2; i++)
for (unsigned i=0; i<ROUNDS/2; i++)
{
right ^= (((s[GETBYTE(left,3)] + s[256+GETBYTE(left,2)])
^ s[2*256+GETBYTE(left,1)]) + s[3*256+GETBYTE(left,0)])
@ -100,12 +91,9 @@ void Blowfish_Base<Info, ByteOrder>::ProcessAndXorBlock(const byte *inBlock, con
^ p[2*i+2];
}
right ^= p[Info::ROUNDS+1];
right ^= p[ROUNDS+1];
typename Block::Put(xorBlock, outBlock)(right)(left);
Block::Put(xorBlock, outBlock)(right)(left);
}
template class Blowfish_Base<Blowfish_Info, BigEndian>;
template class Blowfish_Base<BlowfishCompat_Info, LittleEndian>;
NAMESPACE_END

View File

@ -11,25 +11,6 @@
NAMESPACE_BEGIN(CryptoPP)
/// \brief Class specific implementation and overrides used to operate the cipher.
/// \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions
template<class Info, class ByteOrder>
class CRYPTOPP_NO_VTABLE Blowfish_Base : public BlockCipherImpl<Info>
{
public:
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
void UncheckedSetKey(const byte *key_string, unsigned int keylength, const NameValuePairs &params);
private:
void crypt_block(const word32 in[2], word32 out[2]) const;
static const word32 p_init[Info::ROUNDS+2];
static const word32 s_init[4*256];
FixedSizeSecBlock<word32, Info::ROUNDS+2> pbox;
FixedSizeSecBlock<word32, 4*256> sbox;
};
/// \brief Blowfish block cipher information
struct Blowfish_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 4, 56>, public FixedRounds<16>
{
@ -40,31 +21,34 @@ struct Blowfish_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 4,
/// \brief Blowfish block cipher
/// \since Crypto++ 1.0
struct Blowfish : public Blowfish_Info, public BlockCipherDocumentation
class Blowfish : public Blowfish_Info, public BlockCipherDocumentation
{
typedef BlockCipherFinal<ENCRYPTION, Blowfish_Base<Blowfish_Info, BigEndian> > Encryption;
typedef BlockCipherFinal<DECRYPTION, Blowfish_Base<Blowfish_Info, BigEndian> > Decryption;
/// \brief Class specific implementation and overrides used to operate the cipher.
/// \details Implementations and overrides in \p Base apply to both \p ENCRYPTION and \p DECRYPTION directions
class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<Blowfish_Info>
{
public:
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const;
void UncheckedSetKey(const byte *key_string, unsigned int keylength, const NameValuePairs &params);
private:
void crypt_block(const word32 in[2], word32 out[2]) const;
static const word32 p_init[ROUNDS+2];
static const word32 s_init[4*256];
FixedSizeSecBlock<word32, ROUNDS+2> pbox;
FixedSizeSecBlock<word32, 4*256> sbox;
};
public:
typedef BlockCipherFinal<ENCRYPTION, Base> Encryption;
typedef BlockCipherFinal<DECRYPTION, Base> Decryption;
};
typedef Blowfish::Encryption BlowfishEncryption;
typedef Blowfish::Decryption BlowfishDecryption;
/// \brief BlowfishCompat block cipher information
struct BlowfishCompat_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 4, 56>, public FixedRounds<16>
{
CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() {return "BlowfishCompat";}
};
/// \brief BlowfishCompat block cipher
struct BlowfishCompat : public BlowfishCompat_Info, public BlockCipherDocumentation
{
typedef BlockCipherFinal<ENCRYPTION, Blowfish_Base<BlowfishCompat_Info, LittleEndian> > Encryption;
typedef BlockCipherFinal<DECRYPTION, Blowfish_Base<BlowfishCompat_Info, LittleEndian> > Decryption;
};
typedef BlowfishCompat::Encryption BlowfishCompatEncryption;
typedef BlowfishCompat::Decryption BlowfishCompatDecryption;
NAMESPACE_END
#endif

View File

@ -1025,7 +1025,6 @@ bool Validate(int alg, bool thorough)
case 101: result = ValidateSIMECK(); break;
case 102: result = ValidateSIMON(); break;
case 103: result = ValidateSPECK(); break;
case 104: result = ValidateBlowfishCompat(); break;
case 110: result = ValidateSHA3(); break;
case 111: result = ValidateSHAKE(); break;

View File

@ -135,7 +135,6 @@ bool ValidateAll(bool thorough)
pass=ValidateARC4() && pass;
pass=ValidateRC5() && pass;
pass=ValidateBlowfish() && pass;
pass=ValidateBlowfishCompat() && pass;
pass=ValidateThreeWay() && pass;
pass=ValidateGOST() && pass;
pass=ValidateSHARK() && pass;

View File

@ -1126,69 +1126,6 @@ bool ValidateBlowfish()
return pass1 && pass2 && pass3;
}
bool ValidateBlowfishCompat()
{
std::cout << "\nBlowfishCompat validation suite running...\n\n";
bool pass1 = true, pass2 = true, pass3 = true, fail;
BlowfishCompatEncryption enc1; // 32 to 448-bits (4 to 56-bytes)
pass1 = enc1.StaticGetValidKeyLength(3) == 4 && pass1;
pass1 = enc1.StaticGetValidKeyLength(4) == 4 && pass1;
pass1 = enc1.StaticGetValidKeyLength(5) == 5 && pass1;
pass1 = enc1.StaticGetValidKeyLength(8) == 8 && pass1;
pass1 = enc1.StaticGetValidKeyLength(16) == 16 && pass1;
pass1 = enc1.StaticGetValidKeyLength(24) == 24 && pass1;
pass1 = enc1.StaticGetValidKeyLength(32) == 32 && pass1;
pass1 = enc1.StaticGetValidKeyLength(56) == 56 && pass1;
pass1 = enc1.StaticGetValidKeyLength(57) == 56 && pass1;
pass1 = enc1.StaticGetValidKeyLength(60) == 56 && pass1;
pass1 = enc1.StaticGetValidKeyLength(64) == 56 && pass1;
pass1 = enc1.StaticGetValidKeyLength(128) == 56 && pass1;
BlowfishCompatDecryption dec1; // 32 to 448-bits (4 to 56-bytes)
pass2 = dec1.StaticGetValidKeyLength(3) == 4 && pass2;
pass2 = dec1.StaticGetValidKeyLength(4) == 4 && pass2;
pass2 = dec1.StaticGetValidKeyLength(5) == 5 && pass2;
pass2 = dec1.StaticGetValidKeyLength(8) == 8 && pass2;
pass2 = dec1.StaticGetValidKeyLength(16) == 16 && pass2;
pass2 = dec1.StaticGetValidKeyLength(24) == 24 && pass2;
pass2 = dec1.StaticGetValidKeyLength(32) == 32 && pass2;
pass2 = dec1.StaticGetValidKeyLength(56) == 56 && pass2;
pass2 = dec1.StaticGetValidKeyLength(57) == 56 && pass2;
pass2 = dec1.StaticGetValidKeyLength(60) == 56 && pass2;
pass2 = dec1.StaticGetValidKeyLength(64) == 56 && pass2;
pass2 = dec1.StaticGetValidKeyLength(128) == 56 && pass2;
std::cout << (pass1 && pass2 ? "passed:" : "FAILED:") << " Algorithm key lengths\n";
HexEncoder output(new FileSink(std::cout));
const char *key[]={"abcdefghijklmnopqrstuvwxyz", "Who is John Galt?"};
byte *plain[]={(byte *)"BLOWFISH", (byte *)"\xfe\xdc\xba\x98\x76\x54\x32\x10"};
byte *cipher[]={(byte *)"\x82\x4d\x92\x0d\x00\x4d\x7e\xe3", (byte *)"\xd4\xf9\xb0\x06\xd3\x84\x92\x7e"};
byte out[8], outplain[8];
for (int i=0; i<2; i++)
{
ECB_Mode<BlowfishCompat>::Encryption enc2((byte *)key[i], strlen(key[i]));
enc2.ProcessData(out, plain[i], 8);
fail = memcmp(out, cipher[i], 8) != 0;
ECB_Mode<BlowfishCompat>::Decryption dec2((byte *)key[i], strlen(key[i]));
dec2.ProcessData(outplain, cipher[i], 8);
fail = fail || memcmp(outplain, plain[i], 8);
pass3 = pass3 && !fail;
std::cout << (fail ? "FAILED " : "passed ");
std::cout << '\"' << key[i] << '\"';
for (int j=0; j<(signed int)(30-strlen(key[i])); j++)
std::cout << ' ';
output.Put(outplain, 8);
std::cout << " ";
output.Put(out, 8);
std::cout << std::endl;
}
return pass1 && pass2 && pass3;
}
bool ValidateThreeWay()
{
std::cout << "\n3-WAY validation suite running...\n\n";