Revert AltiVec and Power8 commits

The strategy of "cleanup under-aligned buffers" is not scaling well. Corner cases are still turing up. The library has some corner-case breaks, like old 32-bit Intels. And it still has not solved the AltiVec and Power8 alignment problems.
For now we are backing out the changes and investigating other strategies
pull/489/head
Jeffrey Walton 2017-09-05 16:28:00 -04:00
parent 23b939c62b
commit 37e02f9e0e
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
18 changed files with 139 additions and 378 deletions

View File

@ -36,20 +36,7 @@ void AuthenticatedSymmetricCipherBase::AuthenticateData(const byte *input, size_
// now process the input data in blocks of blockSize bytes and save the leftovers to m_data // now process the input data in blocks of blockSize bytes and save the leftovers to m_data
if (len >= blockSize) if (len >= blockSize)
{ {
// size_t leftOver = AuthenticateBlocks(input, len); size_t leftOver = AuthenticateBlocks(input, len);
size_t leftOver = 0;
const unsigned int alignment = GetSymmetricCipher().OptimalDataAlignment();
if (IsAlignedOn(input, alignment))
{
leftOver = AuthenticateBlocks(input, len);
}
else
{
AlignedSecByteBlock block(input, len);
leftOver = AuthenticateBlocks(block, len);
}
input += (len - leftOver); input += (len - leftOver);
len = leftOver; len = leftOver;
} }

View File

@ -77,8 +77,7 @@ void CMAC_Base::Update(const byte *input, size_t length)
return; return;
BlockCipher &cipher = AccessCipher(); BlockCipher &cipher = AccessCipher();
const unsigned int blockSize = cipher.BlockSize(); unsigned int blockSize = cipher.BlockSize();
const unsigned int alignment = cipher.OptimalDataAlignment();
if (m_counter > 0) if (m_counter > 0)
{ {
@ -101,20 +100,7 @@ void CMAC_Base::Update(const byte *input, size_t length)
if (length > blockSize) if (length > blockSize)
{ {
CRYPTOPP_ASSERT(m_counter == 0); CRYPTOPP_ASSERT(m_counter == 0);
const byte* is = input; // m_reg is always aligned size_t leftOver = 1 + cipher.AdvancedProcessBlocks(m_reg, input, m_reg, length-1, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);
AlignedSecByteBlock i;
if (!IsAlignedOn(input, alignment))
{
i.Assign(input, length);
is = i.begin();
}
// size_t leftOver = 1 + cipher.AdvancedProcessBlocks(m_reg, input, m_reg, length-1,
// BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);
const int flags = BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput;
size_t leftOver = 1 + cipher.AdvancedProcessBlocks(m_reg, is, m_reg, length-1, flags);
input += (length - leftOver); input += (length - leftOver);
length = leftOver; length = leftOver;
} }

2
cmac.h
View File

@ -34,7 +34,7 @@ protected:
virtual BlockCipher & AccessCipher() =0; virtual BlockCipher & AccessCipher() =0;
void ProcessBuf(); void ProcessBuf();
AlignedSecByteBlock m_reg; SecByteBlock m_reg;
unsigned int m_counter; unsigned int m_counter;
}; };

View File

@ -585,11 +585,11 @@ NAMESPACE_END
#if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) #if (CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64)
#if !defined(CRYPTOPP_ALTIVEC_CRYPTO_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM) #if !defined(CRYPTOPP_POWER8_CRYPTO_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ASM)
# if defined(__CRYPTO__) || defined(__ALTIVEC__) || defined(__POWER8_VECTOR__) # if defined(__CRYPTO__) || defined(__ALTIVEC__) || defined(__POWER8_VECTOR__)
# define CRYPTOPP_ALTIVEC_AES_AVAILABLE 1 //# define CRYPTOPP_POWER8_AES_AVAILABLE 1
# define CRYPTOPP_ALTIVEC_SHA_AVAILABLE 1 //# define CRYPTOPP_POWER8_SHA_AVAILABLE 1
# define CRYPTOPP_ALTIVEC_CRC_AVAILABLE 1 //# define CRYPTOPP_POWER8_CRC_AVAILABLE 1
# endif # endif
#endif #endif
@ -598,7 +598,7 @@ NAMESPACE_END
// ***************** Miscellaneous ******************** // ***************** Miscellaneous ********************
// Nearly all Intel's and AMD's have SSE. Enable it independent of SSE ASM and intrinscs // Nearly all Intel's and AMD's have SSE. Enable it independent of SSE ASM and intrinscs
#if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64) && !defined(CRYPTOPP_DISABLE_ASM) #if (CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_PPC32 || CRYPTOPP_BOOL_PPC64) && !defined(CRYPTOPP_DISABLE_ASM)
#define CRYPTOPP_BOOL_ALIGN16 1 #define CRYPTOPP_BOOL_ALIGN16 1
#else #else
#define CRYPTOPP_BOOL_ALIGN16 0 #define CRYPTOPP_BOOL_ALIGN16 0

View File

@ -30,25 +30,11 @@
#endif #endif
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
typedef std::basic_string<char, std::char_traits<char>, AllocatorWithCleanup<char, true> > aligned_string;
typedef StringSinkTemplate<aligned_string> AlignedStringSink;
NAMESPACE_BEGIN(Test) NAMESPACE_BEGIN(Test)
typedef std::map<std::string, std::string> TestData; typedef std::map<std::string, std::string> TestData;
static bool s_thorough = false; static bool s_thorough = false;
bool operator ==(const std::string& a, const aligned_string& b)
{
return a.length() == b.length() && 0 == std::memcmp(a.data(), b.data(), a.size());
}
bool operator !=(const std::string& a, const aligned_string& b)
{
return !(a == b);
}
class TestFailure : public Exception class TestFailure : public Exception
{ {
public: public:
@ -101,7 +87,7 @@ void RandomizedTransfer(BufferedTransformation &source, BufferedTransformation &
{ {
while (source.MaxRetrievable() > (finish ? 0 : 4096)) while (source.MaxRetrievable() > (finish ? 0 : 4096))
{ {
CRYPTOPP_ALIGN_DATA(16) byte buf[4096+64]; byte buf[4096+64];
size_t start = Test::GlobalRNG().GenerateWord32(0, 63); size_t start = Test::GlobalRNG().GenerateWord32(0, 63);
size_t len = Test::GlobalRNG().GenerateWord32(1, UnsignedMin(4096U, 3*source.MaxRetrievable()/2)); size_t len = Test::GlobalRNG().GenerateWord32(1, UnsignedMin(4096U, 3*source.MaxRetrievable()/2));
len = source.Get(buf+start, len); len = source.Get(buf+start, len);
@ -195,13 +181,6 @@ std::string GetDecodedDatum(const TestData &data, const char *name)
return s; return s;
} }
aligned_string GetAlignedDecodedDatum(const TestData &data, const char *name)
{
aligned_string s;
PutDecodedDatumInto(data, name, AlignedStringSink(s).Ref());
return s;
}
std::string GetOptionalDecodedDatum(const TestData &data, const char *name) std::string GetOptionalDecodedDatum(const TestData &data, const char *name)
{ {
std::string s; std::string s;
@ -210,14 +189,6 @@ std::string GetOptionalDecodedDatum(const TestData &data, const char *name)
return s; return s;
} }
aligned_string GetOptionalAlignedDecodedDatum(const TestData &data, const char *name)
{
aligned_string s;
if (DataExists(data, name))
PutDecodedDatumInto(data, name, AlignedStringSink(s).Ref());
return s;
}
class TestDataNameValuePairs : public NameValuePairs class TestDataNameValuePairs : public NameValuePairs
{ {
public: public:
@ -413,11 +384,11 @@ void TestAsymmetricCipher(TestData &v)
void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters) void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
{ {
const std::string name = GetRequiredDatum(v, "Name"); std::string name = GetRequiredDatum(v, "Name");
const std::string test = GetRequiredDatum(v, "Test"); std::string test = GetRequiredDatum(v, "Test");
const aligned_string key = GetAlignedDecodedDatum(v, "Key"); std::string key = GetDecodedDatum(v, "Key");
const aligned_string plaintext = GetAlignedDecodedDatum(v, "Plaintext"); std::string plaintext = GetDecodedDatum(v, "Plaintext");
TestDataNameValuePairs testDataPairs(v); TestDataNameValuePairs testDataPairs(v);
CombinedNameValuePairs pairs(overrideParameters, testDataPairs); CombinedNameValuePairs pairs(overrideParameters, testDataPairs);
@ -475,17 +446,16 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
// If overrideParameters are specified, the caller is responsible for managing the parameter. // If overrideParameters are specified, the caller is responsible for managing the parameter.
v.erase("Tweak"); v.erase("BlockSize"); v.erase("BlockPaddingScheme"); v.erase("Tweak"); v.erase("BlockSize"); v.erase("BlockPaddingScheme");
// std::string encrypted, xorDigest, ciphertext, ciphertextXorDigest; std::string encrypted, xorDigest, ciphertext, ciphertextXorDigest;
aligned_string encrypted, xorDigest, ciphertext, ciphertextXorDigest;
if (test == "EncryptionMCT" || test == "DecryptionMCT") if (test == "EncryptionMCT" || test == "DecryptionMCT")
{ {
SymmetricCipher *cipher = encryptor.get(); SymmetricCipher *cipher = encryptor.get();
AlignedSecByteBlock buf((byte *)plaintext.data(), plaintext.size()), keybuf((byte *)key.data(), key.size()); SecByteBlock buf((byte *)plaintext.data(), plaintext.size()), keybuf((byte *)key.data(), key.size());
if (test == "DecryptionMCT") if (test == "DecryptionMCT")
{ {
cipher = decryptor.get(); cipher = decryptor.get();
ciphertext = GetAlignedDecodedDatum(v, "Ciphertext"); ciphertext = GetDecodedDatum(v, "Ciphertext");
buf.Assign((byte *)ciphertext.data(), ciphertext.size()); buf.Assign((byte *)ciphertext.data(), ciphertext.size());
} }
@ -503,11 +473,11 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
cipher->SetKey(keybuf, keybuf.size()); cipher->SetKey(keybuf, keybuf.size());
} }
encrypted.assign((char *)buf.begin(), buf.size()); encrypted.assign((char *)buf.begin(), buf.size());
ciphertext = GetAlignedDecodedDatum(v, test == "EncryptionMCT" ? "Ciphertext" : "Plaintext"); ciphertext = GetDecodedDatum(v, test == "EncryptionMCT" ? "Ciphertext" : "Plaintext");
if (encrypted != ciphertext) if (encrypted != ciphertext)
{ {
std::cout << "\nincorrectly encrypted: "; std::cout << "\nincorrectly encrypted: ";
StringSource xx(reinterpret_cast<const byte*>(encrypted.data()), encrypted.size(), false, new HexEncoder(new FileSink(std::cout))); StringSource xx(encrypted, false, new HexEncoder(new FileSink(std::cout)));
xx.Pump(256); xx.Flush(false); xx.Pump(256); xx.Flush(false);
std::cout << "\n"; std::cout << "\n";
SignalTestFailure(); SignalTestFailure();
@ -515,7 +485,7 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
return; return;
} }
StreamTransformationFilter encFilter(*encryptor, new AlignedStringSink(encrypted), StreamTransformationFilter encFilter(*encryptor, new StringSink(encrypted),
static_cast<BlockPaddingSchemeDef::BlockPaddingScheme>(paddingScheme)); static_cast<BlockPaddingSchemeDef::BlockPaddingScheme>(paddingScheme));
RandomizedTransfer(StringStore(plaintext).Ref(), encFilter, true); RandomizedTransfer(StringStore(plaintext).Ref(), encFilter, true);
encFilter.MessageEnd(); encFilter.MessageEnd();
@ -530,10 +500,10 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
CRYPTOPP_ASSERT(encrypted[i] == z[i]); CRYPTOPP_ASSERT(encrypted[i] == z[i]);
}*/ }*/
if (test != "EncryptXorDigest") if (test != "EncryptXorDigest")
ciphertext = GetAlignedDecodedDatum(v, "Ciphertext"); ciphertext = GetDecodedDatum(v, "Ciphertext");
else else
{ {
ciphertextXorDigest = GetAlignedDecodedDatum(v, "CiphertextXorDigest"); ciphertextXorDigest = GetDecodedDatum(v, "CiphertextXorDigest");
xorDigest.append(encrypted, 0, 64); xorDigest.append(encrypted, 0, 64);
for (size_t i=64; i<encrypted.size(); i++) for (size_t i=64; i<encrypted.size(); i++)
xorDigest[i%64] ^= encrypted[i]; xorDigest[i%64] ^= encrypted[i];
@ -541,20 +511,20 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
if (test != "EncryptXorDigest" ? encrypted != ciphertext : xorDigest != ciphertextXorDigest) if (test != "EncryptXorDigest" ? encrypted != ciphertext : xorDigest != ciphertextXorDigest)
{ {
std::cout << "\nincorrectly encrypted: "; std::cout << "\nincorrectly encrypted: ";
StringSource xx(reinterpret_cast<const byte*>(encrypted.data()), encrypted.size(), false, new HexEncoder(new FileSink(std::cout))); StringSource xx(encrypted, false, new HexEncoder(new FileSink(std::cout)));
xx.Pump(2048); xx.Flush(false); xx.Pump(2048); xx.Flush(false);
std::cout << "\n"; std::cout << "\n";
SignalTestFailure(); SignalTestFailure();
} }
aligned_string decrypted; std::string decrypted;
StreamTransformationFilter decFilter(*decryptor, new AlignedStringSink(decrypted), StreamTransformationFilter decFilter(*decryptor, new StringSink(decrypted),
static_cast<BlockPaddingSchemeDef::BlockPaddingScheme>(paddingScheme)); static_cast<BlockPaddingSchemeDef::BlockPaddingScheme>(paddingScheme));
RandomizedTransfer(StringStore(encrypted).Ref(), decFilter, true); RandomizedTransfer(StringStore(encrypted).Ref(), decFilter, true);
decFilter.MessageEnd(); decFilter.MessageEnd();
if (decrypted != plaintext) if (decrypted != plaintext)
{ {
std::cout << "\nincorrectly decrypted: "; std::cout << "\nincorrectly decrypted: ";
StringSource xx(reinterpret_cast<const byte*>(decrypted.data()), decrypted.size(), false, new HexEncoder(new FileSink(std::cout))); StringSource xx(decrypted, false, new HexEncoder(new FileSink(std::cout)));
xx.Pump(256); xx.Flush(false); xx.Pump(256); xx.Flush(false);
std::cout << "\n"; std::cout << "\n";
SignalTestFailure(); SignalTestFailure();
@ -572,13 +542,13 @@ void TestAuthenticatedSymmetricCipher(TestData &v, const NameValuePairs &overrid
std::string type = GetRequiredDatum(v, "AlgorithmType"); std::string type = GetRequiredDatum(v, "AlgorithmType");
std::string name = GetRequiredDatum(v, "Name"); std::string name = GetRequiredDatum(v, "Name");
std::string test = GetRequiredDatum(v, "Test"); std::string test = GetRequiredDatum(v, "Test");
aligned_string key = GetAlignedDecodedDatum(v, "Key"); std::string key = GetDecodedDatum(v, "Key");
aligned_string plaintext = GetOptionalAlignedDecodedDatum(v, "Plaintext"); std::string plaintext = GetOptionalDecodedDatum(v, "Plaintext");
aligned_string ciphertext = GetOptionalAlignedDecodedDatum(v, "Ciphertext"); std::string ciphertext = GetOptionalDecodedDatum(v, "Ciphertext");
aligned_string header = GetOptionalAlignedDecodedDatum(v, "Header"); std::string header = GetOptionalDecodedDatum(v, "Header");
aligned_string footer = GetOptionalAlignedDecodedDatum(v, "Footer"); std::string footer = GetOptionalDecodedDatum(v, "Footer");
aligned_string mac = GetOptionalAlignedDecodedDatum(v, "MAC"); std::string mac = GetOptionalDecodedDatum(v, "MAC");
TestDataNameValuePairs testDataPairs(v); TestDataNameValuePairs testDataPairs(v);
CombinedNameValuePairs pairs(overrideParameters, testDataPairs); CombinedNameValuePairs pairs(overrideParameters, testDataPairs);

View File

@ -32,8 +32,8 @@ static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int ite
size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)H::DIGESTSIZE); size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)H::DIGESTSIZE);
byte b[2]; byte b[2];
AlignedSecByteBlock buf(bufSize); SecByteBlock buf(bufSize);
AlignedSecByteBlock outBuf(bufSize); SecByteBlock outBuf(bufSize);
H hash; H hash;
unsigned int i; unsigned int i;
@ -66,14 +66,14 @@ template <class BC, class H, class Info>
static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, unsigned int iterations, byte *key, byte *IV) static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, unsigned int iterations, byte *key, byte *IV)
{ {
// UBsan. User supplied params, may be NULL // UBsan. User supplied params, may be NULL
AlignedSecByteBlock temp(passphraseLength+saltLength); SecByteBlock temp(passphraseLength+saltLength);
if (passphrase != NULLPTR) if (passphrase != NULLPTR)
memcpy(temp, passphrase, passphraseLength); memcpy(temp, passphrase, passphraseLength);
if (salt != NULLPTR) if (salt != NULLPTR)
memcpy(temp+passphraseLength, salt, saltLength); memcpy(temp+passphraseLength, salt, saltLength);
// OK. Derived params, cannot be NULL // OK. Derived params, cannot be NULL
AlignedSecByteBlock keyIV(Info::KEYLENGTH+Info::BLOCKSIZE); SecByteBlock keyIV(Info::KEYLENGTH+Info::BLOCKSIZE);
Mash<H>(temp, passphraseLength + saltLength, keyIV, Info::KEYLENGTH+Info::BLOCKSIZE, iterations); Mash<H>(temp, passphraseLength + saltLength, keyIV, Info::KEYLENGTH+Info::BLOCKSIZE, iterations);
memcpy(key, keyIV, Info::KEYLENGTH); memcpy(key, keyIV, Info::KEYLENGTH);
memcpy(IV, keyIV+Info::KEYLENGTH, Info::BLOCKSIZE); memcpy(IV, keyIV+Info::KEYLENGTH, Info::BLOCKSIZE);
@ -100,7 +100,7 @@ DataEncryptor<BC,H,Info>::DataEncryptor(const byte *passphrase, size_t passphras
template <class BC, class H, class Info> template <class BC, class H, class Info>
void DataEncryptor<BC,H,Info>::FirstPut(const byte *) void DataEncryptor<BC,H,Info>::FirstPut(const byte *)
{ {
AlignedSecByteBlock salt(DIGESTSIZE), keyCheck(DIGESTSIZE); SecByteBlock salt(DIGESTSIZE), keyCheck(DIGESTSIZE);
H hash; H hash;
// use hash(passphrase | time | clock) as salt // use hash(passphrase | time | clock) as salt
@ -119,8 +119,8 @@ void DataEncryptor<BC,H,Info>::FirstPut(const byte *)
AttachedTransformation()->Put(salt, SALTLENGTH); AttachedTransformation()->Put(salt, SALTLENGTH);
// mash passphrase and salt together into key and IV // mash passphrase and salt together into key and IV
AlignedSecByteBlock key(KEYLENGTH); SecByteBlock key(KEYLENGTH);
AlignedSecByteBlock IV(BLOCKSIZE); SecByteBlock IV(BLOCKSIZE);
GenerateKeyIV<BC,H,Info>(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV); GenerateKeyIV<BC,H,Info>(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV);
m_cipher.SetKeyWithIV(key, key.size(), IV); m_cipher.SetKeyWithIV(key, key.size(), IV);
@ -186,15 +186,15 @@ void DataDecryptor<BC,H,Info>::LastPut(const byte *inString, size_t length)
template <class BC, class H, class Info> template <class BC, class H, class Info>
void DataDecryptor<BC,H,Info>::CheckKey(const byte *salt, const byte *keyCheck) void DataDecryptor<BC,H,Info>::CheckKey(const byte *salt, const byte *keyCheck)
{ {
AlignedSecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DIGESTSIZE)); SecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DIGESTSIZE));
H hash; H hash;
hash.Update(m_passphrase, m_passphrase.size()); hash.Update(m_passphrase, m_passphrase.size());
hash.Update(salt, SALTLENGTH); hash.Update(salt, SALTLENGTH);
hash.Final(check); hash.Final(check);
AlignedSecByteBlock key(KEYLENGTH); SecByteBlock key(KEYLENGTH);
AlignedSecByteBlock IV(BLOCKSIZE); SecByteBlock IV(BLOCKSIZE);
GenerateKeyIV<BC,H,Info>(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV); GenerateKeyIV<BC,H,Info>(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, ITERATIONS, key, IV);
m_cipher.SetKeyWithIV(key, key.size(), IV); m_cipher.SetKeyWithIV(key, key.size(), IV);
@ -222,7 +222,7 @@ template <class H, class MAC>
static MAC* NewDataEncryptorMAC(const byte *passphrase, size_t passphraseLength) static MAC* NewDataEncryptorMAC(const byte *passphrase, size_t passphraseLength)
{ {
size_t macKeyLength = MAC::StaticGetValidKeyLength(16); size_t macKeyLength = MAC::StaticGetValidKeyLength(16);
AlignedSecByteBlock macKey(macKeyLength); SecByteBlock macKey(macKeyLength);
// since the MAC is encrypted there is no reason to mash the passphrase for many iterations // since the MAC is encrypted there is no reason to mash the passphrase for many iterations
Mash<H>(passphrase, passphraseLength, macKey, macKeyLength, 1); Mash<H>(passphrase, passphraseLength, macKey, macKeyLength, 1);
return new MAC(macKey, macKeyLength); return new MAC(macKey, macKeyLength);

View File

@ -23,12 +23,6 @@
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
#if CRYPTOPP_BOOL_ALIGN16
const unsigned int s_alignment = 16;
#else
const unsigned int s_alignment = GetAlignmentOf<word32>();
#endif
Filter::Filter(BufferedTransformation *attachment) Filter::Filter(BufferedTransformation *attachment)
: m_attachment(attachment), m_inputPosition(0), m_continueAt(0) : m_attachment(attachment), m_inputPosition(0), m_continueAt(0)
{ {
@ -292,29 +286,29 @@ byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(size_t &numberOfBy
size_t FilterWithBufferedInput::BlockQueue::GetAll(byte *outString) size_t FilterWithBufferedInput::BlockQueue::GetAll(byte *outString)
{ {
// Avoid passing NULL pointer to std::memcpy // Avoid passing NULL pointer to memcpy
if (!outString) return 0; if (!outString) return 0;
size_t size = m_size; size_t size = m_size;
size_t numberOfBytes = m_maxBlocks*m_blockSize; size_t numberOfBytes = m_maxBlocks*m_blockSize;
const byte *ptr = GetContigousBlocks(numberOfBytes); const byte *ptr = GetContigousBlocks(numberOfBytes);
std::memcpy(outString, ptr, numberOfBytes); memcpy(outString, ptr, numberOfBytes);
std::memcpy(outString+numberOfBytes, m_begin, m_size); memcpy(outString+numberOfBytes, m_begin, m_size);
m_size = 0; m_size = 0;
return size; return size;
} }
void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, size_t length) void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, size_t length)
{ {
// Avoid passing NULL pointer to std::memcpy // Avoid passing NULL pointer to memcpy
if (!inString || !length) return; if (!inString || !length) return;
CRYPTOPP_ASSERT(m_size + length <= m_buffer.size()); CRYPTOPP_ASSERT(m_size + length <= m_buffer.size());
byte *end = (m_size < size_t(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size(); byte *end = (m_size < size_t(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size();
const size_t len = STDMIN(length, size_t(m_buffer.end()-end)); size_t len = STDMIN(length, size_t(m_buffer.end()-end));
std::memcpy(end, inString, len); memcpy(end, inString, len);
if (len < length) if (len < length)
std::memcpy(m_buffer, inString+len, length-len); memcpy(m_buffer, inString+len, length-len);
m_size += length; m_size += length;
} }
@ -389,16 +383,8 @@ size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length
if (newLength > m_lastSize) if (newLength > m_lastSize)
{ {
const size_t len = newLength - m_lastSize; size_t len = newLength - m_lastSize;
if (IsAlignedOn(inString, s_alignment))
{
NextPutMaybeModifiable(inString, len, modifiable); NextPutMaybeModifiable(inString, len, modifiable);
}
else
{
AlignedSecByteBlock block(inString, len);
NextPutMaybeModifiable(block, block.size(), modifiable);
}
inString += len; inString += len;
newLength -= len; newLength -= len;
} }
@ -414,7 +400,7 @@ size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length
if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0) if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0)
{ {
CRYPTOPP_ASSERT(m_queue.CurrentSize() < m_blockSize); CRYPTOPP_ASSERT(m_queue.CurrentSize() < m_blockSize);
const size_t len = m_blockSize - m_queue.CurrentSize(); size_t len = m_blockSize - m_queue.CurrentSize();
m_queue.Put(inString, len); m_queue.Put(inString, len);
inString += len; inString += len;
NextPutModifiable(m_queue.GetBlock(), m_blockSize); NextPutModifiable(m_queue.GetBlock(), m_blockSize);
@ -423,16 +409,8 @@ size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length
if (newLength >= m_blockSize + m_lastSize) if (newLength >= m_blockSize + m_lastSize)
{ {
const size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize); size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize);
if (IsAlignedOn(inString, s_alignment))
{
NextPutMaybeModifiable(inString, len, modifiable); NextPutMaybeModifiable(inString, len, modifiable);
}
else
{
AlignedSecByteBlock block(inString, len);
NextPutMaybeModifiable(block, block.size(), modifiable);
}
inString += len; inString += len;
newLength -= len; newLength -= len;
} }
@ -472,7 +450,7 @@ void FilterWithBufferedInput::ForceNextPut()
} }
else else
{ {
size_t len = 0; size_t len;
while ((len = m_queue.CurrentSize()) > 0) while ((len = m_queue.CurrentSize()) > 0)
NextPutModifiable(m_queue.GetContigousBlocks(len), len); NextPutModifiable(m_queue.GetContigousBlocks(len), len);
} }
@ -557,7 +535,7 @@ size_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool bl
{ {
CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking); CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking);
// Avoid passing NULL pointer to std::memcpy. Using memmove due to // Avoid passing NULL pointer to memcpy. Using memmove due to
// Valgrind finding on overlapping buffers. // Valgrind finding on overlapping buffers.
size_t copied = 0; size_t copied = 0;
if (m_buf && begin) if (m_buf && begin)
@ -706,7 +684,7 @@ void StreamTransformationFilter::LastPut(const byte *inString, size_t length)
// do padding // do padding
size_t blockSize = STDMAX(minLastBlockSize, (size_t)m_cipher.MandatoryBlockSize()); size_t blockSize = STDMAX(minLastBlockSize, (size_t)m_cipher.MandatoryBlockSize());
space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, blockSize); space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, blockSize);
if (inString) {std::memcpy(space, inString, length);} if (inString) {memcpy(space, inString, length);}
memset(space + length, 0, blockSize - length); memset(space + length, 0, blockSize - length);
m_cipher.ProcessLastBlock(space, space, blockSize); m_cipher.ProcessLastBlock(space, space, blockSize);
AttachedTransformation()->Put(space, blockSize); AttachedTransformation()->Put(space, blockSize);
@ -738,7 +716,7 @@ void StreamTransformationFilter::LastPut(const byte *inString, size_t length)
if (m_cipher.IsForwardTransformation()) if (m_cipher.IsForwardTransformation())
{ {
CRYPTOPP_ASSERT(length < s); CRYPTOPP_ASSERT(length < s);
if (inString) {std::memcpy(space, inString, length);} if (inString) {memcpy(space, inString, length);}
if (m_padding == PKCS_PADDING) if (m_padding == PKCS_PADDING)
{ {
CRYPTOPP_ASSERT(s < 256); CRYPTOPP_ASSERT(s < 256);
@ -855,7 +833,7 @@ void HashVerificationFilter::FirstPut(const byte *inString)
if (m_flags & HASH_AT_BEGIN) if (m_flags & HASH_AT_BEGIN)
{ {
m_expectedHash.New(m_digestSize); m_expectedHash.New(m_digestSize);
if (inString) {std::memcpy(m_expectedHash, inString, m_expectedHash.size());} if (inString) {memcpy(m_expectedHash, inString, m_expectedHash.size());}
if (m_flags & PUT_HASH) if (m_flags & PUT_HASH)
AttachedTransformation()->Put(inString, m_expectedHash.size()); AttachedTransformation()->Put(inString, m_expectedHash.size());
} }
@ -1050,7 +1028,7 @@ void SignatureVerificationFilter::FirstPut(const byte *inString)
else else
{ {
m_signature.New(m_verifier.SignatureLength()); m_signature.New(m_verifier.SignatureLength());
if (inString) {std::memcpy(m_signature, inString, m_signature.size());} if (inString) {memcpy(m_signature, inString, m_signature.size());}
} }
if (m_flags & PUT_SIGNATURE) if (m_flags & PUT_SIGNATURE)
@ -1150,7 +1128,7 @@ size_t StringStore::TransferTo2(BufferedTransformation &target, lword &transferB
size_t StringStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const size_t StringStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
{ {
size_t i = UnsignedMin(m_length, m_count+begin); size_t i = UnsignedMin(m_length, m_count+begin);
const size_t len = UnsignedMin(m_length-i, end-begin); size_t len = UnsignedMin(m_length-i, end-begin);
size_t blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking); size_t blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking);
if (!blockedBytes) if (!blockedBytes)
begin += len; begin += len;
@ -1182,7 +1160,7 @@ size_t NullStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lwo
static const byte nullBytes[128] = {0}; static const byte nullBytes[128] = {0};
while (begin < end) while (begin < end)
{ {
const size_t len = (size_t)STDMIN(end-begin, lword(128)); size_t len = (size_t)STDMIN(end-begin, lword(128));
size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking); size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking);
if (blockedBytes) if (blockedBytes)
return blockedBytes; return blockedBytes;

View File

@ -210,7 +210,7 @@ struct CRYPTOPP_DLL FilterPutSpaceHelper
{return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);} {return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);}
//! \brief Temporay working space //! \brief Temporay working space
AlignedSecByteBlock m_tempSpace; SecByteBlock m_tempSpace;
}; };
//! \class MeterFilter //! \class MeterFilter
@ -414,7 +414,7 @@ protected:
size_t MaxSize() const {return m_buffer.size();} size_t MaxSize() const {return m_buffer.size();}
private: private:
AlignedSecByteBlock m_buffer; SecByteBlock m_buffer;
size_t m_blockSize, m_maxBlocks, m_size; size_t m_blockSize, m_maxBlocks, m_size;
byte *m_begin; byte *m_begin;
}; };

169
modes.cpp
View File

@ -34,8 +34,7 @@ void CFB_ModePolicy::Iterate(byte *output, const byte *input, CipherDir dir, siz
{ {
CRYPTOPP_ASSERT(input); CRYPTOPP_ASSERT(input);
CRYPTOPP_ASSERT(output); CRYPTOPP_ASSERT(output);
// CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation());
CRYPTOPP_ASSERT(m_feedbackSize == BlockSize()); CRYPTOPP_ASSERT(m_feedbackSize == BlockSize());
const unsigned int s = BlockSize(); const unsigned int s = BlockSize();
@ -44,23 +43,21 @@ void CFB_ModePolicy::Iterate(byte *output, const byte *input, CipherDir dir, siz
m_cipher->ProcessAndXorBlock(m_register, input, output); m_cipher->ProcessAndXorBlock(m_register, input, output);
if (iterationCount > 1) if (iterationCount > 1)
m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0); m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0);
std::memcpy(m_register, output+(iterationCount-1)*s, s); memcpy(m_register, output+(iterationCount-1)*s, s);
} }
else else
{ {
std::memcpy(m_temp, input+(iterationCount-1)*s, s); // make copy first in case of in-place decryption memcpy(m_temp, input+(iterationCount-1)*s, s); // make copy first in case of in-place decryption
if (iterationCount > 1) if (iterationCount > 1)
m_cipher->AdvancedProcessBlocks(input, input+s, output+s, (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection); m_cipher->AdvancedProcessBlocks(input, input+s, output+s, (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection);
m_cipher->ProcessAndXorBlock(m_register, input, output); m_cipher->ProcessAndXorBlock(m_register, input, output);
std::memcpy(m_register, m_temp, s); memcpy(m_register, m_temp, s);
} }
} }
void CFB_ModePolicy::TransformRegister() void CFB_ModePolicy::TransformRegister()
{ {
// CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation());
m_cipher->ProcessBlock(m_register, m_temp); m_cipher->ProcessBlock(m_register, m_temp);
unsigned int updateSize = BlockSize()-m_feedbackSize; unsigned int updateSize = BlockSize()-m_feedbackSize;
memmove_s(m_register, m_register.size(), m_register+m_feedbackSize, updateSize); memmove_s(m_register, m_register.size(), m_register+m_feedbackSize, updateSize);
@ -89,16 +86,12 @@ void CFB_ModePolicy::ResizeBuffers()
void OFB_ModePolicy::WriteKeystream(byte *keystreamBuffer, size_t iterationCount) void OFB_ModePolicy::WriteKeystream(byte *keystreamBuffer, size_t iterationCount)
{ {
CRYPTOPP_ASSERT(keystreamBuffer); CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); // OFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
CRYPTOPP_ASSERT(iterationCount); unsigned int s = BlockSize();
// OFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation());
const unsigned int s = BlockSize();
m_cipher->ProcessBlock(m_register, keystreamBuffer); m_cipher->ProcessBlock(m_register, keystreamBuffer);
if (iterationCount > 1) if (iterationCount > 1)
m_cipher->AdvancedProcessBlocks(keystreamBuffer, NULLPTR, keystreamBuffer+s, s*(iterationCount-1), 0); m_cipher->AdvancedProcessBlocks(keystreamBuffer, NULLPTR, keystreamBuffer+s, s*(iterationCount-1), 0);
std::memcpy(m_register, keystreamBuffer+s*(iterationCount-1), s); memcpy(m_register, keystreamBuffer+s*(iterationCount-1), s);
} }
void OFB_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length) void OFB_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
@ -128,44 +121,18 @@ void CTR_ModePolicy::IncrementCounterBy256()
void CTR_ModePolicy::OperateKeystream(KeystreamOperation /*operation*/, byte *output, const byte *input, size_t iterationCount) void CTR_ModePolicy::OperateKeystream(KeystreamOperation /*operation*/, byte *output, const byte *input, size_t iterationCount)
{ {
CRYPTOPP_ASSERT(output); CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation()); // CTR mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
CRYPTOPP_ASSERT(iterationCount); unsigned int s = BlockSize();
// CTR mode needs the "encrypt" direction of the underlying block cipher, even to decrypt unsigned int inputIncrement = input ? s : 0;
CRYPTOPP_ASSERT(m_cipher->IsForwardTransformation());
const unsigned int s = BlockSize();
const unsigned int inputIncrement = input ? s : 0;
const unsigned int alignment = m_cipher->OptimalDataAlignment();
const byte* is = input; byte* os = output;
AlignedSecByteBlock i, o;
while (iterationCount) while (iterationCount)
{ {
byte lsb = m_counterArray[s-1]; byte lsb = m_counterArray[s-1];
const size_t blocks = UnsignedMin(iterationCount, 256U-lsb); size_t blocks = UnsignedMin(iterationCount, 256U-lsb);
m_cipher->AdvancedProcessBlocks(m_counterArray, input, output, blocks*s, BlockTransformation::BT_InBlockIsCounter|BlockTransformation::BT_AllowParallel);
is = input; os = output;
if(!IsAlignedOn(input, alignment))
{
i.Assign(input, blocks*inputIncrement);
is = i.begin();
}
if(!IsAlignedOn(output, alignment))
{
o.Assign(output, blocks*s);
os = o.begin();
}
m_cipher->AdvancedProcessBlocks(m_counterArray, is, os, blocks*s, BlockTransformation::BT_InBlockIsCounter|BlockTransformation::BT_AllowParallel);
if ((m_counterArray[s-1] = lsb + (byte)blocks) == 0) if ((m_counterArray[s-1] = lsb + (byte)blocks) == 0)
IncrementCounterBy256(); IncrementCounterBy256();
if(!IsAlignedOn(output, alignment))
{
std::memcpy(output, os, blocks*s);
}
output += blocks*s; output += blocks*s;
input += blocks*inputIncrement; input += blocks*inputIncrement;
iterationCount -= blocks; iterationCount -= blocks;
@ -183,9 +150,6 @@ void CTR_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv,
void BlockOrientedCipherModeBase::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params) void BlockOrientedCipherModeBase::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
{ {
CRYPTOPP_ASSERT(key);
CRYPTOPP_ASSERT(length);
m_cipher->SetKey(key, length, params); m_cipher->SetKey(key, length, params);
ResizeBuffers(); ResizeBuffers();
if (IsResynchronizable()) if (IsResynchronizable())
@ -204,85 +168,32 @@ void BlockOrientedCipherModeBase::ResizeBuffers()
void ECB_OneWay::ProcessData(byte *outString, const byte *inString, size_t length) void ECB_OneWay::ProcessData(byte *outString, const byte *inString, size_t length)
{ {
CRYPTOPP_ASSERT(outString);
CRYPTOPP_ASSERT(inString);
CRYPTOPP_ASSERT(length);
CRYPTOPP_ASSERT(length%BlockSize()==0); CRYPTOPP_ASSERT(length%BlockSize()==0);
m_cipher->AdvancedProcessBlocks(inString, NULLPTR, outString, length, BlockTransformation::BT_AllowParallel);
const unsigned int blockSize = BlockSize();
const unsigned int alignment = m_cipher->OptimalDataAlignment();
const byte* is = inString; byte* os = outString;
AlignedSecByteBlock i, o;
if(!IsAlignedOn(inString, alignment))
{
i.Assign(inString, length);
is = i.begin();
}
if(!IsAlignedOn(outString, alignment))
{
o.New(length);
os = o.begin();
}
m_cipher->AdvancedProcessBlocks(is, NULLPTR, os, length, BlockTransformation::BT_AllowParallel);
if(!IsAlignedOn(outString, alignment))
{
std::memcpy(outString, os, length);
}
} }
void CBC_Encryption::ProcessData(byte *outString, const byte *inString, size_t length) void CBC_Encryption::ProcessData(byte *outString, const byte *inString, size_t length)
{ {
CRYPTOPP_ASSERT(outString);
CRYPTOPP_ASSERT(inString);
CRYPTOPP_ASSERT(length);
CRYPTOPP_ASSERT(length%BlockSize()==0);
if (!length) if (!length)
return; return;
CRYPTOPP_ASSERT(length%BlockSize()==0);
const unsigned int blockSize = BlockSize(); unsigned int blockSize = BlockSize();
const unsigned int alignment = m_cipher->OptimalDataAlignment();
const byte* is = inString; byte* os = outString;
AlignedSecByteBlock i, o;
if(!IsAlignedOn(inString, alignment))
{
i.Assign(inString, length);
is = i.begin();
}
if(!IsAlignedOn(outString, alignment))
{
o.New(length);
os = o.begin();
}
m_cipher->AdvancedProcessBlocks(inString, m_register, outString, blockSize, BlockTransformation::BT_XorInput); m_cipher->AdvancedProcessBlocks(inString, m_register, outString, blockSize, BlockTransformation::BT_XorInput);
if (length > blockSize) if (length > blockSize)
m_cipher->AdvancedProcessBlocks(inString+blockSize, outString, outString+blockSize, length-blockSize, BlockTransformation::BT_XorInput); m_cipher->AdvancedProcessBlocks(inString+blockSize, outString, outString+blockSize, length-blockSize, BlockTransformation::BT_XorInput);
std::memcpy(m_register, outString + length - blockSize, blockSize); memcpy(m_register, outString + length - blockSize, blockSize);
if(!IsAlignedOn(outString, alignment))
{
std::memcpy(outString, os, length);
}
} }
void CBC_CTS_Encryption::ProcessLastBlock(byte *outString, const byte *inString, size_t length) void CBC_CTS_Encryption::ProcessLastBlock(byte *outString, const byte *inString, size_t length)
{ {
CRYPTOPP_ASSERT(outString);
CRYPTOPP_ASSERT(inString);
CRYPTOPP_ASSERT(length);
if (length <= BlockSize()) if (length <= BlockSize())
{ {
if (!m_stolenIV) if (!m_stolenIV)
throw InvalidArgument("CBC_Encryption: message is too short for ciphertext stealing"); throw InvalidArgument("CBC_Encryption: message is too short for ciphertext stealing");
// steal from IV // steal from IV
std::memcpy(outString, m_register, length); memcpy(outString, m_register, length);
outString = m_stolenIV; outString = m_stolenIV;
} }
else else
@ -292,13 +203,13 @@ void CBC_CTS_Encryption::ProcessLastBlock(byte *outString, const byte *inString,
m_cipher->ProcessBlock(m_register); m_cipher->ProcessBlock(m_register);
inString += BlockSize(); inString += BlockSize();
length -= BlockSize(); length -= BlockSize();
std::memcpy(outString+BlockSize(), m_register, length); memcpy(outString+BlockSize(), m_register, length);
} }
// output last full ciphertext block // output last full ciphertext block
xorbuf(m_register, inString, length); xorbuf(m_register, inString, length);
m_cipher->ProcessBlock(m_register); m_cipher->ProcessBlock(m_register);
std::memcpy(outString, m_register, BlockSize()); memcpy(outString, m_register, BlockSize());
} }
void CBC_Decryption::ResizeBuffers() void CBC_Decryption::ResizeBuffers()
@ -309,46 +220,20 @@ void CBC_Decryption::ResizeBuffers()
void CBC_Decryption::ProcessData(byte *outString, const byte *inString, size_t length) void CBC_Decryption::ProcessData(byte *outString, const byte *inString, size_t length)
{ {
CRYPTOPP_ASSERT(outString);
CRYPTOPP_ASSERT(inString);
CRYPTOPP_ASSERT(length && length%BlockSize()==0);
if (!length) if (!length)
return; return;
CRYPTOPP_ASSERT(length%BlockSize()==0);
const unsigned int blockSize = BlockSize(); unsigned int blockSize = BlockSize();
const unsigned int alignment = m_cipher->OptimalDataAlignment(); memcpy(m_temp, inString+length-blockSize, blockSize); // save copy now in case of in-place decryption
bool align = !IsAlignedOn(inString, alignment) || !IsAlignedOn(outString, alignment);
if (align && false)
{
AlignedSecByteBlock i(length), o(length);
std::memcpy(i, inString, length);
std::memcpy(o, outString+length-blockSize, blockSize); // copy tail
std::memcpy(m_temp, i+length-blockSize, blockSize); // save copy now in case of in-place decryption
if (length > blockSize)
m_cipher->AdvancedProcessBlocks(i+blockSize, i, o+blockSize, length-blockSize, BlockTransformation::BT_ReverseDirection|BlockTransformation::BT_AllowParallel);
m_cipher->ProcessAndXorBlock(i, m_register, o);
m_register.swap(m_temp);
std::memcpy(outString, o, length);
}
else
{
std::memcpy(m_temp, inString+length-blockSize, blockSize); // save copy now in case of in-place decryption
if (length > blockSize) if (length > blockSize)
m_cipher->AdvancedProcessBlocks(inString+blockSize, inString, outString+blockSize, length-blockSize, BlockTransformation::BT_ReverseDirection|BlockTransformation::BT_AllowParallel); m_cipher->AdvancedProcessBlocks(inString+blockSize, inString, outString+blockSize, length-blockSize, BlockTransformation::BT_ReverseDirection|BlockTransformation::BT_AllowParallel);
m_cipher->ProcessAndXorBlock(inString, m_register, outString); m_cipher->ProcessAndXorBlock(inString, m_register, outString);
m_register.swap(m_temp); m_register.swap(m_temp);
} }
}
void CBC_CTS_Decryption::ProcessLastBlock(byte *outString, const byte *inString, size_t length) void CBC_CTS_Decryption::ProcessLastBlock(byte *outString, const byte *inString, size_t length)
{ {
CRYPTOPP_ASSERT(outString);
CRYPTOPP_ASSERT(inString);
CRYPTOPP_ASSERT(length);
const byte *pn, *pn1; const byte *pn, *pn1;
bool stealIV = length <= BlockSize(); bool stealIV = length <= BlockSize();
@ -365,17 +250,17 @@ void CBC_CTS_Decryption::ProcessLastBlock(byte *outString, const byte *inString,
} }
// decrypt last partial plaintext block // decrypt last partial plaintext block
std::memcpy(m_temp, pn1, BlockSize()); memcpy(m_temp, pn1, BlockSize());
m_cipher->ProcessBlock(m_temp); m_cipher->ProcessBlock(m_temp);
xorbuf(m_temp, pn, length); xorbuf(m_temp, pn, length);
if (stealIV) if (stealIV)
std::memcpy(outString, m_temp, length); memcpy(outString, m_temp, length);
else else
{ {
std::memcpy(outString+BlockSize(), m_temp, length); memcpy(outString+BlockSize(), m_temp, length);
// decrypt next to last plaintext block // decrypt next to last plaintext block
std::memcpy(m_temp, pn, length); memcpy(m_temp, pn, length);
m_cipher->ProcessBlock(m_temp); m_cipher->ProcessBlock(m_temp);
xorbuf(outString, m_temp, m_register, BlockSize()); xorbuf(outString, m_temp, m_register, BlockSize());
} }

22
modes.h
View File

@ -81,7 +81,7 @@ public:
} }
protected: protected:
CipherModeBase() : m_cipher(NULLPTR), m_register(0) {} CipherModeBase() : m_cipher(NULLPTR) {}
inline unsigned int BlockSize() const {CRYPTOPP_ASSERT(m_register.size() > 0); return (unsigned int)m_register.size();} inline unsigned int BlockSize() const {CRYPTOPP_ASSERT(m_register.size() > 0); return (unsigned int)m_register.size();}
virtual void SetFeedbackSize(unsigned int feedbackSize) virtual void SetFeedbackSize(unsigned int feedbackSize)
{ {
@ -134,7 +134,7 @@ protected:
void SetFeedbackSize(unsigned int feedbackSize); void SetFeedbackSize(unsigned int feedbackSize);
void ResizeBuffers(); void ResizeBuffers();
AlignedSecByteBlock m_temp; SecByteBlock m_temp;
unsigned int m_feedbackSize; unsigned int m_feedbackSize;
}; };
@ -209,7 +209,7 @@ protected:
bool RequireAlignedInput() const {return true;} bool RequireAlignedInput() const {return true;}
virtual void ResizeBuffers(); virtual void ResizeBuffers();
AlignedSecByteBlock m_buffer; SecByteBlock m_buffer;
}; };
//! \class ECB_OneWay //! \class ECB_OneWay
@ -436,8 +436,7 @@ struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
typedef Encryption Decryption; typedef Encryption Decryption;
}; };
//! \class CBC_Mode //! CBC mode
//! \brief CBC block cipher mode of operation.
template <class CIPHER> template <class CIPHER>
struct CBC_Mode : public CipherModeDocumentation struct CBC_Mode : public CipherModeDocumentation
{ {
@ -448,16 +447,14 @@ struct CBC_Mode : public CipherModeDocumentation
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Encryption>; CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Encryption>;
CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Decryption>; CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher<CBC_Decryption>;
//! \class CBC_Mode_ExternalCipher //! CBC mode, external cipher
//! \brief CBC mode, external cipher.
struct CBC_Mode_ExternalCipher : public CipherModeDocumentation struct CBC_Mode_ExternalCipher : public CipherModeDocumentation
{ {
typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption> Encryption; typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption> Encryption;
typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption> Decryption; typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption> Decryption;
}; };
//! \class CBC_CTS_Mode //! CBC mode with ciphertext stealing
//! \brief CTS block cipher mode of operation.
template <class CIPHER> template <class CIPHER>
struct CBC_CTS_Mode : public CipherModeDocumentation struct CBC_CTS_Mode : public CipherModeDocumentation
{ {
@ -476,6 +473,13 @@ struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption> Decryption; typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption> Decryption;
}; };
//#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
//typedef CFB_Mode_ExternalCipher::Encryption CFBEncryption;
//typedef CFB_Mode_ExternalCipher::Decryption CFBDecryption;
//typedef OFB_Mode_ExternalCipher::Encryption OFB;
//typedef CTR_Mode_ExternalCipher::Encryption CounterMode;
//#endif
NAMESPACE_END NAMESPACE_END
// Issue 340 // Issue 340

View File

@ -17,7 +17,7 @@ void Poly1305_Base<T>::UncheckedSetKey(const byte *key, unsigned int length, con
if (key && length) if (key && length)
{ {
// key is {k,r} pair, r is 16 bytes // key is {k,r} pair, r is 16 bytes
length = SaturatingSubtract(length, static_cast<unsigned int>(BLOCKSIZE)); length = SaturatingSubtract(length, (unsigned)BLOCKSIZE);
m_cipher.SetKey(key, length); m_cipher.SetKey(key, length);
key += length; key += length;
@ -34,9 +34,7 @@ void Poly1305_Base<T>::UncheckedSetKey(const byte *key, unsigned int length, con
if (params.GetValue(Name::IV(), t) && t.begin() && t.size()) if (params.GetValue(Name::IV(), t) && t.begin() && t.size())
{ {
// Nonce key is a class member to avoid the zeroizer on a temporary // Nonce key is a class member to avoid the zeroizer on a temporary
CRYPTOPP_ASSERT(t.size() == m_nk.size()); m_cipher.ProcessBlock(t.begin(), m_nk.begin());
std::memcpy(m_nk.begin(), t.begin(), t.size());
m_cipher.ProcessBlock(m_nk.begin(), m_nk.begin());
m_n[0] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 0); m_n[0] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 0);
m_n[1] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 4); m_n[1] = GetWord<word32>(false, LITTLE_ENDIAN_ORDER, m_nk + 4);

View File

@ -10,9 +10,6 @@
// Skip Hovsmith and Barry O'Rourke for the mbedTLS project. Stepping // Skip Hovsmith and Barry O'Rourke for the mbedTLS project. Stepping
// mbedTLS under a debugger was helped for us to determine problems // mbedTLS under a debugger was helped for us to determine problems
// with our subkey generation and scheduling. // with our subkey generation and scheduling.
//
// AltiVec and Power8 code based on "POWER8 in-core cryptography."
// http://www.ibm.com/developerworks/library/se-power8-in-core-cryptography/index.html
#include "pch.h" #include "pch.h"
#include "config.h" #include "config.h"
@ -27,7 +24,7 @@
// Hack... We are supposed to use <nmmintrin.h>. GCC 4.8, LLVM Clang 3.5 // Hack... We are supposed to use <nmmintrin.h>. GCC 4.8, LLVM Clang 3.5
// and Apple Clang 6.0 conflates SSE4.1 and SSE4.2. If we use <nmmintrin.h> // and Apple Clang 6.0 conflates SSE4.1 and SSE4.2. If we use <nmmintrin.h>
// then compile fails with "SSE4.2 instruction set not enabled". Also see // then compile fails with "SSE4.2 instruction set not enabled". Also see
// http://gcc.gnu.org/ml/gcc-help/2017-08/msg00015.html. // https://gcc.gnu.org/ml/gcc-help/2017-08/msg00015.html.
# include "smmintrin.h" # include "smmintrin.h"
# include "wmmintrin.h" # include "wmmintrin.h"
#endif #endif

View File

@ -220,15 +220,6 @@ void Rijndael::Base::FillDecTable()
s_TdFilled = true; s_TdFilled = true;
} }
unsigned int Rijndael::Base::OptimalDataAlignment() const
{
#if CRYPTOPP_BOOL_ALIGN16
return 16;
#else
return GetAlignmentOf<word32>();
#endif
}
#if (CRYPTOPP_AESNI_AVAILABLE) #if (CRYPTOPP_AESNI_AVAILABLE)
extern void Rijndael_UncheckedSetKey_SSE4_AESNI(const byte *userKey, size_t keyLen, word32* rk); extern void Rijndael_UncheckedSetKey_SSE4_AESNI(const byte *userKey, size_t keyLen, word32* rk);
extern void Rijndael_UncheckedSetKeyRev_AESNI(word32 *key, unsigned int rounds); extern void Rijndael_UncheckedSetKeyRev_AESNI(word32 *key, unsigned int rounds);
@ -351,11 +342,6 @@ void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLen, c
void Rijndael::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const void Rijndael::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{ {
CRYPTOPP_ASSERT(IsAlignedOn( m_key, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn( inBlock, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn(xorBlock, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn(outBlock, OptimalDataAlignment()));
#if CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) || CRYPTOPP_AESNI_AVAILABLE #if CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) || CRYPTOPP_AESNI_AVAILABLE
# if (CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_RIJNDAEL_ASM) # if (CRYPTOPP_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_RIJNDAEL_ASM)
if (HasSSE2()) if (HasSSE2())
@ -446,11 +432,6 @@ void Rijndael::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock
void Rijndael::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const void Rijndael::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{ {
CRYPTOPP_ASSERT(IsAlignedOn( m_key, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn( inBlock, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn(xorBlock, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn(outBlock, OptimalDataAlignment()));
#if CRYPTOPP_AESNI_AVAILABLE #if CRYPTOPP_AESNI_AVAILABLE
if (HasAESNI()) if (HasAESNI())
{ {
@ -1098,11 +1079,6 @@ Rijndael::Enc::Enc() { }
#if CRYPTOPP_ENABLE_ADVANCED_PROCESS_BLOCKS #if CRYPTOPP_ENABLE_ADVANCED_PROCESS_BLOCKS
size_t Rijndael::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const size_t Rijndael::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const
{ {
CRYPTOPP_ASSERT(IsAlignedOn( m_key, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn( inBlocks, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn(xorBlocks, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn(outBlocks, OptimalDataAlignment()));
#if CRYPTOPP_AESNI_AVAILABLE #if CRYPTOPP_AESNI_AVAILABLE
if (HasAESNI()) if (HasAESNI())
return Rijndael_Enc_AdvancedProcessBlocks_AESNI(m_key, m_rounds, inBlocks, xorBlocks, outBlocks, length, flags); return Rijndael_Enc_AdvancedProcessBlocks_AESNI(m_key, m_rounds, inBlocks, xorBlocks, outBlocks, length, flags);
@ -1166,11 +1142,6 @@ size_t Rijndael::Enc::AdvancedProcessBlocks(const byte *inBlocks, const byte *xo
size_t Rijndael::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const size_t Rijndael::Dec::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const
{ {
CRYPTOPP_ASSERT(IsAlignedOn( m_key, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn( inBlocks, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn(xorBlocks, OptimalDataAlignment()));
CRYPTOPP_ASSERT(IsAlignedOn(outBlocks, OptimalDataAlignment()));
#if CRYPTOPP_AESNI_AVAILABLE #if CRYPTOPP_AESNI_AVAILABLE
if (HasAESNI()) if (HasAESNI())
return Rijndael_Dec_AdvancedProcessBlocks_AESNI(m_key, m_rounds, inBlocks, xorBlocks, outBlocks, length, flags); return Rijndael_Dec_AdvancedProcessBlocks_AESNI(m_key, m_rounds, inBlocks, xorBlocks, outBlocks, length, flags);

View File

@ -39,9 +39,6 @@ class CRYPTOPP_DLL Rijndael : public Rijndael_Info, public BlockCipherDocumentat
class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<Rijndael_Info> class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl<Rijndael_Info>
{ {
public: public:
// Intel and ARM SIMD units can handle unaligned loads, but AltiVec and Power8 cannot.
unsigned int OptimalDataAlignment() const;
void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params); void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs &params);
protected: protected:

View File

@ -39,27 +39,15 @@ void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
if (!length) if (!length)
return; return;
} }
CRYPTOPP_ASSERT(m_leftOver == 0);
PolicyInterface &policy = this->AccessPolicy(); PolicyInterface &policy = this->AccessPolicy();
const unsigned int bytesPerIteration = policy.GetBytesPerIteration(); unsigned int bytesPerIteration = policy.GetBytesPerIteration();
const unsigned int alignment = policy.GetAlignment();
if (length >= bytesPerIteration) if (length >= bytesPerIteration)
{ {
const size_t iterations = length / bytesPerIteration; size_t iterations = length / bytesPerIteration;
// Intel and ARM SIMD units can handle unaligned loads of
// byte buffers, but AltiVec and Power8 cannot.
if (!IsAlignedOn(outString, alignment))
{
AlignedSecByteBlock temp(iterations * bytesPerIteration);
policy.WriteKeystream(temp, iterations);
memcpy(outString, temp, iterations * bytesPerIteration);
}
else
{
policy.WriteKeystream(outString, iterations); policy.WriteKeystream(outString, iterations);
}
outString += iterations * bytesPerIteration; outString += iterations * bytesPerIteration;
length -= iterations * bytesPerIteration; length -= iterations * bytesPerIteration;
} }
@ -90,14 +78,15 @@ void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inStrin
if (!length) if (!length)
return; return;
} }
CRYPTOPP_ASSERT(m_leftOver == 0);
PolicyInterface &policy = this->AccessPolicy(); PolicyInterface &policy = this->AccessPolicy();
const unsigned int bytesPerIteration = policy.GetBytesPerIteration(); unsigned int bytesPerIteration = policy.GetBytesPerIteration();
const unsigned int alignment = policy.GetAlignment();
if (policy.CanOperateKeystream() && length >= bytesPerIteration) if (policy.CanOperateKeystream() && length >= bytesPerIteration)
{ {
const size_t iterations = length / bytesPerIteration; size_t iterations = length / bytesPerIteration;
unsigned int alignment = policy.GetAlignment();
KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment)); KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment));
policy.OperateKeystream(operation, outString, inString, iterations); policy.OperateKeystream(operation, outString, inString, iterations);
@ -190,8 +179,8 @@ void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString
CRYPTOPP_ASSERT(length % this->MandatoryBlockSize() == 0); CRYPTOPP_ASSERT(length % this->MandatoryBlockSize() == 0);
PolicyInterface &policy = this->AccessPolicy(); PolicyInterface &policy = this->AccessPolicy();
const unsigned int bytesPerIteration = policy.GetBytesPerIteration(); unsigned int bytesPerIteration = policy.GetBytesPerIteration();
const unsigned int alignment = policy.GetAlignment(); unsigned int alignment = policy.GetAlignment();
byte *reg = policy.GetRegisterBegin(); byte *reg = policy.GetRegisterBegin();
if (m_leftOver) if (m_leftOver)
@ -207,6 +196,8 @@ void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString
if (!length) if (!length)
return; return;
CRYPTOPP_ASSERT(m_leftOver == 0);
if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment)) if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
{ {
if (IsAlignedOn(inString, alignment)) if (IsAlignedOn(inString, alignment))

View File

@ -187,12 +187,13 @@ struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE
typedef WT WordType; typedef WT WordType;
CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W) CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W)
#if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64)
//! \brief Provides data alignment requirements //! \brief Provides data alignment requirements
//! \returns data alignment requirements, in bytes //! \returns data alignment requirements, in bytes
//! \details Internally, the default implementation returns 1. If the stream cipher is implemented //! \details Internally, the default implementation returns 1. If the stream cipher is implemented
//! using an SSE2 ASM or intrinsics, then the value returned is usually 16. If the cipher is //! using an SSE2 ASM or intrinsics, then the value returned is usually 16.
//! AES on AltiVec or Power 8 then 16 is returned.
unsigned int GetAlignment() const {return GetAlignmentOf<WordType>();} unsigned int GetAlignment() const {return GetAlignmentOf<WordType>();}
#endif
//! \brief Provides number of bytes operated upon during an iteration //! \brief Provides number of bytes operated upon during an iteration
//! \returns bytes operated upon during an iteration, in bytes //! \returns bytes operated upon during an iteration, in bytes
@ -339,7 +340,7 @@ protected:
inline byte * KeystreamBufferBegin() {return this->m_buffer.data();} inline byte * KeystreamBufferBegin() {return this->m_buffer.data();}
inline byte * KeystreamBufferEnd() {return (this->m_buffer.data() + this->m_buffer.size());} inline byte * KeystreamBufferEnd() {return (this->m_buffer.data() + this->m_buffer.size());}
AlignedSecByteBlock m_buffer; SecByteBlock m_buffer;
size_t m_leftOver; size_t m_leftOver;
}; };

View File

@ -2467,16 +2467,16 @@ bool TestHuffmanCodes()
{ {
try try
{ {
SecByteBlock data1(0xfff); byte data1[0xfff]; // Place on stack, avoid new
SecBlock<word32> data2(0xff); unsigned int data2[0xff];
unsigned int len1 = GlobalRNG().GenerateWord32(4, 0xfff); unsigned int len1 = GlobalRNG().GenerateWord32(4, 0xfff);
GlobalRNG().GenerateBlock(data1.BytePtr(), data1.SizeInBytes()); GlobalRNG().GenerateBlock(data1, len1);
unsigned int len2 = GlobalRNG().GenerateWord32(4, 0xff); unsigned int len2 = GlobalRNG().GenerateWord32(4, 0xff);
GlobalRNG().GenerateBlock(data2.BytePtr(), data2.SizeInBytes()); GlobalRNG().GenerateBlock((byte*)data2, len2*sizeof(unsigned int));
ArraySource source(data1.BytePtr(), data1.SizeInBytes(), false); ArraySource source(data1, len1, false);
HuffmanDecoder decoder(data2.begin(), data2.size()); HuffmanDecoder decoder(data2, len2);
LowFirstBitReader reader(source); LowFirstBitReader reader(source);
unsigned int val; unsigned int val;

View File

@ -1909,10 +1909,8 @@ public:
template <class E, class D> class FixedRoundsCipherFactory : public CipherFactory template <class E, class D> class FixedRoundsCipherFactory : public CipherFactory
{ {
public: public:
FixedRoundsCipherFactory(unsigned int keylen=0) : FixedRoundsCipherFactory(unsigned int keylen=0) : m_keylen(keylen?keylen:E::DEFAULT_KEYLENGTH) {}
m_keylen(keylen ? keylen : static_cast<unsigned int>(E::DEFAULT_KEYLENGTH)) {} unsigned int BlockSize() const {return E::BLOCKSIZE;}
unsigned int BlockSize() const {return static_cast<unsigned int>(E::BLOCKSIZE);}
unsigned int KeyLength() const {return m_keylen;} unsigned int KeyLength() const {return m_keylen;}
BlockTransformation* NewEncryption(const byte *keyStr) const BlockTransformation* NewEncryption(const byte *keyStr) const
@ -1926,11 +1924,9 @@ public:
template <class E, class D> class VariableRoundsCipherFactory : public CipherFactory template <class E, class D> class VariableRoundsCipherFactory : public CipherFactory
{ {
public: public:
VariableRoundsCipherFactory(unsigned int keylen=0, unsigned int rounds=0) : VariableRoundsCipherFactory(unsigned int keylen=0, unsigned int rounds=0)
m_keylen(keylen ? keylen : static_cast<unsigned int>(E::DEFAULT_KEYLENGTH)), : m_keylen(keylen ? keylen : E::DEFAULT_KEYLENGTH), m_rounds(rounds ? rounds : E::DEFAULT_ROUNDS) {}
m_rounds(rounds ? rounds : static_cast<unsigned int>(E::DEFAULT_ROUNDS)) {} unsigned int BlockSize() const {return E::BLOCKSIZE;}
unsigned int BlockSize() const {return static_cast<unsigned int>(E::BLOCKSIZE);}
unsigned int KeyLength() const {return m_keylen;} unsigned int KeyLength() const {return m_keylen;}
BlockTransformation* NewEncryption(const byte *keyStr) const BlockTransformation* NewEncryption(const byte *keyStr) const