1 /* $Id: md5-t.c 9827 2015-04-23 14:50:38Z iulius $ */
2 /* MD5 hashing test suite. */
3 
4 #include "config.h"
5 #include "clibrary.h"
6 #include "inn/md5.h"
7 #include "inn/libinn.h"
8 #include "tap/basic.h"
9 
10 /* Used for strings of unsigned characters (called SUC instead of U
11    because it otherwise conflicts with Unicode strings). */
12 #define SUC       (const unsigned char *)
13 
14 /* An unsigned char version of strlen. */
15 #define ustrlen(s)      strlen((const char *) s)
16 
17 /* Used for converting digests to hex to make them easier to deal with. */
18 static const char hex[] = "0123456789abcdef";
19 
20 /* A set of data strings and resulting digests to check.  It's not easy to
21    get nulls into this data structure, so data containing nulls should be
22    checked separately. */
23 static const unsigned char * const testdata[] = {
24     /* First five tests of the MD5 test suite from RFC 1321. */
25     SUC"",
26     SUC"a",
27     SUC"abc",
28     SUC"message digest",
29     SUC"abcdefghijklmnopqrstuvwxyz",
30 
31     /* Three real message IDs to ensure compatibility with old INN versions;
32        the corresponding MD5 hashes were taken directly out of the history
33        file of a server running INN 2.3. */
34     SUC"<J3Ds5.931$Vg6.7556@news01.chello.no>",
35     SUC"<sr5v7ooea6e17@corp.supernews.com>",
36     SUC"<cancel.Y2Ds5.26391$oH5.540535@news-east.usenetserver.com>",
37 
38     /* Other random stuff, including high-bit characters. */
39     SUC"example.test",
40     SUC"||",
41     SUC"|||",
42     SUC"\375\277\277\277\277\276",
43     SUC"\377\277\277\277\277\277"
44 };
45 
46 /* The hashes corresonding to the above data. */
47 static const char * const testhash[] = {
48     "d41d8cd98f00b204e9800998ecf8427e",
49     "0cc175b9c0f1b6a831c399e269772661",
50     "900150983cd24fb0d6963f7d28e17f72",
51     "f96b697d7cb7938d525a2f31aaf161d0",
52     "c3fcd3d76192e4007dfb496cca67e13b",
53     "c4a70fb19af37bed6b7c77f1e1187f00",
54     "7f70531c7027c20b0ddba0a649cf8691",
55     "9d9f0423f38b731c9bf69607cea6be76",
56     "09952be409a7d6464cd7661beeeb966e",
57     "7d010443693eec253a121e2aa2ba177c",
58     "2edf2958166561c5c08cd228e53bbcdc",
59     "c18293a6fe0a09720e841c8ebc697b97",
60     "ce23eb027c63215b999b9f86d6a4f9cb"
61 };
62 
63 static void
digest2hex(const unsigned char * digest,char * result)64 digest2hex(const unsigned char *digest, char *result)
65 {
66     const unsigned char *p;
67     unsigned int i;
68 
69     for (p = digest, i = 0; i < 32; i += 2, p++) {
70         result[i] = hex[(*p & 0xf0) >> 4];
71         result[i + 1] = hex[*p & 0x0f];
72     }
73     result[32] = '\0';
74 }
75 
76 static void
test_md5(int n,const char * expected,const unsigned char * data,size_t length)77 test_md5(int n, const char *expected, const unsigned char *data,
78          size_t length)
79 {
80     unsigned char digest[16];
81     char hexdigest[33];
82 
83     md5_hash(data, length, digest);
84     digest2hex(digest, hexdigest);
85     ok_string(n, expected, hexdigest);
86 }
87 
88 int
main(void)89 main(void)
90 {
91     unsigned int i;
92     int j, n;
93     unsigned char *data;
94     struct md5_context context;
95     char hexdigest[33];
96 
97     test_init(12 + ARRAY_SIZE(testdata));
98 
99     test_md5(1, "93b885adfe0da089cdf634904fd59f71", SUC"\0", 1);
100     test_md5(2, "e94a053c3fbfcfb22b4debaa11af7718", SUC"\0ab\n", 4);
101 
102     data = xmalloc(64 * 1024);
103     memset(data, 0, 64 * 1024);
104     test_md5(3, "fcd6bcb56c1689fcef28b57c22475bad", data, 64 * 1024);
105     memset(data, 1, 32 * 1024);
106     test_md5(4, "3d8897b14254c9f86fbad3fe22f62edd", data, 64 * 1024);
107     test_md5(5, "25364962aa23b187942a24ae736c4e8c", data, 65000);
108     test_md5(6, "f9816b5d5363d15f14bb98d548309dcc", data, 55);
109     test_md5(7, "5e99dfddfb51c18cfc55911dee24ae7b", data, 56);
110     test_md5(8, "0871ffa021e2bc4da87eb93ac22d293c", data, 63);
111     test_md5(9, "784d68ba9112308689114a6816c628ce", data, 64);
112 
113     /* Check the individual functions. */
114     md5_init(&context);
115     md5_update(&context, data, 32 * 1024);
116     md5_update(&context, data + 32 * 1024, 32 * 1024 - 42);
117     md5_update(&context, data + 64 * 1024 - 42, 42);
118     md5_final(&context);
119     digest2hex(context.digest, hexdigest);
120     ok_string(10, "3d8897b14254c9f86fbad3fe22f62edd", hexdigest);
121 
122     /* Part of the MD5 test suite from RFC 1321. */
123     for (i = 0, n = 'A'; n <= 'Z'; i++, n++)
124         data[i] = n;
125     for (i = 26, n = 'a'; n <= 'z'; i++, n++)
126         data[i] = n;
127     for (i = 52, n = '0'; n <= '9'; i++, n++)
128         data[i] = n;
129     test_md5(11, "d174ab98d277d9f5a5611c2c9f419d9f", data, 62);
130     for (i = 0, j = 0; j < 8; j++) {
131         for (n = '1'; n <= '9'; i++, n++)
132             data[i] = n;
133         data[i++] = '0';
134     }
135     test_md5(12, "57edf4a22be3c955ac49da2e2107b67a", data, 80);
136 
137     n = 13;
138     for (i = 0; i < ARRAY_SIZE(testdata); i++)
139         test_md5(n++, testhash[i], testdata[i], ustrlen(testdata[i]));
140 
141     return 0;
142 }
143