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 strategiespull/489/head
parent
23b939c62b
commit
37e02f9e0e
15
authenc.cpp
15
authenc.cpp
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
cmac.cpp
18
cmac.cpp
|
|
@ -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
2
cmac.h
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
10
config.h
10
config.h
|
|
@ -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
|
||||||
|
|
|
||||||
76
datatest.cpp
76
datatest.cpp
|
|
@ -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);
|
||||||
|
|
|
||||||
22
default.cpp
22
default.cpp
|
|
@ -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);
|
||||||
|
|
|
||||||
58
filters.cpp
58
filters.cpp
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
169
modes.cpp
|
|
@ -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 ¶ms)
|
void BlockOrientedCipherModeBase::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)
|
||||||
{
|
{
|
||||||
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
22
modes.h
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
29
rijndael.cpp
29
rijndael.cpp
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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 ¶ms);
|
void UncheckedSetKey(const byte *userKey, unsigned int keyLength, const NameValuePairs ¶ms);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
31
strciphr.cpp
31
strciphr.cpp
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
12
validat0.cpp
12
validat0.cpp
|
|
@ -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;
|
||||||
|
|
|
||||||
14
validat1.cpp
14
validat1.cpp
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue