From 497a22c04fe40e10aa42278450325edf47bd741e Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Mon, 6 May 2013 10:30:03 -0700 Subject: [PATCH] Fix endianness for all tiger algos The PHP version the implementations in hphp were based off of had wrong byte ordering. Fix them in line with PHP having been fixed. --- hphp/runtime/ext/ext_hash.cpp | 10 +++++++ hphp/runtime/ext/hash/hash_tiger.cpp | 40 ++++++---------------------- hphp/runtime/ext/hash/hash_tiger.h | 6 ++++- hphp/test/test_ext_hash.cpp | 14 +++++----- 4 files changed, 31 insertions(+), 39 deletions(-) diff --git a/hphp/runtime/ext/ext_hash.cpp b/hphp/runtime/ext/ext_hash.cpp index 5cc81ae55..2fbf58358 100644 --- a/hphp/runtime/ext/ext_hash.cpp +++ b/hphp/runtime/ext/ext_hash.cpp @@ -60,12 +60,22 @@ public: HashEngines["ripemd256"] = HashEnginePtr(new hash_ripemd256()); HashEngines["ripemd320"] = HashEnginePtr(new hash_ripemd320()); HashEngines["whirlpool"] = HashEnginePtr(new hash_whirlpool()); +#ifdef FACEBOOK + HashEngines["tiger128,3-fb"] + = HashEnginePtr(new hash_tiger(true, 128, true)); + // Temporarily leave tiger128,3 algo inverting its hash output + // to retain BC pending conversion of user code to correct endianness + // sgolemon(2013-04-30) + HashEngines["tiger128,3"] = HashEnginePtr(new hash_tiger(true, 128, true)); +#else HashEngines["tiger128,3"] = HashEnginePtr(new hash_tiger(true, 128)); +#endif HashEngines["tiger160,3"] = HashEnginePtr(new hash_tiger(true, 160)); HashEngines["tiger192,3"] = HashEnginePtr(new hash_tiger(true, 192)); HashEngines["tiger128,4"] = HashEnginePtr(new hash_tiger(false, 128)); HashEngines["tiger160,4"] = HashEnginePtr(new hash_tiger(false, 160)); HashEngines["tiger192,4"] = HashEnginePtr(new hash_tiger(false, 192)); + HashEngines["snefru"] = HashEnginePtr(new hash_snefru()); HashEngines["gost"] = HashEnginePtr(new hash_gost()); HashEngines["adler32"] = HashEnginePtr(new hash_adler32()); diff --git a/hphp/runtime/ext/hash/hash_tiger.cpp b/hphp/runtime/ext/hash/hash_tiger.cpp index eb0a42748..73c5eae44 100644 --- a/hphp/runtime/ext/hash/hash_tiger.cpp +++ b/hphp/runtime/ext/hash/hash_tiger.cpp @@ -39,9 +39,9 @@ typedef struct { unsigned char buffer[64]; } PHP_TIGER_CTX; -hash_tiger::hash_tiger(bool tiger3, int digest) +hash_tiger::hash_tiger(bool tiger3, int digest, bool invert /*= false */) : HashEngine(digest / 8, 64, sizeof(PHP_TIGER_CTX)), - m_tiger3(tiger3), m_digest(digest) { + m_tiger3(tiger3), m_digest(digest), m_invert(invert) { } #define save_abc \ @@ -112,7 +112,7 @@ hash_tiger::hash_tiger(bool tiger3, int digest) x0=str[0]; x1=str[1]; x2=str[2]; x3=str[3]; \ x4=str[4]; x5=str[5]; x6=str[6]; x7=str[7]; #ifdef WORDS_BIGENDIAN -# define split(str) \ +# define split(str) \ { \ int i; \ uint64_t tmp[8]; \ @@ -123,7 +123,7 @@ hash_tiger::hash_tiger(bool tiger3, int digest) split_ex(tmp); \ } #else -# define split split_ex +# define split split_ex #endif #define tiger_compress(passes, str, state) \ @@ -228,34 +228,10 @@ void hash_tiger::hash_final(unsigned char *digest, void *context_) { TigerFinalize(context); - switch (m_digest) { - case 192: - digest[20] = (unsigned char) ((context->state[2] >> 24) & 0xff); - digest[21] = (unsigned char) ((context->state[2] >> 16) & 0xff); - digest[22] = (unsigned char) ((context->state[2] >> 8) & 0xff); - digest[23] = (unsigned char) (context->state[2] & 0xff); - case 160: - digest[16] = (unsigned char) ((context->state[2] >> 56) & 0xff); - digest[17] = (unsigned char) ((context->state[2] >> 48) & 0xff); - digest[18] = (unsigned char) ((context->state[2] >> 40) & 0xff); - digest[19] = (unsigned char) ((context->state[2] >> 32) & 0xff); - case 128: - digest[0] = (unsigned char) ((context->state[0] >> 56) & 0xff); - digest[1] = (unsigned char) ((context->state[0] >> 48) & 0xff); - digest[2] = (unsigned char) ((context->state[0] >> 40) & 0xff); - digest[3] = (unsigned char) ((context->state[0] >> 32) & 0xff); - digest[4] = (unsigned char) ((context->state[0] >> 24) & 0xff); - digest[5] = (unsigned char) ((context->state[0] >> 16) & 0xff); - digest[6] = (unsigned char) ((context->state[0] >> 8) & 0xff); - digest[7] = (unsigned char) (context->state[0] & 0xff); - digest[8] = (unsigned char) ((context->state[1] >> 56) & 0xff); - digest[9] = (unsigned char) ((context->state[1] >> 48) & 0xff); - digest[10] = (unsigned char) ((context->state[1] >> 40) & 0xff); - digest[11] = (unsigned char) ((context->state[1] >> 32) & 0xff); - digest[12] = (unsigned char) ((context->state[1] >> 24) & 0xff); - digest[13] = (unsigned char) ((context->state[1] >> 16) & 0xff); - digest[14] = (unsigned char) ((context->state[1] >> 8) & 0xff); - digest[15] = (unsigned char) (context->state[1] & 0xff); + for(int i = 0; i < (m_digest >> 3); ++i) { + digest[i] = (unsigned char) ((context->state[i >> 3] >> + ((m_invert ? (7 - i) : i) << 3)) + & 0xff); } memset(context, 0, sizeof(*context)); diff --git a/hphp/runtime/ext/hash/hash_tiger.h b/hphp/runtime/ext/hash/hash_tiger.h index 96a39d2df..811e91f7b 100644 --- a/hphp/runtime/ext/hash/hash_tiger.h +++ b/hphp/runtime/ext/hash/hash_tiger.h @@ -25,7 +25,7 @@ namespace HPHP { class hash_tiger : public HashEngine { public: - hash_tiger(bool tiger3, int digest); + hash_tiger(bool tiger3, int digest, bool invert = false); virtual void hash_init(void *context); virtual void hash_update(void *context, const unsigned char *buf, @@ -35,6 +35,10 @@ public: private: bool m_tiger3; int m_digest; + + // Initial implementations of tiger had inverted byte ordering + // Allow for explicit use of this ordering for BC + bool m_invert; }; /////////////////////////////////////////////////////////////////////////////// diff --git a/hphp/test/test_ext_hash.cpp b/hphp/test/test_ext_hash.cpp index 42256716b..053db7ab2 100644 --- a/hphp/test/test_ext_hash.cpp +++ b/hphp/test/test_ext_hash.cpp @@ -55,12 +55,13 @@ bool TestExtHash::test_hash() { "50c51844b845b31323765ae334349dd6a94db3e5b9624540bcbfa940f6857c3f", "67b248ca0b750028e76f09f5f9b9b746f04c228ce659f75393c83ee46b82dea011f15f465a7e4f71", "802dc377bf6dc4f905b90cf2f1ddb39d4958526c3772bce41c03488701630eeede851f5ddc195714ea9e35311a513e31c3b616ffce5756bd963e0fdc092b2f87", - "9370512795923aaeeb76fe3d8ea7433e", - "9370512795923aaeeb76fe3d8ea7433e0697d65d", - "9370512795923aaeeb76fe3d8ea7433e0697d65d1d6b3975", - "623163ed5f7b8e35ca1c2c1beb083289", - "623163ed5f7b8e35ca1c2c1beb0832891ab00cc6", - "623163ed5f7b8e35ca1c2c1beb0832891ab00cc615ef6e6b", + "9370512795923aaeeb76fe3d8ea7433e", // tiger128,3-fb + "9370512795923aaeeb76fe3d8ea7433e", // tiger128,3 + "ae3a9295275170933e43a78e3dfe76eb75396b1d", // tiger160,3 + "ae3a9295275170933e43a78e3dfe76eb75396b1d5dd69706", // tiger192,3 + "358e7b5fed633162893208eb1b2c1cca", // tiger128,4 + "358e7b5fed633162893208eb1b2c1cca6b6eef15", // tiger160,4 + "358e7b5fed633162893208eb1b2c1cca6b6eef15c60cb01a", // tiger192,4 "1d4ca34cc860789a2a63fab87cd6a2c3ae5ecb1df8bd3cce605ffa2de1fbd73b", "c10eb0cb71a04377a0452a4aa64853996f73cac95f6ae434df8083d473fac944", "5e10f17b", @@ -97,6 +98,7 @@ bool TestExtHash::test_hash() { VS(f_hash("ripemd256", data), expected[i++]); VS(f_hash("ripemd320", data), expected[i++]); VS(f_hash("whirlpool", data), expected[i++]); + VS(f_hash("tiger128,3-fb", data), expected[i++]); VS(f_hash("tiger128,3", data), expected[i++]); VS(f_hash("tiger160,3", data), expected[i++]); VS(f_hash("tiger192,3", data), expected[i++]);