First public contribution.
2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
21 #include <cryptostrength.h>
22 #include <securityerr.h>
26 #include <pbencryptor.h>
27 #include "pbesymmetricfactory.h"
29 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(const TPBPassword& aPassword)
31 CPBEncryptElement* self = NewLC(aPassword);
36 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(const TPBPassword& aPassword)
38 CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
39 CleanupStack::PushL(self);
40 self->ConstructL(aPassword.Password());
44 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(const TPBPassword& aPassword,
45 const TPBECipher aCipher)
47 CPBEncryptElement* self = NewLC(aPassword, aCipher);
52 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(const TPBPassword& aPassword,
53 const TPBECipher aCipher)
55 CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
56 CleanupStack::PushL(self);
57 self->ConstructL(aPassword.Password(), aCipher);
61 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(const TPBPassword& aPassword,
62 const CPBEncryptParms& aParms)
64 CPBEncryptElement* self = NewLC(aPassword, aParms);
69 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(const TPBPassword& aPassword,
70 const CPBEncryptParms& aParms)
72 CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
73 CleanupStack::PushL(self);
74 self->ConstructL(aPassword.Password(), aParms);
78 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(
79 const CPBEncryptionData& aData, const TPBPassword& aPassword)
81 CPBEncryptElement* self = CPBEncryptElement::NewLC(aData, aPassword);
86 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(
87 const CPBEncryptionData& aData, const TPBPassword& aPassword)
89 CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
90 CleanupStack::PushL(self);
91 self->ConstructL(aData, aPassword);
95 CPBEncryptElement::CPBEncryptElement(void)
99 CPBEncryptElement::~CPBEncryptElement(void)
105 void CPBEncryptElement::ConstructL(const TDesC8& aPassword)
107 // Construct based on cryptography strength
108 if (TCrypto::Strength() == TCrypto::EStrong)
110 ConstructL(aPassword, KPBEDefaultStrongCipher);
114 ConstructL(aPassword, KPBEDefaultWeakCipher);
118 void CPBEncryptElement::ConstructL(const TDesC8& aPassword, TPBECipher aCipher)
120 TBuf8<KPBEMaxCipherIVBytes> iv(KPBEMaxCipherIVBytes);
121 iv.SetLength(PBE::GetBlockBytes(aCipher));
122 TRandom::RandomL(iv);
124 TBuf8<KPBEDefaultSaltBytes> encryptSalt(KPBEDefaultSaltBytes);
125 TRandom::RandomL(encryptSalt);
127 TBuf8<KPBEDefaultSaltBytes> authSalt(KPBEDefaultSaltBytes);
128 TRandom::RandomL(authSalt);
130 iData = CPBEncryptionData::NewL(aPassword, aCipher, authSalt, encryptSalt,
131 iv, KDefaultIterations);
133 MakeEncryptKeyL(PBE::GetKeyBytes(aCipher), aPassword);
136 void CPBEncryptElement::ConstructL(const CPBEncryptionData& aData,
137 const TPBPassword& aPassword)
139 iData = CPBEncryptionData::NewL(aData);
140 if(!AuthenticateL(aPassword))
142 User::Leave(KErrBadPassphrase);
146 void CPBEncryptElement::ConstructL(const TDesC8& aPassword,
147 const CPBEncryptParms& aParms)
149 TUint keySize = PBE::GetKeyBytes(aParms.Cipher());
151 TBuf8<KPBEDefaultSaltBytes> authSalt(KPBEDefaultSaltBytes);
152 TRandom::RandomL(authSalt);
154 //Recreate parms with given data and create a totally new auth
155 iData = CPBEncryptionData::NewL(aPassword, authSalt, aParms);
156 MakeEncryptKeyL(keySize, aPassword);
159 const CPBEncryptionData& CPBEncryptElement::EncryptionData(void) const
164 CPBEncryptor* CPBEncryptElement::NewEncryptL() const
166 CPBEncryptor* encryptor = NewEncryptLC();
171 CPBEncryptor* CPBEncryptElement::NewEncryptLC() const
173 CPBEncryptor* encryptor = CPBEncryptorElement::NewLC(
174 iData->EncryptParms().Cipher(), *iEncryptKey,
175 iData->EncryptParms().IV());
179 TBool CPBEncryptElement::AuthenticateL(const TPBPassword& aPassword)
181 TBool retval = EFalse;
183 //create a new auth to test against the existing one
184 //therefore we use the same key size, and salt as the current one
185 CPBAuthData* auth = CPBAuthData::NewLC(aPassword.Password(),
186 iData->AuthData().Salt(), iData->AuthData().Key().Size(),
187 iData->AuthData().Iterations());
188 if(*auth==iData->AuthData())
190 //We've got a valid password, regenerate the key so they can decrypt
191 //stuff. We don't the change the length of iEncryptKey as we assume the
192 //previous key size is appropriate for the new one
193 MakeEncryptKeyL(PBE::GetKeyBytes(iData->EncryptParms().Cipher()),
194 aPassword.Password());
197 CleanupStack::PopAndDestroy(auth);
201 CPBDecryptor* CPBEncryptElement::NewDecryptL() const
203 CPBDecryptor* decryptor = NewDecryptLC();
208 CPBDecryptor* CPBEncryptElement::NewDecryptLC() const
210 CPBDecryptor* decryptor = CPBDecryptorElement::NewLC(
211 iData->EncryptParms().Cipher(), *iEncryptKey,
212 iData->EncryptParms().IV());
216 // Warning: This function is only valid BEFORE you call NewEncryptL
217 // After creating the cipher, ask it about itself, not me!
218 // This is _very_ dodgy as I assume all sorts of things about the encryptor.
219 // 1) That it uses SSLv3 or similar style padding
220 // 2) That it stores the IV for that stream at the front.
221 // This is here for specific application that requires this and aren't able to
222 // actually construct the cipher and ask it. In almost all other cases you
223 // should construct the cipher and ask it.
224 TInt CPBEncryptElement::MaxCiphertextLength(TInt aPlaintextLength) const
226 TUint blocksize = PBE::GetBlockBytes(iData->EncryptParms().Cipher());
227 TUint padding = blocksize - aPlaintextLength % blocksize;
228 //len = inputLength + padding
229 return aPlaintextLength + padding;
232 // Warning: This function is only valid BEFORE you call NewDecryptL
233 // After creating the cipher, ask it about itself, not me!
234 TInt CPBEncryptElement::MaxPlaintextLength(TInt aCiphertextLength) const
236 /*It's impossible to determine anything about how much padding will be
237 * removed. So we'll return a max length that is longer than will
238 * ever happen by at most a blocksize - 1.
240 //totallength = inputlength - 1 byte of padding min
241 return aCiphertextLength - 1;
244 void CPBEncryptElement::MakeEncryptKeyL(TUint aKeySize, const TDesC8& aPassword)
246 iEncryptKey = HBufC8::NewMaxL(aKeySize);
247 TPtr8 encryptKeyBuf = iEncryptKey->Des();
248 iData->EncryptParms().DeriveKeyL(aPassword, encryptKeyBuf);
251 EXPORT_C TPBPassword::TPBPassword(const TDesC8& aPassword)
253 iPassword.Set(aPassword);
256 EXPORT_C TPBPassword::TPBPassword(const TDesC16& aPassword)
258 iPassword.Set(reinterpret_cast<const TUint8*>(aPassword.Ptr()), aPassword.Size());
261 EXPORT_C const TDesC8& TPBPassword::Password(void) const