File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard / sha1.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:03:57 2014 UTC (10 years, 1 month ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | PHP Version 5                                                        |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1997-2014 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,v 1.1.1.4 2014/06/15 20:03:57 misho Exp $ */
   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, "p|b", &arg, &arg_len, &raw_output) == FAILURE) {
   79: 		return;
   80: 	}
   81: 	
   82: 	stream = php_stream_open_wrapper(arg, "rb", REPORT_ERRORS, 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>