Return to sha1.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard |
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: */