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

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