os/security/crypto/weakcryptospi/source/pbe/pbe.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include <e32std.h>
sl@0
    20
#include <random.h>
sl@0
    21
#include <cryptostrength.h>
sl@0
    22
#include <securityerr.h>
sl@0
    23
#include <pbedata.h>
sl@0
    24
#include "pkcs5kdf.h"
sl@0
    25
#include "pbe.h"
sl@0
    26
#include <pbencryptor.h>
sl@0
    27
#include "pbesymmetricfactory.h"
sl@0
    28
sl@0
    29
EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(const TPBPassword& aPassword)
sl@0
    30
	{
sl@0
    31
	CPBEncryptElement* self = NewLC(aPassword);
sl@0
    32
	CleanupStack::Pop();
sl@0
    33
	return self;
sl@0
    34
	}
sl@0
    35
sl@0
    36
EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(const TPBPassword& aPassword)
sl@0
    37
	{
sl@0
    38
	CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
sl@0
    39
	CleanupStack::PushL(self);
sl@0
    40
	self->ConstructL(aPassword.Password());
sl@0
    41
	return self;
sl@0
    42
	}
sl@0
    43
sl@0
    44
EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(const TPBPassword& aPassword, 
sl@0
    45
	const TPBECipher aCipher)
sl@0
    46
	{
sl@0
    47
	CPBEncryptElement* self = NewLC(aPassword, aCipher);
sl@0
    48
	CleanupStack::Pop();
sl@0
    49
	return self;
sl@0
    50
	}
sl@0
    51
sl@0
    52
EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(const TPBPassword& aPassword, 
sl@0
    53
	const TPBECipher aCipher)
sl@0
    54
	{
sl@0
    55
	CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
sl@0
    56
	CleanupStack::PushL(self);
sl@0
    57
	self->ConstructL(aPassword.Password(), aCipher);
sl@0
    58
	return self;
sl@0
    59
	}
sl@0
    60
sl@0
    61
EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(const TPBPassword& aPassword, 
sl@0
    62
	const CPBEncryptParms& aParms)
sl@0
    63
	{
sl@0
    64
	CPBEncryptElement* self = NewLC(aPassword, aParms);
sl@0
    65
	CleanupStack::Pop();
sl@0
    66
	return self;
sl@0
    67
	}
sl@0
    68
sl@0
    69
EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(const TPBPassword& aPassword, 
sl@0
    70
	const CPBEncryptParms& aParms)
sl@0
    71
	{
sl@0
    72
	CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
sl@0
    73
	CleanupStack::PushL(self);
sl@0
    74
	self->ConstructL(aPassword.Password(), aParms);
sl@0
    75
	return self;
sl@0
    76
	}
sl@0
    77
sl@0
    78
EXPORT_C CPBEncryptElement* CPBEncryptElement::NewL(
sl@0
    79
	const CPBEncryptionData& aData, const TPBPassword& aPassword)
sl@0
    80
	{
sl@0
    81
	CPBEncryptElement* self = CPBEncryptElement::NewLC(aData, aPassword);
sl@0
    82
	CleanupStack::Pop();
sl@0
    83
	return self;
sl@0
    84
	}
sl@0
    85
sl@0
    86
EXPORT_C CPBEncryptElement* CPBEncryptElement::NewLC(
sl@0
    87
	const CPBEncryptionData& aData, const TPBPassword& aPassword)
sl@0
    88
	{
sl@0
    89
	CPBEncryptElement* self = new(ELeave) CPBEncryptElement;
sl@0
    90
	CleanupStack::PushL(self);
sl@0
    91
	self->ConstructL(aData, aPassword);
sl@0
    92
	return self;
sl@0
    93
	}
sl@0
    94
sl@0
    95
CPBEncryptElement::CPBEncryptElement(void) 
sl@0
    96
	{
sl@0
    97
	}
sl@0
    98
sl@0
    99
CPBEncryptElement::~CPBEncryptElement(void)
sl@0
   100
	{
sl@0
   101
	delete iData;
sl@0
   102
	delete iEncryptKey;
sl@0
   103
	}
sl@0
   104
sl@0
   105
void CPBEncryptElement::ConstructL(const TDesC8& aPassword)
sl@0
   106
	{
sl@0
   107
	// Construct based on cryptography strength
sl@0
   108
	if (TCrypto::Strength() == TCrypto::EStrong)
sl@0
   109
		{
sl@0
   110
		ConstructL(aPassword, KPBEDefaultStrongCipher);
sl@0
   111
		}
sl@0
   112
	else
sl@0
   113
		{
sl@0
   114
		ConstructL(aPassword, KPBEDefaultWeakCipher);
sl@0
   115
		}
sl@0
   116
	}
