Back to index

php5  5.3.10
hash_sha.c
Go to the documentation of this file.
00001 /*
00002   +----------------------------------------------------------------------+
00003   | PHP Version 5                                                        |
00004   +----------------------------------------------------------------------+
00005   | Copyright (c) 1997-2012 The PHP Group                                |
00006   +----------------------------------------------------------------------+
00007   | This source file is subject to version 3.01 of the PHP license,      |
00008   | that is bundled with this package in the file LICENSE, and is        |
00009   | available through the world-wide-web at the following url:           |
00010   | http://www.php.net/license/3_01.txt                                  |
00011   | If you did not receive a copy of the PHP license and are unable to   |
00012   | obtain it through the world-wide-web, please send a note to          |
00013   | license@php.net so we can mail you a copy immediately.               |
00014   +----------------------------------------------------------------------+
00015   | Authors: Steffan Esser <sesser@php.net>                              |
00016   |          Sara Golemon <pollita@php.net>                              |
00017   +----------------------------------------------------------------------+
00018 */
00019 
00020 /* $Id: hash_sha.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #include "php_hash.h"
00023 #include "php_hash_sha.h"
00024 
00025 static const unsigned char PADDING[128] =
00026 {
00027        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00028        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00029        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00030        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00031        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00032        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00033        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00034        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00035 };
00036 
00037 /* {{{ SHAEncode32
00038    Encodes input (php_hash_uint32) into output (unsigned char). Assumes len is
00039    a multiple of 4.
00040  */
00041 static void SHAEncode32(unsigned char *output, php_hash_uint32 *input, unsigned int len)
00042 {
00043        unsigned int i, j;
00044 
00045        for (i = 0, j = 0; j < len; i++, j += 4) {
00046               output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
00047               output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
00048               output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
00049               output[j + 3] = (unsigned char) (input[i] & 0xff);
00050        }
00051 }
00052 /* }}} */
00053 
00054 
00055 /* {{{ SHADecode32
00056    Decodes input (unsigned char) into output (php_hash_uint32). Assumes len is
00057    a multiple of 4.
00058  */
00059 static void SHADecode32(php_hash_uint32 *output, const unsigned char *input, unsigned int len)
00060 {
00061        unsigned int i, j;
00062 
00063        for (i = 0, j = 0; j < len; i++, j += 4)
00064               output[i] = ((php_hash_uint32) input[j + 3]) | (((php_hash_uint32) input[j + 2]) << 8) |
00065                      (((php_hash_uint32) input[j + 1]) << 16) | (((php_hash_uint32) input[j]) << 24);
00066 }
00067 /* }}} */
00068 
00069 const php_hash_ops php_hash_sha1_ops = {
00070        (php_hash_init_func_t) PHP_SHA1Init,
00071        (php_hash_update_func_t) PHP_SHA1Update,
00072        (php_hash_final_func_t) PHP_SHA1Final,
00073        (php_hash_copy_func_t) php_hash_copy,
00074        20,
00075        64,
00076        sizeof(PHP_SHA1_CTX)
00077 };
00078 
00079 #ifdef PHP_HASH_SHA1_NOT_IN_CORE
00080 
00081 PHP_HASH_API void make_sha1_digest(char *sha1str, unsigned char *digest)
00082 {
00083        php_hash_bin2hex(sha1str, digest, 20);
00084        sha1str[40] = '\0';
00085 }
00086 
00087 /* {{{ proto string sha1(string str [, bool raw_output])
00088    Calculate the sha1 hash of a string */
00089 PHP_FUNCTION(sha1)
00090 {
00091        char *arg;
00092        int arg_len;
00093        zend_bool raw_output = 0;
00094        char sha1str[41];
00095        PHP_SHA1_CTX context;
00096        unsigned char digest[20];
00097        
00098        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
00099               return;
00100        }
00101 
00102        sha1str[0] = '\0';
00103        PHP_SHA1Init(&context);
00104        PHP_SHA1Update(&context, arg, arg_len);
00105        PHP_SHA1Final(digest, &context);
00106        if (raw_output) {
00107               RETURN_STRINGL(digest, 20, 1);
00108        } else {
00109               make_sha1_digest(sha1str, digest);
00110               RETVAL_STRING(sha1str, 1);
00111        }
00112 
00113 }
00114 
00115 /* }}} */
00116 
00117 /* {{{ proto string sha1_file(string filename [, bool raw_output])
00118    Calculate the sha1 hash of given filename */
00119 PHP_FUNCTION(sha1_file)
00120 {
00121        char          *arg;
00122        int           arg_len;
00123        zend_bool raw_output = 0;
00124        char          sha1str[41];
00125        unsigned char buf[1024];
00126        unsigned char digest[20];
00127        PHP_SHA1_CTX   context;
00128        int           n;
00129        php_stream    *stream;
00130 
00131        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
00132               return;
00133        }
00134        
00135        stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
00136        if (!stream) {
00137               RETURN_FALSE;
00138        }
00139 
00140        PHP_SHA1Init(&context);
00141 
00142        while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
00143               PHP_SHA1Update(&context, buf, n);
00144        }
00145 
00146        PHP_SHA1Final(digest, &context);
00147 
00148        php_stream_close(stream);
00149 
00150        if (n<0) {
00151               RETURN_FALSE;
00152        }
00153 
00154        if (raw_output) {
00155               RETURN_STRINGL(digest, 20, 1);
00156        } else {
00157               make_sha1_digest(sha1str, digest);
00158               RETVAL_STRING(sha1str, 1);
00159        }
00160 }
00161 /* }}} */
00162 
00163 /* F, G, H and I are basic SHA1 functions.
00164  */
00165 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
00166 #define G(x, y, z) ((x) ^ (y) ^ (z))
00167 #define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
00168 #define I(x, y, z) ((x) ^ (y) ^ (z))
00169 
00170 /* ROTATE_LEFT rotates x left n bits.
00171  */
00172 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00173 
00174 /* W[i]
00175  */
00176 #define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
00177        (x[i&15]=ROTATE_LEFT(tmp, 1)) )  
00178 
00179 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00180  */
00181 #define FF(a, b, c, d, e, w) { \
00182  (e) += F ((b), (c), (d)) + (w) + (php_hash_uint32)(0x5A827999); \
00183  (e) += ROTATE_LEFT ((a), 5); \
00184  (b) = ROTATE_LEFT((b), 30); \
00185   }
00186 #define GG(a, b, c, d, e, w) { \
00187  (e) += G ((b), (c), (d)) + (w) + (php_hash_uint32)(0x6ED9EBA1); \
00188  (e) += ROTATE_LEFT ((a), 5); \
00189  (b) = ROTATE_LEFT((b), 30); \
00190   }
00191 #define HH(a, b, c, d, e, w) { \
00192  (e) += H ((b), (c), (d)) + (w) + (php_hash_uint32)(0x8F1BBCDC); \
00193  (e) += ROTATE_LEFT ((a), 5); \
00194  (b) = ROTATE_LEFT((b), 30); \
00195   }
00196 #define II(a, b, c, d, e, w) { \
00197  (e) += I ((b), (c), (d)) + (w) + (php_hash_uint32)(0xCA62C1D6); \
00198  (e) += ROTATE_LEFT ((a), 5); \
00199  (b) = ROTATE_LEFT((b), 30); \
00200   }
00201                                          
00202 
00203 /* {{{ PHP_SHA1Init
00204  * SHA1 initialization. Begins an SHA1 operation, writing a new context.
00205  */
00206 PHP_HASH_API void PHP_SHA1Init(PHP_SHA1_CTX * context)
00207 {
00208        context->count[0] = context->count[1] = 0;
00209        /* Load magic initialization constants.
00210         */
00211        context->state[0] = 0x67452301;
00212        context->state[1] = 0xefcdab89;
00213        context->state[2] = 0x98badcfe;
00214        context->state[3] = 0x10325476;
00215        context->state[4] = 0xc3d2e1f0;
00216 }
00217 /* }}} */
00218 
00219 /* {{{ SHA1Transform
00220  * SHA1 basic transformation. Transforms state based on block.
00221  */
00222 static void SHA1Transform(php_hash_uint32 state[5], const unsigned char block[64])
00223 {
00224        php_hash_uint32 a = state[0], b = state[1], c = state[2];
00225        php_hash_uint32 d = state[3], e = state[4], x[16], tmp;
00226 
00227        SHADecode32(x, block, 64);
00228 
00229        /* Round 1 */
00230        FF(a, b, c, d, e, x[0]);   /* 1 */
00231        FF(e, a, b, c, d, x[1]);   /* 2 */
00232        FF(d, e, a, b, c, x[2]);   /* 3 */
00233        FF(c, d, e, a, b, x[3]);   /* 4 */
00234        FF(b, c, d, e, a, x[4]);   /* 5 */
00235        FF(a, b, c, d, e, x[5]);   /* 6 */
00236        FF(e, a, b, c, d, x[6]);   /* 7 */
00237        FF(d, e, a, b, c, x[7]);   /* 8 */
00238        FF(c, d, e, a, b, x[8]);   /* 9 */
00239        FF(b, c, d, e, a, x[9]);   /* 10 */
00240        FF(a, b, c, d, e, x[10]);  /* 11 */
00241        FF(e, a, b, c, d, x[11]);  /* 12 */
00242        FF(d, e, a, b, c, x[12]);  /* 13 */
00243        FF(c, d, e, a, b, x[13]);  /* 14 */
00244        FF(b, c, d, e, a, x[14]);  /* 15 */
00245        FF(a, b, c, d, e, x[15]);  /* 16 */
00246        FF(e, a, b, c, d, W(16));  /* 17 */
00247        FF(d, e, a, b, c, W(17));  /* 18 */
00248        FF(c, d, e, a, b, W(18));  /* 19 */
00249        FF(b, c, d, e, a, W(19));  /* 20 */
00250 
00251        /* Round 2 */
00252        GG(a, b, c, d, e, W(20));  /* 21 */
00253        GG(e, a, b, c, d, W(21));  /* 22 */
00254        GG(d, e, a, b, c, W(22));  /* 23 */
00255        GG(c, d, e, a, b, W(23));  /* 24 */
00256        GG(b, c, d, e, a, W(24));  /* 25 */
00257        GG(a, b, c, d, e, W(25));  /* 26 */
00258        GG(e, a, b, c, d, W(26));  /* 27 */
00259        GG(d, e, a, b, c, W(27));  /* 28 */
00260        GG(c, d, e, a, b, W(28));  /* 29 */
00261        GG(b, c, d, e, a, W(29));  /* 30 */
00262        GG(a, b, c, d, e, W(30));  /* 31 */
00263        GG(e, a, b, c, d, W(31));  /* 32 */
00264        GG(d, e, a, b, c, W(32));  /* 33 */
00265        GG(c, d, e, a, b, W(33));  /* 34 */
00266        GG(b, c, d, e, a, W(34));  /* 35 */
00267        GG(a, b, c, d, e, W(35));  /* 36 */
00268        GG(e, a, b, c, d, W(36));  /* 37 */
00269        GG(d, e, a, b, c, W(37));  /* 38 */
00270        GG(c, d, e, a, b, W(38));  /* 39 */
00271        GG(b, c, d, e, a, W(39));  /* 40 */
00272 
00273        /* Round 3 */
00274        HH(a, b, c, d, e, W(40));  /* 41 */
00275        HH(e, a, b, c, d, W(41));  /* 42 */
00276        HH(d, e, a, b, c, W(42));  /* 43 */
00277        HH(c, d, e, a, b, W(43));  /* 44 */
00278        HH(b, c, d, e, a, W(44));  /* 45 */
00279        HH(a, b, c, d, e, W(45));  /* 46 */
00280        HH(e, a, b, c, d, W(46));  /* 47 */
00281        HH(d, e, a, b, c, W(47));  /* 48 */
00282        HH(c, d, e, a, b, W(48));  /* 49 */
00283        HH(b, c, d, e, a, W(49));  /* 50 */
00284        HH(a, b, c, d, e, W(50));  /* 51 */
00285        HH(e, a, b, c, d, W(51));  /* 52 */
00286        HH(d, e, a, b, c, W(52));  /* 53 */
00287        HH(c, d, e, a, b, W(53));  /* 54 */
00288        HH(b, c, d, e, a, W(54));  /* 55 */
00289        HH(a, b, c, d, e, W(55));  /* 56 */
00290        HH(e, a, b, c, d, W(56));  /* 57 */
00291        HH(d, e, a, b, c, W(57));  /* 58 */
00292        HH(c, d, e, a, b, W(58));  /* 59 */
00293        HH(b, c, d, e, a, W(59));  /* 60 */
00294 
00295        /* Round 4 */
00296        II(a, b, c, d, e, W(60));  /* 61 */
00297        II(e, a, b, c, d, W(61));  /* 62 */
00298        II(d, e, a, b, c, W(62));  /* 63 */
00299        II(c, d, e, a, b, W(63));  /* 64 */
00300        II(b, c, d, e, a, W(64));  /* 65 */
00301        II(a, b, c, d, e, W(65));  /* 66 */
00302        II(e, a, b, c, d, W(66));  /* 67 */
00303        II(d, e, a, b, c, W(67));  /* 68 */
00304        II(c, d, e, a, b, W(68));  /* 69 */
00305        II(b, c, d, e, a, W(69));  /* 70 */
00306        II(a, b, c, d, e, W(70));  /* 71 */
00307        II(e, a, b, c, d, W(71));  /* 72 */
00308        II(d, e, a, b, c, W(72));  /* 73 */
00309        II(c, d, e, a, b, W(73));  /* 74 */
00310        II(b, c, d, e, a, W(74));  /* 75 */
00311        II(a, b, c, d, e, W(75));  /* 76 */
00312        II(e, a, b, c, d, W(76));  /* 77 */
00313        II(d, e, a, b, c, W(77));  /* 78 */
00314        II(c, d, e, a, b, W(78));  /* 79 */
00315        II(b, c, d, e, a, W(79));  /* 80 */
00316 
00317        state[0] += a;
00318        state[1] += b;
00319        state[2] += c;
00320        state[3] += d;
00321        state[4] += e;
00322 
00323        /* Zeroize sensitive information. */
00324        memset((unsigned char*) x, 0, sizeof(x));
00325 }
00326 /* }}} */
00327 
00328 /* {{{ PHP_SHA1Update
00329    SHA1 block update operation. Continues an SHA1 message-digest
00330    operation, processing another message block, and updating the
00331    context.
00332  */
00333 PHP_HASH_API void PHP_SHA1Update(PHP_SHA1_CTX * context, const unsigned char *input,
00334                         unsigned int inputLen)
00335 {
00336        unsigned int i, index, partLen;
00337 
00338        /* Compute number of bytes mod 64 */
00339        index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00340 
00341        /* Update number of bits */
00342        if ((context->count[0] += ((php_hash_uint32) inputLen << 3))
00343               < ((php_hash_uint32) inputLen << 3))
00344               context->count[1]++;
00345        context->count[1] += ((php_hash_uint32) inputLen >> 29);
00346 
00347        partLen = 64 - index;
00348 
00349        /* Transform as many times as possible.
00350         */
00351        if (inputLen >= partLen) {
00352               memcpy
00353                      ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00354               SHA1Transform(context->state, context->buffer);
00355 
00356               for (i = partLen; i + 63 < inputLen; i += 64)
00357                      SHA1Transform(context->state, &input[i]);
00358 
00359               index = 0;
00360        } else
00361               i = 0;
00362 
00363        /* Buffer remaining input */
00364        memcpy
00365               ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
00366                inputLen - i);
00367 }
00368 /* }}} */
00369 
00370 /* {{{ PHP_SHA1Final
00371    SHA1 finalization. Ends an SHA1 message-digest operation, writing the
00372    the message digest and zeroizing the context.
00373  */
00374 PHP_HASH_API void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
00375 {
00376        unsigned char bits[8];
00377        unsigned int index, padLen;
00378 
00379        /* Save number of bits */
00380        bits[7] = context->count[0] & 0xFF;
00381        bits[6] = (context->count[0] >> 8) & 0xFF;
00382        bits[5] = (context->count[0] >> 16) & 0xFF;
00383        bits[4] = (context->count[0] >> 24) & 0xFF;
00384        bits[3] = context->count[1] & 0xFF;
00385        bits[2] = (context->count[1] >> 8) & 0xFF;
00386        bits[1] = (context->count[1] >> 16) & 0xFF;
00387        bits[0] = (context->count[1] >> 24) & 0xFF;
00388        
00389        /* Pad out to 56 mod 64.
00390         */
00391        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00392        padLen = (index < 56) ? (56 - index) : (120 - index);
00393        PHP_SHA1Update(context, PADDING, padLen);
00394 
00395        /* Append length (before padding) */
00396        PHP_SHA1Update(context, bits, 8);
00397 
00398        /* Store state in digest */
00399        SHAEncode32(digest, context->state, 20);
00400 
00401        /* Zeroize sensitive information.
00402         */
00403        memset((unsigned char*) context, 0, sizeof(*context));
00404 }
00405 /* }}} */
00406 
00407 #endif /* PHP_HASH_SHA1_NOT_IN_CORE */
00408 
00409 /* sha224/sha256 */
00410 
00411 const php_hash_ops php_hash_sha256_ops = {
00412        (php_hash_init_func_t) PHP_SHA256Init,
00413        (php_hash_update_func_t) PHP_SHA256Update,
00414        (php_hash_final_func_t) PHP_SHA256Final,
00415        (php_hash_copy_func_t) php_hash_copy,
00416        32,
00417        64,
00418        sizeof(PHP_SHA256_CTX)
00419 };
00420 
00421 const php_hash_ops php_hash_sha224_ops = {
00422        (php_hash_init_func_t) PHP_SHA224Init,
00423        (php_hash_update_func_t) PHP_SHA224Update,
00424        (php_hash_final_func_t) PHP_SHA224Final,
00425        (php_hash_copy_func_t) php_hash_copy,
00426        28,
00427        64,
00428        sizeof(PHP_SHA224_CTX)
00429 };
00430 
00431 #define ROTR32(b,x)         ((x >> b) | (x << (32 - b)))
00432 #define ROTR64(b,x)         ((x >> b) | (x << (64 - b)))
00433 #define SHR(b, x)           (x >> b)
00434 
00435 /* Ch */
00436 #define SHA256_F0(x,y,z)    (((x) & (y)) ^ ((~(x)) & (z)))
00437 /* Maj */
00438 #define SHA256_F1(x,y,z)    (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
00439 /* SUM0 */
00440 #define SHA256_F2(x)        (ROTR32( 2,(x)) ^ ROTR32(13,(x)) ^ ROTR32(22,(x)))
00441 /* SUM1 */
00442 #define SHA256_F3(x)        (ROTR32( 6,(x)) ^ ROTR32(11,(x)) ^ ROTR32(25,(x)))
00443 /* OM0 */
00444 #define SHA256_F4(x)        (ROTR32( 7,(x)) ^ ROTR32(18,(x)) ^ SHR( 3,(x)))
00445 /* OM1 */
00446 #define SHA256_F5(x)        (ROTR32(17,(x)) ^ ROTR32(19,(x)) ^ SHR(10,(x)))
00447 
00448 static const php_hash_uint32 SHA256_K[64] = {
00449        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00450        0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00451        0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00452        0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00453        0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00454        0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00455        0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00456        0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
00457 
00458 /* {{{ PHP_SHA256Init
00459  * SHA256 initialization. Begins an SHA256 operation, writing a new context.
00460  */
00461 PHP_HASH_API void PHP_SHA256Init(PHP_SHA256_CTX * context)
00462 {
00463        context->count[0] = context->count[1] = 0;
00464        /* Load magic initialization constants.
00465         */
00466        context->state[0] = 0x6a09e667;
00467        context->state[1] = 0xbb67ae85;
00468        context->state[2] = 0x3c6ef372;
00469        context->state[3] = 0xa54ff53a;
00470        context->state[4] = 0x510e527f;
00471        context->state[5] = 0x9b05688c;
00472        context->state[6] = 0x1f83d9ab;
00473        context->state[7] = 0x5be0cd19;
00474 }
00475 /* }}} */
00476 
00477 /* {{{ SHA256Transform
00478  * SHA256 basic transformation. Transforms state based on block.
00479  */
00480 static void SHA256Transform(php_hash_uint32 state[8], const unsigned char block[64])
00481 {
00482        php_hash_uint32 a = state[0], b = state[1], c = state[2], d = state[3];
00483        php_hash_uint32 e = state[4], f = state[5], g = state[6], h = state[7];
00484        php_hash_uint32 x[16], T1, T2, W[64];
00485        int i;
00486 
00487        SHADecode32(x, block, 64);
00488 
00489        /* Schedule */
00490        for(i = 0; i < 16; i++) {
00491               W[i] = x[i];
00492        }
00493        for(i = 16; i < 64; i++) {
00494               W[i] = SHA256_F5(W[i-2]) + W[i-7] + SHA256_F4(W[i-15]) + W[i-16];
00495        }
00496 
00497        for (i = 0; i < 64; i++) {
00498               T1 = h + SHA256_F3(e) + SHA256_F0(e,f,g) + SHA256_K[i] + W[i];
00499               T2 = SHA256_F2(a) + SHA256_F1(a,b,c);
00500               h = g; g = f; f = e; e = d + T1;
00501               d = c; c = b; b = a; a = T1 + T2;
00502        }
00503 
00504        state[0] += a;
00505        state[1] += b;
00506        state[2] += c;
00507        state[3] += d;
00508        state[4] += e;
00509        state[5] += f;
00510        state[6] += g;
00511        state[7] += h;
00512 
00513        /* Zeroize sensitive information. */
00514        memset((unsigned char*) x, 0, sizeof(x));
00515 }
00516 /* }}} */
00517 
00518 /* {{{ PHP_SHA224Init
00519  * SHA224 initialization. Begins an SHA224 operation, writing a new context.
00520  */
00521 PHP_HASH_API void PHP_SHA224Init(PHP_SHA224_CTX * context)
00522 {
00523        context->count[0] = context->count[1] = 0;
00524        /* Load magic initialization constants.
00525         */
00526        context->state[0] = 0xc1059ed8;
00527        context->state[1] = 0x367cd507;
00528        context->state[2] = 0x3070dd17;
00529        context->state[3] = 0xf70e5939;
00530        context->state[4] = 0xffc00b31;
00531        context->state[5] = 0x68581511;
00532        context->state[6] = 0x64f98fa7;
00533        context->state[7] = 0xbefa4fa4;
00534 }
00535 /* }}} */
00536 
00537 /* {{{ PHP_SHA224Update
00538    SHA224 block update operation. Continues an SHA224 message-digest
00539    operation, processing another message block, and updating the
00540    context.
00541  */
00542 PHP_HASH_API void PHP_SHA224Update(PHP_SHA224_CTX * context, const unsigned char *input, unsigned int inputLen)
00543 {
00544        unsigned int i, index, partLen;
00545 
00546        /* Compute number of bytes mod 64 */
00547        index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00548 
00549        /* Update number of bits */
00550        if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
00551               context->count[1]++;
00552        }
00553        context->count[1] += ((php_hash_uint32) inputLen >> 29);
00554 
00555        partLen = 64 - index;
00556 
00557        /* Transform as many times as possible.
00558         */
00559        if (inputLen >= partLen) {
00560               memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00561               SHA256Transform(context->state, context->buffer);
00562 
00563               for (i = partLen; i + 63 < inputLen; i += 64) {
00564                      SHA256Transform(context->state, &input[i]);
00565               }
00566 
00567               index = 0;
00568        } else {
00569               i = 0;
00570        }
00571 
00572        /* Buffer remaining input */
00573        memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
00574 }
00575 /* }}} */
00576 
00577 /* {{{ PHP_SHA224Final
00578    SHA224 finalization. Ends an SHA224 message-digest operation, writing the
00579    the message digest and zeroizing the context.
00580  */
00581 PHP_HASH_API void PHP_SHA224Final(unsigned char digest[28], PHP_SHA224_CTX * context)
00582 {
00583        unsigned char bits[8];
00584        unsigned int index, padLen;
00585 
00586        /* Save number of bits */
00587        bits[7] = (unsigned char) (context->count[0] & 0xFF);
00588        bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
00589        bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
00590        bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
00591        bits[3] = (unsigned char) (context->count[1] & 0xFF);
00592        bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
00593        bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
00594        bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
00595 
00596        /* Pad out to 56 mod 64.
00597         */
00598        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00599        padLen = (index < 56) ? (56 - index) : (120 - index);
00600        PHP_SHA224Update(context, PADDING, padLen);
00601 
00602        /* Append length (before padding) */
00603        PHP_SHA224Update(context, bits, 8);
00604 
00605        /* Store state in digest */
00606        SHAEncode32(digest, context->state, 28);
00607 
00608        /* Zeroize sensitive information.
00609         */
00610        memset((unsigned char*) context, 0, sizeof(*context));
00611 }
00612 /* }}} */
00613 
00614 /* {{{ PHP_SHA256Update
00615    SHA256 block update operation. Continues an SHA256 message-digest
00616    operation, processing another message block, and updating the
00617    context.
00618  */
00619 PHP_HASH_API void PHP_SHA256Update(PHP_SHA256_CTX * context, const unsigned char *input, unsigned int inputLen)
00620 {
00621        unsigned int i, index, partLen;
00622 
00623        /* Compute number of bytes mod 64 */
00624        index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00625 
00626        /* Update number of bits */
00627        if ((context->count[0] += ((php_hash_uint32) inputLen << 3)) < ((php_hash_uint32) inputLen << 3)) {
00628               context->count[1]++;
00629        }
00630        context->count[1] += ((php_hash_uint32) inputLen >> 29);
00631 
00632        partLen = 64 - index;
00633 
00634        /* Transform as many times as possible.
00635         */
00636        if (inputLen >= partLen) {
00637               memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00638               SHA256Transform(context->state, context->buffer);
00639 
00640               for (i = partLen; i + 63 < inputLen; i += 64) {
00641                      SHA256Transform(context->state, &input[i]);
00642               }
00643 
00644               index = 0;
00645        } else {
00646               i = 0;
00647        }
00648 
00649        /* Buffer remaining input */
00650        memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
00651 }
00652 /* }}} */
00653 
00654 /* {{{ PHP_SHA256Final
00655    SHA256 finalization. Ends an SHA256 message-digest operation, writing the
00656    the message digest and zeroizing the context.
00657  */
00658 PHP_HASH_API void PHP_SHA256Final(unsigned char digest[32], PHP_SHA256_CTX * context)
00659 {
00660        unsigned char bits[8];
00661        unsigned int index, padLen;
00662 
00663        /* Save number of bits */
00664        bits[7] = (unsigned char) (context->count[0] & 0xFF);
00665        bits[6] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
00666        bits[5] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
00667        bits[4] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
00668        bits[3] = (unsigned char) (context->count[1] & 0xFF);
00669        bits[2] = (unsigned char) ((context->count[1] >> 8) & 0xFF);
00670        bits[1] = (unsigned char) ((context->count[1] >> 16) & 0xFF);
00671        bits[0] = (unsigned char) ((context->count[1] >> 24) & 0xFF);
00672        
00673        /* Pad out to 56 mod 64.
00674         */
00675        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00676        padLen = (index < 56) ? (56 - index) : (120 - index);
00677        PHP_SHA256Update(context, PADDING, padLen);
00678 
00679        /* Append length (before padding) */
00680        PHP_SHA256Update(context, bits, 8);
00681 
00682        /* Store state in digest */
00683        SHAEncode32(digest, context->state, 32);
00684 
00685        /* Zeroize sensitive information.
00686         */
00687        memset((unsigned char*) context, 0, sizeof(*context));
00688 }
00689 /* }}} */
00690 
00691 /* sha384/sha512 */
00692 
00693 /* Ch */
00694 #define SHA512_F0(x,y,z)           (((x) & (y)) ^ ((~(x)) & (z)))
00695 /* Maj */
00696 #define SHA512_F1(x,y,z)           (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
00697 /* SUM0 */
00698 #define SHA512_F2(x)               (ROTR64(28, x) ^ ROTR64(34, x) ^ ROTR64(39, x))
00699 /* SUM1 */
00700 #define SHA512_F3(x)               (ROTR64(14, x) ^ ROTR64(18, x) ^ ROTR64(41, x))
00701 /* OM0 */
00702 #define SHA512_F4(x)               (ROTR64( 1, x) ^ ROTR64( 8, x) ^ SHR(7, x))
00703 /* OM1 */
00704 #define SHA512_F5(x)               (ROTR64(19, x) ^ ROTR64(61, x) ^ SHR(6, x))
00705 
00706 static const php_hash_uint64 SHA512_K[128] = {
00707        L64(0x428a2f98d728ae22), L64(0x7137449123ef65cd), L64(0xb5c0fbcfec4d3b2f), L64(0xe9b5dba58189dbbc),
00708        L64(0x3956c25bf348b538), L64(0x59f111f1b605d019), L64(0x923f82a4af194f9b), L64(0xab1c5ed5da6d8118),
00709        L64(0xd807aa98a3030242), L64(0x12835b0145706fbe), L64(0x243185be4ee4b28c), L64(0x550c7dc3d5ffb4e2),
00710        L64(0x72be5d74f27b896f), L64(0x80deb1fe3b1696b1), L64(0x9bdc06a725c71235), L64(0xc19bf174cf692694),
00711        L64(0xe49b69c19ef14ad2), L64(0xefbe4786384f25e3), L64(0x0fc19dc68b8cd5b5), L64(0x240ca1cc77ac9c65),
00712        L64(0x2de92c6f592b0275), L64(0x4a7484aa6ea6e483), L64(0x5cb0a9dcbd41fbd4), L64(0x76f988da831153b5),
00713        L64(0x983e5152ee66dfab), L64(0xa831c66d2db43210), L64(0xb00327c898fb213f), L64(0xbf597fc7beef0ee4),
00714        L64(0xc6e00bf33da88fc2), L64(0xd5a79147930aa725), L64(0x06ca6351e003826f), L64(0x142929670a0e6e70),
00715        L64(0x27b70a8546d22ffc), L64(0x2e1b21385c26c926), L64(0x4d2c6dfc5ac42aed), L64(0x53380d139d95b3df),
00716        L64(0x650a73548baf63de), L64(0x766a0abb3c77b2a8), L64(0x81c2c92e47edaee6), L64(0x92722c851482353b),
00717        L64(0xa2bfe8a14cf10364), L64(0xa81a664bbc423001), L64(0xc24b8b70d0f89791), L64(0xc76c51a30654be30),
00718        L64(0xd192e819d6ef5218), L64(0xd69906245565a910), L64(0xf40e35855771202a), L64(0x106aa07032bbd1b8),
00719        L64(0x19a4c116b8d2d0c8), L64(0x1e376c085141ab53), L64(0x2748774cdf8eeb99), L64(0x34b0bcb5e19b48a8),
00720        L64(0x391c0cb3c5c95a63), L64(0x4ed8aa4ae3418acb), L64(0x5b9cca4f7763e373), L64(0x682e6ff3d6b2b8a3),
00721        L64(0x748f82ee5defb2fc), L64(0x78a5636f43172f60), L64(0x84c87814a1f0ab72), L64(0x8cc702081a6439ec),
00722        L64(0x90befffa23631e28), L64(0xa4506cebde82bde9), L64(0xbef9a3f7b2c67915), L64(0xc67178f2e372532b),
00723        L64(0xca273eceea26619c), L64(0xd186b8c721c0c207), L64(0xeada7dd6cde0eb1e), L64(0xf57d4f7fee6ed178),
00724        L64(0x06f067aa72176fba), L64(0x0a637dc5a2c898a6), L64(0x113f9804bef90dae), L64(0x1b710b35131c471b),
00725        L64(0x28db77f523047d84), L64(0x32caab7b40c72493), L64(0x3c9ebe0a15c9bebc), L64(0x431d67c49c100d4c),
00726        L64(0x4cc5d4becb3e42b6), L64(0x597f299cfc657e2a), L64(0x5fcb6fab3ad6faec), L64(0x6c44198c4a475817) };
00727 
00728 /* {{{ SHAEncode64
00729    Encodes input (php_hash_uint64) into output (unsigned char). Assumes len is
00730    a multiple of 8.
00731  */
00732 static void SHAEncode64(unsigned char *output, php_hash_uint64 *input, unsigned int len)
00733 {
00734        unsigned int i, j;
00735 
00736        for (i = 0, j = 0; j < len; i++, j += 8) {
00737               output[j] = (unsigned char) ((input[i] >> 56) & 0xff);
00738               output[j + 1] = (unsigned char) ((input[i] >> 48) & 0xff);
00739               output[j + 2] = (unsigned char) ((input[i] >> 40) & 0xff);
00740               output[j + 3] = (unsigned char) ((input[i] >> 32) & 0xff);
00741               output[j + 4] = (unsigned char) ((input[i] >> 24) & 0xff);
00742               output[j + 5] = (unsigned char) ((input[i] >> 16) & 0xff);
00743               output[j + 6] = (unsigned char) ((input[i] >> 8) & 0xff);
00744               output[j + 7] = (unsigned char) (input[i] & 0xff);
00745        }
00746 }
00747 /* }}} */
00748 
00749 
00750 /* {{{ SHADecode64
00751    Decodes input (unsigned char) into output (php_hash_uint64). Assumes len is
00752    a multiple of 8.
00753  */
00754 static void SHADecode64(php_hash_uint64 *output, const unsigned char *input, unsigned int len)
00755 {
00756        unsigned int i, j;
00757 
00758        for (i = 0, j = 0; j < len; i++, j += 8)
00759               output[i] = 
00760                      ((php_hash_uint64) input[j + 7]) | (((php_hash_uint64) input[j + 6]) << 8) |
00761                      (((php_hash_uint64) input[j + 5]) << 16) | (((php_hash_uint64) input[j + 4]) << 24) |
00762                      (((php_hash_uint64) input[j + 3]) << 32) | (((php_hash_uint64) input[j + 2]) << 40) |
00763                      (((php_hash_uint64) input[j + 1]) << 48) | (((php_hash_uint64) input[j]) << 56);
00764 }
00765 /* }}} */
00766 
00767 /* {{{ PHP_SHA384Init
00768  * SHA384 initialization. Begins an SHA384 operation, writing a new context.
00769  */
00770 PHP_HASH_API void PHP_SHA384Init(PHP_SHA384_CTX * context)
00771 {
00772        context->count[0] = context->count[1] = 0;
00773        /* Load magic initialization constants.
00774         */
00775        context->state[0] = L64(0xcbbb9d5dc1059ed8);
00776        context->state[1] = L64(0x629a292a367cd507);
00777        context->state[2] = L64(0x9159015a3070dd17);
00778        context->state[3] = L64(0x152fecd8f70e5939);
00779        context->state[4] = L64(0x67332667ffc00b31);
00780        context->state[5] = L64(0x8eb44a8768581511);
00781        context->state[6] = L64(0xdb0c2e0d64f98fa7);
00782        context->state[7] = L64(0x47b5481dbefa4fa4);
00783 }
00784 /* }}} */
00785 
00786 /* {{{ SHA512Transform
00787  * SHA512 basic transformation. Transforms state based on block.
00788  * SHA384 uses the exact same algorithm
00789  */
00790 static void SHA512Transform(php_hash_uint64 state[8], const unsigned char block[128])
00791 {
00792        php_hash_uint64 a = state[0], b = state[1], c = state[2], d = state[3];
00793        php_hash_uint64 e = state[4], f = state[5], g = state[6], h = state[7];
00794        php_hash_uint64 x[16], T1, T2, W[80];
00795        int i;
00796 
00797        SHADecode64(x, block, 128);
00798 
00799        /* Schedule */
00800        for(i = 0; i < 16; i++) {
00801               W[i] = x[i];
00802        }
00803        for(i = 16; i < 80; i++) {
00804               W[i] = SHA512_F5(W[i-2]) + W[i-7] + SHA512_F4(W[i-15]) + W[i-16];
00805        }
00806 
00807        for (i = 0; i < 80; i++) {
00808               T1 = h + SHA512_F3(e) + SHA512_F0(e,f,g) + SHA512_K[i] + W[i];
00809               T2 = SHA512_F2(a) + SHA512_F1(a,b,c);
00810               h = g; g = f; f = e; e = d + T1;
00811               d = c; c = b; b = a; a = T1 + T2;
00812        }
00813 
00814        state[0] += a;
00815        state[1] += b;
00816        state[2] += c;
00817        state[3] += d;
00818        state[4] += e;
00819        state[5] += f;
00820        state[6] += g;
00821        state[7] += h;
00822 
00823        /* Zeroize sensitive information. */
00824        memset((unsigned char*) x, 0, sizeof(x));
00825 }
00826 /* }}} */
00827 
00828 /* {{{ PHP_SHA384Update
00829    SHA384 block update operation. Continues an SHA384 message-digest
00830    operation, processing another message block, and updating the
00831    context.
00832  */
00833 PHP_HASH_API void PHP_SHA384Update(PHP_SHA384_CTX * context, const unsigned char *input, unsigned int inputLen)
00834 {
00835        unsigned int i, index, partLen;
00836 
00837        /* Compute number of bytes mod 128 */
00838        index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
00839 
00840        /* Update number of bits */
00841        if ((context->count[0] += ((php_hash_uint64) inputLen << 3)) < ((php_hash_uint64) inputLen << 3)) {
00842               context->count[1]++;
00843        }
00844        context->count[1] += ((php_hash_uint64) inputLen >> 61);
00845 
00846        partLen = 128 - index;
00847 
00848        /* Transform as many times as possible.
00849         */
00850        if (inputLen >= partLen) {
00851               memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00852               SHA512Transform(context->state, context->buffer);
00853 
00854               for (i = partLen; i + 127 < inputLen; i += 128) {
00855                      SHA512Transform(context->state, &input[i]);
00856               }
00857 
00858               index = 0;
00859        } else {
00860               i = 0;
00861        }
00862 
00863        /* Buffer remaining input */
00864        memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
00865 }
00866 /* }}} */
00867 
00868 /* {{{ PHP_SHA384Final
00869    SHA384 finalization. Ends an SHA384 message-digest operation, writing the
00870    the message digest and zeroizing the context.
00871  */
00872 PHP_HASH_API void PHP_SHA384Final(unsigned char digest[48], PHP_SHA384_CTX * context)
00873 {
00874        unsigned char bits[16];
00875        unsigned int index, padLen;
00876 
00877        /* Save number of bits */
00878        bits[15] = (unsigned char) (context->count[0] & 0xFF);
00879        bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
00880        bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
00881        bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
00882        bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
00883        bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
00884        bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
00885        bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
00886        bits[7]  = (unsigned char) (context->count[1] & 0xFF);
00887        bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
00888        bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
00889        bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
00890        bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
00891        bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
00892        bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
00893        bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
00894        
00895        /* Pad out to 112 mod 128.
00896         */
00897        index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
00898        padLen = (index < 112) ? (112 - index) : (240 - index);
00899        PHP_SHA384Update(context, PADDING, padLen);
00900 
00901        /* Append length (before padding) */
00902        PHP_SHA384Update(context, bits, 16);
00903 
00904        /* Store state in digest */
00905        SHAEncode64(digest, context->state, 48);
00906 
00907        /* Zeroize sensitive information.
00908         */
00909        memset((unsigned char*) context, 0, sizeof(*context));
00910 }
00911 /* }}} */
00912 
00913 const php_hash_ops php_hash_sha384_ops = {
00914        (php_hash_init_func_t) PHP_SHA384Init,
00915        (php_hash_update_func_t) PHP_SHA384Update,
00916        (php_hash_final_func_t) PHP_SHA384Final,
00917        (php_hash_copy_func_t) php_hash_copy,
00918        48,
00919        128,
00920        sizeof(PHP_SHA384_CTX)
00921 };
00922 
00923 /* {{{ PHP_SHA512Init
00924  * SHA512 initialization. Begins an SHA512 operation, writing a new context.
00925  */
00926 PHP_HASH_API void PHP_SHA512Init(PHP_SHA512_CTX * context)
00927 {
00928        context->count[0] = context->count[1] = 0;
00929        /* Load magic initialization constants.
00930         */
00931        context->state[0] = L64(0x6a09e667f3bcc908);
00932        context->state[1] = L64(0xbb67ae8584caa73b);
00933        context->state[2] = L64(0x3c6ef372fe94f82b);
00934        context->state[3] = L64(0xa54ff53a5f1d36f1);
00935        context->state[4] = L64(0x510e527fade682d1);
00936        context->state[5] = L64(0x9b05688c2b3e6c1f);
00937        context->state[6] = L64(0x1f83d9abfb41bd6b);
00938        context->state[7] = L64(0x5be0cd19137e2179);
00939 }
00940 /* }}} */
00941 
00942 /* {{{ PHP_SHA512Update
00943    SHA512 block update operation. Continues an SHA512 message-digest
00944    operation, processing another message block, and updating the
00945    context.
00946  */
00947 PHP_HASH_API void PHP_SHA512Update(PHP_SHA512_CTX * context, const unsigned char *input, unsigned int inputLen)
00948 {
00949        unsigned int i, index, partLen;
00950 
00951        /* Compute number of bytes mod 128 */
00952        index = (unsigned int) ((context->count[0] >> 3) & 0x7F);
00953 
00954        /* Update number of bits */
00955        if ((context->count[0] += ((php_hash_uint64) inputLen << 3)) < ((php_hash_uint64) inputLen << 3)) {
00956               context->count[1]++;
00957        }
00958        context->count[1] += ((php_hash_uint64) inputLen >> 61);
00959 
00960        partLen = 128 - index;
00961 
00962        /* Transform as many times as possible.
00963         */
00964        if (inputLen >= partLen) {
00965               memcpy((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00966               SHA512Transform(context->state, context->buffer);
00967 
00968               for (i = partLen; i + 127 < inputLen; i += 128) {
00969                      SHA512Transform(context->state, &input[i]);
00970               }
00971 
00972               index = 0;
00973        } else {
00974               i = 0;
00975        }
00976 
00977        /* Buffer remaining input */
00978        memcpy((unsigned char*) & context->buffer[index], (unsigned char*) & input[i], inputLen - i);
00979 }
00980 /* }}} */
00981 
00982 /* {{{ PHP_SHA512Final
00983    SHA512 finalization. Ends an SHA512 message-digest operation, writing the
00984    the message digest and zeroizing the context.
00985  */
00986 PHP_HASH_API void PHP_SHA512Final(unsigned char digest[64], PHP_SHA512_CTX * context)
00987 {
00988        unsigned char bits[16];
00989        unsigned int index, padLen;
00990 
00991        /* Save number of bits */
00992        bits[15] = (unsigned char) (context->count[0] & 0xFF);
00993        bits[14] = (unsigned char) ((context->count[0] >> 8) & 0xFF);
00994        bits[13] = (unsigned char) ((context->count[0] >> 16) & 0xFF);
00995        bits[12] = (unsigned char) ((context->count[0] >> 24) & 0xFF);
00996        bits[11] = (unsigned char) ((context->count[0] >> 32) & 0xFF);
00997        bits[10] = (unsigned char) ((context->count[0] >> 40) & 0xFF);
00998        bits[9]  = (unsigned char) ((context->count[0] >> 48) & 0xFF);
00999        bits[8]  = (unsigned char) ((context->count[0] >> 56) & 0xFF);
01000        bits[7]  = (unsigned char) (context->count[1] & 0xFF);
01001        bits[6]  = (unsigned char) ((context->count[1] >> 8) & 0xFF);
01002        bits[5]  = (unsigned char) ((context->count[1] >> 16) & 0xFF);
01003        bits[4]  = (unsigned char) ((context->count[1] >> 24) & 0xFF);
01004        bits[3]  = (unsigned char) ((context->count[1] >> 32) & 0xFF);
01005        bits[2]  = (unsigned char) ((context->count[1] >> 40) & 0xFF);
01006        bits[1]  = (unsigned char) ((context->count[1] >> 48) & 0xFF);
01007        bits[0]  = (unsigned char) ((context->count[1] >> 56) & 0xFF);
01008 
01009        /* Pad out to 112 mod 128.
01010         */
01011        index = (unsigned int) ((context->count[0] >> 3) & 0x7f);
01012        padLen = (index < 112) ? (112 - index) : (240 - index);
01013        PHP_SHA512Update(context, PADDING, padLen);
01014 
01015        /* Append length (before padding) */
01016        PHP_SHA512Update(context, bits, 16);
01017 
01018        /* Store state in digest */
01019        SHAEncode64(digest, context->state, 64);
01020 
01021        /* Zeroize sensitive information.
01022         */
01023        memset((unsigned char*) context, 0, sizeof(*context));
01024 }
01025 /* }}} */
01026 
01027 const php_hash_ops php_hash_sha512_ops = {
01028        (php_hash_init_func_t) PHP_SHA512Init,
01029        (php_hash_update_func_t) PHP_SHA512Update,
01030        (php_hash_final_func_t) PHP_SHA512Final,
01031        (php_hash_copy_func_t) php_hash_copy,
01032        64,
01033        128,
01034        sizeof(PHP_SHA512_CTX)
01035 };
01036 
01037 /*
01038  * Local variables:
01039  * tab-width: 4
01040  * c-basic-offset: 4
01041  * End:
01042  * vim600: sw=4 ts=4 fdm=marker
01043  * vim<600: sw=4 ts=4
01044  */