Annotation of embedaddon/php/ext/standard/sha1.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
                      5:    | Copyright (c) 1997-2012 The PHP Group                                |
                      6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 of the PHP license,      |
                      8:    | that is bundled with this package in the file LICENSE, and is        |
                      9:    | available through the world-wide-web at the following url:           |
                     10:    | http://www.php.net/license/3_01.txt                                  |
                     11:    | If you did not receive a copy of the PHP license and are unable to   |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@php.net so we can mail you a copy immediately.               |
                     14:    +----------------------------------------------------------------------+
                     15:    | Author: Stefan Esser <sesser@php.net>                                |
                     16:    +----------------------------------------------------------------------+
                     17: */
                     18: 
                     19: /* $Id: sha1.c 321634 2012-01-01 13:15:04Z felipe $ */
                     20: 
                     21: #include "php.h"
                     22: 
                     23: /* This code is heavily based on the PHP md5 implementation */ 
                     24: 
                     25: #include "sha1.h"
                     26: #include "md5.h"
                     27: 
                     28: PHPAPI void make_sha1_digest(char *sha1str, unsigned char *digest)
                     29: {
                     30:        make_digest_ex(sha1str, digest, 20);
                     31: }
                     32: 
                     33: /* {{{ proto string sha1(string str [, bool raw_output])
                     34:    Calculate the sha1 hash of a string */
                     35: PHP_FUNCTION(sha1)
                     36: {
                     37:        char *arg;
                     38:        int arg_len;
                     39:        zend_bool raw_output = 0;
                     40:        char sha1str[41];
                     41:        PHP_SHA1_CTX context;
                     42:        unsigned char digest[20];
                     43:        
                     44:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
                     45:                return;
                     46:        }
                     47: 
                     48:        sha1str[0] = '\0';
                     49:        PHP_SHA1Init(&context);
                     50:        PHP_SHA1Update(&context, arg, arg_len);
                     51:        PHP_SHA1Final(digest, &context);
                     52:        if (raw_output) {
                     53:                RETURN_STRINGL(digest, 20, 1);
                     54:        } else {
                     55:                make_digest_ex(sha1str, digest, 20);
                     56:                RETVAL_STRING(sha1str, 1);
                     57:        }
                     58: 
                     59: }
                     60: 
                     61: /* }}} */
                     62: 
                     63: 
                     64: /* {{{ proto string sha1_file(string filename [, bool raw_output])
                     65:    Calculate the sha1 hash of given filename */
                     66: PHP_FUNCTION(sha1_file)
                     67: {
                     68:        char          *arg;
                     69:        int           arg_len;
                     70:        zend_bool raw_output = 0;
                     71:        char          sha1str[41];
                     72:        unsigned char buf[1024];
                     73:        unsigned char digest[20];
                     74:        PHP_SHA1_CTX   context;
                     75:        int           n;
                     76:        php_stream    *stream;
                     77: 
                     78:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &arg, &arg_len, &raw_output) == FAILURE) {
                     79:                return;
                     80:        }
                     81:        
                     82:        stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL);
                     83:        if (!stream) {
                     84:                RETURN_FALSE;
                     85:        }
                     86: 
                     87:        PHP_SHA1Init(&context);
                     88: 
                     89:        while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
                     90:                PHP_SHA1Update(&context, buf, n);
                     91:        }
                     92: 
                     93:        PHP_SHA1Final(digest, &context);
                     94: 
                     95:        php_stream_close(stream);
                     96: 
                     97:        if (n<0) {
                     98:                RETURN_FALSE;
                     99:        }
                    100: 
                    101:        if (raw_output) {
                    102:                RETURN_STRINGL(digest, 20, 1);
                    103:        } else {
                    104:                make_digest_ex(sha1str, digest, 20);
                    105:                RETVAL_STRING(sha1str, 1);
                    106:        }
                    107: }
                    108: /* }}} */
                    109: 
                    110: 
                    111: static void SHA1Transform(php_uint32[5], const unsigned char[64]);
                    112: static void SHA1Encode(unsigned char *, php_uint32 *, unsigned int);
                    113: static void SHA1Decode(php_uint32 *, const unsigned char *, unsigned int);
                    114: 
                    115: static unsigned char PADDING[64] =
                    116: {
                    117:        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    118:        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                    119:        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
                    120: };
                    121: 
                    122: /* F, G, H and I are basic SHA1 functions.
                    123:  */
                    124: #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
                    125: #define G(x, y, z) ((x) ^ (y) ^ (z))
                    126: #define H(x, y, z) (((x) & (y)) | ((z) & ((x) | (y))))
                    127: #define I(x, y, z) ((x) ^ (y) ^ (z))
                    128: 
                    129: /* ROTATE_LEFT rotates x left n bits.
                    130:  */
                    131: #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
                    132: 
                    133: /* W[i]
                    134:  */
                    135: #define W(i) ( tmp=x[(i-3)&15]^x[(i-8)&15]^x[(i-14)&15]^x[i&15], \
                    136:        (x[i&15]=ROTATE_LEFT(tmp, 1)) )  
                    137: 
                    138: /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
                    139:  */
                    140: #define FF(a, b, c, d, e, w) { \
                    141:  (e) += F ((b), (c), (d)) + (w) + (php_uint32)(0x5A827999); \
                    142:  (e) += ROTATE_LEFT ((a), 5); \
                    143:  (b) = ROTATE_LEFT((b), 30); \
                    144:   }
                    145: #define GG(a, b, c, d, e, w) { \
                    146:  (e) += G ((b), (c), (d)) + (w) + (php_uint32)(0x6ED9EBA1); \
                    147:  (e) += ROTATE_LEFT ((a), 5); \
                    148:  (b) = ROTATE_LEFT((b), 30); \
                    149:   }
                    150: #define HH(a, b, c, d, e, w) { \
                    151:  (e) += H ((b), (c), (d)) + (w) + (php_uint32)(0x8F1BBCDC); \
                    152:  (e) += ROTATE_LEFT ((a), 5); \
                    153:  (b) = ROTATE_LEFT((b), 30); \
                    154:   }
                    155: #define II(a, b, c, d, e, w) { \
                    156:  (e) += I ((b), (c), (d)) + (w) + (php_uint32)(0xCA62C1D6); \
                    157:  (e) += ROTATE_LEFT ((a), 5); \
                    158:  (b) = ROTATE_LEFT((b), 30); \
                    159:   }
                    160:                                            
                    161: 
                    162: /* {{{ PHP_SHA1Init
                    163:  * SHA1 initialization. Begins an SHA1 operation, writing a new context.
                    164:  */
                    165: PHPAPI void PHP_SHA1Init(PHP_SHA1_CTX * context)
                    166: {
                    167:        context->count[0] = context->count[1] = 0;
                    168:        /* Load magic initialization constants.
                    169:         */
                    170:        context->state[0] = 0x67452301;
                    171:        context->state[1] = 0xefcdab89;
                    172:        context->state[2] = 0x98badcfe;
                    173:        context->state[3] = 0x10325476;
                    174:        context->state[4] = 0xc3d2e1f0;
                    175: }
                    176: /* }}} */
                    177: 
                    178: /* {{{ PHP_SHA1Update
                    179:    SHA1 block update operation. Continues an SHA1 message-digest
                    180:    operation, processing another message block, and updating the
                    181:    context.
                    182:  */
                    183: PHPAPI void PHP_SHA1Update(PHP_SHA1_CTX * context, const unsigned char *input,
                    184:                           unsigned int inputLen)
                    185: {
                    186:        unsigned int i, index, partLen;
                    187: 
                    188:        /* Compute number of bytes mod 64 */
                    189:        index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
                    190: 
                    191:        /* Update number of bits */
                    192:        if ((context->count[0] += ((php_uint32) inputLen << 3))
                    193:                < ((php_uint32) inputLen << 3))
                    194:                context->count[1]++;
                    195:        context->count[1] += ((php_uint32) inputLen >> 29);
                    196: 
                    197:        partLen = 64 - index;
                    198: 
                    199:        /* Transform as many times as possible.
                    200:         */
                    201:        if (inputLen >= partLen) {
                    202:                memcpy
                    203:                        ((unsigned char*) & context->buffer[index], (unsigned char*) input, partLen);
                    204:                SHA1Transform(context->state, context->buffer);
                    205: 
                    206:                for (i = partLen; i + 63 < inputLen; i += 64)
                    207:                        SHA1Transform(context->state, &input[i]);
                    208: 
                    209:                index = 0;
                    210:        } else
                    211:                i = 0;
                    212: 
                    213:        /* Buffer remaining input */
                    214:        memcpy
                    215:                ((unsigned char*) & context->buffer[index], (unsigned char*) & input[i],
                    216:                 inputLen - i);
                    217: }
                    218: /* }}} */
                    219: 
                    220: /* {{{ PHP_SHA1Final
                    221:    SHA1 finalization. Ends an SHA1 message-digest operation, writing the
                    222:    the message digest and zeroizing the context.
                    223:  */
                    224: PHPAPI void PHP_SHA1Final(unsigned char digest[20], PHP_SHA1_CTX * context)
                    225: {
                    226:        unsigned char bits[8];
                    227:        unsigned int index, padLen;
                    228: 
                    229:        /* Save number of bits */
                    230:        bits[7] = context->count[0] & 0xFF;
                    231:        bits[6] = (context->count[0] >> 8) & 0xFF;
                    232:        bits[5] = (context->count[0] >> 16) & 0xFF;
                    233:        bits[4] = (context->count[0] >> 24) & 0xFF;
                    234:        bits[3] = context->count[1] & 0xFF;
                    235:        bits[2] = (context->count[1] >> 8) & 0xFF;
                    236:        bits[1] = (context->count[1] >> 16) & 0xFF;
                    237:        bits[0] = (context->count[1] >> 24) & 0xFF;
                    238:        
                    239:        /* Pad out to 56 mod 64.
                    240:         */
                    241:        index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
                    242:        padLen = (index < 56) ? (56 - index) : (120 - index);
                    243:        PHP_SHA1Update(context, PADDING, padLen);
                    244: 
                    245:        /* Append length (before padding) */
                    246:        PHP_SHA1Update(context, bits, 8);
                    247: 
                    248:        /* Store state in digest */
                    249:        SHA1Encode(digest, context->state, 20);
                    250: 
                    251:        /* Zeroize sensitive information.
                    252:         */
                    253:        memset((unsigned char*) context, 0, sizeof(*context));
                    254: }
                    255: /* }}} */
                    256: 
                    257: /* {{{ SHA1Transform
                    258:  * SHA1 basic transformation. Transforms state based on block.
                    259:  */
                    260: static void SHA1Transform(state, block)
                    261: php_uint32 state[5];
                    262: const unsigned char block[64];
                    263: {
                    264:        php_uint32 a = state[0], b = state[1], c = state[2];
                    265:        php_uint32 d = state[3], e = state[4], x[16], tmp;
                    266: 
                    267:        SHA1Decode(x, block, 64);
                    268: 
                    269:        /* Round 1 */
                    270:        FF(a, b, c, d, e, x[0]);   /* 1 */
                    271:        FF(e, a, b, c, d, x[1]);   /* 2 */
                    272:        FF(d, e, a, b, c, x[2]);   /* 3 */
                    273:        FF(c, d, e, a, b, x[3]);   /* 4 */
                    274:        FF(b, c, d, e, a, x[4]);   /* 5 */
                    275:        FF(a, b, c, d, e, x[5]);   /* 6 */
                    276:        FF(e, a, b, c, d, x[6]);   /* 7 */
                    277:        FF(d, e, a, b, c, x[7]);   /* 8 */
                    278:        FF(c, d, e, a, b, x[8]);   /* 9 */
                    279:        FF(b, c, d, e, a, x[9]);   /* 10 */
                    280:        FF(a, b, c, d, e, x[10]);  /* 11 */
                    281:        FF(e, a, b, c, d, x[11]);  /* 12 */
                    282:        FF(d, e, a, b, c, x[12]);  /* 13 */
                    283:        FF(c, d, e, a, b, x[13]);  /* 14 */
                    284:        FF(b, c, d, e, a, x[14]);  /* 15 */
                    285:        FF(a, b, c, d, e, x[15]);  /* 16 */
                    286:        FF(e, a, b, c, d, W(16));  /* 17 */
                    287:        FF(d, e, a, b, c, W(17));  /* 18 */
                    288:        FF(c, d, e, a, b, W(18));  /* 19 */
                    289:        FF(b, c, d, e, a, W(19));  /* 20 */
                    290: 
                    291:        /* Round 2 */
                    292:        GG(a, b, c, d, e, W(20));  /* 21 */
                    293:        GG(e, a, b, c, d, W(21));  /* 22 */
                    294:        GG(d, e, a, b, c, W(22));  /* 23 */
                    295:        GG(c, d, e, a, b, W(23));  /* 24 */
                    296:        GG(b, c, d, e, a, W(24));  /* 25 */
                    297:        GG(a, b, c, d, e, W(25));  /* 26 */
                    298:        GG(e, a, b, c, d, W(26));  /* 27 */
                    299:        GG(d, e, a, b, c, W(27));  /* 28 */
                    300:        GG(c, d, e, a, b, W(28));  /* 29 */
                    301:        GG(b, c, d, e, a, W(29));  /* 30 */
                    302:        GG(a, b, c, d, e, W(30));  /* 31 */
                    303:        GG(e, a, b, c, d, W(31));  /* 32 */
                    304:        GG(d, e, a, b, c, W(32));  /* 33 */
                    305:        GG(c, d, e, a, b, W(33));  /* 34 */
                    306:        GG(b, c, d, e, a, W(34));  /* 35 */
                    307:        GG(a, b, c, d, e, W(35));  /* 36 */
                    308:        GG(e, a, b, c, d, W(36));  /* 37 */
                    309:        GG(d, e, a, b, c, W(37));  /* 38 */
                    310:        GG(c, d, e, a, b, W(38));  /* 39 */
                    311:        GG(b, c, d, e, a, W(39));  /* 40 */
                    312: 
                    313:        /* Round 3 */
                    314:        HH(a, b, c, d, e, W(40));  /* 41 */
                    315:        HH(e, a, b, c, d, W(41));  /* 42 */
                    316:        HH(d, e, a, b, c, W(42));  /* 43 */
                    317:        HH(c, d, e, a, b, W(43));  /* 44 */
                    318:        HH(b, c, d, e, a, W(44));  /* 45 */
                    319:        HH(a, b, c, d, e, W(45));  /* 46 */
                    320:        HH(e, a, b, c, d, W(46));  /* 47 */
                    321:        HH(d, e, a, b, c, W(47));  /* 48 */
                    322:        HH(c, d, e, a, b, W(48));  /* 49 */
                    323:        HH(b, c, d, e, a, W(49));  /* 50 */
                    324:        HH(a, b, c, d, e, W(50));  /* 51 */
                    325:        HH(e, a, b, c, d, W(51));  /* 52 */
                    326:        HH(d, e, a, b, c, W(52));  /* 53 */
                    327:        HH(c, d, e, a, b, W(53));  /* 54 */
                    328:        HH(b, c, d, e, a, W(54));  /* 55 */
                    329:        HH(a, b, c, d, e, W(55));  /* 56 */
                    330:        HH(e, a, b, c, d, W(56));  /* 57 */
                    331:        HH(d, e, a, b, c, W(57));  /* 58 */
                    332:        HH(c, d, e, a, b, W(58));  /* 59 */
                    333:        HH(b, c, d, e, a, W(59));  /* 60 */
                    334: 
                    335:        /* Round 4 */
                    336:        II(a, b, c, d, e, W(60));  /* 61 */
                    337:        II(e, a, b, c, d, W(61));  /* 62 */
                    338:        II(d, e, a, b, c, W(62));  /* 63 */
                    339:        II(c, d, e, a, b, W(63));  /* 64 */
                    340:        II(b, c, d, e, a, W(64));  /* 65 */
                    341:        II(a, b, c, d, e, W(65));  /* 66 */
                    342:        II(e, a, b, c, d, W(66));  /* 67 */
                    343:        II(d, e, a, b, c, W(67));  /* 68 */
                    344:        II(c, d, e, a, b, W(68));  /* 69 */
                    345:        II(b, c, d, e, a, W(69));  /* 70 */
                    346:        II(a, b, c, d, e, W(70));  /* 71 */
                    347:        II(e, a, b, c, d, W(71));  /* 72 */
                    348:        II(d, e, a, b, c, W(72));  /* 73 */
                    349:        II(c, d, e, a, b, W(73));  /* 74 */
                    350:        II(b, c, d, e, a, W(74));  /* 75 */
                    351:        II(a, b, c, d, e, W(75));  /* 76 */
                    352:        II(e, a, b, c, d, W(76));  /* 77 */
                    353:        II(d, e, a, b, c, W(77));  /* 78 */
                    354:        II(c, d, e, a, b, W(78));  /* 79 */
                    355:        II(b, c, d, e, a, W(79));  /* 80 */
                    356: 
                    357:        state[0] += a;
                    358:        state[1] += b;
                    359:        state[2] += c;
                    360:        state[3] += d;
                    361:        state[4] += e;
                    362: 
                    363:        /* Zeroize sensitive information. */
                    364:        memset((unsigned char*) x, 0, sizeof(x));
                    365: }
                    366: /* }}} */
                    367: 
                    368: /* {{{ SHA1Encode
                    369:    Encodes input (php_uint32) into output (unsigned char). Assumes len is
                    370:    a multiple of 4.
                    371:  */
                    372: static void SHA1Encode(output, input, len)
                    373: unsigned char *output;
                    374: php_uint32 *input;
                    375: unsigned int len;
                    376: {
                    377:        unsigned int i, j;
                    378: 
                    379:        for (i = 0, j = 0; j < len; i++, j += 4) {
                    380:                output[j] = (unsigned char) ((input[i] >> 24) & 0xff);
                    381:                output[j + 1] = (unsigned char) ((input[i] >> 16) & 0xff);
                    382:                output[j + 2] = (unsigned char) ((input[i] >> 8) & 0xff);
                    383:                output[j + 3] = (unsigned char) (input[i] & 0xff);
                    384:        }
                    385: }
                    386: /* }}} */
                    387: 
                    388: /* {{{ SHA1Decode
                    389:    Decodes input (unsigned char) into output (php_uint32). Assumes len is
                    390:    a multiple of 4.
                    391:  */
                    392: static void SHA1Decode(output, input, len)
                    393: php_uint32 *output;
                    394: const unsigned char *input;
                    395: unsigned int len;
                    396: {
                    397:        unsigned int i, j;
                    398: 
                    399:        for (i = 0, j = 0; j < len; i++, j += 4)
                    400:                output[i] = ((php_uint32) input[j + 3]) | (((php_uint32) input[j + 2]) << 8) |
                    401:                        (((php_uint32) input[j + 1]) << 16) | (((php_uint32) input[j]) << 24);
                    402: }
                    403: /* }}} */
                    404: 
                    405: /*
                    406:  * Local variables:
                    407:  * tab-width: 4
                    408:  * c-basic-offset: 4
                    409:  * End:
                    410:  * vim600: sw=4 ts=4 fdm=marker
                    411:  * vim<600: sw=4 ts=4
                    412:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>