tor-browser

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

sha_fast.c (17065B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifdef FREEBL_NO_DEPEND
      6 #include "stubs.h"
      7 #endif
      8 
      9 #include <memory.h>
     10 #include "blapi.h"
     11 #include "sha_fast.h"
     12 #include "prerror.h"
     13 #include "secerr.h"
     14 
     15 #ifdef TRACING_SSL
     16 #include "ssl.h"
     17 #include "ssltrace.h"
     18 #endif
     19 
     20 static void shaCompress(volatile SHA_HW_t *X, const PRUint32 *datain);
     21 
     22 #define W u.w
     23 #define B u.b
     24 
     25 #define SHA_F1(X, Y, Z) ((((Y) ^ (Z)) & (X)) ^ (Z))
     26 #define SHA_F2(X, Y, Z) ((X) ^ (Y) ^ (Z))
     27 #define SHA_F3(X, Y, Z) (((X) & (Y)) | ((Z) & ((X) | (Y))))
     28 #define SHA_F4(X, Y, Z) ((X) ^ (Y) ^ (Z))
     29 
     30 #define SHA_MIX(n, a, b, c) XW(n) = SHA_ROTL(XW(a) ^ XW(b) ^ XW(c) ^ XW(n), 1)
     31 
     32 void SHA1_Compress_Native(SHA1Context *ctx);
     33 void SHA1_Update_Native(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len);
     34 
     35 static void SHA1_Compress_Generic(SHA1Context *ctx);
     36 static void SHA1_Update_Generic(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len);
     37 
     38 #ifndef USE_HW_SHA1
     39 void
     40 SHA1_Compress_Native(SHA1Context *ctx)
     41 {
     42    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
     43    PORT_Assert(0);
     44 }
     45 
     46 void
     47 SHA1_Update_Native(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
     48 {
     49    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
     50    PORT_Assert(0);
     51 }
     52 #endif
     53 
     54 /*
     55 *  SHA: initialize context
     56 */
     57 void
     58 SHA1_Begin(SHA1Context *ctx)
     59 {
     60    ctx->size = 0;
     61    /*
     62     *  Initialize H with constants from FIPS180-1.
     63     */
     64    ctx->H[0] = 0x67452301L;
     65    ctx->H[1] = 0xefcdab89L;
     66    ctx->H[2] = 0x98badcfeL;
     67    ctx->H[3] = 0x10325476L;
     68    ctx->H[4] = 0xc3d2e1f0L;
     69 
     70 #if defined(USE_HW_SHA1) && defined(IS_LITTLE_ENDIAN)
     71    /* arm's implementation is tested on little endian only */
     72    if (arm_sha1_support()) {
     73        ctx->compress = SHA1_Compress_Native;
     74        ctx->update = SHA1_Update_Native;
     75    } else
     76 #endif
     77    {
     78        ctx->compress = SHA1_Compress_Generic;
     79        ctx->update = SHA1_Update_Generic;
     80    }
     81 }
     82 
     83 /* Explanation of H array and index values:
     84 * The context's H array is actually the concatenation of two arrays
     85 * defined by SHA1, the H array of state variables (5 elements),
     86 * and the W array of intermediate values, of which there are 16 elements.
     87 * The W array starts at H[5], that is W[0] is H[5].
     88 * Although these values are defined as 32-bit values, we use 64-bit
     89 * variables to hold them because the AMD64 stores 64 bit values in
     90 * memory MUCH faster than it stores any smaller values.
     91 *
     92 * Rather than passing the context structure to shaCompress, we pass
     93 * this combined array of H and W values.  We do not pass the address
     94 * of the first element of this array, but rather pass the address of an
     95 * element in the middle of the array, element X.  Presently X[0] is H[11].
     96 * So we pass the address of H[11] as the address of array X to shaCompress.
     97 * Then shaCompress accesses the members of the array using positive AND
     98 * negative indexes.
     99 *
    100 * Pictorially: (each element is 8 bytes)
    101 * H | H0 H1 H2 H3 H4 W0 W1 W2 W3 W4 W5 W6 W7 W8 W9 Wa Wb Wc Wd We Wf |
    102 * X |-11-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 |
    103 *
    104 * The byte offset from X[0] to any member of H and W is always
    105 * representable in a signed 8-bit value, which will be encoded
    106 * as a single byte offset in the X86-64 instruction set.
    107 * If we didn't pass the address of H[11], and instead passed the
    108 * address of H[0], the offsets to elements H[16] and above would be
    109 * greater than 127, not representable in a signed 8-bit value, and the
    110 * x86-64 instruction set would encode every such offset as a 32-bit
    111 * signed number in each instruction that accessed element H[16] or
    112 * higher.  This results in much bigger and slower code.
    113 */
    114 #if !defined(SHA_PUT_W_IN_STACK)
    115 #define H2X 11 /* X[0] is H[11], and H[0] is X[-11] */
    116 #define W2X 6  /* X[0] is W[6],  and W[0] is X[-6]  */
    117 #else
    118 #define H2X 0
    119 #endif
    120 
    121 /*
    122 *  SHA: Add data to context.
    123 */
    124 void
    125 SHA1_Update(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
    126 {
    127    ctx->update(ctx, dataIn, len);
    128 }
    129 
    130 static void
    131 SHA1_Update_Generic(SHA1Context *ctx, const unsigned char *dataIn, unsigned int len)
    132 {
    133    register unsigned int lenB;
    134    register unsigned int togo;
    135 
    136    if (!len)
    137        return;
    138 
    139    /* accumulate the byte count. */
    140    lenB = (unsigned int)(ctx->size) & 63U;
    141 
    142    ctx->size += len;
    143 
    144    /*
    145     *  Read the data into W and process blocks as they get full
    146     */
    147    if (lenB > 0) {
    148        togo = 64U - lenB;
    149        if (len < togo)
    150            togo = len;
    151        memcpy(ctx->B + lenB, dataIn, togo);
    152        len -= togo;
    153        dataIn += togo;
    154        lenB = (lenB + togo) & 63U;
    155        if (!lenB) {
    156            shaCompress(&ctx->H[H2X], ctx->W);
    157        }
    158    }
    159 #if !defined(HAVE_UNALIGNED_ACCESS)
    160    if ((ptrdiff_t)dataIn % sizeof(PRUint32)) {
    161        while (len >= 64U) {
    162            memcpy(ctx->B, dataIn, 64);
    163            len -= 64U;
    164            shaCompress(&ctx->H[H2X], ctx->W);
    165            dataIn += 64U;
    166        }
    167    } else
    168 #endif
    169    {
    170        while (len >= 64U) {
    171            len -= 64U;
    172            shaCompress(&ctx->H[H2X], (PRUint32 *)dataIn);
    173            dataIn += 64U;
    174        }
    175    }
    176    if (len) {
    177        memcpy(ctx->B, dataIn, len);
    178    }
    179 }
    180 
    181 /*
    182 *  SHA: Generate hash value from context
    183 */
    184 void NO_SANITIZE_ALIGNMENT
    185 SHA1_End(SHA1Context *ctx, unsigned char *hashout,
    186         unsigned int *pDigestLen, unsigned int maxDigestLen)
    187 {
    188    register PRUint64 size;
    189    register PRUint32 lenB;
    190 
    191    static const unsigned char bulk_pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    192                                                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,
    193                                                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 };
    194 #define tmp lenB
    195 
    196    PORT_Assert(maxDigestLen >= SHA1_LENGTH);
    197 
    198    /*
    199     *  Pad with a binary 1 (e.g. 0x80), then zeroes, then length in bits
    200     */
    201    size = ctx->size;
    202 
    203    lenB = (PRUint32)size & 63;
    204    SHA1_Update(ctx, bulk_pad, (((55 + 64) - lenB) & 63) + 1);
    205    PORT_Assert(((PRUint32)ctx->size & 63) == 56);
    206    /* Convert size from bytes to bits. */
    207    size <<= 3;
    208    ctx->W[14] = SHA_HTONL((PRUint32)(size >> 32));
    209    ctx->W[15] = SHA_HTONL((PRUint32)size);
    210    ctx->compress(ctx);
    211 
    212    /*
    213     *  Output hash
    214     */
    215    SHA_STORE_RESULT;
    216    if (pDigestLen) {
    217        *pDigestLen = SHA1_LENGTH;
    218    }
    219 #undef tmp
    220 }
    221 
    222 void
    223 SHA1_EndRaw(SHA1Context *ctx, unsigned char *hashout,
    224            unsigned int *pDigestLen, unsigned int maxDigestLen)
    225 {
    226 #if defined(SHA_NEED_TMP_VARIABLE)
    227    register PRUint32 tmp;
    228 #endif
    229    PORT_Assert(maxDigestLen >= SHA1_LENGTH);
    230 
    231    SHA_STORE_RESULT;
    232    if (pDigestLen)
    233        *pDigestLen = SHA1_LENGTH;
    234 }
    235 
    236 #undef B
    237 /*
    238 *  SHA: Compression function, unrolled.
    239 *
    240 * Some operations in shaCompress are done as 5 groups of 16 operations.
    241 * Others are done as 4 groups of 20 operations.
    242 * The code below shows that structure.
    243 *
    244 * The functions that compute the new values of the 5 state variables
    245 * A-E are done in 4 groups of 20 operations (or you may also think
    246 * of them as being done in 16 groups of 5 operations).  They are
    247 * done by the SHA_RNDx macros below, in the right column.
    248 *
    249 * The functions that set the 16 values of the W array are done in
    250 * 5 groups of 16 operations.  The first group is done by the
    251 * LOAD macros below, the latter 4 groups are done by SHA_MIX below,
    252 * in the left column.
    253 *
    254 * gcc's optimizer observes that each member of the W array is assigned
    255 * a value 5 times in this code.  It reduces the number of store
    256 * operations done to the W array in the context (that is, in the X array)
    257 * by creating a W array on the stack, and storing the W values there for
    258 * the first 4 groups of operations on W, and storing the values in the
    259 * context's W array only in the fifth group.  This is undesirable.
    260 * It is MUCH bigger code than simply using the context's W array, because
    261 * all the offsets to the W array in the stack are 32-bit signed offsets,
    262 * and it is no faster than storing the values in the context's W array.
    263 *
    264 * The original code for sha_fast.c prevented this creation of a separate
    265 * W array in the stack by creating a W array of 80 members, each of
    266 * whose elements is assigned only once. It also separated the computations
    267 * of the W array values and the computations of the values for the 5
    268 * state variables into two separate passes, W's, then A-E's so that the
    269 * second pass could be done all in registers (except for accessing the W
    270 * array) on machines with fewer registers.  The method is suboptimal
    271 * for machines with enough registers to do it all in one pass, and it
    272 * necessitates using many instructions with 32-bit offsets.
    273 *
    274 * This code eliminates the separate W array on the stack by a completely
    275 * different means: by declaring the X array volatile.  This prevents
    276 * the optimizer from trying to reduce the use of the X array by the
    277 * creation of a MORE expensive W array on the stack. The result is
    278 * that all instructions use signed 8-bit offsets and not 32-bit offsets.
    279 *
    280 * The combination of this code and the -O3 optimizer flag on GCC 3.4.3
    281 * results in code that is 3 times faster than the previous NSS sha_fast
    282 * code on AMD64.
    283 */
    284 static void NO_SANITIZE_ALIGNMENT
    285 shaCompress(volatile SHA_HW_t *X, const PRUint32 *inbuf)
    286 {
    287    register SHA_HW_t A, B, C, D, E;
    288 
    289 #if defined(SHA_NEED_TMP_VARIABLE)
    290    register PRUint32 tmp;
    291 #endif
    292 
    293 #if !defined(SHA_PUT_W_IN_STACK)
    294 #define XH(n) X[n - H2X]
    295 #define XW(n) X[n - W2X]
    296 #else
    297    SHA_HW_t w_0, w_1, w_2, w_3, w_4, w_5, w_6, w_7,
    298        w_8, w_9, w_10, w_11, w_12, w_13, w_14, w_15;
    299 #define XW(n) w_##n
    300 #define XH(n) X[n]
    301 #endif
    302 
    303 #define K0 0x5a827999L
    304 #define K1 0x6ed9eba1L
    305 #define K2 0x8f1bbcdcL
    306 #define K3 0xca62c1d6L
    307 
    308 #define SHA_RND1(a, b, c, d, e, n)                         \
    309    a = SHA_ROTL(b, 5) + SHA_F1(c, d, e) + a + XW(n) + K0; \
    310    c = SHA_ROTL(c, 30)
    311 #define SHA_RND2(a, b, c, d, e, n)                         \
    312    a = SHA_ROTL(b, 5) + SHA_F2(c, d, e) + a + XW(n) + K1; \
    313    c = SHA_ROTL(c, 30)
    314 #define SHA_RND3(a, b, c, d, e, n)                         \
    315    a = SHA_ROTL(b, 5) + SHA_F3(c, d, e) + a + XW(n) + K2; \
    316    c = SHA_ROTL(c, 30)
    317 #define SHA_RND4(a, b, c, d, e, n)                         \
    318    a = SHA_ROTL(b, 5) + SHA_F4(c, d, e) + a + XW(n) + K3; \
    319    c = SHA_ROTL(c, 30)
    320 
    321 #define LOAD(n) XW(n) = SHA_HTONL(inbuf[n])
    322 
    323    A = XH(0);
    324    B = XH(1);
    325    C = XH(2);
    326    D = XH(3);
    327    E = XH(4);
    328 
    329    LOAD(0);
    330    SHA_RND1(E, A, B, C, D, 0);
    331    LOAD(1);
    332    SHA_RND1(D, E, A, B, C, 1);
    333    LOAD(2);
    334    SHA_RND1(C, D, E, A, B, 2);
    335    LOAD(3);
    336    SHA_RND1(B, C, D, E, A, 3);
    337    LOAD(4);
    338    SHA_RND1(A, B, C, D, E, 4);
    339    LOAD(5);
    340    SHA_RND1(E, A, B, C, D, 5);
    341    LOAD(6);
    342    SHA_RND1(D, E, A, B, C, 6);
    343    LOAD(7);
    344    SHA_RND1(C, D, E, A, B, 7);
    345    LOAD(8);
    346    SHA_RND1(B, C, D, E, A, 8);
    347    LOAD(9);
    348    SHA_RND1(A, B, C, D, E, 9);
    349    LOAD(10);
    350    SHA_RND1(E, A, B, C, D, 10);
    351    LOAD(11);
    352    SHA_RND1(D, E, A, B, C, 11);
    353    LOAD(12);
    354    SHA_RND1(C, D, E, A, B, 12);
    355    LOAD(13);
    356    SHA_RND1(B, C, D, E, A, 13);
    357    LOAD(14);
    358    SHA_RND1(A, B, C, D, E, 14);
    359    LOAD(15);
    360    SHA_RND1(E, A, B, C, D, 15);
    361 
    362    SHA_MIX(0, 13, 8, 2);
    363    SHA_RND1(D, E, A, B, C, 0);
    364    SHA_MIX(1, 14, 9, 3);
    365    SHA_RND1(C, D, E, A, B, 1);
    366    SHA_MIX(2, 15, 10, 4);
    367    SHA_RND1(B, C, D, E, A, 2);
    368    SHA_MIX(3, 0, 11, 5);
    369    SHA_RND1(A, B, C, D, E, 3);
    370 
    371    SHA_MIX(4, 1, 12, 6);
    372    SHA_RND2(E, A, B, C, D, 4);
    373    SHA_MIX(5, 2, 13, 7);
    374    SHA_RND2(D, E, A, B, C, 5);
    375    SHA_MIX(6, 3, 14, 8);
    376    SHA_RND2(C, D, E, A, B, 6);
    377    SHA_MIX(7, 4, 15, 9);
    378    SHA_RND2(B, C, D, E, A, 7);
    379    SHA_MIX(8, 5, 0, 10);
    380    SHA_RND2(A, B, C, D, E, 8);
    381    SHA_MIX(9, 6, 1, 11);
    382    SHA_RND2(E, A, B, C, D, 9);
    383    SHA_MIX(10, 7, 2, 12);
    384    SHA_RND2(D, E, A, B, C, 10);
    385    SHA_MIX(11, 8, 3, 13);
    386    SHA_RND2(C, D, E, A, B, 11);
    387    SHA_MIX(12, 9, 4, 14);
    388    SHA_RND2(B, C, D, E, A, 12);
    389    SHA_MIX(13, 10, 5, 15);
    390    SHA_RND2(A, B, C, D, E, 13);
    391    SHA_MIX(14, 11, 6, 0);
    392    SHA_RND2(E, A, B, C, D, 14);
    393    SHA_MIX(15, 12, 7, 1);
    394    SHA_RND2(D, E, A, B, C, 15);
    395 
    396    SHA_MIX(0, 13, 8, 2);
    397    SHA_RND2(C, D, E, A, B, 0);
    398    SHA_MIX(1, 14, 9, 3);
    399    SHA_RND2(B, C, D, E, A, 1);
    400    SHA_MIX(2, 15, 10, 4);
    401    SHA_RND2(A, B, C, D, E, 2);
    402    SHA_MIX(3, 0, 11, 5);
    403    SHA_RND2(E, A, B, C, D, 3);
    404    SHA_MIX(4, 1, 12, 6);
    405    SHA_RND2(D, E, A, B, C, 4);
    406    SHA_MIX(5, 2, 13, 7);
    407    SHA_RND2(C, D, E, A, B, 5);
    408    SHA_MIX(6, 3, 14, 8);
    409    SHA_RND2(B, C, D, E, A, 6);
    410    SHA_MIX(7, 4, 15, 9);
    411    SHA_RND2(A, B, C, D, E, 7);
    412 
    413    SHA_MIX(8, 5, 0, 10);
    414    SHA_RND3(E, A, B, C, D, 8);
    415    SHA_MIX(9, 6, 1, 11);
    416    SHA_RND3(D, E, A, B, C, 9);
    417    SHA_MIX(10, 7, 2, 12);
    418    SHA_RND3(C, D, E, A, B, 10);
    419    SHA_MIX(11, 8, 3, 13);
    420    SHA_RND3(B, C, D, E, A, 11);
    421    SHA_MIX(12, 9, 4, 14);
    422    SHA_RND3(A, B, C, D, E, 12);
    423    SHA_MIX(13, 10, 5, 15);
    424    SHA_RND3(E, A, B, C, D, 13);
    425    SHA_MIX(14, 11, 6, 0);
    426    SHA_RND3(D, E, A, B, C, 14);
    427    SHA_MIX(15, 12, 7, 1);
    428    SHA_RND3(C, D, E, A, B, 15);
    429 
    430    SHA_MIX(0, 13, 8, 2);
    431    SHA_RND3(B, C, D, E, A, 0);
    432    SHA_MIX(1, 14, 9, 3);
    433    SHA_RND3(A, B, C, D, E, 1);
    434    SHA_MIX(2, 15, 10, 4);
    435    SHA_RND3(E, A, B, C, D, 2);
    436    SHA_MIX(3, 0, 11, 5);
    437    SHA_RND3(D, E, A, B, C, 3);
    438    SHA_MIX(4, 1, 12, 6);
    439    SHA_RND3(C, D, E, A, B, 4);
    440    SHA_MIX(5, 2, 13, 7);
    441    SHA_RND3(B, C, D, E, A, 5);
    442    SHA_MIX(6, 3, 14, 8);
    443    SHA_RND3(A, B, C, D, E, 6);
    444    SHA_MIX(7, 4, 15, 9);
    445    SHA_RND3(E, A, B, C, D, 7);
    446    SHA_MIX(8, 5, 0, 10);
    447    SHA_RND3(D, E, A, B, C, 8);
    448    SHA_MIX(9, 6, 1, 11);
    449    SHA_RND3(C, D, E, A, B, 9);
    450    SHA_MIX(10, 7, 2, 12);
    451    SHA_RND3(B, C, D, E, A, 10);
    452    SHA_MIX(11, 8, 3, 13);
    453    SHA_RND3(A, B, C, D, E, 11);
    454 
    455    SHA_MIX(12, 9, 4, 14);
    456    SHA_RND4(E, A, B, C, D, 12);
    457    SHA_MIX(13, 10, 5, 15);
    458    SHA_RND4(D, E, A, B, C, 13);
    459    SHA_MIX(14, 11, 6, 0);
    460    SHA_RND4(C, D, E, A, B, 14);
    461    SHA_MIX(15, 12, 7, 1);
    462    SHA_RND4(B, C, D, E, A, 15);
    463 
    464    SHA_MIX(0, 13, 8, 2);
    465    SHA_RND4(A, B, C, D, E, 0);
    466    SHA_MIX(1, 14, 9, 3);
    467    SHA_RND4(E, A, B, C, D, 1);
    468    SHA_MIX(2, 15, 10, 4);
    469    SHA_RND4(D, E, A, B, C, 2);
    470    SHA_MIX(3, 0, 11, 5);
    471    SHA_RND4(C, D, E, A, B, 3);
    472    SHA_MIX(4, 1, 12, 6);
    473    SHA_RND4(B, C, D, E, A, 4);
    474    SHA_MIX(5, 2, 13, 7);
    475    SHA_RND4(A, B, C, D, E, 5);
    476    SHA_MIX(6, 3, 14, 8);
    477    SHA_RND4(E, A, B, C, D, 6);
    478    SHA_MIX(7, 4, 15, 9);
    479    SHA_RND4(D, E, A, B, C, 7);
    480    SHA_MIX(8, 5, 0, 10);
    481    SHA_RND4(C, D, E, A, B, 8);
    482    SHA_MIX(9, 6, 1, 11);
    483    SHA_RND4(B, C, D, E, A, 9);
    484    SHA_MIX(10, 7, 2, 12);
    485    SHA_RND4(A, B, C, D, E, 10);
    486    SHA_MIX(11, 8, 3, 13);
    487    SHA_RND4(E, A, B, C, D, 11);
    488    SHA_MIX(12, 9, 4, 14);
    489    SHA_RND4(D, E, A, B, C, 12);
    490    SHA_MIX(13, 10, 5, 15);
    491    SHA_RND4(C, D, E, A, B, 13);
    492    SHA_MIX(14, 11, 6, 0);
    493    SHA_RND4(B, C, D, E, A, 14);
    494    SHA_MIX(15, 12, 7, 1);
    495    SHA_RND4(A, B, C, D, E, 15);
    496 
    497    XH(0) += A;
    498    XH(1) += B;
    499    XH(2) += C;
    500    XH(3) += D;
    501    XH(4) += E;
    502 }
    503 
    504 static void
    505 SHA1_Compress_Generic(SHA1Context *ctx)
    506 {
    507    shaCompress(&ctx->H[H2X], ctx->u.w);
    508 }
    509 
    510 /*************************************************************************
    511 ** Code below this line added to make SHA code support BLAPI interface
    512 */
    513 
    514 SHA1Context *
    515 SHA1_NewContext(void)
    516 {
    517    SHA1Context *cx;
    518 
    519    /* no need to ZNew, SHA1_Begin will init the context */
    520    cx = PORT_New(SHA1Context);
    521    return cx;
    522 }
    523 
    524 /* Zero and free the context */
    525 void
    526 SHA1_DestroyContext(SHA1Context *cx, PRBool freeit)
    527 {
    528    memset(cx, 0, sizeof *cx);
    529    if (freeit) {
    530        PORT_Free(cx);
    531    }
    532 }
    533 
    534 SECStatus
    535 SHA1_HashBuf(unsigned char *dest, const unsigned char *src, PRUint32 src_length)
    536 {
    537    SHA1Context ctx;
    538    unsigned int outLen;
    539 
    540    SHA1_Begin(&ctx);
    541    ctx.update(&ctx, src, src_length);
    542    SHA1_End(&ctx, dest, &outLen, SHA1_LENGTH);
    543    memset(&ctx, 0, sizeof ctx);
    544    return SECSuccess;
    545 }
    546 
    547 /* Hash a null-terminated character string. */
    548 SECStatus
    549 SHA1_Hash(unsigned char *dest, const char *src)
    550 {
    551    return SHA1_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
    552 }
    553 
    554 /*
    555 * need to support save/restore state in pkcs11. Stores all the info necessary
    556 * for a structure into just a stream of bytes.
    557 */
    558 unsigned int
    559 SHA1_FlattenSize(SHA1Context *cx)
    560 {
    561    return sizeof(SHA1Context);
    562 }
    563 
    564 SECStatus
    565 SHA1_Flatten(SHA1Context *cx, unsigned char *space)
    566 {
    567    PORT_Memcpy(space, cx, sizeof(SHA1Context));
    568    return SECSuccess;
    569 }
    570 
    571 SHA1Context *
    572 SHA1_Resurrect(unsigned char *space, void *arg)
    573 {
    574    SHA1Context *cx = SHA1_NewContext();
    575    if (cx == NULL)
    576        return NULL;
    577 
    578    PORT_Memcpy(cx, space, sizeof(SHA1Context));
    579    return cx;
    580 }
    581 
    582 void
    583 SHA1_Clone(SHA1Context *dest, SHA1Context *src)
    584 {
    585    memcpy(dest, src, sizeof *dest);
    586 }
    587 
    588 void
    589 SHA1_TraceState(SHA1Context *ctx)
    590 {
    591    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    592 }