1 #include <stdio.h>
2 #include <string.h>
3 #include <assert.h>
4 
5 #include "nspr.h"
6 
7 /* nss headers */
8 #include "prtypes.h"
9 #include "plgetopt.h"
10 #include "hasht.h"
11 #include "nsslowhash.h"
12 #include "secport.h"
13 #include "hasht.h"
14 #include "basicutil.h"
15 
16 static char *progName = NULL;
17 
18 static int
test_long_message(NSSLOWInitContext * initCtx,HASH_HashType algoType,unsigned int hashLen,const PRUint8 expected[],PRUint8 results[])19 test_long_message(NSSLOWInitContext *initCtx,
20                   HASH_HashType algoType, unsigned int hashLen,
21                   const PRUint8 expected[], PRUint8 results[])
22 {
23     unsigned int len, i, rv = 0;
24     NSSLOWHASHContext *ctx;
25 
26     /* The message is meant to be 'a' repeated 1,000,000 times.
27      * This is too much to allocate on the stack so we will use a 1,000 char
28      * buffer and call update 1,000 times.
29      */
30     unsigned char buf[1000];
31     (void)PORT_Memset(buf, 'a', sizeof(buf));
32 
33     ctx = NSSLOWHASH_NewContext(initCtx, algoType);
34     if (ctx == NULL) {
35         SECU_PrintError(progName, "Couldn't get hash context\n");
36         return 1;
37     }
38 
39     NSSLOWHASH_Begin(ctx);
40     for (i = 0; i < 1000; ++i) {
41         NSSLOWHASH_Update(ctx, buf, 1000);
42     }
43 
44     NSSLOWHASH_End(ctx, results, &len, hashLen);
45     PR_ASSERT(len == hashLen);
46     PR_ASSERT(PORT_Memcmp(expected, results, hashLen) == 0);
47     if (PORT_Memcmp(expected, results, len) != 0) {
48         SECU_PrintError(progName, "Hash mismatch\n");
49         SECU_PrintBuf(stdout, "Expected: ", expected, hashLen);
50         SECU_PrintBuf(stdout, "Actual:   ", results, len);
51         rv = 1;
52     }
53 
54     NSSLOWHASH_Destroy(ctx);
55     NSSLOW_Shutdown(initCtx);
56 
57     return rv;
58 }
59 
60 static int
test_long_message_sha1(NSSLOWInitContext * initCtx)61 test_long_message_sha1(NSSLOWInitContext *initCtx)
62 {
63     PRUint8 results[SHA1_LENGTH];
64     /* Test vector from FIPS 180-2: appendix B.3.  */
65 
66     /* 34aa973c d4c4daa4 f61eeb2b dbad2731 6534016f. */
67     static const PRUint8 expected[SHA256_LENGTH] =
68         { 0x34, 0xaa, 0x97, 0x3c, 0xd4, 0xc4, 0xda, 0xa4, 0xf6, 0x1e, 0xeb, 0x2b,
69           0xdb, 0xad, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6f };
70     unsigned char buf[1000];
71     (void)PORT_Memset(buf, 'a', sizeof(buf));
72     return test_long_message(initCtx, HASH_AlgSHA1,
73                              SHA1_LENGTH, &expected[0], results);
74 }
75 
76 static int
test_long_message_sha256(NSSLOWInitContext * initCtx)77 test_long_message_sha256(NSSLOWInitContext *initCtx)
78 {
79     PRUint8 results[SHA256_LENGTH];
80     /* cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0. */
81     static const PRUint8 expected[SHA256_LENGTH] =
82         { 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67,
83           0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 };
84     unsigned char buf[1000];
85     (void)PORT_Memset(buf, 'a', sizeof(buf));
86     return test_long_message(initCtx, HASH_AlgSHA256,
87                              SHA256_LENGTH, &expected[0], results);
88 }
89 
90 static int
test_long_message_sha384(NSSLOWInitContext * initCtx)91 test_long_message_sha384(NSSLOWInitContext *initCtx)
92 {
93     PRUint8 results[SHA384_LENGTH];
94     /* Test vector from FIPS 180-2: appendix B.3.  */
95     /*
96     9d0e1809716474cb
97     086e834e310a4a1c
98     ed149e9c00f24852
99     7972cec5704c2a5b
100     07b8b3dc38ecc4eb
101     ae97ddd87f3d8985.
102     */
103     static const PRUint8 expected[SHA384_LENGTH] =
104         { 0x9d, 0x0e, 0x18, 0x09, 0x71, 0x64, 0x74, 0xcb,
105           0x08, 0x6e, 0x83, 0x4e, 0x31, 0x0a, 0x4a, 0x1c,
106           0xed, 0x14, 0x9e, 0x9c, 0x00, 0xf2, 0x48, 0x52,
107           0x79, 0x72, 0xce, 0xc5, 0x70, 0x4c, 0x2a, 0x5b,
108           0x07, 0xb8, 0xb3, 0xdc, 0x38, 0xec, 0xc4, 0xeb,
109           0xae, 0x97, 0xdd, 0xd8, 0x7f, 0x3d, 0x89, 0x85 };
110     unsigned char buf[1000];
111     (void)PORT_Memset(buf, 'a', sizeof(buf));
112 
113     return test_long_message(initCtx, HASH_AlgSHA384,
114                              SHA384_LENGTH, &expected[0], results);
115 }
116 
117 static int
test_long_message_sha512(NSSLOWInitContext * initCtx)118 test_long_message_sha512(NSSLOWInitContext *initCtx)
119 {
120     PRUint8 results[SHA512_LENGTH];
121     /* Test vector from FIPS 180-2: appendix B.3.  */
122     static const PRUint8 expected[SHA512_LENGTH] =
123         { 0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64, 0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63,
124           0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28, 0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb,
125           0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a, 0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b,
126           0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e, 0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b };
127     unsigned char buf[1000];
128     (void)PORT_Memset(buf, 'a', sizeof(buf));
129 
130     return test_long_message(initCtx, HASH_AlgSHA512,
131                              SHA512_LENGTH, &expected[0], results);
132 }
133 
134 static int
testMessageDigest(NSSLOWInitContext * initCtx,HASH_HashType algoType,unsigned int hashLen,const unsigned char * message,const PRUint8 expected[],PRUint8 results[])135 testMessageDigest(NSSLOWInitContext *initCtx,
136                   HASH_HashType algoType, unsigned int hashLen,
137                   const unsigned char *message,
138                   const PRUint8 expected[], PRUint8 results[])
139 {
140     NSSLOWHASHContext *ctx;
141     unsigned int len;
142     int rv = 0;
143 
144     ctx = NSSLOWHASH_NewContext(initCtx, algoType);
145     if (ctx == NULL) {
146         SECU_PrintError(progName, "Couldn't get hash context\n");
147         return 1;
148     }
149 
150     NSSLOWHASH_Begin(ctx);
151     NSSLOWHASH_Update(ctx, message, PORT_Strlen((const char *)message));
152     NSSLOWHASH_End(ctx, results, &len, hashLen);
153     PR_ASSERT(len == hashLen);
154     PR_ASSERT(PORT_Memcmp(expected, results, len) == 0);
155 
156     if (PORT_Memcmp(expected, results, len) != 0) {
157         SECU_PrintError(progName, "Hash mismatch\n");
158         SECU_PrintBuf(stdout, "Expected: ", expected, hashLen);
159         SECU_PrintBuf(stdout, "Actual:   ", results, len);
160         rv = 1;
161     }
162 
163     NSSLOWHASH_Destroy(ctx);
164     NSSLOW_Shutdown(initCtx);
165 
166     return rv;
167 }
168 
169 static int
testMD5(NSSLOWInitContext * initCtx)170 testMD5(NSSLOWInitContext *initCtx)
171 {
172     /* test vectors that glibc, our API main client, uses */
173 
174     static const struct {
175         const unsigned char *input;
176         const PRUint8 result[MD5_LENGTH];
177     } md5tests[] = {
178         { (unsigned char *)"",
179           { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
180         { (unsigned char *)"a",
181           { 0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
182         { (unsigned char *)"abc",
183           { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
184         { (unsigned char *)"message digest",
185           { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
186         { (unsigned char *)"abcdefghijklmnopqrstuvwxyz",
187           { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
188         { (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
189           { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
190         { (unsigned char *)"123456789012345678901234567890123456789012345678901234567890"
191                            "12345678901234567890",
192           { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }
193     };
194     PRUint8 results[MD5_LENGTH];
195     int rv = 0, cnt, numTests;
196 
197     numTests = sizeof(md5tests) / sizeof(md5tests[0]);
198     for (cnt = 0; cnt < numTests; cnt++) {
199         rv += testMessageDigest(initCtx, HASH_AlgMD5, MD5_LENGTH,
200                                 (const unsigned char *)md5tests[cnt].input,
201                                 md5tests[cnt].result, &results[0]);
202     }
203     return rv;
204 }
205 
206 /*
207  * Tests with test vectors from FIPS 180-2 Appendixes B.1, B.2, B.3, C, and D
208  *
209  */
210 
211 static int
testSHA1(NSSLOWInitContext * initCtx)212 testSHA1(NSSLOWInitContext *initCtx)
213 {
214     static const struct {
215         const unsigned char *input;
216         const PRUint8 result[SHA1_LENGTH];
217     } sha1tests[] = {
218         /* one block messsage */
219         {
220             (const unsigned char *)"abc",
221             /* a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d. */
222 
223             { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,  /* a9993e36 4706816a */
224               0xba, 0x3e, 0x25, 0x71,                          /* ba3e2571 */
225               0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d } /* 7850c26c 9cd0d89d */
226         },
227         { (const unsigned char *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
228           /* 84983e44 1c3bd26e baae4aa1 f95129e5 e54670f1. */
229           { 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 0xba, 0xae, 0x4a, 0xa1,
230             0xf9, 0x51, 0x29, 0xe5, 0xe5, 0x46, 0x70, 0xf1 } }
231     };
232 
233     PRUint8 results[SHA1_LENGTH];
234     int rv = 0, cnt, numTests;
235 
236     numTests = sizeof(sha1tests) / sizeof(sha1tests[0]);
237     for (cnt = 0; cnt < numTests; cnt++) {
238         rv += testMessageDigest(initCtx, HASH_AlgSHA1, SHA1_LENGTH,
239                                 (const unsigned char *)sha1tests[cnt].input,
240                                 sha1tests[cnt].result, &results[0]);
241     }
242 
243     rv += test_long_message_sha1(initCtx);
244     return rv;
245 }
246 
247 static int
testSHA224(NSSLOWInitContext * initCtx)248 testSHA224(NSSLOWInitContext *initCtx)
249 {
250     static const struct {
251         const unsigned char *input;
252         const PRUint8 result[SHA224_LENGTH];
253     } sha224tests[] = {
254         /* one block messsage */
255         { (const unsigned char *)"abc",
256           { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3,
257             0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, 0xE3, 0x6C, 0x9D, 0xA7 } },
258         /* two block message */
259         { (const unsigned char *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
260           { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50,
261             0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, 0x52, 0x52, 0x25, 0x25 } }
262     };
263 
264     PRUint8 results[SHA224_LENGTH];
265     int rv = 0, cnt, numTests;
266 
267     numTests = sizeof(sha224tests) / sizeof(sha224tests[0]);
268     for (cnt = 0; cnt < numTests; cnt++) {
269         rv += testMessageDigest(initCtx, HASH_AlgSHA224, SHA224_LENGTH,
270                                 (const unsigned char *)sha224tests[cnt].input,
271                                 sha224tests[cnt].result, &results[0]);
272     }
273 
274     return rv;
275 }
276 
277 static int
testSHA256(NSSLOWInitContext * initCtx)278 testSHA256(NSSLOWInitContext *initCtx)
279 {
280     static const struct {
281         const unsigned char *input;
282         const PRUint8 result[SHA256_LENGTH];
283     } sha256tests[] = {
284         /* Test vectors from FIPS 180-2: appendix B.1.  */
285         { (unsigned char *)"abc",
286           { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
287             0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } },
288         /* Test vectors from FIPS 180-2: appendix B.2.  */
289         { (unsigned char *)"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
290           { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
291             0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } }
292     };
293 
294     PRUint8 results[SHA256_LENGTH];
295     int rv = 0, cnt, numTests;
296 
297     numTests = sizeof(sha256tests) / sizeof(sha256tests[0]);
298     for (cnt = 0; cnt < numTests; cnt++) {
299         rv += testMessageDigest(initCtx, HASH_AlgSHA256, SHA256_LENGTH,
300                                 (const unsigned char *)sha256tests[cnt].input,
301                                 sha256tests[cnt].result, &results[0]);
302     }
303 
304     rv += test_long_message_sha256(initCtx);
305     return rv;
306 }
307 
308 static int
testSHA384(NSSLOWInitContext * initCtx)309 testSHA384(NSSLOWInitContext *initCtx)
310 {
311     static const struct {
312         const unsigned char *input;
313         const PRUint8 result[SHA384_LENGTH];
314     } sha384tests[] = {
315         /* Test vector from FIPS 180-2: appendix D, single-block message.  */
316         { (unsigned char *)"abc",
317           { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
318             0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
319             0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
320             0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
321             0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
322             0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } },
323 
324         /* Test vectors from FIPS 180-2: appendix D, multi-block message.  */
325         { (unsigned char *)"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
326                            "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
327           /*
328         09330c33f71147e8
329         3d192fc782cd1b47
330         53111b173b3b05d2
331         2fa08086e3b0f712
332         fcc7c71a557e2db9
333         66c3e9fa91746039.
334         */
335           { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
336             0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
337             0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
338             0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
339             0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
340             0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } }
341     };
342 
343     PRUint8 results[SHA384_LENGTH];
344     int rv = 0, cnt, numTests;
345 
346     numTests = sizeof(sha384tests) / sizeof(sha384tests[0]);
347     for (cnt = 0; cnt < numTests; cnt++) {
348         rv += testMessageDigest(initCtx, HASH_AlgSHA384, SHA384_LENGTH,
349                                 (const unsigned char *)sha384tests[cnt].input,
350                                 sha384tests[cnt].result, &results[0]);
351     }
352     rv += test_long_message_sha384(initCtx);
353 
354     return rv;
355 }
356 
357 int
testSHA512(NSSLOWInitContext * initCtx)358 testSHA512(NSSLOWInitContext *initCtx)
359 {
360     static const struct {
361         const unsigned char *input;
362         const PRUint8 result[SHA512_LENGTH];
363     } sha512tests[] = {
364         /* Test vectors from FIPS 180-2: appendix C.1.  */
365         { (unsigned char *)"abc",
366           { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
367             0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
368             0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
369             0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f } },
370         /* Test vectors from FIPS 180-2: appendix C.2.  */
371         { (unsigned char *)"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
372                            "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
373           { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
374             0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
375             0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
376             0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 } }
377     };
378 
379     PRUint8 results[SHA512_LENGTH];
380     int rv = 0, cnt, numTests;
381 
382     numTests = sizeof(sha512tests) / sizeof(sha512tests[0]);
383     for (cnt = 0; cnt < numTests; cnt++) {
384         rv = testMessageDigest(initCtx, HASH_AlgSHA512, SHA512_LENGTH,
385                                (const unsigned char *)sha512tests[cnt].input,
386                                sha512tests[cnt].result, &results[0]);
387     }
388     rv += test_long_message_sha512(initCtx);
389     return rv;
390 }
391 
392 static void
Usage(char * progName)393 Usage(char *progName)
394 {
395     fprintf(stderr, "Usage: %s [algorithm]\n",
396             progName);
397     fprintf(stderr, "algorithm must be one of %s\n",
398             "{ MD5 | SHA1 | SHA224 | SHA256 | SHA384 | SHA512 }");
399     fprintf(stderr, "default is to test all\n");
400     exit(-1);
401 }
402 
403 int
main(int argc,char ** argv)404 main(int argc, char **argv)
405 {
406     NSSLOWInitContext *initCtx;
407     int rv = 0; /* counts the number of failures */
408 
409     progName = strrchr(argv[0], '/');
410     progName = progName ? progName + 1 : argv[0];
411 
412     initCtx = NSSLOW_Init();
413     if (initCtx == NULL) {
414         SECU_PrintError(progName, "Couldn't initialize for hashing\n");
415         return 1;
416     }
417 
418     if (argc || !argv[1] || strlen(argv[1]) == 0) {
419         rv += testMD5(initCtx);
420         rv += testSHA1(initCtx);
421         rv += testSHA224(initCtx);
422         rv += testSHA256(initCtx);
423         rv += testSHA384(initCtx);
424         rv += testSHA512(initCtx);
425     } else if (strcmp(argv[1], "MD5") == 0) {
426         rv += testMD5(initCtx);
427     } else if (strcmp(argv[1], "SHA1") == 0) {
428         rv += testSHA1(initCtx);
429     } else if (strcmp(argv[1], "SHA224") == 0) {
430         rv += testSHA224(initCtx);
431     } else if (strcmp(argv[1], "SHA226") == 0) {
432         rv += testSHA256(initCtx);
433     } else if (strcmp(argv[1], "SHA384") == 0) {
434         rv += testSHA384(initCtx);
435     } else if (strcmp(argv[1], "SHA512") == 0) {
436         rv += testSHA512(initCtx);
437     } else {
438         SECU_PrintError(progName, "Unsupported hash type %s\n", argv[0]);
439         Usage(progName);
440     }
441 
442     NSSLOW_Shutdown(initCtx);
443 
444     return (rv == 0) ? 0 : 1;
445 }
446