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: @internalComponent sl@0: @released sl@0: */ sl@0: #include "cryptodriver.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: _LIT(KTxtEPOC32EX,"tcrypto: mainL failed"); sl@0: _LIT(KTxtPressAnyKey," [press any key]"); sl@0: sl@0: #define RNG_TESTS sl@0: //#define RNG_USE_SVR sl@0: //#define KEYLEN 16 sl@0: #define KEYLEN 24 sl@0: //#define KEYLEN 32 sl@0: sl@0: #define USE_CBCMODE sl@0: //#define DISABLE_AES_CHECKS sl@0: sl@0: //#define PADDING_PKCS7 sl@0: sl@0: //#define BUFLEN 256 sl@0: #define BUFLEN (256*16) sl@0: #define LOOPCOUNT 10000 sl@0: sl@0: sl@0: // public sl@0: CConsoleBase* console; // write all your messages to this sl@0: sl@0: // private sl@0: LOCAL_C void mainL(); sl@0: sl@0: GLDEF_C TInt E32Main() // main function called by E32 sl@0: { sl@0: __UHEAP_MARK; sl@0: CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack sl@0: TRAPD(error,mainL()); // more initialization, then do example sl@0: __ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error)); sl@0: delete cleanup; // destroy clean-up stack sl@0: __UHEAP_MARKEND; sl@0: return 0; // and return sl@0: } sl@0: sl@0: LOCAL_D RTest test(_L("tcrypto")); sl@0: sl@0: _LIT(KLddFileName,"cryptoldd.ldd"); sl@0: _LIT(KPddFileName,"crypto.h4.pdd"); sl@0: sl@0: LOCAL_C void mainL() // initialize and call example code under cleanup stack sl@0: { sl@0: #if 0 sl@0: test.Printf(KTxtPressAnyKey); sl@0: test.Getch(); // get and ignore character sl@0: test.Printf(_L("\n")); sl@0: #endif sl@0: sl@0: test.Title(); sl@0: sl@0: RDebug::Printf("Hello from user side\n"); sl@0: sl@0: sl@0: TInt r; sl@0: sl@0: test.Start(_L(" @SYMTestCaseID:SEC-CRYPTOSPI-CRYPTO-0001 Loading Physical Device ")); sl@0: r=User::LoadPhysicalDevice(KPddFileName); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: sl@0: test.Next(_L("Re-Loading Physical Device")); sl@0: r=User::LoadPhysicalDevice(KPddFileName); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: sl@0: test.Next(_L("Loading Logical Device")); sl@0: r=User::LoadLogicalDevice(KLddFileName); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: sl@0: test.Next(_L("Re-Loading Logical Device")); sl@0: r=User::LoadLogicalDevice(KLddFileName); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: sl@0: test.Next(_L("Open Device")); sl@0: RDevice device; sl@0: r=device.Open(RCryptoDriver::Name()); sl@0: test(r==KErrNone); sl@0: sl@0: test.Next(_L("Get Device Capabilities")); sl@0: RCryptoDriver::TCaps caps; sl@0: TPckgcapsPckg(caps); sl@0: capsPckg.FillZ(); // Zero 'caps' so we can tell if GetCaps has really filled it sl@0: device.GetCaps(capsPckg); sl@0: TVersion expectedVer(RCryptoDriver::VersionRequired()); sl@0: test(caps.iVersion.iMajor==expectedVer.iMajor); sl@0: test(caps.iVersion.iMinor==expectedVer.iMinor); sl@0: test(caps.iVersion.iBuild==expectedVer.iBuild); sl@0: sl@0: test.Next(_L("Close Device")); sl@0: device.Close(); sl@0: sl@0: test.Next(_L("Open Logical Channel")); sl@0: RCryptoDriver ldd; sl@0: r=ldd.Open(); sl@0: test(r==KErrNone); sl@0: sl@0: test.Next(_L("GetHwVersions")); sl@0: RCryptoDriver::THwVersionsBuf hwVersionsBuf; sl@0: hwVersionsBuf.FillZ(); // Zero 'config' so we can tell if GetConfig has really filled it sl@0: r=ldd.GetHwVersions(hwVersionsBuf); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("RNG h/w version 0x%x\n"), hwVersionsBuf().iRngHwVersion); sl@0: test.Printf(_L("DES/3DES h/w version 0x%x\n"), hwVersionsBuf().iDes3DesHwVersion); sl@0: test.Printf(_L("SHA1/MD5 h/w version 0x%x\n"), hwVersionsBuf().iSha1Md5HwVersion); sl@0: test.Printf(_L("AES h/w version 0x%x\n"), hwVersionsBuf().iAesHwVersion); sl@0: test.Printf(_L("PKA h/w version 0x%x\n"), hwVersionsBuf().iPkaHwVersion); sl@0: sl@0: test.Next(_L("GetConfig")); sl@0: RCryptoDriver::TConfigBuf configBuf; sl@0: configBuf.FillZ(); // Zero 'config' so we can tell if GetConfig has really filled it sl@0: r=ldd.GetConfig(configBuf); sl@0: test(r==KErrNone); sl@0: sl@0: { sl@0: test.Next(_L("Open Logical Channel 2nd time")); sl@0: RCryptoDriver lddB; sl@0: r=lddB.Open(); sl@0: test(r==KErrNone); sl@0: sl@0: test.Next(_L("GetConfig")); sl@0: RCryptoDriver::TConfigBuf configBuf; sl@0: configBuf.FillZ(); // Zero 'config' so we can tell if GetConfig has really filled it sl@0: r=lddB.GetConfig(configBuf); sl@0: test(r==KErrNone); sl@0: lddB.Close(); sl@0: } sl@0: sl@0: RCryptoDriver::TConfig& config=configBuf(); sl@0: sl@0: test.Next(_L("SetConfig")); sl@0: TInt setting = configBuf().iFakeDriverSetting+1; sl@0: configBuf().iFakeDriverSetting = setting; sl@0: r=ldd.SetConfig(configBuf); // Use SetConfig to change setting sl@0: test(r==KErrNone); sl@0: sl@0: configBuf.FillZ(); sl@0: r=ldd.GetConfig(configBuf); sl@0: test(r==KErrNone); sl@0: test(configBuf().iFakeDriverSetting==setting); sl@0: sl@0: test.Next(_L("Check access by wrong client")); sl@0: RCryptoDriver ldd2=ldd; sl@0: r=ldd2.Duplicate(RThread(),EOwnerProcess); sl@0: test(r==KErrAccessDenied); sl@0: sl@0: test.Next(_L("Check handle duplication")); sl@0: ldd2=ldd; sl@0: r=ldd2.Duplicate(RThread(),EOwnerThread); sl@0: test(r==KErrNone); sl@0: ldd2.Close(); sl@0: sl@0: sl@0: TRequestStatus status; sl@0: TRequestStatus status2; sl@0: TInt startCount; sl@0: TInt endCount; sl@0: sl@0: sl@0: { sl@0: test.Next(_L("Random h/w use 2nd chan")); sl@0: HBufC8 *hbuf = HBufC8::NewLC(20); sl@0: TPtr8 buf = hbuf->Des(); sl@0: buf.SetLength(buf.MaxLength()); sl@0: ldd.Random(status,buf); sl@0: User::WaitForRequest(status); sl@0: sl@0: test.Printf(_L(" Try 2nd chan")); sl@0: RCryptoDriver lddB; sl@0: r=lddB.Open(); sl@0: test(r==KErrNone); sl@0: buf.SetLength(buf.MaxLength()); sl@0: lddB.Random(status,buf); sl@0: User::WaitForRequest(status); sl@0: sl@0: test.Printf(_L(" Try re-using 1st chan\n")); sl@0: buf.SetLength(buf.MaxLength()); sl@0: ldd.Random(status,buf); sl@0: User::WaitForRequest(status); sl@0: sl@0: lddB.Close(); sl@0: CleanupStack::PopAndDestroy(hbuf); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: #ifdef RNG_TESTS sl@0: test.Next(_L("Random (h/w)")); sl@0: #ifdef __MARM__ sl@0: HBufC8 *hbuf = HBufC8::NewLC(32768); sl@0: #else sl@0: HBufC8 *hbuf = HBufC8::NewLC(1024); sl@0: #endif sl@0: TPtr8 buf = hbuf->Des(); sl@0: buf.SetLength(buf.MaxLength()); sl@0: startCount = User::NTickCount(); sl@0: for(TInt i=0; i<100; ++i) sl@0: { sl@0: // Should discard existing contents of buf sl@0: ldd.Random(status,buf); sl@0: // User::After(20); sl@0: // return; sl@0: User::WaitForRequest(status); sl@0: } sl@0: endCount = User::NTickCount(); sl@0: test.Printf(_L("Duration in ticks (h/w) = %d\n"), endCount - startCount); sl@0: sl@0: #ifndef __MARM__ sl@0: { sl@0: TUint32 *p = (TUint32 *) &buf[0]; sl@0: test.Printf(_L("buf =\n ")); sl@0: for(TInt i = 0 ; i<256; ++i) sl@0: { sl@0: if(i && (i%16 == 0)) sl@0: { sl@0: test.Printf(_L("\n ")); sl@0: } sl@0: test.Printf(_L("%08x "), p[i]); sl@0: } sl@0: test.Printf(_L("\n")); sl@0: } sl@0: sl@0: #endif sl@0: sl@0: { sl@0: test.Next(_L("Random (s/w)")); sl@0: #ifdef RNG_USE_SVR sl@0: RRandomSession rs; sl@0: TRAPD(ret,rs.ConnectL()); sl@0: User::LeaveIfError(ret); sl@0: CleanupClosePushL(rs); sl@0: #endif sl@0: sl@0: TInt startCount = User::NTickCount(); sl@0: for(TInt i=0; i<100; ++i) sl@0: { sl@0: // Should discard existing contents of buf sl@0: #ifdef RNG_USE_SVR sl@0: User::LeaveIfError(rs.GetRandom(buf)); sl@0: #else sl@0: TRandom::RandomL(buf); sl@0: #endif sl@0: } sl@0: TInt endCount = User::NTickCount(); sl@0: test.Printf(_L("Duration in ticks (s/w) = %d\n"), endCount - startCount); sl@0: sl@0: #ifdef RNG_USE_SVR sl@0: CleanupStack::PopAndDestroy(&rs); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: #ifdef __MARM__ sl@0: const TInt end = 10; sl@0: #else sl@0: const TInt end = 1; sl@0: #endif sl@0: sl@0: for(TInt i = 0 ; i key; sl@0: key.SetLength(key.MaxLength()); sl@0: ldd.Random(status, key); sl@0: User::WaitForRequest(status); sl@0: key[0] = 'K'; sl@0: key[1] = 'E'; sl@0: key[2] = 'Y'; sl@0: key[3] = '*'; sl@0: for(int z=4; z iv; sl@0: iv.SetLength(iv.MaxLength()); sl@0: ldd.Random(status, iv); sl@0: User::WaitForRequest(status); sl@0: iv[0] = 'I'; sl@0: iv[1] = 'V'; sl@0: iv[2] = '*'; sl@0: iv[3] = '*'; sl@0: sl@0: TBuf8 plaintext; sl@0: plaintext.SetLength(BUFLEN); sl@0: plaintext[0] = 'P'; sl@0: plaintext[1] = 'L'; sl@0: plaintext[2] = 'A'; sl@0: plaintext[3] = 'I'; sl@0: plaintext[4] = 'N'; sl@0: plaintext.SetLength(BUFLEN); sl@0: for(int i=0; i b1; sl@0: b1 = _L8("0123456789"); sl@0: TBuf8<6> b2; sl@0: b2 = _L8("012345"); sl@0: TBuf8<64> b3; sl@0: sl@0: test.Printf(_L("Test of Process/ProcessFinal\n")); sl@0: aes->Reset(); sl@0: aes->Process(b1,b3); sl@0: aes->ProcessFinalL(b2, b3); sl@0: aes->Reset(); sl@0: } sl@0: sl@0: test.Printf(_L("About to s/w encrypt\n")); sl@0: TBuf8 sw; sl@0: sw.SetLength(0); sl@0: aes->ProcessFinalL(plaintext, sw); sl@0: sl@0: test.Printf(_L("sw =\n ")); sl@0: for(TInt i = 0 ; i<256; ++i) sl@0: { sl@0: if(i && (i%16 == 0)) sl@0: { sl@0: test.Printf(_L("\n ")); sl@0: } sl@0: test.Printf(_L("%02x "), sw[i]); sl@0: } sl@0: test.Printf(_L("\n")); sl@0: sl@0: aes->Reset(); sl@0: test.Printf(_L("S/W - Encrypt %d bytes %d times\n"), BUFLEN, LOOPCOUNT); sl@0: startCount = User::NTickCount(); sl@0: for(int z=0; z < LOOPCOUNT; ++z) sl@0: { sl@0: //aes->Reset(); sl@0: sw.SetLength(0); sl@0: //aes->ProcessFinalL(plaintext, sw); sl@0: aes->Process(plaintext, sw); sl@0: } sl@0: endCount = User::NTickCount(); sl@0: test.Printf(_L("Duration in ticks (s/w) = %d\n"), endCount - startCount); sl@0: sl@0: sl@0: CleanupStack::PopAndDestroy(aes); sl@0: sl@0: test.Next(_L("AES - H/W")); sl@0: sl@0: sl@0: test.Printf(_L("Setting config\n")); sl@0: #ifdef USE_CBCMODE sl@0: r = ldd.SetAesConfig(ETrue, RCryptoDriver::ECbcMode, key, iv); sl@0: test.Printf(_L(" CBC\n")); sl@0: #else sl@0: r = ldd.SetAesConfig(ETrue, RCryptoDriver::EEcbMode, key, iv); sl@0: test.Printf(_L(" ECB\n")); sl@0: #endif sl@0: test(r==KErrNone); sl@0: sl@0: sl@0: test.Printf(_L("H/W - Encrypt %d bytes %d times\n"), BUFLEN, LOOPCOUNT); sl@0: TBuf8 tmp2; sl@0: startCount = User::NTickCount(); sl@0: for(int z=0; z < LOOPCOUNT; ++z) sl@0: { sl@0: tmp2.SetLength(0); sl@0: ldd.AesRead(status2, tmp2, tmp2.MaxLength()); sl@0: ldd.AesWrite(status, plaintext); sl@0: User::WaitForRequest(status); sl@0: User::WaitForRequest(status2); sl@0: #ifdef DISABLE_AES_CHECKS sl@0: tmp2.SetLength(BUFLEN); sl@0: #endif sl@0: } sl@0: endCount = User::NTickCount(); sl@0: test.Printf(_L("Duration in ticks (h/w) = %d\n"), endCount - startCount); sl@0: sl@0: sl@0: #ifndef DISABLE_AES_CHECKS sl@0: #ifdef __MARM__ sl@0: test.Printf(_L("Compare tmp2 and sw\n")); sl@0: test(tmp2==sw); sl@0: #else sl@0: test.Printf(_L("Compare tmp2 and plaintext\n")); sl@0: test(tmp2==plaintext); sl@0: #endif sl@0: #endif sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: // User::Panic(_L("Fake app crash"), 42); sl@0: sl@0: test.Next(_L("Close Logical Channel")); sl@0: ldd.Close(); sl@0: sl@0: __KHEAP_MARKEND; sl@0: sl@0: test.Next(_L("Unload Logical Device")); sl@0: r=User::FreeLogicalDevice(RCryptoDriver::Name()); sl@0: test(r==KErrNone); sl@0: sl@0: test.Next(_L("Unload Physical Device")); sl@0: TName pddName(RCryptoDriver::Name()); sl@0: _LIT(KVariantExtension,".h4"); sl@0: pddName.Append(KVariantExtension); sl@0: r=User::FreePhysicalDevice(pddName); sl@0: test(r==KErrNone); sl@0: sl@0: test.End(); sl@0: sl@0: test.Printf(KTxtPressAnyKey); sl@0: test.Getch(); // get and ignore character sl@0: test.Close(); sl@0: } sl@0: sl@0: sl@0: // End of file