sl@0: /* sl@0: * Copyright (c) 2007-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: /** sl@0: @file sl@0: @internalTechnology sl@0: */ sl@0: sl@0: #include "symmetriccipherctrmodeoutoforderstep.h" sl@0: sl@0: using namespace CryptoSpi; sl@0: sl@0: CSymmetricCipherCtrModeOutOfOrderStep::CSymmetricCipherCtrModeOutOfOrderStep() sl@0: { sl@0: SetTestStepName(KSymmetricCipherCtrModeOutOfOrderStep); sl@0: } sl@0: sl@0: sl@0: TVerdict CSymmetricCipherCtrModeOutOfOrderStep::doTestStepPreambleL() sl@0: { sl@0: SetTestStepResult(EPass); sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: sl@0: TVerdict CSymmetricCipherCtrModeOutOfOrderStep::doTestStepL() sl@0: { sl@0: INFO_PRINTF1(_L("*** Symmetric Cipher - Counter mode out of order operation ***")); sl@0: INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells()); sl@0: sl@0: if (TestStepResult() != EPass) sl@0: { sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: //Assume failure, unless all is successful sl@0: SetTestStepResult(EFail); sl@0: sl@0: TVariantPtrC operationMode; sl@0: sl@0: CSymmetricCipher* impl = NULL; sl@0: CKey* key = NULL; sl@0: SetupCipherL(EFalse, EFalse, operationMode, impl, key); sl@0: sl@0: INFO_PRINTF1(_L("Plugin loaded.")); sl@0: sl@0: CleanupStack::PushL(key); sl@0: CleanupStack::PushL(impl); sl@0: sl@0: sl@0: if (TUid(operationMode) != KOperationModeCTRUid) sl@0: { sl@0: ERR_PRINTF2(_L("*** FAIL: This test supports CTR operation mode only and not mode id: %d ***"), (TUid(operationMode)).iUid); sl@0: CleanupStack::PopAndDestroy(2, key); sl@0: INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells()); sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: sl@0: HBufC8* plaintext = ReadInPlaintextL(); sl@0: CleanupStack::PushL(plaintext); sl@0: sl@0: sl@0: TInt blockSize = CtrModeCalcBlockSizeL(*impl)/8; sl@0: sl@0: if (plaintext->Length() < ((blockSize * 2) + 1)) sl@0: { sl@0: ERR_PRINTF2(_L("*** FAIL: Plaintext argument is not long enough for this test, length(B) = %d ***"), plaintext->Length()); sl@0: CleanupStack::PopAndDestroy(3, key); sl@0: INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells()); sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: // This will store our calculated version of the ciphertext to compare with that in the .ini file sl@0: TUint8* calculatedCiphertext = new (ELeave) TUint8[plaintext->Length()]; sl@0: CleanupStack::PushL(calculatedCiphertext); sl@0: // Ptr to the first block of the calculated ciphertext sl@0: TPtr8 calcCipherPtr1(calculatedCiphertext, blockSize); sl@0: // Ptr to the remaining blocks of the calculated ciphertext sl@0: TPtr8 calcCipherPtr2((calculatedCiphertext + blockSize), (plaintext->Length() - blockSize)); sl@0: sl@0: // Ptr to the first block of the .ini file's plaintext sl@0: TPtrC8 knownPlainPtr1(plaintext->Ptr(), blockSize); sl@0: // Ptr to the remaining blocks of the .ini file's plaintext sl@0: TPtrC8 knownPlainPtr2((plaintext->Ptr() + blockSize), (plaintext->Length() - blockSize)); sl@0: sl@0: sl@0: HBufC8* iv = ReadInIvL(); sl@0: CleanupStack::PushL(iv); sl@0: sl@0: // Increment IV to the value for the second block so we can encrypt blocks 2+ first sl@0: HBufC8* incrementedIv1 = CtrModeIncrementCounterL((*iv)); sl@0: CleanupStack::PushL(incrementedIv1); sl@0: sl@0: impl->SetIvL(*incrementedIv1); sl@0: sl@0: sl@0: INFO_PRINTF1(_L("Setup complete. Encrypting blocks 2+.")); sl@0: impl->ProcessL(knownPlainPtr2, calcCipherPtr2); sl@0: sl@0: INFO_PRINTF1(_L("Blocks 2+ encrypted. Reseting and encrypting block 1.")); sl@0: impl->SetIvL((*iv)); sl@0: impl->ProcessL(knownPlainPtr1, calcCipherPtr1); sl@0: sl@0: sl@0: HBufC8* knownCiphertext = ReadInCiphertextL(); sl@0: CleanupStack::PushL(knownCiphertext); sl@0: sl@0: // Check that calculated ciphertext matches the expected value sl@0: TPtrC8 wholeCalcCiphertext(calculatedCiphertext, (plaintext->Length())); sl@0: if (wholeCalcCiphertext.Compare((*knownCiphertext)) != 0) sl@0: { sl@0: ERR_PRINTF1(_L("*** FAIL: Calculated ciphertext does not match expected value ***")); sl@0: CleanupStack::PopAndDestroy(7, key); sl@0: INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells()); sl@0: return TestStepResult(); sl@0: } sl@0: else sl@0: { sl@0: INFO_PRINTF1(_L("Calculated ciphertext matches the expected value.")); sl@0: } sl@0: sl@0: sl@0: // **** SWITCH TO DECRYPTION NOW **** sl@0: sl@0: // This will store our calculated version of the plaintext to compare with that in the .ini file sl@0: TUint8* calculatedPlaintext = new (ELeave) TUint8[plaintext->Length()]; sl@0: CleanupStack::PushL(calculatedPlaintext); sl@0: // Ptr to the first block of the calculated plaintext sl@0: TPtr8 calcPlainPtr1(calculatedPlaintext, (blockSize * 2)); sl@0: // Ptr to the remaining blocks of the calculated plaintext sl@0: TPtr8 calcPlainPtr2((calculatedPlaintext + (blockSize * 2)), (plaintext->Length() - (blockSize * 2))); sl@0: sl@0: // Ptr to the first 2 blocks of the ciphertext sl@0: TPtrC8 knownCipherPtr1(wholeCalcCiphertext.Ptr(), (blockSize * 2)); sl@0: // Ptr to the remaining blocks of the ciphertext sl@0: TPtrC8 knownCipherPtr2((wholeCalcCiphertext.Ptr() + (blockSize * 2)), (wholeCalcCiphertext.Length() - (blockSize * 2))); sl@0: sl@0: sl@0: // Increment IV to the value for the third block so we can decrypt blocks 3+ first sl@0: HBufC8* incrementedIv2 = CtrModeIncrementCounterL(*incrementedIv1); sl@0: CleanupStack::PushL(incrementedIv2); sl@0: impl->SetIvL(*incrementedIv2); sl@0: sl@0: INFO_PRINTF1(_L("Setup complete. Decrypting blocks 3+.")); sl@0: impl->ProcessL(knownCipherPtr2, calcPlainPtr2); sl@0: sl@0: INFO_PRINTF1(_L("Blocks 3+ encrypted. Reseting and encrypting blocks 1 and 2.")); sl@0: impl->SetIvL((*iv)); sl@0: impl->ProcessL(knownCipherPtr1, calcPlainPtr1); sl@0: sl@0: TPtrC8 wholeCalcPlaintext(calculatedPlaintext, (plaintext->Length())); sl@0: sl@0: if (wholeCalcPlaintext.Compare((*plaintext)) != 0) sl@0: { sl@0: ERR_PRINTF1(_L("*** FAIL: Calculated plaintext does not match expected value ***")); sl@0: } sl@0: else sl@0: { sl@0: INFO_PRINTF1(_L("*** PASS: Calculated plaintext matches the original one ***")); sl@0: SetTestStepResult(EPass); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(9, key); sl@0: sl@0: INFO_PRINTF2(_L("HEAP CELLS: %d"), User::CountAllocCells()); sl@0: sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: sl@0: TVerdict CSymmetricCipherCtrModeOutOfOrderStep::doTestStepPostambleL() sl@0: { sl@0: return TestStepResult(); sl@0: }