summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rijndael.cpp14
-rw-r--r--strciphr.cpp41
2 files changed, 31 insertions, 24 deletions
diff --git a/rijndael.cpp b/rijndael.cpp
index a43ff3ef..5ccc45f0 100644
--- a/rijndael.cpp
+++ b/rijndael.cpp
@@ -257,8 +257,10 @@ unsigned int Rijndael::Base::OptimalDataAlignment() const
return 4; // load uint32x4_t
#endif
#if (CRYPTOGAMS_ARM_AES)
+ // Must use 1 here for Cryptogams AES. Also see
+ // https://github.com/weidai11/cryptopp/issues/683
if (HasARMv7())
- return 1; // CFB mode error without 1
+ return 1;
#endif
#if (CRYPTOPP_POWER8_AES_AVAILABLE)
if (HasAES())
@@ -330,8 +332,8 @@ extern size_t Rijndael_Dec_AdvancedProcessBlocks_ARMV8(const word32 *subkeys, si
#if (CRYPTOGAMS_ARM_AES)
extern "C" int AES_set_encrypt_key(const unsigned char *userKey, const int bitLen, word32 *rkey);
extern "C" int AES_set_decrypt_key(const unsigned char *userKey, const int bitLen, word32 *rkey);
-extern "C" void AES_encrypt(const unsigned char in[16], unsigned char out[16], const word32 *rkey);
-extern "C" void AES_decrypt(const unsigned char in[16], unsigned char out[16], const word32 *rkey);
+extern "C" void AES_encrypt_block(const unsigned char *in, unsigned char *out, const word32 *rkey);
+extern "C" void AES_decrypt_block(const unsigned char *in, unsigned char *out, const word32 *rkey);
#endif
#if (CRYPTOPP_POWER8_AES_AVAILABLE)
@@ -355,13 +357,13 @@ int CRYPTOGAMS_set_decrypt_key(const byte *userKey, const int bitLen, word32 *rk
}
void CRYPTOGAMS_encrypt(const byte *inBlock, const byte *xorBlock, byte *outBlock, const word32 *rkey)
{
- AES_encrypt(inBlock, outBlock, rkey);
+ AES_encrypt_block(inBlock, outBlock, rkey);
if (xorBlock)
xorbuf (outBlock, xorBlock, 16);
}
void CRYPTOGAMS_decrypt(const byte *inBlock, const byte *xorBlock, byte *outBlock, const word32 *rkey)
{
- AES_decrypt(inBlock, outBlock, rkey);
+ AES_decrypt_block(inBlock, outBlock, rkey);
if (xorBlock)
xorbuf (outBlock, xorBlock, 16);
}
@@ -400,7 +402,7 @@ void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keyLen, c
if (HasARMv7())
{
m_rounds = keyLen/4 + 6;
- m_key.New(4*(15+1)+4);
+ m_key.New(4*(14+1)+4);
if (IsForwardTransformation())
CRYPTOGAMS_set_encrypt_key(userKey, keyLen*8, m_key.begin());
diff --git a/strciphr.cpp b/strciphr.cpp
index 1ccb0670..e5ca04fd 100644
--- a/strciphr.cpp
+++ b/strciphr.cpp
@@ -36,7 +36,7 @@ void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
if (m_leftOver > 0)
{
const size_t len = STDMIN(m_leftOver, length);
- memcpy(outString, PtrSub(KeystreamBufferEnd(), m_leftOver), len);
+ std::memcpy(outString, PtrSub(KeystreamBufferEnd(), m_leftOver), len);
length -= len; m_leftOver -= len;
outString = PtrAdd(outString, len);
@@ -60,7 +60,7 @@ void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
size_t bufferIterations = bufferByteSize / bytesPerIteration;
policy.WriteKeystream(PtrSub(KeystreamBufferEnd(), bufferByteSize), bufferIterations);
- memcpy(outString, PtrSub(KeystreamBufferEnd(), bufferByteSize), length);
+ std::memcpy(outString, PtrSub(KeystreamBufferEnd(), bufferByteSize), length);
m_leftOver = bufferByteSize - length;
}
}
@@ -71,11 +71,13 @@ void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inStrin
if (m_leftOver > 0)
{
const size_t len = STDMIN(m_leftOver, length);
- xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
+ xorbuf(outString, inString, PtrSub(KeystreamBufferEnd(), m_leftOver), len);
length -= len; m_leftOver -= len;
inString = PtrAdd(inString, len);
outString = PtrAdd(outString, len);
+
+ if (!length) {return;}
}
PolicyInterface &policy = this->AccessPolicy();
@@ -85,12 +87,17 @@ void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inStrin
{
const size_t iterations = length / bytesPerIteration;
unsigned int alignment = policy.GetAlignment();
- KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment));
+ volatile int inAligned = IsAlignedOn(inString, alignment) << 1;
+ volatile int outAligned = IsAlignedOn(outString, alignment) << 0;
+
+ KeystreamOperation operation = KeystreamOperation(inAligned | outAligned);
policy.OperateKeystream(operation, outString, inString, iterations);
inString = PtrAdd(inString, iterations * bytesPerIteration);
outString = PtrAdd(outString, iterations * bytesPerIteration);
length -= iterations * bytesPerIteration;
+
+ if (!length) {return;}
}
size_t bufferByteSize = m_buffer.size();
@@ -188,6 +195,8 @@ void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString
outString = PtrAdd(outString, len);
}
+ if (!length) {return;}
+
// TODO: Figure out what is happening on ARM A-32. x86, Aarch64 and PowerPC are OK.
// The issue surfaced for CFB mode when we cut-in Cryptogams AES ARMv7 asm.
// Using 'outString' for both input and output leads to incorrect results.
@@ -196,23 +205,19 @@ void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString
// below costs about 9 cpb for CFB mode on ARM.
//
// Also see https://github.com/weidai11/cryptopp/issues/683.
- //
- // UPDATE: It appears the issue is related to alignment checks. When we made
- // the alignment check result volatile GCC and Clang stopped short-
- // 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.
const unsigned int alignment = policy.GetAlignment();
- volatile bool isAligned = IsAlignedOn(outString, alignment);
- if (policy.CanIterate() && length >= bytesPerIteration && isAligned)
+ volatile bool inAligned = IsAlignedOn(inString, alignment);
+ volatile bool outAligned = IsAlignedOn(outString, alignment);
+
+ if (policy.CanIterate() && length >= bytesPerIteration && outAligned)
{
- isAligned &= IsAlignedOn(inString, alignment);
- const CipherDir cipherDir = GetCipherDir(*this);
- if (isAligned)
+ CipherDir cipherDir = GetCipherDir(*this);
+ if (inAligned)
policy.Iterate(outString, inString, cipherDir, length / bytesPerIteration);
else
{
- // GCC and Clang does not like this on ARM. The incorrect result is a string
+ // GCC and Clang do not like this on ARM. The incorrect result is a string
// of 0's instead of ciphertext (or plaintext if decrypting). The 0's trace
// back to the allocation for the std::string in datatest.cpp. Elements in the
// string are initialized to their default value, which is 0.
@@ -231,8 +236,8 @@ void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString
//
// std::string temp(inString, length);
// policy.Iterate(outString, &temp[0], cipherDir, length / bytesPerIteration);
- //
- memcpy(outString, inString, length);
+
+ std::memcpy(outString, inString, length);
policy.Iterate(outString, outString, cipherDir, length / bytesPerIteration);
}
const size_t remainder = length % bytesPerIteration;
@@ -262,7 +267,7 @@ template <class BASE>
void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
{
xorbuf(reg, message, length);
- memcpy(output, reg, length);
+ std::memcpy(output, reg, length);
}
template <class BASE>