From 5a1fabb9969772242f2c2aef34b10bed17adebb6 Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Mon, 26 Feb 2018 19:58:12 +0100 Subject: Introduce enum comphelper::Hash::IterCount instead of bool Clarifies intention, and with IterCount::NONE prepared to handle something like old PBKDF1, if anything actually used that. See https://tools.ietf.org/html/rfc8018#section-5.1 where iteration count is not part of the re-hash. Change-Id: I5f97ca7a91f611eced8ced0a0c64961c04535d36 --- comphelper/qa/unit/test_hash.cxx | 5 +++-- comphelper/source/misc/docpasswordhelper.cxx | 8 ++++---- comphelper/source/misc/hash.cxx | 28 ++++++++++++++++------------ 3 files changed, 23 insertions(+), 18 deletions(-) (limited to 'comphelper') diff --git a/comphelper/qa/unit/test_hash.cxx b/comphelper/qa/unit/test_hash.cxx index 5d2ece34dc83..29ef2b884f28 100644 --- a/comphelper/qa/unit/test_hash.cxx +++ b/comphelper/qa/unit/test_hash.cxx @@ -99,7 +99,7 @@ void TestHash::testSHA512_NoSaltNoSpin() const char* const pInput = ""; std::vector calculate_hash = comphelper::Hash::calculateHash( reinterpret_cast(pInput), 0, - nullptr, 0, 0, false, comphelper::HashType::SHA512); + nullptr, 0, 0, comphelper::Hash::IterCount::NONE, comphelper::HashType::SHA512); CPPUNIT_ASSERT_EQUAL(size_t(64), calculate_hash.size()); std::string aStr("cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"); CPPUNIT_ASSERT_EQUAL(aStr, tostring(calculate_hash)); @@ -112,7 +112,8 @@ void TestHash::testSHA512_saltspin() const OUString aPass("pwd"); const OUString aAlgo("SHA-512"); const OUString aSalt("876MLoKTq42+/DLp415iZQ=="); - const OUString aHash = comphelper::DocPasswordHelper::GetOoxHashAsBase64( aPass, aSalt, 100000, false, aAlgo); + const OUString aHash = comphelper::DocPasswordHelper::GetOoxHashAsBase64( aPass, aSalt, 100000, + comphelper::Hash::IterCount::APPEND, aAlgo); const OUString aStr("5l3mgNHXpWiFaBPv5Yso1Xd/UifWvQWmlDnl/hsCYbFT2sJCzorjRmBCQ/3qeDu6Q/4+GIE8a1DsdaTwYh1q2g=="); CPPUNIT_ASSERT_EQUAL(aStr, aHash); } diff --git a/comphelper/source/misc/docpasswordhelper.cxx b/comphelper/source/misc/docpasswordhelper.cxx index 5dfd25575d91..8a35c33ca92d 100644 --- a/comphelper/source/misc/docpasswordhelper.cxx +++ b/comphelper/source/misc/docpasswordhelper.cxx @@ -263,7 +263,7 @@ css::uno::Sequence DocPasswordHelper::GetOoxHashAsSequence( const rtl::OUString& rPassword, const rtl::OUString& rSaltValue, sal_uInt32 nSpinCount, - bool bPrependNotAppend, + comphelper::Hash::IterCount eIterCount, const rtl::OUString& rAlgorithmName) { comphelper::HashType eType; @@ -287,7 +287,7 @@ css::uno::Sequence DocPasswordHelper::GetOoxHashAsSequence( } std::vector hash( comphelper::Hash::calculateHash( rPassword, aSaltVec, nSpinCount, - bPrependNotAppend, eType)); + eIterCount, eType)); return comphelper::containerToSequence( hash); } @@ -296,11 +296,11 @@ OUString DocPasswordHelper::GetOoxHashAsBase64( const rtl::OUString& rPassword, const rtl::OUString& rSaltValue, sal_uInt32 nSpinCount, - bool bPrependNotAppend, + comphelper::Hash::IterCount eIterCount, const rtl::OUString& rAlgorithmName) { css::uno::Sequence aSeq( GetOoxHashAsSequence( rPassword, rSaltValue, nSpinCount, - bPrependNotAppend, rAlgorithmName)); + eIterCount, rAlgorithmName)); OUStringBuffer aBuf; comphelper::Base64::encode( aBuf, aSeq); diff --git a/comphelper/source/misc/hash.cxx b/comphelper/source/misc/hash.cxx index 8d709daa75f7..b07fd66c0628 100644 --- a/comphelper/source/misc/hash.cxx +++ b/comphelper/source/misc/hash.cxx @@ -157,7 +157,7 @@ std::vector Hash::calculateHash( const unsigned char* pInput, size_t nLength, const unsigned char* pSalt, size_t nSaltLen, sal_uInt32 nSpinCount, - bool bPrependNotAppend, + IterCount eIterCount, HashType eType) { if (!pSalt) @@ -188,21 +188,25 @@ std::vector Hash::calculateHash( // https://msdn.microsoft.com/en-us/library/dd924776 and // https://msdn.microsoft.com/en-us/library/dd925430 // say the iteration is prepended to the hash. - const size_t nIterPos = (bPrependNotAppend ? 0 : hash.size()); - const size_t nHashPos = (bPrependNotAppend ? 4 : 0); - std::vector data( hash.size() + 4, 0); + const size_t nAddIter = (eIterCount == IterCount::NONE ? 0 : 4); + const size_t nIterPos = (eIterCount == IterCount::APPEND ? hash.size() : 0); + const size_t nHashPos = (eIterCount == IterCount::PREPEND ? nAddIter : 0); + std::vector data( hash.size() + nAddIter, 0); for (sal_uInt32 i = 0; i < nSpinCount; ++i) { std::copy( hash.begin(), hash.end(), data.begin() + nHashPos); + if (nAddIter) + { #ifdef OSL_BIGENDIAN - sal_uInt32 be = i; - sal_uInt8* p = reinterpret_cast(&be); - std::swap( p[0], p[3] ); - std::swap( p[1], p[2] ); - memcpy( data.data() + nIterPos, &be, 4); + sal_uInt32 be = i; + sal_uInt8* p = reinterpret_cast(&be); + std::swap( p[0], p[3] ); + std::swap( p[1], p[2] ); + memcpy( data.data() + nIterPos, &be, nAddIter); #else - memcpy( data.data() + nIterPos, &i, 4); + memcpy( data.data() + nIterPos, &i, nAddIter); #endif + } /* TODO: isn't there something better than * creating/finalizing/destroying on each iteration? */ Hash aReHash(eType); @@ -218,7 +222,7 @@ std::vector Hash::calculateHash( const OUString& rPassword, const std::vector& rSaltValue, sal_uInt32 nSpinCount, - bool bPrependNotAppend, + IterCount eIterCount, HashType eType) { const unsigned char* pPassBytes = reinterpret_cast(rPassword.getStr()); @@ -240,7 +244,7 @@ std::vector Hash::calculateHash( } #endif return calculateHash( pPassBytes, nPassBytesLen, rSaltValue.data(), rSaltValue.size(), nSpinCount, - bPrependNotAppend, eType); + eIterCount, eType); } } -- cgit