1/* 2 +----------------------------------------------------------------------+ 3 | PHP Version 5 | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1997-2013 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$ */ 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 28PHPAPI 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 */ 35PHP_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 */ 66PHP_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 111static void SHA1Transform(php_uint32[5], const unsigned char[64]); 112static void SHA1Encode(unsigned char *, php_uint32 *, unsigned int); 113static void SHA1Decode(php_uint32 *, const unsigned char *, unsigned int); 114 115static 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 */ 165PHPAPI 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 */ 183PHPAPI 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 */ 224PHPAPI 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 */ 260static void SHA1Transform(state, block) 261php_uint32 state[5]; 262const 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 */ 372static void SHA1Encode(output, input, len) 373unsigned char *output; 374php_uint32 *input; 375unsigned 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 */ 392static void SHA1Decode(output, input, len) 393php_uint32 *output; 394const unsigned char *input; 395unsigned 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 */ 413