First public contribution.
2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
24 #include "cryptodriver.h"
32 #include <bufferedtransformation.h>
34 #include <e32def_private.h>
36 _LIT(KTxtEPOC32EX,"tcrypto: mainL failed");
37 _LIT(KTxtPressAnyKey," [press any key]");
46 //#define DISABLE_AES_CHECKS
48 //#define PADDING_PKCS7
51 #define BUFLEN (256*16)
52 #define LOOPCOUNT 10000
56 CConsoleBase* console; // write all your messages to this
61 GLDEF_C TInt E32Main() // main function called by E32
64 CTrapCleanup* cleanup=CTrapCleanup::New(); // get clean-up stack
65 TRAPD(error,mainL()); // more initialization, then do example
66 __ASSERT_ALWAYS(!error,User::Panic(KTxtEPOC32EX,error));
67 delete cleanup; // destroy clean-up stack
69 return 0; // and return
72 LOCAL_D RTest test(_L("tcrypto"));
74 _LIT(KLddFileName,"cryptoldd.ldd");
75 _LIT(KPddFileName,"crypto.h4.pdd");
77 LOCAL_C void mainL() // initialize and call example code under cleanup stack
80 test.Printf(KTxtPressAnyKey);
81 test.Getch(); // get and ignore character
82 test.Printf(_L("\n"));
87 RDebug::Printf("Hello from user side\n");
92 test.Start(_L(" @SYMTestCaseID:SEC-CRYPTOSPI-CRYPTO-0001 Loading Physical Device "));
93 r=User::LoadPhysicalDevice(KPddFileName);
94 test(r==KErrNone || r==KErrAlreadyExists);
96 test.Next(_L("Re-Loading Physical Device"));
97 r=User::LoadPhysicalDevice(KPddFileName);
98 test(r==KErrNone || r==KErrAlreadyExists);
100 test.Next(_L("Loading Logical Device"));
101 r=User::LoadLogicalDevice(KLddFileName);
102 test(r==KErrNone || r==KErrAlreadyExists);
104 test.Next(_L("Re-Loading Logical Device"));
105 r=User::LoadLogicalDevice(KLddFileName);
106 test(r==KErrNone || r==KErrAlreadyExists);
108 test.Next(_L("Open Device"));
110 r=device.Open(RCryptoDriver::Name());
113 test.Next(_L("Get Device Capabilities"));
114 RCryptoDriver::TCaps caps;
115 TPckg<RCryptoDriver::TCaps>capsPckg(caps);
116 capsPckg.FillZ(); // Zero 'caps' so we can tell if GetCaps has really filled it
117 device.GetCaps(capsPckg);
118 TVersion expectedVer(RCryptoDriver::VersionRequired());
119 test(caps.iVersion.iMajor==expectedVer.iMajor);
120 test(caps.iVersion.iMinor==expectedVer.iMinor);
121 test(caps.iVersion.iBuild==expectedVer.iBuild);
123 test.Next(_L("Close Device"));
126 test.Next(_L("Open Logical Channel"));
131 test.Next(_L("GetHwVersions"));
132 RCryptoDriver::THwVersionsBuf hwVersionsBuf;
133 hwVersionsBuf.FillZ(); // Zero 'config' so we can tell if GetConfig has really filled it
134 r=ldd.GetHwVersions(hwVersionsBuf);
136 test.Printf(_L("RNG h/w version 0x%x\n"), hwVersionsBuf().iRngHwVersion);
137 test.Printf(_L("DES/3DES h/w version 0x%x\n"), hwVersionsBuf().iDes3DesHwVersion);
138 test.Printf(_L("SHA1/MD5 h/w version 0x%x\n"), hwVersionsBuf().iSha1Md5HwVersion);
139 test.Printf(_L("AES h/w version 0x%x\n"), hwVersionsBuf().iAesHwVersion);
140 test.Printf(_L("PKA h/w version 0x%x\n"), hwVersionsBuf().iPkaHwVersion);
142 test.Next(_L("GetConfig"));
143 RCryptoDriver::TConfigBuf configBuf;
144 configBuf.FillZ(); // Zero 'config' so we can tell if GetConfig has really filled it
145 r=ldd.GetConfig(configBuf);
149 test.Next(_L("Open Logical Channel 2nd time"));
154 test.Next(_L("GetConfig"));
155 RCryptoDriver::TConfigBuf configBuf;
156 configBuf.FillZ(); // Zero 'config' so we can tell if GetConfig has really filled it
157 r=lddB.GetConfig(configBuf);
162 RCryptoDriver::TConfig& config=configBuf();
164 test.Next(_L("SetConfig"));
165 TInt setting = configBuf().iFakeDriverSetting+1;
166 configBuf().iFakeDriverSetting = setting;
167 r=ldd.SetConfig(configBuf); // Use SetConfig to change setting
171 r=ldd.GetConfig(configBuf);
173 test(configBuf().iFakeDriverSetting==setting);
175 test.Next(_L("Check access by wrong client"));
176 RCryptoDriver ldd2=ldd;
177 r=ldd2.Duplicate(RThread(),EOwnerProcess);
178 test(r==KErrAccessDenied);
180 test.Next(_L("Check handle duplication"));
182 r=ldd2.Duplicate(RThread(),EOwnerThread);
187 TRequestStatus status;
188 TRequestStatus status2;
194 test.Next(_L("Random h/w use 2nd chan"));
195 HBufC8 *hbuf = HBufC8::NewLC(20);
196 TPtr8 buf = hbuf->Des();
197 buf.SetLength(buf.MaxLength());
198 ldd.Random(status,buf);
199 User::WaitForRequest(status);
201 test.Printf(_L(" Try 2nd chan"));
205 buf.SetLength(buf.MaxLength());
206 lddB.Random(status,buf);
207 User::WaitForRequest(status);
209 test.Printf(_L(" Try re-using 1st chan\n"));
210 buf.SetLength(buf.MaxLength());
211 ldd.Random(status,buf);
212 User::WaitForRequest(status);
215 CleanupStack::PopAndDestroy(hbuf);
222 test.Next(_L("Random (h/w)"));
224 HBufC8 *hbuf = HBufC8::NewLC(32768);
226 HBufC8 *hbuf = HBufC8::NewLC(1024);
228 TPtr8 buf = hbuf->Des();
229 buf.SetLength(buf.MaxLength());
230 startCount = User::NTickCount();
231 for(TInt i=0; i<100; ++i)
233 // Should discard existing contents of buf
234 ldd.Random(status,buf);
237 User::WaitForRequest(status);
239 endCount = User::NTickCount();
240 test.Printf(_L("Duration in ticks (h/w) = %d\n"), endCount - startCount);
244 TUint32 *p = (TUint32 *) &buf[0];
245 test.Printf(_L("buf =\n "));
246 for(TInt i = 0 ; i<256; ++i)
250 test.Printf(_L("\n "));
252 test.Printf(_L("%08x "), p[i]);
254 test.Printf(_L("\n"));
260 test.Next(_L("Random (s/w)"));
263 TRAPD(ret,rs.ConnectL());
264 User::LeaveIfError(ret);
265 CleanupClosePushL(rs);
268 TInt startCount = User::NTickCount();
269 for(TInt i=0; i<100; ++i)
271 // Should discard existing contents of buf
273 User::LeaveIfError(rs.GetRandom(buf));
275 TRandom::RandomL(buf);
278 TInt endCount = User::NTickCount();
279 test.Printf(_L("Duration in ticks (s/w) = %d\n"), endCount - startCount);
282 CleanupStack::PopAndDestroy(&rs);
293 for(TInt i = 0 ; i<end; ++i)
295 test.Printf(_L("buf[%d] = 0x%x\n"), i, buf[i]);
300 CleanupStack::PopAndDestroy(hbuf);
304 test.Next(_L("Random - Generating key & IV for AES tests"));
305 test.Printf(_L("Generating random key\n"));
306 // Generate random 16 byte key
308 key.SetLength(key.MaxLength());
309 ldd.Random(status, key);
310 User::WaitForRequest(status);
315 for(int z=4; z<KEYLEN; ++z) key[z] = z;
317 test.Printf(_L("Generating random IV\n"));
318 // Generate random 16 byte IV
320 iv.SetLength(iv.MaxLength());
321 ldd.Random(status, iv);
322 User::WaitForRequest(status);
328 TBuf8<BUFLEN> plaintext;
329 plaintext.SetLength(BUFLEN);
335 plaintext.SetLength(BUFLEN);
336 for(int i=0; i<BUFLEN; ++i)
343 test.Next(_L("AES - S/W"));
346 CPadding *pad = CPaddingPKCS7::NewLC(16);
348 CPadding *pad = CPaddingNone::NewLC(16);
353 test.Printf(_L(" CBC\n"));
354 CAESEncryptor *rawaes = CAESEncryptor::NewLC(key); // pad, rawaes
355 CModeCBCEncryptor *cbc = CModeCBCEncryptor::NewL(rawaes, iv);
356 CleanupStack::Pop(rawaes); // pad
357 CleanupStack::PushL(cbc); // pad, cbc
359 CBufferedEncryptor *aes = CBufferedEncryptor::NewL(cbc, pad);
360 CleanupStack::Pop(cbc); // pad
361 CleanupStack::Pop(pad); //
362 CleanupStack::PushL(aes); //aes
365 test.Printf(_L(" ECB\n"));
366 CAESEncryptor *rawaes = CAESEncryptor::NewLC(key); // pad, rawaes
367 CBufferedEncryptor *aes = CBufferedEncryptor::NewL(rawaes, pad);
368 CleanupStack::Pop(rawaes); // pad
369 CleanupStack::Pop(pad); //
370 CleanupStack::PushL(aes); // aes
375 b1 = _L8("0123456789");
380 test.Printf(_L("Test of Process/ProcessFinal\n"));
383 aes->ProcessFinalL(b2, b3);
387 test.Printf(_L("About to s/w encrypt\n"));
390 aes->ProcessFinalL(plaintext, sw);
392 test.Printf(_L("sw =\n "));
393 for(TInt i = 0 ; i<256; ++i)
397 test.Printf(_L("\n "));
399 test.Printf(_L("%02x "), sw[i]);
401 test.Printf(_L("\n"));
404 test.Printf(_L("S/W - Encrypt %d bytes %d times\n"), BUFLEN, LOOPCOUNT);
405 startCount = User::NTickCount();
406 for(int z=0; z < LOOPCOUNT; ++z)
410 //aes->ProcessFinalL(plaintext, sw);
411 aes->Process(plaintext, sw);
413 endCount = User::NTickCount();
414 test.Printf(_L("Duration in ticks (s/w) = %d\n"), endCount - startCount);
417 CleanupStack::PopAndDestroy(aes);
419 test.Next(_L("AES - H/W"));
422 test.Printf(_L("Setting config\n"));
424 r = ldd.SetAesConfig(ETrue, RCryptoDriver::ECbcMode, key, iv);
425 test.Printf(_L(" CBC\n"));
427 r = ldd.SetAesConfig(ETrue, RCryptoDriver::EEcbMode, key, iv);
428 test.Printf(_L(" ECB\n"));
433 test.Printf(_L("H/W - Encrypt %d bytes %d times\n"), BUFLEN, LOOPCOUNT);
435 startCount = User::NTickCount();
436 for(int z=0; z < LOOPCOUNT; ++z)
439 ldd.AesRead(status2, tmp2, tmp2.MaxLength());
440 ldd.AesWrite(status, plaintext);
441 User::WaitForRequest(status);
442 User::WaitForRequest(status2);
443 #ifdef DISABLE_AES_CHECKS
444 tmp2.SetLength(BUFLEN);
447 endCount = User::NTickCount();
448 test.Printf(_L("Duration in ticks (h/w) = %d\n"), endCount - startCount);
451 #ifndef DISABLE_AES_CHECKS
453 test.Printf(_L("Compare tmp2 and sw\n"));
456 test.Printf(_L("Compare tmp2 and plaintext\n"));
457 test(tmp2==plaintext);
465 // User::Panic(_L("Fake app crash"), 42);
467 test.Next(_L("Close Logical Channel"));
472 test.Next(_L("Unload Logical Device"));
473 r=User::FreeLogicalDevice(RCryptoDriver::Name());
476 test.Next(_L("Unload Physical Device"));
477 TName pddName(RCryptoDriver::Name());
478 _LIT(KVariantExtension,".h4");
479 pddName.Append(KVariantExtension);
480 r=User::FreePhysicalDevice(pddName);
485 test.Printf(KTxtPressAnyKey);
486 test.Getch(); // get and ignore character