-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmd5.rex
1899 lines (1656 loc) · 89.7 KB
/
md5.rex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* REXX MD5 procedures and RfC examples (version 2.1), for future */
/* updates see <URL:http://purl.net/xyzzy/src/md5.cmd>. This is */
/* only the code and a test suite, copy wanted procedures to REXX */
/* scripts (e.g. <URL:http://purl.net/xyzzy/src/popstop.cmd>). */
/* -------------------------------------------------------------- */
/* Modifications in version 2.1: */
/* - ToDo: fix PHPASS(), add SUNMD5(), rename APR1() to BSDMD5() */
/* - Fixed stupid MF2B32() bug found by classic REXX-Regina 3.7 */
/* Modifications in version 2.0: */
/* - added 3 NIST NSRL tests <http://www.nsrl.nist.gov/testdata/> */
/* - RfC 2384 APOP erratum 2943 now enabled (verified after 1.9) */
/* Modifications in version 1.9: */
/* - added Solar Designer PHPASS(); disabled due to unclear bug */
/* - added five APR1() "MD5 crypt" tests from different sources */
/* - added historic RfC 2777 NomCom code variant, this allows to */
/* test fraction input in NOMCOM() with an RfC 2777 example */
/* - added IETF NomCom 2009, 2010, and 2011 selections (RfC 3797) */
/* - RfC 6331 moved RfC 2831 SASL DIGEST-MD5 to "historic": This */
/* move was announced in an MD5 test suite version before 1.2; */
/* it affects only procedure DIGEST(), not RfC 2617 AUTHTTP() */
/* Modifications in version 1.8: */
/* - check out RfC 6151 for updated MD5 security considerations */
/* - added "minimal" collision by Tao Xie and Dengguo Feng (2010, */
/* the one page PDF announcement uses a little endian notation) */
/* - added "web-safe base64" input, compare RfC 4648 erratum 2837 */
/* - Unpadded ("invalid") base64 input STILL not supported, but */
/* non-canonical input with correct padding as in 'YR==' works */
/* - NOMCOM (RfC 3797) alpha input STILL not tested */
/* - exit code 0 fixed, BAD <> 3 exit in version 1.7 was for 1.6 */
/* Modifications in version 1.7: */
/* - all expected errors eliminated (see below), all should PASS */
/* - four RfC errata for MD5 verified by the IESG in 2009...2010 */
/* RfC 2069 erratum 749 (code modified to use fixed MD5 value) */
/* RfC 4122 erratum 1352 \/ (code to demonstate these verified */
/* RfC 2938 erratum 1080 /\ errata removed in MD5 version 1.7) */
/* RfC 3920 erratum 1406 (editorial, no code in the test suite) */
/* - added NomCom 2008 example (was published as hot fix for 1.6) */
/* Modifications in versions 1.6: */
/* - added RfC 5034 POP3 DIGEST-MD5 example with RfC 2617 variant */
/* - added RfC 4122 UUID example (with a fix for erratum 1352) */
/* - added RfC 1910 example, very slow, disabled by IF 0 THEN ... */
/* Modifications in versions 1.5: */
/* - updated for RfC 5090 (fixed two RFC 4590 RADIUS examples) */
/* - added RfC 2617 AUTHTTP variant of RfC 2831 DIGEST procedure */
/* for different 'md5-sess' calculations, six new test cases. */
/* - replaced DIGEST by AUTHTTP for six 'md5-sess' SIP examples */
/* found in the (expired) I-D.smith-sipping-auth-examples-01. */
/* Minor modifications in version 1.3 and 1.4 */
/* - RfC 2938 erratum submitted, RfC 2069 erratum finally listed. */
/* - added NomCom 2007 example, allow 38 digits entropy in MD5 */
/* Features added in version 1.2: */
/* - MD5 code rewritten to allow incremental updates (streaming), */
/* bit strings are now also supported. Usage: */
/* hash = MD5( bytes ) ==> MD5 of an octet string */
/* ctxt = MD5( bytes, '' ) ==> init. new MD5 context */
/* ctxt = MD5( bytes, ctxt ) ==> update old MD5 context */
/* hash = MD5( /**/ , ctxt ) ==> finalize MD5 context */
/* hash = MD5( bytes, /**/, n ) ==> MD5 of n zero-fill bits */
/* ctxt = MD5( bytes, '' , n ) ==> init. MD5 bit context */
/* ctxt = MD5( bytes, ctxt, n ) ==> update MD5 bit context */
/* - pre v1.2 history removed */
/* - APR1 passwd, 2 tests copied from the OpenSSL 0.9.6m manual, */
/* 3rd test verified with a 'htpasswd' and an 'openssl passwd'. */
/* - added six SIP INVITE tests found in an old Internet Draft. */
/* - added seven B64 examples found in RfC 4648 (obsoleted 3548), */
/* fixed B64.I() bug for an empty input string. */
/* -------------------------------------------------------------- */
/* List of procedures: */
/* TEST procedure to display and count test case errors */
/* B64.I base64 decoder used in test suite; B64.I = B64 input */
/* B64.O base64 encoder used in test suite; B64.O = B64 output */
/* B64.W base64 encoder for "web-safe base64" (or "base64url") */
/* AUTHTTP HTTP Auth Digest (RfCs 2617 and 2069), HA2 simplified */
/* DIGEST obsolete SASL Digest-MD5 (RfC 2831), based on AUTHTTP */
/* NOMCOM Select M random candidates of N volunteers, RfC 3797 */
/* MF2B32 B32 encoded MD5 of media feature set, RfC 2938 */
/* APR1 BSD $1$ / Apache $apr1$ .htpasswd MD5 crypt() variant */
/* APR1.S pseudo-random SALT for APR1(), given as APR1.B() B64 */
/* APR1.B right to left B64 variant used by APR1() like crypt() */
/* PHPASS portable "private" PasswordHash.php, a.k.a. PHPass.pm */
/* EX1910 used to check the very slow HISTORIC RfC 1910 example */
/* UUID.3 RfC 4122 UUID version 3 (DNS, URL, OID, X.500 names) */
/* OTP one time password (hex.), RfCs 2243, 2289, and 2444 */
/* OTP.6 one time password (six words encoder used by clients) */
/* OTP.3 one time password (six words decoder used by servers) */
/* OTP.2 used by OTP.6 and OTP.3 (six words parity) */
/* OTP.1 used by OTP.6 and OTP.3 (six words dictionary) */
/* OTP.0 used by OTP.6 and in test suite */
/* CRAM Challenge-Response Authentication Mechanism, RfC 2195 */
/* HMAC Keyed-Hashing for Message Authentication, RfC 2104 */
/* MD5 Message Digest (RfC 1321) */
/* MD5.1 MD5 round 1 used by MD5 */
/* MD5.2 MD5 round 2 used by MD5 */
/* MD5.3 MD5 round 3 used by MD5 */
/* MD5.4 MD5 round 4 used by MD5 */
/* MD5.. MD5 round 1..4 common part */
/* -------------------------------------------------------------- */
/* REXX MD5 test suite : number of test cases and comment */
/* RfC 4648 base64 : 7, edit "if 0 then" to debug B64 stuff */
/* RfC 3548 base64 : 6, B64 examples in RfC 2440 (= 3548), */
/* RfC 1864 base64 : 2, B64 examples in RfC 1864 */
/* RfC 2195 base64 : 4, B64 examples in RfC 2195 */
/* web-safe base64 : 2, recycled RfC 2440 example for 4648 */
/* bad YR== base64 : 1, RfC 4648 implementation report test */
/* RfC 1321 MD5 : 7, simple interface MD5( string ) */
/* RfC 1939 APOP : 1, tests MD5( msgid || pass ) */
/* RfC 2384 POP URL : 1, reflects value in erratum 2943 */
/* USCYBERCOM : 1, easter egg in USCYBERCOM logo */
/* NIST NSRL KAT : 3, <http://www.nsrl.nist.gov/testdata/> */
/* RfC 2104 HMAC MD5 : 3, simple interface HMAC( key, string ) */
/* RfC 2202 HMAC MD5 : 4, test cases 4..7 (like RfC 2104 1..3) */
/* RfC 2195 AUTH : 1, simple test HMAC( pass, challenge ) */
/* RfC 2195 CRAM MD5 : 1, tests CRAM( user, pass, challenge ) */
/* I-D 2195bis : 4, ditto draft-ietf-sasl-crammd5 */
/* MD5 collision : 2, 6 of 1024 bits modified (2004-08-19) */
/* Message collision : 2, 2 of 512 bits modified (2010-12-24) */
/* APR1 : 8, apache .htpasswd MD5 crypt() variant */
/* PHPASS : 2, PHP MD5 (disabled, doesn't work yet) */
/* RfC 1910 maplesyrup : 1, edit "if 0 then" for slow 1024*1024 */
/* RfC 2289 six words : 9, edit "if 0 then" to debug six words */
/* RfC 2289 OTP MD5 : 9, OTP( pass, seed, count ) and OTP.6() */
/* RfC 2243 OTP MD5 ext : 2, edit "if 0 then" for slow count 499 */
/* RfC 2444 OTP MD5 ext : 4, B64 tests of OTP( pass, seed, sequ ) */
/* RfC 2938 features : 3, three ok., known 4th erratum removed */
/* RfC 2777 NomCom : 1, "10 of 25", limit 255, test fraction */
/* RfC 3797 NomCom : 6, "10+1 of 25" plus 5 IETF 2007..2011 */
/* RfC 4122 UUID (v=3) : 3, three ok., known 4th erratum removed */
/* RfC 2069 http 1.0 : 1, fixed value for RfC 2069 erratum 749 */
/* RfC 2617 http 1.1 : 1, MD5 digest (qop=auth) */
/* RfC 2831 Digest-MD5 : 4, response + rspauth IMAP + ACAP */
/* RfC 4643 NNTPAUTH : 2, response + rspauth NNTP (auth-conf) */
/* RfC 5034 Digest-MD5 : 4, response + rspauth POP3 */
/* RfC 5090 RADIUS : 4, response + rspauth RADIUS */
/* I-D.smith-sipping : 6, draft smith-sipping-auth-examples-01 */
/* 3.1 qop missing => RfC 2069 fallback */
/* 3.2 qop=auth, alg missing => MD5 */
/* 3.3 qop=auth, alg=MD5 */
/* 3.4 qop=auth, alg=MD5-sess (2617) */
/* 3.5 qop=auth-int, alg=MD5 */
/* 3.6 qop=auth-int, alg=MD5-sess (2617) */
/* RfC 2831 Digest-MD5 : 4, modified for RfC 2617 erratum */
/* RfC 4643 NNTPAUTH : 2, modified for RfC 2617 erratum */
/* RfC 5034 Digest-MD5 : 2, modified for RfC 2617 erratum */
signal on novalue
BAD = 0 ; VERSION = 2.1
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
if 1 then do /* optional base64 sanity tests: */
X = '' ; Y = '' /* RfC 4648 1st example */
BAD = BAD + TEST( B64.O( X ), Y, '4648 encoded empty base64' )
BAD = BAD + TEST( B64.I( Y ), X, '4648 decoded empty base64' )
X = 'f' ; Y = 'Zg==' /* RfC 4648 2nd example */
BAD = BAD + TEST( B64.O( X ), Y, '4648 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '4648 decoded base64' Y )
X = 'fo' ; Y = 'Zm8=' /* RfC 4648 3rd example */
BAD = BAD + TEST( B64.O( X ), Y, '4648 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '4648 decoded base64' Y )
X = 'foo' ; Y = 'Zm9v' /* RfC 4648 4th example */
BAD = BAD + TEST( B64.O( X ), Y, '4648 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '4648 decoded base64' Y )
X = 'foob' ; Y = 'Zm9vYg==' /* RfC 4648 5th example */
BAD = BAD + TEST( B64.O( X ), Y, '4648 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '4648 decoded base64' Y )
X = 'fooba' ; Y = 'Zm9vYmE=' /* RfC 4648 6th example */
BAD = BAD + TEST( B64.O( X ), Y, '4648 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '4648 decoded base64' Y )
X = 'foobar' ; Y = 'Zm9vYmFy' /* RfC 4648 7th example */
BAD = BAD + TEST( B64.O( X ), Y, '4648 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '4648 decoded base64' Y )
K = '14fb9c03d97e' /* RfC 3548 / 2440 (1st example) */
Y = 'FPucA9l+' ; X = x2c( K ) ; K = '0x' || K
BAD = BAD + TEST( B64.O( X ), Y, '3548 encoded base64' K )
BAD = BAD + TEST( B64.I( Y ), X, '3548 decoded base64' K )
K = '14fb9c03d9' /* RfC 3548 / 2440 (2nd example) */
Y = 'FPucA9k=' ; X = x2c( K ) ; K = '0x' || K
BAD = BAD + TEST( B64.O( X ), Y, '3548 encoded base64' K )
BAD = BAD + TEST( B64.I( Y ), X, '3548 decoded base64' K )
K = '14fb9c03' /* RfC 3548 / 2440 (3rd example) */
Y = 'FPucAw==' ; X = x2c( K ) ; K = '0x' || K
BAD = BAD + TEST( B64.O( X ), Y, '3548 encoded base64' K )
BAD = BAD + TEST( B64.I( Y ), X, '3548 decoded base64' K )
X = 'Check Integrity!' ; Y = 'Q2hlY2sgSW50ZWdyaXR5IQ=='
BAD = BAD + TEST( B64.O( X ), Y, '1864 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '1864 decoded base64' X )
X = '<1896.697170952@postoffice.reston.mci.net>'
Y = 'PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+'
BAD = BAD + TEST( B64.O( X ), Y, '2195 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '2195 decoded base64' X )
X = 'tim b913a602c7eda7a495b4e6e7334d3890'
Y = 'dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw'
BAD = BAD + TEST( B64.O( X ), Y, '2195 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '2195 decoded base64' X )
K = '14fb9c03d97e' /* modified RfC 3548 "web-safe": */
Y = 'FPucA9l-' ; X = x2c( K ) ; K = '0x' || K
BAD = BAD + TEST( B64.W( X ), Y, 'encoded web-safe base64' K )
BAD = BAD + TEST( B64.I( Y ), X, 'decoded web-safe base64' K )
X = 'a' /* a bad encoding of 'a': 'YQ==' */
Y = 'YR==' ; K = 'vs. canonical' B64.O( X )
BAD = BAD + TEST( B64.I( Y ), X, '4648 test of base64' Y K )
end
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
X = '' /* RfC 1321 test suite example 1 */
Y = 'd41d8cd98f00b204e9800998ecf8427e'
BAD = BAD + TEST( MD5( X ), Y, '1321 empty' )
X = 'a' /* RfC 1321 test suite example 2 */
Y = '0cc175b9c0f1b6a831c399e269772661'
BAD = BAD + TEST( MD5( X ), Y, '1321' X )
X = 'abc' /* RfC 1321 test suite example 3 */
Y = '900150983cd24fb0d6963f7d28e17f72'
BAD = BAD + TEST( MD5( X ), Y, '1321' X )
X = 'message digest' /* RfC 1321 test suite example 4 */
Y = 'f96b697d7cb7938d525a2f31aaf161d0'
BAD = BAD + TEST( MD5( X ), Y, '1321' X )
X = 'abcdefghijklmnopqrstuvwxyz'
Y = 'c3fcd3d76192e4007dfb496cca67e13b'
BAD = BAD + TEST( MD5( X ), Y, '1321' X )
X = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
X = X || '0123456789' /* RfC 1321 test suite example 6 */
Y = 'd174ab98d277d9f5a5611c2c9f419d9f'
BAD = BAD + TEST( MD5( X ), Y, '1321 AB..Zab..z01..9' )
X = copies( '1234567890', 8 ) /* RfC 1321 test suite example 7 */
Y = '57edf4a22be3c955ac49da2e2107b67a'
BAD = BAD + TEST( MD5( X ), Y, '1321 8 * 1234567890' )
X = MD5( '123', '' ) ; X = MD5( copies( '4567890123', 7 ), X )
X = MD5( '4567890', X ) ; X = MD5( /**/, X )
BAD = BAD + TEST( X, Y, '1321 8 * 1234567890 streaming input' )
X = '<1896.697170952@dbc.mtview.ca.us>tanstaaf'
Y = 'c4c9334bac560ecc979e58001b3e22fb'
BAD = BAD + TEST( MD5( X ), Y, '1939 APOP' )
X = '<1896.697170952@mail.eudora.com>secret'
Y = '8f5de26536bc248ba202a9ca612e71bd'
BAD = BAD + TEST( MD5( X ), Y, '2384 APOP (erratum 2943)' )
X = MD5( '', '' ) /* get a new "empty" MD5 context */
X = MD5( 'USCYBERCOM plans, coordinates, integrates, synchr', X )
X = MD5( 'onizes and conducts activities to: direct the ope', X )
X = MD5( 'rations and defense of specified Department of De', X )
X = MD5( 'fense information networks and; prepare to, and w', X )
X = MD5( 'hen directed, conduct full spectrum military cybe', X )
X = MD5( 'rspace operations in order to enable actions in a', X )
X = MD5( 'll domains, ensure US/Allied freedom of action in', X )
X = MD5( ' cyberspace and deny the same to our adversaries.', X )
Y = '9ec4c12949a4f31474f299058ce2b22a'
K = 'USCYBERCOM mission statement (MD5 in logo)'
BAD = BAD + TEST( MD5( /* finalize MD5 context */, X ), Y, K )
X = 'abc' /* www.nsrl.nist.gov/testdata/ */
Y = '900150983cd24fb0d6963f7d28e17f72'
BAD = BAD + TEST( MD5( X ), Y, 'NIST NSRL Test Data (1 of 3)' )
X = 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'
Y = '8215ef0796a20bcaaae116d3876c664a'
BAD = BAD + TEST( MD5( X ), Y, 'NIST NSRL Test Data (2 of 3)' )
K = copies( 'a', 1000 ) /* split 1,000,000 lower case A: */
X = MD5( K, '' ) /* initial MD5 context: 1000 'a' */
do 999
X = MD5( K, X ) /* update context: 1000*1000 'a' */
end
X = MD5( /**/, X ) /* finalize MD5 of given context */
Y = '7707d6ae4e027c70eea2a935c2296f21'
BAD = BAD + TEST( X , Y, 'NIST NSRL Test Data (3 of 3)' )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
K = copies( '0B'x, 16 ) /* RfC 2104 / RFC 2202 example 1 */
X = 'Hi There'
Y = '9294727a3638bb1c13f48ef8158bfc9d'
BAD = BAD + TEST( HMAC( K, X ), Y, '2104' X )
K = 'Jefe' /* RfC 2104 / RFC 2202 example 2 */
X = 'what do ya want for nothing?'
Y = '750c783e6ab0b503eaa86e310a5db738'
BAD = BAD + TEST( HMAC( K, X ), Y, '2104' X )
K = copies( 'AA'x, 16 ) /* RfC 2104 / RFC 2202 example 3 */
X = copies( 'DD'x, 50 )
Y = '56be34521d144c88dbb8c733f0e8b3f6'
BAD = BAD + TEST( HMAC( K, X ), Y, '2104 16 * AA, 50 * DD' )
K = '0102030405060708090a0b0c0d0e0f10111213141516171819'x
X = copies( 'CD'x, 50 ) /* RfC 2202 test suite example 4 */
Y = '697eaf0aca3a3aea3a75164746ffaa79'
BAD = BAD + TEST( HMAC( K, X ), Y, '2202 HMAC-MD5 test 4' )
K = copies( '0C'x, 16 ) /* RfC 2202 test suite example 5 */
X = 'Test With Truncation' /* (trunc. to 96 bits not shown) */
Y = '56461ef2342edc00f9bab995690efd4c'
BAD = BAD + TEST( HMAC( K, X ), Y, '2202 HMAC-MD5 test 5' )
K = copies( 'AA'x, 80 ) /* RfC 2202 test suite example 6 */
X = 'Test Using Larger Than Block-Size Key - Hash Key First'
Y = '6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd'
BAD = BAD + TEST( HMAC( K, X ), Y, '2202 HMAC-MD5 test 6' )
K = copies( 'AA'x, 80 ) /* RfC 2202 test suite example 7 */
X = 'Test Using Larger Than Block-Size Key'
X = X 'and Larger Than One Block-Size Data'
Y = '6f630fad67cda0ee1fb1f562db3aa53e'
BAD = BAD + TEST( HMAC( K, X ), Y, '2202 HMAC-MD5 test 7' )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
K = 'tanstaaftanstaaf' /* RfC 2195 AUTH CRAM-MD5 detail */
X = '<1896.697170952@postoffice.reston.mci.net>'
Y = 'b913a602c7eda7a495b4e6e7334d3890'
BAD = BAD + TEST( HMAC( K, X ), Y, '2195 CRAM-MD5 details' )
USER = 'tim' /* RfC 2195 AUTH CRAM-MD5 (same */
PASS = 'tanstaaftanstaaf' /* example recycled in RfC 2595) */
X = '+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+'
Y = 'dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw'
BAD = BAD + TEST( CRAM( USER, PASS, X ), Y, '2195 CRAM-MD5 B64' )
USER = 'joe' /* 2195bis A.1.1 */
PASS = 'tanstaaftanstaaf'
X = '+ PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UuZXhhbXBsZS5uZXQ+'
Y = 'am9lIDNkYmM4OGYwNjI0Nzc2YTczN2IzOTA5M2Y2ZWI2NDI3'
BAD = BAD + TEST( CRAM( USER, PASS, X ), Y, 'I-D 2195bis A.1.1' )
USER = 'Ali Baba' /* 2195bis A.1.2 */
PASS = 'Open, Sesame'
X = B64.O( '<68451038525716401353.0@localhost>' )
Y = B64.O( USER '6fa32b6e768f073132588e3418e00f71' )
BAD = BAD + TEST( CRAM( USER, PASS, X ), Y, 'I-D 2195bis A.1.2' )
USER = 'Aladdin' || x2c( 'C2AE' )
PASS = 'Open, Sesame' /* 2195bis A.1.3, UTF-8 SASLprep */
X = B64.O( '<92230559549732219941.0@localhost>' )
Y = B64.O( USER '9950ea407844a71e2f0cd3284cbd912d' )
BAD = BAD + TEST( CRAM( USER, PASS, X ), Y, 'I-D 2195bis A.1.3' )
USER = 'joe' /* 2195bis A.2.1 */
PASS = 'tanstaaftanstaaf'
X = B64.O( '<2262304172.6455022@gw2.gestalt.entity.net>' )
Y = B64.O( USER '2aa383bf320a941d8209a7001ef6aeb6' )
BAD = BAD + TEST( CRAM( USER, PASS, X ), Y, 'I-D 2195bis A.2.1' )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
X = 'd1 31 dd 02 c5 e6 ee c4 69 3d 9a 06 98 af f9 5c'
X = X '2f ca b5 87 12 46 7e ab 40 04 58 3e b8 fb 7f 89'
X = X '55 ad 34 06 09 f4 b3 02 83 e4 88 83 25 71 41 5a'
X = X '08 51 25 e8 f7 cd c9 9f d9 1d bd f2 80 37 3c 5b'
X = X 'd8 82 3e 31 56 34 8f 5b ae 6d ac d4 36 c9 19 c6'
X = X 'dd 53 e2 b4 87 da 03 fd 02 39 63 06 d2 48 cd a0'
X = X 'e9 9f 33 42 0f 57 7e e8 ce 54 b6 70 80 a8 0d 1e'
X = X 'c6 98 21 bc b6 a8 83 93 96 f9 65 2b 6f f7 2a 70'
C = x2c( X )
Y = '79054025255fb1a26e4bc422aef54eb4'
TXT = 'MD5 collision test, 6 of 1024 bits modified'
BAD = BAD + TEST( MD5( C ), Y, TXT '- see also at URL:' )
X = '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
X = X '00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00'
X = X '00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00'
X = X '00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00'
X = X '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
X = X '00 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00'
X = X '00 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00'
X = X '00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00'
C = bitxor( C, x2c( X )) /* toggle 6 bits of 1024 =16*8*8 */
TXT = 'www.rtfm.com/movabletype/archives/2004_08.html#001055'
BAD = BAD + TEST( MD5( C ), Y, '<http://' || TXT || '>' )
X = '0e 30 65 61 55 9a a7 87 d0 0b c6 f7 0b bd fe 34'
X = X '04 cf 03 65 9e 70 4f 85 34 c0 0f fb 65 9c 4c 87'
X = X '40 cc 94 2f eb 2d a1 15 a3 f4 15 5c bb 86 07 49'
X = X '73 86 65 6d 7d 1f 34 a4 20 59 d7 8f 5a 8d d1 ef'
C = x2c( X )
Y = 'cee9a457e790cf20d4bdaa6d69f01e41'
TXT = 'MD5 message collision, 2 of 512 bits modified'
BAD = BAD + TEST( MD5( C ), Y, TXT '(2010), see URL:' )
X = '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
X = X '00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 00'
X = X '00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00'
X = X '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
C = bitxor( C, x2c( X )) /* toggle 2 bits of 512 = 16*8*4 */
TXT = 'eprint.iacr.org/2010/643.pdf> (Tao Xie, Dengguo Feng)'
BAD = BAD + TEST( MD5( C ), Y, '<http://' || TXT )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
PASS = 'password' /* found in the `openssl passwd` */
MAGIC = '$1$' /* examples for option -1 (BSD) */
SALT = 'xxxxxxxx'
HASH = APR1( PASS, MAGIC, SALT )
Y = MAGIC || SALT || '$UYCIxa628.9qXjpQCjM4a.'
BAD = BAD + TEST( HASH, Y, 'APR1 test 1 of 8:' Y )
PASS = 'password' /* found in the `openssl passwd` */
MAGIC = '$apr1$' /* examples for option -apr1 */
SALT = 'xxxxxxxx'
HASH = APR1( PASS, MAGIC, SALT )
Y = MAGIC || SALT || '$dxHfLAsjHkDRmG83UXe8K0'
BAD = BAD + TEST( HASH, Y, 'APR1 test 2 of 8:' Y )
PASS = 'password' /* found in John's sample hashes */
MAGIC = '$1$' /* on http://openwall.info/wiki/ */
SALT = 'O3JMY.Tw'
HASH = APR1( PASS, MAGIC, SALT )
Y = MAGIC || SALT || '$AdLnLjQ/5jXF9.MTp3gHv/'
BAD = BAD + TEST( HASH, Y, 'APR1 test 3 of 8:' Y )
PASS = 'passphrase' /* found in cpan.org MD5Crypt.pm */
MAGIC = '$1$' /* - the author "zefram" states */
SALT = 'Vd3f8aG6' /* that MD5 crypt() is "baroque" */
HASH = APR1( PASS, MAGIC, SALT )
Y = MAGIC || SALT || '$GcsdF4YCXb0PM2UmXjIoI1'
BAD = BAD + TEST( HASH, Y, 'APR1 test 4 of 8:' Y )
PASS = 'GNU libc manual' /* GNU is Not Unix (recursively) */
MAGIC = '$1$'
SALT = '/iSaq7rB'
HASH = APR1( PASS, MAGIC, SALT )
Y = MAGIC || SALT || '$EoUw5jJPPvAPECNaaWzMK/'
BAD = BAD + TEST( HASH, Y, 'APR1 test 5 of 8:' Y )
PASS = 'rasmuslerdorf' /* PHP CRYPT_MD5 crypt() example */
MAGIC = '$1$'
SALT = 'rasmusle'
HASH = APR1( PASS, MAGIC, SALT )
Y = MAGIC || SALT || '$rISCgZzpwk3UhDidwXvin0'
BAD = BAD + TEST( HASH, Y, 'APR1 test 6 of 8:' Y )
PASS = 'password' /* Python passlib.hash.md5_crypt */
MAGIC = '$1$'
SALT = '3azHgidD'
HASH = APR1( PASS, MAGIC, SALT )
Y = MAGIC || SALT || '$SrJPt7B.9rekpmwJwtON31'
BAD = BAD + TEST( HASH, Y, 'APR1 test 7 of 8:' Y )
PASS = '0123456789-0123456789-0123456789-'
MAGIC = '$apr1$' /* length 33 test, verified with */
SALT = 'dz1.....' /* htpasswd and `openssl passwd` */
HASH = APR1( PASS, MAGIC, SALT )
Y = MAGIC || SALT || '$g7vOevi4RVgXbTai5Bo.g/'
BAD = BAD + TEST( HASH, Y, 'APR1 test 8 of 8:' Y )
if 0 then do /** disabled, does not yet work **/
PASS = 'test12345' /* PHP portable PasswordHash.php */
MAGIC = '$P$' /* published by "Solar Designer" */
COST = 11 /* 11th APR1.B() is expected '9' */
SALT = 'IQRaTwmf' /* 8 char.s SALT following $P$9 */
HASH = PHPASS( PASS, MAGIC, COST, SALT )
Y = left( APR1.B( d2c( COST )), 1 )
Y = MAGIC || Y || SALT || 'eRo7ud9Fh4E2PdI0S3r.L0'
BAD = BAD + TEST( HASH, Y, 'PasswordHash.php:' Y )
PASS = 'passphrase' /* in cpan.org/~zefram PHPass.pm */
MAGIC = '$P$' /* based on Solar Designer code */
COST = 10 /* 10th APR1.B() is expected '8' */
SALT = 'NaClNaCl' /* 8 char.s SALT following $P$8 */
HASH = PHPASS( PASS, MAGIC, COST, SALT )
Y = left( APR1.B( d2c( COST )), 1 )
Y = MAGIC || Y || SALT || 'ObRxTm/.EiiYN02xUeAQs/'
BAD = BAD + TEST( HASH, Y, 'ditto, PHPass.pm:' Y )
PASS = 'password' /* Python example found in */
MAGIC = '$P$' /* code.google.com/p/passlib */
COST = 10
SALT = 'ohUJ.1sd'
HASH = PHPASS( PASS, MAGIC, COST, SALT )
Y = left( APR1.B( d2c( COST )), 1 )
Y = MAGIC || Y || SALT || 'Fw09/bMaAQPTGDNi2BIUt1'
BAD = BAD + TEST( HASH, Y, 'ditto, PHPass.pm:' Y )
end /* ----------------------------- */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
if 0 then do /* disable slow RfC 1910 example */
X = EX1910( 'maplesyrup', x2c( d2x( 2, 24 )))
Y = '526f5eed9fcce26f8964c2930787d82b'
BAD = BAD + TEST( X, Y, '1910 maplesyrup' )
end
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
if 0 then do /* RfC 2289 Six-word parity test */
X = '85c43ee03857765b' /* lower case hex. and no spaces */
Y = 'FOWL KID MASH DEAD DUAL OAF'
BAD = BAD + TEST( OTP.0( X ), Y, '2289 encoded 6 words' X )
BAD = BAD + TEST( OTP.3( Y ), X, '2289 decoded 6 words' X )
X = '' /* expect empty for parity error */
Y = 'FOWL KID MASH DEAD DUAL NUT'
BAD = BAD + TEST( OTP.3( Y ), X, '2289 parity error in' Y )
Y = 'FOWL KID MASH DEAD DUAL O'
BAD = BAD + TEST( OTP.3( Y ), X, '2289 parity error in' Y )
Y = 'FOWL KID MASH DEAD DUAL OAK'
BAD = BAD + TEST( OTP.3( Y ), X, '2289 parity error in' Y )
PASS = 'Too_short' /* RfC 2289 invalid arguments */
SEED = 'iamvalid' /* length of PASS phrase < 10 */
RFC = '2289 verify' PASS SEED
BAD = BAD + TEST( OTP.6( PASS, SEED, 1 ), '', RFC )
PASS = 'A_Valid_Pass_Phrase'
SEED = 'Length_Okay' /* SEED must be alphanumeric */
RFC = '2289 verify' PASS SEED
BAD = BAD + TEST( OTP.6( PASS, SEED, 1 ), '', RFC )
SEED = 'LengthOfSeventeen' /* SEED length 1..16 characters */
RFC = '2289 verify' PASS SEED
BAD = BAD + TEST( OTP.6( PASS, SEED, 1 ), '', RFC )
SEED = 'A Seed' /* SEED must not contain spaces */
RFC = '2289 verify' PASS SEED
BAD = BAD + TEST( OTP.6( PASS, SEED, 1 ), '', RFC )
end
PASS = 'This is a test.' /* RfC 2289 test 1..3 hex:/word: */
SEED = 'TeSt'
X = 0 /* RfC 2289 test 1..3, 1st X= 0 */
Y = '9e876134d90499dd' /* lower case hex. and no spaces */
BAD = BAD + TEST( OTP( PASS, SEED, X ), Y, '2289 1 hex:' || Y )
Y = 'INCH SEA ANNE LONG AHEM TOUR'
BAD = BAD + TEST( OTP.6( PASS, SEED, X ), Y, '2289 word:' || Y )
X = 1 /* RfC 2289 test 1..3, 2nd X= 1 */
Y = '7965e05436f5029f'
BAD = BAD + TEST( OTP( PASS, SEED, X ), Y, '2289 2 hex:' || Y )
Y = 'EASE OIL FUM CURE AWRY AVIS'
BAD = BAD + TEST( OTP.6( PASS, SEED, X ), Y, '2289 word:' || Y )
X = 99 /* RfC 2289 test 1..3, 3rd X=99 */
Y = '50fe1962c4965880'
BAD = BAD + TEST( OTP( PASS, SEED, X ), Y, '2289 3 hex:' || Y )
Y = 'BAIL TUFT BITS GANG CHEF THY'
BAD = BAD + TEST( OTP.6( PASS, SEED, X ), Y, '2289 word:' || Y )
PASS = 'AbCdEfGhIjK' /* RfC 2289 test 4..6 hex:/word: */
SEED = 'alpha1'
X = 0 /* RfC 2289 test 4..6, 1st X= 0 */
Y = '87066dd9644bf206'
BAD = BAD + TEST( OTP( PASS, SEED, X ), Y, '2289 4 hex:' || Y )
Y = 'FULL PEW DOWN ONCE MORT ARC'
BAD = BAD + TEST( OTP.6( PASS, SEED, X ), Y, '2289 word:' || Y )
X = 1 /* RfC 2289 test 4..6, 2nd X= 1 */
Y = '7cd34c1040add14b'
BAD = BAD + TEST( OTP( PASS, SEED, X ), Y, '2289 5 hex:' || Y )
Y = 'FACT HOOF AT FIST SITE KENT'
BAD = BAD + TEST( OTP.6( PASS, SEED, X ), Y, '2289 word:' || Y )
X = 99 /* RfC 2289 test 4..6, 3rd X=99 */
Y = '5aa37a81f212146c'
BAD = BAD + TEST( OTP( PASS, SEED, X ), Y, '2289 6 hex:' || Y )
Y = 'BODE HOP JAKE STOW JUT RAP'
BAD = BAD + TEST( OTP.6( PASS, SEED, X ), Y, '2289 word:' || Y )
PASS = "OTP's are good" /* RfC 2289 test 7..9 hex:/word: */
SEED = 'correct'
X = 0 /* RfC 2289 test 7..9, 1st X= 0 */
Y = 'f205753943de4cf9'
BAD = BAD + TEST( OTP( PASS, SEED, X ), Y, '2289 7 hex:' || Y )
Y = 'ULAN NEW ARMY FUSE SUIT EYED'
BAD = BAD + TEST( OTP.6( PASS, SEED, X ), Y, '2289 word:' || Y )
X = 1 /* RfC 2289 test 7..9, 2nd X= 1 */
Y = 'ddcdac956f234937'
BAD = BAD + TEST( OTP( PASS, SEED, X ), Y, '2289 8 hex:' || Y )
Y = 'SKIM CULT LOB SLAM POE HOWL'
BAD = BAD + TEST( OTP.6( PASS, SEED, X ), Y, '2289 word:' || Y )
X = 99 /* RfC 2289 test 7..9, 3rd X=99 */
Y = 'b203e28fa525be47'
BAD = BAD + TEST( OTP( PASS, SEED, X ), Y, '2289 9 hex:' || Y )
Y = 'LONG IVY JULY AJAR BOND LEE'
BAD = BAD + TEST( OTP.6( PASS, SEED, X ), Y, '2289 word:' || Y )
if 1 then do /* RfC 2243 example, challenge */
PASS = 'This is a test.' /* was 'otp-md5 499 ke1234 ext' */
SEED = 'ke1234'
OLDX = 499 /* X = 499 MD5 iterations (slow) */
NEWS = 'ke1235'
NEWX = 499
Y = 'init-hex:5bf075d9959d036f'
Y = Y || ':md5' NEWX NEWS || ':3712dcb4aa5316c1'
INIT = OTP( PASS, SEED, OLDX ) || ':md5' NEWX NEWS || ':'
INIT = 'init-hex:' || INIT || OTP( PASS, NEWS, NEWX )
BAD = BAD + TEST( INIT, Y, '2243' Y )
Y = 'init-word:BOND FOGY DRAB NE RISE MART'
Y = Y || ':md5' NEWX NEWS || ':RED HERD NOW BEAN PA BURG'
INIT = OTP.6( PASS, SEED, OLDX ) || ':md5' NEWX NEWS || ':'
INIT = 'init-word:' || INIT || OTP.6( PASS, NEWS, NEWX )
BAD = BAD + TEST( INIT, Y, '2243' left( Y, 53 ) '..' )
end
X = 'otp-md5 123 ke1234 ext' /* RfC 2444 OTP IMAP challenge */
Y = 'b3RwLW1kNSAxMjMga2UxMjM0IGV4dA=='
BAD = BAD + TEST( B64.O( X ), Y, '2444 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '2444 decoded base64' X )
parse var X . SEQU SEED .
PASS = 'this is a test'
X = 'hex:' || OTP( PASS, SEED, SEQU )
Y = 'aGV4OjExZDRjMTQ3ZTIyN2MxZjE='
BAD = BAD + TEST( B64.O( X ), Y, '2444 encoded base64' X )
BAD = BAD + TEST( B64.I( Y ), X, '2444 decoded base64' X )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
X = '(& (pix-x<=200) (pix-y<=150) )'
Y = '(h.SBB5REAOMHC09CP2GM4V07PQP0)'
BAD = BAD + TEST( MF2B32( X ), Y, '2938' Y )
Y = x2c( 0D0A ) /* RfC 2938 3rd example (ch. 4) */
X = '(& (image-file-structure=TIFF-minimal) ' Y
X = X ' (MRC-mode=0) ' Y
X = X ' (color=Binary) ' Y
X = X ' (image-coding=MH) (MRC-mode=0) ' Y
X = X ' (| (& (dpi=204) (dpi-xyratio=[204/98,204/196]) )' Y
X = X ' (& (dpi=200) (dpi-xyratio=[200/100,1]) ) ) ' Y
X = X ' (size-x<=2150/254) ' Y
X = X ' (paper-size=A4) ' Y
X = X ' (ua-media=stationery) ) ' Y
Y = '(h.MSB955PVIRT1QOHET9AJT5JM3O)'
BAD = BAD + TEST( MF2B32( X ), Y, '2938' Y )
Y = x2c( 0D0A ) /* RfC 2938 4th example (ch. 4) */
X = '(& (image-coding=JPEG) ' Y
X = X ' (image-coding-constraint=JPEG-T4E) ' Y
X = X ' (color-space=CIELAB) ' Y
X = X ' (color-illuminant=D50) ' Y
X = X ' (CIELAB-L-min>=0) ' Y
X = X ' (CIELAB-L-max<=100) ' Y
X = X ' (dpi=[100,200,300]) (dpi-xyratio=1) )' Y
Y = '(h.QVSEM8V2LMJ8VOR7V682J7079O)'
BAD = BAD + TEST( MF2B32( X ), Y, '2938' Y )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
S.1 = '9, 18, 26, 34, 41, 45' /* RfC 2777: six lottery numbers */
S.2 = '2, 5, 12, 8, 10' /* RfC 2777: five winning horses */
S.3 = '9319' /* RfC 2777: whole number input */
S.4 = '13.6875' /* RfC 2777: 13 11/16 as 13.6875 */
X = NOMCOM( -25, 10, S.1, S.2, S.3, S.4 )
Y = '12 6 8 3 2 24 11 19 15 22'
BAD = BAD + TEST( X, Y, '2777 NomCom' Y )
S.1 = '9319' /* 1st "raw" random input string */
S.2 = '2, 5, 12, 8, 10' /* 2nd "raw" input (CSV numbers) */
S.3 = '9, 18, 26, 34, 41, 45' /* 3rd "raw" input (CSV numbers) */
X = NOMCOM( 25, 11, S.1, S.2, S.3 )
Y = '17 7 2 16 25 23 8 24 19 13 22'
BAD = BAD + TEST( X, Y, '3797 NomCom' Y )
S.1 = '9 13 15 31 48 3 6' ; S.2 = '61636147'
S.4 = '7 39 41 48 53 21' ; S.3 = '95231775'
X = NOMCOM( 108, 20, S.1, S.2, S.3, S.4 )
Y = '57 12 105 5 11 18 99 93 43 102'
Y = Y '40 14 84 28 79 60 72 75 78 89'
BAD = BAD + TEST( X, Y, '3797 NomCom 2007' )
S.1 = '02 20 25 37 39 05 08' ; S.2 = '42831475'
S.4 = '21 25 26 50 51 22' ; S.3 = '14964684'
X = NOMCOM( 99, 15, S.1, S.2, S.3, S.4 )
Y = '91 38 36 94 52 33 84 1 53 34 86 29 81 78 89'
BAD = BAD + TEST( X, Y, '3797 NomCom 2008' )
S.1 = '5 8 10 29 39 41 15' ; S.2 = '05260357'
S.4 = '20 29 35 45 53 41' ; S.3 = '81433717'
X = NOMCOM( 93, 15, S.1, S.2, S.3, S.4 )
Y = '43 83 27 15 10 26 88 60 31 28 16 84 54 20 72'
BAD = BAD + TEST( X, Y, '3797 NomCom 2009' )
S.1 = '01 08 09 14 17 20 23' ; S.2 = '76998828'
S.4 = '20 21 23 38 42 6' ; S.3 = '79622755'
X = NOMCOM( 101, 15, S.1, S.2, S.3, S.4 )
Y = '87 25 14 46 79 31 75 91 47 23 16 60 92 89 19'
BAD = BAD + TEST( X, Y, '3797 NomCom 2010' )
S.1 = '02 12 23 35 39 49 44' ; S.2 = '43838132'
S.4 = '06 26 33 34 39 03 04' ; S.3 = '43531153'
X = NOMCOM( 120, 15, S.1, S.2, S.3, S.4 )
Y = '118 35 100 44 84 92 1 99 108 76 58 104 54 97 90'
BAD = BAD + TEST( X, Y, '3797 NomCom 2011' )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
X = UUID.3( 'DNS', 'www.widgets.com', 'bypass RfC 4122 erratum' )
Y = 'urn:uuid:e902893a-9d22-3c7e-a7b8-d6e313b71d9f'
BAD = BAD + TEST( X, Y, '4122' Y )
X = UUID.3( 'DNS', 'python.org' )
Y = 'urn:uuid:6fa459ea-ee8a-3ca4-894e-db77e160355e'
BAD = BAD + TEST( X, Y, '4122 UUID for python.org' )
X = UUID.3( 'URL', 'http://www.ossp.org/' )
Y = 'urn:uuid:02d9e6d5-9467-382e-8f9b-9300a64ac3cd'
BAD = BAD + TEST( X, Y, '4122 UUID for http://www.ossp.org/' )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
USER = 'Mufasa' /* RfC 2069 example (has no qop) */
PASS = 'CircleOfLife' /* This is a FIXED version based */
REALM = 'testrealm@host.com' /* on RfC 2069 erratum 749 (NEW) */
NONCE = 'dcd98b7102dd2f0e8b11d0f600bfb0c093'
URI = '/dir/index.html'
ALG = 'MD5' /* can be also omitted for 2069 */
X = 'GET:' || URI /* HTTP access method for 2069 */
X = DIGEST( USER, PASS, REALM, NONCE, /**/, /**/, /**/, X, ALG )
Y = 'e966c932a9242554e42c8ee200cec7f6' /* OLD - expect FAIL */
Y = '1949323746fe6a43ef61f9606e7febea' /* NEW - expect PASS */
BAD = BAD + TEST( X, Y, '2069 erratum 749 authorization' )
USER = 'Mufasa' /* RfC 2617 qop=auth example */
PASS = 'Circle Of Life'
REALM = 'testrealm@host.com'
NONCE = 'dcd98b7102dd2f0e8b11d0f600bfb0c093'
CNONCE = '0a4f113b'
NC = 1
QOP = 'auth'
URI = '/dir/index.html'
ALG = 'md5'
X = 'GET:' || URI /* HTTP access method for 2617 */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '6629fae49393a05397450978507c4ef1'
BAD = BAD + TEST( X, Y, '2617 HTTP/1.1 qop=auth' )
USER = 'chris' /* RfC 2831 IMAP example */
PASS = 'secret' /* (B64 output format not shown) */
REALM = 'elwood.innosoft.com'
NONCE = 'OA6MG9tEQGm2hh'
CNONCE = 'OA6MHXh6VqTrRk'
NC = 1
QOP = 'auth'
URI = 'imap/elwood.innosoft.com'
ALG = 'md5-sess'
X = 'AUTHENTICATE:' || URI /* 2831 AUTHENTICATE:digest-uri */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'd388dad90d4bbd760a152321f2143af7'
BAD = BAD + TEST( X, Y, '2831 IMAP example' )
X = ':' || URI /* 2831 rspauth for IMAP example */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'ea40f60335c427b5527b84dbabcdfffd'
BAD = BAD + TEST( X, Y, '2831 IMAP rspauth' )
NONCE = 'OA9BSXrbuRhWay' /* RfC 2831 ACAP example */
CNONCE = 'OA9BSuZWMSpW8m' /* (other values as shown above) */
URI = 'acap/elwood.innosoft.com'
X = 'AUTHENTICATE:' || URI /* 2831 AUTHENTICATE:digest-uri */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '6084c6db3fede7352c551284490fd0fc'
BAD = BAD + TEST( X, Y, '2831 ACAP example' )
X = ':' || URI /* 2831 rspauth for ACAP example */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '2f0b3d7c3c2e486600ef710726aa2eae'
BAD = BAD + TEST( X, Y, '2831 ACAP rspauth' )
USER = 'test' /* NNTPAUTH example in RfC 4643 */
PASS = 'test' /* (B64 encoding not shown here) */
REALM = 'eagle.oceana.com'
NONCE = 'sayAOhCEKGIdPMHC0wtleLqOIcOI2wQYIe4zzeAtuiQ='
CNONCE = '0Y3JQV2Tg9ScDip+O1SVC0rhVg//+dnOIiGz/7CeNJ8='
NC = 1
QOP = 'auth-conf' /* auth-conf dummy hash 32 zeros */
URI = 'nntp/localhost' || ':' || d2x( 0, 32 )
ALG = 'md5-sess'
X = 'AUTHENTICATE:' || URI /* NNTP AUTHENTICATE:digest-uri */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'd43cf66cffa903f9eb0356c08a3db0f2'
BAD = BAD + TEST( X, Y, '4643 NNTPAUTH example' )
X = ':' || URI /* NNTP rspauth in 283 parameter */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'de2e127e5a81cda53d97acda35cde83a'
BAD = BAD + TEST( X, Y, '4643 NNTPAUTH rspauth' )
USER = 'chris' /* RfC 5034 POP3 example */
PASS = 'secret' /* B64 input + output not shown */
REALM = 'elwood.innosoft.com'
NONCE = 'OA6MG9tEQGm2hh'
CNONCE = 'OA6MHXh6VqTrRk'
NC = 1
QOP = 'auth'
URI = 'pop/elwood.innosoft.com'
ALG = 'md5-sess'
X = 'AUTHENTICATE:' || URI /* 5034 AUTHENTICATE:digest-uri */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'b0d56d2f054c24b62072322106468db9'
BAD = BAD + TEST( X, Y, '5034 POP3 example' )
X = ':' || URI /* 5034 rspauth for POP3 example */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '0b971462cef5e8f930db9a33b02fc9a0'
BAD = BAD + TEST( X, Y, '5034 POP3 rspauth' )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
USER = '12345678' /* RfC 5090 fixed 4590 example 1 */
PASS = 'secret'
REALM = 'example.com'
NONCE = '3bada1a0'
CNONCE = '56593a80'
NC = 1
QOP = 'auth'
URI = 'sip:97226491335@example.com'
ALG = 'md5'
X = 'INVITE:' || URI /* RADIUS example SIP/2.0 INVITE */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '756933f735fcd93f90a4bbdd5467f263'
BAD = BAD + TEST( X, Y, 'RfC 5090 RADIUS INVITE' )
X = ':' || URI /* RADIUS Access-Accept rspauth */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'f847de948d12285f8f4199e366f1af21'
BAD = BAD + TEST( X, Y, 'RfC 5090 RADIUS rspauth' )
USER = '12345678' /* RfC 5090 fixes 4590 example 2 */
PASS = 'secret'
REALM = 'example.com'
NONCE = 'a3086ac8'
CNONCE = '56593a80'
NC = 1
QOP = 'auth'
URI = '/index.html'
ALG = 'MD5'
X = 'GET:' || URI /* RADIUS example HTTP/1.1 GET */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'a4fac45c27a30f4f244c54a2e99fa117'
BAD = BAD + TEST( X, Y, 'RfC 5090 RADIUS GET' )
X = ':' || URI /* RADIUS Access-Accept rspauth */
X = DIGEST( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '08c4e942d1d0a191de8b3aa98cd35147'
BAD = BAD + TEST( X, Y, 'RfC 5090 RADIUS rspauth' )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
USER = 'bob' /* RfC 3261 SIP INVITE, in draft */
REALM = 'biloxi.com' /* -smith-sipping-auth-examples, */
PASS = 'zanzibar' /* I-D password known to be okay */
NONCE = 'dcd98b7102dd2f0e8b11d0f600bfb0c093'
CNONCE = '0a4f113b'
NC = 1
URI = 'sip:bob@biloxi.com'
X = 'INVITE:' || URI /* I-D.smith 3.1.2, QOP omitted: */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, /* QOP */, X )
Y = 'bf57e4e0d0bffc0fbaedce64d59add5e'
BAD = BAD + TEST( X, Y, 'I-D.smith-sipping-auth-examples 3.1.2' )
QOP = 'auth'
X = 'INVITE:' || URI /* I-D.smith 3.2.2 uses QOP=auth */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, /**/ )
Y = '89eb0059246c02b2f6ee02c7961d5ea3'
BAD = BAD + TEST( X, Y, 'I-D.smith-sipping-auth-examples 3.2.2' )
ALG = 'MD5' /* I-D.smith 3.3.2 uses ALG=MD5, */
X = 'INVITE:' || URI /* as expected the same result */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
BAD = BAD + TEST( X, Y, 'I-D.smith-sipping-auth-examples 3.3.2' )
ALG = 'MD5-sess' /* I-D.smith 3.4.2, ALG=MD5-sess */
X = 'INVITE:' || URI /* okay based on RfC 2617 errata */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'e4e4ea61d186d07a92c9e1f6919902e9'
BAD = BAD + TEST( X, Y, 'I-D.smith-sipping-auth-examples 3.4.2' )
ALG = 'MD5' /* I-D.smith 3.5.2, QOP=auth-int */
QOP = 'auth-int' /* H(entity-body) added directly */
X = 'INVITE:' || URI || ':c1ed018b8ec4a3b170c0921f5b564e48'
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'bdbeebb2da6adb6bca02599c2239e192'
BAD = BAD + TEST( X, Y, 'I-D.smith-sipping-auth-examples 3.5.2' )
ALG = 'MD5-sess' /* I-D.smith 3.6.2, QOP=auth-int */
QOP = 'auth-int' /* okay based on RfC 2617 errata */
X = 'INVITE:' || URI || ':c1ed018b8ec4a3b170c0921f5b564e48'
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '91984da2d8663716e91554859c22ca70'
BAD = BAD + TEST( X, Y, 'I-D.smith-sipping-auth-examples 3.6.2' )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
USER = 'chris' /* compare RfC 2831 IMAP example */
PASS = 'secret' /* modified for RfC 2617 erratum */
REALM = 'elwood.innosoft.com'
NONCE = 'OA6MG9tEQGm2hh'
CNONCE = 'OA6MHXh6VqTrRk'
NC = 1
QOP = 'auth'
URI = 'imap/elwood.innosoft.com'
ALG = 'md5-sess'
X = 'AUTHENTICATE:' || URI /* 2831 AUTHENTICATE:digest-uri */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '26ef1190b643a36e879673066098379c'
BAD = BAD + TEST( X, Y, '2831 IMAP example (RfC 2617 md5-sess)' )
X = ':' || URI /* 2831 rspauth for IMAP example */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'c316c87a595a2cbfb4405784db016e34'
BAD = BAD + TEST( X, Y, '2831 IMAP rspauth (RfC 2617 md5-sess)' )
NONCE = 'OA9BSXrbuRhWay' /* compare RfC 2831 ACAP example */
CNONCE = 'OA9BSuZWMSpW8m' /* (other values as shown above) */
URI = 'acap/elwood.innosoft.com'
X = 'AUTHENTICATE:' || URI /* 2831 AUTHENTICATE:digest-uri */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '90771dc5643a801bb9a9bcbb1ed3cd34'
BAD = BAD + TEST( X, Y, '2831 ACAP example (RfC 2617 md5-sess)' )
X = ':' || URI /* 2831 rspauth for ACAP example */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'ec0700b2da00dd133bcb0c841f42d341'
BAD = BAD + TEST( X, Y, '2831 ACAP rspauth (RfC 2617 md5-sess)' )
USER = 'test' /* compare NNTPAUTH in RfC 4643, */
PASS = 'test' /* modified for RfC 2617 erratum */
REALM = 'eagle.oceana.com'
NONCE = 'sayAOhCEKGIdPMHC0wtleLqOIcOI2wQYIe4zzeAtuiQ='
CNONCE = '0Y3JQV2Tg9ScDip+O1SVC0rhVg//+dnOIiGz/7CeNJ8='
NC = 1
QOP = 'auth-conf' /* auth-conf dummy hash 32 zeros */
URI = 'nntp/localhost' || ':' || d2x( 0, 32 )
ALG = 'md5-sess'
X = 'AUTHENTICATE:' || URI /* NNTP AUTHENTICATE:digest-uri */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '41e814138958b1a0f08ef8b2dbe94ee9'
BAD = BAD + TEST( X, Y, '4643 example using RfC 2617 md5-sess' )
X = ':' || URI /* NNTP rspauth in 283 parameter */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '3f4d2b034c67c0c77df650f34ece6127'
BAD = BAD + TEST( X, Y, '4643 rspauth using RfC 2617 md5-sess' )
USER = 'chris' /* compare RfC 5034 POP3 example */
PASS = 'secret' /* modified for RfC 2617 erratum */
REALM = 'elwood.innosoft.com'
NONCE = 'OA6MG9tEQGm2hh'
CNONCE = 'OA6MHXh6VqTrRk'
NC = 1
QOP = 'auth'
URI = 'pop/elwood.innosoft.com'
ALG = 'md5-sess'
X = 'AUTHENTICATE:' || URI /* 5034 AUTHENTICATE:digest-uri */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = '089a19fffd2d75667e9d01583ee0fd58'
BAD = BAD + TEST( X, Y, '5034 POP3 example (RfC 2617 md5-sess)' )
X = ':' || URI /* 5034 rspauth for POP3 example */
X = AUTHTTP( USER, PASS, REALM, NONCE, CNONCE, NC, QOP, X, ALG )
Y = 'bb52468bdaadaac994e05c3958c71a09'
BAD = BAD + TEST( X, Y, '5034 POP3 rspauth (RfC 2617 md5-sess)' )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
say BAD 'error(s); no error expected in MD5 test suite' VERSION
exit ( BAD <> 0 )
/* -------------------------------------------------------------- */
TEST : procedure /* TEST( got, want, rfc text ) */
parse arg GOT, WANT, RFC TEXT
if datatype( RFC, 'w' ) then RFC = 'RfC' RFC
if GOT == WANT then do /* caller counts 1: bad, 0: okay */
say 'okay:' RFC TEXT ; return 0
end
say 'FAIL:' RFC TEXT ; say 'want:' WANT
say ' got:' GOT ; return 1
/* -------------------------------------------------------------- */
/* RfC 4648 base64 procedure B64.I() decodes and B64.O() encodes. */
/* B64.I() also supports "web-safe base64" input ('-_' for '+/'). */
/* B64.W() translates B64.O() to RfC 4648 "web-safe base64". */