summaryrefslogtreecommitdiff
path: root/pwdbased.h
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2015-11-05 01:59:46 -0500
committerJeffrey Walton <noloader@gmail.com>2015-11-05 01:59:46 -0500
commit48809d4e85c125814425c621d8d0d89f95405924 (patch)
tree1010fd16c4b1199f3d27dd726dda241a2bd29f83 /pwdbased.h
parent025337a94aceb75d188149db70c2094673772816 (diff)
downloadcryptopp-git-48809d4e85c125814425c621d8d0d89f95405924.tar.gz
CRYPTOPP 5.6.3 RC6 checkin
Diffstat (limited to 'pwdbased.h')
-rw-r--r--pwdbased.h443
1 files changed, 227 insertions, 216 deletions
diff --git a/pwdbased.h b/pwdbased.h
index eb1cfe47..4f26366a 100644
--- a/pwdbased.h
+++ b/pwdbased.h
@@ -1,216 +1,227 @@
-// pwdbased.h - written and placed in the public domain by Wei Dai
-
-#ifndef CRYPTOPP_PWDBASED_H
-#define CRYPTOPP_PWDBASED_H
-
-#include "cryptlib.h"
-#include "integer.h"
-#include "hmac.h"
-#include "hrtimer.h"
-#include "integer.h"
-#include "trap.h"
-
-NAMESPACE_BEGIN(CryptoPP)
-
-//! abstract base class for password based key derivation function
-class PasswordBasedKeyDerivationFunction
-{
-public:
- virtual size_t MaxDerivedKeyLength() const =0;
- virtual bool UsesPurposeByte() const =0;
- //! derive key from password
- /*! If timeInSeconds != 0, will iterate until time elapsed, as measured by ThreadUserTimer
- Returns actual iteration count, which is equal to iterations if timeInSeconds == 0, and not less than iterations otherwise. */
- virtual unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const =0;
-};
-
-//! PBKDF1 from PKCS #5, T should be a HashTransformation class
-template <class T>
-class PKCS5_PBKDF1 : public PasswordBasedKeyDerivationFunction
-{
-public:
- size_t MaxDerivedKeyLength() const {return T::DIGESTSIZE;}
- bool UsesPurposeByte() const {return false;}
- // PKCS #5 says PBKDF1 should only take 8-byte salts. This implementation allows salts of any length.
- unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const;
-};
-
-//! PBKDF2 from PKCS #5, T should be a HashTransformation class
-template <class T>
-class PKCS5_PBKDF2_HMAC : public PasswordBasedKeyDerivationFunction
-{
-public:
- size_t MaxDerivedKeyLength() const {return 0xffffffffU;} // should multiply by T::DIGESTSIZE, but gets overflow that way
- bool UsesPurposeByte() const {return false;}
- unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const;
-};
-
-/*
-class PBKDF2Params
-{
-public:
- SecByteBlock m_salt;
- unsigned int m_interationCount;
- ASNOptional<ASNUnsignedWrapper<word32> > m_keyLength;
-};
-*/
-
-template <class T>
-unsigned int PKCS5_PBKDF1<T>::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const
-{
- CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength());
- CRYPTOPP_ASSERT(iterations > 0 || timeInSeconds > 0);
-
- if (!iterations)
- iterations = 1;
-
- T hash;
- hash.Update(password, passwordLen);
- hash.Update(salt, saltLen);
-
- SecByteBlock buffer(hash.DigestSize());
- hash.Final(buffer);
-
- unsigned int i;
- ThreadUserTimer timer;
-
- if (timeInSeconds)
- timer.StartTimer();
-
- for (i=1; i<iterations || (timeInSeconds && (i%128!=0 || timer.ElapsedTimeAsDouble() < timeInSeconds)); i++)
- hash.CalculateDigest(buffer, buffer, buffer.size());
-
- memcpy(derived, buffer, derivedLen);
- return i;
-}
-
-template <class T>
-unsigned int PKCS5_PBKDF2_HMAC<T>::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const
-{
- CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength());
- CRYPTOPP_ASSERT(iterations > 0 || timeInSeconds > 0);
-
- if (!iterations)
- iterations = 1;
-
- HMAC<T> hmac(password, passwordLen);
- SecByteBlock buffer(hmac.DigestSize());
- ThreadUserTimer timer;
-
- unsigned int i=1;
- while (derivedLen > 0)
- {
- hmac.Update(salt, saltLen);
- unsigned int j;
- for (j=0; j<4; j++)
- {
- byte b = byte(i >> ((3-j)*8));
- hmac.Update(&b, 1);
- }
- hmac.Final(buffer);
-
- size_t segmentLen = STDMIN(derivedLen, buffer.size());
- memcpy(derived, buffer, segmentLen);
-
- if (timeInSeconds)
- {
- timeInSeconds = timeInSeconds / ((derivedLen + buffer.size() - 1) / buffer.size());
- timer.StartTimer();
- }
-
- for (j=1; j<iterations || (timeInSeconds && (j%128!=0 || timer.ElapsedTimeAsDouble() < timeInSeconds)); j++)
- {
- hmac.CalculateDigest(buffer, buffer, buffer.size());
- xorbuf(derived, buffer, segmentLen);
- }
-
- if (timeInSeconds)
- {
- iterations = j;
- timeInSeconds = 0;
- }
-
- derived += segmentLen;
- derivedLen -= segmentLen;
- i++;
- }
-
- return iterations;
-}
-
-//! PBKDF from PKCS #12, appendix B, T should be a HashTransformation class
-template <class T>
-class PKCS12_PBKDF : public PasswordBasedKeyDerivationFunction
-{
-public:
- size_t MaxDerivedKeyLength() const {return size_t(0)-1;}
- bool UsesPurposeByte() const {return true;}
- unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const;
-};
-
-template <class T>
-unsigned int PKCS12_PBKDF<T>::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const
-{
- CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength());
- CRYPTOPP_ASSERT(iterations > 0 || timeInSeconds > 0);
-
- if (!iterations)
- iterations = 1;
-
- const size_t v = T::BLOCKSIZE; // v is in bytes rather than bits as in PKCS #12
- const size_t DLen = v, SLen = RoundUpToMultipleOf(saltLen, v);
- const size_t PLen = RoundUpToMultipleOf(passwordLen, v), ILen = SLen + PLen;
- SecByteBlock buffer(DLen + SLen + PLen);
- byte *D = buffer, *S = buffer+DLen, *P = buffer+DLen+SLen, *I = S;
-
- memset(D, purpose, DLen);
- size_t i;
- for (i=0; i<SLen; i++)
- S[i] = salt[i % saltLen];
- for (i=0; i<PLen; i++)
- P[i] = password[i % passwordLen];
-
-
- T hash;
- SecByteBlock Ai(T::DIGESTSIZE), B(v);
- ThreadUserTimer timer;
-
- while (derivedLen > 0)
- {
- hash.CalculateDigest(Ai, buffer, buffer.size());
-
- if (timeInSeconds)
- {
- timeInSeconds = timeInSeconds / ((derivedLen + Ai.size() - 1) / Ai.size());
- timer.StartTimer();
- }
-
- for (i=1; i<iterations || (timeInSeconds && (i%128!=0 || timer.ElapsedTimeAsDouble() < timeInSeconds)); i++)
- hash.CalculateDigest(Ai, Ai, Ai.size());
-
- if (timeInSeconds)
- {
- iterations = (unsigned int)i;
- timeInSeconds = 0;
- }
-
- for (i=0; i<B.size(); i++)
- B[i] = Ai[i % Ai.size()];
-
- Integer B1(B, B.size());
- ++B1;
- for (i=0; i<ILen; i+=v)
- (Integer(I+i, v) + B1).Encode(I+i, v);
-
- size_t segmentLen = STDMIN(derivedLen, Ai.size());
- memcpy(derived, Ai, segmentLen);
- derived += segmentLen;
- derivedLen -= segmentLen;
- }
-
- return iterations;
-}
-
-NAMESPACE_END
-
-#endif
+// pwdbased.h - written and placed in the public domain by Wei Dai
+
+#ifndef CRYPTOPP_PWDBASED_H
+#define CRYPTOPP_PWDBASED_H
+
+#include "cryptlib.h"
+#include "hrtimer.h"
+#include "integer.h"
+#include "hmac.h"
+
+NAMESPACE_BEGIN(CryptoPP)
+
+//! abstract base class for password based key derivation function
+class PasswordBasedKeyDerivationFunction
+{
+public:
+ virtual size_t MaxDerivedKeyLength() const =0;
+ virtual bool UsesPurposeByte() const =0;
+ //! derive key from password
+ /*! If timeInSeconds != 0, will iterate until time elapsed, as measured by ThreadUserTimer
+ Returns actual iteration count, which is equal to iterations if timeInSeconds == 0, and not less than iterations otherwise. */
+ virtual unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const =0;
+};
+
+//! PBKDF1 from PKCS #5, T should be a HashTransformation class
+template <class T>
+class PKCS5_PBKDF1 : public PasswordBasedKeyDerivationFunction
+{
+public:
+ size_t MaxDerivedKeyLength() const {return T::DIGESTSIZE;}
+ bool UsesPurposeByte() const {return false;}
+ // PKCS #5 says PBKDF1 should only take 8-byte salts. This implementation allows salts of any length.
+ unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const;
+};
+
+//! PBKDF2 from PKCS #5, T should be a HashTransformation class
+template <class T>
+class PKCS5_PBKDF2_HMAC : public PasswordBasedKeyDerivationFunction
+{
+public:
+ size_t MaxDerivedKeyLength() const {return 0xffffffffU;} // should multiply by T::DIGESTSIZE, but gets overflow that way
+ bool UsesPurposeByte() const {return false;}
+ unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const;
+};
+
+/*
+class PBKDF2Params
+{
+public:
+ SecByteBlock m_salt;
+ unsigned int m_interationCount;
+ ASNOptional<ASNUnsignedWrapper<word32> > m_keyLength;
+};
+*/
+
+template <class T>
+unsigned int PKCS5_PBKDF1<T>::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const
+{
+ CRYPTOPP_UNUSED(purpose);
+ assert(derivedLen <= MaxDerivedKeyLength());
+ assert(iterations > 0 || timeInSeconds > 0);
+
+ if (!iterations)
+ iterations = 1;
+
+ T hash;
+ hash.Update(password, passwordLen);
+ hash.Update(salt, saltLen);
+
+ SecByteBlock buffer(hash.DigestSize());
+ hash.Final(buffer);
+
+ unsigned int i;
+ ThreadUserTimer timer;
+
+ if (timeInSeconds)
+ timer.StartTimer();
+
+ for (i=1; i<iterations || (timeInSeconds && (i%128!=0 || timer.ElapsedTimeAsDouble() < timeInSeconds)); i++)
+ hash.CalculateDigest(buffer, buffer, buffer.size());
+
+ memcpy(derived, buffer, derivedLen);
+ return i;
+}
+
+template <class T>
+unsigned int PKCS5_PBKDF2_HMAC<T>::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const
+{
+ CRYPTOPP_UNUSED(purpose);
+ assert(derivedLen <= MaxDerivedKeyLength());
+ assert(iterations > 0 || timeInSeconds > 0);
+
+ if (!iterations)
+ iterations = 1;
+
+ HMAC<T> hmac(password, passwordLen);
+ SecByteBlock buffer(hmac.DigestSize());
+ ThreadUserTimer timer;
+
+ unsigned int i=1;
+ while (derivedLen > 0)
+ {
+ hmac.Update(salt, saltLen);
+ unsigned int j;
+ for (j=0; j<4; j++)
+ {
+ byte b = byte(i >> ((3-j)*8));
+ hmac.Update(&b, 1);
+ }
+ hmac.Final(buffer);
+
+#if CRYPTOPP_MSC_VERSION
+ const size_t segmentLen = STDMIN(derivedLen, buffer.size());
+ memcpy_s(derived, segmentLen, buffer, segmentLen);
+#else
+ const size_t segmentLen = STDMIN(derivedLen, buffer.size());
+ memcpy(derived, buffer, segmentLen);
+#endif
+
+ if (timeInSeconds)
+ {
+ timeInSeconds = timeInSeconds / ((derivedLen + buffer.size() - 1) / buffer.size());
+ timer.StartTimer();
+ }
+
+ for (j=1; j<iterations || (timeInSeconds && (j%128!=0 || timer.ElapsedTimeAsDouble() < timeInSeconds)); j++)
+ {
+ hmac.CalculateDigest(buffer, buffer, buffer.size());
+ xorbuf(derived, buffer, segmentLen);
+ }
+
+ if (timeInSeconds)
+ {
+ iterations = j;
+ timeInSeconds = 0;
+ }
+
+ derived += segmentLen;
+ derivedLen -= segmentLen;
+ i++;
+ }
+
+ return iterations;
+}
+
+//! PBKDF from PKCS #12, appendix B, T should be a HashTransformation class
+template <class T>
+class PKCS12_PBKDF : public PasswordBasedKeyDerivationFunction
+{
+public:
+ size_t MaxDerivedKeyLength() const {return size_t(0)-1;}
+ bool UsesPurposeByte() const {return true;}
+ unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const;
+};
+
+template <class T>
+unsigned int PKCS12_PBKDF<T>::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const
+{
+ assert(derivedLen <= MaxDerivedKeyLength());
+ assert(iterations > 0 || timeInSeconds > 0);
+
+ if (!iterations)
+ iterations = 1;
+
+ const size_t v = T::BLOCKSIZE; // v is in bytes rather than bits as in PKCS #12
+ const size_t DLen = v, SLen = RoundUpToMultipleOf(saltLen, v);
+ const size_t PLen = RoundUpToMultipleOf(passwordLen, v), ILen = SLen + PLen;
+ SecByteBlock buffer(DLen + SLen + PLen);
+ byte *D = buffer, *S = buffer+DLen, *P = buffer+DLen+SLen, *I = S;
+
+ memset(D, purpose, DLen);
+ size_t i;
+ for (i=0; i<SLen; i++)
+ S[i] = salt[i % saltLen];
+ for (i=0; i<PLen; i++)
+ P[i] = password[i % passwordLen];
+
+
+ T hash;
+ SecByteBlock Ai(T::DIGESTSIZE), B(v);
+ ThreadUserTimer timer;
+
+ while (derivedLen > 0)
+ {
+ hash.CalculateDigest(Ai, buffer, buffer.size());
+
+ if (timeInSeconds)
+ {
+ timeInSeconds = timeInSeconds / ((derivedLen + Ai.size() - 1) / Ai.size());
+ timer.StartTimer();
+ }
+
+ for (i=1; i<iterations || (timeInSeconds && (i%128!=0 || timer.ElapsedTimeAsDouble() < timeInSeconds)); i++)
+ hash.CalculateDigest(Ai, Ai, Ai.size());
+
+ if (timeInSeconds)
+ {
+ iterations = (unsigned int)i;
+ timeInSeconds = 0;
+ }
+
+ for (i=0; i<B.size(); i++)
+ B[i] = Ai[i % Ai.size()];
+
+ Integer B1(B, B.size());
+ ++B1;
+ for (i=0; i<ILen; i+=v)
+ (Integer(I+i, v) + B1).Encode(I+i, v);
+
+#if CRYPTOPP_MSC_VERSION
+ const size_t segmentLen = STDMIN(derivedLen, Ai.size());
+ memcpy_s(derived, segmentLen, Ai, segmentLen);
+#else
+ const size_t segmentLen = STDMIN(derivedLen, Ai.size());
+ std::memcpy(derived, Ai, segmentLen);
+#endif
+
+ derived += segmentLen;
+ derivedLen -= segmentLen;
+ }
+
+ return iterations;
+}
+
+NAMESPACE_END
+
+#endif