crypto/weakcryptospi/source/pbe/pbe.cpp
changeset 19 cd501b96611d
equal deleted inserted replaced
15:da2ae96f639b 19:cd501b96611d
       
     1 /*
       
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     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".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32std.h>
       
    20 #include <random.h>
       
    21 #include <cryptostrength.h>
       
    22 #include <securityerr.h>
       
    23 #include <pbedata.h>
       
    24 #include "pkcs5kdf.h"
       
    25 #include "pbe.h"
       
    26 #include <pbencryptor.h>
       
    27 #include "pbesymmetricfactory.h"
       
    28 
       
    29 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(const TPBPassword& aPassword)
       
    30 	{
       
    31 	CPBEncryptElement* self = NewLC(aPassword);
       
    32 	CleanupStack::Pop();
       
    33 	return self;
       
    34 	}
       
    35 
       
    36 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(const TPBPassword& aPassword)
       
    37 	{
       
    38 	CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
       
    39 	CleanupStack::PushL(self);
       
    40 	self->ConstructL(aPassword.Password());
       
    41 	return self;
       
    42 	}
       
    43 
       
    44 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(const TPBPassword& aPassword, 
       
    45 	const TPBECipher aCipher)
       
    46 	{
       
    47 	CPBEncryptElement* self = NewLC(aPassword, aCipher);
       
    48 	CleanupStack::Pop();
       
    49 	return self;
       
    50 	}
       
    51 
       
    52 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(const TPBPassword& aPassword, 
       
    53 	const TPBECipher aCipher)
       
    54 	{
       
    55 	CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
       
    56 	CleanupStack::PushL(self);
       
    57 	self->ConstructL(aPassword.Password(), aCipher);
       
    58 	return self;
       
    59 	}
       
    60 
       
    61 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(const TPBPassword& aPassword, 
       
    62 	const CPBEncryptParms& aParms)
       
    63 	{
       
    64 	CPBEncryptElement* self = NewLC(aPassword, aParms);
       
    65 	CleanupStack::Pop();
       
    66 	return self;
       
    67 	}
       
    68 
       
    69 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(const TPBPassword& aPassword, 
       
    70 	const CPBEncryptParms& aParms)
       
    71 	{
       
    72 	CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
       
    73 	CleanupStack::PushL(self);
       
    74 	self->ConstructL(aPassword.Password(), aParms);
       
    75 	return self;
       
    76 	}
       
    77 
       
    78 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(
       
    79 	const CPBEncryptionData& aData, const TPBPassword& aPassword)
       
    80 	{
       
    81 	CPBEncryptElement* self = CPBEncryptElement::NewLC(aData, aPassword);
       
    82 	CleanupStack::Pop();
       
    83 	return self;
       
    84 	}
       
    85 
       
    86 EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(
       
    87 	const CPBEncryptionData& aData, const TPBPassword& aPassword)
       
    88 	{
       
    89 	CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
       
    90 	CleanupStack::PushL(self);
       
    91 	self->ConstructL(aData, aPassword);
       
    92 	return self;
       
    93 	}
       
    94 
       
    95 CPBEncryptElement::CPBEncryptElement(void) 
       
    96 	{
       
    97 	}
       
    98 
       
    99 CPBEncryptElement::~CPBEncryptElement(void)
       
   100 	{
       
   101 	delete iData;
       
   102 	delete iEncryptKey;
       
   103 	}
       
   104 
       
   105 void CPBEncryptElement::ConstructL(const TDesC8& aPassword)
       
   106 	{
       
   107 	// Construct based on cryptography strength
       
   108 	if (TCrypto::Strength() == TCrypto::EStrong)
       
   109 		{
       
   110 		ConstructL(aPassword, KPBEDefaultStrongCipher);
       
   111 		}
       
   112 	else
       
   113 		{
       
   114 		ConstructL(aPassword, KPBEDefaultWeakCipher);
       
   115 		}
       
   116 	}
       
   117 
       
   118 void CPBEncryptElement::ConstructL(const TDesC8& aPassword, TPBECipher aCipher)
       
   119 	{
       
   120 	TBuf8<KPBEMaxCipherIVBytes> iv(KPBEMaxCipherIVBytes);
       
   121 	iv.SetLength(PBE::GetBlockBytes(aCipher));
       
   122 	TRandom::RandomL(iv);
       
   123 
       
   124 	TBuf8<KPBEDefaultSaltBytes> encryptSalt(KPBEDefaultSaltBytes);
       
   125 	TRandom::RandomL(encryptSalt);
       
   126 
       
   127 	TBuf8<KPBEDefaultSaltBytes> authSalt(KPBEDefaultSaltBytes);
       
   128 	TRandom::RandomL(authSalt);
       
   129 
       
   130 	iData = CPBEncryptionData::NewL(aPassword, aCipher, authSalt, encryptSalt,
       
   131 		iv, KDefaultIterations);
       
   132 
       
   133 	MakeEncryptKeyL(PBE::GetKeyBytes(aCipher), aPassword);
       
   134 	}
       
   135 
       
   136 void CPBEncryptElement::ConstructL(const CPBEncryptionData& aData, 
       
   137 	const TPBPassword& aPassword)
       
   138 	{
       
   139 	iData = CPBEncryptionData::NewL(aData);
       
   140 	if(!AuthenticateL(aPassword))
       
   141 		{
       
   142 		User::Leave(KErrBadPassphrase);
       
   143 		}
       
   144 	}
       
   145 
       
   146 void CPBEncryptElement::ConstructL(const TDesC8& aPassword,
       
   147 	const CPBEncryptParms& aParms)
       
   148 	{
       
   149 	TUint keySize = PBE::GetKeyBytes(aParms.Cipher());
       
   150 
       
   151 	TBuf8<KPBEDefaultSaltBytes> authSalt(KPBEDefaultSaltBytes);
       
   152 	TRandom::RandomL(authSalt);
       
   153 
       
   154 	//Recreate parms with given data and create a totally new auth
       
   155 	iData = CPBEncryptionData::NewL(aPassword, authSalt, aParms);
       
   156 	MakeEncryptKeyL(keySize, aPassword);
       
   157 	}
       
   158 
       
   159 const CPBEncryptionData& CPBEncryptElement::EncryptionData(void) const
       
   160 	{
       
   161 	return *iData;
       
   162 	}
       
   163 
       
   164 CPBEncryptor* CPBEncryptElement::NewEncryptL() const 
       
   165 	{
       
   166 	CPBEncryptor* encryptor = NewEncryptLC();
       
   167 	CleanupStack::Pop();
       
   168 	return encryptor;
       
   169 	}
       
   170 
       
   171 CPBEncryptor* CPBEncryptElement::NewEncryptLC() const
       
   172 	{
       
   173 	CPBEncryptor* encryptor = CPBEncryptorElement::NewLC( 
       
   174 		iData->EncryptParms().Cipher(), *iEncryptKey, 
       
   175 		iData->EncryptParms().IV());
       
   176 	return encryptor;
       
   177 	}
       
   178 
       
   179 TBool CPBEncryptElement::AuthenticateL(const TPBPassword& aPassword)
       
   180 	{
       
   181 	TBool retval = EFalse;
       
   182 
       
   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())
       
   189 		{
       
   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());
       
   195 		retval = ETrue;
       
   196 		}
       
   197 	CleanupStack::PopAndDestroy(auth);
       
   198 	return retval;
       
   199 	}
       
   200 
       
   201 CPBDecryptor* CPBEncryptElement::NewDecryptL() const
       
   202 	{
       
   203 	CPBDecryptor* decryptor = NewDecryptLC();
       
   204 	CleanupStack::Pop();
       
   205 	return decryptor;
       
   206 	}
       
   207 
       
   208 CPBDecryptor* CPBEncryptElement::NewDecryptLC() const
       
   209 	{
       
   210 	CPBDecryptor* decryptor = CPBDecryptorElement::NewLC(
       
   211 		iData->EncryptParms().Cipher(), *iEncryptKey,
       
   212 		iData->EncryptParms().IV());
       
   213 	return decryptor;
       
   214 	}
       
   215 
       
   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
       
   225 	{
       
   226 	TUint blocksize = PBE::GetBlockBytes(iData->EncryptParms().Cipher());
       
   227 	TUint padding = blocksize - aPlaintextLength % blocksize;
       
   228 	//len = inputLength + padding
       
   229 	return aPlaintextLength + padding;
       
   230 	}
       
   231 
       
   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
       
   235 	{
       
   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.
       
   239 	 */
       
   240 	//totallength = inputlength - 1 byte of padding min
       
   241 	return aCiphertextLength - 1;
       
   242 	}
       
   243 
       
   244 void CPBEncryptElement::MakeEncryptKeyL(TUint aKeySize, const TDesC8& aPassword)
       
   245 	{
       
   246 	iEncryptKey = HBufC8::NewMaxL(aKeySize);
       
   247 	TPtr8 encryptKeyBuf = iEncryptKey->Des();
       
   248 	iData->EncryptParms().DeriveKeyL(aPassword, encryptKeyBuf);
       
   249 	}
       
   250 
       
   251 EXPORT_C TPBPassword::TPBPassword(const TDesC8& aPassword)
       
   252 	{
       
   253 	iPassword.Set(aPassword);
       
   254 	}
       
   255 
       
   256 EXPORT_C TPBPassword::TPBPassword(const TDesC16& aPassword)
       
   257 	{
       
   258 	iPassword.Set(reinterpret_cast<const TUint8*>(aPassword.Ptr()), aPassword.Size());
       
   259 	}
       
   260 
       
   261 EXPORT_C const TDesC8& TPBPassword::Password(void) const
       
   262 	{
       
   263 	return iPassword;
       
   264 	}
       
   265 
       
   266