sl@0
   117
sl@0
   118
void CPBEncryptElement::ConstructL(const TDesC8& aPassword, TPBECipher aCipher)
sl@0
   119
	{
sl@0
   120
	TBuf8<KPBEMaxCipherIVBytes> iv(KPBEMaxCipherIVBytes);
sl@0
   121
	iv.SetLength(PBE::GetBlockBytes(aCipher));
sl@0
   122
	TRandom::RandomL(iv);
sl@0
   123
sl@0
   124
	TBuf8<KPBEDefaultSaltBytes> encryptSalt(KPBEDefaultSaltBytes);
sl@0
   125
	TRandom::RandomL(encryptSalt);
sl@0
   126
sl@0
   127
	TBuf8<KPBEDefaultSaltBytes> authSalt(KPBEDefaultSaltBytes);
sl@0
   128
	TRandom::RandomL(authSalt);
sl@0
   129
sl@0
   130
	iData = CPBEncryptionData::NewL(aPassword, aCipher, authSalt, encryptSalt,
sl@0
   131
		iv, KDefaultIterations);
sl@0
   132
sl@0
   133
	MakeEncryptKeyL(PBE::GetKeyBytes(aCipher), aPassword);
sl@0
   134
	}
sl@0
   135
sl@0
   136
void CPBEncryptElement::ConstructL(const CPBEncryptionData& aData, 
sl@0
   137
	const TPBPassword& aPassword)
sl@0
   138
	{
sl@0
   139
	iData = CPBEncryptionData::NewL(aData);
sl@0
   140
	if(!AuthenticateL(aPassword))
sl@0
   141
		{
sl@0
   142
		User::Leave(KErrBadPassphrase);
sl@0
   143
		}
sl@0
   144
	}
sl@0
   145
sl@0
   146
void CPBEncryptElement::ConstructL(const TDesC8& aPassword,
sl@0
   147
	const CPBEncryptParms& aParms)
sl@0
   148
	{
sl@0
   149
	TUint keySize = PBE::GetKeyBytes(aParms.Cipher());
sl@0
   150
sl@0
   151
	TBuf8<KPBEDefaultSaltBytes> authSalt(KPBEDefaultSaltBytes);
sl@0
   152
	TRandom::RandomL(authSalt);
sl@0
   153
sl@0
   154
	//Recreate parms with given data and create a totally new auth
sl@0
   155
	iData = CPBEncryptionData::NewL(aPassword, authSalt, aParms);
sl@0
   156
	MakeEncryptKeyL(keySize, aPassword);
sl@0
   157
	}
sl@0
   158
sl@0
   159
const CPBEncryptionData& CPBEncryptElement::EncryptionData(void) const
sl@0
   160
	{
sl@0
   161
	return *iData;
sl@0
   162
	}
sl@0
   163
sl@0
   164
CPBEncryptor* CPBEncryptElement::NewEncryptL() const 
sl@0
   165
	{
sl@0
   166
	CPBEncryptor* encryptor = NewEncryptLC();
sl@0
   167
	CleanupStack::Pop();
sl@0
   168
	return encryptor;
sl@0
   169
	}
sl@0
   170
sl@0
   171
CPBEncryptor* CPBEncryptElement::NewEncryptLC() const
sl@0
   172
	{
sl@0
   173
	CPBEncryptor* encryptor = CPBEncryptorElement::NewLC( 
sl@0
   174
		iData->EncryptParms().Cipher(), *iEncryptKey, 
sl@0
   175
		iData->EncryptParms().IV());
sl@0
   176
	return encryptor;
sl@0
   177
	}
sl@0
   178
sl@0
   179
TBool CPBEncryptElement::AuthenticateL(const TPBPassword& aPassword)
sl@0
   180
	{
sl@0
   181
	TBool retval = EFalse;
sl@0
   182
sl@0
   183
	//create a new auth to test against the existing one
sl@0
   184
	//therefore we use the same key size, and salt as the current one
sl@0
   185
	CPBAuthData* auth = CPBAuthData::NewLC(aPassword.Password(),
sl@0
   186
		iData->AuthData().Salt(), iData->AuthData().Key().Size(),
sl@0
   187
		iData->AuthData().Iterations());
sl@0
   188
	if(*auth==iData->AuthData())
sl@0
   189
		{
sl@0
   190
		//We've got a valid password, regenerate the key so they can decrypt
sl@0
   191
		//stuff.  We don't the change the length of iEncryptKey as we assume the
sl@0
   192
		//previous key size is appropriate for the new one
sl@0
   193
		MakeEncryptKeyL(PBE::GetKeyBytes(iData->EncryptParms().Cipher()),
sl@0
   194
			aPassword.Password());
sl@0
   195
		retval = ETrue;
sl@0
   196
		}
sl@0
   197
	CleanupStack::PopAndDestroy(auth);
sl@0
   198
	return retval;
sl@0
   199
	}
