root/ext/standard/sha1.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. make_sha1_digest
  2. PHP_FUNCTION
  3. PHP_FUNCTION
  4. PHP_SHA1Init
  5. PHP_SHA1Update
  6. PHP_SHA1Final
  7. SHA1Transform
  8. SHA1Encode
  9. SHA1Decode

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 5                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 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 
  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  */

/* [<][>][^][v][top][bottom][index][help] */