Back to index

php5  5.3.10
sha1.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    | Author: Stefan Esser <sesser@php.net>                                |
00016    +----------------------------------------------------------------------+
00017 */
00018 
00019 /* $Id: sha1.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #include "php.h"
00022 
00023 /* This code is heavily based on the PHP md5 implementation */ 
00024 
00025 #include "sha1.h"
00026 #include "md5.h"
00027 
00028 PHPAPI void make_sha1_digest(char *sha1str, unsigned char *digest)
00029 {
00030        make_digest_ex(sha1str, digest, 20);
00031 }
00032 
00033 /* {{{ proto string sha1(string str [, bool raw_output])
00034    Calculate the sha1 hash of a string */
00035 PHP_FUNCTION(sha1)
00036 {
00037        char *arg;
00038        int arg_len;
00039        zend_bool raw_output = 0;
00040        char sha1str[41];
00041        PHP_SHA1_CTX context;
00042        unsigned char digest[20];
00043        
00044        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
00045               return;
00046        }
00047 
00048        sha1str[0] = '\0';
00049        PHP_SHA1Init(&context);
00050        PHP_SHA1Update(&context, arg, arg_len);
00051        PHP_SHA1Final(digest, &context);
00052        if (raw_output) {
00053               RETURN_STRINGL(digest, 20, 1);
00054        } else {
00055               make_digest_ex(sha1str, digest, 20);
00056               RETVAL_STRING(sha1str, 1);
00057        }
00058 
00059 }
00060 
00061 /* }}} */
00062 
00063 
00064 /* {{{ proto string sha1_file(string filename [, bool raw_output])
00065    Calculate the sha1 hash of given filename */
00066 PHP_FUNCTION(sha1_file)
00067 {
00068        char          *arg;
00069        int           arg_len;
00070        zend_bool raw_output = 0;
00071        char          sha1str[41];
00072        unsigned char buf[1024];
00073        unsigned char digest[20];
00074        PHP_SHA1_CTX   context;
00075        int           n;
00076        php_stream    *stream;
00077 
00078        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
00079               return;
00080        }
00081        
00082        stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
00083        if (!stream) {
00084               RETURN_FALSE;
00085        }
00086 
00087        PHP_SHA1Init(&context);
00088 
00089        while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
00090               PHP_SHA1Update(&context, buf, n);
00091        }
00092 
00093        PHP_SHA1Final(digest, &context);
00094 
00095        php_stream_close(stream);
00096 
00097        if (n<0) {
00098               RETURN_FALSE;
00099        }
00100 
00101        if (raw_output) {
00102               RETURN_STRINGL(digest, 20, 1);
00103        } else {
00104               make_digest_ex(sha1str, digest, 20);
00105               RETVAL_STRING(sha1str, 1);
00106        }
00107 }
00108 /* }}} */
00109 
00110 
00111 static void SHA1Transform(php_uint32[5], const unsigned char[64]);
00112 static void SHA1Encode(unsigned char *, php_uint32 *, unsigned int);
00113 static void SHA1Decode(php_uint32 *, const unsigned char *, unsigned int);
00114 
00115 static unsigned char PADDING[64] =
00116 {
00117        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00118        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00119        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00120 };
00121 
00122 /* F, G, H and I are basic SHA1 functions.
00123  */
00124 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
00125 #define G(x, y, z) ((x) ^ (y) ^ (z))
00126 #define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
00127 #define I(x, y, z) ((x) ^ (y) ^ (z))
00128 
00129 /* ROTATE_LEFT rotates x left n bits.
00130  */
00131 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
00132 
00133 /* W[i]
00134  */
00135 #define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
00136        (x[i&15]=ROTATE_LEFT(tmp, 1)) )  
00137 
00138 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
00139  */
00140 #define FF(a, b, c, d, e, w) { \
00141  (e) += F ((b), (c), (d)) + (w) + (php_uint32)(0x5A827999); \
00142  (e) += ROTATE_LEFT ((a), 5); \
00143  (b) = ROTATE_LEFT((b), 30); \
00144   }
00145 #define GG(a, b, c, d, e, w) { \
00146  (e) += G ((b), (c), (d)) + (w) + (php_uint32)(0x6ED9EBA1); \
00147  (e) += ROTATE_LEFT ((a), 5); \
00148  (b) = ROTATE_LEFT((b), 30); \
00149   }
00150 #define HH(a, b, c, d, e, w) { \
00151  (e) += H ((b), (c), (d)) + (w) + (php_uint32)(0x8F1BBCDC); \
00152  (e) += ROTATE_LEFT ((a), 5); \
00153  (b) = ROTATE_LEFT((b), 30); \
00154   }
00155 #define II(a, b, c, d, e, w) { \
00156  (e) += I ((b), (c), (d)) + (w) + (php_uint32)(0xCA62C1D6); \
00157  (e) += ROTATE_LEFT ((a), 5); \
00158  (b) = ROTATE_LEFT((b), 30); \
00159   }
00160                                          
00161 
00162 /* {{{ PHP_SHA1Init
00163  * SHA1 initialization. Begins an SHA1 operation, writing a new context.
00164  */
00165 PHPAPI void PHP_SHA1Init(PHP_SHA1_CTX * context)
00166 {
00167        context->count[0] = context->count[1] = 0;
00168        /* Load magic initialization constants.
00169         */
00170        context->state[0] = 0x67452301;
00171        context->state[1] = 0xefcdab89;
00172        context->state[2] = 0x98badcfe;
00173        context->state[3] = 0x10325476;
00174        context->state[4] = 0xc3d2e1f0;
00175 }
00176 /* }}} */
00177 
00178 /* {{{ PHP_SHA1Update
00179    SHA1 block update operation. Continues an SHA1 message-digest
00180    operation, processing another message block, and updating the
00181    context.
00182  */
00183 PHPAPI void PHP_SHA1Update(PHP_SHA1_CTX * context, const unsigned char *input,
00184                         unsigned int inputLen)
00185 {
00186        unsigned int i, index, partLen;
00187 
00188        /* Compute number of bytes mod 64 */
00189        index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
00190 
00191        /* Update number of bits */
00192        if ((context->count[0] += ((php_uint32) inputLen << 3))
00193               < ((php_uint32) inputLen << 3))
00194               context->count[1]++;
00195        context->count[1] += ((php_uint32) inputLen >> 29);
00196 
00197        partLen = 64 - index;
00198 
00199        /* Transform as many times as possible.
00200         */
00201        if (inputLen >= partLen) {
00202               memcpy
00203                      ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
00204               SHA1Transform(context->state, context->buffer);
00205 
00206               for (i = partLen; i + 63 < inputLen; i += 64)
00207                      SHA1Transform(context->state, &input[i]);
00208 
00209               index = 0;
00210        } else
00211               i = 0;
00212 
00213        /* Buffer remaining input */
00214        memcpy
00215               ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
00216                inputLen - i);
00217 }
00218 /* }}} */
00219 
00220 /* {{{ PHP_SHA1Final
00221    SHA1 finalization. Ends an SHA1 message-digest operation, writing the
00222    the message digest and zeroizing the context.
00223  */
00224 PHPAPI void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
00225 {
00226        unsigned char bits[8];
00227        unsigned int index, padLen;
00228 
00229        /* Save number of bits */
00230        bits[7] = context->count[0] & 0xFF;
00231        bits[6] = (context->count[0] >> 8) & 0xFF;
00232        bits[5] = (context->count[0] >> 16) & 0xFF;
00233        bits[4] = (context->count[0] >> 24) & 0xFF;
00234        bits[3] = context->count[1] & 0xFF;
00235        bits[2] = (context->count[1] >> 8) & 0xFF;
00236        bits[1] = (context->count[1] >> 16) & 0xFF;
00237        bits[0] = (context->count[1] >> 24) & 0xFF;
00238        
00239        /* Pad out to 56 mod 64.
00240         */
00241        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
00242        padLen = (index < 56) ? (56 - index) : (120 - index);
00243        PHP_SHA1Update(context, PADDING, padLen);
00244 
00245        /* Append length (before padding) */
00246        PHP_SHA1Update(context, bits, 8);
00247 
00248        /* Store state in digest */
00249        SHA1Encode(digest, context->state, 20);
00250 
00251        /* Zeroize sensitive information.
00252         */
00253        memset((unsigned char*) context, 0, sizeof(*context));
00254 }
00255 /* }}} */
00256 
00257 /* {{{ SHA1Transform
00258  * SHA1 basic transformation. Transforms state based on block.
00259  */
00260 static void SHA1Transform(state, block)
00261 php_uint32 state[5];
00262 const unsigned char block[64];
00263 {
00264        php_uint32 a = state[0], b = state[1], c = state[2];
00265        php_uint32 d = state[3], e = state[4], x[16], tmp;
00266 
00267        SHA1Decode(x, block, 64);
00268 
00269        /* Round 1 */
00270        FF(a, b, c, d, e, x[0]);   /* 1 */
00271        FF(e, a, b, c, d, x[1]);   /* 2 */
00272        FF(d, e, a, b, c, x[2]);   /* 3 */
00273        FF(c, d, e, a, b, x[3]);   /* 4 */
00274        FF(b, c, d, e, a, x[4]);   /* 5 */
00275        FF(a, b, c, d, e, x[5]);   /* 6 */
00276        FF(e, a, b, c, d, x[6]);   /* 7 */
00277        FF(d, e, a, b, c, x[7]);   /* 8 */
00278        FF(c, d, e, a, b, x[8]);   /* 9 */
00279        FF(b, c, d, e, a, x[9]);   /* 10 */
00280        FF(a, b, c, d, e, x[10]);  /* 11 */
00281        FF(e, a, b, c, d, x[11]);  /* 12 */
00282        FF(d, e, a, b, c, x[12]);  /* 13 */
00283        FF(c, d, e, a, b, x[13]);  /* 14 */
00284        FF(b, c, d, e, a, x[14]);  /* 15 */
00285        FF(a, b, c, d, e, x[15]);  /* 16 */
00286        FF(e, a, b, c, d, W(16));  /* 17 */
00287        FF(d, e, a, b, c, W(17));  /* 18 */
00288        FF(c, d, e, a, b, W(18));  /* 19 */
00289        FF(b, c, d, e, a, W(19));  /* 20 */
00290 
00291        /* Round 2 */
00292        GG(a, b, c, d, e, W(20));  /* 21 */
00293        GG(e, a, b, c, d, W(21));  /* 22 */
00294        GG(d, e, a, b, c, W(22));  /* 23 */
00295        GG(c, d, e, a, b, W(23));  /* 24 */
00296        GG(b, c, d, e, a, W(24));  /* 25 */
00297        GG(a, b, c, d, e, W(25));  /* 26 */
00298        GG(e, a, b, c, d, W(26));  /* 27 */
00299        GG(d, e, a, b, c, W(27));  /* 28 */
00300        GG(c, d, e, a, b, W(28));  /* 29 */
00301        GG(b, c, d, e, a, W(29));  /* 30 */
00302        GG(a, b, c, d, e, W(30));  /* 31 */
00303        GG(e, a, b, c, d, W(31));  /* 32 */
00304        GG(d, e, a, b, c, W(32));  /* 33 */
00305        GG(c, d, e, a, b, W(33));  /* 34 */
00306        GG(b, c, d, e, a, W(34));  /* 35 */
00307        GG(a, b, c, d, e, W(35));  /* 36 */
00308        GG(e, a, b, c, d, W(36));  /* 37 */
00309        GG(d, e, a, b, c, W(37));  /* 38 */
00310        GG(c, d, e, a, b, W(38));  /* 39 */
00311        GG(b, c, d, e, a, W(39));  /* 40 */
00312 
00313        /* Round 3 */
00314        HH(a, b, c, d, e, W(40));  /* 41 */
00315        HH(e, a, b, c, d, W(41));  /* 42 */
00316        HH(d, e, a, b, c, W(42));  /* 43 */
00317        HH(c, d, e, a, b, W(43));  /* 44 */
00318        HH(b, c, d, e, a, W(44));  /* 45 */
00319        HH(a, b, c, d, e, W(45));  /* 46 */
00320        HH(e, a, b, c, d, W(46));  /* 47 */
00321        HH(d, e, a, b, c, W(47));  /* 48 */
00322        HH(c, d, e, a, b, W(48));  /* 49 */
00323        HH(b, c, d, e, a, W(49));  /* 50 */
00324        HH(a, b, c, d, e, W(50));  /* 51 */
00325        HH(e, a, b, c, d, W(51));  /* 52 */
00326        HH(d, e, a, b, c, W(52));  /* 53 */
00327        HH(c, d, e, a, b, W(53));  /* 54 */
00328        HH(b, c, d, e, a, W(54));  /* 55 */
00329        HH(a, b, c, d, e, W(55));  /* 56 */
00330        HH(e, a, b, c, d, W(56));  /* 57 */
00331        HH(d, e, a, b, c, W(57));  /* 58 */
00332        HH(c, d, e, a, b, W(58));  /* 59 */
00333        HH(b, c, d, e, a, W(59));  /* 60 */
00334 
00335        /* Round 4 */
00336        II(a, b, c, d, e, W(60));  /* 61 */
00337        II(e, a, b, c, d, W(61));  /* 62 */
00338        II(d, e, a, b, c, W(62));  /* 63 */
00339        II(c, d, e, a, b, W(63));  /* 64 */
00340        II(b, c, d, e, a, W(64));  /* 65 */
00341        II(a, b, c, d, e, W(65));  /* 66 */
00342        II(e, a, b, c, d, W(66));  /* 67 */
00343        II(d, e, a, b, c, W(67));  /* 68 */
00344        II(c, d, e, a, b, W(68));  /* 69 */
00345        II(b, c, d, e, a, W(69));  /* 70 */
00346        II(a, b, c, d, e, W(70));  /* 71 */
00347        II(e, a, b, c, d, W(71));  /* 72 */
00348        II(d, e, a, b, c, W(72));  /* 73 */
00349        II(c, d, e, a, b, W(73));  /* 74 */
00350        II(b, c, d, e, a, W(74));  /* 75 */
00351        II(a, b, c, d, e, W(75));  /* 76 */
00352        II(e, a, b, c, d, W(76));  /* 77 */
00353        II(d, e, a, b, c, W(77));  /* 78 */
00354        II(c, d, e, a, b, W(78));  /* 79 */
00355        II(b, c, d, e, a, W(79));  /* 80 */
00356 
00357        state[0] += a;
00358        state[1] += b;
00359        state[2] += c;
00360        state[3] += d;
00361        state[4] += e;
00362 
00363        /* Zeroize sensitive information. */
00364        memset((unsigned char*) x, 0, sizeof(x));
00365 }
00366 /* }}} */
00367 
00368 /* {{{ SHA1Encode
00369    Encodes input (php_uint32) into output (unsigned char). Assumes len is
00370    a multiple of 4.
00371  */
00372 static void SHA1Encode(output, input, len)
00373 unsigned char *output;
00374 php_uint32 *input;
00375 unsigned int len;
00376 {
00377        unsigned int i, j;
00378 
00379        for (i = 0, j = 0; j < len; i++, j += 4) {
00380               output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
00381               output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
00382               output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
00383               output[j + 3] = (unsigned char) (input[i] & 0xff);
00384        }
00385 }
00386 /* }}} */
00387 
00388 /* {{{ SHA1Decode
00389    Decodes input (unsigned char) into output (php_uint32). Assumes len is
00390    a multiple of 4.
00391  */
00392 static void SHA1Decode(output, input, len)
00393 php_uint32 *output;
00394 const unsigned char *input;
00395 unsigned int len;
00396 {
00397        unsigned int i, j;
00398 
00399        for (i = 0, j = 0; j < len; i++, j += 4)
00400               output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
00401                      (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
00402 }
00403 /* }}} */
00404 
00405 /*
00406  * Local variables:
00407  * tab-width: 4
00408  * c-basic-offset: 4
00409  * End:
00410  * vim600: sw=4 ts=4 fdm=marker
00411  * vim<600: sw=4 ts=4
00412  */