Add ability to Seek64 in test framework (GH #732)

Also see https://github.com/randombit/botan/pull/1728
pull/737/head
Jeffrey Walton 2018-11-04 14:21:54 -05:00
parent f7c0fab5b2
commit 40fa6873f9
No known key found for this signature in database
GPG Key ID: B36AB348921B1838
4 changed files with 55 additions and 16 deletions

View File

@ -24,7 +24,8 @@ before the Test field.
Data Types Data Types
========== ==========
int - small integer (less than 2^32) in decimal representation signed int - small integer (less than 2^32) in decimal representation
unsigned long - large integer (less than 2^64) convertible by strtoul or strtoull
string - human readable string string - human readable string
encoded string - can be one of the following encoded string - can be one of the following
- quoted string: "message" means "message" without the quotes - quoted string: "message" means "message" without the quotes
@ -68,6 +69,7 @@ DerivedLength - encoded string
Digest - encoded string Digest - encoded string
TruncatedSize - int, size of truncated digest in bytes TruncatedSize - int, size of truncated digest in bytes
Seek - int, seek location for random access ciphers Seek - int, seek location for random access ciphers
Seek64 - unsigned long, seek location for random access ciphers
(more to come here) (more to come here)
Possible Tests Possible Tests

View File

@ -393,6 +393,24 @@ public:
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
{return GetValueWithDefault(name, defaultValue);} {return GetValueWithDefault(name, defaultValue);}
/// \brief Get a named value with type word64
/// \param name the name of the value to retrieve
/// \param value the value retrieved upon success
/// \return true if an word64 value was retrieved, false otherwise
/// \sa GetValue(), GetValueWithDefault(), GetWord64ValueWithDefault(), GetIntValue(),
/// GetIntValueWithDefault(), GetRequiredParameter() and GetRequiredIntParameter()
CRYPTOPP_DLL bool GetWord64Value(const char *name, word64 &value) const
{return GetValue(name, value);}
/// \brief Get a named value with type word64, with default
/// \param name the name of the value to retrieve
/// \param defaultValue the default value if the name does not exist
/// \return the value retrieved on success or the default value
/// \sa GetValue(), GetValueWithDefault(), GetWord64Value(), GetIntValue(),
/// GetIntValueWithDefault(), GetRequiredParameter() and GetRequiredWord64Parameter()
CRYPTOPP_DLL word64 GetWord64ValueWithDefault(const char *name, word64 defaultValue) const
{return GetValueWithDefault(name, defaultValue);}
/// \brief Ensures an expected name and type is present /// \brief Ensures an expected name and type is present
/// \param name the name of the value /// \param name the name of the value
/// \param stored the type that was stored for the name /// \param stored the type that was stored for the name

View File

@ -30,6 +30,12 @@
# pragma warning(disable: 4505 4355) # pragma warning(disable: 4505 4355)
#endif #endif
#ifdef _MSC_VER
# define STRTOUL64 _strtoui64
#else
# define STRTOUL64 strtoull
#endif
NAMESPACE_BEGIN(CryptoPP) NAMESPACE_BEGIN(CryptoPP)
NAMESPACE_BEGIN(Test) NAMESPACE_BEGIN(Test)
@ -220,6 +226,16 @@ public:
if (valueType == typeid(int)) if (valueType == typeid(int))
*reinterpret_cast<int *>(pValue) = atoi(value.c_str()); *reinterpret_cast<int *>(pValue) = atoi(value.c_str());
else if (valueType == typeid(word64))
{
std::string x(value); errno = 0;
const char* beg = &x[0];
char* end = &x[0] + value.size();
*reinterpret_cast<word64*>(pValue) = STRTOUL64(beg, &end, 0);
if (errno != 0)
return false;
}
else if (valueType == typeid(Integer)) else if (valueType == typeid(Integer))
*reinterpret_cast<Integer *>(pValue) = Integer((std::string(value) + "h").c_str()); *reinterpret_cast<Integer *>(pValue) = Integer((std::string(value) + "h").c_str());
else if (valueType == typeid(ConstByteArrayParameter)) else if (valueType == typeid(ConstByteArrayParameter))
@ -445,11 +461,20 @@ void TestSymmetricCipher(TestData &v, const NameValuePairs &overrideParameters)
decryptor->SetKey(reinterpret_cast<const byte*>(&key[0]), key.size(), pairs); decryptor->SetKey(reinterpret_cast<const byte*>(&key[0]), key.size(), pairs);
} }
int seek = pairs.GetIntValueWithDefault("Seek", 0); word64 seek64 = pairs.GetWord64ValueWithDefault("Seek64", 0);
if (seek) if (seek64)
{ {
encryptor->Seek(seek); encryptor->Seek(seek64);
decryptor->Seek(seek); decryptor->Seek(seek64);
}
else
{
int seek = pairs.GetIntValueWithDefault("Seek", 0);
if (seek)
{
encryptor->Seek(seek);
decryptor->Seek(seek);
}
} }
// If a per-test vector parameter was set for a test, like BlockPadding, // If a per-test vector parameter was set for a test, like BlockPadding,