sl@0
   200
sl@0
   201
CPBDecryptor* CPBEncryptElement::NewDecryptL() const
sl@0
   202
	{
sl@0
   203
	CPBDecryptor* decryptor = NewDecryptLC();
sl@0
   204
	CleanupStack::Pop();
sl@0
   205
	return decryptor;
sl@0
   206
	}
sl@0
   207
sl@0
   208
CPBDecryptor* CPBEncryptElement::NewDecryptLC() const
sl@0
   209
	{
sl@0
   210
	CPBDecryptor* decryptor = CPBDecryptorElement::NewLC(
sl@0
   211
		iData->EncryptParms().Cipher(), *iEncryptKey,
sl@0
   212
		iData->EncryptParms().IV());
sl@0
   213
	return decryptor;
sl@0
   214
	}
sl@0
   215
sl@0
   216
// Warning: This function is only valid BEFORE you call NewEncryptL
sl@0
   217
// After creating the cipher, ask it about itself, not me!
sl@0
   218
// This is _very_ dodgy as I assume all sorts of things about the encryptor.
sl@0
   219
// 1) That it uses SSLv3 or similar style padding
sl@0
   220
// 2) That it stores the IV for that stream at the front.
sl@0
   221
// This is here for specific application that requires this and aren't able to
sl@0
   222
// actually construct the cipher and ask it.  In almost all other cases you
sl@0
   223
// should construct the cipher and ask it.
sl@0
   224
TInt CPBEncryptElement::MaxCiphertextLength(TInt aPlaintextLength) const
sl@0
   225
	{
sl@0
   226
	TUint blocksize = PBE::GetBlockBytes(iData->EncryptParms().Cipher());
sl@0
   227
	TUint padding = blocksize - aPlaintextLength % blocksize;
sl@0
   228
	//len = inputLength + padding
sl@0
   229
	return aPlaintextLength + padding;
sl@0
   230
	}
sl@0
   231
sl@0
   232
// Warning: This function is only valid BEFORE you call NewDecryptL
sl@0
   233
// After creating the cipher, ask it about itself, not me!
sl@0
   234
TInt CPBEncryptElement::MaxPlaintextLength(TInt aCiphertextLength) const
sl@0
   235
	{
sl@0
   236
	/*It's impossible to determine anything about how much padding will be
sl@0
   237
	 * removed.  So we'll return a max length that is longer than will
sl@0
   238
	 * ever happen by at most a blocksize - 1.
sl@0
   239
	 */
sl@0
   240
	//totallength = inputlength - 1 byte of padding min
sl@0
   241
	return aCiphertextLength - 1;
sl@0
   242
	}
sl@0
   243
sl@0
   244
void CPBEncryptElement::MakeEncryptKeyL(TUint aKeySize, const TDesC8& aPassword)
sl@0
   245
	{
sl@0
   246
	iEncryptKey = HBufC8::NewMaxL(aKeySize);
sl@0
   247
	TPtr8 encryptKeyBuf = iEncryptKey->Des();
sl@0
   248
	iData->EncryptParms().DeriveKeyL(aPassword, encryptKeyBuf);
sl@0
   249
	}
sl@0
   250
sl@0
   251
EXPORT_C TPBPassword::TPBPassword(const TDesC8& aPassword)
sl@0
   252
	{
sl@0
   253
	iPassword.Set(aPassword);
sl@0
   254
	}
sl@0
   255
sl@0
   256
EXPORT_C TPBPassword::TPBPassword(const TDesC16& aPassword)
sl@0
   257
	{
sl@0
   258
	iPassword.Set(reinterpret_cast<const TUint8*>(aPassword.Ptr()), aPassword.Size());
sl@0
   259
	}
sl@0
   260
sl@0
   261
EXPORT_C const TDesC8& TPBPassword::Password(void) const
sl@0
   262
	{
sl@0
   263
	return iPassword;
sl@0
   264
	}
sl@0
   265
sl@0
   266