tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

lowhashtest.c (18633B)


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