sl@0: /* sl@0: * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include "tactionmontecarlo.h" sl@0: #include "bufferedtransformation.h" sl@0: #include "rijndael.h" sl@0: #include "cbcmode.h" sl@0: #include "padding.h" sl@0: sl@0: const TInt KAESBlockSizeBytes = 16; // 128 bits sl@0: sl@0: CTestAction* CActionMonteCarlo::NewL(RFs& aFs, sl@0: CConsoleBase& aConsole, sl@0: Output& aOut, sl@0: const TTestActionSpec& aTestActionSpec) sl@0: { sl@0: CTestAction* self = CActionMonteCarlo::NewLC(aFs, aConsole, sl@0: aOut, aTestActionSpec); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: CTestAction* CActionMonteCarlo::NewLC(RFs& aFs, sl@0: CConsoleBase& aConsole, sl@0: Output& aOut, sl@0: const TTestActionSpec& aTestActionSpec) sl@0: { sl@0: CActionMonteCarlo* self = new(ELeave) CActionMonteCarlo(aFs, aConsole, aOut); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aTestActionSpec); sl@0: return self; sl@0: } sl@0: sl@0: CActionMonteCarlo::~CActionMonteCarlo() sl@0: { sl@0: delete iEncrypt; sl@0: delete iDecrypt; sl@0: } sl@0: sl@0: CActionMonteCarlo::CActionMonteCarlo(RFs& aFs, sl@0: CConsoleBase& aConsole, sl@0: Output& aOut) sl@0: sl@0: : CCryptoTestAction(aFs, aConsole, aOut) sl@0: {} sl@0: sl@0: sl@0: void CActionMonteCarlo::DoPerformPrerequisiteL() sl@0: { sl@0: TInt err = KErrNone; sl@0: TInt pos = 0; sl@0: TPtrC8 monteCarlo = Input::ParseElement(*iBody, KMonteCarloStart, KMonteCarloEnd, pos, err); sl@0: sl@0: DoInputParseL(monteCarlo); sl@0: sl@0: CBlockTransformation* encryptor = NULL; sl@0: CBlockTransformation* decryptor = NULL; sl@0: sl@0: switch (iCipherType) sl@0: { sl@0: case (EAESMonteCarloEncryptECB): sl@0: { sl@0: encryptor = CAESEncryptor::NewLC(iKey->Des()); sl@0: } sl@0: break; sl@0: case (EAESMonteCarloDecryptECB): sl@0: { sl@0: decryptor = CAESDecryptor::NewLC(iKey->Des()); sl@0: } sl@0: break; sl@0: case (EAESMonteCarloEncryptCBC): sl@0: { sl@0: CBlockTransformation* aesEncryptor = NULL; sl@0: aesEncryptor = CAESEncryptor::NewLC(iKey->Des()); sl@0: sl@0: encryptor = CModeCBCEncryptor::NewL(aesEncryptor, iIV->Des()); sl@0: CleanupStack::Pop(aesEncryptor); sl@0: CleanupStack::PushL(encryptor); sl@0: } sl@0: break; sl@0: case (EAESMonteCarloDecryptCBC): sl@0: { sl@0: CBlockTransformation* aesDecryptor = NULL; sl@0: aesDecryptor = CAESDecryptor::NewLC(iKey->Des()); sl@0: sl@0: decryptor = CModeCBCDecryptor::NewL(aesDecryptor, iIV->Des()); sl@0: CleanupStack::Pop(aesDecryptor); sl@0: CleanupStack::PushL(decryptor); sl@0: } sl@0: break; sl@0: default: sl@0: { sl@0: ASSERT(0); sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: } sl@0: sl@0: sl@0: CPaddingSSLv3* padding = 0; sl@0: if (encryptor) sl@0: { sl@0: padding = CPaddingSSLv3::NewLC(encryptor->BlockSize()); sl@0: iEncrypt = CBufferedEncryptor::NewL(encryptor, padding); sl@0: iEResult = HBufC8::NewMaxL(iEncrypt->MaxOutputLength(iInput->Length())); sl@0: } sl@0: else if (decryptor) sl@0: { sl@0: padding = CPaddingSSLv3::NewLC(decryptor->BlockSize()); sl@0: iDecrypt = CBufferedDecryptor::NewL(decryptor, padding); sl@0: iDResult = HBufC8::NewMaxL(iDecrypt->MaxOutputLength(iInput->Size())); sl@0: } sl@0: sl@0: CleanupStack::Pop(2); // padding, encryptor/decryptor sl@0: sl@0: } sl@0: sl@0: sl@0: void CActionMonteCarlo::DoPerformActionL() sl@0: { sl@0: iResult = EFalse; sl@0: sl@0: __ASSERT_DEBUG(iInput->Size()==KAESBlockSizeBytes, User::Panic(_L("tsymmetric"), KErrNotSupported)); sl@0: sl@0: if (iCipherType==EAESMonteCarloEncryptECB) sl@0: DoAESEncryptECB(); sl@0: else if (iCipherType==EAESMonteCarloDecryptECB) sl@0: DoAESDecryptECB(); sl@0: else if (iCipherType==EAESMonteCarloEncryptCBC) sl@0: DoAESEncryptCBC(); sl@0: else if (iCipherType==EAESMonteCarloDecryptCBC) sl@0: DoAESDecryptCBC(); sl@0: else sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: sl@0: void CActionMonteCarlo::DoAESEncryptECB() sl@0: { sl@0: TPtr8 theEncryptResult(iEResult->Des()); sl@0: theEncryptResult.FillZ(theEncryptResult.MaxLength()); sl@0: theEncryptResult.SetLength(0); sl@0: sl@0: TInt index = 0; sl@0: TPtr8 theInput(iInput->Des()); sl@0: for (; index < KMonteCarloIterations; index++) sl@0: { sl@0: iEncrypt->Process(theInput, theEncryptResult); sl@0: theInput.Copy(theEncryptResult); sl@0: theEncryptResult.FillZ(theEncryptResult.MaxLength()); sl@0: theEncryptResult.SetLength(0); sl@0: } sl@0: sl@0: if (*iOutput==*iEResult) sl@0: { sl@0: iResult = ETrue; sl@0: } sl@0: } sl@0: sl@0: void CActionMonteCarlo::DoAESDecryptECB() sl@0: { sl@0: TPtr8 theDecryptResult(iDResult->Des()); sl@0: theDecryptResult.FillZ(theDecryptResult.MaxLength()); sl@0: theDecryptResult.SetLength(0); sl@0: sl@0: TInt index = 0; sl@0: TPtr8 theInput(iInput->Des()); sl@0: for (; index < KMonteCarloIterations; index++) sl@0: { sl@0: iDecrypt->Process(theInput, theDecryptResult); sl@0: theInput.Copy(theDecryptResult); sl@0: theDecryptResult.FillZ(theDecryptResult.MaxLength()); sl@0: theDecryptResult.SetLength(0); sl@0: } sl@0: sl@0: if (*iOutput==*iInput) sl@0: { sl@0: iResult = ETrue; sl@0: } sl@0: } sl@0: sl@0: void CActionMonteCarlo::DoAESEncryptCBC() sl@0: { sl@0: TPtr8 theEncryptResult(iEResult->Des()); sl@0: theEncryptResult.FillZ(theEncryptResult.MaxLength()); sl@0: theEncryptResult.SetLength(0); sl@0: sl@0: TInt index = 0; sl@0: TPtr8 theInput(iInput->Des()); sl@0: sl@0: TBuf8 nextBuf; sl@0: nextBuf.FillZ(KAESBlockSizeBytes); sl@0: sl@0: for (; index < KMonteCarloIterations-1; index++) sl@0: { sl@0: iEncrypt->Process(theInput, theEncryptResult); sl@0: sl@0: if (index==0) sl@0: theInput.Copy(*iIV); // First loop, use the original IV as next PT block sl@0: else sl@0: theInput.Copy(nextBuf); // Use previous CT block as next PT block sl@0: sl@0: // Save CT block for next loop when it'll become the PT block sl@0: nextBuf.Copy(theEncryptResult); sl@0: // Reset for next encryption sl@0: theEncryptResult.FillZ(theEncryptResult.MaxLength()); sl@0: theEncryptResult.SetLength(0); sl@0: } sl@0: sl@0: iEncrypt->Process(theInput, theEncryptResult); sl@0: sl@0: if (theEncryptResult.Compare(*iOutput)==KErrNone) sl@0: { sl@0: iResult = ETrue; sl@0: } sl@0: sl@0: } sl@0: sl@0: void CActionMonteCarlo::DoAESDecryptCBC() sl@0: { sl@0: TPtr8 theDecryptResult(iDResult->Des()); sl@0: theDecryptResult.FillZ(theDecryptResult.MaxLength()); sl@0: theDecryptResult.SetLength(0); sl@0: sl@0: TInt index = 0; sl@0: TPtr8 theInput(iInput->Des()); sl@0: sl@0: for (; index < KMonteCarloIterations-1; index++) sl@0: { sl@0: iDecrypt->Process(theInput, theDecryptResult); sl@0: sl@0: // Use previous PT block as next CT block sl@0: theInput.Copy(theDecryptResult); sl@0: sl@0: // Reset for next decryption sl@0: theDecryptResult.FillZ(theDecryptResult.MaxLength()); sl@0: theDecryptResult.SetLength(0); sl@0: } sl@0: sl@0: // Last loop sl@0: iDecrypt->Process(theInput, theDecryptResult); sl@0: sl@0: if (theDecryptResult.Compare(*iOutput)==KErrNone) sl@0: { sl@0: iResult = ETrue; sl@0: } sl@0: sl@0: }