--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/weakcryptospi/test/thash/thash.cpp Thu Sep 10 14:01:51 2009 +0300
@@ -0,0 +1,1150 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+/**
+ @file
+*/
+
+#include "hashtestutils.h"
+#include <utf.h>
+
+TBool gInOOMTest=EFalse;
+
+RTest test(_L("Hash Tests"));
+
+const TInt KMaxHashSize = 64; // Hash size in bytes
+
+void Hex(HBufC8& aString)
+ {
+ TPtr8 ptr=aString.Des();
+ if (aString.Length()%2)
+ {
+ ptr.SetLength(0);
+ return;
+ }
+ TInt i;
+ for (i=0;i<aString.Length();i+=2)
+ {
+ TUint8 tmp;
+ tmp=(TUint8)(aString[i]-(aString[i]>'9'?('A'-10):'0'));
+ tmp*=16;
+ tmp|=(TUint8)(aString[i+1]-(aString[i+1]>'9'?('A'-10):'0'));
+ ptr[i/2]=tmp;
+ }
+ ptr.SetLength(aString.Length()/2);
+ }
+
+void Spin()
+{// Pointless function to print a dot
+ if (gInOOMTest)
+ {
+ static TInt count=0;
+ if (count++==100)
+ {
+ test.Printf(_L("o"));
+ count=0;
+ }
+ return;
+ }
+ test.Printf(_L("."));
+}
+
+void FunctionalityTestL(CMessageDigest* aMD)
+ {
+ if (!gInOOMTest)
+ test.Next(_L("Functionality test - original API"));
+
+ const TInt maxbuffersize=1024;
+ TInt buffersize;
+ TInt increment;
+ if (gInOOMTest)
+ {
+ buffersize=256;
+ increment=6;
+ }
+ else
+ {
+ buffersize=maxbuffersize;
+ increment=1;
+ }
+
+ TBool testSuccess = ETrue;
+ TInt i = 0;
+ TBuf8<maxbuffersize> buf(maxbuffersize);
+ for (;i<buffersize;i++)
+ {
+ buf[i]=(TUint8)i;
+ }
+
+ for (i=0;i<buffersize;i+=increment)
+ {
+ TInt j;
+ Spin();
+ if (!gInOOMTest)
+ {
+ if (i>128)
+ {
+ increment=8;
+ }
+ }
+ else
+ {
+ if (i>24)
+ {
+ increment=32;
+ }
+ }
+
+ for (j=0;j<i;j+=16)
+ {
+ buf[0]=(TUint8)j;
+ TPtrC8 ptr=buf.Left(i);
+ TPtrC8 ptr2=buf.Left(j);
+ TPtrC8 ptr3=buf.Mid(j,i-j);
+
+ CMessageDigest* first=aMD->ReplicateL();
+ CleanupStack::PushL(first);
+ TPtrC8 firstFinal = first->Hash(ptr);
+
+ aMD->Reset();
+ aMD->Update(ptr);
+ TPtrC8 aMDFinal = aMD->Final();
+
+ CMessageDigest* second=aMD->ReplicateL();
+ CleanupStack::PushL(second);
+ second->Hash(ptr2);
+
+ CMessageDigest* third=second->CopyL();
+ CleanupStack::PushL(third);
+
+ TPtrC8 secondFinal = second->Hash(ptr3);
+
+ if (aMDFinal!=firstFinal)
+ {
+ testSuccess = EFalse;
+ }
+
+ if (firstFinal!=secondFinal)
+ {
+ testSuccess = EFalse;
+ }
+
+ TPtrC8 thirdFinal = third->Hash(ptr3);
+ if (firstFinal!=thirdFinal)
+ {
+ testSuccess = EFalse;
+ }
+ CleanupStack::PopAndDestroy(3); // first, second, third
+ }
+ }
+
+///////////////////////////////////////////////////////////////
+// Now test the new API - Update/Final functions
+///////////////////////////////////////////////////////////////
+ if (!gInOOMTest)
+ test.Next(_L("\rFunctionality test - calls added API functions Final & Update"));
+
+ for (i=0;i<buffersize;i++)
+ {
+ buf[i]=(TUint8)i;
+ }
+
+ for (i=0;i<buffersize;i+=increment)
+ {
+ TInt j;
+ Spin();
+ if (!gInOOMTest)
+ {
+ if (i>128)
+ {
+ increment=8;
+ }
+ }
+ else
+ {
+ if (i>24)
+ {
+ increment=32;
+ }
+ }
+ for (j=0;j<i;j+=16)
+ {
+ buf[0]=(TUint8)j;
+ TPtrC8 ptr=buf.Left(i);
+ TPtrC8 ptr2=buf.Left(j);
+ TPtrC8 ptr3=buf.Mid(j,i-j);
+
+ CMessageDigest* first=aMD->ReplicateL();
+ CleanupStack::PushL(first);
+ first->Update(ptr);
+
+ aMD->Update(ptr);
+
+ CMessageDigest* second=aMD->ReplicateL();
+ CleanupStack::PushL(second);
+ second->Update(ptr2);
+
+ CMessageDigest* third=second->CopyL();
+ CleanupStack::PushL(third);
+ third->Update(ptr3);
+
+ second->Update(ptr3);
+
+ TPtrC8 aMDFinal = aMD->Final();
+ TPtrC8 firstFinal = first->Final();
+ TPtrC8 secondFinal = second->Final();
+ TPtrC8 thirdFinal = third->Final();
+
+ if (aMDFinal!=firstFinal)
+ {
+ testSuccess = EFalse;
+ }
+
+ if (firstFinal!=secondFinal)
+ {
+ testSuccess = EFalse;
+ }
+
+ if (firstFinal!=thirdFinal)
+ {
+ testSuccess = EFalse;
+ }
+
+ CleanupStack::PopAndDestroy(3); // first, second, third
+ }
+ }
+
+
+ test.Printf(_L("\r\n"));
+
+ if (!testSuccess)
+ User::Leave(KErrGeneral);
+ }
+
+void VectorTestL(CMessageDigest* aMD,const TDesC& aFilename)
+ {
+ test.Next(_L("Test Vector tests - original API"));
+ TBool finished=EFalse;
+ TBool testSuccess = ETrue;
+ //aFilename is a .dat file which contains the message and the corresponding digest
+ CTestData* data = CTestData::NewL(aFilename);
+ CleanupStack::PushL(data);
+
+ while (!finished)
+ {
+ switch (data->Type())
+ {
+ case CTestData::EMessage:
+ {
+ break;
+ }
+ //This is added to read large input data from the files.
+ case CTestData::EFileName:
+ {
+ CMessageDigest* md=aMD->ReplicateL();
+ CleanupStack::PushL(md);
+
+ //get the filename from the .dat file
+ HBufC8* filename = (*data)[1];
+ User::LeaveIfNull(filename);
+ CleanupStack::PushL(filename);
+
+ HBufC8* output= (*data)[2];
+ User::LeaveIfNull(output);
+ CleanupStack::PushL(output);
+ Hex(*output);
+
+ HBufC16* inputFileName = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*filename);
+
+ RFs fs;
+ RFile file;
+ CleanupClosePushL(fs);
+ User::LeaveIfError(fs.Connect());
+ TDriveUnit sysDrive(fs.GetSystemDrive());
+ TBuf<24> filePath (sysDrive.Name());
+ filePath.Append(_L("\\thash\\"));
+ User::LeaveIfError(fs.SetSessionPath(filePath));
+ CleanupClosePushL(file);
+ User::LeaveIfError(file.Open(fs,*inputFileName,EFileShareAny|EFileRead));
+ // read into iFile
+ TInt size=0;
+ file.Size(size);
+
+ HBufC8* fileContents=HBufC8::NewMaxL(size);
+
+ TPtr8 ptr=fileContents->Des();
+ User::LeaveIfError(file.Read(ptr));
+ CleanupStack::PopAndDestroy(2, &fs);
+ CleanupStack::PushL(fileContents);
+ delete inputFileName;
+
+ TPtrC8 digest = md->Hash(*fileContents);
+ if (digest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+
+ md->Reset();
+
+ TPtrC8 digest2 = md->Hash(*fileContents);
+ if (digest2!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+
+ // Now try this in 2 half sections (just a quick check)
+ md->Reset();
+
+ TInt inputLen = fileContents->Length();
+ if (inputLen > 1)
+ {
+ TInt leftHandLen = inputLen/2;
+ TPtrC8 left = fileContents->Left(leftHandLen);
+ TPtrC8 right = fileContents->Right(inputLen - leftHandLen);
+
+ TPtrC8 halfDigest = md->Hash(left);
+ if (halfDigest.Size()==0) // Unnecessary test, but removes
+ User::Leave(KErrAbort); // a warning about not using halfDigest
+
+ TPtrC8 wholeDigest = md->Hash(right);
+
+ if (wholeDigest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+ }
+
+ md->Reset();
+ if (md->Final(*fileContents)!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+
+ // Now try this in 2 half sections (just a quick check)
+ md->Reset();
+ inputLen = fileContents->Length();
+ if (inputLen > 1)
+ {
+ TInt leftHandLen = inputLen/2;
+ TPtrC8 left = fileContents->Left(leftHandLen);
+ TPtrC8 right = fileContents->Right(inputLen - leftHandLen);
+
+ md->Update(left);
+ TPtrC8 wholeDigest = md->Final(right);
+
+ if (wholeDigest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+ }
+ CleanupStack::PopAndDestroy(4, md);//md,filename,output,fileContents
+
+ break;
+ }
+ case CTestData::EData:
+ {
+ CMessageDigest* md=aMD->ReplicateL();
+ CleanupStack::PushL(md);
+
+ HBufC8* input = (*data)[0];
+ User::LeaveIfNull(input);
+ CleanupStack::PushL(input);
+
+ HBufC8* output= (*data)[1];
+ User::LeaveIfNull(output);
+ CleanupStack::PushL(output);
+ Hex(*input);
+ Hex(*output);
+
+ //call the Hash function of the Algorithm.
+ TPtrC8 digest = md->Hash(*input);
+ //Compare the digest generated with the output(digest) expected.
+ if (digest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+
+ //check the Reset() function.
+ md->Reset();
+
+ TPtrC8 digest2 = md->Hash(*input);
+ if (digest2!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+
+ // Now try this in 2 half sections (just a quick check)
+ md->Reset();
+
+ TInt inputLen = input->Length();
+ if (inputLen > 1)
+ {
+ TInt leftHandLen = inputLen/2;
+ TPtrC8 left = input->Left(leftHandLen);
+ TPtrC8 right = input->Right(inputLen - leftHandLen);
+
+ TPtrC8 halfDigest = md->Hash(left);
+ if (halfDigest.Size()==0) // Unnecessary test, but removes
+ User::Leave(KErrAbort); // a warning about not using halfDigest
+
+ TPtrC8 wholeDigest = md->Hash(right);
+
+ if (wholeDigest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+ }
+
+///////////////////////////////////////////////////////////////
+// Now test the new API - Update/Final functions
+///////////////////////////////////////////////////////////////
+ md->Reset();
+ if (md->Final(*input)!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+
+ // Now try this in 2 half sections (just a quick check)
+ md->Reset();
+ inputLen = input->Length();
+ if (inputLen > 1)
+ {
+ TInt leftHandLen = inputLen/2;
+ TPtrC8 left = input->Left(leftHandLen);
+ TPtrC8 right = input->Right(inputLen - leftHandLen);
+
+ md->Update(left);
+ TPtrC8 wholeDigest = md->Final(right);
+
+ if (wholeDigest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+ }
+ CleanupStack::PopAndDestroy(3);
+ break;
+ }
+ case CTestData::EFinished:
+ finished=ETrue;
+ break;
+ default:
+ test.Printf(_L("Error in data file\r\n"));
+ break;
+ }
+ };
+
+ CleanupStack::PopAndDestroy(data);
+
+ if (!testSuccess)
+ User::Leave(KErrGeneral);
+ }
+
+void OOMTestL(CMessageDigest* aMD)
+ {
+ test.Next(_L("Out of memory test"));
+ TInt err = KErrNoMemory;
+ TInt nextFailure=0;
+ gInOOMTest=ETrue;
+ while (err!=KErrNone)
+ {
+ __UHEAP_MARK;
+ __UHEAP_FAILNEXT(nextFailure);
+ TRAP(err,FunctionalityTestL(aMD));
+ __UHEAP_MARKEND;
+ nextFailure++;
+ }
+ __UHEAP_RESET;
+ gInOOMTest=EFalse;
+ }
+
+void HMACVectorTestL(CMessageDigest* aMD,const TDesC& aFilename)
+ {
+ test.Next(_L("HMAC Test Vector tests"));
+ CTestData* data = CTestData::NewL(aFilename);
+ CleanupStack::PushL(data);
+
+ TBool finished=EFalse;
+ TBool testSuccess = ETrue;
+
+ while (!finished)
+ {
+ switch (data->Type())
+ {
+ case CTestData::EMessage:
+ {
+ break;
+ }
+ case CTestData::EFileName:
+ {
+ //get the filename from the .dat file
+ HBufC8* filename = (*data)[1];
+ User::LeaveIfNull(filename);
+ CleanupStack::PushL(filename);
+
+ HBufC8* key= (*data)[2];
+ User::LeaveIfNull(key);
+ CleanupStack::PushL(key);
+
+ HBufC16* inputFileName = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*filename);
+
+ HBufC8* output = (*data)[3];
+ User::LeaveIfNull(output);
+ CleanupStack::PushL(output);
+
+ Hex(*key);
+ Hex(*output);
+
+ RFs fs;
+ RFile file;
+ CleanupClosePushL(fs);
+ User::LeaveIfError(fs.Connect());
+ TDriveUnit sysDrive(fs.GetSystemDrive());
+ TBuf<24> filePath (sysDrive.Name());
+ filePath.Append(_L("\\thash\\"));
+ User::LeaveIfError(fs.SetSessionPath(filePath));
+ CleanupClosePushL(file);
+ User::LeaveIfError(file.Open(fs,*inputFileName,EFileShareAny|EFileRead));
+ // read into iFile
+ TInt size=0;
+ file.Size(size);
+ HBufC8* fileContents=HBufC8::NewMaxL(size);
+
+ TPtr8 ptr=fileContents->Des();
+ User::LeaveIfError(file.Read(ptr));
+ CleanupStack::PopAndDestroy(2, &fs);
+ CleanupStack::PushL(fileContents);
+ delete inputFileName;
+
+ CMessageDigest* temp = aMD->ReplicateL();
+ CleanupStack::PushL(temp);
+ CMessageDigest* md = CHMAC::NewL(*key, temp);
+ CleanupStack::Pop(temp); // Now owned by md
+
+ TPtrC8 digest = md->Hash(*fileContents);
+ if (digest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+
+ // Now try this in 2 half sections (just a quick check)
+ md->Reset();
+
+ TInt inputLen = fileContents->Length();
+ if (inputLen > 1)
+ {
+ TInt leftHandLen = inputLen/2;
+ TPtrC8 left = fileContents->Left(leftHandLen);
+ TPtrC8 right = fileContents->Right(inputLen - leftHandLen);
+
+ TPtrC8 halfDigest = md->Hash(left);
+ if (halfDigest.Size()==0) // Unnecessary test, but removes
+ User::Leave(KErrAbort); // a warning about not using halfDigest
+ TPtrC8 wholeDigest = md->Hash(right);
+
+ if (wholeDigest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+ }
+
+ md->Reset();
+ TPtrC8 finalDigest = md->Final(*fileContents);
+ if (finalDigest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+
+ // Now try this in 2 half sections (just a quick check)
+ md->Reset();
+
+ inputLen = fileContents->Length();
+ if (inputLen > 1)
+ {
+ TInt leftHandLen = inputLen/2;
+ TPtrC8 left = fileContents->Left(leftHandLen);
+ TPtrC8 right = fileContents->Right(inputLen - leftHandLen);
+
+ md->Update(left);
+ TPtrC8 wholeDigest = md->Final(right);
+
+ if (wholeDigest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+ }
+ delete md;
+ CleanupStack::PopAndDestroy(4, filename); // filename, key, output,fileContents
+ break;
+ }
+ case CTestData::EData:
+ {
+ HBufC8* input = (*data)[0];
+ User::LeaveIfNull(input);
+ CleanupStack::PushL(input);
+
+ HBufC8* key = (*data)[1];
+ User::LeaveIfNull(key);
+ CleanupStack::PushL(key);
+
+ HBufC8* output = (*data)[2];
+ User::LeaveIfNull(output);
+ CleanupStack::PushL(output);
+
+ Hex(*input);
+ Hex(*key);
+ Hex(*output);
+
+ CMessageDigest* temp = aMD->ReplicateL();
+ CleanupStack::PushL(temp);
+ CMessageDigest* md = CHMAC::NewL(*key, temp);
+ CleanupStack::Pop(temp); // Now owned by md
+
+ TPtrC8 digest = md->Hash(*input);
+ if (digest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+
+ // Now try this in 2 half sections (just a quick check)
+ md->Reset();
+
+ TInt inputLen = input->Length();
+ if (inputLen > 1)
+ {
+ TInt leftHandLen = inputLen/2;
+ TPtrC8 left = input->Left(leftHandLen);
+ TPtrC8 right = input->Right(inputLen - leftHandLen);
+
+ TPtrC8 halfDigest = md->Hash(left);
+ if (halfDigest.Size()==0) // Unnecessary test, but removes
+ User::Leave(KErrAbort); // a warning about not using halfDigest
+ TPtrC8 wholeDigest = md->Hash(right);
+
+ if (wholeDigest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+ }
+
+///////////////////////////////////////////////////////////////
+// Now test the new API - Update/Final functions
+///////////////////////////////////////////////////////////////
+ md->Reset();
+ TPtrC8 finalDigest = md->Final(*input);
+ if (finalDigest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+
+ // Now try this in 2 half sections (just a quick check)
+ md->Reset();
+
+ inputLen = input->Length();
+ if (inputLen > 1)
+ {
+ TInt leftHandLen = inputLen/2;
+ TPtrC8 left = input->Left(leftHandLen);
+ TPtrC8 right = input->Right(inputLen - leftHandLen);
+
+ md->Update(left);
+ TPtrC8 wholeDigest = md->Final(right);
+
+ if (wholeDigest!=(*output))
+ {
+ testSuccess = EFalse;
+ }
+ }
+ delete md;
+ CleanupStack::PopAndDestroy(3); // input, key, output
+ break;
+ }
+ case CTestData::EFinished:
+ finished=ETrue;
+ break;
+ default:
+ test.Printf(_L("Error in data file\r\n"));
+ break;
+ }
+ };
+
+ CleanupStack::PopAndDestroy(data);
+
+ if (!testSuccess)
+ User::Leave(KErrGeneral);
+ }
+
+void HMACTestsL(CMessageDigest* aMD,const TDesC& aFilename, const TDesC& aHashType)
+ {
+ TBuf<0x40> formattable;
+ formattable.Format(_L("HMAC Tests for %S"), &aHashType);
+ test.Next(formattable);
+ CMessageDigest* temp = aMD->ReplicateL();
+ CleanupStack::PushL(temp);
+ CHMAC* hmac=CHMAC::NewL(_L8("aaaaaaaa"), temp);
+ CleanupStack::Pop(temp);
+ CleanupStack::PushL(hmac);
+
+// For each of the available digests
+ FunctionalityTestL(hmac); //JCS for now
+ HMACVectorTestL(aMD,aFilename);
+ OOMTestL(hmac);
+
+ CleanupStack::PopAndDestroy(hmac);
+ }
+
+void MD2TestsL()
+ {
+ CMD2* md2;
+ md2=CMD2::NewL();
+ CleanupStack::PushL(md2);
+
+ FunctionalityTestL(md2);
+
+ VectorTestL(md2,_L("md2.dat"));
+
+ OOMTestL(md2);
+
+ CleanupStack::PopAndDestroy(md2);
+
+// Problem reported by Jal Panvel, 17-12-1999.
+// Report by email, CSHA1::Hash() returning zero length descriptor
+//
+// This was caused by failure to set internal hash descriptor length on setup, this
+// problem was present in all hashes except MD2 which set it up correctly.
+// Fixed 17-12-1999.
+ test.Next(_L("Fixed bugs Tests"));
+ md2 = CMD2::NewL();
+ CleanupStack::PushL(md2);
+ TPtrC8 data(_L8("The quick brown fox jumped over the lazy dog"));
+ TBuf8<128> hash;
+ hash = md2->Hash(data);
+ test(hash.Length() == md2->HashSize());
+
+ HMACTestsL(md2,_L("hmacmd2.dat"), _L("md2"));
+ CleanupStack::PopAndDestroy(md2);
+ }
+
+void MD5TestsL()
+ {
+ CMD5* md5;
+ md5=CMD5::NewL();
+ CleanupStack::PushL(md5);
+
+ FunctionalityTestL(md5);
+
+ VectorTestL(md5,_L("md5.dat"));
+
+ OOMTestL(md5);
+
+ CleanupStack::PopAndDestroy(md5);
+ test.Next(_L("Fixed bugs Tests"));
+// Problem reported by Jal Panvel, 17-12-1999.
+// Report by email, CSHA1::Hash() returning zero length descriptor
+//
+// This was caused by failure to set internal hash descriptor length on setup, this
+// problem was present in all hashes except MD2 which set it up correctly.
+// Fixed 17-12-1999.
+ CMD5* md = CMD5::NewL();
+ CleanupStack::PushL(md);
+ TPtrC8 data(_L8("The quick brown fox jumped over the lazy dog"));
+ TBuf8<128> hash;
+ hash = md->Hash(data);
+ test(hash.Length() == md->HashSize());
+
+ HMACTestsL(md,_L("hmacmd5.dat"), _L("md5"));
+ CleanupStack::PopAndDestroy(md);
+
+ // Test for DEF001510 "TLS - Receives Disconnect Indication during hands..."
+ CMD5* testHasher = CMD5::NewL();
+ CleanupStack::PushL(testHasher);
+ TPtrC8 client(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A4"));
+ TPtrC8 server(_L8("3E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8"));
+
+ HBufC8* clientData = client.AllocLC();
+ HBufC8* serverData = server.AllocLC();
+
+ Hex(*clientData);
+ Hex(*serverData);
+
+ testHasher->Hash(*clientData);
+ testHasher->Hash(*serverData);
+
+ TBuf8<32> md5buf;
+ md5buf.Copy(testHasher->Hash(TPtrC8(0,0)));
+
+ testHasher->Reset();
+
+// Now hash in one chunk
+ TPtrC8 all(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A43E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8"));
+ HBufC8* allData = all.AllocLC();
+ Hex(*allData);
+
+ TBuf8<32> allbuf;
+ allbuf = testHasher->Hash(*allData);
+ test(allbuf.Compare(md5buf)==0);
+ CleanupStack::PopAndDestroy(4, testHasher);
+ }
+
+
+void MD4TestsL()
+ {
+ CMD4* md4;
+ md4=CMD4::NewL();
+ CleanupStack::PushL(md4);
+
+ FunctionalityTestL(md4);
+
+ VectorTestL(md4,_L("md4.dat"));
+
+ OOMTestL(md4);
+
+ CleanupStack::PopAndDestroy(md4);
+
+ //Copied the tests carried out for other Digest generating algorithms (MD5, SHA1)
+ CMD4* md = CMD4::NewL();
+ CleanupStack::PushL(md);
+ TPtrC8 data(_L8("The quick brown fox jumped over the lazy dog"));
+ TBuf8<128> hash;
+ hash = md->Hash(data);
+ test(hash.Length() == md->HashSize());
+
+ HMACTestsL(md,_L("hmacmd4.dat"), _L("md4"));
+ CleanupStack::PopAndDestroy(md);
+
+ CMD4* testHasher = CMD4::NewL();
+ CleanupStack::PushL(testHasher);
+ TPtrC8 client(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A4"));
+ TPtrC8 server(_L8("3E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8"));
+
+ HBufC8* clientData = client.AllocLC();
+ HBufC8* serverData = server.AllocLC();
+
+ Hex(*clientData);
+ Hex(*serverData);
+
+ testHasher->Hash(*clientData);
+ testHasher->Hash(*serverData);
+
+ TBuf8<32> md4buf;
+ md4buf.Copy(testHasher->Hash(TPtrC8(0,0)));
+
+ testHasher->Reset();
+
+// Now hash in one chunk
+ TPtrC8 all(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A43E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8"));
+ HBufC8* allData = all.AllocLC();
+ Hex(*allData);
+
+ TBuf8<32> allbuf;
+ allbuf = testHasher->Hash(*allData);
+ test(allbuf.Compare(md4buf)==0);
+ CleanupStack::PopAndDestroy(4, testHasher);
+
+ //Tests for the Factory Method CMessageDigestFactory
+ CMessageDigest* messageDigest = CMessageDigestFactory::NewDigestLC(CMessageDigest::EMD4);
+ VectorTestL(messageDigest,_L("md4.dat"));
+ CleanupStack::PopAndDestroy(messageDigest);
+
+
+ }
+
+void SHA1TestsL()
+ {
+ CSHA1* sha;
+ sha=CSHA1::NewL();
+ CleanupStack::PushL(sha);
+
+ VectorTestL(sha,_L("sha1.dat"));
+
+ FunctionalityTestL(sha);
+
+ OOMTestL(sha);
+
+ CleanupStack::PopAndDestroy(sha);
+
+ test.Next(_L("Fixed bugs Tests"));
+// Problem reported by Jal Panvel, 17-12-1999.
+// Report by email, CSHA1::Hash() returning zero length descriptor
+//
+// This was caused by failure to set internal hash descriptor length on setup, this
+// problem was present in all hashes except MD2 which set it up correctly.
+// Fixed 17-12-1999.
+
+ sha=CSHA1::NewL();
+ CleanupStack::PushL(sha);
+ TPtrC8 data(_L8("The quick brown fox jumped over the lazy dog"));
+ TBuf8<128> hash;
+ hash = sha->Hash(data);
+ test(hash.Length() == sha->HashSize());
+ sha->Reset();
+
+ // Test for DEF001510 "TLS - Receives Disconnect Indication during hands..."
+ CSHA1* testHasher = CSHA1::NewL();
+ CleanupStack::PushL(testHasher);
+ TPtrC8 client(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A4"));
+ TPtrC8 server(_L8("3E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8"));
+
+ HBufC8* clientData = client.AllocLC();
+ HBufC8* serverData = server.AllocLC();
+
+ Hex(*clientData);
+ Hex(*serverData);
+
+// Hash in 2 portions
+ TBuf8<32> clientbuf;
+ TBuf8<32> serverbuf;
+ clientbuf = testHasher->Hash(*clientData);
+ serverbuf = testHasher->Hash(*serverData);
+
+ TBuf8<32> shabuf;
+ shabuf.Copy(testHasher->Hash(TPtrC8(0,0)));
+ testHasher->Reset();
+
+// Now hash in one chunk
+ TPtrC8 all(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A43E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8"));
+ HBufC8* allData = all.AllocLC();
+ Hex(*allData);
+
+ TBuf8<32> allbuf;
+ allbuf = testHasher->Hash(*allData);
+
+ test(allbuf.Compare(shabuf)==0);
+ CleanupStack::PopAndDestroy(4, testHasher);
+
+ // Test hashing non-word aligned data - used to crash on arm
+ TPtrC8 nonAlignedData = data.Mid(1);
+ hash = sha->Final(nonAlignedData);
+ test(hash.Length() == sha->HashSize());
+ sha->Reset();
+
+// Test end
+ HMACTestsL(sha,_L("hmacsha1.dat"), _L("sha1"));
+ CleanupStack::PopAndDestroy(); // sha
+ }
+
+void ExecuteSha2TestsL(CMessageDigest* aMD, const TDesC& aVector, const TDesC& aHMACVector, const TDesC& aHashType)
+ {
+ VectorTestL(aMD, aVector);
+ FunctionalityTestL(aMD);
+ OOMTestL(aMD);
+ aMD->Reset();
+
+ test.Next(_L("Fixed bugs Tests"));
+
+ _LIT8(KTest1Data, "The quick brown fox jumped over the lazy dog");
+ TBuf8<KMaxHashSize> hash;
+ hash = aMD->Hash(KTest1Data());
+ test(hash.Length() == aMD->HashSize());
+ aMD->Reset();
+
+ _LIT8(KClientData, "D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A4");
+ _LIT8(KServerData, "3E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8");
+
+ HBufC8* clientData = KClientData().AllocLC();
+ HBufC8* serverData = KServerData().AllocLC();
+
+ Hex(*clientData);
+ Hex(*serverData);
+
+// Hash in 2 portions
+ aMD->Hash(*clientData);
+ aMD->Hash(*serverData);
+
+ CleanupStack::PopAndDestroy(2, clientData);
+
+ TBuf8<KMaxHashSize> shabuf;
+ shabuf.Copy(aMD->Hash(KNullDesC8()));
+ aMD->Reset();
+
+// Now hash in one chunk
+ _LIT8(KAllData, "D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A43E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8");
+ HBufC8* allData = KAllData().AllocLC();
+ Hex(*allData);
+
+ TBuf8<KMaxHashSize> allbuf;
+ allbuf = aMD->Hash(*allData);
+
+ test(allbuf.Compare(shabuf)==0);
+ CleanupStack::PopAndDestroy(allData);
+
+ // Test hashing non-word aligned data - used to crash on arm
+ TPtrC8 nonAlignedData = KTest1Data().Mid(1);
+ hash = aMD->Final(nonAlignedData);
+ test(hash.Length() == aMD->HashSize());
+ aMD->Reset();
+
+// Test end
+ HMACTestsL(aMD, aHMACVector, aHashType);
+ }
+
+_LIT(K224Algo, "SHA-224.dat");
+_LIT(K256Algo, "SHA-256.dat");
+_LIT(K384Algo, "SHA-384.dat");
+_LIT(K512Algo, "SHA-512.dat");
+_LIT(K224Vector, "sha224.dat");
+_LIT(K256Vector, "sha256.dat");
+_LIT(K384Vector, "sha384.dat");
+_LIT(K512Vector, "sha512.dat");
+_LIT(K224HmacVector, "hmacsha224.dat");
+_LIT(K256HmacVector, "hmacsha256.dat");
+_LIT(K384HmacVector, "hmacsha384.dat");
+_LIT(K512HmacVector, "hmacsha512.dat");
+
+const TDesC* gNames[] =
+ {
+ &K224Vector(),
+ &K224HmacVector(),
+ &K224Algo(),
+ &K256Vector(),
+ &K256HmacVector(),
+ &K256Algo(),
+ &K384Vector(),
+ &K384HmacVector(),
+ &K384Algo(),
+ &K512Vector(),
+ &K512HmacVector(),
+ &K512Algo(),
+ };
+
+
+void SHA2TestsL(CMessageDigest::THashId aHashId)
+ {
+ CMessageDigest* md = CMessageDigestFactory::NewDigestLC(aHashId);
+ TInt pos = aHashId - CMessageDigest::ESHA224;
+ pos *= 3;
+ ExecuteSha2TestsL (md, *gNames[pos], *gNames[pos+1], *gNames[pos+2]);
+ CleanupStack::PopAndDestroy(md);
+ }
+
+void HashTests(void)
+ {
+ TInt32 testsFailed=0, testCount=0;
+
+ test.Start(_L("MD4 Tests"));
+ TRAPD(r, MD4TestsL());
+ ++testCount;
+ if (r!=KErrNone)
+ {
+ test.Printf(_L("\r\nMD4 Tests failed error code =%d\r\n\r\n"),r);
+ ++testsFailed;
+ }
+
+ test.Start(_L("SHA1 Tests"));
+ TRAP(r, SHA1TestsL());
+ ++testCount;
+ if (r!=KErrNone)
+ {
+ test.Printf(_L("\r\nSHA1 Tests failed error code =%d\r\n\r\n"),r);
+ ++testsFailed;
+ }
+
+ test.Start(_L("SHA-224 Tests"));
+ TRAP(r, SHA2TestsL(CMessageDigest::ESHA224));
+ ++testCount;
+ if (r!=KErrNone)
+ {
+ test.Printf(_L("\r\nSHA-224 Tests failed error code =%d\r\n\r\n"),r);
+ ++testsFailed;
+ }
+
+ test.Start(_L("SHA-256 Tests"));
+ TRAP(r, SHA2TestsL(CMessageDigest::ESHA256));
+ ++testCount;
+ if (r!=KErrNone)
+ {
+ test.Printf(_L("\r\nSHA-256 Tests failed error code =%d\r\n\r\n"),r);
+ ++testsFailed;
+ }
+
+ test.Start(_L("SHA-384 Tests"));
+ TRAP(r, SHA2TestsL(CMessageDigest::ESHA384));
+ ++testCount;
+ if (r!=KErrNone)
+ {
+ test.Printf(_L("\r\nSHA-384 Tests failed error code =%d\r\n\r\n"),r);
+ ++testsFailed;
+ }
+
+ test.Start(_L("SHA-512 Tests"));
+ TRAP(r, SHA2TestsL(CMessageDigest::ESHA512));
+ ++testCount;
+ if (r!=KErrNone)
+ {
+ test.Printf(_L("\r\nSHA-512 Tests failed error code =%d\r\n\r\n"),r);
+ ++testsFailed;
+ }
+
+ test.Start(_L("MD5 Tests"));
+ TRAP(r, MD5TestsL());
+ ++testCount;
+ if (r!=KErrNone)
+ {
+ test.Printf(_L("\r\nMD5 Tests failed error code =%d\r\n\r\n"),r);
+ ++testsFailed;
+ }
+
+ test.Start(_L("MD2 Tests"));
+ TRAP(r, MD2TestsL());
+ ++testCount;
+ if (r!=KErrNone)
+ {
+ test.Printf(_L("\r\nMD2 Tests failed error code =%d\r\n\r\n"),r);
+ ++testsFailed;
+ }
+
+ test.Printf(_L("\r\n%d tests failed out of %d \r\n"),testsFailed,testCount);
+ test(testsFailed==0);
+ }
+
+
+GLDEF_C TInt E32Main(void)
+
+ {
+ CTrapCleanup* cleanup;
+ cleanup=CTrapCleanup::New();
+
+ test.Start(_L(" @SYMTestCaseID:SEC-CRYPTOSPI-HASH-0035 Hash Algorithm Tests "));
+ CTestConsole* con=NULL;
+ TRAPD(ret, con=CTestConsole::NewL(test.Console()));
+ if(ret != KErrNone)
+ {
+ return ret;
+ }
+ RFs fs;
+
+ fs.Connect();
+ RFile* file;
+ file=new (ELeave) RFile;
+
+ TDriveUnit sysDrive (fs.GetSystemDrive());
+ TBuf<24> hashLogFile (sysDrive.Name());
+ hashLogFile.Append(_L("\\HashLog.txt"));
+
+ file->Replace(fs,hashLogFile,EFileShareAny|EFileWrite);
+ con->SetLogFile(file);
+
+ test.SetConsole(con);
+ __UHEAP_MARK;
+ HashTests();
+ __UHEAP_MARKEND;
+
+ test.End();
+ test.Close();
+ delete cleanup;
+ return(KErrNone);
+ }