00001
00002
00003
#ifndef CRYPTOPP_PWDBASED_H
00004
#define CRYPTOPP_PWDBASED_H
00005
00006
#include "cryptlib.h"
00007
#include "hmac.h"
00008
00009 NAMESPACE_BEGIN(CryptoPP)
00010
00011 class PasswordBasedKeyDerivationFunction
00012 {
00013
public:
00014
virtual unsigned int MaxDerivedKeyLength() const =0;
00015 virtual
void GeneralDeriveKey(byte *derived,
unsigned int derivedLen, byte purpose, const byte *password,
unsigned int passwordLen, const byte *salt,
unsigned int saltLen,
unsigned int iterations) const =0;
00016 };
00017
00018
00019 template <class T>
00020 class
PKCS5_PBKDF1 : public PasswordBasedKeyDerivationFunction
00021 {
00022
public:
00023
unsigned int MaxDerivedKeyLength()
const {
return T::DIGESTSIZE;}
00024
00025
void GeneralDeriveKey(byte *derived,
unsigned int derivedLen, byte ignored,
const byte *password,
unsigned int passwordLen,
const byte *salt,
unsigned int saltLen,
unsigned int iterations)
const
00026
{DeriveKey(derived, derivedLen, password, passwordLen, salt, saltLen, iterations);}
00027
void DeriveKey(byte *derived,
unsigned int derivedLen,
const byte *password,
unsigned int passwordLen,
const byte *salt,
unsigned int saltLen=8,
unsigned int iterations=1000)
const;
00028 };
00029
00030
00031
template <
class T>
00032 class PKCS5_PBKDF2_HMAC :
public PasswordBasedKeyDerivationFunction
00033 {
00034
public:
00035
unsigned int MaxDerivedKeyLength()
const {
return 0xffffffffU;}
00036
void GeneralDeriveKey(byte *derived,
unsigned int derivedLen, byte ignored,
const byte *password,
unsigned int passwordLen,
const byte *salt,
unsigned int saltLen,
unsigned int iterations)
const
00037
{DeriveKey(derived, derivedLen, password, passwordLen, salt, saltLen, iterations);}
00038
void DeriveKey(byte *derived,
unsigned int derivedLen,
const byte *password,
unsigned int passwordLen,
const byte *salt,
unsigned int saltLen,
unsigned int iterations=1000)
const;
00039 };
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
template <
class T>
00052
void PKCS5_PBKDF1<T>::DeriveKey(byte *derived,
unsigned int derivedLen,
const byte *password,
unsigned int passwordLen,
const byte *salt,
unsigned int saltLen,
unsigned int iterations)
const
00053
{
00054 assert(derivedLen <= MaxDerivedLength());
00055 assert(iterations > 0);
00056
00057 T hash;
00058 hash.Update(password, passwordLen);
00059 hash.Update(salt, saltLen);
00060
00061
SecByteBlock buffer(hash.DigestSize());
00062 hash.Final(buffer);
00063
00064
for (
unsigned int i=1; i<iterations; i++)
00065 hash.CalculateDigest(buffer, buffer, buffer.
size());
00066
00067 memcpy(derived, buffer, derivedLen);
00068 }
00069
00070
template <
class T>
00071
void PKCS5_PBKDF2_HMAC<T>::DeriveKey(byte *derived,
unsigned int derivedLen,
const byte *password,
unsigned int passwordLen,
const byte *salt,
unsigned int saltLen,
unsigned int iterations)
const
00072
{
00073 assert(derivedLen <= MaxDerivedKeyLength());
00074 assert(iterations > 0);
00075
00076
HMAC<T> hmac(password, passwordLen);
00077
SecByteBlock buffer(hmac.
DigestSize());
00078
00079
unsigned int i=1;
00080
while (derivedLen > 0)
00081 {
00082 hmac.
Update(salt, saltLen);
00083
unsigned int j;
00084
for (j=0; j<4; j++)
00085 {
00086 byte b = i >> ((3-j)*8);
00087 hmac.
Update(&b, 1);
00088 }
00089 hmac.
Final(buffer);
00090
00091
unsigned int segmentLen = STDMIN(derivedLen, (
unsigned int)buffer.
size());
00092 memcpy(derived, buffer, segmentLen);
00093
00094
for (j=1; j<iterations; j++)
00095 {
00096 hmac.
CalculateDigest(buffer, buffer, buffer.
size());
00097 xorbuf(derived, buffer, segmentLen);
00098 }
00099
00100 derived += segmentLen;
00101 derivedLen -= segmentLen;
00102 i++;
00103 }
00104 }
00105
00106
00107
template <
class T>
00108 class PKCS12_PBKDF :
public PasswordBasedKeyDerivationFunction
00109 {
00110
public:
00111
unsigned int MaxDerivedKeyLength()
const {
return UINT_MAX;}
00112
void GeneralDeriveKey(byte *derived,
unsigned int derivedLen, byte purpose,
const byte *password,
unsigned int passwordLen,
const byte *salt,
unsigned int saltLen,
unsigned int iterations)
const
00113
{DeriveKey(derived, derivedLen, purpose, password, passwordLen, salt, saltLen, iterations);}
00114
void DeriveKey(byte *derived,
unsigned int derivedLen, byte ID,
const byte *password,
unsigned int passwordLen,
const byte *salt,
unsigned int saltLen,
unsigned int iterations=1000)
const;
00115 };
00116
00117
template <
class T>
00118
void PKCS12_PBKDF<T>::DeriveKey(byte *derived,
unsigned int derivedLen, byte ID,
const byte *password,
unsigned int passwordLen,
const byte *salt,
unsigned int saltLen,
unsigned int iterations)
const
00119
{
00120 assert(derivedLen <= MaxDerivedKeyLength());
00121 assert(iterations > 0);
00122
00123
const unsigned int v = T::BLOCKSIZE;
00124
const unsigned int DLen = v, SLen = RoundUpToMultipleOf(saltLen, v);
00125
const unsigned int PLen = RoundUpToMultipleOf(passwordLen, v), ILen = SLen + PLen;
00126
SecByteBlock buffer(DLen + SLen + PLen);
00127 byte *D = buffer, *S = buffer+DLen, *P = buffer+DLen+SLen, *I = S;
00128
00129 memset(D, ID, DLen);
00130
unsigned int i;
00131
for (i=0; i<SLen; i++)
00132 S[i] = salt[i % saltLen];
00133
for (i=0; i<PLen; i++)
00134 P[i] = password[i % passwordLen];
00135
00136
00137 T hash;
00138
SecByteBlock Ai(T::DIGESTSIZE), B(v);
00139
00140
while (derivedLen > 0)
00141 {
00142 hash.CalculateDigest(Ai, buffer, buffer.size());
00143
for (i=1; i<iterations; i++)
00144 hash.CalculateDigest(Ai, Ai, Ai.
size());
00145
for (i=0; i<B.
size(); i++)
00146 B[i] = Ai[i % Ai.size()];
00147
00148
Integer B1(B, B.
size());
00149 ++B1;
00150
for (i=0; i<ILen; i+=v)
00151 (
Integer(I+i, v) + B1).Encode(I+i, v);
00152
00153
unsigned int segmentLen = STDMIN(derivedLen, (
unsigned int)Ai.size());
00154 memcpy(derived, Ai, segmentLen);
00155 derived += segmentLen;
00156 derivedLen -= segmentLen;
00157 }
00158 }
00159
00160 NAMESPACE_END
00161
00162
#endif