|
1 /* |
|
2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
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". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 /** |
|
22 @file |
|
23 */ |
|
24 |
|
25 #include "hashtestutils.h" |
|
26 #include <utf.h> |
|
27 |
|
28 TBool gInOOMTest=EFalse; |
|
29 |
|
30 RTest test(_L("Hash Tests")); |
|
31 |
|
32 const TInt KMaxHashSize = 64; // Hash size in bytes |
|
33 |
|
34 void Hex(HBufC8& aString) |
|
35 { |
|
36 TPtr8 ptr=aString.Des(); |
|
37 if (aString.Length()%2) |
|
38 { |
|
39 ptr.SetLength(0); |
|
40 return; |
|
41 } |
|
42 TInt i; |
|
43 for (i=0;i<aString.Length();i+=2) |
|
44 { |
|
45 TUint8 tmp; |
|
46 tmp=(TUint8)(aString[i]-(aString[i]>'9'?('A'-10):'0')); |
|
47 tmp*=16; |
|
48 tmp|=(TUint8)(aString[i+1]-(aString[i+1]>'9'?('A'-10):'0')); |
|
49 ptr[i/2]=tmp; |
|
50 } |
|
51 ptr.SetLength(aString.Length()/2); |
|
52 } |
|
53 |
|
54 void Spin() |
|
55 {// Pointless function to print a dot |
|
56 if (gInOOMTest) |
|
57 { |
|
58 static TInt count=0; |
|
59 if (count++==100) |
|
60 { |
|
61 test.Printf(_L("o")); |
|
62 count=0; |
|
63 } |
|
64 return; |
|
65 } |
|
66 test.Printf(_L(".")); |
|
67 } |
|
68 |
|
69 void FunctionalityTestL(CMessageDigest* aMD) |
|
70 { |
|
71 if (!gInOOMTest) |
|
72 test.Next(_L("Functionality test - original API")); |
|
73 |
|
74 const TInt maxbuffersize=1024; |
|
75 TInt buffersize; |
|
76 TInt increment; |
|
77 if (gInOOMTest) |
|
78 { |
|
79 buffersize=256; |
|
80 increment=6; |
|
81 } |
|
82 else |
|
83 { |
|
84 buffersize=maxbuffersize; |
|
85 increment=1; |
|
86 } |
|
87 |
|
88 TBool testSuccess = ETrue; |
|
89 TInt i = 0; |
|
90 TBuf8<maxbuffersize> buf(maxbuffersize); |
|
91 for (;i<buffersize;i++) |
|
92 { |
|
93 buf[i]=(TUint8)i; |
|
94 } |
|
95 |
|
96 for (i=0;i<buffersize;i+=increment) |
|
97 { |
|
98 TInt j; |
|
99 Spin(); |
|
100 if (!gInOOMTest) |
|
101 { |
|
102 if (i>128) |
|
103 { |
|
104 increment=8; |
|
105 } |
|
106 } |
|
107 else |
|
108 { |
|
109 if (i>24) |
|
110 { |
|
111 increment=32; |
|
112 } |
|
113 } |
|
114 |
|
115 for (j=0;j<i;j+=16) |
|
116 { |
|
117 buf[0]=(TUint8)j; |
|
118 TPtrC8 ptr=buf.Left(i); |
|
119 TPtrC8 ptr2=buf.Left(j); |
|
120 TPtrC8 ptr3=buf.Mid(j,i-j); |
|
121 |
|
122 CMessageDigest* first=aMD->ReplicateL(); |
|
123 CleanupStack::PushL(first); |
|
124 TPtrC8 firstFinal = first->Hash(ptr); |
|
125 |
|
126 aMD->Reset(); |
|
127 aMD->Update(ptr); |
|
128 TPtrC8 aMDFinal = aMD->Final(); |
|
129 |
|
130 CMessageDigest* second=aMD->ReplicateL(); |
|
131 CleanupStack::PushL(second); |
|
132 second->Hash(ptr2); |
|
133 |
|
134 CMessageDigest* third=second->CopyL(); |
|
135 CleanupStack::PushL(third); |
|
136 |
|
137 TPtrC8 secondFinal = second->Hash(ptr3); |
|
138 |
|
139 if (aMDFinal!=firstFinal) |
|
140 { |
|
141 testSuccess = EFalse; |
|
142 } |
|
143 |
|
144 if (firstFinal!=secondFinal) |
|
145 { |
|
146 testSuccess = EFalse; |
|
147 } |
|
148 |
|
149 TPtrC8 thirdFinal = third->Hash(ptr3); |
|
150 if (firstFinal!=thirdFinal) |
|
151 { |
|
152 testSuccess = EFalse; |
|
153 } |
|
154 CleanupStack::PopAndDestroy(3); // first, second, third |
|
155 } |
|
156 } |
|
157 |
|
158 /////////////////////////////////////////////////////////////// |
|
159 // Now test the new API - Update/Final functions |
|
160 /////////////////////////////////////////////////////////////// |
|
161 if (!gInOOMTest) |
|
162 test.Next(_L("\rFunctionality test - calls added API functions Final & Update")); |
|
163 |
|
164 for (i=0;i<buffersize;i++) |
|
165 { |
|
166 buf[i]=(TUint8)i; |
|
167 } |
|
168 |
|
169 for (i=0;i<buffersize;i+=increment) |
|
170 { |
|
171 TInt j; |
|
172 Spin(); |
|
173 if (!gInOOMTest) |
|
174 { |
|
175 if (i>128) |
|
176 { |
|
177 increment=8; |
|
178 } |
|
179 } |
|
180 else |
|
181 { |
|
182 if (i>24) |
|
183 { |
|
184 increment=32; |
|
185 } |
|
186 } |
|
187 for (j=0;j<i;j+=16) |
|
188 { |
|
189 buf[0]=(TUint8)j; |
|
190 TPtrC8 ptr=buf.Left(i); |
|
191 TPtrC8 ptr2=buf.Left(j); |
|
192 TPtrC8 ptr3=buf.Mid(j,i-j); |
|
193 |
|
194 CMessageDigest* first=aMD->ReplicateL(); |
|
195 CleanupStack::PushL(first); |
|
196 first->Update(ptr); |
|
197 |
|
198 aMD->Update(ptr); |
|
199 |
|
200 CMessageDigest* second=aMD->ReplicateL(); |
|
201 CleanupStack::PushL(second); |
|
202 second->Update(ptr2); |
|
203 |
|
204 CMessageDigest* third=second->CopyL(); |
|
205 CleanupStack::PushL(third); |
|
206 third->Update(ptr3); |
|
207 |
|
208 second->Update(ptr3); |
|
209 |
|
210 TPtrC8 aMDFinal = aMD->Final(); |
|
211 TPtrC8 firstFinal = first->Final(); |
|
212 TPtrC8 secondFinal = second->Final(); |
|
213 TPtrC8 thirdFinal = third->Final(); |
|
214 |
|
215 if (aMDFinal!=firstFinal) |
|
216 { |
|
217 testSuccess = EFalse; |
|
218 } |
|
219 |
|
220 if (firstFinal!=secondFinal) |
|
221 { |
|
222 testSuccess = EFalse; |
|
223 } |
|
224 |
|
225 if (firstFinal!=thirdFinal) |
|
226 { |
|
227 testSuccess = EFalse; |
|
228 } |
|
229 |
|
230 CleanupStack::PopAndDestroy(3); // first, second, third |
|
231 } |
|
232 } |
|
233 test.Printf(_L("\r\n")); |
|
234 |
|
235 if (!testSuccess) |
|
236 User::Leave(KErrGeneral); |
|
237 } |
|
238 |
|
239 void VectorTestL(CMessageDigest* aMD,const TDesC& aFilename) |
|
240 { |
|
241 test.Next(_L("Test Vector tests - original API")); |
|
242 TBool finished=EFalse; |
|
243 TBool testSuccess = ETrue; |
|
244 CTestData* data = CTestData::NewL(aFilename); |
|
245 CleanupStack::PushL(data); |
|
246 |
|
247 while (!finished) |
|
248 { |
|
249 switch (data->Type()) |
|
250 { |
|
251 case CTestData::EMessage: |
|
252 { |
|
253 break; |
|
254 } |
|
255 //This is added to read large input data from the files. |
|
256 case CTestData::EFileName: |
|
257 { |
|
258 CMessageDigest* md=aMD->ReplicateL(); |
|
259 CleanupStack::PushL(md); |
|
260 |
|
261 //get the filename from the .dat file |
|
262 HBufC8* filename = (*data)[1]; |
|
263 User::LeaveIfNull(filename); |
|
264 CleanupStack::PushL(filename); |
|
265 |
|
266 HBufC8* output= (*data)[2]; |
|
267 User::LeaveIfNull(output); |
|
268 CleanupStack::PushL(output); |
|
269 Hex(*output); |
|
270 |
|
271 HBufC16* inputFileName = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*filename); |
|
272 |
|
273 RFs fs; |
|
274 RFile file; |
|
275 CleanupClosePushL(fs); |
|
276 User::LeaveIfError(fs.Connect()); |
|
277 TDriveUnit sysDrive(fs.GetSystemDrive()); |
|
278 TBuf<24> filePath (sysDrive.Name()); |
|
279 filePath.Append(_L("\\thash\\")); |
|
280 User::LeaveIfError(fs.SetSessionPath(filePath)); |
|
281 CleanupClosePushL(file); |
|
282 User::LeaveIfError(file.Open(fs,*inputFileName,EFileShareAny|EFileRead)); |
|
283 // read into iFile |
|
284 TInt size=0; |
|
285 file.Size(size); |
|
286 HBufC8* fileContents=HBufC8::NewMaxL(size); |
|
287 |
|
288 TPtr8 ptr=fileContents->Des(); |
|
289 User::LeaveIfError(file.Read(ptr)); |
|
290 CleanupStack::PopAndDestroy(2, &fs); |
|
291 CleanupStack::PushL(fileContents); |
|
292 delete inputFileName; |
|
293 |
|
294 TPtrC8 digest = md->Hash(*fileContents); |
|
295 if (digest!=(*output)) |
|
296 { |
|
297 test.Next(_L("Digest Not Equal")); |
|
298 testSuccess = EFalse; |
|
299 } |
|
300 |
|
301 md->Reset(); |
|
302 |
|
303 TPtrC8 digest2 = md->Hash(*fileContents); |
|
304 if (digest2!=(*output)) |
|
305 { |
|
306 testSuccess = EFalse; |
|
307 } |
|
308 |
|
309 // Now try this in 2 half sections (just a quick check) |
|
310 md->Reset(); |
|
311 |
|
312 TInt inputLen = fileContents->Length(); |
|
313 if (inputLen > 1) |
|
314 { |
|
315 TInt leftHandLen = inputLen/2; |
|
316 TPtrC8 left = fileContents->Left(leftHandLen); |
|
317 TPtrC8 right = fileContents->Right(inputLen - leftHandLen); |
|
318 |
|
319 TPtrC8 halfDigest = md->Hash(left); |
|
320 if (halfDigest.Size()==0) // Unnecessary test, but removes |
|
321 User::Leave(KErrAbort); // a warning about not using halfDigest |
|
322 |
|
323 TPtrC8 wholeDigest = md->Hash(right); |
|
324 |
|
325 if (wholeDigest!=(*output)) |
|
326 { |
|
327 testSuccess = EFalse; |
|
328 } |
|
329 } |
|
330 |
|
331 md->Reset(); |
|
332 if (md->Final(*fileContents)!=(*output)) |
|
333 { |
|
334 testSuccess = EFalse; |
|
335 } |
|
336 |
|
337 // Now try this in 2 half sections (just a quick check) |
|
338 md->Reset(); |
|
339 inputLen = fileContents->Length(); |
|
340 if (inputLen > 1) |
|
341 { |
|
342 TInt leftHandLen = inputLen/2; |
|
343 TPtrC8 left = fileContents->Left(leftHandLen); |
|
344 TPtrC8 right = fileContents->Right(inputLen - leftHandLen); |
|
345 |
|
346 md->Update(left); |
|
347 TPtrC8 wholeDigest = md->Final(right); |
|
348 |
|
349 if (wholeDigest!=(*output)) |
|
350 { |
|
351 testSuccess = EFalse; |
|
352 } |
|
353 } |
|
354 CleanupStack::PopAndDestroy(4, md);//md,filename,output,fileContents |
|
355 |
|
356 break; |
|
357 } |
|
358 case CTestData::EData: |
|
359 { |
|
360 CMessageDigest* md=aMD->ReplicateL(); |
|
361 CleanupStack::PushL(md); |
|
362 |
|
363 HBufC8* input = (*data)[0]; |
|
364 User::LeaveIfNull(input); |
|
365 CleanupStack::PushL(input); |
|
366 |
|
367 HBufC8* output= (*data)[1]; |
|
368 User::LeaveIfNull(output); |
|
369 CleanupStack::PushL(output); |
|
370 Hex(*input); |
|
371 Hex(*output); |
|
372 |
|
373 TPtrC8 digest = md->Hash(*input); |
|
374 if (digest!=(*output)) |
|
375 { |
|
376 testSuccess = EFalse; |
|
377 } |
|
378 |
|
379 md->Reset(); |
|
380 |
|
381 TPtrC8 digest2 = md->Hash(*input); |
|
382 if (digest2!=(*output)) |
|
383 { |
|
384 testSuccess = EFalse; |
|
385 } |
|
386 |
|
387 // Now try this in 2 half sections (just a quick check) |
|
388 md->Reset(); |
|
389 |
|
390 TInt inputLen = input->Length(); |
|
391 if (inputLen > 1) |
|
392 { |
|
393 TInt leftHandLen = inputLen/2; |
|
394 TPtrC8 left = input->Left(leftHandLen); |
|
395 TPtrC8 right = input->Right(inputLen - leftHandLen); |
|
396 |
|
397 TPtrC8 halfDigest = md->Hash(left); |
|
398 if (halfDigest.Size()==0) // Unnecessary test, but removes |
|
399 User::Leave(KErrAbort); // a warning about not using halfDigest |
|
400 |
|
401 TPtrC8 wholeDigest = md->Hash(right); |
|
402 |
|
403 if (wholeDigest!=(*output)) |
|
404 { |
|
405 testSuccess = EFalse; |
|
406 } |
|
407 } |
|
408 |
|
409 /////////////////////////////////////////////////////////////// |
|
410 // Now test the new API - Update/Final functions |
|
411 /////////////////////////////////////////////////////////////// |
|
412 md->Reset(); |
|
413 if (md->Final(*input)!=(*output)) |
|
414 { |
|
415 testSuccess = EFalse; |
|
416 } |
|
417 |
|
418 // Now try this in 2 half sections (just a quick check) |
|
419 md->Reset(); |
|
420 inputLen = input->Length(); |
|
421 if (inputLen > 1) |
|
422 { |
|
423 TInt leftHandLen = inputLen/2; |
|
424 TPtrC8 left = input->Left(leftHandLen); |
|
425 TPtrC8 right = input->Right(inputLen - leftHandLen); |
|
426 |
|
427 md->Update(left); |
|
428 TPtrC8 wholeDigest = md->Final(right); |
|
429 |
|
430 if (wholeDigest!=(*output)) |
|
431 { |
|
432 testSuccess = EFalse; |
|
433 } |
|
434 } |
|
435 CleanupStack::PopAndDestroy(3); |
|
436 break; |
|
437 } |
|
438 case CTestData::EFinished: |
|
439 finished=ETrue; |
|
440 break; |
|
441 default: |
|
442 test.Printf(_L("Error in data file\r\n")); |
|
443 break; |
|
444 } |
|
445 }; |
|
446 |
|
447 CleanupStack::PopAndDestroy(data); |
|
448 |
|
449 if (!testSuccess) |
|
450 User::Leave(KErrGeneral); |
|
451 } |
|
452 |
|
453 void OOMTestL(CMessageDigest* aMD) |
|
454 { |
|
455 test.Next(_L("Out of memory test")); |
|
456 TInt err = KErrNoMemory; |
|
457 TInt nextFailure=0; |
|
458 gInOOMTest=ETrue; |
|
459 while (err!=KErrNone) |
|
460 { |
|
461 __UHEAP_MARK; |
|
462 __UHEAP_FAILNEXT(nextFailure); |
|
463 TRAP(err,FunctionalityTestL(aMD)); |
|
464 __UHEAP_MARKEND; |
|
465 nextFailure++; |
|
466 } |
|
467 __UHEAP_RESET; |
|
468 gInOOMTest=EFalse; |
|
469 } |
|
470 |
|
471 void HMACVectorTestL(CMessageDigest* aMD,const TDesC& aFilename) |
|
472 { |
|
473 test.Next(_L("HMAC Test Vector tests")); |
|
474 CTestData* data = CTestData::NewL(aFilename); |
|
475 CleanupStack::PushL(data); |
|
476 |
|
477 TBool finished=EFalse; |
|
478 TBool testSuccess = ETrue; |
|
479 |
|
480 while (!finished) |
|
481 { |
|
482 switch (data->Type()) |
|
483 { |
|
484 case CTestData::EMessage: |
|
485 { |
|
486 break; |
|
487 } |
|
488 case CTestData::EFileName: |
|
489 { |
|
490 //get the filename from the .dat file |
|
491 HBufC8* filename = (*data)[1]; |
|
492 User::LeaveIfNull(filename); |
|
493 CleanupStack::PushL(filename); |
|
494 |
|
495 HBufC8* key= (*data)[2]; |
|
496 User::LeaveIfNull(key); |
|
497 CleanupStack::PushL(key); |
|
498 |
|
499 HBufC16* inputFileName = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*filename); |
|
500 |
|
501 HBufC8* output = (*data)[3]; |
|
502 User::LeaveIfNull(output); |
|
503 CleanupStack::PushL(output); |
|
504 |
|
505 Hex(*key); |
|
506 Hex(*output); |
|
507 |
|
508 RFs fs; |
|
509 RFile file; |
|
510 CleanupClosePushL(fs); |
|
511 User::LeaveIfError(fs.Connect()); |
|
512 TDriveUnit sysDrive(fs.GetSystemDrive()); |
|
513 TBuf<24> filePath (sysDrive.Name()); |
|
514 filePath.Append(_L("\\thash\\")); |
|
515 User::LeaveIfError(fs.SetSessionPath(filePath)); |
|
516 CleanupClosePushL(file); |
|
517 User::LeaveIfError(file.Open(fs,*inputFileName,EFileShareAny|EFileRead)); |
|
518 // read into iFile |
|
519 TInt size=0; |
|
520 file.Size(size); |
|
521 HBufC8* fileContents=HBufC8::NewMaxL(size); |
|
522 |
|
523 TPtr8 ptr=fileContents->Des(); |
|
524 User::LeaveIfError(file.Read(ptr)); |
|
525 CleanupStack::PopAndDestroy(2, &fs); |
|
526 CleanupStack::PushL(fileContents); |
|
527 delete inputFileName; |
|
528 |
|
529 CMessageDigest* temp = aMD->ReplicateL(); |
|
530 CleanupStack::PushL(temp); |
|
531 CMessageDigest* md = CHMAC::NewL(*key, temp); |
|
532 CleanupStack::Pop(temp); // Now owned by md |
|
533 |
|
534 TPtrC8 digest = md->Hash(*fileContents); |
|
535 if (digest!=(*output)) |
|
536 { |
|
537 testSuccess = EFalse; |
|
538 } |
|
539 |
|
540 // Now try this in 2 half sections (just a quick check) |
|
541 md->Reset(); |
|
542 |
|
543 TInt inputLen = fileContents->Length(); |
|
544 if (inputLen > 1) |
|
545 { |
|
546 TInt leftHandLen = inputLen/2; |
|
547 TPtrC8 left = fileContents->Left(leftHandLen); |
|
548 TPtrC8 right = fileContents->Right(inputLen - leftHandLen); |
|
549 |
|
550 TPtrC8 halfDigest = md->Hash(left); |
|
551 if (halfDigest.Size()==0) // Unnecessary test, but removes |
|
552 User::Leave(KErrAbort); // a warning about not using halfDigest |
|
553 TPtrC8 wholeDigest = md->Hash(right); |
|
554 |
|
555 if (wholeDigest!=(*output)) |
|
556 { |
|
557 testSuccess = EFalse; |
|
558 } |
|
559 } |
|
560 |
|
561 md->Reset(); |
|
562 TPtrC8 finalDigest = md->Final(*fileContents); |
|
563 if (finalDigest!=(*output)) |
|
564 { |
|
565 testSuccess = EFalse; |
|
566 } |
|
567 |
|
568 // Now try this in 2 half sections (just a quick check) |
|
569 md->Reset(); |
|
570 |
|
571 inputLen = fileContents->Length(); |
|
572 if (inputLen > 1) |
|
573 { |
|
574 TInt leftHandLen = inputLen/2; |
|
575 TPtrC8 left = fileContents->Left(leftHandLen); |
|
576 TPtrC8 right = fileContents->Right(inputLen - leftHandLen); |
|
577 |
|
578 md->Update(left); |
|
579 TPtrC8 wholeDigest = md->Final(right); |
|
580 |
|
581 if (wholeDigest!=(*output)) |
|
582 { |
|
583 testSuccess = EFalse; |
|
584 } |
|
585 } |
|
586 delete md; |
|
587 |
|
588 CleanupStack::PopAndDestroy(4, filename); // filename, key, output,fileContents |
|
589 break; |
|
590 } |
|
591 case CTestData::EData: |
|
592 { |
|
593 HBufC8* input = (*data)[0]; |
|
594 User::LeaveIfNull(input); |
|
595 CleanupStack::PushL(input); |
|
596 |
|
597 HBufC8* key = (*data)[1]; |
|
598 User::LeaveIfNull(key); |
|
599 CleanupStack::PushL(key); |
|
600 |
|
601 HBufC8* output = (*data)[2]; |
|
602 User::LeaveIfNull(output); |
|
603 CleanupStack::PushL(output); |
|
604 |
|
605 Hex(*input); |
|
606 Hex(*key); |
|
607 Hex(*output); |
|
608 |
|
609 CMessageDigest* temp = aMD->ReplicateL(); |
|
610 CleanupStack::PushL(temp); |
|
611 CMessageDigest* md = CHMAC::NewL(*key, temp); |
|
612 CleanupStack::Pop(temp); // Now owned by md |
|
613 |
|
614 TPtrC8 digest = md->Hash(*input); |
|
615 if (digest!=(*output)) |
|
616 { |
|
617 testSuccess = EFalse; |
|
618 } |
|
619 |
|
620 // Now try this in 2 half sections (just a quick check) |
|
621 md->Reset(); |
|
622 |
|
623 TInt inputLen = input->Length(); |
|
624 if (inputLen > 1) |
|
625 { |
|
626 TInt leftHandLen = inputLen/2; |
|
627 TPtrC8 left = input->Left(leftHandLen); |
|
628 TPtrC8 right = input->Right(inputLen - leftHandLen); |
|
629 |
|
630 TPtrC8 halfDigest = md->Hash(left); |
|
631 if (halfDigest.Size()==0) // Unnecessary test, but removes |
|
632 User::Leave(KErrAbort); // a warning about not using halfDigest |
|
633 TPtrC8 wholeDigest = md->Hash(right); |
|
634 |
|
635 if (wholeDigest!=(*output)) |
|
636 { |
|
637 testSuccess = EFalse; |
|
638 } |
|
639 } |
|
640 |
|
641 /////////////////////////////////////////////////////////////// |
|
642 // Now test the new API - Update/Final functions |
|
643 /////////////////////////////////////////////////////////////// |
|
644 md->Reset(); |
|
645 TPtrC8 finalDigest = md->Final(*input); |
|
646 if (finalDigest!=(*output)) |
|
647 { |
|
648 testSuccess = EFalse; |
|
649 } |
|
650 |
|
651 // Now try this in 2 half sections (just a quick check) |
|
652 md->Reset(); |
|
653 |
|
654 inputLen = input->Length(); |
|
655 if (inputLen > 1) |
|
656 { |
|
657 TInt leftHandLen = inputLen/2; |
|
658 TPtrC8 left = input->Left(leftHandLen); |
|
659 TPtrC8 right = input->Right(inputLen - leftHandLen); |
|
660 |
|
661 md->Update(left); |
|
662 TPtrC8 wholeDigest = md->Final(right); |
|
663 |
|
664 if (wholeDigest!=(*output)) |
|
665 { |
|
666 testSuccess = EFalse; |
|
667 } |
|
668 } |
|
669 delete md; |
|
670 CleanupStack::PopAndDestroy(3); // input, key, output |
|
671 break; |
|
672 } |
|
673 case CTestData::EFinished: |
|
674 finished=ETrue; |
|
675 break; |
|
676 default: |
|
677 test.Printf(_L("Error in data file\r\n")); |
|
678 break; |
|
679 } |
|
680 }; |
|
681 |
|
682 CleanupStack::PopAndDestroy(data); |
|
683 |
|
684 if (!testSuccess) |
|
685 User::Leave(KErrGeneral); |
|
686 } |
|
687 |
|
688 void HMACTestsL(CMessageDigest* aMD,const TDesC& aFilename, const TDesC& aHashType) |
|
689 { |
|
690 TBuf<0x40> formattable; |
|
691 formattable.Format(_L("HMAC Tests for %S"), &aHashType); |
|
692 test.Next(formattable); |
|
693 CMessageDigest* temp = aMD->ReplicateL(); |
|
694 CleanupStack::PushL(temp); |
|
695 CHMAC* hmac=CHMAC::NewL(_L8("aaaaaaaa"), temp); |
|
696 CleanupStack::Pop(temp); |
|
697 CleanupStack::PushL(hmac); |
|
698 |
|
699 // For each of the available digests |
|
700 FunctionalityTestL(hmac); //JCS for now |
|
701 HMACVectorTestL(aMD,aFilename); |
|
702 OOMTestL(hmac); |
|
703 |
|
704 CleanupStack::PopAndDestroy(hmac); |
|
705 } |
|
706 |
|
707 |
|
708 void MD2TestsL() |
|
709 { |
|
710 CMD2* md2; |
|
711 md2=CMD2::NewL(); |
|
712 CleanupStack::PushL(md2); |
|
713 |
|
714 FunctionalityTestL(md2); |
|
715 |
|
716 VectorTestL(md2,_L("md2.dat")); |
|
717 |
|
718 OOMTestL(md2); |
|
719 |
|
720 CleanupStack::PopAndDestroy(md2); |
|
721 |
|
722 // Problem reported by Jal Panvel, 17-12-1999. |
|
723 // Report by email, CSHA1::Hash() returning zero length descriptor |
|
724 // |
|
725 // This was caused by failure to set internal hash descriptor length on setup, this |
|
726 // problem was present in all hashes except MD2 which set it up correctly. |
|
727 // Fixed 17-12-1999. |
|
728 test.Next(_L("Fixed bugs Tests")); |
|
729 md2 = CMD2::NewL(); |
|
730 CleanupStack::PushL(md2); |
|
731 TPtrC8 data(_L8("The quick brown fox jumped over the lazy dog")); |
|
732 TBuf8<128> hash; |
|
733 hash = md2->Hash(data); |
|
734 test(hash.Length() == md2->HashSize()); |
|
735 |
|
736 HMACTestsL(md2,_L("hmacmd2.dat"), _L("md2")); |
|
737 CleanupStack::PopAndDestroy(md2); |
|
738 } |
|
739 |
|
740 void MD5TestsL() |
|
741 { |
|
742 CMD5* md5; |
|
743 md5=CMD5::NewL(); |
|
744 CleanupStack::PushL(md5); |
|
745 |
|
746 FunctionalityTestL(md5); |
|
747 |
|
748 VectorTestL(md5,_L("md5.dat")); |
|
749 |
|
750 OOMTestL(md5); |
|
751 |
|
752 CleanupStack::PopAndDestroy(md5); |
|
753 test.Next(_L("Fixed bugs Tests")); |
|
754 // Problem reported by Jal Panvel, 17-12-1999. |
|
755 // Report by email, CSHA1::Hash() returning zero length descriptor |
|
756 // |
|
757 // This was caused by failure to set internal hash descriptor length on setup, this |
|
758 // problem was present in all hashes except MD2 which set it up correctly. |
|
759 // Fixed 17-12-1999. |
|
760 CMD5* md = CMD5::NewL(); |
|
761 CleanupStack::PushL(md); |
|
762 TPtrC8 data(_L8("The quick brown fox jumped over the lazy dog")); |
|
763 TBuf8<128> hash; |
|
764 hash = md->Hash(data); |
|
765 test(hash.Length() == md->HashSize()); |
|
766 |
|
767 HMACTestsL(md5,_L("hmacmd5.dat"), _L("md5")); |
|
768 CleanupStack::PopAndDestroy(md); |
|
769 |
|
770 // Test for DEF001510 "TLS - Receives Disconnect Indication during hands..." |
|
771 CMD5* testHasher = CMD5::NewL(); |
|
772 CleanupStack::PushL(testHasher); |
|
773 TPtrC8 client(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A4")); |
|
774 TPtrC8 server(_L8("3E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8")); |
|
775 |
|
776 HBufC8* clientData = client.AllocLC(); |
|
777 HBufC8* serverData = server.AllocLC(); |
|
778 |
|
779 Hex(*clientData); |
|
780 Hex(*serverData); |
|
781 |
|
782 testHasher->Hash(*clientData); |
|
783 testHasher->Hash(*serverData); |
|
784 |
|
785 TBuf8<32> md5buf; |
|
786 md5buf.Copy(testHasher->Hash(TPtrC8(0,0))); |
|
787 |
|
788 testHasher->Reset(); |
|
789 |
|
790 // Now hash in one chunk |
|
791 TPtrC8 all(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A43E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8")); |
|
792 HBufC8* allData = all.AllocLC(); |
|
793 Hex(*allData); |
|
794 |
|
795 TBuf8<32> allbuf; |
|
796 allbuf = testHasher->Hash(*allData); |
|
797 test(allbuf.Compare(md5buf)==0); |
|
798 CleanupStack::PopAndDestroy(4, testHasher); |
|
799 } |
|
800 |
|
801 // Test for the MD4 Message Digest Algorithm API's |
|
802 void MD4TestsL() |
|
803 { |
|
804 CMD4* md4; |
|
805 md4=CMD4::NewL(); |
|
806 CleanupStack::PushL(md4); |
|
807 |
|
808 FunctionalityTestL(md4); |
|
809 |
|
810 VectorTestL(md4,_L("md4.dat")); |
|
811 |
|
812 OOMTestL(md4); |
|
813 |
|
814 CleanupStack::PopAndDestroy(md4); |
|
815 |
|
816 //Test to check the Hash Size. |
|
817 CMD4* md = CMD4::NewL(); |
|
818 CleanupStack::PushL(md); |
|
819 TPtrC8 data(_L8("The quick brown fox jumped over the lazy dog")); |
|
820 TBuf8<128> hash; |
|
821 hash = md->Hash(data); |
|
822 test(hash.Length() == md->HashSize()); |
|
823 |
|
824 HMACTestsL(md,_L("hmacmd4.dat"), _L("md4")); |
|
825 CleanupStack::PopAndDestroy(md); |
|
826 |
|
827 //Tests carried for other Message Digest Algorithms copied(SHA1 and MD5) |
|
828 //Here Input Data is given in two parts and as a whole and the digest generated is compared. |
|
829 CMD4* testHasher = CMD4::NewL(); |
|
830 CleanupStack::PushL(testHasher); |
|
831 TPtrC8 client(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A4")); |
|
832 TPtrC8 server(_L8("3E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8")); |
|
833 |
|
834 HBufC8* clientData = client.AllocLC(); |
|
835 HBufC8* serverData = server.AllocLC(); |
|
836 |
|
837 Hex(*clientData); |
|
838 Hex(*serverData); |
|
839 |
|
840 testHasher->Hash(*clientData); |
|
841 testHasher->Hash(*serverData); |
|
842 |
|
843 TBuf8<32> md4buf; |
|
844 md4buf.Copy(testHasher->Hash(TPtrC8(0,0))); |
|
845 |
|
846 testHasher->Reset(); |
|
847 |
|
848 // Now hash in one chunk |
|
849 TPtrC8 all(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A43E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8")); |
|
850 HBufC8* allData = all.AllocLC(); |
|
851 Hex(*allData); |
|
852 |
|
853 TBuf8<32> allbuf; |
|
854 allbuf = testHasher->Hash(*allData); |
|
855 test(allbuf.Compare(md4buf)==0); |
|
856 CleanupStack::PopAndDestroy(4, testHasher); |
|
857 |
|
858 //Tests for the Factory Method CMessageDigestFactory |
|
859 CMessageDigest* messageDigest = CMessageDigestFactory::NewDigestLC(CMessageDigest::EMD4); |
|
860 VectorTestL(messageDigest,_L("md4.dat")); |
|
861 CleanupStack::PopAndDestroy(messageDigest); |
|
862 } |
|
863 |
|
864 |
|
865 void SHA1TestsL() |
|
866 { |
|
867 CSHA1* sha; |
|
868 sha=CSHA1::NewL(); |
|
869 CleanupStack::PushL(sha); |
|
870 |
|
871 VectorTestL(sha,_L("sha1.dat")); |
|
872 |
|
873 FunctionalityTestL(sha); |
|
874 |
|
875 OOMTestL(sha); |
|
876 |
|
877 CleanupStack::PopAndDestroy(sha); |
|
878 |
|
879 test.Next(_L("Fixed bugs Tests")); |
|
880 // Problem reported by Jal Panvel, 17-12-1999. |
|
881 // Report by email, CSHA1::Hash() returning zero length descriptor |
|
882 // |
|
883 // This was caused by failure to set internal hash descriptor length on setup, this |
|
884 // problem was present in all hashes except MD2 which set it up correctly. |
|
885 // Fixed 17-12-1999. |
|
886 |
|
887 sha=CSHA1::NewL(); |
|
888 CleanupStack::PushL(sha); |
|
889 TPtrC8 data(_L8("The quick brown fox jumped over the lazy dog")); |
|
890 TBuf8<128> hash; |
|
891 hash = sha->Hash(data); |
|
892 test(hash.Length() == sha->HashSize()); |
|
893 sha->Reset(); |
|
894 |
|
895 // Test for DEF001510 "TLS - Receives Disconnect Indication during hands..." |
|
896 CSHA1* testHasher = CSHA1::NewL(); |
|
897 CleanupStack::PushL(testHasher); |
|
898 TPtrC8 client(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A4")); |
|
899 TPtrC8 server(_L8("3E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8")); |
|
900 |
|
901 HBufC8* clientData = client.AllocLC(); |
|
902 HBufC8* serverData = server.AllocLC(); |
|
903 |
|
904 Hex(*clientData); |
|
905 Hex(*serverData); |
|
906 |
|
907 // Hash in 2 portions |
|
908 TBuf8<32> clientbuf; |
|
909 TBuf8<32> serverbuf; |
|
910 clientbuf = testHasher->Hash(*clientData); |
|
911 serverbuf = testHasher->Hash(*serverData); |
|
912 |
|
913 TBuf8<32> shabuf; |
|
914 shabuf.Copy(testHasher->Hash(TPtrC8(0,0))); |
|
915 testHasher->Reset(); |
|
916 |
|
917 // Now hash in one chunk |
|
918 TPtrC8 all(_L8("D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A43E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8")); |
|
919 HBufC8* allData = all.AllocLC(); |
|
920 Hex(*allData); |
|
921 |
|
922 TBuf8<32> allbuf; |
|
923 allbuf = testHasher->Hash(*allData); |
|
924 |
|
925 test(allbuf.Compare(shabuf)==0); |
|
926 CleanupStack::PopAndDestroy(4, testHasher); |
|
927 |
|
928 // Test hashing non-word aligned data - used to crash on arm |
|
929 TPtrC8 nonAlignedData = data.Mid(1); |
|
930 hash = sha->Final(nonAlignedData); |
|
931 test(hash.Length() == sha->HashSize()); |
|
932 sha->Reset(); |
|
933 |
|
934 // Test end |
|
935 HMACTestsL(sha,_L("hmacsha1.dat"), _L("sha1")); |
|
936 CleanupStack::PopAndDestroy(); // sha |
|
937 } |
|
938 |
|
939 void ExecuteHashTestsL(CMessageDigest* aMD, const TDesC& aVector, const TDesC& aHMACVector, const TDesC& aHashType) |
|
940 { |
|
941 VectorTestL(aMD, aVector); |
|
942 FunctionalityTestL(aMD); |
|
943 OOMTestL(aMD); |
|
944 aMD->Reset(); |
|
945 |
|
946 test.Next(_L("Fixed bugs Tests")); |
|
947 |
|
948 _LIT8(KTest1Data, "The quick brown fox jumped over the lazy dog"); |
|
949 TBuf8<KMaxHashSize> hash; |
|
950 hash = aMD->Hash(KTest1Data()); |
|
951 test(hash.Length() == aMD->HashSize()); |
|
952 aMD->Reset(); |
|
953 |
|
954 // Test for DEF001510 "TLS - Receives Disconnect Indication during hands..." |
|
955 _LIT8(KClientData, "D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A4"); |
|
956 _LIT8(KServerData, "3E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8"); |
|
957 |
|
958 HBufC8* clientData = KClientData().AllocLC(); |
|
959 HBufC8* serverData = KServerData().AllocLC(); |
|
960 |
|
961 Hex(*clientData); |
|
962 Hex(*serverData); |
|
963 |
|
964 // Hash in 2 portions |
|
965 aMD->Hash(*clientData); |
|
966 aMD->Hash(*serverData); |
|
967 |
|
968 CleanupStack::PopAndDestroy(2, clientData); |
|
969 |
|
970 TBuf8<KMaxHashSize> shabuf; |
|
971 shabuf.Copy(aMD->Hash(KNullDesC8())); |
|
972 aMD->Reset(); |
|
973 |
|
974 // Now hash in one chunk |
|
975 _LIT8(KAllData, "D652CA1A6154D8303C16C055E424A5ACF3EBAB94284CD9B05B85C0D0F0B8E7A43E3E56059EFEE4F8C5B05C76128C4C84916DF9E935510C3C063454856FF29FF8"); |
|
976 HBufC8* allData = KAllData().AllocLC(); |
|
977 Hex(*allData); |
|
978 |
|
979 TBuf8<KMaxHashSize> allbuf; |
|
980 allbuf = aMD->Hash(*allData); |
|
981 |
|
982 test(allbuf.Compare(shabuf)==0); |
|
983 CleanupStack::PopAndDestroy(allData); |
|
984 |
|
985 // Test hashing non-word aligned data - used to crash on arm |
|
986 TPtrC8 nonAlignedData = KTest1Data().Mid(1); |
|
987 hash = aMD->Final(nonAlignedData); |
|
988 test(hash.Length() == aMD->HashSize()); |
|
989 aMD->Reset(); |
|
990 |
|
991 // Test end |
|
992 HMACTestsL(aMD, aHMACVector, aHashType); |
|
993 } |
|
994 |
|
995 _LIT(K224Algo, "SHA-224.dat"); |
|
996 _LIT(K256Algo, "SHA-256.dat"); |
|
997 _LIT(K384Algo, "SHA-384.dat"); |
|
998 _LIT(K512Algo, "SHA-512.dat"); |
|
999 _LIT(K224Vector, "sha224.dat"); |
|
1000 _LIT(K256Vector, "sha256.dat"); |
|
1001 _LIT(K384Vector, "sha384.dat"); |
|
1002 _LIT(K512Vector, "sha512.dat"); |
|
1003 _LIT(K224HmacVector, "hmacsha224.dat"); |
|
1004 _LIT(K256HmacVector, "hmacsha256.dat"); |
|
1005 _LIT(K384HmacVector, "hmacsha384.dat"); |
|
1006 _LIT(K512HmacVector, "hmacsha512.dat"); |
|
1007 |
|
1008 const TDesC* gNames[] = |
|
1009 { |
|
1010 &K224Vector(), |
|
1011 &K224HmacVector(), |
|
1012 &K224Algo(), |
|
1013 &K256Vector(), |
|
1014 &K256HmacVector(), |
|
1015 &K256Algo(), |
|
1016 &K384Vector(), |
|
1017 &K384HmacVector(), |
|
1018 &K384Algo(), |
|
1019 &K512Vector(), |
|
1020 &K512HmacVector(), |
|
1021 &K512Algo(), |
|
1022 }; |
|
1023 |
|
1024 |
|
1025 void SHA2TestsL(CMessageDigest::THashId aHashId) |
|
1026 { |
|
1027 CMessageDigest* md = CMessageDigestFactory::NewDigestLC(aHashId); |
|
1028 TInt pos = aHashId - CMessageDigest::ESHA224; |
|
1029 pos *= 3; |
|
1030 ExecuteHashTestsL(md, *gNames[pos], *gNames[pos+1], *gNames[pos+2]); |
|
1031 CleanupStack::PopAndDestroy(md); |
|
1032 } |
|
1033 |
|
1034 void HashTests(void) |
|
1035 { |
|
1036 TInt32 testsFailed=0, testCount=0; |
|
1037 |
|
1038 test.Start(_L("SHA1 Tests")); |
|
1039 TRAPD(r, SHA1TestsL()); |
|
1040 ++testCount; |
|
1041 if (r!=KErrNone) |
|
1042 { |
|
1043 test.Printf(_L("\r\nSHA1 Tests failed error code = %d\r\n\r\n"),r); |
|
1044 ++testsFailed; |
|
1045 } |
|
1046 |
|
1047 test.Start(_L("SHA-224 Tests")); |
|
1048 TRAP(r, SHA2TestsL(CMessageDigest::ESHA224)); |
|
1049 ++testCount; |
|
1050 if (r!=KErrNone) |
|
1051 { |
|
1052 test.Printf(_L("\r\nSHA-224 Tests failed error code = %d\r\n\r\n"),r); |
|
1053 ++testsFailed; |
|
1054 } |
|
1055 |
|
1056 test.Start(_L("SHA-256 Tests")); |
|
1057 TRAP(r, SHA2TestsL(CMessageDigest::ESHA256)); |
|
1058 ++testCount; |
|
1059 if (r!=KErrNone) |
|
1060 { |
|
1061 test.Printf(_L("\r\nSHA-256 Tests failed error code = %d\r\n\r\n"),r); |
|
1062 ++testsFailed; |
|
1063 } |
|
1064 |
|
1065 test.Start(_L("SHA-384 Tests")); |
|
1066 TRAP(r, SHA2TestsL(CMessageDigest::ESHA384)); |
|
1067 ++testCount; |
|
1068 if (r!=KErrNone) |
|
1069 { |
|
1070 test.Printf(_L("\r\nSHA-384 Tests failed error code = %d\r\n\r\n"),r); |
|
1071 ++testsFailed; |
|
1072 } |
|
1073 |
|
1074 test.Start(_L("SHA-512 Tests")); |
|
1075 TRAP(r, SHA2TestsL(CMessageDigest::ESHA512)); |
|
1076 ++testCount; |
|
1077 if (r!=KErrNone) |
|
1078 { |
|
1079 test.Printf(_L("\r\nSHA-512 Tests failed error code = %d\r\n\r\n"),r); |
|
1080 ++testsFailed; |
|
1081 } |
|
1082 |
|
1083 test.Start(_L("MD5 Tests")); |
|
1084 TRAP(r, MD5TestsL()); |
|
1085 ++testCount; |
|
1086 if (r!=KErrNone) |
|
1087 { |
|
1088 test.Printf(_L("\r\nMD5 Tests failed error code = %d\r\n\r\n"),r); |
|
1089 ++testsFailed; |
|
1090 } |
|
1091 |
|
1092 test.Start(_L("MD2 Tests")); |
|
1093 TRAP(r, MD2TestsL()); |
|
1094 ++testCount; |
|
1095 if (r!=KErrNone) |
|
1096 { |
|
1097 test.Printf(_L("\r\nMD2 Tests failed error code = %d\r\n\r\n"),r); |
|
1098 ++testsFailed; |
|
1099 } |
|
1100 |
|
1101 //MD4 Message Digest Algorithm Tests |
|
1102 test.Start(_L("MD4 Tests")); |
|
1103 TRAP(r, MD4TestsL()); |
|
1104 ++testCount; |
|
1105 if (r!=KErrNone) |
|
1106 { |
|
1107 test.Printf(_L("\r\nMD4 Tests failed error code = %d\r\n\r\n"),r); |
|
1108 ++testsFailed; |
|
1109 } |
|
1110 |
|
1111 test.Printf(_L("\r\n%d tests failed out of %d \r\n"),testsFailed,testCount); |
|
1112 |
|
1113 |
|
1114 test(testsFailed==0); |
|
1115 } |
|
1116 |
|
1117 |
|
1118 GLDEF_C TInt E32Main(void) |
|
1119 |
|
1120 { |
|
1121 CTrapCleanup* cleanup; |
|
1122 cleanup=CTrapCleanup::New(); |
|
1123 |
|
1124 test.Start(_L("Hash Algorithm Tests")); |
|
1125 CTestConsole* con=NULL; |
|
1126 TRAPD(ret, con=CTestConsole::NewL(test.Console())); |
|
1127 if(ret != KErrNone) |
|
1128 { |
|
1129 return ret; |
|
1130 } |
|
1131 RFs fs; |
|
1132 |
|
1133 fs.Connect(); |
|
1134 RFile* file; |
|
1135 file=new (ELeave) RFile; |
|
1136 |
|
1137 TDriveUnit sysDrive (fs.GetSystemDrive()); |
|
1138 TDriveName driveName(sysDrive.Name()); |
|
1139 TBuf<24> hashLogFile (driveName); |
|
1140 hashLogFile.Append(_L("\\HashLog.txt")); |
|
1141 |
|
1142 file->Replace(fs,hashLogFile,EFileShareAny|EFileWrite); |
|
1143 con->SetLogFile(file); |
|
1144 |
|
1145 test.SetConsole(con); |
|
1146 __UHEAP_MARK; |
|
1147 HashTests(); |
|
1148 __UHEAP_MARKEND; |
|
1149 |
|
1150 test.End(); |
|
1151 test.Close(); |
|
1152 delete cleanup; |
|
1153 return(KErrNone); |
|
1154 } |