From 8cef820ac8fe0925ae7a358fc92adf86ffdc97c9 Mon Sep 17 00:00:00 2001 From: Jeffrey Walton Date: Fri, 17 Jul 2015 22:21:01 -0400 Subject: [PATCH] Cleared UBsan error based on undefined shift. Tightened behaviors based on offline conversation with Wei and Denis. One shift error remains due to use of rotVariable by Cast. The UB will be cleared shortly, when specializations using GCC assembler is checked in --- misc.h | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/misc.h b/misc.h index ed3ae048..20bc6d48 100644 --- a/misc.h +++ b/misc.h @@ -685,40 +685,54 @@ CRYPTOPP_DLL void CRYPTOPP_API UnalignedDeallocate(void *p); // Finally, if a specialization avoids the undefined behavior, then it // does not assert. +// Well defined if y in [0,31], non-constant time due to branch template inline T rotlFixed(T x, unsigned int y) { - assert(y < sizeof(T)*8); - return y ? T((x<>(sizeof(T)*8-y))) : x; + static const unsigned int THIS_SIZE = sizeof(T)*8; + assert(y < THIS_SIZE); + return y ? T((x<>(THIS_SIZE-y))) : x; } +// Well defined if y in [0,31], non-constant time due to branch template inline T rotrFixed(T x, unsigned int y) { - assert(y < sizeof(T)*8); - return y ? T((x>>y) | (x<<(sizeof(T)*8-y))) : x; + static const unsigned int THIS_SIZE = sizeof(T)*8; + assert(y < THIS_SIZE); + return y ? T((x>>y) | (x<<(THIS_SIZE-y))) : x; } +// Well defined if y in [1,31], near constant time template inline T rotlVariable(T x, unsigned int y) { - assert(y < sizeof(T)*8); - return T((x<>(sizeof(T)*8-y))); + static const unsigned int THIS_SIZE = sizeof(T)*8; + assert(y > 0 && y < THIS_SIZE); + y %= THIS_SIZE; + return T((x<>(THIS_SIZE-y))); } +// Well defined if y in [1,31], near constant time template inline T rotrVariable(T x, unsigned int y) { - assert(y < sizeof(T)*8); - return T((x>>y) | (x<<(sizeof(T)*8-y))); + static const unsigned int THIS_SIZE = sizeof(T)*8; + assert(y > 0 && y < THIS_SIZE); + y %= THIS_SIZE; + return T((x>>y) | (x<<(THIS_SIZE-y))); } +// Well defined for all y, near constant time template inline T rotlMod(T x, unsigned int y) { - y %= sizeof(T)*8; - return T((x<>((sizeof(T)*8-y) % (sizeof(T)*8)))); + static const unsigned int THIS_SIZE = sizeof(T)*8; + y %= THIS_SIZE; + return T((x<>((THIS_SIZE-y) % THIS_SIZE))); } +// Well defined for all y, near constant time template inline T rotrMod(T x, unsigned int y) { - y %= sizeof(T)*8; - return T((x>>y) | (x<<((sizeof(T)*8-y) % (sizeof(T)*8)))); + static const unsigned int THIS_SIZE = sizeof(T)*8; + y %= THIS_SIZE; + return T((x>>y) | (x<<((THIS_SIZE-y) % THIS_SIZE))); } #ifdef _MSC_VER