tor-browser

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

sha512.c (49639B)


      1 /*
      2 * sha512.c - implementation of SHA224, SHA256, SHA384 and SHA512
      3 *
      4 * This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #ifdef FREEBL_NO_DEPEND
      9 #include "stubs.h"
     10 #endif
     11 
     12 #include "prcpucfg.h"
     13 #if defined(NSS_X86) || defined(SHA_NO_LONG_LONG)
     14 #define NOUNROLL512 1
     15 #undef HAVE_LONG_LONG
     16 #endif
     17 #include "prtypes.h" /* for PRUintXX */
     18 #include "prlong.h"
     19 #include "secport.h" /* for PORT_XXX */
     20 #include "blapi.h"
     21 #include "blapii.h"
     22 #include "secerr.h"
     23 #include "sha256.h" /* for struct SHA256ContextStr */
     24 #include "crypto_primitives.h"
     25 #include "ppc-crypto.h" /* for USE_PPC_CRYPTO */
     26 
     27 /* ============= Common constants and defines ======================= */
     28 
     29 #define W ctx->u.w
     30 #define B ctx->u.b
     31 #define H ctx->h
     32 
     33 #define SHR(x, n) (x >> n)
     34 #define SHL(x, n) (x << n)
     35 #define Ch(x, y, z) ((x & y) ^ (~x & z))
     36 #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
     37 #define SHA_MIN(a, b) (a < b ? a : b)
     38 
     39 /* Padding used with all flavors of SHA */
     40 static const PRUint8 pad[240] = {
     41    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     42    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
     43    /* compiler will fill the rest in with zeros */
     44 };
     45 
     46 /* ============= SHA256 implementation ================================== */
     47 
     48 /* SHA-256 constants, K256. */
     49 pre_align static const PRUint32 K256[64] post_align = {
     50    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
     51    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
     52    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
     53    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
     54    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
     55    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
     56    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
     57    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
     58    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
     59    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
     60    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
     61    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
     62    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
     63    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
     64    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
     65    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
     66 };
     67 
     68 /* SHA-256 initial hash values */
     69 static const PRUint32 H256[8] = {
     70    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
     71    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
     72 };
     73 
     74 #if defined(IS_LITTLE_ENDIAN)
     75 #if (_MSC_VER >= 1300)
     76 #include <stdlib.h>
     77 #pragma intrinsic(_byteswap_ulong)
     78 #define SHA_HTONL(x) _byteswap_ulong(x)
     79 #elif defined(_MSC_VER) && defined(NSS_X86_OR_X64)
     80 #ifndef FORCEINLINE
     81 #if (_MSC_VER >= 1200)
     82 #define FORCEINLINE __forceinline
     83 #else
     84 #define FORCEINLINE __inline
     85 #endif
     86 #endif
     87 #define FASTCALL __fastcall
     88 
     89 static FORCEINLINE PRUint32 FASTCALL
     90 swap4b(PRUint32 dwd)
     91 {
     92    __asm {
     93        mov   eax,dwd
     94    bswap eax
     95    }
     96 }
     97 
     98 #define SHA_HTONL(x) swap4b(x)
     99 
    100 #elif defined(__GNUC__) && defined(NSS_X86_OR_X64)
    101 static __inline__ PRUint32
    102 swap4b(PRUint32 value)
    103 {
    104    __asm__("bswap %0"
    105            : "+r"(value));
    106    return (value);
    107 }
    108 #define SHA_HTONL(x) swap4b(x)
    109 
    110 #elif defined(__GNUC__) && (defined(__thumb2__) ||         \
    111                            (!defined(__thumb__) &&        \
    112                             (defined(__ARM_ARCH_6__) ||   \
    113                              defined(__ARM_ARCH_6J__) ||  \
    114                              defined(__ARM_ARCH_6K__) ||  \
    115                              defined(__ARM_ARCH_6Z__) ||  \
    116                              defined(__ARM_ARCH_6ZK__) || \
    117                              defined(__ARM_ARCH_6T2__) || \
    118                              defined(__ARM_ARCH_7__) ||   \
    119                              defined(__ARM_ARCH_7A__) ||  \
    120                              defined(__ARM_ARCH_7R__))))
    121 static __inline__ PRUint32
    122 swap4b(PRUint32 value)
    123 {
    124    PRUint32 ret;
    125    __asm__("rev %0, %1"
    126            : "=r"(ret)
    127            : "r"(value));
    128    return ret;
    129 }
    130 #define SHA_HTONL(x) swap4b(x)
    131 
    132 #else
    133 #define SWAP4MASK 0x00FF00FF
    134 static PRUint32
    135 swap4b(PRUint32 value)
    136 {
    137    PRUint32 t1 = (value << 16) | (value >> 16);
    138    return ((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK);
    139 }
    140 #define SHA_HTONL(x) swap4b(x)
    141 #endif
    142 #define BYTESWAP4(x) x = SHA_HTONL(x)
    143 #endif /* defined(IS_LITTLE_ENDIAN) */
    144 
    145 #if defined(_MSC_VER)
    146 #pragma intrinsic(_lrotr, _lrotl)
    147 #define ROTR32(x, n) _lrotr(x, n)
    148 #define ROTL32(x, n) _lrotl(x, n)
    149 #else
    150 #define ROTR32(x, n) ((x >> n) | (x << ((8 * sizeof x) - n)))
    151 #define ROTL32(x, n) ((x << n) | (x >> ((8 * sizeof x) - n)))
    152 #endif
    153 
    154 /* Capitol Sigma and lower case sigma functions */
    155 #define S0(x) (ROTR32(x, 2) ^ ROTR32(x, 13) ^ ROTR32(x, 22))
    156 #define S1(x) (ROTR32(x, 6) ^ ROTR32(x, 11) ^ ROTR32(x, 25))
    157 #define s0(x) (ROTR32(x, 7) ^ ROTR32(x, 18) ^ SHR(x, 3))
    158 #define s1(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR(x, 10))
    159 
    160 void SHA256_Compress_Native(SHA256Context *ctx);
    161 void SHA256_Update_Native(SHA256Context *ctx, const unsigned char *input, unsigned int inputLen);
    162 
    163 static void SHA256_Compress_Generic(SHA256Context *ctx);
    164 static void SHA256_Update_Generic(SHA256Context *ctx, const unsigned char *input,
    165                                  unsigned int inputLen);
    166 
    167 #if !defined(USE_HW_SHA2)
    168 void
    169 SHA256_Compress_Native(SHA256Context *ctx)
    170 {
    171    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
    172    PORT_Assert(0);
    173 }
    174 
    175 void
    176 SHA256_Update_Native(SHA256Context *ctx, const unsigned char *input,
    177                     unsigned int inputLen)
    178 {
    179    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
    180    PORT_Assert(0);
    181 }
    182 #endif
    183 
    184 SHA256Context *
    185 SHA256_NewContext(void)
    186 {
    187    SHA256Context *ctx = PORT_New(SHA256Context);
    188    return ctx;
    189 }
    190 
    191 void
    192 SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
    193 {
    194    memset(ctx, 0, sizeof *ctx);
    195    if (freeit) {
    196        PORT_Free(ctx);
    197    }
    198 }
    199 
    200 void
    201 SHA256_Begin(SHA256Context *ctx)
    202 {
    203    PRBool use_hw_sha2 = PR_FALSE;
    204 
    205    memset(ctx, 0, sizeof *ctx);
    206    memcpy(H, H256, sizeof H256);
    207 
    208 #if defined(USE_HW_SHA2) && defined(IS_LITTLE_ENDIAN)
    209    /* arm's implementation is tested on little endian only */
    210    use_hw_sha2 = arm_sha2_support() || (sha_support() && ssse3_support() && sse4_1_support());
    211 #endif
    212 
    213    if (use_hw_sha2) {
    214        ctx->compress = SHA256_Compress_Native;
    215        ctx->update = SHA256_Update_Native;
    216    } else {
    217        ctx->compress = SHA256_Compress_Generic;
    218        ctx->update = SHA256_Update_Generic;
    219    }
    220 }
    221 
    222 #if defined(USE_PPC_CRYPTO)
    223 
    224 #define ROUND(n, a, b, c, d, e, f, g, h)         \
    225    s0 = __builtin_crypto_vshasigmaw(e, 1, 0xf); \
    226    h += s0 + vec_sel(g, f, e) + w[n / 4];       \
    227    d += h;                                      \
    228    s0 = __builtin_crypto_vshasigmaw(a, 1, 0);   \
    229    h += s0 + vec_sel(b, c, vec_xor(a, b));      \
    230    if (n % 4 != 3)                              \
    231        w[n / 4] = vec_sro(w[n / 4], rshift);
    232 
    233 #else
    234 
    235 #define ROUND(n, a, b, c, d, e, f, g, h)       \
    236    h += S1(e) + Ch(e, f, g) + K256[n] + W[n]; \
    237    d += h;                                    \
    238    h += S0(a) + Maj(a, b, c);
    239 
    240 #endif
    241 
    242 #define SHA256_UNROLLED_ROUNDS        \
    243    ROUND(0, a, b, c, d, e, f, g, h)  \
    244    ROUND(1, h, a, b, c, d, e, f, g)  \
    245    ROUND(2, g, h, a, b, c, d, e, f)  \
    246    ROUND(3, f, g, h, a, b, c, d, e)  \
    247    ROUND(4, e, f, g, h, a, b, c, d)  \
    248    ROUND(5, d, e, f, g, h, a, b, c)  \
    249    ROUND(6, c, d, e, f, g, h, a, b)  \
    250    ROUND(7, b, c, d, e, f, g, h, a)  \
    251                                      \
    252    ROUND(8, a, b, c, d, e, f, g, h)  \
    253    ROUND(9, h, a, b, c, d, e, f, g)  \
    254    ROUND(10, g, h, a, b, c, d, e, f) \
    255    ROUND(11, f, g, h, a, b, c, d, e) \
    256    ROUND(12, e, f, g, h, a, b, c, d) \
    257    ROUND(13, d, e, f, g, h, a, b, c) \
    258    ROUND(14, c, d, e, f, g, h, a, b) \
    259    ROUND(15, b, c, d, e, f, g, h, a) \
    260                                      \
    261    ROUND(16, a, b, c, d, e, f, g, h) \
    262    ROUND(17, h, a, b, c, d, e, f, g) \
    263    ROUND(18, g, h, a, b, c, d, e, f) \
    264    ROUND(19, f, g, h, a, b, c, d, e) \
    265    ROUND(20, e, f, g, h, a, b, c, d) \
    266    ROUND(21, d, e, f, g, h, a, b, c) \
    267    ROUND(22, c, d, e, f, g, h, a, b) \
    268    ROUND(23, b, c, d, e, f, g, h, a) \
    269                                      \
    270    ROUND(24, a, b, c, d, e, f, g, h) \
    271    ROUND(25, h, a, b, c, d, e, f, g) \
    272    ROUND(26, g, h, a, b, c, d, e, f) \
    273    ROUND(27, f, g, h, a, b, c, d, e) \
    274    ROUND(28, e, f, g, h, a, b, c, d) \
    275    ROUND(29, d, e, f, g, h, a, b, c) \
    276    ROUND(30, c, d, e, f, g, h, a, b) \
    277    ROUND(31, b, c, d, e, f, g, h, a) \
    278                                      \
    279    ROUND(32, a, b, c, d, e, f, g, h) \
    280    ROUND(33, h, a, b, c, d, e, f, g) \
    281    ROUND(34, g, h, a, b, c, d, e, f) \
    282    ROUND(35, f, g, h, a, b, c, d, e) \
    283    ROUND(36, e, f, g, h, a, b, c, d) \
    284    ROUND(37, d, e, f, g, h, a, b, c) \
    285    ROUND(38, c, d, e, f, g, h, a, b) \
    286    ROUND(39, b, c, d, e, f, g, h, a) \
    287                                      \
    288    ROUND(40, a, b, c, d, e, f, g, h) \
    289    ROUND(41, h, a, b, c, d, e, f, g) \
    290    ROUND(42, g, h, a, b, c, d, e, f) \
    291    ROUND(43, f, g, h, a, b, c, d, e) \
    292    ROUND(44, e, f, g, h, a, b, c, d) \
    293    ROUND(45, d, e, f, g, h, a, b, c) \
    294    ROUND(46, c, d, e, f, g, h, a, b) \
    295    ROUND(47, b, c, d, e, f, g, h, a) \
    296                                      \
    297    ROUND(48, a, b, c, d, e, f, g, h) \
    298    ROUND(49, h, a, b, c, d, e, f, g) \
    299    ROUND(50, g, h, a, b, c, d, e, f) \
    300    ROUND(51, f, g, h, a, b, c, d, e) \
    301    ROUND(52, e, f, g, h, a, b, c, d) \
    302    ROUND(53, d, e, f, g, h, a, b, c) \
    303    ROUND(54, c, d, e, f, g, h, a, b) \
    304    ROUND(55, b, c, d, e, f, g, h, a) \
    305                                      \
    306    ROUND(56, a, b, c, d, e, f, g, h) \
    307    ROUND(57, h, a, b, c, d, e, f, g) \
    308    ROUND(58, g, h, a, b, c, d, e, f) \
    309    ROUND(59, f, g, h, a, b, c, d, e) \
    310    ROUND(60, e, f, g, h, a, b, c, d) \
    311    ROUND(61, d, e, f, g, h, a, b, c) \
    312    ROUND(62, c, d, e, f, g, h, a, b) \
    313    ROUND(63, b, c, d, e, f, g, h, a)
    314 
    315 static void
    316 SHA256_Compress_Generic(SHA256Context *ctx)
    317 {
    318 #if defined(USE_PPC_CRYPTO)
    319    vec_u32 w[16], s0, s1;
    320    const vec_u8 rshift = (vec_u8)vec_splats(4 << 3);
    321    const vec_u8 shifthalf = (vec_u8)vec_splats(8 << 3);
    322    const vec_u8 bswap4 = (vec_u8){
    323        3, 2, 1, 0, 7, 6, 5, 4, 11,
    324        10, 9, 8, 15, 14, 13, 12
    325    };
    326    unsigned i;
    327 
    328    for (i = 0; i < 4; i++) {
    329        w[i] = vec_vsx_ld(0, &W[i * 4]);
    330        w[i] = vec_perm(w[i], w[i], bswap4);
    331    }
    332 
    333    /* prepare the message schedule */
    334    for (i = 4; i < 16; i++) {
    335        vec_u32 off1 = vec_sld(w[i - 3], w[i - 4], 12);
    336        vec_u32 off2 = vec_sld(w[i - 1], w[i - 2], 12);
    337        s0 = __builtin_crypto_vshasigmaw(off1, 0, 0);
    338        /* first half, s1 depends on two prior ints */
    339        s1 = __builtin_crypto_vshasigmaw(w[i - 1], 0, 0xf);
    340        s1 = vec_sro(s1, shifthalf);
    341        w[i] = w[i - 4] + s0 + off2 + s1;
    342 
    343        /* second half s1 */
    344        s1 = __builtin_crypto_vshasigmaw(w[i], 0, 0xf);
    345        s1 = vec_slo(s1, shifthalf);
    346        w[i] += s1;
    347    }
    348 
    349    for (i = 0; i < 16; i++) {
    350        w[i] += vec_ld(0, &K256[i * 4]);
    351    }
    352 
    353    vec_u32 a, b, c, d, e, f, g, h;
    354    a = vec_splats(H[0]);
    355    b = vec_splats(H[1]);
    356    c = vec_splats(H[2]);
    357    d = vec_splats(H[3]);
    358    e = vec_splats(H[4]);
    359    f = vec_splats(H[5]);
    360    g = vec_splats(H[6]);
    361    h = vec_splats(H[7]);
    362 
    363    SHA256_UNROLLED_ROUNDS;
    364 
    365    H[0] += a[0];
    366    H[1] += b[0];
    367    H[2] += c[0];
    368    H[3] += d[0];
    369    H[4] += e[0];
    370    H[5] += f[0];
    371    H[6] += g[0];
    372    H[7] += h[0];
    373 
    374 #undef ROUND
    375 
    376 #else /* USE_PPC_CRYPTO*/
    377 
    378    {
    379 #if defined(IS_LITTLE_ENDIAN)
    380        BYTESWAP4(W[0]);
    381        BYTESWAP4(W[1]);
    382        BYTESWAP4(W[2]);
    383        BYTESWAP4(W[3]);
    384        BYTESWAP4(W[4]);
    385        BYTESWAP4(W[5]);
    386        BYTESWAP4(W[6]);
    387        BYTESWAP4(W[7]);
    388        BYTESWAP4(W[8]);
    389        BYTESWAP4(W[9]);
    390        BYTESWAP4(W[10]);
    391        BYTESWAP4(W[11]);
    392        BYTESWAP4(W[12]);
    393        BYTESWAP4(W[13]);
    394        BYTESWAP4(W[14]);
    395        BYTESWAP4(W[15]);
    396 #endif
    397 
    398 #define INITW(t) W[t] = (s1(W[t - 2]) + W[t - 7] + s0(W[t - 15]) + W[t - 16])
    399 
    400 /* prepare the "message schedule"   */
    401 #ifdef NOUNROLL256
    402        {
    403            int t;
    404            for (t = 16; t < 64; ++t) {
    405                INITW(t);
    406            }
    407        }
    408 #else
    409        INITW(16);
    410        INITW(17);
    411        INITW(18);
    412        INITW(19);
    413 
    414        INITW(20);
    415        INITW(21);
    416        INITW(22);
    417        INITW(23);
    418        INITW(24);
    419        INITW(25);
    420        INITW(26);
    421        INITW(27);
    422        INITW(28);
    423        INITW(29);
    424 
    425        INITW(30);
    426        INITW(31);
    427        INITW(32);
    428        INITW(33);
    429        INITW(34);
    430        INITW(35);
    431        INITW(36);
    432        INITW(37);
    433        INITW(38);
    434        INITW(39);
    435 
    436        INITW(40);
    437        INITW(41);
    438        INITW(42);
    439        INITW(43);
    440        INITW(44);
    441        INITW(45);
    442        INITW(46);
    443        INITW(47);
    444        INITW(48);
    445        INITW(49);
    446 
    447        INITW(50);
    448        INITW(51);
    449        INITW(52);
    450        INITW(53);
    451        INITW(54);
    452        INITW(55);
    453        INITW(56);
    454        INITW(57);
    455        INITW(58);
    456        INITW(59);
    457 
    458        INITW(60);
    459        INITW(61);
    460        INITW(62);
    461        INITW(63);
    462 
    463 #endif
    464 #undef INITW
    465    }
    466    {
    467        PRUint32 a, b, c, d, e, f, g, h;
    468 
    469        a = H[0];
    470        b = H[1];
    471        c = H[2];
    472        d = H[3];
    473        e = H[4];
    474        f = H[5];
    475        g = H[6];
    476        h = H[7];
    477 
    478 #ifdef NOUNROLL256
    479        {
    480            int t;
    481            for (t = 0; t < 64; t += 8) {
    482                ROUND(t + 0, a, b, c, d, e, f, g, h)
    483                ROUND(t + 1, h, a, b, c, d, e, f, g)
    484                ROUND(t + 2, g, h, a, b, c, d, e, f)
    485                ROUND(t + 3, f, g, h, a, b, c, d, e)
    486                ROUND(t + 4, e, f, g, h, a, b, c, d)
    487                ROUND(t + 5, d, e, f, g, h, a, b, c)
    488                ROUND(t + 6, c, d, e, f, g, h, a, b)
    489                ROUND(t + 7, b, c, d, e, f, g, h, a)
    490            }
    491        }
    492 #else
    493        SHA256_UNROLLED_ROUNDS;
    494 #endif
    495 
    496        H[0] += a;
    497        H[1] += b;
    498        H[2] += c;
    499        H[3] += d;
    500        H[4] += e;
    501        H[5] += f;
    502        H[6] += g;
    503        H[7] += h;
    504    }
    505 #undef ROUND
    506 #endif /* !USE_PPC_CRYPTO */
    507 }
    508 
    509 #undef s0
    510 #undef s1
    511 #undef S0
    512 #undef S1
    513 
    514 void
    515 SHA256_Update(SHA256Context *ctx, const unsigned char *input,
    516              unsigned int inputLen)
    517 {
    518    ctx->update(ctx, input, inputLen);
    519 }
    520 
    521 static void
    522 SHA256_Update_Generic(SHA256Context *ctx, const unsigned char *input,
    523                      unsigned int inputLen)
    524 {
    525    unsigned int inBuf = ctx->sizeLo & 0x3f;
    526    if (!inputLen)
    527        return;
    528 
    529    /* Add inputLen into the count of bytes processed, before processing */
    530    if ((ctx->sizeLo += inputLen) < inputLen)
    531        ctx->sizeHi++;
    532 
    533    /* if data already in buffer, attemp to fill rest of buffer */
    534    if (inBuf) {
    535        unsigned int todo = SHA256_BLOCK_LENGTH - inBuf;
    536        if (inputLen < todo)
    537            todo = inputLen;
    538        memcpy(B + inBuf, input, todo);
    539        input += todo;
    540        inputLen -= todo;
    541        if (inBuf + todo == SHA256_BLOCK_LENGTH)
    542            SHA256_Compress_Generic(ctx);
    543    }
    544 
    545    /* if enough data to fill one or more whole buffers, process them. */
    546    while (inputLen >= SHA256_BLOCK_LENGTH) {
    547        memcpy(B, input, SHA256_BLOCK_LENGTH);
    548        input += SHA256_BLOCK_LENGTH;
    549        inputLen -= SHA256_BLOCK_LENGTH;
    550        SHA256_Compress_Generic(ctx);
    551    }
    552    /* if data left over, fill it into buffer */
    553    if (inputLen)
    554        memcpy(B, input, inputLen);
    555 }
    556 
    557 void
    558 SHA256_End(SHA256Context *ctx, unsigned char *digest,
    559           unsigned int *digestLen, unsigned int maxDigestLen)
    560 {
    561    unsigned int inBuf = ctx->sizeLo & 0x3f;
    562    unsigned int padLen = (inBuf < 56) ? (56 - inBuf) : (56 + 64 - inBuf);
    563    PRUint32 hi, lo;
    564 
    565    hi = (ctx->sizeHi << 3) | (ctx->sizeLo >> 29);
    566    lo = (ctx->sizeLo << 3);
    567 
    568    ctx->update(ctx, pad, padLen);
    569 
    570 #if defined(IS_LITTLE_ENDIAN)
    571    W[14] = SHA_HTONL(hi);
    572    W[15] = SHA_HTONL(lo);
    573 #else
    574    W[14] = hi;
    575    W[15] = lo;
    576 #endif
    577    ctx->compress(ctx);
    578 
    579 /* now output the answer */
    580 #if defined(IS_LITTLE_ENDIAN)
    581    BYTESWAP4(H[0]);
    582    BYTESWAP4(H[1]);
    583    BYTESWAP4(H[2]);
    584    BYTESWAP4(H[3]);
    585    BYTESWAP4(H[4]);
    586    BYTESWAP4(H[5]);
    587    BYTESWAP4(H[6]);
    588    BYTESWAP4(H[7]);
    589 #endif
    590    padLen = PR_MIN(SHA256_LENGTH, maxDigestLen);
    591    memcpy(digest, H, padLen);
    592    if (digestLen)
    593        *digestLen = padLen;
    594 }
    595 
    596 void
    597 SHA256_EndRaw(SHA256Context *ctx, unsigned char *digest,
    598              unsigned int *digestLen, unsigned int maxDigestLen)
    599 {
    600    PRUint32 h[8];
    601    unsigned int len;
    602 
    603    memcpy(h, ctx->h, sizeof(h));
    604 
    605 #if defined(IS_LITTLE_ENDIAN)
    606    BYTESWAP4(h[0]);
    607    BYTESWAP4(h[1]);
    608    BYTESWAP4(h[2]);
    609    BYTESWAP4(h[3]);
    610    BYTESWAP4(h[4]);
    611    BYTESWAP4(h[5]);
    612    BYTESWAP4(h[6]);
    613    BYTESWAP4(h[7]);
    614 #endif
    615 
    616    len = PR_MIN(SHA256_LENGTH, maxDigestLen);
    617    memcpy(digest, h, len);
    618    if (digestLen)
    619        *digestLen = len;
    620 }
    621 
    622 SECStatus
    623 SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
    624               PRUint32 src_length)
    625 {
    626    SHA256Context ctx;
    627    unsigned int outLen;
    628 
    629    SHA256_Begin(&ctx);
    630    SHA256_Update(&ctx, src, src_length);
    631    SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH);
    632    memset(&ctx, 0, sizeof ctx);
    633 
    634    return SECSuccess;
    635 }
    636 
    637 SECStatus
    638 SHA256_Hash(unsigned char *dest, const char *src)
    639 {
    640    return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
    641 }
    642 
    643 void
    644 SHA256_TraceState(SHA256Context *ctx)
    645 {
    646 }
    647 
    648 unsigned int
    649 SHA256_FlattenSize(SHA256Context *ctx)
    650 {
    651    return sizeof *ctx;
    652 }
    653 
    654 SECStatus
    655 SHA256_Flatten(SHA256Context *ctx, unsigned char *space)
    656 {
    657    PORT_Memcpy(space, ctx, sizeof *ctx);
    658    return SECSuccess;
    659 }
    660 
    661 SHA256Context *
    662 SHA256_Resurrect(unsigned char *space, void *arg)
    663 {
    664    SHA256Context *ctx = SHA256_NewContext();
    665    if (ctx)
    666        PORT_Memcpy(ctx, space, sizeof *ctx);
    667    return ctx;
    668 }
    669 
    670 void
    671 SHA256_Clone(SHA256Context *dest, SHA256Context *src)
    672 {
    673    memcpy(dest, src, sizeof *dest);
    674 }
    675 
    676 /* ============= SHA224 implementation ================================== */
    677 
    678 /* SHA-224 initial hash values */
    679 static const PRUint32 H224[8] = {
    680    0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
    681    0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
    682 };
    683 
    684 SHA224Context *
    685 SHA224_NewContext(void)
    686 {
    687    return SHA256_NewContext();
    688 }
    689 
    690 void
    691 SHA224_DestroyContext(SHA224Context *ctx, PRBool freeit)
    692 {
    693    SHA256_DestroyContext(ctx, freeit);
    694 }
    695 
    696 void
    697 SHA224_Begin(SHA224Context *ctx)
    698 {
    699    PRBool use_hw_sha2;
    700 
    701    memset(ctx, 0, sizeof *ctx);
    702    memcpy(H, H224, sizeof H224);
    703 
    704 #if defined(USE_HW_SHA2) && defined(IS_LITTLE_ENDIAN)
    705    /* arm's implementation is tested on little endian only */
    706    use_hw_sha2 = arm_sha2_support() || (sha_support() && ssse3_support() && sse4_1_support());
    707 #else
    708    use_hw_sha2 = PR_FALSE;
    709 #endif
    710 
    711    if (use_hw_sha2) {
    712        ctx->compress = SHA256_Compress_Native;
    713        ctx->update = SHA256_Update_Native;
    714    } else {
    715        ctx->compress = SHA256_Compress_Generic;
    716        ctx->update = SHA256_Update_Generic;
    717    }
    718 }
    719 
    720 void
    721 SHA224_Update(SHA224Context *ctx, const unsigned char *input,
    722              unsigned int inputLen)
    723 {
    724    ctx->update(ctx, input, inputLen);
    725 }
    726 
    727 void
    728 SHA224_End(SHA256Context *ctx, unsigned char *digest,
    729           unsigned int *digestLen, unsigned int maxDigestLen)
    730 {
    731    unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH);
    732    SHA256_End(ctx, digest, digestLen, maxLen);
    733 }
    734 
    735 void
    736 SHA224_EndRaw(SHA256Context *ctx, unsigned char *digest,
    737              unsigned int *digestLen, unsigned int maxDigestLen)
    738 {
    739    unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH);
    740    SHA256_EndRaw(ctx, digest, digestLen, maxLen);
    741 }
    742 
    743 SECStatus
    744 SHA224_HashBuf(unsigned char *dest, const unsigned char *src,
    745               PRUint32 src_length)
    746 {
    747    SHA256Context ctx;
    748    unsigned int outLen;
    749 
    750    SHA224_Begin(&ctx);
    751    SHA256_Update(&ctx, src, src_length);
    752    SHA256_End(&ctx, dest, &outLen, SHA224_LENGTH);
    753    memset(&ctx, 0, sizeof ctx);
    754 
    755    return SECSuccess;
    756 }
    757 
    758 SECStatus
    759 SHA224_Hash(unsigned char *dest, const char *src)
    760 {
    761    return SHA224_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
    762 }
    763 
    764 void
    765 SHA224_TraceState(SHA224Context *ctx)
    766 {
    767 }
    768 
    769 unsigned int
    770 SHA224_FlattenSize(SHA224Context *ctx)
    771 {
    772    return SHA256_FlattenSize(ctx);
    773 }
    774 
    775 SECStatus
    776 SHA224_Flatten(SHA224Context *ctx, unsigned char *space)
    777 {
    778    return SHA256_Flatten(ctx, space);
    779 }
    780 
    781 SHA224Context *
    782 SHA224_Resurrect(unsigned char *space, void *arg)
    783 {
    784    return SHA256_Resurrect(space, arg);
    785 }
    786 
    787 void
    788 SHA224_Clone(SHA224Context *dest, SHA224Context *src)
    789 {
    790    SHA256_Clone(dest, src);
    791 }
    792 
    793 /* ======= SHA512 and SHA384 common constants and defines ================= */
    794 
    795 /* common #defines for SHA512 and SHA384 */
    796 #if defined(HAVE_LONG_LONG)
    797 #define S0(x) (ROTR64(x, 28) ^ ROTR64(x, 34) ^ ROTR64(x, 39))
    798 #define S1(x) (ROTR64(x, 14) ^ ROTR64(x, 18) ^ ROTR64(x, 41))
    799 #define s0(x) (ROTR64(x, 1) ^ ROTR64(x, 8) ^ SHR(x, 7))
    800 #define s1(x) (ROTR64(x, 19) ^ ROTR64(x, 61) ^ SHR(x, 6))
    801 
    802 #if PR_BYTES_PER_LONG == 8
    803 #define ULLC(hi, lo) 0x##hi##lo##UL
    804 #elif defined(_MSC_VER)
    805 #define ULLC(hi, lo) 0x##hi##lo##ui64
    806 #else
    807 #define ULLC(hi, lo) 0x##hi##lo##ULL
    808 #endif
    809 
    810 #define BYTESWAP8(x) x = FREEBL_HTONLL(x)
    811 
    812 #else /* no long long */
    813 
    814 #if defined(IS_LITTLE_ENDIAN)
    815 #define ULLC(hi, lo)         \
    816    {                        \
    817        0x##lo##U, 0x##hi##U \
    818    }
    819 #define FREEBL_HTONLL(x) (BYTESWAP4(x.lo), BYTESWAP4(x.hi), \
    820                          x.hi ^= x.lo ^= x.hi ^= x.lo, x)
    821 #define BYTESWAP8(x)     \
    822    do {                 \
    823        PRUint32 tmp;    \
    824        BYTESWAP4(x.lo); \
    825        BYTESWAP4(x.hi); \
    826        tmp = x.lo;      \
    827        x.lo = x.hi;     \
    828        x.hi = tmp;      \
    829    } while (0)
    830 #else
    831 #define ULLC(hi, lo)         \
    832    {                        \
    833        0x##hi##U, 0x##lo##U \
    834    }
    835 #endif
    836 
    837 #endif
    838 
    839 #if defined(USE_PPC_CRYPTO)
    840 void sha512_block_p8(void *ctx, const void *inp, size_t len);
    841 
    842 #else /* USE_PPC_CRYPTO */
    843 
    844 /* SHA-384 and SHA-512 constants, K512. */
    845 static const PRUint64 K512[80] = {
    846 #if PR_BYTES_PER_LONG == 8
    847    0x428a2f98d728ae22UL, 0x7137449123ef65cdUL,
    848    0xb5c0fbcfec4d3b2fUL, 0xe9b5dba58189dbbcUL,
    849    0x3956c25bf348b538UL, 0x59f111f1b605d019UL,
    850    0x923f82a4af194f9bUL, 0xab1c5ed5da6d8118UL,
    851    0xd807aa98a3030242UL, 0x12835b0145706fbeUL,
    852    0x243185be4ee4b28cUL, 0x550c7dc3d5ffb4e2UL,
    853    0x72be5d74f27b896fUL, 0x80deb1fe3b1696b1UL,
    854    0x9bdc06a725c71235UL, 0xc19bf174cf692694UL,
    855    0xe49b69c19ef14ad2UL, 0xefbe4786384f25e3UL,
    856    0x0fc19dc68b8cd5b5UL, 0x240ca1cc77ac9c65UL,
    857    0x2de92c6f592b0275UL, 0x4a7484aa6ea6e483UL,
    858    0x5cb0a9dcbd41fbd4UL, 0x76f988da831153b5UL,
    859    0x983e5152ee66dfabUL, 0xa831c66d2db43210UL,
    860    0xb00327c898fb213fUL, 0xbf597fc7beef0ee4UL,
    861    0xc6e00bf33da88fc2UL, 0xd5a79147930aa725UL,
    862    0x06ca6351e003826fUL, 0x142929670a0e6e70UL,
    863    0x27b70a8546d22ffcUL, 0x2e1b21385c26c926UL,
    864    0x4d2c6dfc5ac42aedUL, 0x53380d139d95b3dfUL,
    865    0x650a73548baf63deUL, 0x766a0abb3c77b2a8UL,
    866    0x81c2c92e47edaee6UL, 0x92722c851482353bUL,
    867    0xa2bfe8a14cf10364UL, 0xa81a664bbc423001UL,
    868    0xc24b8b70d0f89791UL, 0xc76c51a30654be30UL,
    869    0xd192e819d6ef5218UL, 0xd69906245565a910UL,
    870    0xf40e35855771202aUL, 0x106aa07032bbd1b8UL,
    871    0x19a4c116b8d2d0c8UL, 0x1e376c085141ab53UL,
    872    0x2748774cdf8eeb99UL, 0x34b0bcb5e19b48a8UL,
    873    0x391c0cb3c5c95a63UL, 0x4ed8aa4ae3418acbUL,
    874    0x5b9cca4f7763e373UL, 0x682e6ff3d6b2b8a3UL,
    875    0x748f82ee5defb2fcUL, 0x78a5636f43172f60UL,
    876    0x84c87814a1f0ab72UL, 0x8cc702081a6439ecUL,
    877    0x90befffa23631e28UL, 0xa4506cebde82bde9UL,
    878    0xbef9a3f7b2c67915UL, 0xc67178f2e372532bUL,
    879    0xca273eceea26619cUL, 0xd186b8c721c0c207UL,
    880    0xeada7dd6cde0eb1eUL, 0xf57d4f7fee6ed178UL,
    881    0x06f067aa72176fbaUL, 0x0a637dc5a2c898a6UL,
    882    0x113f9804bef90daeUL, 0x1b710b35131c471bUL,
    883    0x28db77f523047d84UL, 0x32caab7b40c72493UL,
    884    0x3c9ebe0a15c9bebcUL, 0x431d67c49c100d4cUL,
    885    0x4cc5d4becb3e42b6UL, 0x597f299cfc657e2aUL,
    886    0x5fcb6fab3ad6faecUL, 0x6c44198c4a475817UL
    887 #else
    888    ULLC(428a2f98, d728ae22), ULLC(71374491, 23ef65cd),
    889    ULLC(b5c0fbcf, ec4d3b2f), ULLC(e9b5dba5, 8189dbbc),
    890    ULLC(3956c25b, f348b538), ULLC(59f111f1, b605d019),
    891    ULLC(923f82a4, af194f9b), ULLC(ab1c5ed5, da6d8118),
    892    ULLC(d807aa98, a3030242), ULLC(12835b01, 45706fbe),
    893    ULLC(243185be, 4ee4b28c), ULLC(550c7dc3, d5ffb4e2),
    894    ULLC(72be5d74, f27b896f), ULLC(80deb1fe, 3b1696b1),
    895    ULLC(9bdc06a7, 25c71235), ULLC(c19bf174, cf692694),
    896    ULLC(e49b69c1, 9ef14ad2), ULLC(efbe4786, 384f25e3),
    897    ULLC(0fc19dc6, 8b8cd5b5), ULLC(240ca1cc, 77ac9c65),
    898    ULLC(2de92c6f, 592b0275), ULLC(4a7484aa, 6ea6e483),
    899    ULLC(5cb0a9dc, bd41fbd4), ULLC(76f988da, 831153b5),
    900    ULLC(983e5152, ee66dfab), ULLC(a831c66d, 2db43210),
    901    ULLC(b00327c8, 98fb213f), ULLC(bf597fc7, beef0ee4),
    902    ULLC(c6e00bf3, 3da88fc2), ULLC(d5a79147, 930aa725),
    903    ULLC(06ca6351, e003826f), ULLC(14292967, 0a0e6e70),
    904    ULLC(27b70a85, 46d22ffc), ULLC(2e1b2138, 5c26c926),
    905    ULLC(4d2c6dfc, 5ac42aed), ULLC(53380d13, 9d95b3df),
    906    ULLC(650a7354, 8baf63de), ULLC(766a0abb, 3c77b2a8),
    907    ULLC(81c2c92e, 47edaee6), ULLC(92722c85, 1482353b),
    908    ULLC(a2bfe8a1, 4cf10364), ULLC(a81a664b, bc423001),
    909    ULLC(c24b8b70, d0f89791), ULLC(c76c51a3, 0654be30),
    910    ULLC(d192e819, d6ef5218), ULLC(d6990624, 5565a910),
    911    ULLC(f40e3585, 5771202a), ULLC(106aa070, 32bbd1b8),
    912    ULLC(19a4c116, b8d2d0c8), ULLC(1e376c08, 5141ab53),
    913    ULLC(2748774c, df8eeb99), ULLC(34b0bcb5, e19b48a8),
    914    ULLC(391c0cb3, c5c95a63), ULLC(4ed8aa4a, e3418acb),
    915    ULLC(5b9cca4f, 7763e373), ULLC(682e6ff3, d6b2b8a3),
    916    ULLC(748f82ee, 5defb2fc), ULLC(78a5636f, 43172f60),
    917    ULLC(84c87814, a1f0ab72), ULLC(8cc70208, 1a6439ec),
    918    ULLC(90befffa, 23631e28), ULLC(a4506ceb, de82bde9),
    919    ULLC(bef9a3f7, b2c67915), ULLC(c67178f2, e372532b),
    920    ULLC(ca273ece, ea26619c), ULLC(d186b8c7, 21c0c207),
    921    ULLC(eada7dd6, cde0eb1e), ULLC(f57d4f7f, ee6ed178),
    922    ULLC(06f067aa, 72176fba), ULLC(0a637dc5, a2c898a6),
    923    ULLC(113f9804, bef90dae), ULLC(1b710b35, 131c471b),
    924    ULLC(28db77f5, 23047d84), ULLC(32caab7b, 40c72493),
    925    ULLC(3c9ebe0a, 15c9bebc), ULLC(431d67c4, 9c100d4c),
    926    ULLC(4cc5d4be, cb3e42b6), ULLC(597f299c, fc657e2a),
    927    ULLC(5fcb6fab, 3ad6faec), ULLC(6c44198c, 4a475817)
    928 #endif
    929 };
    930 
    931 #endif /* !USE_PPC_CRYPTO */
    932 
    933 struct SHA512ContextStr {
    934    union {
    935        PRUint64 w[80]; /* message schedule, input buffer, plus 64 words */
    936        PRUint32 l[160];
    937        PRUint8 b[640];
    938    } u;
    939    PRUint64 h[8];   /* 8 state variables */
    940    PRUint64 sizeLo; /* 64-bit count of hashed bytes. */
    941 };
    942 
    943 /* =========== SHA512 implementation ===================================== */
    944 
    945 /* SHA-512 initial hash values */
    946 static const PRUint64 H512[8] = {
    947 #if PR_BYTES_PER_LONG == 8
    948    0x6a09e667f3bcc908UL, 0xbb67ae8584caa73bUL,
    949    0x3c6ef372fe94f82bUL, 0xa54ff53a5f1d36f1UL,
    950    0x510e527fade682d1UL, 0x9b05688c2b3e6c1fUL,
    951    0x1f83d9abfb41bd6bUL, 0x5be0cd19137e2179UL
    952 #else
    953    ULLC(6a09e667, f3bcc908), ULLC(bb67ae85, 84caa73b),
    954    ULLC(3c6ef372, fe94f82b), ULLC(a54ff53a, 5f1d36f1),
    955    ULLC(510e527f, ade682d1), ULLC(9b05688c, 2b3e6c1f),
    956    ULLC(1f83d9ab, fb41bd6b), ULLC(5be0cd19, 137e2179)
    957 #endif
    958 };
    959 
    960 SHA512Context *
    961 SHA512_NewContext(void)
    962 {
    963    SHA512Context *ctx = PORT_New(SHA512Context);
    964    return ctx;
    965 }
    966 
    967 void
    968 SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit)
    969 {
    970    memset(ctx, 0, sizeof *ctx);
    971    if (freeit) {
    972        PORT_Free(ctx);
    973    }
    974 }
    975 
    976 void
    977 SHA512_Begin(SHA512Context *ctx)
    978 {
    979    memset(ctx, 0, sizeof *ctx);
    980    memcpy(H, H512, sizeof H512);
    981 }
    982 
    983 #if defined(SHA512_TRACE)
    984 #if defined(HAVE_LONG_LONG)
    985 #define DUMP(n, a, d, e, h) printf(" t = %2d, %s = %016lx, %s = %016lx\n", \
    986                                   n, #e, d, #a, h);
    987 #else
    988 #define DUMP(n, a, d, e, h) printf(" t = %2d, %s = %08x%08x, %s = %08x%08x\n", \
    989                                   n, #e, d.hi, d.lo, #a, h.hi, h.lo);
    990 #endif
    991 #else
    992 #define DUMP(n, a, d, e, h)
    993 #endif
    994 
    995 #if defined(HAVE_LONG_LONG)
    996 
    997 #define ADDTO(x, y) y += x
    998 
    999 #define INITW(t) W[t] = (s1(W[t - 2]) + W[t - 7] + s0(W[t - 15]) + W[t - 16])
   1000 
   1001 #define ROUND(n, a, b, c, d, e, f, g, h)       \
   1002    h += S1(e) + Ch(e, f, g) + K512[n] + W[n]; \
   1003    d += h;                                    \
   1004    h += S0(a) + Maj(a, b, c);                 \
   1005    DUMP(n, a, d, e, h)
   1006 
   1007 #else /* use only 32-bit variables, and don't unroll loops */
   1008 
   1009 #undef NOUNROLL512
   1010 #define NOUNROLL512 1
   1011 
   1012 #define ADDTO(x, y) \
   1013    y.lo += x.lo;   \
   1014    y.hi += x.hi + (x.lo > y.lo)
   1015 
   1016 #define ROTR64a(x, n, lo, hi) (x.lo >> n | x.hi << (32 - n))
   1017 #define ROTR64A(x, n, lo, hi) (x.lo << (64 - n) | x.hi >> (n - 32))
   1018 #define SHR64a(x, n, lo, hi) (x.lo >> n | x.hi << (32 - n))
   1019 
   1020 /* Capitol Sigma and lower case sigma functions */
   1021 #define s0lo(x) (ROTR64a(x, 1, lo, hi) ^ ROTR64a(x, 8, lo, hi) ^ SHR64a(x, 7, lo, hi))
   1022 #define s0hi(x) (ROTR64a(x, 1, hi, lo) ^ ROTR64a(x, 8, hi, lo) ^ (x.hi >> 7))
   1023 
   1024 #define s1lo(x) (ROTR64a(x, 19, lo, hi) ^ ROTR64A(x, 61, lo, hi) ^ SHR64a(x, 6, lo, hi))
   1025 #define s1hi(x) (ROTR64a(x, 19, hi, lo) ^ ROTR64A(x, 61, hi, lo) ^ (x.hi >> 6))
   1026 
   1027 #define S0lo(x) (ROTR64a(x, 28, lo, hi) ^ ROTR64A(x, 34, lo, hi) ^ ROTR64A(x, 39, lo, hi))
   1028 #define S0hi(x) (ROTR64a(x, 28, hi, lo) ^ ROTR64A(x, 34, hi, lo) ^ ROTR64A(x, 39, hi, lo))
   1029 
   1030 #define S1lo(x) (ROTR64a(x, 14, lo, hi) ^ ROTR64a(x, 18, lo, hi) ^ ROTR64A(x, 41, lo, hi))
   1031 #define S1hi(x) (ROTR64a(x, 14, hi, lo) ^ ROTR64a(x, 18, hi, lo) ^ ROTR64A(x, 41, hi, lo))
   1032 
   1033 /* 32-bit versions of Ch and Maj */
   1034 #define Chxx(x, y, z, lo) ((x.lo & y.lo) ^ (~x.lo & z.lo))
   1035 #define Majx(x, y, z, lo) ((x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo))
   1036 
   1037 #define INITW(t)                                                                      \
   1038    do {                                                                              \
   1039        PRUint32 lo, tm;                                                              \
   1040        PRUint32 cy = 0;                                                              \
   1041        lo = s1lo(W[t - 2]);                                                          \
   1042        lo += (tm = W[t - 7].lo);                                                     \
   1043        if (lo < tm)                                                                  \
   1044            cy++;                                                                     \
   1045        lo += (tm = s0lo(W[t - 15]));                                                 \
   1046        if (lo < tm)                                                                  \
   1047            cy++;                                                                     \
   1048        lo += (tm = W[t - 16].lo);                                                    \
   1049        if (lo < tm)                                                                  \
   1050            cy++;                                                                     \
   1051        W[t].lo = lo;                                                                 \
   1052        W[t].hi = cy + s1hi(W[t - 2]) + W[t - 7].hi + s0hi(W[t - 15]) + W[t - 16].hi; \
   1053    } while (0)
   1054 
   1055 #define ROUND(n, a, b, c, d, e, f, g, h)                                 \
   1056    {                                                                    \
   1057        PRUint32 lo, tm, cy;                                             \
   1058        lo = S1lo(e);                                                    \
   1059        lo += (tm = Chxx(e, f, g, lo));                                  \
   1060        cy = (lo < tm);                                                  \
   1061        lo += (tm = K512[n].lo);                                         \
   1062        if (lo < tm)                                                     \
   1063            cy++;                                                        \
   1064        lo += (tm = W[n].lo);                                            \
   1065        if (lo < tm)                                                     \
   1066            cy++;                                                        \
   1067        h.lo += lo;                                                      \
   1068        if (h.lo < lo)                                                   \
   1069            cy++;                                                        \
   1070        h.hi += cy + S1hi(e) + Chxx(e, f, g, hi) + K512[n].hi + W[n].hi; \
   1071        d.lo += h.lo;                                                    \
   1072        d.hi += h.hi + (d.lo < h.lo);                                    \
   1073        lo = S0lo(a);                                                    \
   1074        lo += (tm = Majx(a, b, c, lo));                                  \
   1075        cy = (lo < tm);                                                  \
   1076        h.lo += lo;                                                      \
   1077        if (h.lo < lo)                                                   \
   1078            cy++;                                                        \
   1079        h.hi += cy + S0hi(a) + Majx(a, b, c, hi);                        \
   1080        DUMP(n, a, d, e, h)                                              \
   1081    }
   1082 #endif
   1083 
   1084 static void
   1085 SHA512_Compress(SHA512Context *ctx)
   1086 {
   1087 #if defined(USE_PPC_CRYPTO)
   1088    sha512_block_p8(&H[0], &W[0], 1);
   1089 #else /* USE_PPC_CRYPTO */
   1090 
   1091 #if defined(IS_LITTLE_ENDIAN)
   1092    {
   1093        BYTESWAP8(W[0]);
   1094        BYTESWAP8(W[1]);
   1095        BYTESWAP8(W[2]);
   1096        BYTESWAP8(W[3]);
   1097        BYTESWAP8(W[4]);
   1098        BYTESWAP8(W[5]);
   1099        BYTESWAP8(W[6]);
   1100        BYTESWAP8(W[7]);
   1101        BYTESWAP8(W[8]);
   1102        BYTESWAP8(W[9]);
   1103        BYTESWAP8(W[10]);
   1104        BYTESWAP8(W[11]);
   1105        BYTESWAP8(W[12]);
   1106        BYTESWAP8(W[13]);
   1107        BYTESWAP8(W[14]);
   1108        BYTESWAP8(W[15]);
   1109    }
   1110 #endif
   1111 
   1112    {
   1113 #ifdef NOUNROLL512
   1114        {
   1115            /* prepare the "message schedule"   */
   1116            int t;
   1117            for (t = 16; t < 80; ++t) {
   1118                INITW(t);
   1119            }
   1120        }
   1121 #else
   1122        INITW(16);
   1123        INITW(17);
   1124        INITW(18);
   1125        INITW(19);
   1126 
   1127        INITW(20);
   1128        INITW(21);
   1129        INITW(22);
   1130        INITW(23);
   1131        INITW(24);
   1132        INITW(25);
   1133        INITW(26);
   1134        INITW(27);
   1135        INITW(28);
   1136        INITW(29);
   1137 
   1138        INITW(30);
   1139        INITW(31);
   1140        INITW(32);
   1141        INITW(33);
   1142        INITW(34);
   1143        INITW(35);
   1144        INITW(36);
   1145        INITW(37);
   1146        INITW(38);
   1147        INITW(39);
   1148 
   1149        INITW(40);
   1150        INITW(41);
   1151        INITW(42);
   1152        INITW(43);
   1153        INITW(44);
   1154        INITW(45);
   1155        INITW(46);
   1156        INITW(47);
   1157        INITW(48);
   1158        INITW(49);
   1159 
   1160        INITW(50);
   1161        INITW(51);
   1162        INITW(52);
   1163        INITW(53);
   1164        INITW(54);
   1165        INITW(55);
   1166        INITW(56);
   1167        INITW(57);
   1168        INITW(58);
   1169        INITW(59);
   1170 
   1171        INITW(60);
   1172        INITW(61);
   1173        INITW(62);
   1174        INITW(63);
   1175        INITW(64);
   1176        INITW(65);
   1177        INITW(66);
   1178        INITW(67);
   1179        INITW(68);
   1180        INITW(69);
   1181 
   1182        INITW(70);
   1183        INITW(71);
   1184        INITW(72);
   1185        INITW(73);
   1186        INITW(74);
   1187        INITW(75);
   1188        INITW(76);
   1189        INITW(77);
   1190        INITW(78);
   1191        INITW(79);
   1192 #endif
   1193    }
   1194 #ifdef SHA512_TRACE
   1195    {
   1196        int i;
   1197        for (i = 0; i < 80; ++i) {
   1198 #ifdef HAVE_LONG_LONG
   1199            printf("W[%2d] = %016lx\n", i, W[i]);
   1200 #else
   1201            printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo);
   1202 #endif
   1203        }
   1204    }
   1205 #endif
   1206    {
   1207        PRUint64 a, b, c, d, e, f, g, h;
   1208 
   1209        a = H[0];
   1210        b = H[1];
   1211        c = H[2];
   1212        d = H[3];
   1213        e = H[4];
   1214        f = H[5];
   1215        g = H[6];
   1216        h = H[7];
   1217 
   1218 #ifdef NOUNROLL512
   1219        {
   1220            int t;
   1221            for (t = 0; t < 80; t += 8) {
   1222                ROUND(t + 0, a, b, c, d, e, f, g, h)
   1223                ROUND(t + 1, h, a, b, c, d, e, f, g)
   1224                ROUND(t + 2, g, h, a, b, c, d, e, f)
   1225                ROUND(t + 3, f, g, h, a, b, c, d, e)
   1226                ROUND(t + 4, e, f, g, h, a, b, c, d)
   1227                ROUND(t + 5, d, e, f, g, h, a, b, c)
   1228                ROUND(t + 6, c, d, e, f, g, h, a, b)
   1229                ROUND(t + 7, b, c, d, e, f, g, h, a)
   1230            }
   1231        }
   1232 #else
   1233        ROUND(0, a, b, c, d, e, f, g, h)
   1234        ROUND(1, h, a, b, c, d, e, f, g)
   1235        ROUND(2, g, h, a, b, c, d, e, f)
   1236        ROUND(3, f, g, h, a, b, c, d, e)
   1237        ROUND(4, e, f, g, h, a, b, c, d)
   1238        ROUND(5, d, e, f, g, h, a, b, c)
   1239        ROUND(6, c, d, e, f, g, h, a, b)
   1240        ROUND(7, b, c, d, e, f, g, h, a)
   1241 
   1242        ROUND(8, a, b, c, d, e, f, g, h)
   1243        ROUND(9, h, a, b, c, d, e, f, g)
   1244        ROUND(10, g, h, a, b, c, d, e, f)
   1245        ROUND(11, f, g, h, a, b, c, d, e)
   1246        ROUND(12, e, f, g, h, a, b, c, d)
   1247        ROUND(13, d, e, f, g, h, a, b, c)
   1248        ROUND(14, c, d, e, f, g, h, a, b)
   1249        ROUND(15, b, c, d, e, f, g, h, a)
   1250 
   1251        ROUND(16, a, b, c, d, e, f, g, h)
   1252        ROUND(17, h, a, b, c, d, e, f, g)
   1253        ROUND(18, g, h, a, b, c, d, e, f)
   1254        ROUND(19, f, g, h, a, b, c, d, e)
   1255        ROUND(20, e, f, g, h, a, b, c, d)
   1256        ROUND(21, d, e, f, g, h, a, b, c)
   1257        ROUND(22, c, d, e, f, g, h, a, b)
   1258        ROUND(23, b, c, d, e, f, g, h, a)
   1259 
   1260        ROUND(24, a, b, c, d, e, f, g, h)
   1261        ROUND(25, h, a, b, c, d, e, f, g)
   1262        ROUND(26, g, h, a, b, c, d, e, f)
   1263        ROUND(27, f, g, h, a, b, c, d, e)
   1264        ROUND(28, e, f, g, h, a, b, c, d)
   1265        ROUND(29, d, e, f, g, h, a, b, c)
   1266        ROUND(30, c, d, e, f, g, h, a, b)
   1267        ROUND(31, b, c, d, e, f, g, h, a)
   1268 
   1269        ROUND(32, a, b, c, d, e, f, g, h)
   1270        ROUND(33, h, a, b, c, d, e, f, g)
   1271        ROUND(34, g, h, a, b, c, d, e, f)
   1272        ROUND(35, f, g, h, a, b, c, d, e)
   1273        ROUND(36, e, f, g, h, a, b, c, d)
   1274        ROUND(37, d, e, f, g, h, a, b, c)
   1275        ROUND(38, c, d, e, f, g, h, a, b)
   1276        ROUND(39, b, c, d, e, f, g, h, a)
   1277 
   1278        ROUND(40, a, b, c, d, e, f, g, h)
   1279        ROUND(41, h, a, b, c, d, e, f, g)
   1280        ROUND(42, g, h, a, b, c, d, e, f)
   1281        ROUND(43, f, g, h, a, b, c, d, e)
   1282        ROUND(44, e, f, g, h, a, b, c, d)
   1283        ROUND(45, d, e, f, g, h, a, b, c)
   1284        ROUND(46, c, d, e, f, g, h, a, b)
   1285        ROUND(47, b, c, d, e, f, g, h, a)
   1286 
   1287        ROUND(48, a, b, c, d, e, f, g, h)
   1288        ROUND(49, h, a, b, c, d, e, f, g)
   1289        ROUND(50, g, h, a, b, c, d, e, f)
   1290        ROUND(51, f, g, h, a, b, c, d, e)
   1291        ROUND(52, e, f, g, h, a, b, c, d)
   1292        ROUND(53, d, e, f, g, h, a, b, c)
   1293        ROUND(54, c, d, e, f, g, h, a, b)
   1294        ROUND(55, b, c, d, e, f, g, h, a)
   1295 
   1296        ROUND(56, a, b, c, d, e, f, g, h)
   1297        ROUND(57, h, a, b, c, d, e, f, g)
   1298        ROUND(58, g, h, a, b, c, d, e, f)
   1299        ROUND(59, f, g, h, a, b, c, d, e)
   1300        ROUND(60, e, f, g, h, a, b, c, d)
   1301        ROUND(61, d, e, f, g, h, a, b, c)
   1302        ROUND(62, c, d, e, f, g, h, a, b)
   1303        ROUND(63, b, c, d, e, f, g, h, a)
   1304 
   1305        ROUND(64, a, b, c, d, e, f, g, h)
   1306        ROUND(65, h, a, b, c, d, e, f, g)
   1307        ROUND(66, g, h, a, b, c, d, e, f)
   1308        ROUND(67, f, g, h, a, b, c, d, e)
   1309        ROUND(68, e, f, g, h, a, b, c, d)
   1310        ROUND(69, d, e, f, g, h, a, b, c)
   1311        ROUND(70, c, d, e, f, g, h, a, b)
   1312        ROUND(71, b, c, d, e, f, g, h, a)
   1313 
   1314        ROUND(72, a, b, c, d, e, f, g, h)
   1315        ROUND(73, h, a, b, c, d, e, f, g)
   1316        ROUND(74, g, h, a, b, c, d, e, f)
   1317        ROUND(75, f, g, h, a, b, c, d, e)
   1318        ROUND(76, e, f, g, h, a, b, c, d)
   1319        ROUND(77, d, e, f, g, h, a, b, c)
   1320        ROUND(78, c, d, e, f, g, h, a, b)
   1321        ROUND(79, b, c, d, e, f, g, h, a)
   1322 #endif
   1323 
   1324        ADDTO(a, H[0]);
   1325        ADDTO(b, H[1]);
   1326        ADDTO(c, H[2]);
   1327        ADDTO(d, H[3]);
   1328        ADDTO(e, H[4]);
   1329        ADDTO(f, H[5]);
   1330        ADDTO(g, H[6]);
   1331        ADDTO(h, H[7]);
   1332    }
   1333 
   1334 #endif /* !USE_PPC_CRYPTO */
   1335 }
   1336 
   1337 void
   1338 SHA512_Update(SHA512Context *ctx, const unsigned char *input,
   1339              unsigned int inputLen)
   1340 {
   1341    unsigned int inBuf;
   1342    if (!inputLen)
   1343        return;
   1344 
   1345 #if defined(HAVE_LONG_LONG)
   1346    inBuf = (unsigned int)ctx->sizeLo & 0x7f;
   1347    /* Add inputLen into the count of bytes processed, before processing */
   1348    ctx->sizeLo += inputLen;
   1349 #else
   1350    inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
   1351    ctx->sizeLo.lo += inputLen;
   1352    if (ctx->sizeLo.lo < inputLen)
   1353        ctx->sizeLo.hi++;
   1354 #endif
   1355 
   1356    /* if data already in buffer, attemp to fill rest of buffer */
   1357    if (inBuf) {
   1358        unsigned int todo = SHA512_BLOCK_LENGTH - inBuf;
   1359        if (inputLen < todo)
   1360            todo = inputLen;
   1361        memcpy(B + inBuf, input, todo);
   1362        input += todo;
   1363        inputLen -= todo;
   1364        if (inBuf + todo == SHA512_BLOCK_LENGTH)
   1365            SHA512_Compress(ctx);
   1366    }
   1367 
   1368    /* if enough data to fill one or more whole buffers, process them. */
   1369    while (inputLen >= SHA512_BLOCK_LENGTH) {
   1370        memcpy(B, input, SHA512_BLOCK_LENGTH);
   1371        input += SHA512_BLOCK_LENGTH;
   1372        inputLen -= SHA512_BLOCK_LENGTH;
   1373        SHA512_Compress(ctx);
   1374    }
   1375    /* if data left over, fill it into buffer */
   1376    if (inputLen)
   1377        memcpy(B, input, inputLen);
   1378 }
   1379 
   1380 void
   1381 SHA512_End(SHA512Context *ctx, unsigned char *digest,
   1382           unsigned int *digestLen, unsigned int maxDigestLen)
   1383 {
   1384 #if defined(HAVE_LONG_LONG)
   1385    unsigned int inBuf = (unsigned int)ctx->sizeLo & 0x7f;
   1386 #else
   1387    unsigned int inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
   1388 #endif
   1389    unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
   1390    PRUint64 lo;
   1391    LL_SHL(lo, ctx->sizeLo, 3);
   1392 
   1393    SHA512_Update(ctx, pad, padLen);
   1394 
   1395 #if defined(HAVE_LONG_LONG)
   1396    W[14] = 0;
   1397 #else
   1398    W[14].lo = 0;
   1399    W[14].hi = 0;
   1400 #endif
   1401 
   1402    W[15] = lo;
   1403 #if defined(IS_LITTLE_ENDIAN)
   1404    BYTESWAP8(W[15]);
   1405 #endif
   1406    SHA512_Compress(ctx);
   1407 
   1408 /* now output the answer */
   1409 #if defined(IS_LITTLE_ENDIAN)
   1410    BYTESWAP8(H[0]);
   1411    BYTESWAP8(H[1]);
   1412    BYTESWAP8(H[2]);
   1413    BYTESWAP8(H[3]);
   1414    BYTESWAP8(H[4]);
   1415    BYTESWAP8(H[5]);
   1416    BYTESWAP8(H[6]);
   1417    BYTESWAP8(H[7]);
   1418 #endif
   1419    padLen = PR_MIN(SHA512_LENGTH, maxDigestLen);
   1420    memcpy(digest, H, padLen);
   1421    if (digestLen)
   1422        *digestLen = padLen;
   1423 }
   1424 
   1425 void
   1426 SHA512_EndRaw(SHA512Context *ctx, unsigned char *digest,
   1427              unsigned int *digestLen, unsigned int maxDigestLen)
   1428 {
   1429    PRUint64 h[8];
   1430    unsigned int len;
   1431 
   1432    memcpy(h, ctx->h, sizeof(h));
   1433 
   1434 #if defined(IS_LITTLE_ENDIAN)
   1435    BYTESWAP8(h[0]);
   1436    BYTESWAP8(h[1]);
   1437    BYTESWAP8(h[2]);
   1438    BYTESWAP8(h[3]);
   1439    BYTESWAP8(h[4]);
   1440    BYTESWAP8(h[5]);
   1441    BYTESWAP8(h[6]);
   1442    BYTESWAP8(h[7]);
   1443 #endif
   1444    len = PR_MIN(SHA512_LENGTH, maxDigestLen);
   1445    memcpy(digest, h, len);
   1446    if (digestLen)
   1447        *digestLen = len;
   1448 }
   1449 
   1450 SECStatus
   1451 SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
   1452               PRUint32 src_length)
   1453 {
   1454    SHA512Context ctx;
   1455    unsigned int outLen;
   1456 
   1457    SHA512_Begin(&ctx);
   1458    SHA512_Update(&ctx, src, src_length);
   1459    SHA512_End(&ctx, dest, &outLen, SHA512_LENGTH);
   1460    memset(&ctx, 0, sizeof ctx);
   1461 
   1462    return SECSuccess;
   1463 }
   1464 
   1465 SECStatus
   1466 SHA512_Hash(unsigned char *dest, const char *src)
   1467 {
   1468    return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
   1469 }
   1470 
   1471 void
   1472 SHA512_TraceState(SHA512Context *ctx)
   1473 {
   1474 }
   1475 
   1476 unsigned int
   1477 SHA512_FlattenSize(SHA512Context *ctx)
   1478 {
   1479    return sizeof *ctx;
   1480 }
   1481 
   1482 SECStatus
   1483 SHA512_Flatten(SHA512Context *ctx, unsigned char *space)
   1484 {
   1485    PORT_Memcpy(space, ctx, sizeof *ctx);
   1486    return SECSuccess;
   1487 }
   1488 
   1489 SHA512Context *
   1490 SHA512_Resurrect(unsigned char *space, void *arg)
   1491 {
   1492    SHA512Context *ctx = SHA512_NewContext();
   1493    if (ctx)
   1494        PORT_Memcpy(ctx, space, sizeof *ctx);
   1495    return ctx;
   1496 }
   1497 
   1498 void
   1499 SHA512_Clone(SHA512Context *dest, SHA512Context *src)
   1500 {
   1501    memcpy(dest, src, sizeof *dest);
   1502 }
   1503 
   1504 /* ======================================================================= */
   1505 /* SHA384 uses a SHA512Context as the real context.
   1506 ** The only differences between SHA384 an SHA512 are:
   1507 ** a) the intialization values for the context, and
   1508 ** b) the number of bytes of data produced as output.
   1509 */
   1510 
   1511 /* SHA-384 initial hash values */
   1512 static const PRUint64 H384[8] = {
   1513 #if PR_BYTES_PER_LONG == 8
   1514    0xcbbb9d5dc1059ed8UL, 0x629a292a367cd507UL,
   1515    0x9159015a3070dd17UL, 0x152fecd8f70e5939UL,
   1516    0x67332667ffc00b31UL, 0x8eb44a8768581511UL,
   1517    0xdb0c2e0d64f98fa7UL, 0x47b5481dbefa4fa4UL
   1518 #else
   1519    ULLC(cbbb9d5d, c1059ed8), ULLC(629a292a, 367cd507),
   1520    ULLC(9159015a, 3070dd17), ULLC(152fecd8, f70e5939),
   1521    ULLC(67332667, ffc00b31), ULLC(8eb44a87, 68581511),
   1522    ULLC(db0c2e0d, 64f98fa7), ULLC(47b5481d, befa4fa4)
   1523 #endif
   1524 };
   1525 
   1526 SHA384Context *
   1527 SHA384_NewContext(void)
   1528 {
   1529    return SHA512_NewContext();
   1530 }
   1531 
   1532 void
   1533 SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit)
   1534 {
   1535    SHA512_DestroyContext(ctx, freeit);
   1536 }
   1537 
   1538 void
   1539 SHA384_Begin(SHA384Context *ctx)
   1540 {
   1541    memset(ctx, 0, sizeof *ctx);
   1542    memcpy(H, H384, sizeof H384);
   1543 }
   1544 
   1545 void
   1546 SHA384_Update(SHA384Context *ctx, const unsigned char *input,
   1547              unsigned int inputLen)
   1548 {
   1549    SHA512_Update(ctx, input, inputLen);
   1550 }
   1551 
   1552 void
   1553 SHA384_End(SHA384Context *ctx, unsigned char *digest,
   1554           unsigned int *digestLen, unsigned int maxDigestLen)
   1555 {
   1556    unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
   1557    SHA512_End(ctx, digest, digestLen, maxLen);
   1558 }
   1559 
   1560 void
   1561 SHA384_EndRaw(SHA384Context *ctx, unsigned char *digest,
   1562              unsigned int *digestLen, unsigned int maxDigestLen)
   1563 {
   1564    unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
   1565    SHA512_EndRaw(ctx, digest, digestLen, maxLen);
   1566 }
   1567 
   1568 SECStatus
   1569 SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
   1570               PRUint32 src_length)
   1571 {
   1572    SHA512Context ctx;
   1573    unsigned int outLen;
   1574 
   1575    SHA384_Begin(&ctx);
   1576    SHA512_Update(&ctx, src, src_length);
   1577    SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH);
   1578    memset(&ctx, 0, sizeof ctx);
   1579 
   1580    return SECSuccess;
   1581 }
   1582 
   1583 SECStatus
   1584 SHA384_Hash(unsigned char *dest, const char *src)
   1585 {
   1586    return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
   1587 }
   1588 
   1589 void
   1590 SHA384_TraceState(SHA384Context *ctx)
   1591 {
   1592 }
   1593 
   1594 unsigned int
   1595 SHA384_FlattenSize(SHA384Context *ctx)
   1596 {
   1597    return sizeof(SHA384Context);
   1598 }
   1599 
   1600 SECStatus
   1601 SHA384_Flatten(SHA384Context *ctx, unsigned char *space)
   1602 {
   1603    return SHA512_Flatten(ctx, space);
   1604 }
   1605 
   1606 SHA384Context *
   1607 SHA384_Resurrect(unsigned char *space, void *arg)
   1608 {
   1609    return SHA512_Resurrect(space, arg);
   1610 }
   1611 
   1612 void
   1613 SHA384_Clone(SHA384Context *dest, SHA384Context *src)
   1614 {
   1615    memcpy(dest, src, sizeof *dest);
   1616 }
   1617 
   1618 /* ======================================================================= */
   1619 #ifdef SELFTEST
   1620 #include <stdio.h>
   1621 
   1622 static const char abc[] = { "abc" };
   1623 static const char abcdbc[] = {
   1624    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
   1625 };
   1626 static const char abcdef[] = {
   1627    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
   1628    "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
   1629 };
   1630 
   1631 void
   1632 dumpHash32(const unsigned char *buf, unsigned int bufLen)
   1633 {
   1634    unsigned int i;
   1635    for (i = 0; i < bufLen; i += 4) {
   1636        printf(" %02x%02x%02x%02x", buf[i], buf[i + 1], buf[i + 2], buf[i + 3]);
   1637    }
   1638    printf("\n");
   1639 }
   1640 
   1641 void
   1642 test256(void)
   1643 {
   1644    unsigned char outBuf[SHA256_LENGTH];
   1645 
   1646    printf("SHA256, input = %s\n", abc);
   1647    SHA256_Hash(outBuf, abc);
   1648    dumpHash32(outBuf, sizeof outBuf);
   1649 
   1650    printf("SHA256, input = %s\n", abcdbc);
   1651    SHA256_Hash(outBuf, abcdbc);
   1652    dumpHash32(outBuf, sizeof outBuf);
   1653 }
   1654 
   1655 void
   1656 test224(void)
   1657 {
   1658    SHA224Context ctx;
   1659    unsigned char a1000times[1000];
   1660    unsigned int outLen;
   1661    unsigned char outBuf[SHA224_LENGTH];
   1662    int i;
   1663 
   1664    /* Test Vector 1 */
   1665    printf("SHA224, input = %s\n", abc);
   1666    SHA224_Hash(outBuf, abc);
   1667    dumpHash32(outBuf, sizeof outBuf);
   1668 
   1669    /* Test Vector 2 */
   1670    printf("SHA224, input = %s\n", abcdbc);
   1671    SHA224_Hash(outBuf, abcdbc);
   1672    dumpHash32(outBuf, sizeof outBuf);
   1673 
   1674    /* Test Vector 3 */
   1675 
   1676    /* to hash one million 'a's perform 1000
   1677     * sha224 updates on a buffer with 1000 'a's
   1678     */
   1679    memset(a1000times, 'a', 1000);
   1680    printf("SHA224, input = %s\n", "a one million times");
   1681    SHA224_Begin(&ctx);
   1682    for (i = 0; i < 1000; i++)
   1683        SHA224_Update(&ctx, a1000times, 1000);
   1684    SHA224_End(&ctx, outBuf, &outLen, SHA224_LENGTH);
   1685    dumpHash32(outBuf, sizeof outBuf);
   1686 }
   1687 
   1688 void
   1689 dumpHash64(const unsigned char *buf, unsigned int bufLen)
   1690 {
   1691    unsigned int i;
   1692    for (i = 0; i < bufLen; i += 8) {
   1693        if (i % 32 == 0)
   1694            printf("\n");
   1695        printf(" %02x%02x%02x%02x%02x%02x%02x%02x",
   1696               buf[i], buf[i + 1], buf[i + 2], buf[i + 3],
   1697               buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]);
   1698    }
   1699    printf("\n");
   1700 }
   1701 
   1702 void
   1703 test512(void)
   1704 {
   1705    unsigned char outBuf[SHA512_LENGTH];
   1706 
   1707    printf("SHA512, input = %s\n", abc);
   1708    SHA512_Hash(outBuf, abc);
   1709    dumpHash64(outBuf, sizeof outBuf);
   1710 
   1711    printf("SHA512, input = %s\n", abcdef);
   1712    SHA512_Hash(outBuf, abcdef);
   1713    dumpHash64(outBuf, sizeof outBuf);
   1714 }
   1715 
   1716 void
   1717 time512(void)
   1718 {
   1719    unsigned char outBuf[SHA512_LENGTH];
   1720 
   1721    SHA512_Hash(outBuf, abc);
   1722    SHA512_Hash(outBuf, abcdef);
   1723 }
   1724 
   1725 void
   1726 test384(void)
   1727 {
   1728    unsigned char outBuf[SHA384_LENGTH];
   1729 
   1730    printf("SHA384, input = %s\n", abc);
   1731    SHA384_Hash(outBuf, abc);
   1732    dumpHash64(outBuf, sizeof outBuf);
   1733 
   1734    printf("SHA384, input = %s\n", abcdef);
   1735    SHA384_Hash(outBuf, abcdef);
   1736    dumpHash64(outBuf, sizeof outBuf);
   1737 }
   1738 
   1739 int
   1740 main(int argc, char *argv[], char *envp[])
   1741 {
   1742    int i = 1;
   1743    if (argc > 1) {
   1744        i = atoi(argv[1]);
   1745    }
   1746    if (i < 2) {
   1747        test224();
   1748        test256();
   1749        test384();
   1750        test512();
   1751    } else {
   1752        while (i-- > 0) {
   1753            time512();
   1754        }
   1755        printf("done\n");
   1756    }
   1757    return 0;
   1758 }
   1759 
   1760 void *
   1761 PORT_Alloc(size_t len)
   1762 {
   1763    return malloc(len);
   1764 }
   1765 void
   1766 PORT_Free(void *ptr)
   1767 {
   1768    free(ptr);
   1769 }
   1770 void
   1771 PORT_ZFree(void *ptr, size_t len)
   1772 {
   1773    memset(ptr, 0, len);
   1774    free(ptr);
   1775 }
   1776 #endif