View File

@ -76,8 +76,6 @@ void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inStrin
length -= len; m_leftOver -= len; length -= len; m_leftOver -= len;
inString = PtrAdd(inString, len); inString = PtrAdd(inString, len);
outString = PtrAdd(outString, len); outString = PtrAdd(outString, len);
if (!length) {return;}
} }
PolicyInterface &policy = this->AccessPolicy(); PolicyInterface &policy = this->AccessPolicy();
@ -93,8 +91,6 @@ void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inStrin
inString = PtrAdd(inString, iterations * bytesPerIteration); inString = PtrAdd(inString, iterations * bytesPerIteration);
outString = PtrAdd(outString, iterations * bytesPerIteration); outString = PtrAdd(outString, iterations * bytesPerIteration);
length -= iterations * bytesPerIteration; length -= iterations * bytesPerIteration;
if (!length) {return;}
} }
size_t bufferByteSize = m_buffer.size(); size_t bufferByteSize = m_buffer.size();
@ -134,7 +130,7 @@ template <class BASE>
void AdditiveCipherTemplate<BASE>::Seek(lword position) void AdditiveCipherTemplate<BASE>::Seek(lword position)
{ {
PolicyInterface &policy = this->AccessPolicy(); PolicyInterface &policy = this->AccessPolicy();
unsigned int bytesPerIteration = policy.GetBytesPerIteration(); word32 bytesPerIteration = policy.GetBytesPerIteration();
policy.SeekToIteration(position / bytesPerIteration); policy.SeekToIteration(position / bytesPerIteration);
position %= bytesPerIteration; position %= bytesPerIteration;
@ -142,7 +138,7 @@ void AdditiveCipherTemplate<BASE>::Seek(lword position)
if (position > 0) if (position > 0)
{ {
policy.WriteKeystream(PtrSub(KeystreamBufferEnd(), bytesPerIteration), 1); policy.WriteKeystream(PtrSub(KeystreamBufferEnd(), bytesPerIteration), 1);
m_leftOver = bytesPerIteration - (unsigned int)position; m_leftOver = bytesPerIteration - static_cast<word32>(position);
} }
else else
m_leftOver = 0; m_leftOver = 0;
@ -179,7 +175,7 @@ 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();
unsigned int bytesPerIteration = policy.GetBytesPerIteration(); word32 bytesPerIteration = policy.GetBytesPerIteration();
byte *reg = policy.GetRegisterBegin(); byte *reg = policy.GetRegisterBegin();
if (m_leftOver) if (m_leftOver)
@ -190,8 +186,6 @@ void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString
m_leftOver -= len; length -= len; m_leftOver -= len; length -= len;
inString = PtrAdd(inString, len); inString = PtrAdd(inString, len);
outString = PtrAdd(outString, len); outString = PtrAdd(outString, len);
if (!length) {return;}
} }
// TODO: Figure out what is happening on ARM A-32. x86, Aarch64 and PowerPC are OK. // TODO: Figure out what is happening on ARM A-32. x86, Aarch64 and PowerPC are OK.
@ -204,8 +198,8 @@ void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString
// Also see https://github.com/weidai11/cryptopp/issues/683. // Also see https://github.com/weidai11/cryptopp/issues/683.
// //
// UPDATE: It appears the issue is related to alignment checks. When we made // UPDATE: It appears the issue is related to alignment checks. When we made
// the alignment check result volatile GCC and Clang stopped // the alignment check result volatile GCC and Clang stopped short-
// short-circuiting the transform, which is what we wanted. I suspect // circuiting the transform, which is what we wanted. I suspect
// there's a little more to the issue, but we can enable the block again. // there's a little more to the issue, but we can enable the block again.
const unsigned int alignment = policy.GetAlignment(); const unsigned int alignment = policy.GetAlignment();