File modules/phpseclib/Crypt/Hash.class.php

Last commit: Sat Oct 31 03:22:35 2020 +0100	Jan Dankert	Fix: Crypt\RSA needs Crypt\Hash
1 <?php 2 3 /** 4 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions. 5 * 6 * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following: 7 * 8 * md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96 9 * 10 * If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to 11 * the hash. If no valid algorithm is provided, sha1 will be used. 12 * 13 * PHP version 5 14 * 15 * {@internal The variable names are the same as those in 16 * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}} 17 * 18 * Here's a short example of how to use this library: 19 * <code> 20 * <?php 21 * include 'vendor/autoload.php'; 22 * 23 * $hash = new \phpseclib\Crypt\Hash('sha1'); 24 * 25 * $hash->setKey('abcdefg'); 26 * 27 * echo base64_encode($hash->hash('abcdefg')); 28 * ?> 29 * </code> 30 * 31 * @category Crypt 32 * @package Hash 33 * @author Jim Wigginton <terrafrost@php.net> 34 * @copyright 2007 Jim Wigginton 35 * @license http://www.opensource.org/licenses/mit-license.html MIT License 36 * @link http://phpseclib.sourceforge.net 37 */ 38 39 namespace phpseclib\Crypt; 40 41 use phpseclib\Math\BigInteger; 42 43 /** 44 * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions. 45 * 46 * @package Hash 47 * @author Jim Wigginton <terrafrost@php.net> 48 * @access public 49 */ 50 class Hash 51 { 52 /**#@+ 53 * @access private 54 * @see \phpseclib\Crypt\Hash::__construct() 55 */ 56 /** 57 * Toggles the internal implementation 58 */ 59 const MODE_INTERNAL = 1; 60 /** 61 * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+. 62 */ 63 const MODE_MHASH = 2; 64 /** 65 * Toggles the hash() implementation, which works on PHP 5.1.2+. 66 */ 67 const MODE_HASH = 3; 68 /**#@-*/ 69 70 /** 71 * Hash Parameter 72 * 73 * @see self::setHash() 74 * @var int 75 * @access private 76 */ 77 var $hashParam; 78 79 /** 80 * Byte-length of compression blocks / key (Internal HMAC) 81 * 82 * @see self::setAlgorithm() 83 * @var int 84 * @access private 85 */ 86 var $b; 87 88 /** 89 * Byte-length of hash output (Internal HMAC) 90 * 91 * @see self::setHash() 92 * @var int 93 * @access private 94 */ 95 var $l = false; 96 97 /** 98 * Hash Algorithm 99 * 100 * @see self::setHash() 101 * @var string 102 * @access private 103 */ 104 var $hash; 105 106 /** 107 * Key 108 * 109 * @see self::setKey() 110 * @var string 111 * @access private 112 */ 113 var $key = false; 114 115 /** 116 * Computed Key 117 * 118 * @see self::_computeKey() 119 * @var string 120 * @access private 121 */ 122 var $computedKey = false; 123 124 /** 125 * Outer XOR (Internal HMAC) 126 * 127 * @see self::setKey() 128 * @var string 129 * @access private 130 */ 131 var $opad; 132 133 /** 134 * Inner XOR (Internal HMAC) 135 * 136 * @see self::setKey() 137 * @var string 138 * @access private 139 */ 140 var $ipad; 141 142 /** 143 * Engine 144 * 145 * @see self::setHash() 146 * @var string 147 * @access private 148 */ 149 var $engine; 150 151 /** 152 * Default Constructor. 153 * 154 * @param string $hash 155 * @return \phpseclib\Crypt\Hash 156 * @access public 157 */ 158 function __construct($hash = 'sha1') 159 { 160 if (!defined('CRYPT_HASH_MODE')) { 161 switch (true) { 162 case extension_loaded('hash'): 163 define('CRYPT_HASH_MODE', self::MODE_HASH); 164 break; 165 case extension_loaded('mhash'): 166 define('CRYPT_HASH_MODE', self::MODE_MHASH); 167 break; 168 default: 169 define('CRYPT_HASH_MODE', self::MODE_INTERNAL); 170 } 171 } 172 173 $this->setHash($hash); 174 } 175 176 /** 177 * Sets the key for HMACs 178 * 179 * Keys can be of any length. 180 * 181 * @access public 182 * @param string $key 183 */ 184 function setKey($key = false) 185 { 186 $this->key = $key; 187 $this->_computeKey(); 188 } 189 190 /** 191 * Pre-compute the key used by the HMAC 192 * 193 * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes 194 * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC." 195 * 196 * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/ 197 * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during 198 * every call 199 * 200 * @access private 201 */ 202 function _computeKey() 203 { 204 if ($this->key === false) { 205 $this->computedKey = false; 206 return; 207 } 208 209 if (strlen($this->key) <= $this->b) { 210 $this->computedKey = $this->key; 211 return; 212 } 213 214 switch ($this->engine) { 215 case self::MODE_MHASH: 216 $this->computedKey = mhash($this->hash, $this->key); 217 break; 218 case self::MODE_HASH: 219 $this->computedKey = hash($this->hash, $this->key, true); 220 break; 221 case self::MODE_INTERNAL: 222 $this->computedKey = call_user_func($this->hash, $this->key); 223 } 224 } 225 226 /** 227 * Gets the hash function. 228 * 229 * As set by the constructor or by the setHash() method. 230 * 231 * @access public 232 * @return string 233 */ 234 function getHash() 235 { 236 return $this->hashParam; 237 } 238 239 /** 240 * Sets the hash function. 241 * 242 * @access public 243 * @param string $hash 244 */ 245 function setHash($hash) 246 { 247 $this->hashParam = $hash = strtolower($hash); 248 switch ($hash) { 249 case 'md5-96': 250 case 'sha1-96': 251 case 'sha256-96': 252 case 'sha512-96': 253 $hash = substr($hash, 0, -3); 254 $this->l = 12; // 96 / 8 = 12 255 break; 256 case 'md2': 257 case 'md5': 258 $this->l = 16; 259 break; 260 case 'sha1': 261 $this->l = 20; 262 break; 263 case 'sha256': 264 $this->l = 32; 265 break; 266 case 'sha384': 267 $this->l = 48; 268 break; 269 case 'sha512': 270 $this->l = 64; 271 } 272 273 switch ($hash) { 274 case 'md2-96': 275 case 'md2': 276 $this->b = 16; 277 case 'md5-96': 278 case 'sha1-96': 279 case 'sha224-96': 280 case 'sha256-96': 281 case 'md2': 282 case 'md5': 283 case 'sha1': 284 case 'sha224': 285 case 'sha256': 286 $this->b = 64; 287 break; 288 default: 289 $this->b = 128; 290 } 291 292 switch ($hash) { 293 case 'md2': 294 $this->engine = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ? 295 self::MODE_HASH : self::MODE_INTERNAL; 296 break; 297 case 'sha384': 298 case 'sha512': 299 $this->engine = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE; 300 break; 301 default: 302 $this->engine = CRYPT_HASH_MODE; 303 } 304 305 switch ($this->engine) { 306 case self::MODE_MHASH: 307 switch ($hash) { 308 case 'md5': 309 $this->hash = MHASH_MD5; 310 break; 311 case 'sha256': 312 $this->hash = MHASH_SHA256; 313 break; 314 case 'sha1': 315 default: 316 $this->hash = MHASH_SHA1; 317 } 318 $this->_computeKey(self::MODE_MHASH); 319 return; 320 case self::MODE_HASH: 321 switch ($hash) { 322 case 'md5': 323 $this->hash = 'md5'; 324 return; 325 case 'md2': 326 case 'sha256': 327 case 'sha384': 328 case 'sha512': 329 $this->hash = $hash; 330 return; 331 case 'sha1': 332 default: 333 $this->hash = 'sha1'; 334 } 335 $this->_computeKey(self::MODE_HASH); 336 return; 337 } 338 339 switch ($hash) { 340 case 'md2': 341 $this->hash = array($this, '_md2'); 342 break; 343 case 'md5': 344 $this->hash = array($this, '_md5'); 345 break; 346 case 'sha256': 347 $this->hash = array($this, '_sha256'); 348 break; 349 case 'sha384': 350 case 'sha512': 351 $this->hash = array($this, '_sha512'); 352 break; 353 case 'sha1': 354 default: 355 $this->hash = array($this, '_sha1'); 356 } 357 358 $this->ipad = str_repeat(chr(0x36), $this->b); 359 $this->opad = str_repeat(chr(0x5C), $this->b); 360 361 $this->_computeKey(self::MODE_INTERNAL); 362 } 363 364 /** 365 * Compute the HMAC. 366 * 367 * @access public 368 * @param string $text 369 * @return string 370 */ 371 function hash($text) 372 { 373 if (!empty($this->key) || is_string($this->key)) { 374 switch ($this->engine) { 375 case self::MODE_MHASH: 376 $output = mhash($this->hash, $text, $this->computedKey); 377 break; 378 case self::MODE_HASH: 379 $output = hash_hmac($this->hash, $text, $this->computedKey, true); 380 break; 381 case self::MODE_INTERNAL: 382 $key = str_pad($this->computedKey, $this->b, chr(0)); // step 1 383 $temp = $this->ipad ^ $key; // step 2 384 $temp .= $text; // step 3 385 $temp = call_user_func($this->hash, $temp); // step 4 386 $output = $this->opad ^ $key; // step 5 387 $output.= $temp; // step 6 388 $output = call_user_func($this->hash, $output); // step 7 389 } 390 } else { 391 switch ($this->engine) { 392 case self::MODE_MHASH: 393 $output = mhash($this->hash, $text); 394 break; 395 case self::MODE_HASH: 396 $output = hash($this->hash, $text, true); 397 break; 398 case self::MODE_INTERNAL: 399 $output = call_user_func($this->hash, $text); 400 } 401 } 402 403 return substr($output, 0, $this->l); 404 } 405 406 /** 407 * Returns the hash length (in bytes) 408 * 409 * @access public 410 * @return int 411 */ 412 function getLength() 413 { 414 return $this->l; 415 } 416 417 /** 418 * Wrapper for MD5 419 * 420 * @access private 421 * @param string $m 422 */ 423 function _md5($m) 424 { 425 return pack('H*', md5($m)); 426 } 427 428 /** 429 * Wrapper for SHA1 430 * 431 * @access private 432 * @param string $m 433 */ 434 function _sha1($m) 435 { 436 return pack('H*', sha1($m)); 437 } 438 439 /** 440 * Pure-PHP implementation of MD2 441 * 442 * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}. 443 * 444 * @access private 445 * @param string $m 446 */ 447 function _md2($m) 448 { 449 static $s = array( 450 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 451 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 452 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 453 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 454 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, 455 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, 456 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, 457 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, 458 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, 459 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, 460 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, 461 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 462 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 463 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 464 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, 465 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, 466 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, 467 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 468 ); 469 470 // Step 1. Append Padding Bytes 471 $pad = 16 - (strlen($m) & 0xF); 472 $m.= str_repeat(chr($pad), $pad); 473 474 $length = strlen($m); 475 476 // Step 2. Append Checksum 477 $c = str_repeat(chr(0), 16); 478 $l = chr(0); 479 for ($i = 0; $i < $length; $i+= 16) { 480 for ($j = 0; $j < 16; $j++) { 481 // RFC1319 incorrectly states that C[j] should be set to S[c xor L] 482 //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]); 483 // per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j] 484 $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j])); 485 $l = $c[$j]; 486 } 487 } 488 $m.= $c; 489 490 $length+= 16; 491 492 // Step 3. Initialize MD Buffer 493 $x = str_repeat(chr(0), 48); 494 495 // Step 4. Process Message in 16-Byte Blocks 496 for ($i = 0; $i < $length; $i+= 16) { 497 for ($j = 0; $j < 16; $j++) { 498 $x[$j + 16] = $m[$i + $j]; 499 $x[$j + 32] = $x[$j + 16] ^ $x[$j]; 500 } 501 $t = chr(0); 502 for ($j = 0; $j < 18; $j++) { 503 for ($k = 0; $k < 48; $k++) { 504 $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]); 505 //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]); 506 } 507 $t = chr(ord($t) + $j); 508 } 509 } 510 511 // Step 5. Output 512 return substr($x, 0, 16); 513 } 514 515 /** 516 * Pure-PHP implementation of SHA256 517 * 518 * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}. 519 * 520 * @access private 521 * @param string $m 522 */ 523 function _sha256($m) 524 { 525 if (extension_loaded('suhosin')) { 526 return pack('H*', sha256($m)); 527 } 528 529 // Initialize variables 530 $hash = array( 531 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 532 ); 533 // Initialize table of round constants 534 // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311) 535 static $k = array( 536 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 537 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 538 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 539 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 540 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 541 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 542 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 543 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 544 ); 545 546 // Pre-processing 547 $length = strlen($m); 548 // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64 549 $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F)); 550 $m[$length] = chr(0x80); 551 // we don't support hashing strings 512MB long 552 $m.= pack('N2', 0, $length << 3); 553 554 // Process the message in successive 512-bit chunks 555 $chunks = str_split($m, 64); 556 foreach ($chunks as $chunk) { 557 $w = array(); 558 for ($i = 0; $i < 16; $i++) { 559 extract(unpack('Ntemp', $this->_string_shift($chunk, 4))); 560 $w[] = $temp; 561 } 562 563 // Extend the sixteen 32-bit words into sixty-four 32-bit words 564 for ($i = 16; $i < 64; $i++) { 565 // @codingStandardsIgnoreStart 566 $s0 = $this->_rightRotate($w[$i - 15], 7) ^ 567 $this->_rightRotate($w[$i - 15], 18) ^ 568 $this->_rightShift( $w[$i - 15], 3); 569 $s1 = $this->_rightRotate($w[$i - 2], 17) ^ 570 $this->_rightRotate($w[$i - 2], 19) ^ 571 $this->_rightShift( $w[$i - 2], 10); 572 // @codingStandardsIgnoreEnd 573 $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1); 574 } 575 576 // Initialize hash value for this chunk 577 list($a, $b, $c, $d, $e, $f, $g, $h) = $hash; 578 579 // Main loop 580 for ($i = 0; $i < 64; $i++) { 581 $s0 = $this->_rightRotate($a, 2) ^ 582 $this->_rightRotate($a, 13) ^ 583 $this->_rightRotate($a, 22); 584 $maj = ($a & $b) ^ 585 ($a & $c) ^ 586 ($b & $c); 587 $t2 = $this->_add($s0, $maj); 588 589 $s1 = $this->_rightRotate($e, 6) ^ 590 $this->_rightRotate($e, 11) ^ 591 $this->_rightRotate($e, 25); 592 $ch = ($e & $f) ^ 593 ($this->_not($e) & $g); 594 $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]); 595 596 $h = $g; 597 $g = $f; 598 $f = $e; 599 $e = $this->_add($d, $t1); 600 $d = $c; 601 $c = $b; 602 $b = $a; 603 $a = $this->_add($t1, $t2); 604 } 605 606 // Add this chunk's hash to result so far 607 $hash = array( 608 $this->_add($hash[0], $a), 609 $this->_add($hash[1], $b), 610 $this->_add($hash[2], $c), 611 $this->_add($hash[3], $d), 612 $this->_add($hash[4], $e), 613 $this->_add($hash[5], $f), 614 $this->_add($hash[6], $g), 615 $this->_add($hash[7], $h) 616 ); 617 } 618 619 // Produce the final hash value (big-endian) 620 return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]); 621 } 622 623 /** 624 * Pure-PHP implementation of SHA384 and SHA512 625 * 626 * @access private 627 * @param string $m 628 */ 629 function _sha512($m) 630 { 631 static $init384, $init512, $k; 632 633 if (!isset($k)) { 634 // Initialize variables 635 $init384 = array( // initial values for SHA384 636 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939', 637 '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4' 638 ); 639 $init512 = array( // initial values for SHA512 640 '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1', 641 '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179' 642 ); 643 644 for ($i = 0; $i < 8; $i++) { 645 $init384[$i] = new BigInteger($init384[$i], 16); 646 $init384[$i]->setPrecision(64); 647 $init512[$i] = new BigInteger($init512[$i], 16); 648 $init512[$i]->setPrecision(64); 649 } 650 651 // Initialize table of round constants 652 // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) 653 $k = array( 654 '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', 655 '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', 656 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', 657 '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', 658 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', 659 '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', 660 '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', 661 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', 662 '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', 663 '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', 664 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', 665 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', 666 '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', 667 '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', 668 '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', 669 '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', 670 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', 671 '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', 672 '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', 673 '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' 674 ); 675 676 for ($i = 0; $i < 80; $i++) { 677 $k[$i] = new BigInteger($k[$i], 16); 678 } 679 } 680 681 $hash = $this->l == 48 ? $init384 : $init512; 682 683 // Pre-processing 684 $length = strlen($m); 685 // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 686 $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F)); 687 $m[$length] = chr(0x80); 688 // we don't support hashing strings 512MB long 689 $m.= pack('N4', 0, 0, 0, $length << 3); 690 691 // Process the message in successive 1024-bit chunks 692 $chunks = str_split($m, 128); 693 foreach ($chunks as $chunk) { 694 $w = array(); 695 for ($i = 0; $i < 16; $i++) { 696 $temp = new BigInteger($this->_string_shift($chunk, 8), 256); 697 $temp->setPrecision(64); 698 $w[] = $temp; 699 } 700 701 // Extend the sixteen 32-bit words into eighty 32-bit words 702 for ($i = 16; $i < 80; $i++) { 703 $temp = array( 704 $w[$i - 15]->bitwise_rightRotate(1), 705 $w[$i - 15]->bitwise_rightRotate(8), 706 $w[$i - 15]->bitwise_rightShift(7) 707 ); 708 $s0 = $temp[0]->bitwise_xor($temp[1]); 709 $s0 = $s0->bitwise_xor($temp[2]); 710 $temp = array( 711 $w[$i - 2]->bitwise_rightRotate(19), 712 $w[$i - 2]->bitwise_rightRotate(61), 713 $w[$i - 2]->bitwise_rightShift(6) 714 ); 715 $s1 = $temp[0]->bitwise_xor($temp[1]); 716 $s1 = $s1->bitwise_xor($temp[2]); 717 $w[$i] = $w[$i - 16]->copy(); 718 $w[$i] = $w[$i]->add($s0); 719 $w[$i] = $w[$i]->add($w[$i - 7]); 720 $w[$i] = $w[$i]->add($s1); 721 } 722 723 // Initialize hash value for this chunk 724 $a = $hash[0]->copy(); 725 $b = $hash[1]->copy(); 726 $c = $hash[2]->copy(); 727 $d = $hash[3]->copy(); 728 $e = $hash[4]->copy(); 729 $f = $hash[5]->copy(); 730 $g = $hash[6]->copy(); 731 $h = $hash[7]->copy(); 732 733 // Main loop 734 for ($i = 0; $i < 80; $i++) { 735 $temp = array( 736 $a->bitwise_rightRotate(28), 737 $a->bitwise_rightRotate(34), 738 $a->bitwise_rightRotate(39) 739 ); 740 $s0 = $temp[0]->bitwise_xor($temp[1]); 741 $s0 = $s0->bitwise_xor($temp[2]); 742 $temp = array( 743 $a->bitwise_and($b), 744 $a->bitwise_and($c), 745 $b->bitwise_and($c) 746 ); 747 $maj = $temp[0]->bitwise_xor($temp[1]); 748 $maj = $maj->bitwise_xor($temp[2]); 749 $t2 = $s0->add($maj); 750 751 $temp = array( 752 $e->bitwise_rightRotate(14), 753 $e->bitwise_rightRotate(18), 754 $e->bitwise_rightRotate(41) 755 ); 756 $s1 = $temp[0]->bitwise_xor($temp[1]); 757 $s1 = $s1->bitwise_xor($temp[2]); 758 $temp = array( 759 $e->bitwise_and($f), 760 $g->bitwise_and($e->bitwise_not()) 761 ); 762 $ch = $temp[0]->bitwise_xor($temp[1]); 763 $t1 = $h->add($s1); 764 $t1 = $t1->add($ch); 765 $t1 = $t1->add($k[$i]); 766 $t1 = $t1->add($w[$i]); 767 768 $h = $g->copy(); 769 $g = $f->copy(); 770 $f = $e->copy(); 771 $e = $d->add($t1); 772 $d = $c->copy(); 773 $c = $b->copy(); 774 $b = $a->copy(); 775 $a = $t1->add($t2); 776 } 777 778 // Add this chunk's hash to result so far 779 $hash = array( 780 $hash[0]->add($a), 781 $hash[1]->add($b), 782 $hash[2]->add($c), 783 $hash[3]->add($d), 784 $hash[4]->add($e), 785 $hash[5]->add($f), 786 $hash[6]->add($g), 787 $hash[7]->add($h) 788 ); 789 } 790 791 // Produce the final hash value (big-endian) 792 // (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) 793 $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . 794 $hash[4]->toBytes() . $hash[5]->toBytes(); 795 if ($this->l != 48) { 796 $temp.= $hash[6]->toBytes() . $hash[7]->toBytes(); 797 } 798 799 return $temp; 800 } 801 802 /** 803 * Right Rotate 804 * 805 * @access private 806 * @param int $int 807 * @param int $amt 808 * @see self::_sha256() 809 * @return int 810 */ 811 function _rightRotate($int, $amt) 812 { 813 $invamt = 32 - $amt; 814 $mask = (1 << $invamt) - 1; 815 return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask); 816 } 817 818 /** 819 * Right Shift 820 * 821 * @access private 822 * @param int $int 823 * @param int $amt 824 * @see self::_sha256() 825 * @return int 826 */ 827 function _rightShift($int, $amt) 828 { 829 $mask = (1 << (32 - $amt)) - 1; 830 return ($int >> $amt) & $mask; 831 } 832 833 /** 834 * Not 835 * 836 * @access private 837 * @param int $int 838 * @see self::_sha256() 839 * @return int 840 */ 841 function _not($int) 842 { 843 return ~$int & 0xFFFFFFFF; 844 } 845 846 /** 847 * Add 848 * 849 * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the 850 * possibility of overflow exists, care has to be taken. BigInteger could be used but this should be faster. 851 * 852 * @param int $... 853 * @return int 854 * @see self::_sha256() 855 * @access private 856 */ 857 function _add() 858 { 859 static $mod; 860 if (!isset($mod)) { 861 $mod = pow(2, 32); 862 } 863 864 $result = 0; 865 $arguments = func_get_args(); 866 foreach ($arguments as $argument) { 867 $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument; 868 } 869 870 if ((php_uname('m') & "\xDF\xDF\xDF") != 'ARM') { 871 return fmod($result, $mod); 872 } 873 874 return (fmod($result, 0x80000000) & 0x7FFFFFFF) | 875 ((fmod(floor($result / 0x80000000), 2) & 1) << 31); 876 } 877 878 /** 879 * String Shift 880 * 881 * Inspired by array_shift 882 * 883 * @param string $string 884 * @param int $index 885 * @return string 886 * @access private 887 */ 888 function _string_shift(&$string, $index = 1) 889 { 890 $substr = substr($string, 0, $index); 891 $string = substr($string, $index); 892 return $substr; 893 } 894 }
Download modules/phpseclib/Crypt/Hash.class.php
History Sat, 31 Oct 2020 03:22:35 +0100 Jan Dankert Fix: Crypt\RSA needs Crypt\Hash