From 49d852ee8c7c15e9ddf409aa53d7f0d23d3f3189 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Sat, 13 Oct 2018 22:16:59 -0400 Subject: Enable same buffer for in and out on ARM A-32 (GH #683) --- strciphr.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'strciphr.cpp') diff --git a/strciphr.cpp b/strciphr.cpp index 7d33af15..b84f2c60 100644 --- a/strciphr.cpp +++ b/strciphr.cpp @@ -203,12 +203,18 @@ void CFB_CipherTemplate::ProcessData(byte *outString, const byte *inString // // Also see https://github.com/weidai11/cryptopp/issues/683. // -#if !defined(__arm__) - unsigned int alignment = policy.GetAlignment(); - if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment)) + // 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) { + isAligned &= IsAlignedOn(inString, alignment); const CipherDir cipherDir = GetCipherDir(*this); - if (IsAlignedOn(inString, alignment)) + if (isAligned) policy.Iterate(outString, inString, cipherDir, length / bytesPerIteration); else { @@ -226,11 +232,6 @@ void CFB_CipherTemplate::ProcessData(byte *outString, const byte *inString // to use ptrdiff_t when subtracting pointers. We believe the relevant code paths // are clean. // - // There are two remaining open questions. The first is aliasing rules. Char-types - // are not bound by aliasing rules so we are OK. The second is array const-ness. - // The arrays are created in datatest.cpp and they are non-const. Since the original - // objects are non-const we are OK casting const-ness away as buffers are twiddled. - // // One workaround is a distinct and aligned temporary buffer. It [mostly] works // as expected but requires an extra allocation (casts not shown): // @@ -241,11 +242,11 @@ void CFB_CipherTemplate::ProcessData(byte *outString, const byte *inString memcpy(outString, inString, length); policy.Iterate(outString, outString, cipherDir, length / bytesPerIteration); } - inString = PtrAdd(inString, length - length % bytesPerIteration); - outString = PtrAdd(outString, length - length % bytesPerIteration); - length %= bytesPerIteration; + const size_t remainder = length % bytesPerIteration; + inString = PtrAdd(inString, length - remainder); + outString = PtrAdd(outString, length - remainder); + length = remainder; } -#endif while (length >= bytesPerIteration) { -- cgit v1.2.1