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